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 |
||
2 | |||
3 | namespace CultuurNet\UDB3; |
||
4 | |||
5 | use Cake\Chronos\Chronos; |
||
6 | use CultureFeed_Cdb_Data_Calendar_Timestamp; |
||
7 | use CultuurNet\UDB3\Calendar\DayOfWeek; |
||
8 | use CultuurNet\UDB3\Calendar\DayOfWeekCollection; |
||
9 | use CultuurNet\UDB3\Calendar\OpeningHour; |
||
10 | use CultuurNet\UDB3\Calendar\OpeningTime; |
||
11 | use CultuurNet\UDB3\Cdb\DateTimeFactory; |
||
12 | use DateTimeInterface; |
||
13 | |||
14 | class CalendarFactory implements CalendarFactoryInterface |
||
15 | { |
||
16 | /** |
||
17 | * @inheritdoc |
||
18 | */ |
||
19 | public function createFromCdbCalendar(\CultureFeed_Cdb_Data_Calendar $cdbCalendar) |
||
20 | { |
||
21 | // |
||
22 | // Get the start day. |
||
23 | // |
||
24 | $cdbCalendar->rewind(); |
||
25 | $startDateString = ''; |
||
26 | if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) { |
||
27 | /** @var \CultureFeed_Cdb_Data_Calendar_Period $period */ |
||
28 | $period = $cdbCalendar->current(); |
||
29 | $startDateString = $period->getDateFrom() . 'T00:00:00'; |
||
30 | } elseif ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) { |
||
31 | $firstTimestamp = $cdbCalendar->current(); |
||
32 | $cdbCalendarAsArray = iterator_to_array($cdbCalendar); |
||
33 | $timestamp = $this->getFirstTimestamp($cdbCalendarAsArray, $firstTimestamp); |
||
34 | if ($timestamp->getStartTime()) { |
||
35 | $startDateString = $timestamp->getDate() . 'T' . substr($timestamp->getStartTime(), 0, 5) . ':00'; |
||
36 | } else { |
||
37 | $startDateString = $timestamp->getDate() . 'T00:00:00'; |
||
38 | } |
||
39 | } |
||
40 | $startDate = !empty($startDateString) ? DateTimeFactory::dateTimeFromDateString($startDateString) : null; |
||
41 | |||
42 | // |
||
43 | // Get the end day. |
||
44 | // |
||
45 | $cdbCalendar->rewind(); |
||
46 | $endDateString = ''; |
||
47 | if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) { |
||
48 | /** @var \CultureFeed_Cdb_Data_Calendar_Period $period */ |
||
49 | $period = $cdbCalendar->current(); |
||
50 | $endDateString = $period->getDateTo() . 'T00:00:00'; |
||
51 | } elseif ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) { |
||
52 | $firstTimestamp = $cdbCalendar->current(); |
||
53 | /** @var \CultureFeed_Cdb_Data_Calendar_Timestamp $timestamp */ |
||
54 | $cdbCalendarAsArray = iterator_to_array($cdbCalendar); |
||
55 | $timestamp = $this->getLastTimestamp($cdbCalendarAsArray, $firstTimestamp); |
||
56 | if ($timestamp->getEndTime()) { |
||
57 | $endDateString = $timestamp->getDate() . 'T' . $timestamp->getEndTime(); |
||
58 | } else { |
||
59 | $endTime = $timestamp->getStartTime() ? $timestamp->getStartTime() : '00:00:00'; |
||
60 | $endDateString = $timestamp->getDate() . 'T' . $endTime; |
||
61 | } |
||
62 | } |
||
63 | $endDate = !empty($endDateString) ? DateTimeFactory::dateTimeFromDateString($endDateString) : null; |
||
64 | |||
65 | // |
||
66 | // Get the time stamps. |
||
67 | // |
||
68 | $cdbCalendar->rewind(); |
||
69 | $timestamps = []; |
||
70 | if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) { |
||
71 | $splitPeriods = []; |
||
72 | while ($cdbCalendar->valid()) { |
||
73 | /** @var \CultureFeed_Cdb_Data_Calendar_Timestamp $timestamp */ |
||
74 | $timestamp = $cdbCalendar->current(); |
||
75 | $cdbCalendar->next(); |
||
76 | |||
77 | $startTime = $timestamp->getStartTime() ? $timestamp->getStartTime() : '00:00:00'; |
||
78 | $startDateString = $timestamp->getDate() . 'T' . $startTime; |
||
79 | |||
80 | if ($timestamp->getEndTime()) { |
||
81 | $endDateString = $timestamp->getDate() . 'T' . $timestamp->getEndTime(); |
||
82 | } else { |
||
83 | $endDateString = $timestamp->getDate() . 'T' . $startTime; |
||
84 | } |
||
85 | |||
86 | $timestamp = $this->createTimestamp( |
||
87 | $startDateString, |
||
88 | $endDateString |
||
89 | ); |
||
90 | |||
91 | $index = intval($timestamp->getStartDate()->format('s')); |
||
92 | if ($index > 0) { |
||
93 | $splitPeriods[$index][] = $timestamp; |
||
94 | } else { |
||
95 | $timestamps[] = $timestamp; |
||
96 | } |
||
97 | } |
||
98 | |||
99 | $periods = array_map( |
||
100 | function (array $periodParts) { |
||
101 | $firstPart = array_shift($periodParts); |
||
102 | $lastPart = array_pop($periodParts); |
||
103 | return new Timestamp( |
||
104 | Chronos::instance($firstPart->getStartDate())->second(0), |
||
105 | $lastPart ? $lastPart->getEndDate() : $firstPart->getEndDate() |
||
106 | ); |
||
107 | }, |
||
108 | $splitPeriods |
||
109 | ); |
||
110 | |||
111 | $timestamps = array_merge($timestamps, $periods); |
||
112 | } |
||
113 | |||
114 | // |
||
115 | // Get the opening hours. |
||
116 | // |
||
117 | $cdbCalendar->rewind(); |
||
118 | $openingHours = []; |
||
119 | |||
120 | $weekSchema = null; |
||
121 | if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) { |
||
122 | $period = $cdbCalendar->current(); |
||
123 | $weekSchema = $period->getWeekScheme(); |
||
124 | } elseif ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_Permanent) { |
||
125 | $weekSchema = $cdbCalendar->getWeekScheme(); |
||
126 | } |
||
127 | |||
128 | if ($weekSchema) { |
||
129 | $openingHours = $this->createOpeningHoursFromWeekScheme($weekSchema); |
||
130 | } |
||
131 | |||
132 | if (isset($startDate) && isset($endDate)) { |
||
133 | $calendarTimeSpan = $this->createChronologicalTimestamp($startDate, $endDate); |
||
134 | } |
||
135 | |||
136 | // |
||
137 | // Get the calendar type. |
||
138 | // |
||
139 | $calendarType = null; |
||
140 | if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_Permanent) { |
||
141 | $calendarType = CalendarType::PERMANENT(); |
||
142 | } elseif ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) { |
||
143 | $calendarType = CalendarType::PERIODIC(); |
||
144 | } elseif ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) { |
||
145 | $calendarType = CalendarType::SINGLE(); |
||
146 | if (count($timestamps) > 1) { |
||
147 | $calendarType = CalendarType::MULTIPLE(); |
||
148 | } |
||
149 | } |
||
150 | |||
151 | // |
||
152 | // Create the calendar value object. |
||
153 | // |
||
154 | return new Calendar( |
||
155 | $calendarType, |
||
0 ignored issues
–
show
|
|||
156 | isset($calendarTimeSpan) ? $calendarTimeSpan->getStartDate() : null, |
||
157 | isset($calendarTimeSpan) ? $calendarTimeSpan->getEndDate() : null, |
||
158 | $timestamps, |
||
159 | $openingHours |
||
160 | ); |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * @param \CultureFeed_Cdb_Data_Calendar_Weekscheme|null $weekScheme |
||
165 | * @return Calendar |
||
166 | */ |
||
167 | public function createFromWeekScheme( |
||
168 | \CultureFeed_Cdb_Data_Calendar_Weekscheme $weekScheme = null |
||
169 | ) { |
||
170 | $openingHours = []; |
||
171 | |||
172 | if ($weekScheme) { |
||
173 | $openingHours = $this->createOpeningHoursFromWeekScheme($weekScheme); |
||
174 | } |
||
175 | |||
176 | return new Calendar( |
||
177 | CalendarType::PERMANENT(), |
||
178 | null, |
||
179 | null, |
||
180 | [], |
||
181 | $openingHours |
||
182 | ); |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * @param \CultureFeed_Cdb_Data_Calendar_Weekscheme $weekScheme |
||
187 | * @return OpeningHour[] |
||
188 | */ |
||
189 | private function createOpeningHoursFromWeekScheme( |
||
190 | \CultureFeed_Cdb_Data_Calendar_Weekscheme $weekScheme |
||
191 | ) { |
||
192 | $openingHours = []; |
||
193 | |||
194 | foreach ($weekScheme->getDays() as $day) { |
||
195 | if ($day->isOpen()) { |
||
196 | /** @var \CultureFeed_Cdb_Data_Calendar_OpeningTime[] $openingTimes */ |
||
197 | $openingTimes = $day->getOpeningTimes(); |
||
198 | |||
199 | // A day could be marked as open but without any hours. |
||
200 | // This means all day open but needs to be mapped to 00:00:00. |
||
201 | if (count($openingTimes) === 0) { |
||
202 | $openingTimes[] = new \CultureFeed_Cdb_Data_Calendar_OpeningTime( |
||
203 | '00:00:00', |
||
204 | '00:00:00' |
||
205 | ); |
||
206 | } |
||
207 | |||
208 | foreach ($openingTimes as $openingTime) { |
||
209 | $opens = \DateTime::createFromFormat( |
||
210 | 'H:i:s', |
||
211 | $openingTime->getOpenFrom() |
||
212 | ); |
||
213 | $closes = \DateTime::createFromFormat( |
||
214 | 'H:i:s', |
||
215 | $openingTime->getOpenTill() |
||
216 | ); |
||
217 | |||
218 | $openingHour = new OpeningHour( |
||
219 | OpeningTime::fromNativeDateTime($opens), |
||
0 ignored issues
–
show
It seems like
$opens defined by \DateTime::createFromFor...ingTime->getOpenFrom()) on line 209 can also be of type false ; however, CultuurNet\UDB3\Calendar...e::fromNativeDateTime() does only seem to accept object<DateTimeInterface> , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
220 | $closes ? OpeningTime::fromNativeDateTime($closes) : OpeningTime::fromNativeDateTime($opens), |
||
0 ignored issues
–
show
It seems like
$opens defined by \DateTime::createFromFor...ingTime->getOpenFrom()) on line 209 can also be of type false ; however, CultuurNet\UDB3\Calendar...e::fromNativeDateTime() does only seem to accept object<DateTimeInterface> , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
221 | new DayOfWeekCollection(DayOfWeek::fromNative($day->getDayName())) |
||
222 | ); |
||
223 | |||
224 | $openingHours = $this->addToOpeningHours($openingHour, ...$openingHours); |
||
225 | } |
||
226 | } |
||
227 | } |
||
228 | |||
229 | return $openingHours; |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * @param OpeningHour $newOpeningHour |
||
234 | * @param OpeningHour[] ...$openingHours |
||
235 | * @return OpeningHour[] |
||
236 | */ |
||
237 | private function addToOpeningHours( |
||
238 | OpeningHour $newOpeningHour, |
||
239 | OpeningHour ...$openingHours |
||
240 | ) { |
||
241 | foreach ($openingHours as $openingHour) { |
||
242 | if ($openingHour->hasEqualHours($newOpeningHour)) { |
||
0 ignored issues
–
show
|
|||
243 | $openingHour->addDayOfWeekCollection( |
||
0 ignored issues
–
show
|
|||
244 | $newOpeningHour->getDayOfWeekCollection() |
||
245 | ); |
||
246 | return $openingHours; |
||
247 | } |
||
248 | } |
||
249 | |||
250 | $openingHours[] = $newOpeningHour; |
||
251 | return $openingHours; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * @param string $startDateString |
||
256 | * @param string $endDateString |
||
257 | * @return Timestamp |
||
258 | */ |
||
259 | private function createTimestamp( |
||
260 | $startDateString, |
||
261 | $endDateString |
||
262 | ) { |
||
263 | $startDate = DateTimeFactory::dateTimeFromDateString($startDateString); |
||
264 | $endDate = DateTimeFactory::dateTimeFromDateString($endDateString); |
||
265 | |||
266 | return $this->createChronologicalTimestamp($startDate, $endDate); |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * End date might be before start date in cdbxml when event takes place |
||
271 | * between e.g. 9 PM and 3 AM (the next day). To keep the dates chronological we push the end to the next day. |
||
272 | * |
||
273 | * If the end dates does not make any sense at all, it is forced to the start date. |
||
274 | * |
||
275 | * @param DateTimeInterface $start |
||
276 | * @param DateTimeInterface $end |
||
277 | * |
||
278 | * @return Timestamp |
||
279 | */ |
||
280 | private function createChronologicalTimestamp(DateTimeInterface $start, DateTimeInterface $end) |
||
281 | { |
||
282 | $startDate = Chronos::instance($start); |
||
283 | $endDate = Chronos::instance($end); |
||
284 | |||
285 | if ($startDate->isSameDay($endDate) && $endDate->lt($startDate)) { |
||
286 | $endDate = $endDate->addDay(); |
||
287 | } |
||
288 | |||
289 | if ($endDate->lt($startDate)) { |
||
290 | $endDate = $startDate; |
||
291 | } |
||
292 | |||
293 | return new Timestamp($startDate, $endDate); |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * @param CultureFeed_Cdb_Data_Calendar_Timestamp[] $timestampList |
||
298 | * @param CultureFeed_Cdb_Data_Calendar_Timestamp $default |
||
299 | * @return CultureFeed_Cdb_Data_Calendar_Timestamp |
||
300 | */ |
||
301 | View Code Duplication | private function getLastTimestamp(array $timestampList, CultureFeed_Cdb_Data_Calendar_Timestamp $default) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
302 | { |
||
303 | $lastTimestamp = $default; |
||
304 | foreach ($timestampList as $timestamp) { |
||
305 | $currentEndDate = Chronos::parse($lastTimestamp->getEndDate()); |
||
306 | $endDate = Chronos::parse($timestamp->getEndDate()); |
||
307 | if ($currentEndDate->lt($endDate)) { |
||
308 | $lastTimestamp = $timestamp; |
||
309 | } |
||
310 | } |
||
311 | |||
312 | return $lastTimestamp; |
||
313 | } |
||
314 | |||
315 | /** |
||
316 | * @param CultureFeed_Cdb_Data_Calendar_Timestamp[] $timestampList |
||
317 | * @param CultureFeed_Cdb_Data_Calendar_Timestamp $default |
||
318 | * @return CultureFeed_Cdb_Data_Calendar_Timestamp |
||
319 | */ |
||
320 | View Code Duplication | private function getFirstTimestamp(array $timestampList, CultureFeed_Cdb_Data_Calendar_Timestamp $default) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
321 | { |
||
322 | $firstTimestamp = $default; |
||
323 | foreach ($timestampList as $timestamp) { |
||
324 | $currentStartTime = Chronos::parse($firstTimestamp->getDate()); |
||
325 | $startTime = Chronos::parse($timestamp->getDate()); |
||
326 | if ($currentStartTime->gt($startTime)) { |
||
327 | $firstTimestamp = $timestamp; |
||
328 | } |
||
329 | } |
||
330 | |||
331 | return $firstTimestamp; |
||
332 | } |
||
333 | } |
||
334 |
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: