Passed
Branch master (294c87)
by Michael
02:12
created

Metagen   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 415
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 195
dl 0
loc 415
rs 8.96
c 0
b 0
f 0
wmc 43

16 Methods

Rating   Name   Duplication   Size   Complexity  
A html2text() 0 47 1
A createMetaKeywords() 0 11 2
A autoBuildMetaKeywords() 0 2 1
A emptyString() 0 3 1
C setTitle() 0 26 13
A findMetaKeywords() 0 18 5
A __construct() 0 12 2
A setKeywords() 0 3 1
A purifyText() 0 32 2
A setDescription() 0 5 1
A createMetaTags() 0 11 4
A setCategoryPath() 0 4 1
A createMetaDescription() 0 17 3
A buildAutoMetaTags() 0 4 1
A createTitleTag() 0 2 1
B generateSeoTitle() 0 72 4

How to fix   Complexity   

Complex Class

Complex classes like Metagen often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Metagen, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace XoopsModules\Publisher;
4
5
/*
6
 You may not change or alter any portion of this comment or credits
7
 of supporting developers from this source code or any supporting source code
8
 which is considered copyrighted (c) material of the original comment or credit authors.
9
10
 This program is distributed in the hope that it will be useful,
11
 but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * @copyright       The XUUPS Project http://sourceforge.net/projects/xuups/
17
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
18
 * @package         Publisher
19
 * @since           1.0
20
 * @author          trabis <[email protected]>
21
 * @author          The SmartFactory <www.smartfactory.ca>
22
 */
23
24
use XoopsModules\Publisher;
25
26
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
27
28
require_once dirname(__DIR__) . '/include/common.php';
29
30
/**
31
 * Class Metagen
32
 */
