1
|
|
|
<?php namespace XoopsModules\Smartobject; |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Containing the class to manage meta informations of the SmartObject framework |
5
|
|
|
* |
6
|
|
|
* @license GNU |
7
|
|
|
* @author marcan <[email protected]> |
8
|
|
|
* @link http://smartfactory.ca The SmartFactory |
9
|
|
|
* @package SmartObject |
10
|
|
|
* @subpackage SmartObjectCore |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
use XoopsModules\Smartobject; |
14
|
|
|
|
15
|
|
|
// defined('XOOPS_ROOT_PATH') || die('Restricted access'); |
|
|
|
|
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Class MetaGen is a class providing some methods to dynamically and automatically customize Meta Tags information |
19
|
|
|
* @author The SmartFactory <www.smartfactory.ca> |
20
|
|
|
*/ |
21
|
|
|
class MetaGen |
22
|
|
|
{ |
23
|
|
|
public $_myts; |
24
|
|
|
|
25
|
|
|
public $_title; |
26
|
|
|
public $_original_title; |
27
|
|
|
public $_keywords; |
28
|
|
|
public $_meta_description; |
29
|
|
|
public $_categoryPath; |
30
|
|
|
public $_description; |
31
|
|
|
public $_minChar = 4; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* SmartMetaGen constructor. |
35
|
|
|
* @param $title |
36
|
|
|
* @param bool $keywords |
37
|
|
|
* @param bool $description |
38
|
|
|
* @param bool $categoryPath |
39
|
|
|
*/ |
40
|
|
|
public function __construct($title, $keywords = false, $description = false, $categoryPath = false) |
41
|
|
|
{ |
42
|
|
|
$this->_myts = \MyTextSanitizer::getInstance(); |
43
|
|
|
$this->setCategoryPath($categoryPath); |
44
|
|
|
$this->setTitle($title); |
45
|
|
|
$this->setDescription($description); |
46
|
|
|
|
47
|
|
|
if (!$keywords) { |
48
|
|
|
$keywords = $this->createMetaKeywords(); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/* $myts = \MyTextSanitizer::getInstance(); |
|
|
|
|
52
|
|
|
if (method_exists($myts, 'formatForML')) { |
53
|
|
|
$keywords = $myts->formatForML($keywords); |
54
|
|
|
$description = $myts->formatForML($description); |
55
|
|
|
} |
56
|
|
|
*/ |
57
|
|
|
$this->setKeywords($keywords); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Return true if the string is length > 0 |
62
|
|
|
* |
63
|
|
|
* @credit psylove |
64
|
|
|
* |
65
|
|
|
* @var string $string Chaine de caract�re |
66
|
|
|
* @return boolean |
67
|
|
|
*/ |
68
|
|
|
public function emptyString($var) |
69
|
|
|
{ |
70
|
|
|
return (strlen($var) > 0); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Create a title for the short_url field of an article |
75
|
|
|
* |
76
|
|
|
* @credit psylove |
77
|
|
|
* |
78
|
|
|
* @var string $title title of the article |
79
|
|
|
* @param bool|string $withExt |
80
|
|
|
* @return string sort_url for the article |
81
|
|
|
*/ |
82
|
|
|
public function generateSeoTitle($title = '', $withExt = true) |
83
|
|
|
{ |
84
|
|
|
// Transformation de la chaine en minuscule |
85
|
|
|
// Codage de la chaine afin d'éviter les erreurs 500 en cas de caractères imprévus |
86
|
|
|
$title = rawurlencode(strtolower($title)); |
87
|
|
|
|
88
|
|
|
// Transformation des ponctuations |
89
|
|
|
$pattern = [ |
90
|
|
|
'/%09/', // Tab |
91
|
|
|
'/%20/', // Space |
92
|
|
|
'/%21/', // ! |
93
|
|
|
'/%22/', // " |
94
|
|
|
'/%23/', // # |
95
|
|
|
'/%25/', // % |
96
|
|
|
'/%26/', // & |
97
|
|
|
'/%27/', // ' |
98
|
|
|
'/%28/', // ( |
99
|
|
|
'/%29/', // ) |
100
|
|
|
'/%2C/', // , |
101
|
|
|
'/%2F/', // / |
102
|
|
|
'/%3A/', // : |
103
|
|
|
'/%3B/', // ; |
104
|
|
|
'/%3C/', // < |
105
|
|
|
'/%3D/', // = |
106
|
|
|
'/%3E/', // > |
107
|
|
|
'/%3F/', // ? |
108
|
|
|
'/%40/', // @ |
109
|
|
|
'/%5B/', // [ |
110
|
|
|
'/%5C/', // \ |
111
|
|
|
'/%5D/', // ] |
112
|
|
|
'/%5E/', // ^ |
113
|
|
|
'/%7B/', // { |
114
|
|
|
'/%7C/', // | |
115
|
|
|
'/%7D/', // } |
116
|
|
|
'/%7E/', // ~ |
117
|
|
|
"/\./" // . |
118
|
|
|
]; |
119
|
|
|
$rep_pat = [ |
120
|
|
|
'-', |
121
|
|
|
'-', |
122
|
|
|
'-', |
123
|
|
|
'-', |
124
|
|
|
'-', |
125
|
|
|
'-100', |
126
|
|
|
'-', |
127
|
|
|
'-', |
128
|
|
|
'-', |
129
|
|
|
'-', |
130
|
|
|
'-', |
131
|
|
|
'-', |
132
|
|
|
'-', |
133
|
|
|
'-', |
134
|
|
|
'-', |
135
|
|
|
'-', |
136
|
|
|
'-', |
137
|
|
|
'-', |
138
|
|
|
'-at-', |
139
|
|
|
'-', |
140
|
|
|
'-', |
141
|
|
|
'-', |
142
|
|
|
'-', |
143
|
|
|
'-', |
144
|
|
|
'-', |
145
|
|
|
'-', |
146
|
|
|
'-', |
147
|
|
|
'-' |
148
|
|
|
]; |
149
|
|
|
$title = preg_replace($pattern, $rep_pat, $title); |
150
|
|
|
|
151
|
|
|
// Transformation des caractères accentués |
152
|
|
|
$pattern = [ |
153
|
|
|
'/%B0/', // ° |
154
|
|
|
'/%E8/', // è |
155
|
|
|
'/%E9/', // é |
156
|
|
|
'/%EA/', // ê |
157
|
|
|
'/%EB/', // ë |
158
|
|
|
'/%E7/', // ç |
159
|
|
|
'/%E0/', // à |
160
|
|
|
'/%E2/', // â |
161
|
|
|
'/%E4/', // ä |
162
|
|
|
'/%EE/', // î |
163
|
|
|
'/%EF/', // ï |
164
|
|
|
'/%F9/', // ù |
165
|
|
|
'/%FC/', // ü |
166
|
|
|
'/%FB/', // û |
167
|
|
|
'/%F4/', // ô |
168
|
|
|
'/%F6/', // ö |
169
|
|
|
]; |
170
|
|
|
$rep_pat = ['-', 'e', 'e', 'e', 'e', 'c', 'a', 'a', 'a', 'i', 'i', 'u', 'u', 'u', 'o', 'o']; |
171
|
|
|
$title = preg_replace($pattern, $rep_pat, $title); |
172
|
|
|
|
173
|
|
|
$tableau = explode('-', $title); // Transforme la chaine de caract�res en tableau |
174
|
|
|
$tableau = array_filter($tableau, [$this, 'emptyString']); // Supprime les chaines vides du tableau |
175
|
|
|
$title = implode('-', $tableau); // Transforme un tableau en chaine de caract�res s�par� par un tiret |
176
|
|
|
|
177
|
|
|
if (count($title) > 0) { |
178
|
|
|
if ($withExt) { |
179
|
|
|
$title .= '.html'; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
return $title; |
183
|
|
|
} else { |
184
|
|
|
return ''; |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* @param $document |
190
|
|
|
* @return mixed |
191
|
|
|
*/ |
192
|
|
|
public function html2text($document) |
193
|
|
|
{ |
194
|
|
|
return Smartobject\Utility::getHtml2text($document); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @param $title |
199
|
|
|
*/ |
200
|
|
|
public function setTitle($title) |
201
|
|
|
{ |
202
|
|
|
global $xoopsModule, $xoopsModuleConfig; |
203
|
|
|
$this->_title = $this->html2text($title); |
204
|
|
|
$this->_title = $this->purifyText($this->_title); |
205
|
|
|
$this->_original_title = $this->_title; |
206
|
|
|
|
207
|
|
|
$moduleName = $xoopsModule->getVar('name'); |
208
|
|
|
|
209
|
|
|
$titleTag = []; |
210
|
|
|
|
211
|
|
|
$show_mod_name_breadcrumb = isset($xoopsModuleConfig['show_mod_name_breadcrumb']) ? $xoopsModuleConfig['show_mod_name_breadcrumb'] : true; |
212
|
|
|
|
213
|
|
|
if ($moduleName && $show_mod_name_breadcrumb) { |
214
|
|
|
$titleTag['module'] = $moduleName; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
if (isset($this->_title) && ('' !== $this->_title) && (strtoupper($this->_title) != strtoupper($moduleName))) { |
218
|
|
|
$titleTag['title'] = $this->_title; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
if (isset($this->_categoryPath) && ('' !== $this->_categoryPath)) { |
222
|
|
|
$titleTag['category'] = $this->_categoryPath; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
$ret = isset($titleTag['title']) ? $titleTag['title'] : ''; |
226
|
|
|
|
227
|
|
View Code Duplication |
if (isset($titleTag['category']) && '' !== $titleTag['category']) { |
|
|
|
|
228
|
|
|
if ('' !== $ret) { |
229
|
|
|
$ret .= ' - '; |
230
|
|
|
} |
231
|
|
|
$ret .= $titleTag['category']; |
232
|
|
|
} |
233
|
|
View Code Duplication |
if (isset($titleTag['module']) && '' !== $titleTag['module']) { |
|
|
|
|
234
|
|
|
if ('' !== $ret) { |
235
|
|
|
$ret .= ' - '; |
236
|
|
|
} |
237
|
|
|
$ret .= $titleTag['module']; |
238
|
|
|
} |
239
|
|
|
$this->_title = $ret; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* @param $keywords |
244
|
|
|
*/ |
245
|
|
|
public function setKeywords($keywords) |
246
|
|
|
{ |
247
|
|
|
$this->_keywords = $keywords; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* @param $categoryPath |
252
|
|
|
*/ |
253
|
|
|
public function setCategoryPath($categoryPath) |
254
|
|
|
{ |
255
|
|
|
$categoryPath = $this->html2text($categoryPath); |
256
|
|
|
$this->_categoryPath = $categoryPath; |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @param $description |
261
|
|
|
*/ |
262
|
|
|
public function setDescription($description) |
263
|
|
|
{ |
264
|
|
|
if (!$description) { |
265
|
|
|
global $xoopsModuleConfig; |
266
|
|
|
if (isset($xoopsModuleConfig['module_meta_description'])) { |
267
|
|
|
$description = $xoopsModuleConfig['module_meta_description']; |
268
|
|
|
} |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
$description = $this->html2text($description); |
272
|
|
|
$description = $this->purifyText($description); |
273
|
|
|
|
274
|
|
|
$description = preg_replace("/([^\r\n])\r\n([^\r\n])/", "\\1 \\2", $description); |
275
|
|
|
$description = preg_replace("/[\r\n]*\r\n[\r\n]*/", "\r\n\r\n", $description); |
276
|
|
|
$description = preg_replace('/[ ]* [ ]*/', ' ', $description); |
277
|
|
|
$description = stripslashes($description); |
278
|
|
|
|
279
|
|
|
$this->_description = $description; |
280
|
|
|
$this->_meta_description = $this->createMetaDescription(); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
public function createTitleTag() |
284
|
|
|
{ |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* @param $text |
289
|
|
|
* @param bool $keyword |
290
|
|
|
* @return mixed|string |
291
|
|
|
*/ |
292
|
|
|
public function purifyText($text, $keyword = false) |
293
|
|
|
{ |
294
|
|
|
return Smartobject\Utility::purifyText($text, $keyword); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* @param int $maxWords |
299
|
|
|
* @return string |
300
|
|
|
*/ |
301
|
|
|
public function createMetaDescription($maxWords = 100) |
302
|
|
|
{ |
303
|
|
|
$words = []; |
|
|
|
|
304
|
|
|
$words = explode(' ', $this->_description); |
305
|
|
|
|
306
|
|
|
// Only keep $maxWords words |
307
|
|
|
$newWords = []; |
308
|
|
|
$i = 0; |
309
|
|
|
|
310
|
|
|
while ($i < $maxWords - 1 && $i < count($words)) { |
311
|
|
|
$newWords[] = $words[$i]; |
312
|
|
|
++$i; |
313
|
|
|
} |
314
|
|
|
$ret = implode(' ', $newWords); |
315
|
|
|
|
316
|
|
|
return $ret; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* @param $text |
321
|
|
|
* @param $minChar |
322
|
|
|
* @return array |
323
|
|
|
*/ |
324
|
|
|
public function findMetaKeywords($text, $minChar) |
325
|
|
|
{ |
326
|
|
|
$keywords = []; |
327
|
|
|
|
328
|
|
|
$text = $this->purifyText($text); |
329
|
|
|
$text = $this->html2text($text); |
330
|
|
|
|
331
|
|
|
$text = preg_replace("/([^\r\n])\r\n([^\r\n])/", "\\1 \\2", $text); |
332
|
|
|
$text = preg_replace("/[\r\n]*\r\n[\r\n]*/", "\r\n\r\n", $text); |
333
|
|
|
$text = preg_replace('/[ ]* [ ]*/', ' ', $text); |
334
|
|
|
$text = stripslashes($text); |
335
|
|
|
$text = |
|
|
|
|
336
|
|
|
|
337
|
|
|
$originalKeywords = preg_split('/[^a-zA-Z\'"-]+/', $text, -1, PREG_SPLIT_NO_EMPTY); |
338
|
|
|
|
339
|
|
|
foreach ($originalKeywords as $originalKeyword) { |
340
|
|
|
$secondRoundKeywords = explode("'", $originalKeyword); |
341
|
|
|
foreach ($secondRoundKeywords as $secondRoundKeyword) { |
342
|
|
|
if (strlen($secondRoundKeyword) >= $minChar) { |
343
|
|
|
if (!in_array($secondRoundKeyword, $keywords)) { |
344
|
|
|
$keywords[] = trim($secondRoundKeyword); |
345
|
|
|
} |
346
|
|
|
} |
347
|
|
|
} |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
return $keywords; |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
/** |
354
|
|
|
* @return string |
355
|
|
|
*/ |
356
|
|
|
public function createMetaKeywords() |
357
|
|
|
{ |
358
|
|
|
global $xoopsModuleConfig; |
359
|
|
|
$keywords = $this->findMetaKeywords($this->_original_title . ' ' . $this->_description, $this->_minChar); |
360
|
|
|
if (isset($xoopsModuleConfig) && isset($xoopsModuleConfig['moduleMetaKeywords']) |
361
|
|
|
&& '' !== $xoopsModuleConfig['moduleMetaKeywords']) { |
362
|
|
|
$moduleKeywords = explode(',', $xoopsModuleConfig['moduleMetaKeywords']); |
363
|
|
|
$keywords = array_merge($keywords, $moduleKeywords); |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
/* Commenting this out as it may cause problem on XOOPS ML websites |
|
|
|
|
367
|
|
|
$return_keywords = array(); |
368
|
|
|
|
369
|
|
|
// Cleaning for duplicate keywords |
370
|
|
|
foreach ($keywords as $keyword) { |
371
|
|
|
if (!in_array($keyword, $keywords)) { |
372
|
|
|
$return_keywords[] = trim($keyword); |
373
|
|
|
} |
374
|
|
|
}*/ |
375
|
|
|
|
376
|
|
|
// Only take the first 90 keywords |
377
|
|
|
$newKeywords = []; |
378
|
|
|
$i = 0; |
379
|
|
|
while ($i < 90 - 1 && isset($keywords[$i])) { |
380
|
|
|
$newKeywords[] = $keywords[$i]; |
381
|
|
|
++$i; |
382
|
|
|
} |
383
|
|
|
$ret = implode(', ', $newKeywords); |
384
|
|
|
|
385
|
|
|
return $ret; |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
public function autoBuildMeta_keywords() |
389
|
|
|
{ |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
public function buildAutoMetaTags() |
393
|
|
|
{ |
394
|
|
|
global $xoopsModule, $xoopsModuleConfig; |
395
|
|
|
|
396
|
|
|
$this->_keywords = $this->createMetaKeywords(); |
397
|
|
|
$this->_meta_description = $this->createMetaDescription(); |
398
|
|
|
$this->_title = $this->createTitleTag(); |
|
|
|
|
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
public function createMetaTags() |
402
|
|
|
{ |
403
|
|
|
global $xoopsTpl, $xoTheme; |
404
|
|
|
|
405
|
|
|
if (is_object($xoTheme)) { |
406
|
|
|
$xoTheme->addMeta('meta', 'keywords', $this->_keywords); |
407
|
|
|
$xoTheme->addMeta('meta', 'description', $this->_description); |
408
|
|
|
$xoTheme->addMeta('meta', 'title', $this->_title); |
409
|
|
|
} else { |
410
|
|
|
$xoopsTpl->assign('xoops_meta_keywords', $this->_keywords); |
411
|
|
|
$xoopsTpl->assign('xoops_meta_description', $this->_description); |
412
|
|
|
} |
413
|
|
|
$xoopsTpl->assign('xoops_pagetitle', $this->_title); |
414
|
|
|
} |
415
|
|
|
} |
416
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.