GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#36)
by
unknown
02:11
created

hm-post-repeat.php ➔ delete_next_scheduled_repeat_post()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
Plugin Name: Repeatable Posts
5
Description: Designate a post as repeatable and it'll be copied and re-published on your chosen interval.
6
Author: Human Made Limited
7
Author URI: http://hmn.md/
8
Version: 0.4
9
License: GPL-2.0+
10
License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
Text Domain: hm-post-repeat
12
Domain Path: /languages
13
*/
14
15
/*
16
Copyright Human Made Limited  (email : [email protected])
17
18
This program is free software; you can redistribute it and/or modify
19
it under the terms of the GNU General Public License as published by
20
the Free Software Foundation; either version 2 of the License, or
21
(at your option) any later version.
22
23
This program is distributed in the hope that it will be useful,
24
but WITHOUT ANY WARRANTY; without even the implied warranty of
25
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
GNU General Public License for more details.
27
28
You should have received a copy of the GNU General Public License
29
along with this program; if not, write to the Free Software
30
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31
*/
32
33
namespace HM\Post_Repeat;
34
35
/**
36
 * Setup the actions and filters required by this class.
37
 */
38
add_action( 'post_submitbox_misc_actions', __NAMESPACE__ . '\publish_box_ui' );
39
add_action( 'save_post',                   __NAMESPACE__ . '\manage_repeat_post', 10 );
40
add_action( 'admin_enqueue_scripts',       __NAMESPACE__ . '\enqueue_scripts' );
41
add_filter( 'display_post_states',         __NAMESPACE__ . '\admin_table_row_post_states', 10, 2 );
42
43
// Add repeat type table view links to admin screen for each CPT that supports Repeatable Posts.
44
add_action( 'init', function() {
45
	foreach ( repeating_post_types() as $post_type ) {
46
		add_filter( "views_edit-{$post_type}", __NAMESPACE__ . '\admin_table_views_links' );
47
	}
48
} );
49
50
// Display only Repeatable Posts in admin table view for registered view links.
51
add_filter( 'pre_get_posts', __NAMESPACE__ . '\admin_table_repeat_type_posts_query' );
52
53
/**
54
 * Enqueue the scripts and styles that are needed by this plugin.
55
 */
56
function enqueue_scripts( $hook ) {
57
58
	// Ensure we only load them on the edit post and add new post admin screens
59
	if ( ! in_array( $hook, array( 'post.php', 'post-new.php' ) ) ) {
60
		return;
61
	}
62
63
	$plugin_data = get_plugin_data( __FILE__ );
64
	$plugin_dir_url = plugin_dir_url( __FILE__ );
65
66
	wp_enqueue_script( 'hm-post-repeat', $plugin_dir_url . 'hm-post-repeat.js', 'jquery', $plugin_data['Version'], true );
67
	wp_enqueue_style( 'hm-post-repeat', $plugin_dir_url . 'hm-post-repeat.css', array(), $plugin_data['Version'] );
68
69
}
70
71
/**
72
 * Output the Post Repeat UI that is shown in the Publish post meta box.
73
 *
74
 * The UI varies depending on whether the post is the original repeating post
75
 * or itself a repeat.
76
 */
