iCalDate::RenderGMT()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
4
if (!function_exists('dbg_error_log')) {
5
6
	function dbg_error_log()
7
	{
8
	}
9
10
}
11
12
/**
13
* Class for parsing RRule and getting us the dates
14
*
15
* @package   awl
16
* @subpackage   caldav
17
* @author    Andrew McMillan <[email protected]>
18
* @copyright Catalyst .Net Ltd
19
* @license   http://gnu.org/copyleft/gpl.html GNU GPL v2
20
*/
21
22
$GLOBALS['ical_weekdays'] = array( 'SU' => 0, 'MO' => 1, 'TU' => 2, 'WE' => 3, 'TH' => 4, 'FR' => 5, 'SA' => 6 );
23
24
if (!class_exists('iCalDate')) {
25
26
	/**
27
	* A Class for handling dates in iCalendar format.  We do make the simplifying assumption
28
	* that all date handling in here is normalised to GMT.  One day we might provide some
29
	* functions to do that, but for now it is done externally.
30
	*
31
	* @package awl
32
	*/
33
	class iCalDate {
34
	  /**#@+
35
	  * @access private
36
	  */
37
	
38
	  /** Text version */
39
	  var $_text;
40
	
41
	  /** Epoch version */
42
	  var $_epoch;
43
	
44
	  /** Fragmented parts */
45
	  var $_yy;
46
	  var $_mo;
47
	  var $_dd;
48
	  var $_hh;
49
	  var $_mi;
50
	  var $_ss;
51
	  var $_tz;
52
	
53
	  /** Which day of the week does the week start on */
54
	  var $_wkst;
55
	
56
	  /**#@-*/
57
	
58
	  /**
59
	  * The constructor takes either an iCalendar date, a text string formatted as
60
	  * an iCalendar date, or epoch seconds.
61
	  */
62
	  function iCalDate( $input ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
63
	    if ( gettype($input) == 'object' ) {
64
	      $this->_text = $input->_text;
65
	      $this->_epoch = $input->_epoch;
66
	      $this->_yy = $input->_yy;
67
	      $this->_mo = $input->_mo;
68
	      $this->_dd = $input->_dd;
69
	      $this->_hh = $input->_hh;
70
	      $this->_mi = $input->_mi;
71
	      $this->_ss = $input->_ss;
72
	      $this->_tz = $input->_tz;
73
	      return;
74
	    }
75
	
76
	    $this->_wkst = 1; // Monday
77
	    if ( preg_match( '/^\d{8}[T ]\d{6}$/', $input ) ) {
78
	      $this->SetLocalDate($input);
79
	    }
80
	    else if ( preg_match( '/^\d{8}[T ]\d{6}Z$/', $input ) ) {
81
	      $this->SetGMTDate($input);
82
	    }
83
	    else if ( intval($input) == 0 ) {
84
	      $this->SetLocalDate(strtotime($input));
85
	      return;
86
	    }
87
	    else {
88
	      $this->SetEpochDate($input);
89
	    }
90
	  }
91
	
92
	
93
	  /**
94
	  * Set the date from a text string
95
	  */
96
	  function SetGMTDate( $input ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
97
	    $this->_text = $input;
98
	    $this->_PartsFromText();
99
	    $this->_GMTEpochFromParts();
100
	  }
101
	
102
	
103
	  /**
104
	  * Set the date from a text string
105
	  */
106
	  function SetLocalDate( $input ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
107
	    $this->_text = $input;
108
	    $this->_PartsFromText();
109
	    $this->_EpochFromParts();
110
	  }
111
	
112
	
113
	  /**
114
	  * Set the date from an epoch
115
	  */
116
	  function SetEpochDate( $input ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
117
	    $this->_epoch = intval($input);
118
	    $this->_TextFromEpoch();
119
	    $this->_PartsFromText();
120
	  }
121
	
122
	
123
	  /**
124
	  * Given an epoch date, convert it to text
125
	  */
126
	  function _TextFromEpoch() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
127
	    $this->_text = date('Ymd\THis', $this->_epoch );
128
	    dbg_error_log( "RRule", " Text %s from epoch %d", $this->_text, $this->_epoch );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
129
	  }
130
	
131
	  /**
132
	  * Given a GMT epoch date, convert it to text
133
	  */
134
	  function _GMTTextFromEpoch() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
135
	    $this->_text = gmdate('Ymd\THis', $this->_epoch );
136
	    dbg_error_log( "RRule", " Text %s from epoch %d", $this->_text, $this->_epoch );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
137
	  }
138
	
139
	  /**
140
	  * Given a text date, convert it to parts
141
	  */
142
	  function _PartsFromText() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
143
	    $this->_yy = intval(substr($this->_text,0,4));
144
	    $this->_mo = intval(substr($this->_text,4,2));
145
	    $this->_dd = intval(substr($this->_text,6,2));
146
	    $this->_hh = intval(substr($this->_text,9,2));
147
	    $this->_mi = intval(substr($this->_text,11,2));
148
	    $this->_ss = intval(substr($this->_text,13,2));
149
	  }
150
	
151
	
152
	  /**
153
	  * Given a GMT text date, convert it to an epoch
154
	  */
155
	  function _GMTEpochFromParts() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
156
	    $this->_epoch = gmmktime ( $this->_hh, $this->_mi, $this->_ss, $this->_mo, $this->_dd, $this->_yy );
