Completed
Pull Request — master (#243)
by Luc
05:05 queued 10s
created

createOpeningHoursFromWeekScheme()   D

Complexity

Conditions 9
Paths 8

Size

Total Lines 44
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 44
rs 4.909
c 0
b 0
f 0
cc 9
eloc 26
nc 8
nop 1
1
<?php
2
3
namespace CultuurNet\UDB3;
4
5
use CultuurNet\UDB3\Cdb\DateTimeFactory;
6
use ValueObjects\DateTime\Time;
7
use ValueObjects\DateTime\WeekDay;
8
9
class CalendarFactory
10
{
11
    public function createFromCdbCalendar(\CultureFeed_Cdb_Data_Calendar $cdbCalendar)
12
    {
13
        //
14
        // Get the calendar type.
15
        //
16
        $calendarType = '';
17
        if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_Permanent) {
18
            $calendarType = 'permanent';
19
        } else if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) {
20
            $calendarType = 'periodic';
21
        } else if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) {
22
            $calendarType = 'single';
23
            if (iterator_count($cdbCalendar) > 1) {
24
                $calendarType = 'multiple';
25
            }
26
        }
27
28
        //
29
        // Get the start day.
30
        //
31
        $cdbCalendar->rewind();
32
        $startDateString = '';
33
        if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) {
34
            /** @var \CultureFeed_Cdb_Data_Calendar_Period $period */
35
            $period = $cdbCalendar->current();
36
            $startDateString = $period->getDateFrom() . 'T00:00:00';
37 View Code Duplication
        } else if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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.

Loading history...
38
            /** @var \CultureFeed_Cdb_Data_Calendar_Timestamp $timestamp */
39
            $timestamp = $cdbCalendar->current();
40
            if ($timestamp->getStartTime()) {
41
                $startDateString = $timestamp->getDate() . 'T' . $timestamp->getStartTime();
42
            } else {
43
                $startDateString = $timestamp->getDate() . 'T00:00:00';
44
            }
45
        }
46
        $startDate = !empty($startDateString) ? DateTimeFactory::dateTimeFromDateString($startDateString) : null;
47
48
        //
49
        // Get the end day.
50
        //
51
        $cdbCalendar->rewind();
52
        $endDateString = '';
53
        if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) {
54
            /** @var \CultureFeed_Cdb_Data_Calendar_Period $period */
55
            $period = $cdbCalendar->current();
56
            $endDateString = $period->getDateTo() . 'T00:00:00';
57
        } else if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) {
58
            $firstTimestamp = $cdbCalendar->current();
59
            /** @var \CultureFeed_Cdb_Data_Calendar_Timestamp $timestamp */
60
            $cdbCalendarAsArray = iterator_to_array($cdbCalendar);
61
            $timestamp = iterator_count($cdbCalendar) > 1 ? end($cdbCalendarAsArray) : $firstTimestamp;
62 View Code Duplication
            if ($timestamp->getEndTime()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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.

Loading history...
63
                $endDateString = $timestamp->getDate() . 'T' . $timestamp->getEndTime();
64
            } else {
65
                $endTime = $timestamp->getStartTime() ? $timestamp->getStartTime() : '00:00:00';
66
                $endDateString = $timestamp->getDate() . 'T' . $endTime;
67
            }
68
        }
69
        $endDate = !empty($endDateString) ? DateTimeFactory::dateTimeFromDateString($endDateString) : null;
70
71
        //
72
        // Get the time stamps.
73
        //
74
        $cdbCalendar->rewind();
75
        $timestamps = [];
76
        if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) {
77
            while ($cdbCalendar->valid()) {
78
                /** @var \CultureFeed_Cdb_Data_Calendar_Timestamp $timestamp */
79
                $timestamp = $cdbCalendar->current();
80
                $cdbCalendar->next();
81
82
                if ($timestamp->getStartTime()) {
83
                    $startDateString = $timestamp->getDate() . 'T' . $timestamp->getStartTime();
84
85 View Code Duplication
                    if ($timestamp->getEndTime()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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.

Loading history...
86
                        $endDateString = $timestamp->getDate() . 'T' . $timestamp->getEndTime();
87
                    } else {
88
                        $endTime = $timestamp->getStartTime() ? $timestamp->getStartTime() : '00:00:00';
89
                        $endDateString = $timestamp->getDate() . 'T' . $endTime;
90
                    }
91
                }
92
93
                $timestamps[] = new Timestamp(
94
                    DateTimeFactory::dateTimeFromDateString($startDateString),
95
                    DateTimeFactory::dateTimeFromDateString($endDateString)
96
                );
97
            }
98
        }
99
100
        //
101
        // Get the opening hours.
102
        //
103
        $cdbCalendar->rewind();
104
        $openingHoursAsArray = [];
105
106
        $weekSchema = null;
