XOOPS  2.6.0
Metagen.php
Go to the documentation of this file.
1 <?php
2 /*
3  You may not change or alter any portion of this comment or credits
4  of supporting developers from this source code or any supporting source code
5  which is considered copyrighted (c) material of the original comment or credit authors.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  */
11 
12 namespace Xmf;
13 
27 class Metagen
28 {
29 
34  const ELLIPSIS = "…"; // unicode horizontal ellipsis U+2026
35 
43  public static function assignTitle($title)
44  {
45  global $xoopsTpl, $xoTheme;
46 
47  $title = trim($title);
48  $title = self::asPlainText($title);
49  if (!empty($title)) {
50  if (is_object($xoTheme)) {
51  $xoTheme->addMeta('meta', 'title', $title);
52  }
53  $xoopsTpl->assign('xoops_pagetitle', $title);
54  }
55  }
56 
64  public static function assignKeywords($keywords)
65  {
66  global $xoopsTpl, $xoTheme;
67 
68  if (!empty($keywords) && is_array($keywords)) {
69  $keyword_tag = implode(', ', $keywords);
70 
71  if (!empty($keyword_tag)) {
72  if (is_object($xoTheme)) {
73  $xoTheme->addMeta('meta', 'keywords', $keyword_tag);
74  } else {
75  $xoopsTpl->assign('xoops_meta_keywords', $keyword_tag);
76  }
77  }
78  }
79  }
80 
88  public static function assignDescription($description)
89  {
90  global $xoopsTpl, $xoTheme;
91 
92  $description = trim($description);
93  if (!empty($description)) {
94  if (is_object($xoTheme)) {
95  $xoTheme->addMeta('meta', 'description', $description);
96  } else {
97  $xoopsTpl->assign('xoops_meta_description', $description);
98  }
99  }
100  }
101 
112  public static function generateKeywords(
113  $body,
114  $count = 20,
115  $minLength = 4,
116  $forceKeys = null
117  ) {
118  $keywords = array();
119  $keycnt = array();
120  if (!is_array($forceKeys)) {
121  $forceKeys = array();
122  }
123 
124  $text = self::asPlainText($body);
125  $text = mb_strtolower($text);
126 
127  $originalKeywords = preg_split(
128  '/[^a-zA-Z\'"-]+/',
129  $text,
130  -1,
131  PREG_SPLIT_NO_EMPTY
132  );
133 
134  foreach ($originalKeywords as $originalKeyword) {
135  if (self::checkStopWords($originalKeyword)) {
136  $secondRoundKeywords = explode("'", $originalKeyword);
137  foreach ($secondRoundKeywords as $secondRoundKeyword) {
138  if (self::checkStopWords($secondRoundKeyword)
139  && strlen($secondRoundKeyword) >= $minLength
140  ) {
141  $keycnt[$secondRoundKeyword] =
142  empty($keycnt[$secondRoundKeyword]) ? 1 : $keycnt[$secondRoundKeyword] + 1;
143  }
144  }
145  }
146  }
147 
148  while (!empty($forceKeys)) {
149  $tempkey = strtolower(array_pop($forceKeys));
150  $keycnt[$tempkey] = 999999;
151  }
152 
153  arsort($keycnt, SORT_NUMERIC);
154  $key = array_keys($keycnt);
155  $keywords = array_slice($key, 0, $count);
156 
157  return $keywords;
158  }
159 
168  protected static function checkStopWords($key)
169  {
170  static $stopwords = null;
171 
172  if (!$stopwords) {
173  if (!defined('_XMF_STOPWORDS')) {
174  \Xmf\Language::load('stopwords', 'xmf');
175  }
176  if (defined('_XMF_STOPWORDS')) {
177  $sw = explode(' ', _XMF_STOPWORDS);
178  $stopwords = array_fill_keys($sw, true);
179  } else {
180  $stopwords = array('_'=> true);
181  }
182  }
183  if ($stopwords) {
184  return !isset($stopwords[mb_strtolower($key)]);
185  }
186  return true;
187  }
188 
197  public static function generateDescription($body, $wordCount = 100)
198  {
199  $text = self::asPlainText($body);
200 
201  $words = explode(" ", $text);
202 
203  // Only keep $maxWords words
204  $newWords = array();
205  $i = 0;
206  while ($i < $wordCount - 1 && $i < count($words)) {
207  $newWords[] = $words[$i];
208  ++$i;
209  }
210  $ret = implode(' ', $newWords);
211  $len = mb_strlen($ret);
212  $lastperiod = mb_strrpos($ret, '.');
213  $ret .= ($lastperiod === false) ? self::ELLIPSIS : '';
214  if ($len>100 && ($len-$lastperiod)<30) {
215  $ret = mb_substr($ret, 0, $lastperiod+1);
216  }
217 
218  return $ret;
219  }
220 
233  public static function generateMetaTags(
234  $title,
235  $body,
236  $count = 20,
237  $minLength = 4,
238  $wordCount = 100,
239  $forceKeys = null
240  ) {
241  $title_keywords = self::generateKeywords($title, $count, 3, $forceKeys);
242  $keywords = self::generateKeywords($body, $count, $minLength, $title_keywords);
243  $description = self::generateDescription($body, $wordCount);
244  self::assignTitle($title);
245  self::assignKeywords($keywords);
246  self::assignDescription($description);
247  }
248 
258  protected static function nonEmptyString($var)
259  {
260  return (strlen($var) > 0);
261  }
262 
273  public static function generateSeoTitle($title = '', $extension = '')
274  {
275  $title = preg_replace("/[^a-zA-Z0-9]/", "-", $title);
276  $title = \Normalizer::normalize($title, \Normalizer::FORM_C);
277 
278  $tableau = explode("-", $title);
279  $tableau = array_filter($tableau, 'self::nonEmptyString');
280  $tableau = array_filter($tableau, 'self::checkStopWords');
281  $title = implode("-", $tableau);
282 
283  $title = (empty($title)) ? '' : $title . $extension;
284  return $title;
285  }
286 
302  public static function getSearchSummary($haystack, $needles = null, $length = 120)
303  {
304  $encoding = 'UTF-8';
305 
306  $haystack = self::asPlainText($haystack);
307  $pos = self::getNeedlePositions($haystack, $needles);
308 
309  $start = empty($pos) ? 0 : min($pos);
310 
311  $start = max($start - (int)($length/2), 0);
312 
313  $pre = ($start > 0); // need an ellipsis in front?
314  if ($pre) {
315  // we are not at the begining so find first blank
316  $temp = mb_strpos($haystack, ' ', $start, $encoding);
317  $start = ($temp === false) ? $start : $temp;
318  $haystack = mb_substr($haystack, $start, null, $encoding);
319  }
320 
321  $post = !(mb_strlen($haystack, $encoding) < $length); // need an ellipsis in back?
322  if ($post) {
323  $haystack = mb_substr($haystack, 0, $length, $encoding);
324  $end = mb_strrpos($haystack, ' ', 0, $encoding);
325  if ($end) {
326  $haystack = mb_substr($haystack, 0, $end, $encoding);
327  }
328  }
329 
330  $haystack = ($pre ? self::ELLIPSIS : '') . trim($haystack) . ($post ? self::ELLIPSIS : '');
331  return $haystack;
332  }
333 
341  protected static function asPlainText($rawText)
342  {
343  $text = $rawText;
344  $utilities = new Utilities();
345  $text = $utilities->html2text($text);
346  $text = $utilities->purifyText($text);
347 
348  $text = str_replace(array("\n", "\r"), ' ', $text);
349  $text = preg_replace('/[ ]* [ ]*/', ' ', $text);
350 
351  return trim($text);
352  }
353 
365  private static function getNeedlePositions($haystack, $needles)
366  {
367  $pos=array();
368  $needles = empty($needles) ? array() : (array) $needles;
369  foreach ($needles as $needle) {
370  $i = mb_stripos($haystack, $needle, 0, 'UTF-8');
371  if ($i!==false) {
372  $pos[] = $i; // only store matches
373  }
374  }
375  return $pos;
376  }
377 }
$xoTheme
Definition: common.php:262
static getNeedlePositions($haystack, $needles)
Definition: Metagen.php:365
$i
Definition: dialog.php:68
static nonEmptyString($var)
Definition: Metagen.php:258
$text
Definition: qrrender.php:27
$xoopsTpl
Definition: xoops_code.php:45
static assignTitle($title)
Definition: Metagen.php:43
const _XMF_STOPWORDS
Definition: stopwords.php:6
static asPlainText($rawText)
Definition: Metagen.php:341
static checkStopWords($key)
Definition: Metagen.php:168
static generateKeywords($body, $count=20, $minLength=4, $forceKeys=null)
Definition: Metagen.php:112
static assignDescription($description)
Definition: Metagen.php:88
static generateSeoTitle($title= '', $extension= '')
Definition: Metagen.php:273
static generateMetaTags($title, $body, $count=20, $minLength=4, $wordCount=100, $forceKeys=null)
Definition: Metagen.php:233
static assignKeywords($keywords)
Definition: Metagen.php:64
static generateDescription($body, $wordCount=100)
Definition: Metagen.php:197
static load($name, $domain= '', $language=null)
Definition: Language.php:54
$var
Definition: userinfo.php:125
$start
static getSearchSummary($haystack, $needles=null, $length=120)
Definition: Metagen.php:302