77
function publish_box_ui() {
78
79
	if ( ! in_array( get_post_type(), repeating_post_types() ) ) {
80
		return;
81
	} ?>
82
83
	<div class="misc-pub-section misc-pub-hm-post-repeat">
84
85
		<span class="dashicons dashicons-controls-repeat"></span>
86
87
		<?php esc_html_e( 'Repeat:', 'hm-post-repeat' ); ?>
88
89
		<?php if ( is_repeat_post( get_the_id() ) ) : ?>
90
91
			<strong><?php printf( esc_html__( 'Repeat of %s', 'hm-post-repeat' ), '<a href="' . esc_url( get_edit_post_link( get_post()->post_parent ) ) . '">' . esc_html( get_the_title( get_post_field( 'post_parent', get_the_id() ) ) ) . '</a>' ); ?></strong>
92
93
		<?php else : ?>
94
95
			<?php $repeating_schedule = get_repeating_schedule( get_the_id() ); ?>
96
			<?php $is_repeating_post = is_repeating_post( get_the_id() ) && isset( $repeating_schedule ); ?>
97
98
			<strong><?php echo ! $is_repeating_post ? esc_html__( 'No', 'hm-post-repeat' ) : esc_html( $repeating_schedule['display'] ); ?></strong>
99
100
			<a href="#hm-post-repeat" class="edit-hm-post-repeat hide-if-no-js"><span aria-hidden="true"><?php esc_html_e( 'Edit', 'hm-post-repeat' ); ?></span> <span class="screen-reader-text"><?php esc_html_e( 'Edit Repeat Settings', 'hm-post-repeat' ); ?></span></a>
101
102
			<span class="hide-if-js" id="hm-post-repeat">
103
104
				<select name="hm-post-repeat">
105
					<option<?php selected( ! $is_repeating_post ); ?> value="no"><?php esc_html_e( 'No', 'hm-post-repeat' ); ?></option>
106
					<?php foreach ( get_repeating_schedules() as $schedule_slug => $schedule ) : ?>
107
						<option<?php selected( $is_repeating_post && $schedule_slug === $repeating_schedule['slug'] ); ?> value="<?php echo esc_attr( $schedule_slug ); ?>"><?php echo esc_html( $schedule['display'] ); ?></option>
108
					<?php endforeach; ?>
109
				</select>
110
111
				<a href="#hm-post-repeat" class="save-post-hm-post-repeat hide-if-no-js button"><?php esc_html_e( 'OK', 'hm-post-repeat' ); ?></a>
112
113
			</span>
114
115
		<?php endif; ?>
116
117
	</div>
118
119
<?php }
120
121
/**
122
 * Add some custom post states to cover repeat and repeating posts.
123
 *
124
 * By default post states are displayed on the Edit Post screen in bold after the post title.
125
 *
126
 * @param array   $post_states The original array of post states.
127
 * @param WP_Post $post        The post object to get / return the states.
128
 * @return array The array of post states with ours added.
129
 */
130
function admin_table_row_post_states( $post_states, $post ) {
131
132
	if ( is_repeating_post( $post->ID ) ) {
133
134
		// If the schedule has been removed since publishing, let the user know.
135
		if ( get_repeating_schedule( $post->ID ) ) {
136
			$post_states['hm-post-repeat'] = __( 'Repeating', 'hm-post-repeat' );
137
		} else {
138
			$post_states['hm-post-repeat'] = __( 'Invalid Repeating Schedule', 'hm-post-repeat' );
139
		}
140
141
	}
142
143
	if ( is_repeat_post( $post->ID ) ) {
144
		$post_states['hm-post-repeat'] = __( 'Repeat', 'hm-post-repeat' );
145
	}
146
147
	return $post_states;
148
}
149
150
/**
151
 * Manage Repeating Post functionality:
152
 *
153
 * 1. Correctly mark/un-mark a Repeating post as such (i.e. save/delete the Repeating Schedule to/from post meta).
154
 * 2. Manage cleanup and creation of a corresponding Repeat post.
155
 *
156
 * @param int $post_id                The ID of the (Repeating or Repeat) post being saved.
157
 *                                    NB: Used to manually set the Repeating post ID from tests.
158
 * @param string $post_repeat_setting Repeating Schedule setting (daily, weekly, etc).
159
 *                                    NB: Used to manually set the Repeating Schedule for a post from tests.
160
 */