107
        if ($cdbCalendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) {
108
            $period = $cdbCalendar->current();
109
            $weekSchema = $period->getWeekScheme();
110
        } else if ($cdbCalendar instanceof  \CultureFeed_Cdb_Data_Calendar_Permanent) {
111
            $weekSchema = $cdbCalendar->getWeekScheme();
112
        }
113
114
        if ($weekSchema) {
115
            $openingHours = $this->createOpeningHoursFromWeekScheme(
116
                $weekSchema
117
            );
118
119
            $openingHoursAsArray = $this->openingHoursToArray($openingHours);
120
        }
121
122
        //
123
        // Create the calendar value object.
124
        //
125
        return new Calendar(
126
            CalendarType::fromNative($calendarType),
127
            $startDate,
128
            $endDate,
129
            $timestamps,
130
            $openingHoursAsArray
131
        );
132
    }
133
134
    /**
135
     * @param \CultureFeed_Cdb_Data_Calendar_Weekscheme|null $weekscheme
136
     * @return Calendar
137
     */
138
    public function createFromWeekScheme(
139
        \CultureFeed_Cdb_Data_Calendar_Weekscheme $weekscheme = null
140
    ) {
141
        $openingHoursAsArray = [];
142
143
        if ($weekscheme) {
144
            $openingHours = $this->createOpeningHoursFromWeekScheme($weekscheme);
145
            $openingHoursAsArray = $this->openingHoursToArray($openingHours);
146
        }
147
148
        return new Calendar(
149
            CalendarType::PERMANENT(),
150
            null,
151
            null,
152
            [],
153
            $openingHoursAsArray
154
        );
155
    }
156
157
    /**
158
     * @param \CultureFeed_Cdb_Data_Calendar_Weekscheme $weekScheme
159
     * @return OpeningHour[]
160
     */
161
    private function createOpeningHoursFromWeekScheme(
162
        \CultureFeed_Cdb_Data_Calendar_Weekscheme $weekScheme
163
    ) {
164
        $days = $weekScheme->getDays();
165
166
        /** @var OpeningHour[] $openingHours */
167
        $openingHours = [];
168
        foreach ($days as $day) {
169
            if ($day->isOpen()) {
170
                /** @var \CultureFeed_Cdb_Data_Calendar_OpeningTime[] $openingTimes */
171
                $openingTimes = $day->getOpeningTimes();
172
173
                $opens = \DateTime::createFromFormat(
174
                    'H:i:s',
175
                    $openingTimes ? $openingTimes[0]->getOpenFrom() : '00:00:00'
176
                );
177
                $closes = \DateTime::createFromFormat(
178
                    'H:i:s',
179
                    $openingTimes ? $openingTimes[0]->getOpenTill() : '00:00:00'
180
                );
181
182
                $newOpeningHour = new OpeningHour(
183
                    WeekDay::fromNative(ucfirst($day->getDayName())),
184
                    Time::fromNativeDateTime($opens),
0 ignored issues
show
Security Bug introduced by
It seems like $opens defined by \DateTime::createFromFor...penFrom() : '00:00:00') on line 173 can also be of type false; however, ValueObjects\DateTime\Time::fromNativeDateTime() does only seem to accept object<DateTime>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
185
                    $closes ? Time::fromNativeDateTime($closes) : Time::fromNativeDateTime($opens)
0 ignored issues
show
Security Bug introduced by
It seems like $opens defined by \DateTime::createFromFor...penFrom() : '00:00:00') on line 173 can also be of type false; however, ValueObjects\DateTime\Time::fromNativeDateTime() does only seem to accept object<DateTime>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
186
                );
187
188
                $merged = false;
189
                foreach ($openingHours as $openingHour) {
190
                    if ($openingHour->equalHours($newOpeningHour)) {
191
                        $openingHour->mergeWeekday($newOpeningHour);
192
                        $merged = true;
193
                        break;
194
                    }
195
                }
196
197
                if (!$merged) {
198
                    $openingHours[] = $newOpeningHour;
199
                }
200
            }
201
        }
202
203
        return $openingHours;
204
    }
205
206
    /**
207
     * @param array $openingHours
208
     * @return array
209
     */
210
    private function openingHoursToArray(array $openingHours)
211
    {
212
        $openingHoursAsArray = [];
213
214
        if (count($openingHours) > 0) {
215
            foreach ($openingHours as $openingHour) {
216
                $openingHoursAsArray[] = [
217
                    'dayOfWeek' => array_map(
218
                        function (WeekDay $weekDay) {
219
                            return strtolower($weekDay->toNative());
220
                        },
221
                        $openingHour->getWeekDays()
222
                    ),
223
                    'opens' => $openingHour->getOpens()->toNativeDateTime()->format('H:i'),
224
                    'closes' => (string)$openingHour->getCloses()->toNativeDateTime()->format('H:i'),
225
                ];
226
            }
227
        }
228
229
        return $openingHoursAsArray;
230
    }
231
}
232