Completed
Push — develop ( 061975...a44a41 )
by David
02:28
created
src/includes/class-wordlift-timeline-service.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -313,7 +313,7 @@
 block discarded – undo
313 313
 	/**
314 314
 	 * Convert the date to a date array.
315 315
 	 *
316
-	 * @param $value int A date value.
316
+	 * @param integer $value int A date value.
317 317
 	 *
318 318
 	 * @return array An array containing year, month and day values.
319 319
 	 * @since 3.7.0
Please login to merge, or discard this patch.
Indentation   +358 added lines, -358 removed lines patch added patch discarded remove patch
@@ -16,363 +16,363 @@
 block discarded – undo
16 16
  */
17 17
 class Wordlift_Timeline_Service {
18 18
 
19
-	/**
20
-	 * The Log service.
21
-	 *
22
-	 * @since  3.1.0
23
-	 * @access private
24
-	 * @var \Wordlift_Log_Service $log The Log service.
25
-	 */
26
-	private $log;
27
-
28
-	/**
29
-	 * The Entity service.
30
-	 *
31
-	 * @since  3.1.0
32
-	 * @access private
33
-	 * @var \Wordlift_Entity_Service $entity_service The Entity service.
34
-	 */
35
-	private $entity_service;
36
-
37
-	/**
38
-	 * The number of words to use for the excerpt, set in the `to_json` function
39
-	 * and used by a filter.
40
-	 *
41
-	 * @since  3.7.0
42
-	 * @access private
43
-	 * @var int $excerpt_length The number of words to use for the excerpt.
44
-	 */
45
-	private $excerpt_length;
46
-
47
-	/**
48
-	 * The {@link Wordlift_Entity_Type_Service} instance.
49
-	 *
50
-	 * @since  3.15.0
51
-	 * @access private
52
-	 * @var \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
53
-	 */
54
-	private $entity_type_service;
55
-
56
-	/**
57
-	 * A singleton instance of the Timeline service (useful for unit tests).
58
-	 *
59
-	 * @since  3.1.0
60
-	 * @access private
61
-	 * @var \Wordlift_Timeline_Service $instance The singleton instance.
62
-	 */
63
-	private static $instance;
64
-
65
-	/**
66
-	 * Create a Wordlift_Timeline_Service instance.
67
-	 *
68
-	 * @param \Wordlift_Entity_Service $entity_service The Entity service.
69
-	 * @param \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
70
-	 *
71
-	 * @since 3.1.0
72
-	 *
73
-	 */
74
-	public function __construct( $entity_service, $entity_type_service ) {
75
-
76
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Service' );
77
-
78
-		$this->entity_service      = $entity_service;
79
-		$this->entity_type_service = $entity_type_service;
80
-
81
-		self::$instance = $this;
82
-
83
-	}
84
-
85
-	/**
86
-	 * Get the singleton instance of the Wordlift_Timeline_Service
87
-	 *
88
-	 * @return \Wordlift_Timeline_Service The singleton instance of the Wordlift_Timeline_Service.
89
-	 * @since 3.1.0
90
-	 *
91
-	 */
92
-	public static function get_instance() {
93
-
94
-		return self::$instance;
95
-	}
96
-
97
-	/**
98
-	 * Retrieve timeline events and output them in JSON.
99
-	 *
100
-	 * @since 3.1.0
101
-	 */
102
-	public function ajax_timeline() {
103
-
104
-		// Get the ID of the post who requested the timeline.
105
-		$post_id = ( isset( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : null );
106
-
107
-		// Get the events and transform them for the JSON response, then send them to the client.
108
-		wp_send_json( $this->to_json( $this->get_events( $post_id ) ) );
109
-
110
-	}
111
-
112
-	/**
113
-	 * Retrieve timeline events.
114
-	 *
115
-	 * @param int $post_id The post ID.
116
-	 *
117
-	 * @return array An array of event posts.
118
-	 * @since 3.1.0
119
-	 *
120
-	 * @uses  wl_core_get_related_entity_ids() to retrieve the entities referenced by the specified post.
121
-	 *
122
-	 */
123
-	public function get_events( $post_id = null ) {
124
-
125
-		// Get the entity IDs either from the entities related to the specified post or from the last 50 published
126
-		// posts if no post has been specified.
127
-		$ids = ( is_numeric( $post_id )
128
-			? wl_core_get_related_entity_ids( $post_id, array( 'predicate' => 'where', ) )
129
-			: $this->get_all_related_to_last_50_published_posts() );
130
-
131
-		// Add the post itself if it's an entity.
132
-		if ( is_numeric( $post_id ) && $this->entity_service->is_entity( $post_id ) ) {
133
-			$ids[] = $post_id;
134
-		}
135
-
136
-		// If there's no entities, return an empty array right away.
137
-		if ( 0 === sizeof( $ids ) ) {
138
-			$this->log->trace( "No events found [ post id :: $post_id ]" );
139
-
140
-			return array();
141
-		}
142
-
143
-		$this->log->trace( 'Getting events [ entity ids :: ' . join( ', ', $ids ) . ' ]' );
144
-
145
-		$args = array(
146
-			'post__in'       => $ids,
147
-			'post_type'      => Wordlift_Entity_Service::valid_entity_post_types(),
148
-			'post_status'    => 'publish',
149
-			'posts_per_page' => - 1,
150
-			'meta_query'     => array(
151
-				'relation' => 'AND',
152
-				array(
153
-					'key'     => Wordlift_Schema_Service::FIELD_DATE_START,
154
-					'value'   => null,
155
-					'compare' => '!=',
156
-				),
157
-				array(
158
-					'key'     => Wordlift_Schema_Service::FIELD_DATE_END,
159
-					'value'   => null,
160
-					'compare' => '!=',
161
-				),
162
-			),
163
-			'tax_query'      => array(
164
-				array(
165
-					'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
166
-					'field'    => 'slug',
167
-					'terms'    => 'event',
168
-				),
169
-			),
170
-		);
171
-
172
-		return get_posts( $args );
173
-	}
174
-
175
-	/**
176
-	 * Convert timeline events to JSON. This function sets the global post in order
177
-	 * to get an automatic excerpt. Since we're being called inside an AJAX request,
178
-	 * we're not taking care of restoring any previous post: there isn't any.
179
-	 *
180
-	 * @param array $posts An array of posts.
181
-	 *
182
-	 * @return array|string An array of timeline events or an empty string if no posts are provided.
183
-	 * @since 3.1.0
184
-	 *
185
-	 */
186
-	public function to_json( $posts ) {
187
-
188
-		// If there are no events, return empty JSON
189
-		if ( empty( $posts ) || is_null( $posts ) ) {
190
-			return '';
191
-		}
192
-
193
-		// {media|thumbnail}: if set to 'media' the image is attached to the slide, if set to 'background' the image is set as background.
194
-		$display_images_as = isset( $_REQUEST['display_images_as'] ) ? $_REQUEST['display_images_as'] : 'media';
195
-
196
-		// The number of words for the excerpt (by default 55, as WordPress).
197
-		$this->excerpt_length = $excerpt_length = isset( $_REQUEST['excerpt_length'] ) && is_numeric( $_REQUEST['excerpt_length'] ) ? $_REQUEST['excerpt_length'] : 55;
198
-		add_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
199
-
200
-		// Add a filter to remove the [...] after excerpts, since we're adding
201
-		// a link to the post itself.
202
-		add_filter( 'excerpt_more', array( $this, 'excerpt_more' ) );
203
-
204
-		// Prepare for the starting slide data. The starting slide will be the one where *now* is between *start/end* dates.
205
-		$start_at_slide = 0;
206
-		$event_index    = - 1;
207
-		$now            = time();
208
-
209
-		// Prepare the timeline variable.
210
-		$timeline = array();
211
-
212
-		// Populate the arrays.
213
-		$timeline['events'] = array_map( function ( $item ) use ( &$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as, $excerpt_length ) {
214
-
215
-			// Get the start and end dates.
216
-			$start_date = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_START, true ) );
217
-			$end_date   = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_END, true ) );
218
-
219
-			// Set the starting slide.
220
-			$event_index ++;
221
-			if ( 0 === $start_at_slide && $now >= $start_date && $now <= $end_date ) {
222
-				$start_at_slide = $event_index;
223
-			}
224
-
225
-			// Load thumbnail
226
-			if ( '' !== ( $thumbnail_id = get_post_thumbnail_id( $item->ID ) )
227
-			     && false !== ( $attachment = wp_get_attachment_image_src( $thumbnail_id ) )
228
-			) {
229
-
230
-				// Set the thumbnail URL.
231
-				if ( 'background' === $display_images_as ) {
232
-					$date['background'] = array( 'url' => $attachment[0] );
233
-					$date['media']      = array( 'thumbnail' => $attachment[0] );
234
-				} else {
235
-					$date['media'] = array(
236
-						'url'       => $attachment[0],
237
-						'thumbnail' => $attachment[0],
238
-					);
239
-				}
240
-			}
241
-
242
-			// Set the start/end dates by converting them to TimelineJS required format.
243
-			$date['start_date'] = Wordlift_Timeline_Service::date( $start_date );
244
-			$date['end_date']   = Wordlift_Timeline_Service::date( $end_date );
245
-
246
-			setup_postdata( $GLOBALS['post'] = $item );
247
-
248
-			$more_link_text = sprintf(
249
-				'<span aria-label="%1$s">%2$s</span>',
250
-				sprintf(
251
-				/* translators: %s: Name of current post */
252
-					__( 'Continue reading %s' ),
253
-					the_title_attribute( array( 'echo' => false ) )
254
-				),
255
-				__( '(more&hellip;)' )
256
-			);
257
-
258
-			// Set the event text only with the headline (see https://github.com/insideout10/wordlift-plugin/issues/352).
259
-			$date['text'] = array(
260
-				'headline' => '<a href="' . get_permalink( $item->ID ) . '">' . $item->post_title . '</a>',
261
-			);
262
-
263
-			// If we have an excerpt, set it.
264
-			if ( 0 < $excerpt_length ) {
265
-				$date['text']['text'] = sprintf( '%s <a href="%s">%s</a>', get_the_excerpt(), get_permalink(), $more_link_text );
266
-			}
267
-
268
-			return $date;
269
-
270
-		}, $posts );
271
-
272
-		// Finally remove the excerpt filter.
273
-		remove_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
274
-
275
-		// The JSON format is defined here: https://timeline.knightlab.com/docs/json-format.html
276
-		return array(
277
-			'timeline'       => $timeline,
278
-			'start_at_slide' => $start_at_slide,
279
-		);
280
-	}
281
-
282
-	/**
283
-	 * This function filters {@link excerpt_more} by removing it, since we're
284
-	 * adding the 'read more' link. This filter is set by {@see to_json}.
285
-	 *
286
-	 * @param string $excerpt_more The excerpt more preset.
287
-	 *
288
-	 * @return string An empty string.
289
-	 * @since 3.7.0
290
-	 *
291
-	 */
292
-	public function excerpt_more( $excerpt_more ) {
293
-
294
-		return '';
295
-	}
296
-
297
-	/**
298
-	 * A filter for the excerpt length, set by the `to_json` function, to tailor
299
-	 * how many words to return according to the client setting.
300
-	 *
301
-	 * @param int $length The preset number of words.
302
-	 *
303
-	 * @return int The number of words for the preset.
304
-	 * @since 3.7.0
305
-	 *
306
-	 */
307
-	public function excerpt_length( $length ) {
308
-
309
-		return $this->excerpt_length;
310
-	}
311
-
312
-
313
-	/**
314
-	 * Convert the date to a date array.
315
-	 *
316
-	 * @param $value int A date value.
317
-	 *
318
-	 * @return array An array containing year, month and day values.
319
-	 * @since 3.7.0
320
-	 *
321
-	 */
322
-	public static function date( $value ) {
323
-
324
-		return array(
325
-			'year'  => (int) date( 'Y', $value ),
326
-			'month' => (int) date( 'm', $value ),
327
-			'day'   => (int) date( 'd', $value ),
328
-
329
-		);
330
-	}
331
-
332
-	/**
333
-	 * Get the entities related to the last 50 posts published on this blog (we're keeping a long function name due to
334
-	 * its specific function).
335
-	 *
336
-	 * @return array An array of post IDs.
337
-	 * @since 3.1.0
338
-	 *
339
-	 */
340
-	public function get_all_related_to_last_50_published_posts() {
341
-
342
-		// Global timeline. Get entities from the latest posts.
343
-		$latest_posts_ids = get_posts( array(
344
-			'numberposts' => 50,
345
-			'fields'      => 'ids', //only get post IDs
346
-			'post_type'   => Wordlift_Entity_Service::valid_entity_post_types(),
347
-			'tax_query'   => array(
348
-				'relation' => 'OR',
349
-				array(
350
-					'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
351
-					'operator' => 'NOT EXISTS',
352
-				),
353
-				array(
354
-					'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
355
-					'field'    => 'slug',
356
-					'terms'    => 'article',
357
-				),
358
-			),
359
-			'post_status' => 'publish',
360
-		) );
361
-
362
-		if ( empty( $latest_posts_ids ) ) {
363
-			// There are no posts.
364
-			return array();
365
-		}
366
-
367
-		// Collect entities related to latest posts
368
-		$entity_ids = array();
369
-		foreach ( $latest_posts_ids as $id ) {
370
-			$entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array(
371
-				'status' => 'publish',
372
-			) ) );
373
-		}
374
-
375
-		return $entity_ids;
376
-	}
19
+    /**
20
+     * The Log service.
21
+     *
22
+     * @since  3.1.0
23
+     * @access private
24
+     * @var \Wordlift_Log_Service $log The Log service.
25
+     */
26
+    private $log;
27
+
28
+    /**
29
+     * The Entity service.
30
+     *
31
+     * @since  3.1.0
32
+     * @access private
33
+     * @var \Wordlift_Entity_Service $entity_service The Entity service.
34
+     */
35
+    private $entity_service;
36
+
37
+    /**
38
+     * The number of words to use for the excerpt, set in the `to_json` function
39
+     * and used by a filter.
40
+     *
41
+     * @since  3.7.0
42
+     * @access private
43
+     * @var int $excerpt_length The number of words to use for the excerpt.
44
+     */
45
+    private $excerpt_length;
46
+
47
+    /**
48
+     * The {@link Wordlift_Entity_Type_Service} instance.
49
+     *
50
+     * @since  3.15.0
51
+     * @access private
52
+     * @var \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
53
+     */
54
+    private $entity_type_service;
55
+
56
+    /**
57
+     * A singleton instance of the Timeline service (useful for unit tests).
58
+     *
59
+     * @since  3.1.0
60
+     * @access private
61
+     * @var \Wordlift_Timeline_Service $instance The singleton instance.
62
+     */
63
+    private static $instance;
64
+
65
+    /**
66
+     * Create a Wordlift_Timeline_Service instance.
67
+     *
68
+     * @param \Wordlift_Entity_Service $entity_service The Entity service.
69
+     * @param \Wordlift_Entity_Type_Service $entity_type_service The {@link Wordlift_Entity_Type_Service} instance.
70
+     *
71
+     * @since 3.1.0
72
+     *
73
+     */
74
+    public function __construct( $entity_service, $entity_type_service ) {
75
+
76
+        $this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Service' );
77
+
78
+        $this->entity_service      = $entity_service;
79
+        $this->entity_type_service = $entity_type_service;
80
+
81
+        self::$instance = $this;
82
+
83
+    }
84
+
85
+    /**
86
+     * Get the singleton instance of the Wordlift_Timeline_Service
87
+     *
88
+     * @return \Wordlift_Timeline_Service The singleton instance of the Wordlift_Timeline_Service.
89
+     * @since 3.1.0
90
+     *
91
+     */
92
+    public static function get_instance() {
93
+
94
+        return self::$instance;
95
+    }
96
+
97
+    /**
98
+     * Retrieve timeline events and output them in JSON.
99
+     *
100
+     * @since 3.1.0
101
+     */
102
+    public function ajax_timeline() {
103
+
104
+        // Get the ID of the post who requested the timeline.
105
+        $post_id = ( isset( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : null );
106
+
107
+        // Get the events and transform them for the JSON response, then send them to the client.
108
+        wp_send_json( $this->to_json( $this->get_events( $post_id ) ) );
109
+
110
+    }
111
+
112
+    /**
113
+     * Retrieve timeline events.
114
+     *
115
+     * @param int $post_id The post ID.
116
+     *
117
+     * @return array An array of event posts.
118
+     * @since 3.1.0
119
+     *
120
+     * @uses  wl_core_get_related_entity_ids() to retrieve the entities referenced by the specified post.
121
+     *
122
+     */
123
+    public function get_events( $post_id = null ) {
124
+
125
+        // Get the entity IDs either from the entities related to the specified post or from the last 50 published
126
+        // posts if no post has been specified.
127
+        $ids = ( is_numeric( $post_id )
128
+            ? wl_core_get_related_entity_ids( $post_id, array( 'predicate' => 'where', ) )
129
+            : $this->get_all_related_to_last_50_published_posts() );
130
+
131
+        // Add the post itself if it's an entity.
132
+        if ( is_numeric( $post_id ) && $this->entity_service->is_entity( $post_id ) ) {
133
+            $ids[] = $post_id;
134
+        }
135
+
136
+        // If there's no entities, return an empty array right away.
137
+        if ( 0 === sizeof( $ids ) ) {
138
+            $this->log->trace( "No events found [ post id :: $post_id ]" );
139
+
140
+            return array();
141
+        }
142
+
143
+        $this->log->trace( 'Getting events [ entity ids :: ' . join( ', ', $ids ) . ' ]' );
144
+
145
+        $args = array(
146
+            'post__in'       => $ids,
147
+            'post_type'      => Wordlift_Entity_Service::valid_entity_post_types(),
148
+            'post_status'    => 'publish',
149
+            'posts_per_page' => - 1,
150
+            'meta_query'     => array(
151
+                'relation' => 'AND',
152
+                array(
153
+                    'key'     => Wordlift_Schema_Service::FIELD_DATE_START,
154
+                    'value'   => null,
155
+                    'compare' => '!=',
156
+                ),
157
+                array(
158
+                    'key'     => Wordlift_Schema_Service::FIELD_DATE_END,
159
+                    'value'   => null,
160
+                    'compare' => '!=',
161
+                ),
162
+            ),
163
+            'tax_query'      => array(
164
+                array(
165
+                    'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
166
+                    'field'    => 'slug',
167
+                    'terms'    => 'event',
168
+                ),
169
+            ),
170
+        );
171
+
172
+        return get_posts( $args );
173
+    }
174
+
175
+    /**
176
+     * Convert timeline events to JSON. This function sets the global post in order
177
+     * to get an automatic excerpt. Since we're being called inside an AJAX request,
178
+     * we're not taking care of restoring any previous post: there isn't any.
179
+     *
180
+     * @param array $posts An array of posts.
181
+     *
182
+     * @return array|string An array of timeline events or an empty string if no posts are provided.
183
+     * @since 3.1.0
184
+     *
185
+     */
186
+    public function to_json( $posts ) {
187
+
188
+        // If there are no events, return empty JSON
189
+        if ( empty( $posts ) || is_null( $posts ) ) {
190
+            return '';
191
+        }
192
+
193
+        // {media|thumbnail}: if set to 'media' the image is attached to the slide, if set to 'background' the image is set as background.
194
+        $display_images_as = isset( $_REQUEST['display_images_as'] ) ? $_REQUEST['display_images_as'] : 'media';
195
+
196
+        // The number of words for the excerpt (by default 55, as WordPress).
197
+        $this->excerpt_length = $excerpt_length = isset( $_REQUEST['excerpt_length'] ) && is_numeric( $_REQUEST['excerpt_length'] ) ? $_REQUEST['excerpt_length'] : 55;
198
+        add_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
199
+
200
+        // Add a filter to remove the [...] after excerpts, since we're adding
201
+        // a link to the post itself.
202
+        add_filter( 'excerpt_more', array( $this, 'excerpt_more' ) );
203
+
204
+        // Prepare for the starting slide data. The starting slide will be the one where *now* is between *start/end* dates.
205
+        $start_at_slide = 0;
206
+        $event_index    = - 1;
207
+        $now            = time();
208
+
209
+        // Prepare the timeline variable.
210
+        $timeline = array();
211
+
212
+        // Populate the arrays.
213
+        $timeline['events'] = array_map( function ( $item ) use ( &$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as, $excerpt_length ) {
214
+
215
+            // Get the start and end dates.
216
+            $start_date = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_START, true ) );
217
+            $end_date   = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_END, true ) );
218
+
219
+            // Set the starting slide.
220
+            $event_index ++;
221
+            if ( 0 === $start_at_slide && $now >= $start_date && $now <= $end_date ) {
222
+                $start_at_slide = $event_index;
223
+            }
224
+
225
+            // Load thumbnail
226
+            if ( '' !== ( $thumbnail_id = get_post_thumbnail_id( $item->ID ) )
227
+                 && false !== ( $attachment = wp_get_attachment_image_src( $thumbnail_id ) )
228
+            ) {
229
+
230
+                // Set the thumbnail URL.
231
+                if ( 'background' === $display_images_as ) {
232
+                    $date['background'] = array( 'url' => $attachment[0] );
233
+                    $date['media']      = array( 'thumbnail' => $attachment[0] );
234
+                } else {
235
+                    $date['media'] = array(
236
+                        'url'       => $attachment[0],
237
+                        'thumbnail' => $attachment[0],
238
+                    );
239
+                }
240
+            }
241
+
242
+            // Set the start/end dates by converting them to TimelineJS required format.
243
+            $date['start_date'] = Wordlift_Timeline_Service::date( $start_date );
244
+            $date['end_date']   = Wordlift_Timeline_Service::date( $end_date );
245
+
246
+            setup_postdata( $GLOBALS['post'] = $item );
247
+
248
+            $more_link_text = sprintf(
249
+                '<span aria-label="%1$s">%2$s</span>',
250
+                sprintf(
251
+                /* translators: %s: Name of current post */
252
+                    __( 'Continue reading %s' ),
253
+                    the_title_attribute( array( 'echo' => false ) )
254
+                ),
255
+                __( '(more&hellip;)' )
256
+            );
257
+
258
+            // Set the event text only with the headline (see https://github.com/insideout10/wordlift-plugin/issues/352).
259
+            $date['text'] = array(
260
+                'headline' => '<a href="' . get_permalink( $item->ID ) . '">' . $item->post_title . '</a>',
261
+            );
262
+
263
+            // If we have an excerpt, set it.
264
+            if ( 0 < $excerpt_length ) {
265
+                $date['text']['text'] = sprintf( '%s <a href="%s">%s</a>', get_the_excerpt(), get_permalink(), $more_link_text );
266
+            }
267
+
268
+            return $date;
269
+
270
+        }, $posts );
271
+
272
+        // Finally remove the excerpt filter.
273
+        remove_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
274
+
275
+        // The JSON format is defined here: https://timeline.knightlab.com/docs/json-format.html
276
+        return array(
277
+            'timeline'       => $timeline,
278
+            'start_at_slide' => $start_at_slide,
279
+        );
280
+    }
281
+
282
+    /**
283
+     * This function filters {@link excerpt_more} by removing it, since we're
284
+     * adding the 'read more' link. This filter is set by {@see to_json}.
285
+     *
286
+     * @param string $excerpt_more The excerpt more preset.
287
+     *
288
+     * @return string An empty string.
289
+     * @since 3.7.0
290
+     *
291
+     */
292
+    public function excerpt_more( $excerpt_more ) {
293
+
294
+        return '';
295
+    }
296
+
297
+    /**
298
+     * A filter for the excerpt length, set by the `to_json` function, to tailor
299
+     * how many words to return according to the client setting.
300
+     *
301
+     * @param int $length The preset number of words.
302
+     *
303
+     * @return int The number of words for the preset.
304
+     * @since 3.7.0
305
+     *
306
+     */
307
+    public function excerpt_length( $length ) {
308
+
309
+        return $this->excerpt_length;
310
+    }
311
+
312
+
313
+    /**
314
+     * Convert the date to a date array.
315
+     *
316
+     * @param $value int A date value.
317
+     *
318
+     * @return array An array containing year, month and day values.
319
+     * @since 3.7.0
320
+     *
321
+     */
322
+    public static function date( $value ) {
323
+
324
+        return array(
325
+            'year'  => (int) date( 'Y', $value ),
326
+            'month' => (int) date( 'm', $value ),
327
+            'day'   => (int) date( 'd', $value ),
328
+
329
+        );
330
+    }
331
+
332
+    /**
333
+     * Get the entities related to the last 50 posts published on this blog (we're keeping a long function name due to
334
+     * its specific function).
335
+     *
336
+     * @return array An array of post IDs.
337
+     * @since 3.1.0
338
+     *
339
+     */
340
+    public function get_all_related_to_last_50_published_posts() {
341
+
342
+        // Global timeline. Get entities from the latest posts.
343
+        $latest_posts_ids = get_posts( array(
344
+            'numberposts' => 50,
345
+            'fields'      => 'ids', //only get post IDs
346
+            'post_type'   => Wordlift_Entity_Service::valid_entity_post_types(),
347
+            'tax_query'   => array(
348
+                'relation' => 'OR',
349
+                array(
350
+                    'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
351
+                    'operator' => 'NOT EXISTS',
352
+                ),
353
+                array(
354
+                    'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
355
+                    'field'    => 'slug',
356
+                    'terms'    => 'article',
357
+                ),
358
+            ),
359
+            'post_status' => 'publish',
360
+        ) );
361
+
362
+        if ( empty( $latest_posts_ids ) ) {
363
+            // There are no posts.
364
+            return array();
365
+        }
366
+
367
+        // Collect entities related to latest posts
368
+        $entity_ids = array();
369
+        foreach ( $latest_posts_ids as $id ) {
370
+            $entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array(
371
+                'status' => 'publish',
372
+            ) ) );
373
+        }
374
+
375
+        return $entity_ids;
376
+    }
377 377
 