157
	    dbg_error_log( "RRule", " Epoch %d from %04d-%02d-%02d %02d:%02d:%02d", $this->_epoch, $this->_yy, $this->_mo, $this->_dd, $this->_hh, $this->_mi, $this->_ss );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
158
	  }
159
	
160
	
161
	  /**
162
	  * Given a local text date, convert it to an epoch
163
	  */
164
	  function _EpochFromParts() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
165
	    $this->_epoch = mktime ( $this->_hh, $this->_mi, $this->_ss, $this->_mo, $this->_dd, $this->_yy );
166
	    dbg_error_log( "RRule", " Epoch %d from %04d-%02d-%02d %02d:%02d:%02d", $this->_epoch, $this->_yy, $this->_mo, $this->_dd, $this->_hh, $this->_mi, $this->_ss );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
167
	  }
168
	
169
	
170
	  /**
171
	  * Set the day of week used for calculation of week starts
172
	  *
173
	  * @param string $weekstart The day of the week which is the first business day.
174
	  */
175
	  function SetWeekStart($weekstart) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
176
	    global $ical_weekdays;
177
	    $this->_wkst = $ical_weekdays[$weekstart];
178
	  }
179
	
180
	
181
	  /**
182
	  * Set the day of week used for calculation of week starts
183
	  */
184
	  function Render( $fmt = 'Y-m-d H:i:s' ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
185
	    return date( $fmt, $this->_epoch );
186
	  }
187
	
188
	
189
	  /**
190
	  * Render the date as GMT
191
	  */
192
	  function RenderGMT( $fmt = 'Ymd\THis\Z' ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
193
	    return gmdate( $fmt, $this->_epoch );
194
	  }
195
	
196
	
197
	  /**
198
	  * No of days in a month 1(Jan) - 12(Dec)
199
	  */
200
	  function DaysInMonth( $mo=false, $yy=false ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
201
	    if ( $mo === false ) $mo = $this->_mo;
202
	    switch( $mo ) {
203
	      case  1: // January
204
	      case  3: // March
205
	      case  5: // May
206
	      case  7: // July
207
	      case  8: // August
208
	      case 10: // October
209
	      case 12: // December
210
	        return 31;
211
	        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
212
	
213
	      case  4: // April
214
	      case  6: // June
215
	      case  9: // September
216
	      case 11: // November
217
	        return 30;
218
	        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
219
	
220
	      case  2: // February
221
	        if ( $yy === false ) $yy = $this->_yy;
222
	        if ( (($yy % 4) == 0) && ((($yy % 100) != 0) || (($yy % 400) == 0) ) ) return 29;
223
	        return 28;
224
	        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
225
	
226
	      default:
227
	        dbg_error_log( "ERROR"," Invalid month of '%s' passed to DaysInMonth", $mo );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'ERROR'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
228
	        break;
229
	
230
	    }
231
	  }
232
	
233
	
234
	  /**
235
	  * Set the day in the month to what we have been given
236
	  */
237
	  function SetMonthDay( $dd ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
238
	    if ( $dd == $this->_dd ) return; // Shortcut
239
	    $dd = min($dd,$this->DaysInMonth());
240
	    $this->_dd = $dd;
241
	    $this->_EpochFromParts();
242
	    $this->_TextFromEpoch();
243
	  }
244
	
245
	
246
	  /**
247
	  * Add some number of months to a date
248
	  */
249
	  function AddMonths( $mo ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
250
	    dbg_error_log( "RRule", " Adding %d months to %s", $mo, $this->_text );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
251
	    $this->_mo += $mo;
252
	    while ( $this->_mo < 1 ) {
253
	      $this->_mo += 12;
254
	      $this->_yy--;
255
	    }
256
	    while ( $this->_mo > 12 ) {
257
	      $this->_mo -= 12;
258
	      $this->_yy++;
259
	    }
260
	
261
	    if ( ($this->_dd > 28 && $this->_mo == 2) || $this->_dd > 30 ) {
262
	      // Ensure the day of month is still reasonable and coerce to last day of month if needed
263
	      $dim = $this->DaysInMonth();
264
	      if ( $this->_dd > $dim ) {
265
	        $this->_dd = $dim;
266
	      }
267
	    }
268
	    $this->_EpochFromParts();
269
	    $this->_TextFromEpoch();
270
	    dbg_error_log( "RRule", " Added %d months and got %s", $mo, $this->_text );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
271
	  }
272
	
273
	
274
	  /**
275
	  * Add some integer number of days to a date
276
	  */
277
	  function AddDays( $dd ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
278
	    $at_start = $this->_text;
279
	    $this->_dd += $dd;
280
	    while ( 1 > $this->_dd ) {
281
	      $this->_mo--;
282
	      if ( $this->_mo < 1 ) {
283
	        $this->_mo += 12;
284
	        $this->_yy--;
285
	      }
286
	      $this->_dd += $this->DaysInMonth();
287
	    }
288
	    while ( ($dim = $this->DaysInMonth($this->_mo)) < $this->_dd ) {
0 ignored issues
show
Documentation introduced by
$this->_mo is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
289
	      $this->_dd -= $dim;
290
	      $this->_mo++;
291
	      if ( $this->_mo > 12 ) {
292
	        $this->_mo -= 12;
293
	        $this->_yy++;
294
	      }
295
	    }
296
	    $this->_EpochFromParts();
297
	    $this->_TextFromEpoch();
298
	    dbg_error_log( "RRule", " Added %d days to %s and got %s", $dd, $at_start, $this->_text );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
299
	  }
