Completed
Push — master ( ad2e84...81aee3 )
by Tim
06:21
created

IcsReaderService::getEventsFixedEndDate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
/**
4
 * ICS Service.
5
 */
6
declare(strict_types=1);
7
8
namespace HDNET\Calendarize\Service;
9
10
use HDNET\Calendarize\Service\TimeTable\ExternalTimeTable;
11
use HDNET\Calendarize\Utility\DateTimeUtility;
12
use JMBTechnologyLimited\ICalDissect\ICalEvent;
13
use JMBTechnologyLimited\ICalDissect\ICalParser;
14
use Sabre\VObject\Reader;
15
use TYPO3\CMS\Core\Utility\GeneralUtility;
16
17
/**
18
 * ICS Service.
19
 */
20
class IcsReaderService extends AbstractService
21
{
22
    /**
23
     * Generate the times of the given URL.
24
     *
25
     * @param string $url
26
     *
27
     * @return array
28
     */
29
    public function getTimes(string $url): array
30
    {
31
        $fileName = $this->getCachedUrlFile($url);
32
        $times = $this->buildWithICalDissect($fileName);
33
        // $test = $this->buildWithVObject($fileName);
34
        return $times;
35
    }
36
37
    /**
38
     * Build with iCal dissect.
39
     *
40
     * @param string $filename
41
     *
42
     * @return array
43
     */
44
    protected function buildWithICalDissect(string $filename): array
45
    {
46
        $backend = new ICalParser();
47
        if (!$backend->parseFromFile($filename)) {
48
            return [];
49
        }
50
        $events = $backend->getEvents();
51
        $times = [];
52
        foreach ($events as $event) {
53
            /** @var $event ICalEvent */
54
            $startTime = DateTimeUtility::getDaySecondsOfDateTime($event->getStart());
55
            $endTime = DateTimeUtility::getDaySecondsOfDateTime($event->getEnd());
56
            if (ExternalTimeTable::DAY_END === $endTime) {
57
                $endTime = 0;
58
            }
59
60
            $times[] = [
61
                'start_date' => $event->getStart(),
62
                'end_date' => $this->getEventsFixedEndDate($event),
63
                'start_time' => $startTime,
64
                'end_time' => $endTime,
65
                'all_day' => 0 === $endTime,
66
            ];
67
        }
68
69
        return $times;
70
    }
71
72
    /**
73
     * Build with Vobject.
74
     *
75
     * @param string $filename
76
     *
77
     * @return array
78
     *
79
     * @todo implement
80
     */
81
    protected function buildWithVObject(string $filename): array
82
    {
83
        $vcalendar = Reader::read(
84
            GeneralUtility::getUrl($filename)
85
        );
86
        $times = [];
87
        foreach ($vcalendar->VEVENT as $event) {
88
            /*DTSTAMP => array(1 item)
89
      UID => array(1 item)
90
      DTSTART => array(1 item)
91
      DTEND => array(1 item)*/
92
            //DebuggerUtility::var_dump($event->TESTST);
93
            //DebuggerUtility::var_dump($event->DTSTAMP);
94
            //DebuggerUtility::var_dump($event->DTSTART);
95
            //DebuggerUtility::var_dump($event->DTEND);
96
97
            $times[] = [
98
                'start_date' => $event->DTSTART->getDateTime(),
99
                'end_date' => 0, // $this->getEventsFixedEndDate($event),
100
                'start_time' => 0,
101
                'end_time' => 0,
102
                'all_day' => true,
103
            ];
104
        }
105
106
        return $times;
107
    }
108
109
    /**
110
     * Fixes a parser related bug where the DTEND is EXCLUSIVE.
111
     * The parser uses it inclusive so every event is one day
112
     * longer than it should be.
113
     *
114
     * @param ICalEvent $event
115
     *
116
     * @return \DateTime
117
     */
118
    protected function getEventsFixedEndDate(ICalEvent $event)
119
    {
120
        if (!$event->getEnd() instanceof \DateTimeInterface) {
121
            return $event->getStart();
122
        }
123
124
        $end = clone $event->getEnd();
125
        $end->sub(new \DateInterval('P1D'));
126
        if ($end->format('Ymd') === $event->getStart()->format('Ymd')) {
127
            return $end;
128
        }
129
130
        return $event->getEnd();
131
    }
132
133
    /**
134
     * Get cached URL file.
135
     *
136
     * @param string $url
137
     *
138
     * @return string
139
     */
140
    protected function getCachedUrlFile(string $url): string
141
    {
142
        $tempFileName = $this->getCheckedCacheFolder() . \md5($url);
143
        if (!\is_file($tempFileName) || \filemtime($tempFileName) < (\time() - DateTimeUtility::SECONDS_HOUR)) {
144
            $icsFile = GeneralUtility::getUrl($url);
145
            GeneralUtility::writeFile($tempFileName, $icsFile);
146
        }
147
148
        return $tempFileName;
149
    }
150
151
    /**
152
     * Return the cache folder and check if the folder exists.
153
     *
154
     * @return string
155
     */
156
    protected function getCheckedCacheFolder(): string
157
    {
158
        $cacheFolder = GeneralUtility::getFileAbsFileName('typo3temp/var/transient/calendarize/');
159
        if (!\is_dir($cacheFolder)) {
160
            GeneralUtility::mkdir_deep($cacheFolder);
161
        }
162
163
        return $cacheFolder;
164
    }
165
}
166