161
function manage_repeat_post( $post_id = null, $post_repeat_setting = null ) {
162
163
	// Not running a phpunit test - check if Repeating Schedule setting value is present when saving a post.
164
	if ( is_null( $post_repeat_setting ) ) {
165
		$post_repeat_setting = isset( $_POST['hm-post-repeat'] ) ? sanitize_text_field( $_POST['hm-post-repeat'] ) : '';
166
	}
167
168
	/**
169
	 * Stop - if:
170
	 * 1. Post type doesn't support Repeating Posts feature.
171
	 * 2. Not processing a Repeat post.
172
	 * 3. Not processing a Repeating post (i.e. Repeating Schedule isn't specified).
173
	 */
174
	if (
175
			! in_array( get_post_type( $post_id ), repeating_post_types() ) ||
176
			( ! is_repeat_post( $post_id ) && empty( $post_repeat_setting ) )
177
	) {
178
		return;
179
	}
180
181
	// Repeating post - save the specified Repeating Schedule and manage a Repeat post.
182
	if ( $post_repeat_setting ) {
183
184
		// Repeating Schedule is removed - i.e. the post is no longer Repeating.
185
		if ( 'no' === $post_repeat_setting ) {
186
187
			// Remove post meta from the Repeating post.
188
			delete_post_meta( $post_id, 'hm-post-repeat' );
189
190
			// Clean up the currently scheduled Repeat post if any.
191
			delete_next_scheduled_repeat_post( $post_id );
192
		}
193
		// Repeating Schedule is specified and valid - save it to post's meta and manage a Repeat post.
194
		elseif ( in_array( $post_repeat_setting, array_keys( get_repeating_schedules() ) ) ) {
195
196
			/**
197
			 * Clean up the currently scheduled Repeat post if any. This takes care of cases when:
198
			 * 1. Repeating Schedule has changed.
199
			 * 2. Content of the Repeating post is changed.
200
			 *
201
			 * In such cases, the next scheduled post should reflect these changes.
202
			 */
203
			delete_next_scheduled_repeat_post( $post_id );
204
205
			// Update a Repeating Schedule for the current post.
206
			update_post_meta( $post_id, 'hm-post-repeat', $post_repeat_setting );
207
208
			// Schedule a Repeat post.
209
			create_next_repeat_post( $post_id );
210
		}
211
	}
212
213
	// Repeat post - is published, schedule a next Repeat post.
214
	if ( is_repeat_post( $post_id ) && 'publish' === get_post_status( $post_id ) ) {
215
216
		create_next_repeat_post( $post_id );
217
	}
218
}
219
220
/**
221
 * Create the next Repeat post when:
222
 * 1. a Repeating post is published or already published post is re-saved.
223
 * 2. a previously scheduled Repeat post is published.
224
 *
225
 * In such cases we copy the Repeating post and schedule a new Repeat post to publish on the correct interval.
226
 * This way the next Repeat post is always ready to go.
227
 *
228
 * @param int $post_id The ID of the (Repeating or Repeat) post being saved.
229
 *
230
 * @return int|\WP_Error A scheduled Repeat post ID on success,
231
 *                       WP_Error if a Repeat post could not be created.
232
 *                       Terminate function execution if conditions are not met.
233
 */