33
class Metagen
34
{
35
    /**
36
     * @var Publisher\Helper
37
     */
38
    public $helper;
39
40
    /**
41
     * @var \MyTextSanitizer
42
     */
43
    public $myts;
44
45
    /**
46
     * @var string
47
     */
48
    public $title;
49
50
    /**
51
     * @var string
52
     */
53
    public $originalTitle;
54
55
    /**
56
     * @var string
57
     */
58
    public $keywords;
59
60
    /**
61
     * @var string
62
     */
63
    public $categoryPath;
64
65
    /**
66
     * @var string
67
     */
68
    public $description;
69
70
    /**
71
     * @var int
72
     */
73
    public $minChar = 4;
74
75
    /**
76
     * @param string $title
77
     * @param string $keywords
78
     * @param string $description
79
     * @param string $categoryPath
80
     */
81
    public function __construct($title, $keywords = '', $description = '', $categoryPath = '')
82
    {
83
        /** @var Publisher\Helper $this->helper */
84
        $this->helper = \XoopsModules\Publisher\Helper::getInstance();
85
        $this->myts   = \MyTextSanitizer::getInstance();
86
        $this->setCategoryPath($categoryPath);
87
        $this->setTitle($title);
88
        $this->setDescription($description);
89
        if ('' == $keywords) {
90
            $keywords = $this->createMetaKeywords();
91
        }
92
        $this->setKeywords($keywords);
93
    }
94
95
    /**
96
     * @param string $title
97
     */
98
    public function setTitle($title)
99
    {
100
        $this->title         = $this->html2text($title);
101
        $this->originalTitle = $this->title;
102
        $titleTag            = [];
103
        $titleTag['module']  = $this->helper->getModule()->getVar('name');
104
        if (isset($this->title) && ('' != $this->title) && (mb_strtoupper($this->title) != mb_strtoupper($titleTag['module']))) {
0 ignored issues
show
Bug introduced by
It seems like $titleTag['module'] can also be of type array and array; however, parameter $str of mb_strtoupper() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
        if (isset($this->title) && ('' != $this->title) && (mb_strtoupper($this->title) != mb_strtoupper(/** @scrutinizer ignore-type */ $titleTag['module']))) {
Loading history...
105
            $titleTag['title'] = $this->title;
106
        }
107
        if (isset($this->categoryPath) && ('' != $this->categoryPath)) {
108
            $titleTag['category'] = $this->categoryPath;
109
        }
110
        $ret = isset($titleTag['title']) ? $titleTag['title'] : '';
111
        if (isset($titleTag['category']) && '' != $titleTag['category']) {
112
            if ('' != $ret) {
113
                $ret .= ' - ';
114
            }
115
            $ret .= $titleTag['category'];
116
        }
117
        if (isset($titleTag['module']) && '' != $titleTag['module']) {
118
            if ('' != $ret) {
119
                $ret .= ' - ';
120
            }
121
            $ret .= $titleTag['module'];
122
        }
123
        $this->title = $ret;
124
    }
125
126
    /**
127
     * @param string $keywords
128
     */
129
    public function setKeywords($keywords)
130
    {
131
        $this->keywords = $keywords;
132
    }
133
134
    /**
135
     * @param string $categoryPath
136
     */
137
    public function setCategoryPath($categoryPath)
138
    {
139
        $categoryPath       = $this->html2text($categoryPath);
140
        $this->categoryPath = $categoryPath;
141
    }
142
143
    /**
144
     * @param string $description
145
     */
146
    public function setDescription($description)
147
    {
148
        $description       = $this->html2text($description);
149
        $description       = $this->purifyText($description);
150
        $this->description = $description;
151
    }
152
153
    /**
154
     * Does nothing
155
     */
156
    public function createTitleTag()
157
    {
158
    }
159
160
    /**
161
     * @param int $maxWords
162
     *
163
     * @return string
164
     */
165
    public function createMetaDescription($maxWords = 30)
0 ignored issues
show
Unused Code introduced by
The parameter $maxWords is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

165
    public function createMetaDescription(/** @scrutinizer ignore-unused */ $maxWords = 30)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
166
    {
167
        $description = $this->purifyText($this->description);
168
        $description = $this->html2text($description);
169
        $words       = explode(' ', $description);
170
        $ret         = '';
171
        $i           = 1;
172
        $wordCount   = count($words);
173
        foreach ($words as $word) {
174
            $ret .= $word;
175
            if ($i < $wordCount) {
176
                $ret .= ' ';
177
            }
178
            ++$i;
179
        }
180
181
        return $ret;
182
    }
183
184
    /**
185
     * @param string $text
186
     * @param int    $minChar
187
     *
188
     * @return array
189
     */
190
    public function findMetaKeywords($text, $minChar)
191
    {
192
        $keywords         = [];
193
        $text             = $this->purifyText($text);
194
        $text             = $this->html2text($text);
195
        $originalKeywords = explode(' ', $text);
196
        foreach ($originalKeywords as $originalKeyword) {
197
            $secondRoundKeywords = explode("'", $originalKeyword);
198
            foreach ($secondRoundKeywords as $secondRoundKeyword) {
199
                if (mb_strlen($secondRoundKeyword) >= $minChar) {
200
                    if (!in_array($secondRoundKeyword, $keywords, true)) {
201
                        $keywords[] = trim($secondRoundKeyword);
202
                    }
203
                }
204
            }
205
        }
206
207
        return $keywords;
208
    }
209
210
    /**
211
     * @return string
212
     */
213
    public function createMetaKeywords()
214
    {
215
        $keywords       = $this->findMetaKeywords($this->originalTitle . ' ' . $this->description, $this->minChar);
216
        $moduleKeywords = $this->helper->getConfig('seo_meta_keywords');
217
        if ('' != $moduleKeywords) {
218
            $moduleKeywords = explode(',', $moduleKeywords);
219
            $keywords       = array_merge($keywords, array_map('trim', $moduleKeywords));
220
        }
221
        $ret = implode(',', $keywords);
222
223
        return $ret;
224
    }
225
226
    /**
227
     * Does nothing
228
     */
229
    public function autoBuildMetaKeywords()
230
    {
231
    }
232
233
    /**
234
     * Build Metatags
235
     */
236
    public function buildAutoMetaTags()
237
    {
238
        $this->keywords    = $this->createMetaKeywords();
239
        $this->description = $this->createMetaDescription();
240
        //$this->title = $this->createTitleTag();
241
    }
242
243
    /**
244
     * Creates meta tags
245
     */
246
    public function createMetaTags()
247
    {
248
        global $xoopsTpl, $xoTheme;
249
        if ('' != $this->keywords) {
250
            $xoTheme->addMeta('meta', 'keywords', $this->keywords);
251
        }
252
        if ('' != $this->description) {
253
            $xoTheme->addMeta('meta', 'description', $this->description);
254
        }
255
        if ('' != $this->title) {
256
            $xoopsTpl->assign('xoops_pagetitle', $this->title);
257
        }
258
    }
259
260
    /**
261
     * Return true if the string is length > 0
262
     *
263
     * @credit psylove
264
     * @param mixed $var
265
     * @return bool
266
     */
267
    public static function emptyString($var)
268
    {
269
        return ('' !== $var);
270
    }
271
272
    /**
273
     * Create a title for the short_url field of an article
274
     *
275
     * @credit psylove
276
     *
277
     * @param string|array $title   title of the article
278
     * @param bool   $withExt do we add an html extension or not
279
     *
280
     * @return string short url for article
281
     */
282
    public static function generateSeoTitle($title = '', $withExt = true)
283
    {
284
        // Transformation de la chaine en minuscule
285
        // Codage de la chaine afin d'éviter les erreurs 500 en cas de caractères imprévus
286
        $title = rawurlencode(mb_strtolower($title));
0 ignored issues
show
Bug introduced by
It seems like $title can also be of type array; however, parameter $str of mb_strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

286
        $title = rawurlencode(mb_strtolower(/** @scrutinizer ignore-type */ $title));
Loading history...
287
        // Transformation des ponctuations
288
289
        $pattern = [
290
            '/%09/', // Tab
291
            '/%20/', // Space
292
            '/%21/', // !
293
            '/%22/', // "
294
            '/%23/', // #
295
            '/%25/', // %
296
            '/%26/', // &
297
            '/%27/', // '
298
            '/%28/', // (
299
            '/%29/', // )
300
            '/%2C/', // ,
301
            '/%2F/', // /
302
            '/%3A/', // :
303
            '/%3B/', // ;
304
            '/%3C/', // <
305
            '/%3D/', // =
306
            '/%3E/', // >
307
            '/%3F/', // ?
308
            '/%40/', // @
309
            '/%5B/', // [
310
            '/%5C/', // \
311
            '/%5D/', // ]
312
            '/%5E/', // ^
313
            '/%7B/', // {
314
            '/%7C/', // |
315
            '/%7D/', // }
316
            '/%7E/', // ~
317
            "/\./", // .
318
        ];
319
        $repPat  = ['-', '-', '-', '-', '-', '-100', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-at-', '-', '-', '-', '-', '-', '-', '-', '-', '-'];
320
        $title   = str_replace($pattern, $repPat, $title);
321
        // Transformation des caractères accentués
322
        $pattern = [
323
            '/%B0/', // °
324
            '/%E8/', // è
325
            '/%E9/', // é
326
            '/%EA/', // ê
327
            '/%EB/', // ë
328
            '/%E7/', // ç
329
            '/%E0/', // à
330
            '/%E2/', // â
331
            '/%E4/', // ä
332
            '/%EE/', // î
333
            '/%EF/', // ï
334
            '/%F9/', // ù
335
            '/%FC/', // ü
336
            '/%FB/', // û
337
            '/%F4/', // ô
338
            '/%F6/', // ö
339
        ];
340
        $repPat  = ['-', 'e', 'e', 'e', 'e', 'c', 'a', 'a', 'a', 'i', 'i', 'u', 'u', 'u', 'o', 'o'];
341
        $title   = str_replace($pattern, $repPat, $title);
342
        $tableau = explode('-', $title); // Transforms the string in table //Transforme la chaine de caractères en tableau
343
        $tableau = array_filter($tableau, ['Metagen', 'emptyString']); // Remove empty strings of the table //Supprime les chaines vides du tableau
344
        $title   = implode('-', $tableau); // Transforms a character string in table separated by a hyphen //Transforme un tableau en chaine de caractères séparé par un tiret
345
        if ($title && is_array($title)) {
0 ignored issues
show
introduced by
The condition is_array($title) is always false.
Loading history...
346
            if ($withExt) {
347
                $title .= '.html';
348
            }
349
350
            return $title;
351
        }
352
353
        return '';
354
    }
355
356
    /**
357
     * @param      $text
358
     * @param bool $keyword
359
     *
360
     * @return mixed
361
     */
362
    public function purifyText($text, $keyword = false)
363
    {
364
        //        $text = str_replace(['&nbsp;', ' '], ['<br>', ' '], $text); //for php 5.4
365
        $text = str_replace('&nbsp;', ' ', $text);
366
        $text = str_replace('<br>', ' ', $text);
367
        $text = strip_tags($text);
368
        $text = html_entity_decode($text);
369
        $text = $this->myts->undoHtmlSpecialChars($text);
370
371
        $text = str_replace(')', ' ', $text);
372
        $text = str_replace('(', ' ', $text);
373
        $text = str_replace(':', ' ', $text);
374
        $text = str_replace('&euro', ' euro ', $text);
375
        $text = str_replace('&hellip', '...', $text);
376
        $text = str_replace('&rsquo', ' ', $text);
377
        $text = str_replace('!', ' ', $text);
378
        $text = str_replace('?', ' ', $text);
379
        $text = str_replace('"', ' ', $text);
380
        $text = str_replace('-', ' ', $text);
381
        $text = str_replace('\n', ' ', $text);
382
383
        //        $text = str_replace([')','(',':','&euro','&hellip','&rsquo','!','?','"','-','\n'], [' ' , ' ',  ' ',  ' euro ',  '...',  ' ', ' ', ' ',  ' ', ' ',  ' '], $text); //for PHP 5.4
384
385
        if ($keyword) {
386
            $text = str_replace('.', ' ', $text);
387
            $text = str_replace(',', ' ', $text);
388
            $text = str_replace('\'', ' ', $text);
389
            //            $text = str_replace(['.', ' '], [',', ' '], ['\'', ' '], $text); //for PHP 5.4
390
        }
391
        $text = str_replace(';', ' ', $text);
392
393
        return $text;
394
    }
395
396
    /**
397
     * @param string $document
398
     *
399
     * @return mixed
400
     */
401
    public function html2text($document)
402
    {
403
        // PHP Manual:: function preg_replace
404
        // $document should contain an HTML document.
405
        // This will remove HTML tags, javascript sections
406
        // and white space. It will also convert some
407
        // common HTML entities to their text equivalent.
408
        // Credits : newbb2
409
        $search = [
410
            "'<script[^>]*?>.*?</script>'si", // Strip out javascript
411
            "'<img.*?>'si", // Strip out img tags
412
            "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
413
            "'([\r\n])[\s]+'", // Strip out white space
414
            "'&(quot|#34);'i", // Replace HTML entities
415
            "'&(amp|#38);'i",
416
            "'&(lt|#60);'i",
417
            "'&(gt|#62);'i",
418
            "'&(nbsp|#160);'i",
419
            "'&(iexcl|#161);'i",
420
            "'&(cent|#162);'i",
421
            "'&(pound|#163);'i",
422
            "'&(copy|#169);'i",
423
        ]; // evaluate as php
424
425
        $replace = [
426
            '',
427
            '',
428
            '',
429
            '\\1',
430
            '"',
431
            '&',
432
            '<',
433
            '>',
434
            ' ',
435
            chr(161),
436
            chr(162),
437
            chr(163),
438
            chr(169),
439
        ];
440
441
        $text = preg_replace($search, $replace, $document);
442
443
        preg_replace_callback('/&#(\d+);/', function ($matches) {
444
            return chr($matches[1]);
445
        }, $document);
446
447
        return $text;
448
    }
449
}
450