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
|
|
|
* @copyright The XUUPS Project http://sourceforge.net/projects/xuups/ |
13
|
|
|
* @license http://www.fsf.org/copyleft/gpl.html GNU public license |
14
|
|
|
* @package Publisher |
15
|
|
|
* @since 1.0 |
16
|
|
|
* @author trabis <[email protected]> |
17
|
|
|
* @author The SmartFactory <www.smartfactory.ca> |
18
|
|
|
*/ |
19
|
|
|
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined'); |
|
|
|
|
20
|
|
|
|
21
|
|
|
include_once dirname(__DIR__) . '/include/common.php'; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Class PublisherMetagen |
25
|
|
|
*/ |
26
|
|
|
class PublisherMetagen |
|
|
|
|
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* @var PublisherPublisher |
30
|
|
|
* @access public |
31
|
|
|
*/ |
32
|
|
|
public $publisher; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var MyTextSanitizer |
36
|
|
|
*/ |
37
|
|
|
public $myts; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var string |
41
|
|
|
*/ |
42
|
|
|
public $title; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
public $originalTitle; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var string |
51
|
|
|
*/ |
52
|
|
|
public $keywords; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @var string |
56
|
|
|
*/ |
57
|
|
|
public $categoryPath; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @var string |
61
|
|
|
*/ |
62
|
|
|
public $description; |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @var int |
66
|
|
|
* |
67
|
|
|
*/ |
68
|
|
|
public $minChar = 4; |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* @param string $title |
72
|
|
|
* @param string $keywords |
73
|
|
|
* @param string $description |
74
|
|
|
* @param string $categoryPath |
75
|
|
|
*/ |
76
|
|
|
public function __construct($title, $keywords = '', $description = '', $categoryPath = '') |
77
|
|
|
{ |
78
|
|
|
$this->publisher = PublisherPublisher::getInstance(); |
79
|
|
|
$this->myts = MyTextSanitizer::getInstance(); |
80
|
|
|
$this->setCategoryPath($categoryPath); |
81
|
|
|
$this->setTitle($title); |
82
|
|
|
$this->setDescription($description); |
83
|
|
|
if ($keywords == '') { |
84
|
|
|
$keywords = $this->createMetaKeywords(); |
85
|
|
|
} |
86
|
|
|
$this->setKeywords($keywords); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @param string $title |
91
|
|
|
*/ |
92
|
|
|
public function setTitle($title) |
93
|
|
|
{ |
94
|
|
|
$this->title = $this->html2text($title); |
95
|
|
|
$this->originalTitle = $this->title; |
96
|
|
|
$titleTag = array(); |
97
|
|
|
$titleTag['module'] = $this->publisher->getModule()->getVar('name'); |
|
|
|
|
98
|
|
|
if (isset($this->title) && ($this->title != '') && (strtoupper($this->title) != strtoupper($titleTag['module']))) { |
99
|
|
|
$titleTag['title'] = $this->title; |
100
|
|
|
} |
101
|
|
|
if (isset($this->categoryPath) && ($this->categoryPath != '')) { |
102
|
|
|
$titleTag['category'] = $this->categoryPath; |
103
|
|
|
} |
104
|
|
|
$ret = isset($titleTag['title']) ? $titleTag['title'] : ''; |
105
|
|
View Code Duplication |
if (isset($titleTag['category']) && $titleTag['category'] != '') { |
|
|
|
|
106
|
|
|
if ($ret != '') { |
107
|
|
|
$ret .= ' - '; |
108
|
|
|
} |
109
|
|
|
$ret .= $titleTag['category']; |
110
|
|
|
} |
111
|
|
View Code Duplication |
if (isset($titleTag['module']) && $titleTag['module'] != '') { |
|
|
|
|
112
|
|
|
if ($ret != '') { |
113
|
|
|
$ret .= ' - '; |
114
|
|
|
} |
115
|
|
|
$ret .= $titleTag['module']; |
116
|
|
|
} |
117
|
|
|
$this->title = $ret; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @param string $keywords |
122
|
|
|
*/ |
123
|
|
|
public function setKeywords($keywords) |
124
|
|
|
{ |
125
|
|
|
$this->keywords = $keywords; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @param string $categoryPath |
130
|
|
|
*/ |
131
|
|
|
public function setCategoryPath($categoryPath) |
132
|
|
|
{ |
133
|
|
|
$categoryPath = $this->html2text($categoryPath); |
134
|
|
|
$this->categoryPath = $categoryPath; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @param string $description |
139
|
|
|
*/ |
140
|
|
|
public function setDescription($description) |
141
|
|
|
{ |
142
|
|
|
$description = $this->html2text($description); |
143
|
|
|
$description = $this->purifyText($description); |
144
|
|
|
$this->description = $description; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Does nothing |
149
|
|
|
*/ |
150
|
|
|
public function createTitleTag() |
151
|
|
|
{ |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* @param int $maxWords |
156
|
|
|
* |
157
|
|
|
* @return string |
158
|
|
|
*/ |
159
|
|
|
public function createMetaDescription($maxWords = 30) |
|
|
|
|
160
|
|
|
{ |
161
|
|
|
$description = $this->purifyText($this->description); |
162
|
|
|
$description = $this->html2text($description); |
163
|
|
|
$words = explode(' ', $description); |
164
|
|
|
$ret = ''; |
165
|
|
|
$i = 1; |
166
|
|
|
$wordCount = count($words); |
167
|
|
|
foreach ($words as $word) { |
168
|
|
|
$ret .= $word; |
169
|
|
|
if ($i < $wordCount) { |
170
|
|
|
$ret .= ' '; |
171
|
|
|
} |
172
|
|
|
++$i; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
return $ret; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* @param string $text |
180
|
|
|
* @param int $minChar |
181
|
|
|
* |
182
|
|
|
* @return array |
183
|
|
|
*/ |
184
|
|
|
public function findMetaKeywords($text, $minChar) |
185
|
|
|
{ |
186
|
|
|
$keywords = array(); |
187
|
|
|
$text = $this->purifyText($text); |
188
|
|
|
$text = $this->html2text($text); |
189
|
|
|
$originalKeywords = explode(' ', $text); |
190
|
|
|
foreach ($originalKeywords as $originalKeyword) { |
191
|
|
|
$secondRoundKeywords = explode("'", $originalKeyword); |
192
|
|
|
foreach ($secondRoundKeywords as $secondRoundKeyword) { |
193
|
|
|
if (strlen($secondRoundKeyword) >= $minChar) { |
194
|
|
|
if (!in_array($secondRoundKeyword, $keywords)) { |
195
|
|
|
$keywords[] = trim($secondRoundKeyword); |
196
|
|
|
} |
197
|
|
|
} |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
return $keywords; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* @return string |
206
|
|
|
*/ |
207
|
|
|
public function createMetaKeywords() |
208
|
|
|
{ |
209
|
|
|
$keywords = $this->findMetaKeywords($this->originalTitle . ' ' . $this->description, $this->minChar); |
210
|
|
|
$moduleKeywords = $this->publisher->getConfig('seo_meta_keywords'); |
|
|
|
|
211
|
|
|
if ($moduleKeywords != '') { |
212
|
|
|
$moduleKeywords = explode(',', $moduleKeywords); |
213
|
|
|
$keywords = array_merge($keywords, array_map('trim', $moduleKeywords)); |
214
|
|
|
} |
215
|
|
|
$ret = implode(',', $keywords); |
216
|
|
|
|
217
|
|
|
return $ret; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Does nothing |
222
|
|
|
*/ |
223
|
|
|
public function autoBuildMetaKeywords() |
224
|
|
|
{ |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* Build Metatags |
229
|
|
|
*/ |
230
|
|
|
public function buildAutoMetaTags() |
231
|
|
|
{ |
232
|
|
|
$this->keywords = $this->createMetaKeywords(); |
233
|
|
|
$this->description = $this->createMetaDescription(); |
234
|
|
|
//$this->title = $this->createTitleTag(); |
|
|
|
|
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
/** |
238
|
|
|
* Creates meta tags |
239
|
|
|
*/ |
240
|
|
|
public function createMetaTags() |
241
|
|
|
{ |
242
|
|
|
global $xoopsTpl, $xoTheme; |
|
|
|
|
243
|
|
|
if ($this->keywords != '') { |
244
|
|
|
$xoTheme->addMeta('meta', 'keywords', $this->keywords); |
245
|
|
|
} |
246
|
|
|
if ($this->description != '') { |
247
|
|
|
$xoTheme->addMeta('meta', 'description', $this->description); |
248
|
|
|
} |
249
|
|
|
if ($this->title != '') { |
250
|
|
|
$xoopsTpl->assign('xoops_pagetitle', $this->title); |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Return true if the string is length > 0 |
256
|
|
|
* |
257
|
|
|
* @credit psylove |
258
|
|
|
* @var string $string Chaine de caractère |
259
|
|
|
* @return boolean |
260
|
|
|
*/ |
261
|
|
|
public function emptyString($var) |
262
|
|
|
{ |
263
|
|
|
return (strlen($var) > 0); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Create a title for the short_url field of an article |
268
|
|
|
* |
269
|
|
|
* @credit psylove |
270
|
|
|
* |
271
|
|
|
* @param string $title title of the article |
272
|
|
|
* @param bool $withExt do we add an html extension or not |
273
|
|
|
* |
274
|
|
|
* @return string short url for article |
275
|
|
|
*/ |
276
|
|
|
public static function generateSeoTitle($title = '', $withExt = true) |
277
|
|
|
{ |
278
|
|
|
// Transformation de la chaine en minuscule |
279
|
|
|
// Codage de la chaine afin d'éviter les erreurs 500 en cas de caractères imprévus |
280
|
|
|
$title = rawurlencode(strtolower($title)); |
281
|
|
|
// Transformation des ponctuations |
282
|
|
|
|
283
|
|
|
$pattern = array( |
284
|
|
|
'/%09/', // Tab |
285
|
|
|
'/%20/', // Space |
286
|
|
|
'/%21/', // ! |
287
|
|
|
'/%22/', // " |
288
|
|
|
'/%23/', // # |
289
|
|
|
'/%25/', // % |
290
|
|
|
'/%26/', // & |
291
|
|
|
'/%27/', // ' |
292
|
|
|
'/%28/', // ( |
293
|
|
|
'/%29/', // ) |
294
|
|
|
'/%2C/', // , |
295
|
|
|
'/%2F/', // / |
296
|
|
|
'/%3A/', // : |
297
|
|
|
'/%3B/', // ; |
298
|
|
|
'/%3C/', // < |
299
|
|
|
'/%3D/', // = |
300
|
|
|
'/%3E/', // > |
301
|
|
|
'/%3F/', // ? |
302
|
|
|
'/%40/', // @ |
303
|
|
|
'/%5B/', // [ |
304
|
|
|
'/%5C/', // \ |
305
|
|
|
'/%5D/', // ] |
306
|
|
|
'/%5E/', // ^ |
307
|
|
|
'/%7B/', // { |
308
|
|
|
'/%7C/', // | |
309
|
|
|
'/%7D/', // } |
310
|
|
|
'/%7E/', // ~ |
311
|
|
|
"/\./" // . |
312
|
|
|
); |
313
|
|
|
$repPat = array('-', '-', '-', '-', '-', '-100', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-at-', '-', '-', '-', '-', '-', '-', '-', '-', '-'); |
314
|
|
|
$title = preg_replace($pattern, $repPat, $title); |
315
|
|
|
// Transformation des caractères accentués |
316
|
|
|
// ° è é ê ë ç à â ä î ï ù ü û ô ö |
317
|
|
|
$pattern = array('/%B0/', '/%E8/', '/%E9/', '/%EA/', '/%EB/', '/%E7/', '/%E0/', '/%E2/', '/%E4/', '/%EE/', '/%EF/', '/%F9/', '/%FC/', '/%FB/', '/%F4/', '/%F6/'); |
318
|
|
|
$repPat = array('-', 'e', 'e', 'e', 'e', 'c', 'a', 'a', 'a', 'i', 'i', 'u', 'u', 'u', 'o', 'o'); |
319
|
|
|
$title = preg_replace($pattern, $repPat, $title); |
320
|
|
|
$tableau = explode('-', $title); // Transforme la chaine de caractères en tableau |
321
|
|
|
$tableau = array_filter($tableau, array('PublisherMetagen', 'emptyString')); // Supprime les chaines vides du tableau |
322
|
|
|
$title = implode('-', $tableau); // Transforme un tableau en chaine de caractères séparé par un tiret |
323
|
|
|
if (count($title) > 0) { |
324
|
|
|
if ($withExt) { |
325
|
|
|
$title .= '.html'; |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
return $title; |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
return ''; |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* @param $text |
336
|
|
|
* @param bool $keyword |
337
|
|
|
* |
338
|
|
|
* @return mixed |
339
|
|
|
*/ |
340
|
|
|
public function purifyText($text, $keyword = false) |
341
|
|
|
{ |
342
|
|
|
// $text = str_replace([' ', ' '], ['<br>', ' '], $text); //for php 5.4 |
|
|
|
|
343
|
|
|
$text = str_replace(' ', ' ', $text); |
344
|
|
|
$text = str_replace('<br>', ' ', $text); |
345
|
|
|
$text = strip_tags($text); |
346
|
|
|
$text = html_entity_decode($text); |
347
|
|
|
$text = $this->myts->undoHtmlSpecialChars($text); |
348
|
|
|
|
349
|
|
|
$text = str_replace(')', ' ', $text); |
350
|
|
|
$text = str_replace('(', ' ', $text); |
351
|
|
|
$text = str_replace(':', ' ', $text); |
352
|
|
|
$text = str_replace('&euro', ' euro ', $text); |
353
|
|
|
$text = str_replace('&hellip', '...', $text); |
354
|
|
|
$text = str_replace('&rsquo', ' ', $text); |
355
|
|
|
$text = str_replace('!', ' ', $text); |
356
|
|
|
$text = str_replace('?', ' ', $text); |
357
|
|
|
$text = str_replace('"', ' ', $text); |
358
|
|
|
$text = str_replace('-', ' ', $text); |
359
|
|
|
$text = str_replace('\n', ' ', $text); |
360
|
|
|
|
361
|
|
|
// $text = str_replace([')','(',':','&euro','&hellip','&rsquo','!','?','"','-','\n'], [' ' , ' ', ' ', ' euro ', '...', ' ', ' ', ' ', ' ', ' ', ' '], $text); //for PHP 5.4 |
|
|
|
|
362
|
|
|
|
363
|
|
|
if ($keyword) { |
364
|
|
|
$text = str_replace('.', ' ', $text); |
365
|
|
|
$text = str_replace(',', ' ', $text); |
366
|
|
|
$text = str_replace('\'', ' ', $text); |
367
|
|
|
// $text = str_replace(['.', ' '], [',', ' '], ['\'', ' '], $text); //for PHP 5.4 |
368
|
|
|
} |
369
|
|
|
$text = str_replace(';', ' ', $text); |
370
|
|
|
|
371
|
|
|
return $text; |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
/** |
375
|
|
|
* @param string $document |
376
|
|
|
* |
377
|
|
|
* @return mixed |
|
|
|
|
378
|
|
|
*/ |
379
|
|
View Code Duplication |
public function html2text($document) |
|
|
|
|
380
|
|
|
{ |
381
|
|
|
// PHP Manual:: function preg_replace |
382
|
|
|
// $document should contain an HTML document. |
383
|
|
|
// This will remove HTML tags, javascript sections |
384
|
|
|
// and white space. It will also convert some |
385
|
|
|
// common HTML entities to their text equivalent. |
386
|
|
|
// Credits : newbb2 |
387
|
|
|
$search = array( |
388
|
|
|
"'<script[^>]*?>.*?</script>'si", // Strip out javascript<?php |
389
|
|
|
"'<img.*?/>'si", // Strip out img tags |
390
|
|
|
"'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags<?php |
391
|
|
|
"'([\r\n])[\s]+'", // Strip out white space |
392
|
|
|
"'&(quot|#34);'i", // Replace HTML entities |
393
|
|
|
"'&(amp|#38);'i", |
394
|
|
|
"'&(lt|#60);'i", |
395
|
|
|
"'&(gt|#62);'i", |
396
|
|
|
"'&(nbsp|#160);'i", |
397
|
|
|
"'&(iexcl|#161);'i", |
398
|
|
|
"'&(cent|#162);'i", |
399
|
|
|
"'&(pound|#163);'i", |
400
|
|
|
"'&(copy|#169);'i",//"'&#(\d+);'e" |
401
|
|
|
); |
402
|
|
|
// evaluate as php |
403
|
|
|
$replace = array( |
404
|
|
|
'', |
405
|
|
|
'', |
406
|
|
|
'', |
407
|
|
|
"\\1", |
408
|
|
|
"\"", |
409
|
|
|
'&', |
410
|
|
|
'<', |
411
|
|
|
'>', |
412
|
|
|
' ', |
413
|
|
|
chr(161), |
414
|
|
|
chr(162), |
415
|
|
|
chr(163), |
416
|
|
|
chr(169),//"chr(\\1)" |
417
|
|
|
); |
418
|
|
|
$text = preg_replace($search, $replace, $document); |
419
|
|
|
|
420
|
|
|
return $text; |
421
|
|
|
} |
422
|
|
|
} |
423
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.