234
function create_next_repeat_post( $post_id ) {
235
236
	// Stop - post type doesn't support Repeating Posts feature.
237
	if ( ! in_array( get_post_type( $post_id ), repeating_post_types() ) ) {
238
		return false;
239
	}
240
241
	// Stop - the current post isn't being published.
242
	if ( 'publish' !== get_post_status( $post_id ) ) {
243
		return false;
244
	}
245
246
	// Get the Repeating post ID for the current post being saved (which in turn can be a Repeating or Repeat post).
247
	$original_post_id = get_repeating_post( $post_id );
248
249
	if ( ! $original_post_id ) {
250
		return false;
251
	}
252
253
	// Get the original Repeating post.
254
	$original_post = get_post( $original_post_id, ARRAY_A );
255
256
	// Stop - the original Repeating post isn't already published.
257
	if ( 'publish' !== $original_post['post_status'] ) {
258
		return false;
259
	}
260
261
	// Stop - there is already a Repeat post scheduled don't create another one.
262
	if ( get_next_scheduled_repeat_post( $original_post['ID'] ) ) {
263
		return false;
264
	}
265
266
	// Get Repeating Schedule.
267
	$repeating_schedule = get_repeating_schedule( $original_post['ID'] );
268
269
	if ( ! $repeating_schedule ) {
270
		return false;
271
	}
272
273
	$next_post = $original_post;
274
275
	// Create the Repeat post as a copy of the original, but ignore some fields.
276
	unset( $next_post['ID'] );
277
	unset( $next_post['guid'] );
278
	unset( $next_post['post_date_gmt'] );
279
	unset( $next_post['post_modified'] );
280
	unset( $next_post['post_modified_gmt'] );
281
282
	// Set the post_parent to the original Repeating post_id, so they're related.
283
	$next_post['post_parent'] = $original_post['ID'];
284
285
	// Set the next Repeat post to publish in the future.
286
	$next_post['post_status'] = 'future';
287
288
	// Use the date of the current post being saved as the base.
289
	$next_post['post_date'] = date( 'Y-m-d H:i:s', strtotime( get_post_field( 'post_date', $post_id ) . ' + ' . $repeating_schedule['interval'] ) );
290
291
	// Make sure the next post will be in the future from the current time.
292
	if ( strtotime( $next_post['post_date'] ) <= time() ) {
293
		return false;
294
	}
295
296
	/**
297
	 * Use this filter to modify the scheduled post before it gets stored.
298
	 *
299
	 * @param array $next_post          The post data about to be saved.
300
	 * @param array $repeating_schedule Repeating schedule info.
301
	 * @param array $original_post      The original repeating post.
302
	 */
303
	$next_post = apply_filters( 'hm_post_repeat_edit_repeat_post', $next_post, $repeating_schedule, $original_post );
304
305
	/**
306
	 * Remove and then re-add our custom functionality hooked in into `save_post` filter.
307
	 * This is due to inserting a Repeat post using `wp_insert_post()` which in turn
308
	 * calls the `save_post` filters again.
309
	 *
310
	 * We want our custom functionality to run on the `save_post` filter only once.
311
	 */
312
	remove_action( 'save_post', __NAMESPACE__ . '\\manage_repeat_post' );
313
314
	// All checks done, get that post scheduled!
315
	$next_post_id = wp_insert_post( wp_slash( $next_post ), true );
316
317
	add_action( 'save_post', __NAMESPACE__ . '\\manage_repeat_post' );
318
319
	if ( is_wp_error( $next_post_id ) ) {
320
		return false;
321
	}
322
323
	// Mirror any post meta.
324
	$post_meta = get_post_meta( $original_post['ID'] );
325
326
	if ( $post_meta ) {
327
328
		// Ignore some internal meta fields.
329
		unset( $post_meta['_edit_lock'] );
330
		unset( $post_meta['_edit_last'] );
331
332
		// Don't copy the post Repeating Schedule meta as only the original Repeating post should have that.
333
		unset( $post_meta['hm-post-repeat'] );
334
335
		foreach ( $post_meta as $key => $values ) {
336
			foreach ( $values as $value ) {
337
				add_post_meta( $next_post_id, $key, maybe_unserialize( $value ) );
338
			}
339
		}
340
	}
341
342
	// Mirror any term relationships.
343
	$taxonomies = get_object_taxonomies( $original_post['post_type'] );
344
345
	foreach ( $taxonomies as $taxonomy ) {
346
		wp_set_object_terms( $next_post_id, wp_list_pluck( wp_get_object_terms( $original_post['ID'], $taxonomy ), 'slug' ), $taxonomy );
347
	}
348
349
	return $next_post_id;
350
}
351
352
/**
353
 * The post types the feature is enabled on
354
 *
355
 * By default only posts have the feature enabled but others can be added with the `hm_post_repeat_post_types` filter.
356
 *
357
 * @return array An array of post types
358
 */
359
function repeating_post_types() {
360
361
	/**
362
	 * Enable support for additional post types.
363
	 *
364
	 * @param string[] $post_types Post type slugs.
365
	 */
366
	return apply_filters( 'hm_post_repeat_post_types', array( 'post' ) );
367
368
}
369
370
/**
371
 * All available repeat schedules.
372
 *
373
 * @return array An array of all available repeat schedules
374
 */
375
function get_repeating_schedules() {
376
377
	/**
378
	 * Enable support for additional schedules.
379
	 *
380
	 * @param array[] $schedules Schedule array items.
381
	 */
382
	$schedules = apply_filters( 'hm_post_repeat_schedules', array(
383
		'daily'   => array( 'interval' => '1 day',   'display' => __( 'Daily',   'hm-post-repeat' ) ),
384
		'weekly'  => array( 'interval' => '1 week',  'display' => __( 'Weekly',  'hm-post-repeat' ) ),
385
		'monthly' => array( 'interval' => '1 month', 'display' => __( 'Monthly', 'hm-post-repeat' ) ),
386
	) );
387
388
	foreach ( $schedules as $slug => &$schedule ) {
389
		$schedule['slug'] = $slug;
390
	}
391
392
	return $schedules;
393
394
}
395
396
/**
397
 * Get the repeating schedule of the given post_id.
398
 *
399
 * @param int $post_id The id of the post you want to check.
400
 * @return array|null The schedule to repeat by, or null if invalid.
401
 */
