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

InflectorService::inflect()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 15
cts 15
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 14
nc 6
nop 1
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Inflector;
6
7
use Doctrine\Inflector\Rules\Uninflected;
8
use function array_keys;
9
use function array_merge;
10
use function implode;
11
use function is_array;
12
use function preg_match;
13
use function preg_replace;
14
use function strtolower;
15
use function substr;
16
use function ucfirst;
17
18
abstract class InflectorService
19
{
20
    /** @var Uninflected */
21
    protected $uninflected;
22
23
    /** @var mixed[] */
24
    protected $rules = [];
25
26
    /** @var string[] */
27
    protected $cache = [];
28
29 4
    public function __construct(Uninflected $uninflected)
30
    {
31 4
        $this->uninflected = $uninflected;
32 4
        $this->rules       = $this->getRules();
33
34 4
        $this->initializeRules();
35 4
    }
36
37
    /**
38
     * @return string[][]
39
     */
40
    abstract public function getRules() : array;
41
42
    /**
43
     * @param mixed[] $rules
44
     */
45 4
    public function addRules(array $rules, bool $reset = false) : void
46
    {
47 4
        foreach ($rules as $rule => $pattern) {
48 4
            if (! is_array($pattern)) {
49 2
                continue;
50
            }
51
52 4
            if ($reset) {
53 1
                $this->rules[$rule] = $pattern;
54
            } else {
55 3
                $this->rules[$rule] = ($rule === 'uninflected')
56 2
                    ? array_merge($pattern, $this->rules[$rule])
57 3
                    : $pattern + $this->rules[$rule];
58
            }
59
60 4
            unset($rules[$rule], $this->rules['cache' . ucfirst($rule)]);
61
62 4
            if (! isset($this->rules['merged'][$rule])) {
63 4
                continue;
64
            }
65
66 4
            unset($this->rules['merged'][$rule]);
67
        }
68
69 4
        $this->cache          = [];
70 4
        $this->rules['rules'] = $rules + $this->rules['rules'];
71
72 4
        $this->initializeRules();
73 4
    }
74
75 510
    public function inflect(string $word) : string
76
    {
77 510
        if (isset($this->cache[$word])) {
78 24
            return $this->cache[$word];
79
        }
80
81 486
        if (preg_match('/(.*)\\b(' . $this->rules['cacheIrregular'] . ')$/i', $word, $regs)) {
82 93
            $this->cache[$word] = $regs[1] . $word[0] . substr($this->rules['merged']['irregular'][strtolower($regs[2])], 1);
83
84 93
            return $this->cache[$word];
85
        }
86
87 396
        if (preg_match('/^(' . $this->rules['cacheUninflected'] . ')$/i', $word, $regs)) {
88 220
            $this->cache[$word] = $word;
89
90 220
            return $word;
91
        }
92
93 179
        foreach ($this->rules['rules'] as $rule => $replacement) {
94 179
            if (preg_match($rule, $word)) {
95 177
                $this->cache[$word] = preg_replace($rule, $replacement, $word);
96
97 179
                return $this->cache[$word];
98
            }
99
        }
100
101 2
        $this->cache[$word] = $word;
102
103 2
        return $word;
104
    }
105
106 4
    protected function initializeRules() : void
107
    {
108 4
        if (! isset($this->rules['merged']['uninflected'])) {
109 4
            $this->rules['merged']['uninflected'] = array_merge(
110 4
                $this->rules['uninflected'],
111 4
                $this->uninflected->getUninflected()
112
            );
113
        }
114
115 4
        $this->initializeIrregular();
116
117 4
        if (isset($this->rules['cacheUninflected']) && isset($this->rules['cacheIrregular'])) {
118 3
            return;
119
        }
120
121 4
        $this->rules['cacheUninflected'] = '(?:' . implode('|', $this->rules['merged']['uninflected']) . ')';
122 4
        $this->rules['cacheIrregular']   = '(?:' . implode('|', array_keys($this->rules['merged']['irregular'])) . ')';
123 4
    }
124
125
    abstract protected function initializeIrregular() : void;
126
}
127