This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
0 ignored issues
–
show
|
|||
2 | |||
3 | |||
4 | namespace Litipk\Jiffy; |
||
5 | |||
6 | |||
7 | 1 | if (extension_loaded('mongo') && extension_loaded('mongodb')) { |
|
8 | trait TsExtension { use MongoAdapter; use MongodbAdapter; }; |
||
9 | 1 | } elseif (extension_loaded('mongo')) { |
|
10 | trait TsExtension { use MongoAdapter; }; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
The type
Litipk\Jiffy\TsExtension has been defined more than once; this definition is ignored, only the first definition in this file (L8-8) is considered.
This check looks for classes that have been defined more than once in the same file. If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface. This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP. ![]() |
|||
11 | } elseif (extension_loaded('mongodb')) { |
||
12 | trait TsExtension { use MongodbAdapter; }; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
The type
Litipk\Jiffy\TsExtension has been defined more than once; this definition is ignored, only the first definition in this file (L8-8) is considered.
This check looks for classes that have been defined more than once in the same file. If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface. This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP. ![]() |
|||
13 | } else { |
||
14 | trait TsExtension {}; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
The type
Litipk\Jiffy\TsExtension has been defined more than once; this definition is ignored, only the first definition in this file (L8-8) is considered.
This check looks for classes that have been defined more than once in the same file. If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface. This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP. ![]() |
|||
15 | } |
||
16 | |||
17 | |||
18 | /** |
||
19 | * Class UniversalTimestamp |
||
20 | * @package Litipk\Jiffy |
||
21 | */ |
||
22 | final class UniversalTimestamp |
||
0 ignored issues
–
show
|
|||
23 | { |
||
24 | const ISO8601_WITH_MILLISECONDS = '_ISO8601_WITH_MILLIS_'; |
||
25 | const ISO8601_WITH_MILLISECONDS_WITHOUT_TZ = '_ISO8601_WITH_MILLIS_WITHOUT_TZ'; |
||
26 | const ISO8601_WITH_MICROSECONDS = 'Y-m-d\TH:i:s.uO'; |
||
27 | const ISO8601_WITH_MICROSECONDS_WITHOUT_TZ = 'Y-m-d\TH:i:s.u'; |
||
28 | |||
29 | use TsExtension; |
||
30 | |||
31 | /** @var int */ |
||
32 | private $millis; |
||
33 | |||
34 | /** @var int */ |
||
35 | private $micros; |
||
36 | |||
37 | /** |
||
38 | * Constructor. |
||
39 | * |
||
40 | * @param integer $millisSinceEpoch |
||
41 | * @param integer $micros |
||
42 | */ |
||
43 | 18 | private function __construct($millisSinceEpoch, $micros = 0) |
|
44 | { |
||
45 | 18 | if ($millisSinceEpoch < 0 || $micros < 0) { |
|
46 | 1 | throw new JiffyException('The number of milliseconds and microseconds must be positive'); |
|
47 | } |
||
48 | |||
49 | 17 | $this->millis = $millisSinceEpoch + (int)($micros/1000); |
|
50 | 17 | $this->micros = $micros % 1000; |
|
51 | 17 | } |
|
52 | |||
53 | /** |
||
54 | * @return UniversalTimestamp |
||
55 | */ |
||
56 | 10 | public static function now() |
|
57 | { |
||
58 | 10 | $ts_parts = explode(' ', microtime()); |
|
59 | |||
60 | 10 | return new UniversalTimestamp( |
|
61 | 10 | (int)floor($ts_parts[0]*1000) + (int)$ts_parts[1]*1000, // Millis |
|
62 | 10 | ((int)round($ts_parts[0]*1000000))%1000 // Micros |
|
63 | 10 | ); |
|
64 | } |
||
65 | |||
66 | /** |
||
67 | * @param \DateTimeInterface $dateTime |
||
68 | * @return UniversalTimestamp |
||
69 | */ |
||
70 | 4 | public static function fromDateTimeInterface(\DateTimeInterface $dateTime) |
|
71 | { |
||
72 | 4 | $dtU = (int)$dateTime->format('u'); |
|
73 | |||
74 | 4 | return new UniversalTimestamp( |
|
75 | 4 | $dateTime->getTimestamp()*1000 + (int)floor($dtU/1000), |
|
76 | $dtU % 1000 |
||
77 | 4 | ); |
|
78 | } |
||
79 | |||
80 | /** |
||
81 | * @param string $strTimestamp |
||
82 | * @param string $tz |
||
83 | * @return UniversalTimestamp |
||
84 | */ |
||
85 | 3 | public static function fromStringTimestamp($strTimestamp, $tz = 'UTC') |
|
86 | { |
||
87 | try { |
||
88 | 3 | $dt = new \DateTimeImmutable( |
|
89 | 3 | $strTimestamp, |
|
90 | 3 | ($tz instanceof \DateTimeZone) ? $tz : new \DateTimeZone($tz) |
|
91 | 3 | ); |
|
92 | 3 | } catch (\Exception $e) { |
|
93 | 1 | throw new JiffyException('The provided value cannot be interpreted as a timestamp'); |
|
94 | } |
||
95 | 2 | return self::fromDateTimeInterface($dt); |
|
96 | } |
||
97 | |||
98 | /** |
||
99 | * @param int $secondsSinceEpoch |
||
100 | * @return UniversalTimestamp |
||
101 | */ |
||
102 | 1 | public static function fromSecondsTimestamp($secondsSinceEpoch) |
|
103 | { |
||
104 | 1 | return new UniversalTimestamp($secondsSinceEpoch*1000); |
|
105 | } |
||
106 | |||
107 | /** |
||
108 | * @param int $millisSinceEpoch |
||
109 | * @param int $micros |
||
110 | * @return UniversalTimestamp |
||
111 | */ |
||
112 | 9 | public static function fromMillisecondsTimestamp($millisSinceEpoch, $micros = 0) |
|
113 | { |
||
114 | 9 | return new UniversalTimestamp($millisSinceEpoch, $micros); |
|
115 | } |
||
116 | |||
117 | /** |
||
118 | * @param mixed $dateObject If it's an integer, then it's understood as milliseconds since epoch |
||
119 | * @return UniversalTimestamp |
||
120 | */ |
||
121 | 2 | public static function fromWhatever($dateObject) { |
|
122 | 2 | if (null === $dateObject) { |
|
123 | 1 | return self::now(); |
|
124 | 2 | } elseif (is_int($dateObject)) { |
|
125 | 1 | return self::fromMillisecondsTimestamp($dateObject); |
|
126 | 2 | } elseif (is_string($dateObject)) { |
|
127 | 2 | return self::fromStringTimestamp($dateObject); |
|
128 | 1 | } elseif ($dateObject instanceof UniversalTimestamp) { |
|
129 | return $dateObject; |
||
130 | 1 | } elseif ($dateObject instanceof \DateTimeInterface) { |
|
131 | 1 | return self::fromDateTimeInterface($dateObject); |
|
132 | 1 | } elseif ($dateObject instanceof \MongoDate) { |
|
133 | 1 | return self::fromMongoDate($dateObject); |
|
134 | 1 | } elseif ($dateObject instanceof \MongoDB\BSON\UTCDatetime) { |
|
0 ignored issues
–
show
The class
MongoDB\BSON\UTCDatetime does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
135 | 1 | return self::fromMongodbUTCDateTime($dateObject); |
|
136 | } else { |
||
137 | throw new JiffyException('The provided value cannot be interpreted as a timestamp'); |
||
138 | } |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * @param UniversalTimestamp $otherTimestamp |
||
143 | * @return boolean |
||
144 | */ |
||
145 | 3 | public function isGreaterThan(UniversalTimestamp $otherTimestamp) |
|
146 | { |
||
147 | return ( |
||
148 | 3 | $this->millis > $otherTimestamp->millis || |
|
149 | 3 | $this->millis === $otherTimestamp->millis && $this->micros > $otherTimestamp->micros |
|
150 | 3 | ); |
|
151 | } |
||
152 | |||
153 | /** |
||
154 | * @param int $seconds |
||
155 | * @return UniversalTimestamp |
||
156 | */ |
||
157 | 1 | public function addSeconds($seconds) |
|
158 | { |
||
159 | 1 | $copy = clone $this; |
|
160 | 1 | $copy->millis += 1000*$seconds; |
|
161 | |||
162 | 1 | return $copy; |
|
163 | } |
||
164 | |||
165 | /** |
||
166 | * @param int $millis |
||
167 | * @return UniversalTimestamp |
||
168 | */ |
||
169 | 1 | public function addMilliseconds($millis) |
|
170 | { |
||
171 | 1 | $copy = clone $this; |
|
172 | 1 | $copy->millis += $millis; |
|
173 | |||
174 | 1 | return $copy; |
|
175 | } |
||
176 | |||
177 | /** |
||
178 | * @return int |
||
179 | */ |
||
180 | 11 | public function asSeconds() |
|
181 | { |
||
182 | 11 | return (int)floor($this->millis/1000); |
|
183 | } |
||
184 | |||
185 | /** |
||
186 | * @return int |
||
187 | */ |
||
188 | 9 | public function asMilliseconds() |
|
189 | { |
||
190 | 9 | return $this->millis; |
|
191 | } |
||
192 | |||
193 | /** |
||
194 | * @return int |
||
195 | */ |
||
196 | 1 | public function getRemainingMicroseconds() |
|
197 | { |
||
198 | 1 | return $this->micros; |
|
199 | } |
||
200 | |||
201 | /** |
||
202 | * @param string|\DateTimeZone $tz |
||
203 | * @return \DateTimeImmutable |
||
204 | */ |
||
205 | 3 | public function asDateTimeInterface($tz = 'UTC') |
|
206 | { |
||
207 | 3 | $dateTime = new \DateTimeImmutable('@'.((string)$this->asSeconds())); |
|
208 | 3 | $dateTime = $dateTime->setTimezone(is_string($tz) ? new \DateTimeZone($tz) : $tz); |
|
209 | |||
210 | 3 | return new \DateTimeImmutable( |
|
211 | 3 | $dateTime->format('Y-m-d\TH:i:s').'.'. |
|
212 | 3 | sprintf("%03d", $this->millis%1000).sprintf("%03d", $this->micros). |
|
213 | 3 | $dateTime->format('O') |
|
214 | 3 | ); |
|
215 | } |
||
216 | |||
217 | /** |
||
218 | * @param string $format |
||
219 | * @param string|\DateTimeZone $tz |
||
220 | * @return string |
||
221 | */ |
||
222 | 3 | public function asFormattedString($format = self::ISO8601_WITH_MICROSECONDS, $tz = 'UTC') |
|
223 | { |
||
224 | 3 | if (self::ISO8601_WITH_MILLISECONDS === $format) { |
|
225 | 1 | $rParts = preg_split('/\+/', $this->asDateTimeInterface($tz)->format(\DateTime::ISO8601)); |
|
226 | 1 | return $rParts[0].'.'.((string)$this->millis%1000).'+'.$rParts[1]; |
|
227 | 3 | } elseif (self::ISO8601_WITH_MILLISECONDS_WITHOUT_TZ === $format) { |
|
228 | 1 | $rParts = preg_split('/\+/', $this->asDateTimeInterface($tz)->format(\DateTime::ISO8601)); |
|
229 | 1 | return $rParts[0].'.'.((string)$this->millis%1000); |
|
230 | } else { |
||
231 | 3 | return $this->asDateTimeInterface($tz)->format($format); |
|
232 | } |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * @return string |
||
237 | */ |
||
238 | 1 | public function __toString() |
|
239 | { |
||
240 | 1 | return $this->asFormattedString(); |
|
241 | } |
||
242 | } |
||
243 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.