402
function get_repeating_schedule( $post_id ) {
403
404
	if ( ! is_repeating_post( $post_id ) ) {
405
		return;
406
	}
407
408
	$repeating_schedule = get_post_meta( $post_id, 'hm-post-repeat', true );
409
	$schedules = get_repeating_schedules();
410
411
	// Backwards compatibility with 0.3 when we only supported weekly
412
	if ( '1' === $repeating_schedule ) {
413
		$repeating_schedule = 'weekly';
414
	}
415
416
	if ( array_key_exists( $repeating_schedule, $schedules ) ) {
417
		return $schedules[ $repeating_schedule ];
418
	}
419
420
}
421
422
/**
423
 * Check whether a given post_id is a repeating post.
424
 *
425
 * A repeating post is defined as the original post that was set to repeat.
426
 *
427
 * @param int $post_id The id of the post you want to check.
428
 * @return bool Whether the passed post_id is a repeating post or not.
429
 */
430
function is_repeating_post( $post_id ) {
431
432
	// We check $_POST data so that this function works inside a `save_post` hook when the post_meta hasn't yet been saved
433
	if ( isset( $_POST['hm-post-repeat'] ) && isset( $_POST['ID'] ) && $_POST['ID'] === $post_id ) {
434
		return true;
435
	}
436
437
	if ( get_post_meta( $post_id, 'hm-post-repeat', true ) ) {
438
		return true;
439
	}
440
441
	return false;
442
443
}
444
445
/**
446
 * Check whether a given post_id is a repeat post.
447
 *
448
 * A repeat post is defined as any post which is a repeat of the original repeating post.
449
 *
450
 * @param int $post_id The id of the post you want to check.
451
 * @return bool Whether the passed post_id is a repeat post or not.
452
 */
453
function is_repeat_post( $post_id ) {
454
455
	$post_parent = get_post_field( 'post_parent', $post_id );
456
457
	if ( $post_parent && get_post_meta( $post_parent, 'hm-post-repeat', true ) ) {
458
		return true;
459
	}
460
461
	return false;
462
}
463
464
/**
465
 * Delete currently scheduled i.e. future Repeat posts for the specified post.
466
 *
467
 * @param $post_id The ID of a Repeat or Repeating post to delete scheduled posts for.
468
 */
469
function delete_next_scheduled_repeat_post( $post_id ) {
470
471
	// TO DO: will it ever be more than 1 scheduled post?
472
	$next_repeat_post = get_next_scheduled_repeat_post( $post_id );
473
474
	if ( $next_repeat_post ) {
475
		// TO DO: should we trash or permanently delete? I think permanently delete.
476
		wp_delete_post( $next_repeat_post->ID, true );
477
	}
478
}
479
480
/**
481
 * Get the next scheduled repeat post.
482
 *
483
 * @param int $post_id The ID of a Repeat or Repeating post.
484
 *
485
 * @return int|bool Return the ID of the next repeat post_id or false if it can't find one.
486
 */
487
function get_next_scheduled_repeat_post( $post_id ) {
488
489
	$post = get_post( get_repeating_post( $post_id ) );
490
491
	$repeat_posts = get_posts( array( 'post_status' => 'future', 'post_parent' => $post->ID ) );
492
493
	if ( isset( $repeat_posts[0] ) ) {
494
		return $repeat_posts[0];
495
	}
496
497
	return false;
498
}
499
500
/**
501
 * Get the next scheduled repeat post.
502
 *
503
 * @param int $post_id The ID of a Repeat or Repeating post.
504
 *
505
 * @return int|bool Return the original repeating post_id or false if it can't find it.
506
 */
507
function get_repeating_post( $post_id ) {
508
509
	$original_post_id = false;
510
511
	// Are we publishing a Repeat post.
512
	if ( is_repeat_post( $post_id ) ) {
513
		$original_post_id = get_post( $post_id )->post_parent;
514
	}
515
516
	// Or the original Repeating post.
517
	elseif ( is_repeating_post( $post_id ) ) {
518
		$original_post_id = $post_id;
519
	}
520
521
	return $original_post_id;
522
}
523
524
/**
525
 * Adds admin table view link per available repeat type.
526
 * So that only all posts of specific repeat type are displayed.
527
 *
528
 * Added at the end of link list for All | Mine | Published | Scheduled | Drafts
529
 *
530
 * @param array $views An array of available list table views.
531
 *
532
 * @return array Available list of table views with custom added views per repeat type.
533
 */
