Passed
Push — master ( 045f45...2c73e4 )
by Michiel
08:31 queued 11s
created

DateSelector   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 209
Duplicated Lines 0 %

Test Coverage

Coverage 31.82%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 85
dl 0
loc 209
ccs 28
cts 88
cp 0.3182
rs 10
c 1
b 0
f 0
wmc 30

12 Methods

Rating   Name   Duplication   Size   Complexity  
A isSelected() 0 12 5
A __toString() 0 17 3
A setGranularity() 0 3 1
A setMillis() 0 3 1
A setSeconds() 0 3 1
A setDatetime() 0 12 2
A __construct() 0 3 1
A setCheckdirs() 0 3 1
A getSeconds() 0 3 1
A verifySettings() 0 12 4
A setWhen() 0 7 2
B setParameters() 0 24 8
1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19
20
/**
21
 * Selector that chooses files based on their last modified date. Ant uses
22
 * millisecond precision (thanks to Java); PHP is forced to use only seconds
23
 * precision.
24
 *
25
 * @author  Hans Lellelid <[email protected]> (Phing)
26
 * @author  Bruce Atherton <[email protected]> (Ant)
27
 * @package phing.types.selectors
28
 */
29
class DateSelector extends BaseExtendSelector
30
{
31
    private $seconds = -1; // millis in Ant, but PHP doesn't support that level of precision
32
    private $dateTime = null;
33
    private $includeDirs = false;
34
    private $granularity = 0;
35
    private $cmp = 2;
36
    const MILLIS_KEY = "millis";
37
    const DATETIME_KEY = "datetime";
38
    const CHECKDIRS_KEY = "checkdirs";
39
    const GRANULARITY_KEY = "granularity";
40
    const WHEN_KEY = "when";
41
    private static $timeComparisons = ["before", "after", "equal"];
42
43
    /**
44
     *
45
     */
46 2
    public function __construct()
47
    {
48 2
        parent::__construct();
49
        //if (Os.isFamily("dos")) {
50
        //    granularity = 2000;
51
        //}
52 2
    }
53
54
    /**
55
     * @return string
56
     */
57
    public function __toString()
58
    {
59
        $buf = "{dateselector date: ";
60
        $buf .= $this->dateTime;
61
        $buf .= " compare: ";
62
        if ($this->cmp === 0) {
63
            $buf .= "before";
64
        } elseif ($this->cmp === 1) {
65
            $buf .= "after";
66
        } else {
67
            $buf .= "equal";
68
        }
69
        $buf .= " granularity: ";
70
        $buf .= $this->granularity;
71
        $buf .= "}";
72
73
        return $buf;
74
    }
75
76
    /**
77
     * For users that prefer to express time in seconds since 1970
78
     *
79
     * @param int $seconds the time to compare file's last modified date to,
80
     *                     expressed in seconds
81
     */
82 2
    public function setSeconds($seconds)
83
    {
84 2
        $this->seconds = (int) $seconds;
85 2
    }
86
87
    /**
88
     * Returns the seconds value the selector is set for.
89
     */
90
    public function getSeconds()
91
    {
92
        return $this->seconds;
93
    }
94
95
    /**
96
     * @param int $millis the time to compare file's last modified date to, expressed in milliseconds
97
     */
98
    public function setMillis($millis)
99
    {
100
        $this->setSeconds((int) $millis * 1000);
101
    }
102
103
    /**
104
     * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM
105
     * format
106
     *
107
     * @param string $dateTime a string in MM/DD/YYYY HH:MM AM_PM format
108
     */
109 2
    public function setDatetime($dateTime)
110
    {
111 2
        $dt = strtotime($dateTime);
112 2
        if ($dt == -1) {
113
            $this->setError(
114
                "Date of " . $dateTime
115
                . " Cannot be parsed correctly. It should be in"
116
                . " a format parsable by PHP's strtotime() function."
117
            );
118
        } else {
119 2
            $this->dateTime = $dateTime;
120 2
            $this->setSeconds($dt);
121
        }
122 2
    }
123
124
    /**
125
     * Should we be checking dates on directories?
126
     *
127
     * @param boolean $includeDirs whether to check the timestamp on directories
128
     */
129
    public function setCheckdirs($includeDirs)
130
    {
131
        $this->includeDirs = (bool) $includeDirs;
132
    }
133
134
    /**
135
     * Sets the number of milliseconds leeway we will give before we consider
136
     * a file not to have matched a date.
137
     *
138
     * @param int $granularity
139
     */
140
    public function setGranularity($granularity)
141
    {
142
        $this->granularity = (int) $granularity;
143
    }
144
145
    /**
146
     * Sets the type of comparison to be done on the file's last modified
147
     * date.
148
     *
149
     * @param string $cmp The comparison to perform
150
     */
151 2
    public function setWhen($cmp)
152
    {
153 2
        $idx = array_search($cmp, self::$timeComparisons, true);
154 2
        if ($idx === null) {
155
            $this->setError("Invalid value for " . self::WHEN_KEY . ": " . $cmp);
156
        } else {
157 2
            $this->cmp = $idx;
158
        }
159 2
    }
160
161
    /**
162
     * When using this as a custom selector, this method will be called.
163
     * It translates each parameter into the appropriate setXXX() call.
164
     *
165
     * @param array $parameters the complete set of parameters for this selector
166
     * @return mixed|void
167
     */
168
    public function setParameters(array $parameters): void
169
    {
170
        parent::setParameters($parameters);
171
        if ($parameters !== null) {
0 ignored issues
show
introduced by
The condition $parameters !== null is always true.
Loading history...
172
            for ($i = 0, $size = count($parameters); $i < $size; $i++) {
173
                $paramname = $parameters[$i]->getName();
174
                switch (strtolower($paramname)) {
175
                    case self::MILLIS_KEY:
176
                        $this->setMillis($parameters[$i]->getValue());
177
                        break;
178
                    case self::DATETIME_KEY:
179
                        $this->setDatetime($parameters[$i]->getValue());
180
                        break;
181
                    case self::CHECKDIRS_KEY:
182
                        $this->setCheckdirs($parameters[$i]->getValue());
183
                        break;
184
                    case self::GRANULARITY_KEY:
185
                        $this->setGranularity($parameters[$i]->getValue());
186
                        break;
187
                    case self::WHEN_KEY:
188
                        $this->setWhen($parameters[$i]->getValue());
189
                        break;
190
                    default:
191
                        $this->setError("Invalid parameter " . $paramname);
192
                } // switch
193
            }
194
        }
195
    }
196
197
    /**
198
     * This is a consistency check to ensure the selector's required
199
     * values have been set.
200
     */
201 2
    public function verifySettings()
202
    {
203 2
        if ($this->dateTime === null && $this->seconds < 0) {
204
            $this->setError(
205
                "You must provide a datetime or the number of "
206
                . "seconds."
207
            );
208 2
        } elseif ($this->seconds < 0) {
209
            $this->setError(
210
                "Date of " . $this->dateTime
211
                . " results in negative seconds"
212
                . " value relative to epoch (January 1, 1970, 00:00:00 GMT)."
213
            );
214
        }
215 2
    }
216
217
    /**
218
     * The heart of the matter. This is where the selector gets to decide
219
     * on the inclusion of a file in a particular fileset.
220
     *
221
     * @param  PhingFile $basedir the base directory the scan is being done from
222
     * @param  string $filename is the name of the file to check
223
     * @param  PhingFile $file is a PhingFile object the selector can use
224
     * @return boolean   Whether the file should be selected or not
225
     */
226 2
    public function isSelected(PhingFile $basedir, $filename, PhingFile $file)
227
    {
228 2
        $this->validate();
229 2
        if ($file->isDirectory() && ($this->includeDirs === false)) {
230
            return true;
231
        }
232 2
        if ($this->cmp === 0) {
233 1
            return (($file->lastModified() - $this->granularity) < $this->seconds);
234 1
        } elseif ($this->cmp === 1) {
235 1
            return (($file->lastModified() - $this->granularity) > $this->seconds);
236
        } else {
237
            return (abs($file->lastModified() - $this->seconds) <= $this->granularity);
238
        }
239
    }
240
}
241