MetaManipulator   F
last analyzed

Complexity

Total Complexity 105

Size/Duplication

Total Lines 800
Duplicated Lines 4 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 32
loc 800
rs 1.8
c 0
b 0
f 0
wmc 105
lcom 1
cbo 4

53 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 38 3
A getGrammens() 0 4 1
A getStorage() 0 4 1
A setStorage() 0 4 1
A __call() 0 8 3
A make() 0 21 4
B morphing() 0 42 8
B getGrammensWord() 18 27 8
A getTypeMany() 0 15 2
B getTypeSpeechWord() 0 20 6
B checkGrammar() 0 23 9
A setPhpMorphy() 0 4 1
A getPhpMorphy() 0 4 1
A getMorph() 0 7 3
A setMorph() 0 4 2
A transliteration() 0 6 1
A getBrand() 0 4 1
A setBrand() 0 4 1
A getCS() 0 7 2
A setCS() 0 4 1
A getCategory() 0 4 1
A setCategory() 0 4 1
A getDescLength() 0 3 1
A setDescLength() 0 8 3
A getDescription() 0 4 1
A setDescription() 0 12 2
A getModel() 0 4 1
A setModel() 0 4 1
A getID() 0 4 1
A setID() 0 4 1
A getMetaDescription() 0 4 1
A setMetaDescription() 0 4 1
A getMetaH1() 0 4 1
A setMetaH1() 0 4 1
A getMetaKeywords() 0 4 1
A setMetaKeywords() 0 4 1
A getMetaTitle() 0 4 1
A setMetaTitle() 0 4 1
A getName() 0 4 1
A setName() 0 4 1
A getPageNumber() 0 4 2
A setPageNumber() 0 4 1
A getNumber() 0 7 3
A setNumber() 0 4 1
A getPrice() 0 4 1
A setPrice() 0 4 1
B render() 14 36 6
A getWrapper() 0 4 1
A setWrapper() 0 4 1
A getMatching() 0 4 2
A setMatching() 0 4 1
A getMetaArray() 0 4 1
A setMetaArray() 0 8 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like MetaManipulator 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 MetaManipulator, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace CMSFactory\MetaManipulator;
4
5
use CI;
6
use CMSFactory\assetManager;
7
use Currency\Currency;
8
use Exception;
9
use phpMorphy;
10
use phpMorphy_Exception;
11
use phpMorphy_Paradigm_ParadigmInterface;
12
use phpMorphy_WordForm_WordFormInterface;
13
use SBrands;
14
use SCategory;
15
use SProducts;
16
17
/**
18
 * Class MetaManipulator
19
 * @package CMSFactory\MetaManipulator
20
 */