378 378
 }
Please login to merge, or discard this patch.
Spacing   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -71,9 +71,9 @@  discard block
 block discarded – undo
71 71
 	 * @since 3.1.0
72 72
 	 *
73 73
 	 */
74
-	public function __construct( $entity_service, $entity_type_service ) {
74
+	public function __construct($entity_service, $entity_type_service) {
75 75
 
76
-		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Service' );
76
+		$this->log = Wordlift_Log_Service::get_logger('Wordlift_Timeline_Service');
77 77
 
78 78
 		$this->entity_service      = $entity_service;
79 79
 		$this->entity_type_service = $entity_type_service;
@@ -102,10 +102,10 @@  discard block
 block discarded – undo
102 102
 	public function ajax_timeline() {
103 103
 
104 104
 		// Get the ID of the post who requested the timeline.
105
-		$post_id = ( isset( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : null );
105
+		$post_id = (isset($_REQUEST['post_id']) ? $_REQUEST['post_id'] : null);
106 106
 
107 107
 		// Get the events and transform them for the JSON response, then send them to the client.
108
-		wp_send_json( $this->to_json( $this->get_events( $post_id ) ) );
108
+		wp_send_json($this->to_json($this->get_events($post_id)));
109 109
 
110 110
 	}
111 111
 
@@ -120,33 +120,33 @@  discard block
 block discarded – undo
120 120
 	 * @uses  wl_core_get_related_entity_ids() to retrieve the entities referenced by the specified post.
121 121
 	 *
122 122
 	 */
123
-	public function get_events( $post_id = null ) {
123
+	public function get_events($post_id = null) {
124 124
 
125 125
 		// Get the entity IDs either from the entities related to the specified post or from the last 50 published
126 126
 		// posts if no post has been specified.
127
-		$ids = ( is_numeric( $post_id )
128
-			? wl_core_get_related_entity_ids( $post_id, array( 'predicate' => 'where', ) )
129
-			: $this->get_all_related_to_last_50_published_posts() );
127
+		$ids = (is_numeric($post_id)
128
+			? wl_core_get_related_entity_ids($post_id, array('predicate' => 'where',))
129
+			: $this->get_all_related_to_last_50_published_posts());
130 130
 
131 131
 		// Add the post itself if it's an entity.
132
-		if ( is_numeric( $post_id ) && $this->entity_service->is_entity( $post_id ) ) {
132
+		if (is_numeric($post_id) && $this->entity_service->is_entity($post_id)) {
133 133
 			$ids[] = $post_id;
134 134
 		}
135 135
 
136 136
 		// If there's no entities, return an empty array right away.
137
-		if ( 0 === sizeof( $ids ) ) {
138
-			$this->log->trace( "No events found [ post id :: $post_id ]" );
137
+		if (0 === sizeof($ids)) {
138
+			$this->log->trace("No events found [ post id :: $post_id ]");
139 139
 
140 140
 			return array();
141 141
 		}
142 142
 
143
-		$this->log->trace( 'Getting events [ entity ids :: ' . join( ', ', $ids ) . ' ]' );
143
+		$this->log->trace('Getting events [ entity ids :: '.join(', ', $ids).' ]');
144 144
 
145 145
 		$args = array(
146 146
 			'post__in'       => $ids,
147 147
 			'post_type'      => Wordlift_Entity_Service::valid_entity_post_types(),
148 148
 			'post_status'    => 'publish',
149
-			'posts_per_page' => - 1,
149
+			'posts_per_page' => -1,
150 150
 			'meta_query'     => array(
151 151
 				'relation' => 'AND',
152 152
 				array(
@@ -169,7 +169,7 @@  discard block
 block discarded – undo
169 169
 			),
170 170
 		);
171 171
 
172
-		return get_posts( $args );
172
+		return get_posts($args);
173 173
 	}
174 174
 
175 175
 	/**
@@ -183,23 +183,23 @@  discard block
 block discarded – undo
183 183
 	 * @since 3.1.0
184 184
 	 *
185 185
 	 */
186
-	public function to_json( $posts ) {
186
+	public function to_json($posts) {
187 187
 
188 188
 		// If there are no events, return empty JSON
189
-		if ( empty( $posts ) || is_null( $posts ) ) {
189
+		if (empty($posts) || is_null($posts)) {
190 190
 			return '';
191 191
 		}
192 192
 
193 193
 		// {media|thumbnail}: if set to 'media' the image is attached to the slide, if set to 'background' the image is set as background.
194
-		$display_images_as = isset( $_REQUEST['display_images_as'] ) ? $_REQUEST['display_images_as'] : 'media';
194
+		$display_images_as = isset($_REQUEST['display_images_as']) ? $_REQUEST['display_images_as'] : 'media';
195 195
 
196 196
 		// The number of words for the excerpt (by default 55, as WordPress).
197
-		$this->excerpt_length = $excerpt_length = isset( $_REQUEST['excerpt_length'] ) && is_numeric( $_REQUEST['excerpt_length'] ) ? $_REQUEST['excerpt_length'] : 55;
198
-		add_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
197
+		$this->excerpt_length = $excerpt_length = isset($_REQUEST['excerpt_length']) && is_numeric($_REQUEST['excerpt_length']) ? $_REQUEST['excerpt_length'] : 55;
198
+		add_filter('excerpt_length', array($this, 'excerpt_length'));
199 199
 
200 200
 		// Add a filter to remove the [...] after excerpts, since we're adding
201 201
 		// a link to the post itself.
202
-		add_filter( 'excerpt_more', array( $this, 'excerpt_more' ) );
202
+		add_filter('excerpt_more', array($this, 'excerpt_more'));
203 203
 
204 204
 		// Prepare for the starting slide data. The starting slide will be the one where *now* is between *start/end* dates.
205 205
 		$start_at_slide = 0;
@@ -210,27 +210,27 @@  discard block
 block discarded – undo
210 210
 		$timeline = array();
211 211
 
212 212
 		// Populate the arrays.
213
-		$timeline['events'] = array_map( function ( $item ) use ( &$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as, $excerpt_length ) {
213
+		$timeline['events'] = array_map(function($item) use (&$timeline, &$event_index, &$start_at_slide, &$now, $display_images_as, $excerpt_length) {
214 214
 
215 215
 			// Get the start and end dates.
216
-			$start_date = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_START, true ) );
217
-			$end_date   = strtotime( get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_DATE_END, true ) );
216
+			$start_date = strtotime(get_post_meta($item->ID, Wordlift_Schema_Service::FIELD_DATE_START, true));
217
+			$end_date   = strtotime(get_post_meta($item->ID, Wordlift_Schema_Service::FIELD_DATE_END, true));
218 218
 
219 219
 			// Set the starting slide.
220
-			$event_index ++;
221
-			if ( 0 === $start_at_slide && $now >= $start_date && $now <= $end_date ) {
220
+			$event_index++;
221
+			if (0 === $start_at_slide && $now >= $start_date && $now <= $end_date) {
222 222
 				$start_at_slide = $event_index;
223 223
 			}
224 224
 
225 225
 			// Load thumbnail
226
-			if ( '' !== ( $thumbnail_id = get_post_thumbnail_id( $item->ID ) )
227
-			     && false !== ( $attachment = wp_get_attachment_image_src( $thumbnail_id ) )
226
+			if ('' !== ($thumbnail_id = get_post_thumbnail_id($item->ID))
227
+			     && false !== ($attachment = wp_get_attachment_image_src($thumbnail_id))
228 228
 			) {
229 229
 
230 230
 				// Set the thumbnail URL.
231
-				if ( 'background' === $display_images_as ) {
232
-					$date['background'] = array( 'url' => $attachment[0] );
233
-					$date['media']      = array( 'thumbnail' => $attachment[0] );
231
+				if ('background' === $display_images_as) {
232
+					$date['background'] = array('url' => $attachment[0]);
233
+					$date['media']      = array('thumbnail' => $attachment[0]);
234 234
 				} else {
235 235
 					$date['media'] = array(
236 236
 						'url'       => $attachment[0],
@@ -240,37 +240,37 @@  discard block
 block discarded – undo
240 240
 			}
241 241
 
242 242
 			// Set the start/end dates by converting them to TimelineJS required format.
243
-			$date['start_date'] = Wordlift_Timeline_Service::date( $start_date );
244
-			$date['end_date']   = Wordlift_Timeline_Service::date( $end_date );
243
+			$date['start_date'] = Wordlift_Timeline_Service::date($start_date);
244
+			$date['end_date']   = Wordlift_Timeline_Service::date($end_date);
245 245
 
246
-			setup_postdata( $GLOBALS['post'] = $item );
246
+			setup_postdata($GLOBALS['post'] = $item);
247 247
 
248 248
 			$more_link_text = sprintf(
249 249
 				'<span aria-label="%1$s">%2$s</span>',
250 250
 				sprintf(
251 251
 				/* translators: %s: Name of current post */
252
-					__( 'Continue reading %s' ),
253
-					the_title_attribute( array( 'echo' => false ) )
252
+					__('Continue reading %s'),
253
+					the_title_attribute(array('echo' => false))
254 254
 				),
255
-				__( '(more&hellip;)' )
255
+				__('(more&hellip;)')
256 256
 			);
257 257
 
258 258
 			// Set the event text only with the headline (see https://github.com/insideout10/wordlift-plugin/issues/352).
259 259
 			$date['text'] = array(
260
-				'headline' => '<a href="' . get_permalink( $item->ID ) . '">' . $item->post_title . '</a>',
260
+				'headline' => '<a href="'.get_permalink($item->ID).'">'.$item->post_title.'</a>',
261 261
 			);
262 262
 
263 263
 			// If we have an excerpt, set it.
264
-			if ( 0 < $excerpt_length ) {
265
-				$date['text']['text'] = sprintf( '%s <a href="%s">%s</a>', get_the_excerpt(), get_permalink(), $more_link_text );
264
+			if (0 < $excerpt_length) {
265
+				$date['text']['text'] = sprintf('%s <a href="%s">%s</a>', get_the_excerpt(), get_permalink(), $more_link_text);
266 266
 			}
267 267
 
268 268
 			return $date;
269 269
 
270
-		}, $posts );
270
+		}, $posts);
271 271
 
272 272
 		// Finally remove the excerpt filter.
273
-		remove_filter( 'excerpt_length', array( $this, 'excerpt_length' ) );
273
+		remove_filter('excerpt_length', array($this, 'excerpt_length'));
274 274
 
275 275
 		// The JSON format is defined here: https://timeline.knightlab.com/docs/json-format.html
276 276
 		return array(
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
 	 * @since 3.7.0
290 290
 	 *
291 291
 	 */
292
-	public function excerpt_more( $excerpt_more ) {
292
+	public function excerpt_more($excerpt_more) {
293 293
 
294 294
 		return '';
295 295
 	}
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
 	 * @since 3.7.0
305 305
 	 *
306 306
 	 */
307
-	public function excerpt_length( $length ) {
307
+	public function excerpt_length($length) {
308 308
 
309 309
 		return $this->excerpt_length;
310 310
 	}
@@ -319,12 +319,12 @@  discard block
 block discarded – undo
319 319
 	 * @since 3.7.0
320 320
 	 *
321 321
 	 */
322
-	public static function date( $value ) {
322
+	public static function date($value) {
323 323
 
324 324
 		return array(
325
-			'year'  => (int) date( 'Y', $value ),
326
-			'month' => (int) date( 'm', $value ),
327
-			'day'   => (int) date( 'd', $value ),
325
+			'year'  => (int) date('Y', $value),
326
+			'month' => (int) date('m', $value),
327
+			'day'   => (int) date('d', $value),
328 328
 
329 329
 		);
330 330
 	}
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
 	public function get_all_related_to_last_50_published_posts() {
341 341
 
342 342
 		// Global timeline. Get entities from the latest posts.
343
-		$latest_posts_ids = get_posts( array(
343
+		$latest_posts_ids = get_posts(array(
344 344
 			'numberposts' => 50,
345 345
 			'fields'      => 'ids', //only get post IDs
346 346
 			'post_type'   => Wordlift_Entity_Service::valid_entity_post_types(),
@@ -357,19 +357,19 @@  discard block
 block discarded – undo
357 357
 				),
358 358
 			),
359 359
 			'post_status' => 'publish',
360
-		) );
360
+		));
361 361
 
362
-		if ( empty( $latest_posts_ids ) ) {
362
+		if (empty($latest_posts_ids)) {
363 363
 			// There are no posts.
364 364
 			return array();
365 365
 		}
366 366
 
367 367
 		// Collect entities related to latest posts
368 368
 		$entity_ids = array();
369
-		foreach ( $latest_posts_ids as $id ) {
370
-			$entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array(
369
+		foreach ($latest_posts_ids as $id) {
370
+			$entity_ids = array_merge($entity_ids, wl_core_get_related_entity_ids($id, array(
371 371
 				'status' => 'publish',
372
-			) ) );
372
+			)));
373 373
 		}
374 374
 
375 375
 		return $entity_ids;
Please login to merge, or discard this patch.