Issues (9)

src/PcreExtension.php (1 issue)

Checks if the types of returned expressions are compatible with the documented types.

Best Practice Bug Major
1
<?php
2
3
namespace Jasny\Twig;
4
5
use Twig\Error\RuntimeError;
6
use Twig\Extension\AbstractExtension;
7
use Twig\TwigFilter;
8
9
/**
10
 * Expose the PCRE functions to Twig.
11
 *
12
 * @see http://php.net/manual/en/book.pcre.php
13
 */
14
class PcreExtension extends AbstractExtension
15
{
16
    /**
17
     * Class constructor
18
     */
19 27
    public function __construct()
20
    {
21 27
        if (!extension_loaded('pcre')) {
22
            throw new \Exception("The Twig PCRE extension requires the PCRE extension."); // @codeCoverageIgnore
23
        }
24 27
    }
25
26
    /**
27
     * Return extension name
28
     *
29
     * @return string
30
     */
31 1
    public function getName()
32
    {
33 1
        return 'jasny/pcre';
34
    }
35
36
    /**
37
     * {@inheritdoc}
38
     */
39 26
    public function getFilters()
40
    {
41
        return [
42 26
            new TwigFilter('preg_quote', [$this, 'quote']),
43 26
            new TwigFilter('preg_match', [$this, 'match']),
44 26
            new TwigFilter('preg_get', [$this, 'get']),
45 26
            new TwigFilter('preg_get_all', [$this, 'getAll']),
46 26
            new TwigFilter('preg_grep', [$this, 'grep']),
47 26
            new TwigFilter('preg_replace', [$this, 'replace']),
48 26
            new TwigFilter('preg_filter', [$this, 'filter']),
49 26
            new TwigFilter('preg_split', [$this, 'split']),
50
        ];
51
    }
52
53
54
    /**
55
     * Check that the regex doesn't use the eval modifier
56
     *
57
     * @param string $pattern
58
     * @throws \LogicException
59
     */
60 8
    protected function assertNoEval($pattern)
61
    {
62 8
        $patterns = (array)$pattern;
63 8
64
        foreach ($patterns as $pattern) {
65 8
            $pos       = strrpos($pattern, $pattern[0]);
66 2
            $modifiers = substr($pattern, $pos + 1);
67
68 6
            if (strpos($modifiers, 'e') !== false) {
69
                throw new RuntimeError("Using the eval modifier for regular expressions is not allowed");
70
            }
71
        }
72
    }
73
74
75
    /**
76
     * Quote regular expression characters.
77
     *
78 3
     * @param string $value
79
     * @param string $delimiter
80 3
     * @return string
81 1
     */
82
    public function quote($value, $delimiter = '/')
83
    {
84 2
        if (!isset($value)) {
85
            return null;
86
        }
87
88
        return preg_quote($value, $delimiter);
89
    }
90
91
    /**
92
     * Perform a regular expression match.
93
     *
94 4
     * @param string $value
95
     * @param string $pattern
96 4
     * @return boolean
97 1
     */
98
    public function match($value, $pattern)
99
    {
100 3
        if (!isset($value)) {
101
            return null;
102
        }
103
104
        return preg_match($pattern, $value);
105
    }
106
107
    /**
108
     * Perform a regular expression match and return a matched group.
109
     *
110 3
     * @param string $value
111
     * @param string $pattern
112 3
     * @return string
113 1
     */
114
    public function get($value, $pattern, $group = 0)
115
    {
116 2
        if (!isset($value)) {
117
            return null;
118
        }
119
120
        return preg_match($pattern, $value, $matches) && isset($matches[$group]) ? $matches[$group] : null;
121
    }
122
123
    /**
124
     * Perform a regular expression match and return the group for all matches.
125
     *
126 3
     * @param string $value
127
     * @param string $pattern
128 3
     * @return array
129 1
     */
130
    public function getAll($value, $pattern, $group = 0)
131
    {
132 2
        if (!isset($value)) {
133 2
            return null;
134
        }
135
136
        return preg_match_all($pattern, $value, $matches, PREG_PATTERN_ORDER) && isset($matches[$group])
137
            ? $matches[$group] : [];
138
    }
139
140
    /**
141
     * Perform a regular expression match and return an array of entries that match the pattern
142
     *
143
     * @param array  $values
144 3
     * @param string $pattern
145
     * @param string $flags    Optional 'invert' to return entries that do not match the given pattern.
146 3
     * @return array
147 1
     */
148
    public function grep($values, $pattern, $flags = '')
149
    {
150 2
        if (!isset($values)) {
151 2
            return null;
152
        }
153
154 2
        if (is_string($flags)) {
155
            $flags = $flags === 'invert' ? PREG_GREP_INVERT : 0;
156
        }
157
158
        return preg_grep($pattern, $values, $flags);
159
    }
160
161
    /**
162
     * Perform a regular expression search and replace.
163
     *
164
     * @param string $value
165
     * @param string $pattern
166 5
     * @param string $replacement
167
     * @param int    $limit
168 5
     * @return string
169
     */
170 4
    public function replace($value, $pattern, $replacement = '', $limit = -1)
171 1
    {
172
        $this->assertNoEval($pattern);
173
174 3
        if (!isset($value)) {
175
            return null;
176
        }
177
178
        return preg_replace($pattern, $replacement, $value, $limit);
179
    }
180
181
    /**
182
     * Perform a regular expression search and replace, returning only matched subjects.
183
     *
184
     * @param string $value
185
     * @param string $pattern
186 3
     * @param string $replacement
187
     * @param int    $limit
188 3
     * @return string
189
     */
190 2
    public function filter($value, $pattern, $replacement = '', $limit = -1)
191 1
    {
192
        $this->assertNoEval($pattern);
193
194 1
        if (!isset($value)) {
195
            return null;
196
        }
197
198
        return preg_filter($pattern, $replacement, $value, $limit);
0 ignored issues
show
Bug Best Practice introduced by
The expression return preg_filter($patt...cement, $value, $limit) also could return the type array which is incompatible with the documented return type string.
Loading history...
199
    }
200
201
    /**
202
     * Split text into an array using a regular expression.
203
     *
204 2
     * @param string $value
205
     * @param string $pattern
206 2
     * @return array
207 1
     */
208
    public function split($value, $pattern)
209
    {
210 1
        if (!isset($value)) {
211
            return null;
212
        }
213
214
        return preg_split($pattern, $value);
215
    }
216
}
217