300
	
301
	
302
	  /**
303
	  * Add duration
304
	  */
305
	  function AddDuration( $duration ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
306
	    if ( strstr($duration,'T') === false ) $duration .= 'T';
307
	    list( $sign, $days, $time ) = preg_split( '/[PT]/', $duration );
308
	    $sign = ( $sign == "-" ? -1 : 1);
309
	    dbg_error_log( "RRule", " Adding duration to '%s' of sign: %d,  days: %s,  time: %s", $this->_text, $sign, $days, $time );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
310
	    if ( preg_match( '/(\d+)(D|W)/', $days, $matches ) ) {
311
	      $days = intval($matches[1]);
312
	      if ( $matches[2] == 'W' ) $days *= 7;
313
	      $this->AddDays( $days * $sign );
314
	    }
315
	    $hh = 0;    $mi = 0;    $ss = 0;
316
	    if ( preg_match( '/(\d+)(H)/', $time, $matches ) )  $hh = $matches[1];
317
	    if ( preg_match( '/(\d+)(M)/', $time, $matches ) )  $mi = $matches[1];
318
	    if ( preg_match( '/(\d+)(S)/', $time, $matches ) )  $ss = $matches[1];
319
	
320
	    dbg_error_log( "RRule", " Adding %02d:%02d:%02d * %d to %02d:%02d:%02d", $hh, $mi, $ss, $sign, $this->_hh, $this->_mi, $this->_ss );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
321
	    $this->_hh += ($hh * $sign);
322
	    $this->_mi += ($mi * $sign);
323
	    $this->_ss += ($ss * $sign);
324
	
325 View Code Duplication
	    if ( $this->_ss < 0 ) {  $this->_mi -= (intval(abs($this->_ss/60))+1); $this->_ss += ((intval(abs($this->_mi/60))+1) * 60); }
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...
326 View Code Duplication
	    if ( $this->_ss > 59) {  $this->_mi += (intval(abs($this->_ss/60))+1); $this->_ss -= ((intval(abs($this->_mi/60))+1) * 60); }
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...
327 View Code Duplication
	    if ( $this->_mi < 0 ) {  $this->_hh -= (intval(abs($this->_mi/60))+1); $this->_mi += ((intval(abs($this->_mi/60))+1) * 60); }
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...
328 View Code Duplication
	    if ( $this->_mi > 59) {  $this->_hh += (intval(abs($this->_mi/60))+1); $this->_mi -= ((intval(abs($this->_mi/60))+1) * 60); }
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...
329 View Code Duplication
	    if ( $this->_hh < 0 ) {  $this->AddDays( -1 * (intval(abs($this->_hh/24))+1) );  $this->_hh += ((intval(abs($this->_hh/24))+1)*24);  }
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...
330 View Code Duplication
	    if ( $this->_hh > 23) {  $this->AddDays( (intval(abs($this->_hh/24))+1) );       $this->_hh -= ((intval(abs($this->_hh/24))+1)*24);  }
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...
331
	
332
	    $this->_EpochFromParts();
333
	    $this->_TextFromEpoch();
334
	  }
335
	
336
	
337
	  /**
338
	  * Produce an iCalendar format DURATION for the difference between this an another iCalDate
339
	  *
340
	  * @param date $from The start of the period
341
	  * @return string The date difference, as an iCalendar duration format
342
	  */
343
	  function DateDifference( $from ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
344
	    if ( !is_object($from) ) {
345
	      $from = new iCalDate($from);
346
	    }
347
	    if ( $from->_epoch < $this->_epoch ) {
348
	      /** One way to simplify is to always go for positive differences */
349
	      return( "-". $from->DateDifference( $this ) );
0 ignored issues
show
Documentation introduced by
$this is of type this<iCalDate>, but the function expects a object<date>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
350
	    }
351
	//    if ( $from->_yy == $this->_yy && $from->_mo == $this->_mo ) {
352
	      /** Also somewhat simpler if we can use seconds */
353
	      $diff = $from->_epoch - $this->_epoch;
354
	      $result = "";
355
	      if ( $diff >= 86400) {
356
	        $result = intval($diff / 86400);
357
	        $diff = $diff % 86400;
358
	        if ( $diff == 0 && (($result % 7) == 0) ) {
359
	          // Duration is an integer number of weeks.
360
	          $result .= intval($result / 7) . "W";
361
	          return $result;
362
	        }
363
	        $result .= "D";
364
	      }
365
	      $result = "P".$result."T";
366
	      if ( $diff >= 3600) {
367
	        $result .= intval($diff / 3600) . "H";
368
	        $diff = $diff % 3600;
369
	      }
370
	      if ( $diff >= 60) {
371
	        $result .= intval($diff / 60) . "M";
372
	        $diff = $diff % 60;
373
	      }
374
	      if ( $diff > 0) {
375
	        $result .= intval($diff) . "S";
376
	      }
377
	      return $result;
378
	//    }
379
	
380
	/**
381
	* From an intense reading of RFC2445 it appears that durations which are not expressible
382
	* in Weeks/Days/Hours/Minutes/Seconds are invalid.
383
	*  ==> This code is not needed then :-)
384
	    $yy = $from->_yy - $this->_yy;
385
	    $mo = $from->_mo - $this->_mo;
386
	    $dd = $from->_dd - $this->_dd;
387
	    $hh = $from->_hh - $this->_hh;
388
	    $mi = $from->_mi - $this->_mi;
389
	    $ss = $from->_ss - $this->_ss;
390
	
391
	    if ( $ss < 0 ) {  $mi -= 1;   $ss += 60;  }
392
	    if ( $mi < 0 ) {  $hh -= 1;   $mi += 60;  }
393
	    if ( $hh < 0 ) {  $dd -= 1;   $hh += 24;  }
394
	    if ( $dd < 0 ) {  $mo -= 1;   $dd += $this->DaysInMonth();  } // Which will use $this->_(mo|yy) - seemingly sensible
395
	    if ( $mo < 0 ) {  $yy -= 1;   $mo += 12;  }
396
	
397
	    $result = "";
398
	    if ( $yy > 0) {    $result .= $yy."Y";   }
399
	    if ( $mo > 0) {    $result .= $mo."M";   }
400
	    if ( $dd > 0) {    $result .= $dd."D";   }
401
	    $result .= "T";
402
	    if ( $hh > 0) {    $result .= $hh."H";   }
403
	    if ( $mi > 0) {    $result .= $mi."M";   }
404
	    if ( $ss > 0) {    $result .= $ss."S";   }
405
	    return $result;
406
	*/
407
	  }
