Passed
Push — main ( 221f6d...f8c128 )
by Siad
05:28
created

src/Phing/Type/Selector/ContainsRegexpSelector.php (1 issue)

1
<?php
2
3
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing\Type\Selector;
22
23
use Phing\Exception\BuildException;
24
use Phing\Io\BufferedReader;
25
use Phing\Io\File;
26
use Phing\Io\FileReader;
27
use Phing\Io\IOException;
28
use Phing\Project;
29
use Phing\Task\System\Condition\OsCondition;
30
use Phing\Type\RegularExpression;
31
use Phing\Util\Regexp;
32
use Phing\Util\RegexpException;
33
34
/**
35
 * Selector that filters files based on whether they contain a
36
 * particular string using regexp.
37
 *
38
 * @author  Hans Lellelid <[email protected]> (Phing)
39
 * @author  Bruce Atherton <[email protected]> (Ant)
40
 */
41
class ContainsRegexpSelector extends BaseExtendSelector
42
{
43
    public const EXPRESSION_KEY = 'expression';
44
    public const CASE_KEY = 'casesensitive';
45
    public const ML_KEY = 'multiline';
46
    /**
47
     * The expression set from XML.
48
     *
49
     * @var string
50
     */
51
    private $userProvidedExpression;
52
53
    /**
54
     * @var Regexp
55
     */
56
    private $myExpression;
57
58
    /**
59
     * @var bool
60
     */
61
    private $casesensitive = true;
62
63
    /**
64
     * @var bool
65
     */
66
    private $multiline = false;
67
68
    /**
69
     * @var RegularExpression
70
     */
71
    private $myRegExp;
72
73
    /**
74
     * @return string
75
     */
76 1
    public function __toString()
77
    {
78 1
        $buf = '{containsregexpselector expression: ';
79 1
        $buf .= $this->userProvidedExpression;
80 1
        $buf .= ' casesensitive: ';
81 1
        if ($this->casesensitive) {
82 1
            $buf .= 'true';
83
        } else {
84
            $buf .= 'false';
85
        }
86 1
        $buf .= '}';
87
88 1
        return $buf;
89
    }
90
91
    /**
92
     * The expression to match on within a file.
93
     *
94
     * @param string $exp the string that a file must contain to be selected
95
     */
96 1
    public function setExpression($exp)
97
    {
98 1
        $this->userProvidedExpression = $exp;
99 1
    }
100
101
    /**
102
     * Whether to ignore case in the regex match.
103
     *
104
     * @param bool $casesensitive whether to pay attention to case sensitivity
105
     */
106
    public function setCasesensitive($casesensitive)
107
    {
108
        $this->casesensitive = $casesensitive;
109
    }
110
111
    public function setMultiline(bool $multiline): void
112
    {
113
        $this->multiline = $multiline;
114
    }
115
116
    /**
117
     * When using this as a custom selector, this method will be called.
118
     * It translates each parameter into the appropriate setXXX() call.
119
     *
120
     * @param array $parameters the complete set of parameters for this selector
121
     */
122
    public function setParameters(array $parameters): void
123
    {
124
        parent::setParameters($parameters);
125
        if (null !== $parameters) {
0 ignored issues
show
The condition null !== $parameters is always true.
Loading history...
126
            for ($i = 0, $size = count($parameters); $i < $size; ++$i) {
127
                $paramname = $parameters[$i]->getName();
128
129
                switch (strtolower($paramname)) {
130
                    case self::EXPRESSION_KEY:
131
                        $this->setExpression($parameters[$i]->getValue());
132
133
                        break;
134
135
                    case self::CASE_KEY:
136
                        $this->setCasesensitive(Project::toBoolean($parameters[$i]->getValue()));
137
138
                        break;
139
140
                    case self::ML_KEY:
141
                        $this->setMultiLine(Project::toBoolean($parameters[$i]->getValue()));
142
143
                        break;
144
145
                    default:
146
                        $this->setError('Invalid parameter ' . $paramname);
147
                }
148
            } // for each param
149
        } // if params
150
    }
151
152
    /**
153
     * Checks to make sure all settings are kosher. In this case, it
154
     * means that the pattern attribute has been set.
155
     */
156 1
    public function verifySettings()
157
    {
158 1
        if (null === $this->userProvidedExpression) {
159
            $this->setError('The expression attribute is required');
160
        }
161 1
    }
162
163
    /**
164
     * The heart of the matter. This is where the selector gets to decide
165
     * on the inclusion of a file in a particular fileset.
166
     *
167
     * @param File   $basedir  base directory the scan is being done from
168
     * @param string $filename the name of the file to check
169
     * @param File   $file     PhingFile object the selector can use
170
     *
171
     * @throws IOException
172
     * @throws RegexpException
173
     *
174
     * @return bool whether the file should be selected or not
175
     */
176 1
    public function isSelected(File $basedir, $filename, File $file)
177
    {
178 1
        $this->validate();
179
180
        try {
181 1
            if ($file->isDirectory() || $file->isLink()) {
182 1
                return true;
183
            }
184
        } catch (IOException $ioe) {
185
            if (OsCondition::isOS('windows')) {
186
                return true;
187
            }
188
189
            throw new BuildException($ioe);
190
        }
191
192 1
        if (null === $this->myRegExp) {
193 1
            $this->myRegExp = new RegularExpression();
194 1
            $this->myRegExp->setPattern($this->userProvidedExpression);
195 1
            $this->myExpression = $this->myRegExp->getRegexp($this->getProject());
196
        }
197
198 1
        $in = null;
199
200
        try {
201 1
            $in = new BufferedReader(new FileReader($file));
202 1
            $teststr = $in->readLine();
203 1
            while (null !== $teststr) {
204 1
                $this->myExpression->setMultiline($this->multiline);
205 1
                $this->myExpression->setIgnoreCase(!$this->casesensitive);
206 1
                if ($this->myExpression->matches($teststr)) {
207 1
                    return true;
208
                }
209 1
                $teststr = $in->readLine();
210
            }
211
212 1
            $in->close();
213
214 1
            return false;
215
        } catch (IOException $ioe) {
216
            if ($in) {
217
                $in->close();
218
            }
219
220
            throw new BuildException('Could not read file ' . $filename);
221
        }
222
    }
223
}
224