Completed
Push — master ( 62b222...3fdac6 )
by
unknown
07:01
created

Default_Calendar_List::get_name()   A

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
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Default Calendar - List View
4
 *
5
 * @package SimpleCalendar/Calendars
6
 */
7
namespace SimpleCalendar\Calendars\Views;
8
9
use Carbon\Carbon;
10
use Mexitek\PHPColors\Color;
11
use SimpleCalendar\Abstracts\Calendar;
12
use SimpleCalendar\Abstracts\Calendar_View;
13
use SimpleCalendar\Calendars\Default_Calendar;
14
use SimpleCalendar\Events\Event;
15
16
if ( ! defined( 'ABSPATH' ) ) {
17
	exit;
18
}
19
20
/**
21
 * Default Calendar: List View.
22
 *
23
 * @since  3.0.0
24
 */
25
class Default_Calendar_List implements Calendar_View {
26
27
	/**
28
	 * Calendar.
29
	 *
30
	 * @access public
31
	 * @var Default_Calendar
32
	 */
33
	public $calendar = null;
34
35
	/**
36
	 * Current display start.
37
	 *
38
	 * @access private
39
	 * @var int
40
	 */
41
	private $start = 0;
42
43
	private $first_event = 0;
44
45
	private $last_event = 0;
46
47
	/**
48
	 * Current display end.
49
	 *
50
	 * @access private
51
	 * @var int
52
	 */
53
	private $end = 0;
54
55
	/**
56
	 * Previous display start.
57
	 *
58
	 * @access private
59
	 * @var int
60
	 */
61
	private $prev = 0;
62
63
	/**
64
	 * Next display start.
65
	 *
66
	 * @access private
67
	 * @var int
68
	 */
69
	private $next = 0;
70
71
	/**
72
	 * Constructor.
73
	 *
74
	 * @since 3.0.0
75
	 *
76
	 * @param string|Calendar $calendar
77
	 */
78
	public function __construct( $calendar = '' ) {
79
		$this->calendar = $calendar;
0 ignored issues
show
Documentation Bug introduced by
It seems like $calendar of type string or object<SimpleCalendar\Abstracts\Calendar> is incompatible with the declared type object<SimpleCalendar\Calendars\Default_Calendar> of property $calendar.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
80
	}
81
82
	/**
83
	 * Get the view parent calendar type.
84
	 *
85
	 * @since  3.0.0
86
	 *
87
	 * @return string
88
	 */
89
	public function get_parent() {
90
		return 'default-calendar';
91
	}
92
93
	/**
94
	 * Get the view type.
95
	 *
96
	 * @since  3.0.0
97
	 *
98
	 * @return string
99
	 */
100
	public function get_type() {
101
		return 'list';
102
	}
103
104
	/**
105
	 * Get the view name.
106
	 *
107
	 * @since  3.0.0
108
	 *
109
	 * @return string
110
	 */
111
	public function get_name() {
112
		return __( 'List', 'google-calendar-events' );
113
	}
114
115
	/**
116
	 * Add ajax actions.
117
	 *
118
	 * @since 3.0.0
119
	 */
120
	public function add_ajax_actions() {
121
		add_action( 'wp_ajax_simcal_default_calendar_draw_list', array( $this, 'draw_list_ajax' ) );
122
		add_action( 'wp_ajax_nopriv_simcal_default_calendar_draw_list', array( $this, 'draw_list_ajax' ) );
123
	}
124
125
	/**
126
	 * Default calendar list scripts.
127
	 *
128
	 * Scripts to load when this view is displayed.
129
	 *
130
	 * @since  3.0.0
131
	 *
132
	 * @param  string $min
133
	 *
134
	 * @return array
135
	 */
136
	public function scripts( $min = '' ) {
137
		return array(
138
			'simcal-qtip' => array(
139
				'src'       => SIMPLE_CALENDAR_ASSETS . 'js/vendor/qtip' . $min . '.js',
140
				'deps'      => array( 'jquery' ),
141
				'ver'       => '2.2.1',
142
				'in_footer' => true,
143
			),
144
			'simcal-default-calendar' => array(
145
				'src'       => SIMPLE_CALENDAR_ASSETS . 'js/default-calendar' . $min . '.js',
146
				'deps'      => array(
147
					'jquery',
148
					'simcal-qtip',
149
				),
150
				'var'       => SIMPLE_CALENDAR_VERSION,
151
				'in_footer' => true,
152
				'localize'  => array(
153
					'simcal_default_calendar' => simcal_common_scripts_variables(),
154
				),
155
			),
156
		);
157
	}
158
159
	/**
160
	 * Default calendar list styles.
161
	 *
162
	 * Stylesheets to load when this view is displayed.
163
	 *
164
	 * @since  3.0.0
165
	 *
166
	 * @param  string $min = ''
167
	 *
168
	 * @return array
169
	 */
170
	public function styles( $min = '' ) {
171
		return array(
172
			'simcal-default-calendar-list' => array(
173
				'src'   => SIMPLE_CALENDAR_ASSETS . 'css/default-calendar-list' . $min . '.css',
174
				'ver'   => SIMPLE_CALENDAR_VERSION,
175
				'media' => 'all',
176
			),
177
		);
178
	}
179
180
	/**
181
	 * Default calendar list markup.
182
	 *
183
	 * @since 3.0.0
184
	 */
185
	public function html() {
186
187
		$calendar = $this->calendar;
188
189
		if ( $calendar instanceof Default_Calendar ) {
190
191
			$disabled = $calendar->static === true || empty( $calendar->events ) ? ' disabled="disabled"' : '';
192
193
194
			$hide_header = get_post_meta( $this->calendar->id, '_default_calendar_list_header', true ) == 'yes' ? true : false;
195
			$static_calendar = get_post_meta( $this->calendar->id, '_calendar_is_static', true ) == 'yes' ? true : false;
196
197
			$header_class = '';
198
			$compact_list_class = $calendar->compact_list ? 'simcal-calendar-list-compact' : '';
199
200
			edit_post_link( __( 'Edit Calendar', 'google-calendar-events' ), '<p class="simcal-align-right"><small>', '</small></p>', $calendar->id );
201
202
			echo '<div class="simcal-calendar-list ' . $compact_list_class . '">';
203
204
			if ( ! $hide_header && ! $static_calendar ) {
205
				echo '<nav class="simcal-calendar-head">' . "\n";
206
207
				echo "\t" . '<div class="simcal-nav">' . "\n";
208
				echo "\t\t" . '<button class="simcal-nav-button simcal-prev" title="' . __('Previous', 'google-calendar-events') . '"' . $disabled . '>' . "\n";
209
				echo "\t\t\t" . '<i class="simcal-icon-left"></i>' . "\n";
210
				echo "\t\t" . '</button>' . "\n";
211
				echo "\t" . '</div>' . "\n";
212
213
				if ( $hide_header ) {
214
					$header_class = 'simcal-hide-header';
215
				}
216
217
218
				echo "\t" . '<div class="simcal-nav simcal-current ' . $header_class . '" data-calendar-current="' . $calendar->start . '">' . "\n";
219
				echo "\t\t" . '<h3 class="simcal-current-label"> </h3>' . "\n";
220
				echo "\t" . '</div>' . "\n";
221
222
				echo "\t" . '<div class="simcal-nav">';
223
				echo "\t\t" . '<button class="simcal-nav-button simcal-next" title="' . __('Next', 'google-calendar-events') . '"' . $disabled . '>';
224
				echo "\t\t\t" . '<i class="simcal-icon-right"></i>' . "\n";
225
				echo "\t\t" . '</button>' . "\n";
226
				echo "\t" . '</div>' . "\n";
227
228
				echo '</nav>' . "\n";
229
			}
230
231
			echo $this->draw_list( $calendar->start );
232
233
			echo '<div class="simcal-ajax-loader simcal-spinner-top" style="display: none;"><i class="simcal-icon-spinner simcal-icon-spin"></i></div>';
234
235
			echo '</div>';
236
237
		}
238
239
	}
240
241
	/**
242
	 * Get events for current display.
243
	 *
244
	 * @since  3.0.0
245
	 * @access private
246
	 *
247
	 * @param  int $timestamp
248
	 *
249
	 * @return array
250
	 */
251
	private function get_events( $timestamp ) {
252
253
		$calendar = $this->calendar;
254
		$timezone = $calendar->timezone;
255
256
		if ( ! $calendar->group_type || ! $calendar->group_span ) {
257
			return array();
258
		}
259
260
		$current = Carbon::createFromTimestamp( $timestamp, $timezone );
261
		$prev = clone $current;
262
		$next = clone $current;
263
264
		$this->start = $current->getTimestamp();
265
266
		$interval = $span = max( absint( $calendar->group_span ), 1 );
267
268
		if ( 'monthly' == $calendar->group_type ) {
269
			$this->prev = $prev->subMonths( $span )->getTimestamp();
270
			$this->next = $next->addMonths( $span )->getTimestamp();
271
		} elseif ( 'weekly' == $calendar->group_type ) {
272
			$week = new Carbon( $calendar->timezone );
273
			$week->setTimestamp( $timestamp );
274
			$week->setWeekStartsAt( $calendar->week_starts );
275
			$this->prev = $prev->subWeeks( $span )->getTimestamp();
276
			$this->next = $next->addWeeks( $span )->getTimestamp();
277
		} elseif ( 'daily' == $calendar->group_type ) {
278
			$this->prev = $prev->subDays( $span )->getTimestamp();
279
			$this->next = $next->addDays( $span )->getTimestamp();
280
		}
281
282
		$events = $calendar->events;
283
		$daily_events = $paged_events = $flattened_events = array();
284
285
		if ( 'events' != $calendar->group_type ) {
286
287
			$this->end   = $this->next - 1;
288
289
			$timestamps   = array_keys( $events );
290
			$lower_bound  = array_filter( $timestamps,  array( $this, 'filter_events_before' ) );
291
			$higher_bound = array_filter( $lower_bound, array( $this, 'filter_events_after'  ) );
292
293
			if ( is_array( $higher_bound ) && !empty( $higher_bound ) ) {
294
				$filtered = array_intersect_key( $events, array_combine( $higher_bound, $higher_bound ) );
295
				foreach ( $filtered as $timestamp => $events ) {
296
					$paged_events[ intval( $timestamp ) ] = $events;
297
				}
298
			}
299
300
		} else {
301
302
			foreach ( $events as $timestamp => $e ) {
303
				$second = 0;
304
				foreach ( $e as $event ) {
305
					$flattened_events[ intval( $timestamp + $second ) ][] = $event;
306
					$second++;
307
				}
308
			}
309
			ksort( $flattened_events, SORT_NUMERIC );
310
311
			$keys  = array_keys( $flattened_events );
312
			$current = 0;
313
			foreach ( $keys as $timestamp ) {
314
				if ( $timestamp < $this->start ) {
315
					$current++;
316
				}
317
			}
318
319
			$paged_events = array_slice( $flattened_events, $current, $interval, true );
320
321
			$events_end = isset( $keys[ $current + $interval ] ) ? $keys[ $current + $interval ] : $calendar->end;
322
			$this->end  = $events_end > $calendar->end ? $calendar->end : $events_end;
0 ignored issues
show
Documentation Bug introduced by
It seems like $events_end > $calendar-...ndar->end : $events_end can also be of type string. However, the property $end is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
323
324
			$this->prev = isset( $keys[ $current - $interval ] ) ? $keys[ $current - $interval ] : $calendar->earliest_event;
0 ignored issues
show
Documentation Bug introduced by
It seems like isset($keys[$current - $...alendar->earliest_event can also be of type string. However, the property $prev is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
325
			$this->next = isset( $keys[ $current + $interval ] ) ? $keys[ $current + $interval ] : $this->end;
0 ignored issues
show
Documentation Bug introduced by
It seems like isset($keys[$current + $...$interval] : $this->end can also be of type string. However, the property $next is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
326
327
		}
328
329
		// Put resulting events in an associative array, with Ymd date as key for easy retrieval in calendar days loop.
330 View Code Duplication
		foreach ( $paged_events as $timestamp => $events ) {
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
			if ( $timestamp <= $this->end ) {
332
				$date = Carbon::createFromTimestamp( $timestamp, $calendar->timezone )->endOfDay()->format( 'Ymd' );
333
				$daily_events[ intval( $date ) ][] = $events;
334
			}
335
		}
336
		ksort( $daily_events, SORT_NUMERIC );
337
338
		if ( ! empty( $paged_events ) ) {
339
			$first_event       = array_slice( $paged_events, 0, 1, true );
340
			$first_event       = array_pop( $first_event );
341
			$this->first_event = $first_event[0]->start;
342
343
			$last_event       = array_pop( $paged_events );
344
			$this->last_event = $last_event[0]->start;
345
		}
346
347
		return $daily_events;
348
	}
349
350
	/**
351
	 * Get calendar list heading.
352
	 *
353
	 * Parses calender date format and adapts to current display range.
354
	 *
355
	 * @since  3.0.0
356
	 * @access private
357
	 *
358
	 * @return array
359
	 */
360
	private function get_heading() {
361
362
		$calendar = $this->calendar;
363
		$start = Carbon::createFromTimestamp( $calendar->start, $calendar->timezone );
364
		$end = Carbon::createFromTimestamp( $this->end, $calendar->timezone );
365
		$date_format = $this->calendar->date_format;
366
		$date_order  = simcal_get_date_format_order( $date_format );
367
368
		$st = $this->start;
369
		$et = $this->end;
370
371
		if ( $this->first_event !== 0 ) {
372
			$start = Carbon::createFromTimestamp( $this->first_event, $calendar->timezone );
373
			$st = $this->first_event;
374
		}
375
376
		if ( $this->last_event !== 0 ) {
377
			$end = Carbon::createFromTimestamp( $this->last_event, $calendar->timezone );
378
			$et = $this->last_event;
379
		}
380
381
		if ( ( $start->day == $end->day ) && ( $start->month == $end->month ) && ( $start->year == $end->year ) ) {
382
			// Start and end on the same day.
383
			// e.g. 1 February 2020
384
			$large = $small = date_i18n( $calendar->date_format , $st );
385
			if ( ( $date_order['d'] !== false ) && ( $date_order['m'] !== false ) ) {
386
				if ( $date_order['m'] > $date_order['d'] ) {
387 View Code Duplication
					if ( $date_order['y'] !== false && $date_order['y'] > $date_order['m'] ) {
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...
388
						$small = date_i18n( 'Y, d M', $st );
389
					} else {
390
						$small = date_i18n( 'd M Y', $st );
391
					}
392 View Code Duplication
				} else {
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...
393
					if ( $date_order['y'] !== false && $date_order['y'] > $date_order['m'] ) {
394
						$small = date_i18n( 'Y, M d', $st );
395
					} else {
396
						$small = date_i18n( 'M d Y', $st );
397
					}
398
				}
399
			}
400
		} elseif ( ( $start->month == $end->month ) && ( $start->year == $end->year ) ) {
401
			// Start and end days on the same month.
402
			// e.g. August 2020
403
			if ( $date_order['y'] === false ) {
404
				// August.
405
				$large = $small = date_i18n( 'F', $st );
406
			} else {
407
				if ( $date_order['y'] < $date_order['m'] ) {
408
					// 2020 August.
409
					$large = date_i18n( 'Y F', $st );
410
					$small = date_i18n( 'Y M', $st );
411
				} else {
412
					// August 2020.
413
					$large = date_i18n( 'F Y', $st );
414
					$small = date_i18n( 'M Y', $st );
415
				}
416
			}
417
		} elseif ( $start->year == $end->year ) {
418
			// Start and end days on months of the same year.
419
			// e.g. August - September 2020
420
			if ( $date_order['y'] === false ) {
421
				// August - September.
422
				$large = date_i18n( 'F', $st ) . ' - ' . date_i18n( 'F', $et );
423
				$small = date_i18n( 'M', $st ) . ' - ' . date_i18n( 'M', $et );
424
			} else {
425
				if ( $date_order['y'] < $date_order['m'] ) {
426
					// 2020, August - September.
427
					$large  = $small = date( 'Y', $st ) . ', ';
428
					$large .= date_i18n( 'F', $st ) . ' - ' . date_i18n( 'F', $et );
429
					$small .= date_i18n( 'M', $st ) . ' - ' . date_i18n( 'M', $et );
430
				} else {
431
					// August - September, 2020.
432
					$large  = date_i18n( 'F', $st ) . ' - ' . date_i18n( 'F', $et ) . ', ';
433
					$small  = date_i18n( 'M', $st ) . ' - ' . date_i18n( 'M', $et ) . ' ';
434
					$year   = date( 'Y', $st );
435
					$large .= $year;
436
					$small .= $year;
437
				}
438
			}
439
		} else {
440
			$large = $small = date( 'Y', $st ) . ' - ' . date( 'Y', $et );
441
		}
442
443
		return array(
444
			'small' => $small,
445
			'large' => $large,
446
		);
447
	}
448
449
	/**
450
	 * Make a calendar list of events.
451
	 *
452
	 * Outputs a list of events according to events for the specified range.
453
	 *
454
	 * @since  3.0.0
455
	 * @access private
456
	 *
457
	 * @param  int $timestamp
458
	 * @param  int $id
459
	 *
460
	 * @return string
461
	 */
462
	private function draw_list( $timestamp, $id = 0 ) {
463
464
		$calendar = $this->calendar;
465
466
		if ( empty( $calendar ) ) {
467
			$calendar = $this->calendar = simcal_get_calendar( intval( $id ) );
468
			if ( ! $calendar instanceof Default_Calendar ) {
469
				return '';
470
			}
471
		}
472
473
		$feed          = simcal_get_feed( $calendar );
474
		$feed_timezone = get_post_meta( $feed->post_id, '_feed_timezone', true );
475
476
		$now = $calendar->now;
477
		$current_events = $this->get_events( $timestamp );
478
		$day_format = explode( ' ', $calendar->date_format );
479
480
		ob_start();
481
482
		// Draw the events.
483
484
		$block_tag = $calendar->compact_list && ! empty( $current_events ) ? 'div' : 'dl';
485
486
		$data_heading = '';
487
		$heading = $this->get_heading();
488
		foreach ( $heading as $k => $v ) {
489
			$data_heading .= ' data-heading-' . $k . '="' . $v . '"';
490
		}
491
492
		echo '<' . $block_tag . ' class="simcal-events-list-container"' .
493
			' data-prev="' . $this->prev . '"' .
494
			' data-next="' . $this->next . '"' .
495
			$data_heading . '>';
496
497
		if ( ! empty( $current_events ) && is_array( $current_events ) ) :
498
499
			foreach ( $current_events as $ymd => $events ) :
500
501
502
503
				// This is where we can find out if an event is a multi-day event and if it needs to be shown.
504
				// Since this is for list view we are showing the event on the day viewed if it is part of that day even when
505
				// expand multi-day events are turned off.
506
				if ( isset( $events[0][0]->multiple_days ) && $events[0][0]->multiple_days > 0 ) {
507
					if ( 'current_day_only' == get_post_meta($calendar->id, '_default_calendar_expand_multi_day_events', true ) ) {
508
509
						$year  = substr( $ymd, 0, 4 );
510
						$month = substr( $ymd, 4, 2 );
511
						$day   = substr( $ymd, 6, 2 );
512
513
						$temp_date = Carbon::createFromDate( $year, $month, $day );
514
515
						if( ! ( $temp_date < Carbon::now()->endOfDay() ) ) {
516
							continue;
517
						}
518
					}
519
				}
520
521
				$day_ts = Carbon::createFromFormat( 'Ymd', $ymd, $calendar->timezone )->startOfDay()->getTimestamp();
522
523
				if ( ! $calendar->compact_list ) :
524
525
					$date = new Carbon( 'now', $calendar->timezone );
526
					$date->setLocale( substr( get_locale(), 0, 2 ) );
527
					$date->setTimestamp( $day_ts );
528
529
					if ( $date->isToday() ) {
530
						$the_color = new Color( $calendar->today_color );
531
					} else {
532
						$the_color = new Color( $calendar->days_events_color );
533
					}
534
535
					$bg_color = '#' . $the_color->getHex();
536
					$color = $the_color->isDark() ? '#ffffff' : '#000000';
537
					$border_style = ' style="border-bottom: 1px solid ' . $bg_color . ';" ';
538
					$bg_style = ' style="background-color: ' . $bg_color . '; color: ' . $color . ';"';
539
540
					echo "\t" . '<dt class="simcal-day-label"' . $border_style . '>';
541
					echo '<span' . $bg_style .'>';
542
					foreach ( $day_format as $format ) {
543
						echo $format ? '<span class="simcal-date-format" data-date-format="' . $format . '">' . date_i18n( $format, $day_ts ) . '</span> ' : ' ';
544
					}
545
					echo '</span>';
546
					echo '</dt>' . "\n";
547
548
				endif;
549
550
				$list_events = '<ul class="simcal-events">' . "\n";
551
552
				$calendar_classes = array();
553
				$day_classes = 'simcal-weekday-' . date( 'w', $day_ts );
554
555
				// Is this the present, the past or the future, Doc?
556
				if ( $timestamp <= $now && $timestamp >= $now ) {
557
					$day_classes .= ' simcal-today simcal-present simcal-day';
558
				} elseif ( $timestamp < $now ) {
559
					$day_classes .= ' simcal-past simcal-day';
560
				} elseif ( $this->end > $now ) {
561
					$day_classes .= ' simcal-future simcal-day';
562
				}
563
564
				$count = 0;
565
566
				foreach ( $events as $day_events ) :
567
					foreach ( $day_events as $event ) :
568
569
						if ( $event instanceof Event ) :
570
571
							if ( $feed->type == 'grouped-calendars' ) {
572
								date_default_timezone_set( $feed_timezone );
573
							} else {
574
								date_default_timezone_set( $event->timezone );
575
							}
576
577
							$event_classes = $event_visibility = '';
578
579
							$calendar_class     = 'simcal-events-calendar-' . strval( $event->calendar );
580
							$calendar_classes[] = $calendar_class;
581
582
							$recurring     = $event->recurrence ? 'simcal-event-recurring ' : '';
583
							$has_location  = $event->venue ? 'simcal-event-has-location ' : '';
584
585
							$event_classes .= 'simcal-event ' . $recurring . $has_location . $calendar_class;
586
587
							// Toggle some events visibility if more than optional limit.
588 View Code Duplication
							if ( ( $calendar->events_limit > - 1 ) && ( $count >= $calendar->events_limit ) ) :
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...
589
								$event_classes .= ' simcal-event-toggled';
590
								$event_visibility = ' style="display: none"';
591
							endif;
592
593
							$event_color = '';
0 ignored issues
show
Unused Code introduced by
$event_color is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
594
							$bullet = '';
0 ignored issues
show
Unused Code introduced by
$bullet is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
595
							$event_color = $event->get_color();
596
							if ( ! empty( $event_color ) ) {
597
								$side = is_rtl() ? 'right' : 'left';
598
								$event_color = ' style="border-' . $side . ': 4px solid ' . $event_color . '; padding-' . $side . ': 8px;"';
599
							}
600
601
							$list_events .= "\t" . '<li class="' . $event_classes . '"' . $event_visibility . $event_color . ' itemscope itemtype="http://schema.org/Event" data-start="' . esc_attr( $event->start ) . '">' . "\n";
602
							$list_events .= "\t\t" . '<div class="simcal-event-details">' . $calendar->get_event_html( $event ) . '</div>' . "\n";
603
							$list_events .= "\t" . '</li>' . "\n";
604
605
							$count ++;
606
607
							// Event falls within today.
608
							if ( ( $this->end <= $now ) && ( $this->start >= $now ) ) :
609
								$day_classes .= ' simcal-today-has-events';
610
							endif;
611
							$day_classes .= ' simcal-day-has-events simcal-day-has-' . strval( $count ) . '-events';
612
613
							if ( $calendar_classes ) :
0 ignored issues
show
Bug Best Practice introduced by
The expression $calendar_classes of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
614
								$day_classes .= ' ' . trim( implode( ' ', array_unique( $calendar_classes ) ) );
615
							endif;
616
617
						endif;
618
					endforeach;
619
				endforeach;
620
621
				$list_events .= '</ul>' . "\n";
622
623
				// If events visibility is limited, print the button toggle.
624
				if ( ( $calendar->events_limit > -1 ) && ( $count > $calendar->events_limit ) ) :
625
					$list_events .= '<button class="simcal-events-toggle"><i class="simcal-icon-down simcal-icon-animate"></i></button>';
626
				endif;
627
628
				// Print final list of events for the current day.
629
				$tag = $calendar->compact_list ? 'div' : 'dd';
630
				echo '<'  . $tag . ' class="' . $day_classes . '" data-events-count="' . strval( $count ) . '">' . "\n";
631
				echo "\t" . $list_events . "\n";
632
				echo '</' . $tag . '>' . "\n";
633
634
			endforeach;
635
636
		else :
637
638
			echo "\t" . '<p>';
639
640
			$message = get_post_meta( $calendar->id, '_no_events_message', true );
641
642
			if ( 'events' == $calendar->group_type ) {
643
				echo ! empty( $message ) ? $message : __( 'There are no upcoming events.', 'google-calendar-events' );
644
			} else {
645
				if ( ! empty( $message ) ) {
646
					echo $message;
647
				} else {
648
					$from = Carbon::createFromTimestamp( $this->start, $calendar->timezone )->getTimestamp();
649
					$to = Carbon::createFromTimestamp( $this->end, $calendar->timezone )->getTimestamp();
650
					echo apply_filters( 'simcal_no_events_message', sprintf(
651
						__( 'Nothing from %1$s to %2$s.', 'google-calendar-events' ),
652
						date_i18n( $calendar->date_format, $from ),
653
						date_i18n( $calendar->date_format, $to )
654
					), $calendar->id, $from, $to );
655
				}
656
			}
657
658
			echo "\t" . '</p>' . "\n";
659
660
		endif;
661
662
		echo '</' . $block_tag . '>';
663
664
		date_default_timezone_set( $calendar->site_timezone );
665
666
		return ob_get_clean();
667
	}
668
669
	/**
670
	 * Ajax callback to request a new page.
671
	 *
672
	 * @since 3.0.0
673
	 */
674
	public function draw_list_ajax() {
0 ignored issues
show
Coding Style introduced by
draw_list_ajax uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
675
676
		if ( isset( $_POST['ts'] ) && isset( $_POST['id'] ) ) {
677
678
			$ts = absint( $_POST['ts'] );
679
			$id = absint( $_POST['id'] );
680
681
			wp_send_json_success( $this->draw_list( $ts, $id ) );
682
683
		} else {
684
685
			wp_send_json_error( 'Missing arguments in default calendar list ajax request.' );
686
687
		}
688
	}
689
690
	/**
691
	 * Array filter callback.
692
	 *
693
	 * @since  3.0.0
694
	 * @access private
695
	 *
696
	 * @param  int $event Timestamp.
697
	 *
698
	 * @return bool
699
	 */
700
	private function filter_events_before( $event ) {
701
		return intval( $event ) >= intval( $this->start );
702
	}
703
704
	/**
705
	 * Array filter callback.
706
	 *
707
	 * @since  3.0.0
708
	 * @access private
709
	 *
710
	 * @param  int $event Timestamp.
711
	 *
712
	 * @return bool
713
	 */
714
	private function filter_events_after( $event ) {
715
		return intval( $event ) < intval( $this->end );
716
	}
717
718
}
719