Completed
Push — master ( a00b53...3dc4d8 )
by
unknown
21:18
created

Grouped_Calendars   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 3
Bugs 1 Features 2
Metric Value
wmc 36
c 3
b 1
f 2
lcom 1
cbo 3
dl 0
loc 217
rs 8.8

7 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 18 6
D set_source() 0 36 10
C get_events() 0 60 12
A sort_by_start_time() 0 7 3
A array_filter_key() 0 4 1
A filter_events_before() 0 6 2
A filter_events_after() 0 6 2
1
<?php
2
/**
3
 * Grouped Calendars Feed
4
 *
5
 * @package SimpleCalendar/Feeds
6
 */
7
namespace SimpleCalendar\Feeds;
8
9
use SimpleCalendar\Abstracts\Calendar;
10
use SimpleCalendar\Abstracts\Feed;
11
use SimpleCalendar\Feeds\Admin\Grouped_Calendars_Admin;
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Grouped calendars feed.
19
 *
20
 * Feed made of multiple calendar feeds combined together.
21
 *
22
 * @since  3.0.0
23
 */
24
class Grouped_Calendars extends Feed {
25
26
	/**
27
	 * Feed ids to get events from.
28
	 *
29
	 * @access public
30
	 * @var array
31
	 */
32
	public $calendars_ids = array();
33
34
	/**
35
	 * Set properties.
36
	 *
37
	 * @since 3.0.0
38
	 *
39
	 * @param string|Calendar $calendar
40
	 */
41
	public function __construct( $calendar = '' ) {
42
43
		parent::__construct( $calendar );
44
45
		$this->type = 'grouped-calendars';
46
		$this->name = __( 'Grouped Calendar', 'google-calendar-events' );
47
48
		if ( $this->post_id > 0 ) {
49
			$this->set_source();
50
			if ( ! is_admin() || defined( 'DOING_AJAX' ) ) {
51
				$this->events = $this->get_events();
52
			}
53
		}
54
55
		if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
56
			new Grouped_Calendars_Admin( $this );
57
		}
58
	}
59
60
	/**
61
	 * Set source.
62
	 *
63
	 * @since 3.0.0
64
	 *
65
	 * @param array $ids Array of calendar ids.
66
	 */
67
	public function set_source( $ids = array() ) {
68
69
		$source = get_post_meta( $this->post_id, '_grouped_calendars_source', true );
70
71
		if ( 'ids' == $source ) {
72
73
			if ( empty( $ids ) ) {
74
				$ids = get_post_meta( $this->post_id, '_grouped_calendars_ids', true );
75
			}
76
77
			$this->calendars_ids = ! empty( $ids ) && is_array( $ids ) ? array_map( 'absint', $ids ) : array();
78
79
		} elseif ( 'category' == $source ) {
80
81
			$categories = get_post_meta( $this->post_id, '_grouped_calendars_category', true );
82
83
			if ( $categories && is_array( $categories ) ) {
84
85
				$tax_query = array(
86
					'taxonomy' => 'calendar_category',
87
					'field'    => 'term_id',
88
					'terms'    => array_map( 'absint', $categories ),
89
				);
90
91
				$calendars = get_posts( array(
92
					'post_type' => 'calendar',
93
					'tax_query' => array( $tax_query ),
94
					'nopaging'  => true,
95
					'fields'    => 'ids',
96
				) );
97
98
				$this->calendars_ids = ! empty( $calendars ) && is_array( $calendars ) ? $calendars : array();
99
			}
100
101
		}
102
	}
103
104
	/**
105
	 * Get events from multiple calendars.
106
	 *
107
	 * @since  3.0.0
108
	 *
109
	 * @return array
110
	 */
