Passed
Push — master ( d9b23e...c2fe70 )
by Arthur
01:41
created

Words::replace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace detox\core;
4
5
6
use detox\dataset\SetContract;
7
use detox\source\Text;
8
9
/**
10
 * Class Words
11
 * @package detox\core
12
 *
13
 * @property Text text
14
 */
15
class Words
16
{
17
18
    public const MAX_SCORE        = 1;
19
    public const ASTERISKS_MIDDLE = 0.8;
20
    public const ASTERISKS_LEFT   = 0.5;
21
    public const ASTERISKS_RIGHT  = 0.6;
22
23
    protected $dataSet;
24
    protected $score = 0;
25
    protected $text;
26
27
    /**
28
     * Words constructor.
29
     *
30
     * @param SetContract $set
31
     * @param Text $text
32
     */
33
    public function __construct(SetContract $set, Text $text)
34
    {
35
        $this->dataSet = $set;
36
        $this->text    = $text;
37
    }
38
39
    /**
40
     * Finds bad words from *Set and setting score/replace
41
     */
42
    public function processWords() : void
43
    {
44
        // to match lower case letters in words set array
45
        $lowerSource = $this->addLowSpaces($this->text->getString());
46
        /**
47
         * @var string $points
48
         * @var array $words
49
         */
50
        foreach ($this->dataSet->getWords() as $points => $words) {
51
            foreach ($words as $word) {
52
                if (mb_strpos($lowerSource, ' ' . $word . ' ') !== false) {
53
                    $this->score += (float)$points;
54
                    if ($this->text->isReplaceable()) {
55
                        $this->replace($word);
56
                    }
57
                }
58
            }
59
        }
60
        if ($this->score >= self::MAX_SCORE) {
61
            $this->score = self::MAX_SCORE;
62
        }
63
    }
64
65
    /**
66
     * Finds bad words with asterisks and setting score/replace
67
     */
68
    public function processPatterns() : void
69
    {
70
        $lowerSource = $this->addLowSpaces($this->text->getString());
71
        if (preg_match_all('/\s(([\w]+)[\*]+([\w]+))\s/', $lowerSource, $matches) > 0) {
72
            $this->score += (self::ASTERISKS_MIDDLE * count($matches[0]));
73
            if ($this->text->isReplaceable()) {
74
                $this->replaceMatches($matches);
75
            }
76
        }
77
        $lowerSource = $this->addLowSpaces($this->text->getString());
78
        if (preg_match_all('/\s(([\w]+)[\*]+)\s/', $lowerSource, $matches) > 0) {
79
            $this->score += (self::ASTERISKS_RIGHT * count($matches[0]));
80
            if ($this->text->isReplaceable()) {
81
                $this->replaceMatches($matches);
82
            }
83
        }
84
        $lowerSource = $this->addLowSpaces($this->text->getString());
85
        if (preg_match_all('/\s([\*]+([\w]+))\s/', $lowerSource, $matches) > 0) {
86
            $this->score += (self::ASTERISKS_LEFT * count($matches[0]));
87
            if ($this->text->isReplaceable()) {
88
                $this->replaceMatches($matches);
89
            }
90
        }
91
    }
92
93
    /**
94
     * @param SetContract $set
95
     */
96
    public function setData(SetContract $set) : void
97
    {
98
        $this->dataSet = $set;
99
    }
100
101
    /**
102
     * @return float
103
     */
104
    public function getScore() : float
105
    {
106
        return $this->score;
107
    }
108
109
    /**
110
     * @param float $score
111
     */
112
    public function setScore(float $score) : void
113
    {
114
        $this->score = $score;
115
    }
116
117
    /**
118
     * @param string $str
119
     * @return string
120
     */
121
    protected function addLowSpaces(string $str) : string
122
    {
123
        return ' ' . mb_strtolower($str) . ' ';
124
    }
125
126
    /**
127
     * @param string $phrase word or phrase to replace
128
     */
129
    protected function replace(string $phrase) : void
130
    {
131
        // todo: slice the word with replacement to prevent WoRd -> word transformations
132
        $this->text->setString(str_replace($phrase, $this->text->getPrefix() . $this->text->getReplaceChars() . $this->text->getPostfix(),
133
            mb_strtolower($this->text->getString())));
134
    }
135
136
    private function replaceMatches(array $matches) : void
137
    {
138
        /** @var array $matches */
139
        foreach ($matches[0] as $word) {
140
            $this->replace($word);
141
        }
142
    }
143
144
    /**
145
     * Setter for convenient DI with Text object and it's properties
146
     * @param Text $text
147
     */
148
    public function setText(Text $text) : void
149
    {
150
        $this->text = $text;
151
    }
152
153
    /**
154
     * @return Text
155
     */
156
    public function getText() : Text
157
    {
158
        return $this->text;
159
    }
160
}