21
class MetaManipulator
22
{
23
    const META_TITLE = 1;
24
    const META_DESCRIPTION = 2;
25
    const META_KEYWORDS = 3;
26
    const META_H1 = 4;
27
28
    /**
29
     * Currency
30
     * @var string
31
     */
32
    protected $CS;
33
34
    /**
35
     * ID
36
     * @var string
37
     */
38
    protected $ID;
39
40
    /**
41
     * Brand
42
     * @var string
43
     */
44
    protected $brand;
45
46
    /**
47
     * Category
48
     * @var string
49
     */
50
    protected $category;
51
52
    /**
53
     * @var int
54
     */
55
    protected $descLength;
56
57
    /**
58
     * @var string
59
     */
60
    protected $description;
61
62
    /**
63
     * @var array
64
     */
65
    protected $matching = [];
66
67
    /**
68
     * @var array
69
     */
70
    protected $metaArray = [];
71
72
    /**
73
     * @var string
74
     */
75
    protected $metaDescription;
76
77
    /**
78
     * @var string
79
     */
80
    protected $metaH1;
81
82
    /**
83
     * @var string
84
     */
85
    protected $metaKeywords;
86
87
    /**
88
     * @var string
89
     */
90
    protected $metaTitle;
91
92
    /**
93
     * @var SCategory|SBrands|SProducts|array|null
94
     */
95
    protected $model;
96
97
    /**
98
     * @var array
99
     */
100
    protected $morph = [];
101
102
    /**
103
     * @var string
104
     */
105
    protected $name;
106
107
    /**
108
     * @var int
109
     */
110
    protected $number;
111
112
    /**
113
     * @var string
114
     */
115
    protected $pageNumber;
116
117
    /**
118
     * Price
119
     * @var string
120
     */
121
    protected $price;
122
123
    /**
124
     * @var MetaStorage
125
     */
126
    protected $storage;
127
128
    /**
129
     * @var string
130
     */
131
    protected $wrapper = '%';
132
133
    /**
134
     * @var array
135
     */
136
    private $grammens = [
137
                         'ИМ',
138
                         'РД',
139
                         'ДТ',
140
                         'ВН',
141
                         'ТВ',
142
                         'ПР',
143
                        ];
144
145
    /**
146
     * method processing meta data
147
     * @var phpMorphy
148
     */
149
    private $phpMorphy;
150
151
    /**
152
     * MetaManipulator constructor.
153
     * @param SBrands|SCategory|SProducts|array $model
154
     * @param MetaStorage $storage
155
     * @throws Exception
156
     */
157
    public function __construct($model, MetaStorage $storage) {
158
159
        $dir = APPPATH . 'modules/CMSFactory/MetaManipulator/dics';
160
161
        // set some options
162
        $opts = [
163
            // storage type, follow types supported
164
            // PHPMORPHY_STORAGE_FILE - use file operations(fread, fseek) for dictionary access, this is very slow...
165
            // PHPMORPHY_STORAGE_SHM - load dictionary in shared memory(using shmop php extension), this is preferred mode
166
            // PHPMORPHY_STORAGE_MEM - load dict to memory each time when phpMorphy initialized, this useful when shmop ext. not activated.
167
            //                          Speed same as for PHPMORPHY_STORAGE_SHM type
168
                 'storage'           => PHPMORPHY_STORAGE_MEM,
169
            // Enable prediction by suffix
170
171
                 'predict_by_suffix' => true,
172
                 'graminfo_as_text'  => true,
173
                ];
174
175
        $this->setPhpMorphy(new phpMorphy($dir, 'ru_RU', $opts));
176
177
        if ($model === null) {
178
            throw new Exception('Model not set');
179
        }
180
181
        if ($storage === null) {
182
            throw new Exception('Storage not set');
183
        }
184
185
        $this->setModel($model);
186
        $this->setStorage($storage);
187
        $this->setMetaTitle($this->getStorage()->getTitleTemplate());
188
        $this->setMetaDescription($this->getStorage()->getDescriptionTemplate());
189
        $this->setMetaKeywords($this->getStorage()->getKeywordsTemplate());
190
        $this->setMetaH1($this->getStorage()->getH1Template());
191
192
        $this->setMatching('desc', 'description');
193
        $this->setMetaArray(['metaTitle', 'metaH1', 'metaDescription', 'metaKeywords']);
194
    }
195
196
    /**
197
     * @return array
198
     */
199
    public function getGrammens() {
200
201
        return $this->grammens;
202
    }
203
204
    /**
205
     * @return MetaStorage
206
     */
207
    public function getStorage() {
208
209
        return $this->storage;
210
    }
211
212
    /**
213
     * @param MetaStorage $storage
214
     */
215
    public function setStorage($storage) {
216
217
        $this->storage = $storage;
218
    }
219
220
    /**
221
     * @param string $name
222
     * @param string $arguments
223
     * @return string
224
     */
225
    public function __call($name, $arguments) {
226
227
        $prev_string = $name;
228
        $method = substr($name, 0, strpos($name, '['));
229
        $string = method_exists(__CLASS__, $method) ? $this->$method() : '';
230
231
        return $string !== '' ? $this->make($string, $prev_string) : '';
232
    }
233
234
    /**
235
     * @param string $string
236
     * @param string $prev_string
237
     * @return null|string
238
     */
239
    public function make($string, $prev_string) {
240
241
        $return = $string;
242
243
        //morphing
244
        if (preg_match('/\[\d\]/', $prev_string, $match)) {
245
            $part = str_replace(['[', ']'], '', $match[0]);
246
            $words = explode(' ', $string);
247
            foreach ($words as $word) {
248
                $array[] = $this->morphing($word, $part);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$array was never initialized. Although not strictly required by PHP, it is generally a good practice to add $array = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
249
            }
250
            $return = implode(' ', $array);
251
        }
252
253
        //transliteration
254
        if (preg_match('/\[t\]/', $prev_string)) {
255
            $return = $this->transliteration($return);
256
        }
257
258
        return $return;
259
    }
260
261
    /**
262
     * @param string $string
263
     * @param int $part 1-6
264
     * @return string|null
265
     */
266
    protected function morphing($string, $part) {
267
268
        $ucFirst = false;
269
        //check if first letter is uppercase
270
        if (mb_strtolower($string) !== $string) {
271
            $ucFirst = true;
272
        }
273
274
        $word = mb_strtoupper($string);
275
276
        if (!array_key_exists($string, $this->morph)) {
277
            try {
278
279
                if (function_exists('iconv')) {
280
                    $word = iconv('utf-8', $this->getPhpMorphy()->getEncoding(), $word);
281
                }
282
                $collection = $this->getPhpMorphy()->findWord($word);
283
284
                if (false !== $collection) {
285
                    $param = $this->getTypeMany($word);
286
287
                    foreach ($collection->getByPartOfSpeech($param['TypeSpeech']) as $paradigm) {
288
289
                        $checkGrammar = $this->checkGrammar($paradigm, $param, $word);
290
291
                        $result = $this->getGrammensWord($paradigm, $param, $checkGrammar);
0 ignored issues
show
Documentation introduced by
$param is of type array<string,string|arra...,"TypeSpeech":"array"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
292
293
                        if ($result[0] == $word) {
294
                            break;
295
                        }
296
                    }
297
298
                    $this->setMorph($string, $result);
299
                }
300
                return $this->getMorph($string, $part, $ucFirst);
301
            } catch (phpMorphy_Exception $e) {
302
                die('Error occurred while creating phpMorphy instance: ' . PHP_EOL . $e->getMessage());
303
            }
304
        }
305
306
        return $this->getMorph($string, $part, $ucFirst);
307
    }
308
309
    /**
310
     * @param phpMorphy_Paradigm_ParadigmInterface $paradigm
311
     * @param string $param
312
     * @param null|string $grammar
313
     * @return array
314
     */
315
    private function getGrammensWord($paradigm, $param, $grammar = null) {
316
317
        $result = [];
318
        if ($grammar !== null) {
319
320 View Code Duplication
            foreach ($this->getGrammens() as $key => $val) {
321
322
                /** @var phpMorphy_WordForm_WordFormInterface $form */
323
                foreach ($paradigm->getWordFormsByGrammems([$param['param'], $val, $grammar]) as $form) {
0 ignored issues
show
Bug introduced by
The method getWordFormsByGrammems() does not exist on phpMorphy_Paradigm_ParadigmInterface. Did you maybe mean getWordForm()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
324
                    if (!$result[$key]) {
325
                        $result[$key] = $form->getWord();
326
                    }
327
                }
328
            }
329
        } else {
330 View Code Duplication
            foreach ($this->getGrammens() as $key => $val) {
331
332
                /** @var phpMorphy_WordForm_WordFormInterface $form */
333
                foreach ($paradigm->getWordFormsByGrammems([$param['param'], $val]) as $form) {
0 ignored issues
show
Bug introduced by
The method getWordFormsByGrammems() does not exist on phpMorphy_Paradigm_ParadigmInterface. Did you maybe mean getWordForm()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
334
                    if (!$result[$key]) {
335
                        $result[$key] = $form->getWord();
336
                    }
337
                }
338
            }
339
        }
340
        return $result;
341
    }
342
343
    /**
344
     * @param string $word
345
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
346
     */
347
    private function getTypeMany($word) {
348
349
        $checkString = $this->getPhpMorphy()->castFormByGramInfo($word, null, ['МН', 'ИМ'], true)[0];
350
351
        $param = ($word !== $checkString) ? 'ЕД' : 'МН';
352
353
        $typeSpeech = $this->getTypeSpeechWord($word, $param);
354
355
        $result = [
356
                   'param'      => $param,
357
                   'TypeSpeech' => $typeSpeech,
358
                  ];
359
360
        return $result;
361
    }
362
363
    /**
364
     * @param string $word
365
     * @param string $param
366
     * @return array
367
     */
368
    private function getTypeSpeechWord($word, $param) {
369
370
        $typeSpeech = $this->getPhpMorphy()->getPartOfSpeech($word);
371
        foreach ($typeSpeech as $type) {
372
            $checkGrammar[$type] = $this->getPhpMorphy()->castFormByGramInfo($word, $type, [$param, 'ИМ'], true);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$checkGrammar was never initialized. Although not strictly required by PHP, it is generally a good practice to add $checkGrammar = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
373
374
            foreach ($checkGrammar[$type] as $value) {
375
376
                if (empty($resultType)) {
377
                    $resultType = $word === $value ? $type : null;
378
                }
379
                if ($resultType) {
380
                    break 2;
381
                }
382
            }
383
        }
384
385
        return $resultType;
386
387
    }
388
389
    /**
390
     * @param phpMorphy_Paradigm_ParadigmInterface $paradigm
391
     * @param array $param
392
     * @param string $word
393
     * @return string|null
394
     */
395
    private function checkGrammar($paradigm, $param, $word) {
396
        /** @var phpMorphy_WordForm_WordFormInterface $form */
397
        foreach ($paradigm as $form) {
398
            foreach ($form->getGrammems() as $grammatical) {
399
                switch ($grammatical) {
400
                    case 'МР':
401
                    case 'ЖР':
402
                    case 'СР':
403
                        if (empty($checkGrammar)) {
404
405
                            $checkGrammar = ($word === $this->getPhpMorphy()->castFormByGramInfo($word, $param['TypeSpeech'], [$param['param'], 'ИМ', $grammatical], true)[0]) ? $grammatical : null;
406
                        }
407
                        if ($checkGrammar) {
408
                            continue;
409
                        }
410
411
                }
412
            }
413
        }
414
415
        return $checkGrammar;
416
417
    }
418
419
    /**
420
     * @param phpMorphy $phpMorphy
421
     */
422
    private function setPhpMorphy($phpMorphy) {
423
424
        $this->phpMorphy = $phpMorphy;
425
    }
426
427
    /**
428
     * @return phpMorphy
429
     */
430
    private function getPhpMorphy() {
431
432
        return $this->phpMorphy;
433
    }
434
435
    /**
436
     * @param string $string
437
     * @param integer $part
438
     * @param bool $ucFirst
439
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
440
     */
441
    public function getMorph($string, $part, $ucFirst = false) {
442
443
        if (array_key_exists(--$part, $this->morph[$string])) {
444
            $string = mb_strtolower($this->morph[$string][$part]);
445
        }
446
        return $ucFirst ? mb_strtoupper(mb_substr($string, 0, 1)) . mb_substr($string, 1) : $string;
447
    }
448
449
    /**
450
     * @param string $string
451
     * @param array $morph
452
     */
453
    public function setMorph($string, $morph) {
454
455
        $this->morph[$string] = $morph ?: $string;
456
    }
457
458
    /**
459
     * @param string $string
460
     * @return string
461
     */
462
    protected function transliteration($string = '') {
463
464
        CI::$APP->load->helper('translit');
465
466
        return translit($string);
467
    }
468
469
    /**
470
     * @return string
471
     */
472
    public function getBrand() {
473
474
        return $this->brand;
475
    }
476
477
    /**
478
     * @param string $brand
479
     */
480
    public function setBrand($brand) {
481
482
        $this->brand = $brand;
483
    }
484
485
    /**
486
     * @return string
487
     */
488
    public function getCS() {
489
490
        if (!$this->CS) {
491
            $this->setCS(Currency::create()->getSymbol());
492
        }
493
        return $this->CS;
494
    }
495
496
    /**
497
     * @param string $CS
498
     */
499
    public function setCS($CS) {
500
501
        $this->CS = $CS;
502
    }
503
504
    /**
505
     * @return string
506
     */
507
    public function getCategory() {
508
509
        return $this->category;
510
    }
511
512
    /**
513
     * @param string $category
514
     */
515
    public function setCategory($category) {
516
517
        $this->category = $category;
518
    }
519
520
    /**
521
     * @return int
522
     */
523
    public function getDescLength() {
524
        return $this->descLength;
525
    }
526
527
    /**
528
     * @param int $descLength
529
     */
530
    public function setDescLength($descLength) {
531
532
        if ($descLength === '') {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $descLength (integer) and '' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
533
            $this->descLength = 100;
534
        } elseif ((int) $descLength >= 0) {
535
            $this->descLength = (int) $descLength;
536
        }
537
    }
538
539
    /**
540
     * @return string
541
     */
542
    public function getDescription() {
543
544
        return $this->description;
545
    }
546
547
    /**
548
     * @param string $description
549
     */
550
    public function setDescription($description) {
551
552
        $description = strip_tags($description);
553
        $description = str_replace([PHP_EOL, '  '], ' ', $description);
554
        $description = rtrim($description, '!,.-:; ');
555
        if (mb_strlen($description) > $this->getDescLength()) {
556
            $description = mb_substr($description, 0, $this->getDescLength());
557
            $description = mb_substr($description, 0, mb_strrpos($description, ' '));
558
        }
559
560
        $this->description = $description;
561
    }
562
563
    /**
564
     * @return array|null|SBrands|SCategory|SProducts
565
     */
566
    public function getModel() {
567
568
        return $this->model;
569
    }
570
571
    /**
572
     * @param array|null|SBrands|SCategory|SProducts $model
573
     */
574
    public function setModel($model) {
575
576
        $this->model = $model;
577
    }
578
579
    /**
580
     * @return string
581
     */
582
    public function getID() {
583
584
        return $this->ID;
585
    }
586
587
    /**
588
     * @param string $ID
589
     */
590
    public function setID($ID) {
591
592
        $this->ID = $ID;
593
    }
594
595
    /**
596
     * @return string
597
     */
598
    public function getMetaDescription() {
599
600
        return $this->metaDescription;
601
    }
602
603
    /**
604
     * @param string $metaDescription
605
     */
606
    public function setMetaDescription($metaDescription) {
607
608
        $this->metaDescription = $metaDescription;
609
    }
610
611
    /**
612
     * @return string
613
     */
614
    public function getMetaH1() {
615
616
        return $this->metaH1;
617
    }
618
619
    /**
620
     * @param string $metaH1
621
     */
622
    public function setMetaH1($metaH1) {
623
624
        $this->metaH1 = $metaH1;
625
    }
626
627
    /**
628
     * @return string
629
     */
630
    public function getMetaKeywords() {
631
632
        return $this->metaKeywords;
633
    }
634
635
    /**
636
     * @param string $metaKeywords
637
     */
638
    public function setMetaKeywords($metaKeywords) {
639
640
        $this->metaKeywords = $metaKeywords;
641
    }
642
643
    /**
644
     * @return string
645
     */
646
    public function getMetaTitle() {
647
648
        return $this->metaTitle;
649
    }
650
651
    /**
652
     * @param string $metaTitle
653
     */
654
    public function setMetaTitle($metaTitle) {
655
656
        $this->metaTitle = $metaTitle;
657
    }
658
659
    /**
660
     * @return string
661
     */
662
    public function getName() {
663
664
        return $this->name;
665
    }
666
667
    /**
668
     * @param string $name
669
     */
670
    public function setName($name) {
671
672
        $this->name = $name;
673
    }
674
675
    /**
676
     * @return string
677
     */
678
    public function getPageNumber() {
679
680
        return $this->getNumber() ? str_replace('%number%', $this->getNumber(), $this->pageNumber) : '';
681
    }
682
683
    /**
684
     * @param string $pageNumber
685
     */
686
    public function setPageNumber($pageNumber) {
687
688
        $this->pageNumber = $pageNumber;
689
    }
690
691
    /**
692
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
693
     */
694
    public function getNumber() {
695
696
        if (!$this->number) {
697
            $this->setNumber(assetManager::create()->getData('page_number'));
698
        }
699
        return (int) $this->number > 1 ? (int) $this->number : '';
700
    }
701
702
    /**
703
     * @param string $number
704
     */
705
    public function setNumber($number) {
706
707
        $this->number = $number;
0 ignored issues
show
Documentation Bug introduced by
The property $number was declared of type integer, but $number is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
708
    }
709
710
    /**
711
     * @return string
712
     */
713
    public function getPrice() {
714
715
        return $this->price;
716
    }
717
718
    /**
719
     * @param string $price
720
     */
721
    public function setPrice($price) {
722
723
        $this->price = $price;
724
    }
725
726
    /**
727
     * @return array<String>
728
     */
729
    public function render() {
730
731
        $return = [];
732
        /** @var string $w wrapper */
733
        $w = $this->getWrapper();
734
        $vars = $this->getStorage()->getVars();
735
        if ($vars !== []) {
736
            foreach ($vars as $var) {
737
                $method = $this->getMatching($var) ?: $var;
738
                $method = "get$method";
739
740
                $replace = $this->$method();
741
                $search = $w . $var . $w;
742
743 View Code Duplication
                foreach ($this->getMetaArray() as $metaName) {
744
                    $get = "get$metaName";
745
                    $set = "set$metaName";
746
747
                    $return[$metaName] = str_replace($search, $replace, trim($this->$get()));
748
                    $this->$set($return[$metaName]);
749
                }
750
            }
751
        } else {
752 View Code Duplication
            foreach ($this->getMetaArray() as $metaName) {
753
                $get = "get$metaName";
754
                $set = "set$metaName";
755
756
                $return[$metaName] = trim($this->$get());
757
                $this->$set($return[$metaName]);
758
            }
759
760
        }
761
762
        return $return;
763
764
    }
765
766
    /**
767
     * @return string
768
     */
769
    public function getWrapper() {
770
771
        return $this->wrapper;
772
    }
773
774
    /**
775
     * @param string $wrapper
776
     */
777
    public function setWrapper($wrapper) {
778
779
        $this->wrapper = $wrapper;
780
    }
781
782
    /**
783
     * @param string $key
784
     * @return bool|array
785
     */
786
    public function getMatching($key) {
787
788
        return array_key_exists($key, $this->matching) ? $this->matching[$key] : false;
789
    }
790
791
    /**
792
     * @param string $key
793
     * @param string $value
794
     */
795
    public function setMatching($key, $value) {
796
797
        $this->matching[$key] = $value;
798
    }
799
800
    /**
801
     * @return array
802
     */
803
    public function getMetaArray() {
804
805
        return $this->metaArray;
806
    }
807
808
    /**
809
     * @param array $metaArray
810
     */
811
    public function setMetaArray($metaArray) {
812
813
        foreach ($metaArray as $item) {
814
            $this->metaArray[] = $item;
815
        }
816
817
        $this->metaArray = array_unique($this->metaArray);
818
    }
819
820
}