408
	
409
	  /**
410
	  * Test to see if our _mo matches something in the list of months we have received.
411
	  * @param string $monthlist A comma-separated list of months.
412
	  * @return boolean Whether this date falls within one of those months.
413
	  */
414
	  function TestByMonth( $monthlist ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
415
	    dbg_error_log( "RRule", " Testing BYMONTH %s against month %d", (isset($monthlist) ? $monthlist : "no month list"), $this->_mo );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
416
	    if ( !isset($monthlist) ) return true;  // If BYMONTH is not specified any month is OK
417
	    $months = array_flip(split( ',',$monthlist ));
418
	    return isset($months[$this->_mo]);
419
	  }
420
	
421
	  /**
422
	  * Applies any BYDAY to the month to return a set of days
423
	  * @param string $byday The BYDAY rule
424
	  * @return array An array of the day numbers for the month which meet the rule.
425
	  */
426
	  function GetMonthByDay($byday) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
427
	    dbg_error_log( "RRule", " Applying BYDAY %s to month", $byday );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
428
	    $days_in_month = $this->DaysInMonth();
429
	    $dayrules = split(',',$byday);
430
	    $set = array();
431
	    $first_dow = (date('w',$this->_epoch) - $this->_dd + 36) % 7;
432
	    foreach( $dayrules AS $k => $v ) {
433
	      $days = $this->MonthDays($first_dow,$days_in_month,$v);
434
	      foreach( $days AS $k2 => $v2 ) {
435
	        $set[$v2] = $v2;
436
	      }
437
	    }
438
	    asort( $set, SORT_NUMERIC );
439
	    return $set;
440
	  }
441
	
442
	  /**
443
	  * Applies any BYMONTHDAY to the month to return a set of days
444
	  * @param string $bymonthday The BYMONTHDAY rule
445
	  * @return array An array of the day numbers for the month which meet the rule.
446
	  */
447
	  function GetMonthByMonthDay($bymonthday) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
448
	    dbg_error_log( "RRule", " Applying BYMONTHDAY %s to month", $bymonthday );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
449
	    $days_in_month = $this->DaysInMonth();
450
	    $dayrules = split(',',$bymonthday);
451
	    $set = array();
452
	    foreach( $dayrules AS $k => $v ) {
453
	      $v = intval($v);
454
	      if ( $v > 0 && $v <= $days_in_month ) $set[$v] = $v;
455
	    }
456
	    asort( $set, SORT_NUMERIC );
457
	    return $set;
458
	  }
459
	
460
	
461
	  /**
462
	  * Applies any BYDAY to the week to return a set of days
463
	  * @param string $byday The BYDAY rule
464
	  * @param string $increasing When we are moving by months, we want any day of the week, but when by day we only want to increase. Default false.
465
	  * @return array An array of the day numbers for the week which meet the rule.
466
	  */
467
	  function GetWeekByDay($byday, $increasing = false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
468
	    global $ical_weekdays;
469
	    dbg_error_log( "RRule", " Applying BYDAY %s to week", $byday );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
470
	    $days = explode(',',$byday);
471
	    $dow = date('w',$this->_epoch);
472
	    $set = array();
473
	    foreach( $days AS $k => $v ) {
474
	    	
475
	      if (!isset($ical_weekdays[$v]))
476
	      {
477
	      	 continue;
478
	      }
479
	    	
480
	      $daynum = $ical_weekdays[$v];
481
	      $dd = $this->_dd - $dow + $daynum;
482
	      if ( $daynum < $this->_wkst ) $dd += 7;
483
	      if ( $dd > $this->_dd || !$increasing ) $set[$dd] = $dd;
0 ignored issues
show
Bug Best Practice introduced by
The expression $increasing of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
484
	    }
485
	    asort( $set, SORT_NUMERIC );
486
	
487
	    return $set;
488
	  }
489
	
490
	
491
	  /**
492
	  * Test if $this is greater than the date parameter
493
	  * @param string $lesser The other date, as a local time string
494
	  * @return boolean True if $this > $lesser
495
	  */
496
	  function GreaterThan($lesser) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
