GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

calculateTimeRangeForTransitions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php namespace CalDAVClient\Facade\Utils;
2
/**
3
 * Copyright 2017 OpenStack Foundation
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 * http://www.apache.org/licenses/LICENSE-2.0
8
 * Unless required by applicable law or agreed to in writing, software
9
 * distributed under the License is distributed on an "AS IS" BASIS,
10
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
 * See the License for the specific language governing permissions and
12
 * limitations under the License.
13
 **/
14
15
use DateTimeZone;
16
use DateTime;
17
use DateInterval;
18
use Eluceo\iCal\Component\Timezone;
19
use Eluceo\iCal\Component\Calendar;
20
use Eluceo\iCal\Component\TimezoneRule;
21
use Eluceo\iCal\Property\Event\RecurrenceRule;
22
23
/**
24
 * Class ICalTimeZoneBuilder
25
 * @package CalDAVClient\Facade\Utils
26
 */
27
final class ICalTimeZoneBuilder
28
{
29
30
    /**
31
     * @param DateTimeZone $time_zone
32
     * @return array
33
     */
34
    private static function calculateTimeRangeForTransitions(DateTimeZone $time_zone){
35
36
        $now           = new  DateTime('now', $time_zone);
37
        $year          = $now->format('Y');
38
        return [new DateTime('1/1/'.$year, $time_zone),  new DateTime('1/1/'.($year + 1), $time_zone)];
39
    }
40
41
    /**
42
     * @param array $trans
43
     * @param int $former_offset
44
     * @return DateTime
45
     */
46
    private static function convertStartDateFromUTC2Local(array $trans, $former_offset){
47
        $dt     = new DateTime($trans['time'], new DateTimeZone('UTC'));
48
        $hours  = abs($former_offset);
49
        // START TIME IS ON UTC and should be converted to local using former offset
50
        if($former_offset >= 0 )
51
            $dt->add(new DateInterval("PT{$hours}H"));
52
        else
53
            $dt->sub(new DateInterval("PT{$hours}H"));
54
55
        return $dt;
56
    }
57
58
    /**
59
     * @param DateTime $dt
60
     * @return RecurrenceRule
61
     */
62
    private static function calculateRecurrenceRule(DateTime $dt){
63
        $r_rule        = new RecurrenceRule();
64
        $r_rule->setFreq(RecurrenceRule::FREQ_YEARLY);
65
        $r_rule->setByMonth(intval($dt->format('m')));
66
        $r_rule->setByDay
67
        (
68
            self::translate2ByDay($dt)
69
        );
70
        return $r_rule;
71
    }
72
73
    /**
74
     * @param $offset
75
     * @return string
76
     */
77
    private static function calculateOffsetFrom($offset){
78
        return sprintf('%s%02d%02d', $offset >= 0 ? '+' : '-', abs($offset), abs(($offset - floor($offset)) * 60));
79
    }
80
81
    /**
82
     * @param  $offset
83
     * @return string
84
     */
85
    private static function calculateOffsetTo($offset){
86
        return sprintf('%s%02d%02d', $offset >= 0 ? '+' : '-', abs($offset), abs(($offset - floor($offset)) * 60));
87
    }
88
    /**
89
     * @param DateTimeZone $time_zone
90
     * @param string $calendar_prod_id
91
     * @param bool $with_calendar_envelope
92
     * @return Calendar|Timezone
93
     */
94
    public static function build(DateTimeZone $time_zone, $calendar_prod_id, $with_calendar_envelope = true){
95
96
        // get all transitions for one current year and next
97
        list($start_range, $end_range) = self::calculateTimeRangeForTransitions($time_zone);
98
        $transitions   = $time_zone->getTransitions($start_range->getTimestamp(), $end_range->getTimestamp());
99
        $vTimezone     = new Timezone($time_zone->getName());
100
        $former_offset = null;
101
102
        foreach ($transitions as $i => $trans) {
103
            $current_time_zone_rule = null;
104
105
            // skip the first entry...
106
            if ($i == 0) {
107
                // ... but remember the offset for the next TZOFFSETFROM value
108
                $former_offset = $trans['offset'] / 3600;
109
                continue;
110
            }
111
112
            // daylight saving time definition
113
            if ($trans['isdst']) {
114
                $current_time_zone_rule = new TimezoneRule(TimezoneRule::TYPE_DAYLIGHT);;
115
            }
116
            // standard time definition
117
            else {
118
                $current_time_zone_rule = new TimezoneRule(TimezoneRule::TYPE_STANDARD);;
119
            }
120
121
            if ($current_time_zone_rule) {
122
                $offset = $trans['offset'] / 3600;
123
                $dt     = self::convertStartDateFromUTC2Local($trans, $former_offset);
124
                $current_time_zone_rule->setDtStart($dt);
125
                $current_time_zone_rule->setTzOffsetFrom(self::calculateOffsetFrom($former_offset));
126
                $current_time_zone_rule->setTzOffsetTo(self::calculateOffsetTo($offset));
127
128
                // add abbreviated timezone name if available
129
                if (!empty($trans['abbr'])) {
130
                    $current_time_zone_rule->setTzName($trans['abbr']);
131
                }
132
133
                $former_offset = $offset;
134
                $current_time_zone_rule->setRecurrenceRule(self::calculateRecurrenceRule($dt));
135
                $vTimezone->addComponent($current_time_zone_rule);
136
            }
137
138
        }
139
        if($with_calendar_envelope) {
140
            $vCalendar = new Calendar(sprintf("'-//%s//EN'", $calendar_prod_id));
141
            $vCalendar->setTimezone($vTimezone);
142
            return $vCalendar;
143
        };
144
        return $vTimezone;
145
    }
146
147
    /**
148
     * The BYDAY rule part specifies a COMMA-separated list of days of
149
     * the week; SU indicates Sunday; MO indicates Monday; TU indicates
150
     * Tuesday; WE indicates Wednesday; TH indicates Thursday; FR
151
     * indicates Friday; and SA indicates Saturday.
152
     * Each BYDAY value can also be preceded by a positive (+n) or
153
     * negative (-n) integer.
154
     * @see https://tools.ietf.org/html/rfc5545#section-3.3.10 (BYDAY)
155
     * @see http://php.net/manual/en/datetime.formats.relative.php
156
     * @param DateTime $dt)
157
     * @return string
158
     */
159
    private static function translate2ByDay(DateTime $dt){
160
        $day_name = substr(strtoupper($dt->format('D')), 0,2);
161
        $ordinals = ['first', 'second', 'third', 'fourth', 'last'];
162
        $day_nbr  = 0;
163
        $is_last  = false;
164
165
        foreach($ordinals as $idx => $ord){
166
            $dt_n = self::buildOrdinalDateTime($ord, $dt);
167
            if($dt_n->format('Y-m-d') == $dt->format('Y-m-d')){
168
                $day_nbr = $idx  + 1;
169
                if($ord == 'last'){
170
                    $is_last = true;
171
                    $day_nbr  = 1;
172
                }
173
                break;
174
            }
175
        }
176
177
        return sprintf('%s%s%s', $is_last? '-':'', $day_nbr, $day_name);
178
    }
179
180
    /**
181
     * @param string $ord
182
     * @param DateTime $dt
183
     * @return DateTime
184
     */
185
    private static function buildOrdinalDateTime($ord, DateTime $dt){
186
        return new DateTime
187
        (
188
            date
189
            ("Y-m-d",
190
                strtotime
191
                (
192
                    sprintf
193
                    (
194
                        self::GetOrdinalDayQuery,
195
                        $ord,
196
                        $dt->format('l'),
197
                        $dt->format('F'),
198
                        $dt->format('Y')
199
                    )
200
                )
201
            )
202
        );
203
    }
204
205
    const GetOrdinalDayQuery = '%s %s of %s %s';
206
}