111
	public function get_events() {
112
113
		$ids    = $this->calendars_ids;
114
		$events = get_transient( '_simple-calendar_feed_id_' . strval( $this->post_id ) . '_' . $this->type );
115
116
		if ( empty( $events ) && ! empty( $ids ) && is_array( $ids ) ) {
117
118
			$events = array();
119
120
			foreach ( $ids as $cal_id ) {
121
122
				$calendar = simcal_get_calendar( intval( $cal_id ) );
123
124
				simcal_delete_feed_transients( $cal_id );
125
126
				if ( $calendar instanceof Calendar ) {
127
128
					// Sometimes the calendars might have events at the same time from different calendars
129
					// When merging the arrays together some of the events will be lost because the keys are the same and one will overwrite the other
130
					// This snippet checks if the key already exists in the master events array and if it does it subtracts 1 from it to make the key unique and then unsets the original key.
131
					foreach( $calendar->events as $k => $v ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
132
						if ( array_key_exists( $k, $events ) ) {
133
							$calendar->events[ $k - 1 ] = $v;
134
							unset( $k );
135
						}
136
					}
137
138
					$events = is_array( $calendar->events ) ? $events + $calendar->events : $events;
139
				}
140
141
			}
142
143
			if ( ! empty( $events ) ) {
144
145
				// Trim events to set the earliest one as specified in feed settings.
146
				$earliest_event = intval( $this->time_min );
147
				if ( $earliest_event > 0 ) {
148
					$events = $this->array_filter_key( $events, array( $this, 'filter_events_before' ) );
149
				}
150
151
				// Trim events to set the latest one as specified in feed settings.
152
				$latest_event = intval( $this->time_max );
153
				if ( $latest_event > 0 ) {
154
					$events = $this->array_filter_key( $events, array( $this, 'filter_events_after' ) );
155
				}
156
157
				set_transient(
158
					'_simple-calendar_feed_id_' . strval( $this->post_id ) . '_' . $this->type,
159
					$events,
160
					absint( $this->cache )
161
				);
162
			}
163
164
		}
165
	
166
		// Sort events by start time before returning
167
		uasort( $events, array( $this, 'sort_by_start_time' ) );
168
169
		return $events;
170
	}
171
172
	/**
173
	 * uasort helper to sort events by start time.
174
	 *
175
	 * @since  3.0.13
176
	 * @access private
177
	 */
178
	private function sort_by_start_time( $a, $b ) {
179
		if ( $a == $b ) {
180
			return 0;
181
		}
182
183
		return ( $a[0]->start < $b[0]->start ) ? -1 : 1;
184
	}
185
186
187
188
	/**
189
	 * Array filter key.
190
	 *
191
	 * `array_filter` does not allow to parse an associative array keys before PHP 5.6.
192
	 *
193
	 * @since  3.0.0
194
	 * @access private
195
	 *
196
	 * @param  array        $array
197
	 * @param  array|string $callback
198
	 *
199
	 * @return array
200
	 */
201
	private function array_filter_key( array $array, $callback ) {
202
		$matched_keys = array_filter( array_keys( $array ), $callback );
203
		return array_intersect_key( $array, array_flip( $matched_keys ) );
204
	}
205
206
	/**
207
	 * Array filter callback.
208
	 *
209
	 * @since  3.0.0
210
	 * @access private
211
	 *
212
	 * @param  int $event Timestamp.
213
	 *
214
	 * @return bool
215
	 */
216
	private function filter_events_before( $event ) {
217
		if ( $this->time_min !== 0 ) {
0 ignored issues
show
introduced by
Found "!== 0". Use Yoda Condition checks, you must
Loading history...
218
			return intval( $event ) > intval( $this->time_min );
219
		}
220
		return true;
221
	}
222
223
	/**
224
	 * Array filter callback.
225
	 *
226
	 * @since  3.0.0
227
	 * @access private
228
	 *
229
	 * @param  int $event Timestamp.
230
	 *
231
	 * @return bool
232
	 */
233
	private function filter_events_after( $event ) {
234
		if ( $this->time_max !== 0 ) {
0 ignored issues
show
introduced by
Found "!== 0". Use Yoda Condition checks, you must
Loading history...
235
			return intval( $event ) < intval( $this->time_max );
236
		}
237
		return true;
238
	}
239
240
}
241