497
	    if ( is_object($lesser) ) {
498
	//      dbg_error_log( "RRule", " Comparing %s with %s", $this->_text, $lesser->_text );
499
	      return ( $this->_text > $lesser->_text );
500
	    }
501
	//    dbg_error_log( "RRule", " Comparing %s with %s", $this->_text, $lesser );
502
	    return ( $this->_text > $lesser );  // These sorts of dates are designed that way...
503
	  }
504
	
505
	
506
	  /**
507
	  * Test if $this is less than the date parameter
508
	  * @param string $greater The other date, as a local time string
509
	  * @return boolean True if $this < $greater
510
	  */
511
	  function LessThan($greater) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
512
	    if ( is_object($greater) ) {
513
	//      dbg_error_log( "RRule", " Comparing %s with %s", $this->_text, $greater->_text );
514
	      return ( $this->_text < $greater->_text );
515
	    }
516
	//    dbg_error_log( "RRule", " Comparing %s with %s", $this->_text, $greater );
517
	    return ( $this->_text < $greater );  // These sorts of dates are designed that way...
518
	  }
519
	
520
	
521
	  /**
522
	  * Given a MonthDays string like "1MO", "-2WE" return an integer day of the month.
523
	  *
524
	  * @param string $dow_first The day of week of the first of the month.
525
	  * @param string $days_in_month The number of days in the month.
526
	  * @param string $dayspec The specification for a month day (or days) which we parse.
527
	  *
528
	  * @return array An array of the day numbers for the month which meet the rule.
529
	  */
530
	  function &MonthDays($dow_first, $days_in_month, $dayspec) {
531
	    global $ical_weekdays;
532
	    dbg_error_log( "RRule", "MonthDays: Getting days for '%s'. %d days starting on a %d", $dayspec, $days_in_month, $dow_first );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
533
	    $set = array();
534
	    preg_match( '/([0-9-]*)(MO|TU|WE|TH|FR|SA|SU)/', $dayspec, $matches);
535
	    $numeric = intval($matches[1]);
536
	    $dow = $ical_weekdays[$matches[2]];
537
	
538
	    $first_matching_day = 1 + ($dow - $dow_first);
539
	    while ( $first_matching_day < 1 ) $first_matching_day += 7;
540
	
541
	    dbg_error_log( "RRule", " MonthDays: Looking at %d for first match on (%s/%s), %d for numeric", $first_matching_day, $matches[1], $matches[2], $numeric );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
542
	
543
	    while( $first_matching_day <= $days_in_month ) {
544
	      $set[] = $first_matching_day;
545
	      $first_matching_day += 7;
546
	    }
547
	
548
	    if ( $numeric != 0 ) {
549
	      if ( $numeric < 0 ) {
550
	        $numeric += count($set);
551
	      }
552
	      else {
553
	        $numeric--;
554
	      }
555
	      $answer = $set[$numeric];
556
	      $set = array( $answer => $answer );
557
	    }
558
	    else {
559
	      $answers = $set;
560
	      $set = array();
561
	      foreach( $answers AS $k => $v ) {
562
	        $set[$v] = $v;
563
	      }
564
	    }
565
	
566
	//    dbg_log_array( "RRule", 'MonthDays', $set, false );
567
	
568
	    return $set;
569
	  }
570
	
571
	
572
	  /**
573
	  * Given set position descriptions like '1', '3', '11', '-3' or '-1' and a set,
574
	  * return the subset matching the list of set positions.
575
	  *
576
	  * @param string $bysplist  The list of set positions.
577
	  * @param string $set The set of days that we will apply the positions to.
578
	  *
579
	  * @return array The subset which matches.
580
	  */
581
	  function &ApplyBySetPos($bysplist, $set) {
582
	    dbg_error_log( "RRule", " ApplyBySetPos: Applying set position '%s' to set of %d days", $bysplist, count($set) );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
583
	    $subset = array();
584
	    sort( $set, SORT_NUMERIC );
585
	    $max = count($set);
586
	    $positions = split( '[^0-9-]', $bysplist );
587
	    foreach( $positions AS $k => $v ) {
588
	      if ( $v < 0 ) {
589
	        $v += $max;
590
	      }
591
	      else {
592
	        $v--;
593
	      }
594
	      $subset[$set[$v]] = $set[$v];
595
	    }
596
	    return $subset;
597
	  }
598
	}
599
	
