Completed
Pull Request — master (#90)
by Jonathan
02:08
created

RulesetInflector::inflect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Inflector;
6
7
use Doctrine\Inflector\Rules\Ruleset;
8
use function array_keys;
9
use function implode;
10
use function preg_match;
11
use function preg_replace;
12
use function strtolower;
13
use function substr;
14
15
class RulesetInflector
16
{
17
    /** @var Ruleset */
18
    private $ruleset;
19
20
    /** @var string|null */
21
    private $irregularRegex;
22
23
    /** @var string|null */
24
    private $uninflectedRegex;
25
26
    /** @var string[] */
27
    private $wordInflectionCache = [];
28
29 526
    public function __construct(Ruleset $ruleset)
30
    {
31 526
        $this->ruleset = $ruleset;
32 526
    }
33
34
    /**
35
     * @param mixed[] $rules
36
     */
37 4
    public function addRules(array $rules) : void
38
    {
39 4
        $this->ruleset->addRules($rules);
40
41 4
        $this->irregularRegex      = null;
42 4
        $this->uninflectedRegex    = null;
43 4
        $this->wordInflectionCache = [];
44 4
    }
45
46 510
    public function inflect(string $word) : string
47
    {
48 510
        if (! isset($this->wordInflectionCache[$word])) {
49 510
            $this->wordInflectionCache[$word] = $this->doInflect($word);
50
        }
51
52 510
        return $this->wordInflectionCache[$word];
53
    }
54
55 510
    private function doInflect(string $word) : string
56
    {
57 510
        $irregular = $this->ruleset->getIrregular();
58
59 510
        if (preg_match('/(.*)\\b(' . $this->getIrregularRegex($irregular) . ')$/i', $word, $regs)) {
60 93
            return $regs[1] . $word[0] . substr($irregular[strtolower($regs[2])], 1);
61
        }
62
63 420
        if (preg_match('/^(' . $this->getUninflectedRegex() . ')$/i', $word, $regs)) {
64 244
            return $word;
65
        }
66
67 179
        foreach ($this->ruleset->getRules() as $rule => $replacement) {
68 179
            if (preg_match($rule, $word)) {
69 179
                return preg_replace($rule, $replacement, $word);
70
            }
71
        }
72
73 2
        return $word;
74
    }
75
76
    /**
77
     * @param string[] $irregular
78
     */
79 510
    private function getIrregularRegex(array $irregular) : string
80
    {
81 510
        if ($this->irregularRegex === null) {
82 510
            $this->irregularRegex = '(?:' . implode('|', array_keys($irregular)) . ')';
83
        }
84
85 510
        return $this->irregularRegex;
86
    }
87
88 420
    private function getUninflectedRegex() : string
89
    {
90 420
        if ($this->uninflectedRegex === null) {
91 420
            $this->uninflectedRegex = '(?:' . implode('|', $this->ruleset->getUninflected()) . ')';
92
        }
93
94 420
        return $this->uninflectedRegex;
95
    }
96
}
97