534
function admin_table_views_links( $views ) {
535
536
	// Add status link for each repeat type.
537
	foreach ( get_available_repeat_types() as $repeat_type => $repeat_desc ) {
538
539
		$url_args = array(
540
			'post_type'      => get_current_screen()->post_type,
541
			'hm-post-repeat' => $repeat_type,
542
		);
543
544
		// Custom WP_Query to get posts count of repeat type.
545
		$repeat_type_query = new \WP_Query( get_repeat_type_query_params( $repeat_type ) );
546
547
		$link_label = sprintf(
548
				'%s <span class="count">(%s)</span>',
549
			esc_html( $repeat_desc ),
550
			esc_html( number_format_i18n( $repeat_type_query->post_count ) )
551
		);
552
553
		// Add current class to the link to highlight it when it's selected.
554
		$class_html = ( get_repeat_type_url_param() === $repeat_type ) ? ' class="current"' : '';
555
556
		$link_html = sprintf(
557
			'<a href="%s"%s>%s</a>',
558
			esc_url( add_query_arg( $url_args, 'edit.php' ) ),
559
			$class_html, // html - hardcoded, no need to escape.
560
			$link_label  // html - escaped earlier in the code.
561
		);
562
563
		$views[ $repeat_type ] = $link_html;
564
	}
565
566
	return $views;
567
}
568
569
/**
570
 * Customizes main admin query to get posts of specified repeat type
571
 * to be displayed in the admin table.
572
 *
573
 * @param \WP_Query $wp_query Main admin query.
574
 *
575
 * @return mixed Main admin query with edited params to get posts of specified repeat type.
576
 */
577
function admin_table_repeat_type_posts_query( $wp_query ) {
578
579
	// Stop - if not admin or not main query (there are secondary WP_Query for counting posts for view links, etc).
580
	if ( ! is_admin() || ! $wp_query->is_main_query() ) {
581
		return $wp_query;
582
	}
583
584
	// Get URL query param for repeat type and check it's valid.
585
	$repeat_type = get_repeat_type_url_param();
586
587
	if ( ! $repeat_type || ! is_allowed_repeat_type( $repeat_type ) ) {
588
		return $wp_query;
589
	}
590
591
	// Add a table view link per each repeat type.
592
	foreach ( get_repeat_type_query_params( $repeat_type ) as $key => $value ) {
593
		$wp_query->set( $key, $value );
594
	}
595
596
	return $wp_query;
597
}
598
599
/**
600
 * Returns array of custom WP_Query params to get posts of specified repeat type.
601
 * Works for all CPT that support Repeatable Posts.
602
 *
603
 * @param string $repeat_type Repeat type of posts to get.
604
 *
605
 * @return array Array of custom WP_Query params.
606
 */
607
function get_repeat_type_query_params( $repeat_type ) {
608
609
	$query['post_type'] = get_current_screen()->post_type;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $query = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
610
611
	// Construct custom query to get posts of specified repeat type.
612
	$query['meta_query'] = array(
613
			array(
614
					'key'     => 'hm-post-repeat',
615
					'compare' => 'EXISTS',
616
			),
617
	);
618
619
	if ( $repeat_type === 'repeat' ) {
620
		$query['post_parent__not_in'] = array( 0 );
621
622
	} elseif ( $repeat_type === 'repeating' ) {
623
		$query['post_parent__in'] = array( 0 );
624
	}
625
626
	return $query;
627
}
628
629
/**
630
 * Get URL query param for the repeat type of posts being displayed
631
 * in the admin post table.
632
 *
633
 * @return string Sanitized string of repeat type being displayed.
634
 */
635
function get_repeat_type_url_param() {
636
	return isset( $_GET['hm-post-repeat'] ) ? sanitize_text_field( $_GET['hm-post-repeat'] ) : '';
637
}
638
639
/**
640
 * Return available repeat types, i.e. repeating or repeat.
641
 *
642
 * @return array Available repeat types.
643
 */
644
function get_available_repeat_types() {
645
	return array(
646
		'repeating' => __( 'Repeating', 'hm-post-repeat' ),
647
		'repeat'    => __( 'Repeat', 'hm-post-repeat' ),
648
	);
649
}
650
651
/**
652
 * Check if a repeat type is valid.
653
 *
654
 * @param string $repeat_type Repeat type to check.
655
 *
656
 * @return bool True if repeat type is valid,
657
 *              False otherwise.
658
 */
659
function is_allowed_repeat_type( $repeat_type ) {
660
	return in_array( $repeat_type, array_keys( get_available_repeat_types() ) );
661
}
662