600
}
601
602
603
if (!class_exists('RRule')) {
604
	
605
	/**
606
	* A Class for handling Events on a calendar which repeat
607
	*
608
	* Here's the spec, from RFC2445:
609
	*
610
	     recur      = "FREQ"=freq *(
611
	
612
	                ; either UNTIL or COUNT may appear in a 'recur',
613
	                ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
614
	
615
	                ( ";" "UNTIL" "=" enddate ) /
616
	                ( ";" "COUNT" "=" 1*DIGIT ) /
617
	
618
	                ; the rest of these keywords are optional,
619
	                ; but MUST NOT occur more than once
620
	
621
	                ( ";" "INTERVAL" "=" 1*DIGIT )          /
622
	                ( ";" "BYSECOND" "=" byseclist )        /
623
	                ( ";" "BYMINUTE" "=" byminlist )        /
624
	                ( ";" "BYHOUR" "=" byhrlist )           /
625
	                ( ";" "BYDAY" "=" bywdaylist )          /
626
	                ( ";" "BYMONTHDAY" "=" bymodaylist )    /
627
	                ( ";" "BYYEARDAY" "=" byyrdaylist )     /
628
	                ( ";" "BYWEEKNO" "=" bywknolist )       /
629
	                ( ";" "BYMONTH" "=" bymolist )          /
630
	                ( ";" "BYSETPOS" "=" bysplist )         /
631
	                ( ";" "WKST" "=" weekday )              /
632
	                ( ";" x-name "=" text )
633
	                )
634
	
635
	     freq       = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY"
636
	                / "WEEKLY" / "MONTHLY" / "YEARLY"
637
	
638
	     enddate    = date
639
	     enddate    =/ date-time            ;An UTC value
640
	
641
	     byseclist  = seconds / ( seconds *("," seconds) )
642
	
643
	     seconds    = 1DIGIT / 2DIGIT       ;0 to 59
644
	
645
	     byminlist  = minutes / ( minutes *("," minutes) )
646
	
647
	     minutes    = 1DIGIT / 2DIGIT       ;0 to 59
648
	
649
	     byhrlist   = hour / ( hour *("," hour) )
650
	
651
	     hour       = 1DIGIT / 2DIGIT       ;0 to 23
652
	
653
	     bywdaylist = weekdaynum / ( weekdaynum *("," weekdaynum) )
654
	
655
	     weekdaynum = [([plus] ordwk / minus ordwk)] weekday
656
	
657
	     plus       = "+"
658
	
659
	     minus      = "-"
660
	
661
	     ordwk      = 1DIGIT / 2DIGIT       ;1 to 53
662
	
663
	     weekday    = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
664
	     ;Corresponding to SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
665
	     ;FRIDAY, SATURDAY and SUNDAY days of the week.
666
	
667
	     bymodaylist = monthdaynum / ( monthdaynum *("," monthdaynum) )
668
	
669
	     monthdaynum = ([plus] ordmoday) / (minus ordmoday)
670
	
671
	     ordmoday   = 1DIGIT / 2DIGIT       ;1 to 31
672
	
673
	     byyrdaylist = yeardaynum / ( yeardaynum *("," yeardaynum) )
674
	
675
	     yeardaynum = ([plus] ordyrday) / (minus ordyrday)
676
	
677
	     ordyrday   = 1DIGIT / 2DIGIT / 3DIGIT      ;1 to 366
678
	
679
	     bywknolist = weeknum / ( weeknum *("," weeknum) )
680
	
681
	     weeknum    = ([plus] ordwk) / (minus ordwk)
682
	
683
	     bymolist   = monthnum / ( monthnum *("," monthnum) )
684
	
685
	     monthnum   = 1DIGIT / 2DIGIT       ;1 to 12
686
	
687
	     bysplist   = setposday / ( setposday *("," setposday) )
688
	
689
	     setposday  = yeardaynum
690
	*
691
	* At this point we are going to restrict ourselves to parts of the RRULE specification
692
	* seen in the wild.  And by "in the wild" I don't include within people's timezone
693
	* definitions.  We always convert time zones to canonical names and assume the lower
694
	* level libraries can do a better job with them than we can.
695
	*
696
	* We will concentrate on:
697
	*  FREQ=(YEARLY|MONTHLY|WEEKLY|DAILY)
698
	*  UNTIL=
699
	*  COUNT=
700
	*  INTERVAL=
701
	*  BYDAY=
702
	*  BYMONTHDAY=
703
	*  BYSETPOS=
704
	*  WKST=
705
	*  BYYEARDAY=
706
	*  BYWEEKNO=
707
	*  BYMONTH=
708
	*
709
	*
710
	* @package awl
711
	*/
712
	class RRule {
713
	  /**#@+
714
	  * @access private
715
	  */
716
	
717
	  /** The first instance */
718
	  var $_first;
719
	
720
	  /** The current instance pointer */
721
	  var $_current;
722
	
723
	  /** An array of all the dates so far */
724
	  var $_dates;
725
	
726
	  /** Whether we have calculated any of the dates */
727
	  var $_started;
728
	
729
	  /** Whether we have calculated all of the dates */
730
	  var $_finished;
731
	
732
	  /** The rule, in all it's glory */
733
	  var $_rule;
734
	
735
	  /** The rule, in all it's parts */
736
	  var $_part;
737
	
738
	  /**#@-*/
739
	
740
	  /**
741
	  * The constructor takes a start date and an RRULE definition.  Both of these
742
	  * follow the iCalendar standard.
743
	  */
744
	  function RRule( $start, $rrule ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
745
	    $this->_first = new iCalDate($start);
746
	    $this->_finished = false;
747
	    $this->_started = false;
748
	    $this->_dates = array();
749
	    $this->_current = -1;
750
	
751
	    $this->_rule = preg_replace( '/\s/m', '', $rrule);
752
	    if ( substr($this->_rule, 0, 6) == 'RRULE:' ) {
753
	      $this->_rule = substr($this->_rule, 6);
754
	    }
755
	
756
	    dbg_error_log( "RRule", " new RRule: Start: %s, RRULE: %s", $start->Render(), $this->_rule );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
757
	
758
	    $parts = explode(';',$this->_rule);
759
	    $this->_part = array( 'INTERVAL' => 1 );
760
	    foreach( $parts AS $k => $v ) {
761
	    	$arr = explode( '=', $v, 2);
762
	    	if (2 !== count($arr))
763
	    	{
764
	    		trigger_error(sprintf('Error for parameter %s in RRULE : %s', $v, $this->_rule));
765
	    		continue;
766
	    	}
767
	      list( $type, $value ) = $arr;
768
	      dbg_error_log( "RRule", " Parts of %s split into %s and %s", $v, $type, $value );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
769
	      $this->_part[$type] = $value;
770
	    }
771
	
772
	    // A little bit of validation
773
	    if ( !isset($this->_part['FREQ']) ) {
774
	      dbg_error_log( "ERROR", " RRULE MUST have FREQ=value (%s)", $rrule );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'ERROR'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
775
	    }
776 View Code Duplication
	    if ( isset($this->_part['COUNT']) && isset($this->_part['UNTIL'])  ) {
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...
777
	      dbg_error_log( "ERROR", " RRULE MUST NOT have both COUNT=value and UNTIL=value (%s)", $rrule );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'ERROR'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
778
	    }
779 View Code Duplication
	    if ( isset($this->_part['COUNT']) && intval($this->_part['COUNT']) < 1 ) {
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...
780
	      dbg_error_log( "ERROR", " RRULE MUST NOT have both COUNT=value and UNTIL=value (%s)", $rrule );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'ERROR'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
781
	    }
782
	    if ( !preg_match( '/(YEAR|MONTH|WEEK|DAI)LY/', $this->_part['FREQ']) ) {
783
	      dbg_error_log( "ERROR", " RRULE Only FREQ=(YEARLY|MONTHLY|WEEKLY|DAILY) are supported at present (%s)", $rrule );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'ERROR'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
784
	    }
785
	    if ( $this->_part['FREQ'] == "YEARLY" ) {
786
	      $this->_part['INTERVAL'] *= 12;
787
	      $this->_part['FREQ'] = "MONTHLY";
788
	    }
789
	  }
790
	
791
	
792
	  /**
793
	  * Processes the array of $relative_days to $base and removes any
794
	  * which are not within the scope of our rule.
795
	  */
796
	  function WithinScope( $base, $relative_days ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
797
	
798
	    $ok_days = array();
799
	
800
	    $ptr = $this->_current;
801
	
802
	//    dbg_error_log( "RRule", " WithinScope: Processing list of %d days relative to %s", count($relative_days), $base->Render() );
803
	    foreach( $relative_days AS $day => $v ) {
804
	
805
	      $test = new iCalDate($base);
806
	      $days_in_month = $test->DaysInMonth();
807
	
808
	//      dbg_error_log( "RRule", " WithinScope: Testing for day %d based on %s, with %d days in month", $day, $test->Render(), $days_in_month );
809
	      if ( $day > $days_in_month ) {
810
	        $test->SetMonthDay($days_in_month);
811
	        $test->AddDays(1);
812
	        $day -= $days_in_month;
813
	        $test->SetMonthDay($day);
814
	      }
815
	      else if ( $day < 1 ) {
816
	        $test->SetMonthDay(1);
817
	        $test->AddDays(-1);
818
	        $days_in_month = $test->DaysInMonth();
819
	        $day += $days_in_month;
820
	        $test->SetMonthDay($day);
821
	      }
822
	      else {
823
	        $test->SetMonthDay($day);
824
	      }
825
	
826
	      dbg_error_log( "RRule", " WithinScope: Testing if %s is within scope", count($relative_days), $test->Render() );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
827
	
828
	      if ( isset($this->_part['UNTIL']) && $test->GreaterThan($this->_part['UNTIL']) ) {
829
	        $this->_finished = true;
830
	        return $ok_days;
831
	      }
832
	
833
	      // if ( $this->_current >= 0 && $test->LessThan($this->_dates[$this->_current]) ) continue;
834
	
835
	      if ( !$test->LessThan($this->_first) ) {
0 ignored issues
show
Documentation introduced by
$this->_first is of type object<iCalDate>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
836
	        dbg_error_log( "RRule", " WithinScope: Looks like %s is within scope", $test->Render() );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
837
	        $ok_days[$day] = $test;
838
	        $ptr++;
839
	      }
840
	
841
	      if ( isset($this->_part['COUNT']) && $ptr >= $this->_part['COUNT'] ) {
842
	        $this->_finished = true;
843
	        return $ok_days;
844
	      }
845
	
846
	    }
847
	
848
	    return $ok_days;
849
	  }
850
	
851
	
852
	  /**
853
	  * This is most of the meat of the RRULE processing, where we find the next date.
854
	  * We maintain an
855
	  */
856
	  function &GetNext( ) {
857
	
858
	    if ( $this->_current < 0 ) {
859
	      $next = new iCalDate($this->_first);
860
	      $this->_current++;
861
	    }
862
	    else {
863
	      $next = new iCalDate($this->_dates[$this->_current]);
864
	      $this->_current++;
865
	
866
	      /**
867
	      * If we have already found some dates we may just be able to return one of those.
868
	      */
869
	      if ( isset($this->_dates[$this->_current]) ) {
870
	        dbg_error_log( "RRule", " GetNext: Returning %s, (%d'th)", $this->_dates[$this->_current]->Render(), $this->_current );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
871
	        return $this->_dates[$this->_current];
872
	      }
873
	      else {
874
	        if ( isset($this->_part['COUNT']) && $this->_current >= $this->_part['COUNT'] ) // >= since _current is 0-based and COUNT is 1-based
875
	          $this->_finished = true;
876
	      }
877
	    }
878
	
879
	    if ( $this->_finished ) {
880
	      $next = null;
881
	      return $next;
882
	    }
883
	
884
	    $days = array();
885
	    if ( isset($this->_part['WKST']) ) $next->SetWeekStart($this->_part['WKST']);
886
	    if ( $this->_part['FREQ'] == "MONTHLY" ) {
887
	      dbg_error_log( "RRule", " GetNext: Calculating more dates for MONTHLY rule" );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
888
	      $limit = 200;
889
	      do {
890
	        $limit--;
891
	        do {
892
	          $limit--;
893
	          if ( $this->_started ) {
894
	            $next->AddMonths($this->_part['INTERVAL']);
895
	          }
896
	          else {
897
	            $this->_started = true;
898
	          }
899
	        }
900
	        while ( isset($this->_part['BYMONTH']) && $limit > 0 && ! $next->TestByMonth($this->_part['BYMONTH']) );
901
	
902
	        if ( isset($this->_part['BYDAY']) ) {
903
	          $days = $next->GetMonthByDay($this->_part['BYDAY']);
904
	        }
905
	        else if ( isset($this->_part['BYMONTHDAY']) ) {
906
	          $days = $next->GetMonthByMonthDay($this->_part['BYMONTHDAY']);
907
	        }
908
	        else
909
	          $days[$next->_dd] = $next->_dd;
910
	
911
	        if ( isset($this->_part['BYSETPOS']) ) {
912
	          $days = $next->ApplyBySetpos($this->_part['BYSETPOS'], $days);
0 ignored issues
show
Documentation introduced by
$days is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
913
	        }
914
	
915
	        $days = $this->WithinScope( $next, $days);
916
	      }
917
	      while( $limit && count($days) < 1 && ! $this->_finished );
918
	      dbg_error_log( "RRule", " GetNext: Found %d days for MONTHLY rule", count($days) );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
919
	
920
	    }
921
	    else if ( $this->_part['FREQ'] == "WEEKLY" ) {
922
	      dbg_error_log( "RRule", " GetNext: Calculating more dates for WEEKLY rule" );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
923
	      $limit = 200;
924 View Code Duplication
	      do {
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...
925
	        $limit--;
926
	        if ( $this->_started ) {
927
	          $next->AddDays($this->_part['INTERVAL'] * 7);
928
	        }
929
	        else {
930
	          $this->_started = true;
931
	        }
932
	
933
	        if ( isset($this->_part['BYDAY']) ) {
934
	          $days = $next->GetWeekByDay($this->_part['BYDAY'], false );
935
	        }
936
	        else
937
	          $days[$next->_dd] = $next->_dd;
938
	
939
	        if ( isset($this->_part['BYSETPOS']) ) {
940
	          $days = $next->ApplyBySetpos($this->_part['BYSETPOS'], $days);
0 ignored issues
show
Documentation introduced by
$days is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
941
	        }
942
	
943
	        $days = $this->WithinScope( $next, $days);
944
	      }
945
	      while( $limit && count($days) < 1 && ! $this->_finished );
946
	
947
	      dbg_error_log( "RRule", " GetNext: Found %d days for WEEKLY rule", count($days) );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
948
	    }
949
	    else if ( $this->_part['FREQ'] == "DAILY" ) {
950
	      dbg_error_log( "RRule", " GetNext: Calculating more dates for DAILY rule" );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
951
	      $limit = 100;
952 View Code Duplication
	      do {
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...
953
	        $limit--;
954
	        if ( $this->_started ) {
955
	          $next->AddDays($this->_part['INTERVAL']);
956
	        }
957
	
958
	        if ( isset($this->_part['BYDAY']) ) {
959
	          $days = $next->GetWeekByDay($this->_part['BYDAY'], $this->_started );
0 ignored issues
show
Documentation introduced by
$this->_started is of type boolean, but the function expects a false|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
960
	        }
961
	        else
962
	          $days[$next->_dd] = $next->_dd;
963
	
964
	        if ( isset($this->_part['BYSETPOS']) ) {
965
	          $days = $next->ApplyBySetpos($this->_part['BYSETPOS'], $days);
0 ignored issues
show
Documentation introduced by
$days is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
966
	        }
967
	
968
	        $days = $this->WithinScope( $next, $days);
969
	        $this->_started = true;
970
	      }
971
	      while( $limit && count($days) < 1 && ! $this->_finished );
972
	
973
	      dbg_error_log( "RRule", " GetNext: Found %d days for DAILY rule", count($days) );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
974
	    }
975
	
976
	    $ptr = $this->_current;
977
	    foreach( $days AS $k => $v ) {
978
	      $this->_dates[$ptr++] = $v;
979
	    }
980
	
981
	    if ( isset($this->_dates[$this->_current]) ) {
982
	      dbg_error_log( "RRule", " GetNext: Returning %s, (%d'th)", $this->_dates[$this->_current]->Render(), $this->_current );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
983
	      return $this->_dates[$this->_current];
984
	    }
985
	    else {
986
	      dbg_error_log( "RRule", " GetNext: Returning null date" );
0 ignored issues
show
Unused Code introduced by
The call to dbg_error_log() has too many arguments starting with 'RRule'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
987
	      $next = null;
988
	      return $next;
989
	    }
990
	  }
991
992
	}
993
994
}
995