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
01:32
created

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

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 6
nop 2
dl 0
loc 19
rs 9.2
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__ . '\save_post_repeating_status', 10 );
40
add_action( 'save_post',                   __NAMESPACE__ . '\create_next_repeat_post', 11 );
41
add_action( 'admin_enqueue_scripts',       __NAMESPACE__ . '\enqueue_scripts' );
42
add_filter( 'display_post_states',         __NAMESPACE__ . '\admin_table_row_post_states', 10, 2 );
43
44
// Add repeat type table view links to admin screen for each CPT that supports Repeatable Posts.
45
add_action( 'init', function() {
46
	foreach ( repeating_post_types() as $post_type ) {
47
		add_filter( "views_edit-{$post_type}", __NAMESPACE__ . '\admin_table_views_links' );
48
	}
49
} );
50
51
// Display only Repeatable Posts in admin table view for registered view links.
52
add_filter( 'pre_get_posts', __NAMESPACE__ . '\admin_table_repeat_type_posts_query' );
53
54
/**
55
 * Enqueue the scripts and styles that are needed by this plugin.
56
 */
57
function enqueue_scripts( $hook ) {
58
59
	// Ensure we only load them on the edit post and add new post admin screens
60
	if ( ! in_array( $hook, array( 'post.php', 'post-new.php' ) ) ) {
61
		return;
62
	}
63
64
	$plugin_data = get_plugin_data( __FILE__ );
65
	$plugin_dir_url = plugin_dir_url( __FILE__ );
66
67
	wp_enqueue_script( 'hm-post-repeat', $plugin_dir_url . 'hm-post-repeat.js', 'jquery', $plugin_data['Version'], true );
68
	wp_enqueue_style( 'hm-post-repeat', $plugin_dir_url . 'hm-post-repeat.css', array(), $plugin_data['Version'] );
69
70
}
71
72
/**
73
 * Output the Post Repeat UI that is shown in the Publish post meta box.
74
 *
75
 * The UI varies depending on whether the post is the original repeating post
76
 * or itself a repeat.
77
 */
78
function publish_box_ui() {
79
80
	if ( ! in_array( get_post_type(), repeating_post_types() ) ) {
81
		return;
82
	} ?>
83
84
	<div class="misc-pub-section misc-pub-hm-post-repeat">
85
86
		<span class="dashicons dashicons-controls-repeat"></span>
87
88
		<?php esc_html_e( 'Repeat:', 'hm-post-repeat' ); ?>
89
90
		<?php if ( is_repeat_post( get_the_id() ) ) : ?>
91
92
			<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>
93
94
		<?php else : ?>
95
96
			<?php $repeating_schedule = get_repeating_schedule( get_the_id() ); ?>
97
			<?php $is_repeating_post = is_repeating_post( get_the_id() ) && isset( $repeating_schedule ); ?>
98
99
			<strong><?php echo ! $is_repeating_post ? esc_html__( 'No', 'hm-post-repeat' ) : esc_html( $repeating_schedule['display'] ); ?></strong>
100
101
			<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>
102
103
			<span class="hide-if-js" id="hm-post-repeat">
104
105
				<select name="hm-post-repeat">
106
					<option<?php selected( ! $is_repeating_post ); ?> value="no"><?php esc_html_e( 'No', 'hm-post-repeat' ); ?></option>
107
					<?php foreach ( get_repeating_schedules() as $schedule_slug => $schedule ) : ?>
108
						<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>
109
					<?php endforeach; ?>
110
				</select>
111
112
				<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>
113
114
			</span>
115
116
		<?php endif; ?>
117
118
	</div>
119
120
<?php }
121
122
/**
123
 * Add some custom post states to cover repeat and repeating posts.
124
 *
125
 * By default post states are displayed on the Edit Post screen in bold after the post title.
126
 *
127
 * @param array   $post_states The original array of post states.
128
 * @param WP_Post $post        The post object to get / return the states.
129
 * @return array The array of post states with ours added.
130
 */
131
function admin_table_row_post_states( $post_states, $post ) {
132
133
	if ( is_repeating_post( $post->ID ) ) {
134
135
		// If the schedule has been removed since publishing, let the user know.
136
		if ( get_repeating_schedule( $post->ID ) ) {
137
			$post_states['hm-post-repeat'] = __( 'Repeating', 'hm-post-repeat' );
138
		} else {
139
			$post_states['hm-post-repeat'] = __( 'Invalid Repeating Schedule', 'hm-post-repeat' );
140
		}
141
142
	}
143
144
	if ( is_repeat_post( $post->ID ) ) {
145
		$post_states['hm-post-repeat'] = __( 'Repeat', 'hm-post-repeat' );
146
	}
147
148
	return $post_states;
149
}
150
151
/**
152
 * Save the repeating status to post meta.
153
 *
154
 * Hooked into `save_post`. When saving a post that has been set to repeat we save a post meta entry.
155
 *
156
 * @global bool $is_creating_repeat   A flag to identify that a Repeat post is being currently created.
157
 *                                    When we `wp_insert_post` a Repeat post the `save_post` filters are firing again.
158
 *                                    However, we only want to run all our functions hooked into `save_post` once,
159
 *                                    therefor we're skipping them when Repeat post is being created.
160
 *
161
 * @param int    $post_id             The ID of the post.
162
 * @param string $post_repeat_setting Used to manually set the repeating schedule from tests.
163
 */
164
function save_post_repeating_status( $post_id = null, $post_repeat_setting = null ) {
165
	global $is_creating_repeat;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
166
167
	// Stop - Repeat post is being saved, it doesn't need meta data.
168
	// N.B. when inserting a Repeat post via `wp_insert_post` the `save_post` filters are firing again.
169
	if ( $is_creating_repeat ) {
170
		return;
171
	}
172
173
	if ( is_null( $post_repeat_setting ) ) {
174
		$post_repeat_setting = isset( $_POST['hm-post-repeat'] ) ? sanitize_text_field( $_POST['hm-post-repeat'] ) : '';
175
	}
176
177
	if ( ! in_array( get_post_type( $post_id ), repeating_post_types() ) || empty( $post_repeat_setting ) ) {
178
		return;
179
	}
180
181
	if ( 'no' === $post_repeat_setting ) {
182
		delete_post_meta( $post_id, 'hm-post-repeat' );
183
	}
184
	// Make sure we have a valid schedule.
185
	elseif ( in_array( $post_repeat_setting, array_keys( get_repeating_schedules() ) ) ) {
186
		update_post_meta( $post_id, 'hm-post-repeat', $post_repeat_setting );
187
	}
188
}
189
190
191
/**
192
 * Create the next repeat post when the last one is published.
193
 *
194
 * When a Repeat post (or the original) is published we copy and schedule a new post
195
 * to publish on the correct interval. That way the next Repeat post is always ready to go.
196
 * This is hooked into `publish_post`(??) so that the Repeat post is only created when the original
197
 * is published.
198
 *
199
 * @global bool $is_creating_repeat   A flag to identify that a Repeat post is being currently created.
200
 *                                    When we `wp_insert_post` a Repeat post the `save_post` filters are firing again.
201
 *                                    However, we only want to run all our functions hooked into `save_post` once,
202
 *                                    therefor we're skipping them when Repeat post is being created.
203
 *
204
 * @param int $post_id The ID of the post.
205
 *
206
 * @return int|\WP_Error A Repeat post ID on success, WP_Error if Repeat post could not be created.
207
 *                       Terminate function execution if conditions are not met.
208
 */
209
function create_next_repeat_post( $post_id ) {
210
	global $is_creating_repeat;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
211
212
	// Stop - Repeat post is being saved, we need to run this code just once.
213
	// N.B. when inserting a Repeat post via `wp_insert_post` the `save_post` filters are firing again.
214
	if ( $is_creating_repeat ) {
215
		return;
216
	}
217
218
	if ( ! in_array( get_post_type( $post_id ), repeating_post_types() ) ) {
219
		return false;
220
	}
221
222
	if ( 'publish' !== get_post_status( $post_id ) ) {
223
		return false;
224
	}
225
226
	$original_post_id = get_repeating_post( $post_id );
227
228
	// Bail if we're not publishing a repeat(ing) post.
229
	if ( ! $original_post_id ) {
230
		return false;
231
	}
232
233
	$original_post = get_post( $original_post_id, ARRAY_A );
234
235
	// If there is already a repeat post scheduled don't create another one.
236
	if ( get_next_scheduled_repeat_post( $original_post['ID'] ) ) {
237
		return false;
238
	}
239
240
	// Bail if the saved schedule doesn't exist.
241
	$repeating_schedule = get_repeating_schedule( $original_post['ID'] );
242
243
	if ( ! $repeating_schedule ) {
244
		return false;
245
	}
246
247
	// Bail if the original post isn't already published.
248
	if ( 'publish' !== $original_post['post_status'] ) {
249
		return false;
250
	}
251
252
	$next_post = $original_post;
253
254
	// Create the repeat post as a copy of the original, but ignore some fields.
255
	unset( $next_post['ID'] );
256
	unset( $next_post['guid'] );
257
	unset( $next_post['post_date_gmt'] );
258
	unset( $next_post['post_modified'] );
259
	unset( $next_post['post_modified_gmt'] );
260
261
	// We set the post_parent to the original post_id, so they're related.
262
	$next_post['post_parent'] = $original_post['ID'];
263
264
	// Set the next post to publish in the future.
265
	$next_post['post_status'] = 'future';
266
267
	// Use the date of the current post being saved as the base.
268
	$next_post['post_date'] = date( 'Y-m-d H:i:s', strtotime( get_post_field( 'post_date', $post_id ) . ' + ' . $repeating_schedule['interval'] ) );
269
270
	// Make sure the next post will be in the future from the current time.
271
	if ( strtotime( $next_post['post_date'] ) <= time() ) {
272
		return false;
273
	}
274
275
	/**
276
	 * Use this filter to modify the scheduled post before it gets stored.
277
	 *
278
	 * @param array $next_post          The post data about to be saved.
279
	 * @param array $repeating_schedule Repeating schedule info.
280
	 * @param array $original_post      The original repeating post.
281
	 */
282
	$next_post = apply_filters( 'hm_post_repeat_edit_repeat_post', $next_post, $repeating_schedule, $original_post );
283
284
	// All checks done, get that post scheduled!
285
	$is_creating_repeat = true;
286
	$next_post_id       = wp_insert_post( wp_slash( $next_post ), true );
287
	$is_creating_repeat = false;
288
289
	if ( is_wp_error( $next_post_id ) ) {
290
		return false;
291
	}
292
293
	// Mirror any post meta.
294
	$post_meta = get_post_meta( $original_post['ID'] );
295
296
	if ( $post_meta ) {
297
298
		// Ignore some internal meta fields.
299
		unset( $post_meta['_edit_lock'] );
300
		unset( $post_meta['_edit_last'] );
301
302
		// Don't copy the post repeat meta as only the original post should have that.
303
		unset( $post_meta['hm-post-repeat'] );
304
305
		foreach ( $post_meta as $key => $values ) {
306
			foreach ( $values as $value ) {
307
				add_post_meta( $next_post_id, $key, maybe_unserialize( $value ) );
308
			}
309
		}
310
	}
311
312
	// Mirror any term relationships.
313
	$taxonomies = get_object_taxonomies( $original_post['post_type'] );
314
315
	foreach ( $taxonomies as $taxonomy ) {
316
		wp_set_object_terms( $next_post_id, wp_list_pluck( wp_get_object_terms( $original_post['ID'], $taxonomy ), 'slug' ), $taxonomy );
317
	}
318
319
	return $next_post_id;
320
}
321
322
/**
323
 * The post types the feature is enabled on
324
 *
325
 * By default only posts have the feature enabled but others can be added with the `hm_post_repeat_post_types` filter.
326
 *
327
 * @return array An array of post types
328
 */
329
function repeating_post_types() {
330
331
	/**
332
	 * Enable support for additional post types.
333
	 *
334
	 * @param string[] $post_types Post type slugs.
335
	 */
336
	return apply_filters( 'hm_post_repeat_post_types', array( 'post' ) );
337
338
}
339
340
/**
341
 * All available repeat schedules.
342
 *
343
 * @return array An array of all available repeat schedules
344
 */
345
function get_repeating_schedules() {
346
347
	/**
348
	 * Enable support for additional schedules.
349
	 *
350
	 * @param array[] $schedules Schedule array items.
351
	 */
352
	$schedules = apply_filters( 'hm_post_repeat_schedules', array(
353
		'daily'   => array( 'interval' => '1 day',   'display' => __( 'Daily',   'hm-post-repeat' ) ),
354
		'weekly'  => array( 'interval' => '1 week',  'display' => __( 'Weekly',  'hm-post-repeat' ) ),
355
		'monthly' => array( 'interval' => '1 month', 'display' => __( 'Monthly', 'hm-post-repeat' ) ),
356
	) );
357
358
	foreach ( $schedules as $slug => &$schedule ) {
359
		$schedule['slug'] = $slug;
360
	}
361
362
	return $schedules;
363
364
}
365
366
/**
367
 * Get the repeating schedule of the given post_id.
368
 *
369
 * @param int $post_id The id of the post you want to check.
370
 * @return array|null The schedule to repeat by, or null if invalid.
371
 */
372
function get_repeating_schedule( $post_id ) {
373
374
	if ( ! is_repeating_post( $post_id ) ) {
375
		return;
376
	}
377
378
	$repeating_schedule = get_post_meta( $post_id, 'hm-post-repeat', true );
379
	$schedules = get_repeating_schedules();
380
381
	// Backwards compatibility with 0.3 when we only supported weekly
382
	if ( '1' === $repeating_schedule ) {
383
		$repeating_schedule = 'weekly';
384
	}
385
386
	if ( array_key_exists( $repeating_schedule, $schedules ) ) {
387
		return $schedules[ $repeating_schedule ];
388
	}
389
390
}
391
392
/**
393
 * Check whether a given post_id is a repeating post.
394
 *
395
 * A repeating post is defined as the original post that was set to repeat.
396
 *
397
 * @param int $post_id The id of the post you want to check.
398
 * @return bool Whether the passed post_id is a repeating post or not.
399
 */
400
function is_repeating_post( $post_id ) {
401
402
	// We check $_POST data so that this function works inside a `save_post` hook when the post_meta hasn't yet been saved
403
	if ( isset( $_POST['hm-post-repeat'] ) && isset( $_POST['ID'] ) && $_POST['ID'] === $post_id ) {
404
		return true;
405
	}
406
407
	if ( get_post_meta( $post_id, 'hm-post-repeat', true ) ) {
408
		return true;
409
	}
410
411
	return false;
412
413
}
414
415
/**
416
 * Check whether a given post_id is a repeat post.
417
 *
418
 * A repeat post is defined as any post which is a repeat of the original repeating post.
419
 *
420
 * @param int $post_id The id of the post you want to check.
421
 * @return bool Whether the passed post_id is a repeat post or not.
422
 */
423
function is_repeat_post( $post_id ) {
424
425
	$post_parent = get_post_field( 'post_parent', $post_id );
426
427
	if ( $post_parent && get_post_meta( $post_parent, 'hm-post-repeat', true ) ) {
428
		return true;
429
	}
430
431
	return false;
432
433
}
434
435
/**
436
 * Get the next scheduled repeat post
437
 *
438
 * @param int $post_id The id of a repeat or repeating post
439
 * @return Int|Bool Return the ID of the next repeat post_id or false if it can't find one
440
 */
441
function get_next_scheduled_repeat_post( $post_id ) {
442
443
	$post = get_post( get_repeating_post( $post_id ) );
444
445
	$repeat_posts = get_posts( array( 'post_status' => 'future', 'post_parent' => $post->ID ) );
446
447
	if ( isset( $repeat_posts[0] ) ) {
448
	 	return $repeat_posts[0];
449
	}
450
451
	return false;
452
453
}
454
455
/**
456
 * Get the next scheduled repeat post
457
 *
458
 * @param int $post_id The id of a repeat or repeating post
459
 * @return Int|Bool Return the original repeating post_id or false if it can't find it
460
 */
461
function get_repeating_post( $post_id ) {
462
463
	$original_post_id = false;
464
465
	// Are we publishing a repeat post
466
	if ( is_repeat_post( $post_id ) ) {
467
		$original_post_id = get_post( $post_id )->post_parent;
468
	}
469
470
	// Or the original
471
	elseif ( is_repeating_post( $post_id ) ) {
472
		$original_post_id = $post_id;
473
	}
474
475
	return $original_post_id;
476
477
}
478
479
/**
480
 * Adds admin table view link per available repeat type.
481
 * So that only all posts of specific repeat type are displayed.
482
 *
483
 * Added at the end of link list for All | Mine | Published | Scheduled | Drafts
484
 *
485
 * @param array $views An array of available list table views.
486
 *
487
 * @return array Available list of table views with custom added views per repeat type.
488
 */
489
function admin_table_views_links( $views ) {
490
491
	// Add status link for each repeat type.
492
	foreach ( get_available_repeat_types() as $repeat_type => $repeat_desc ) {
493
494
		$url_args = array(
495
			'post_type'      => get_current_screen()->post_type,
496
			'hm-post-repeat' => $repeat_type,
497
		);
498
499
		// Custom WP_Query to get posts count of repeat type.
500
		$repeat_type_query = new \WP_Query( get_repeat_type_query_params( $repeat_type ) );
501
502
		$link_label = sprintf(
503
				'%s <span class="count">(%s)</span>',
504
			esc_html( $repeat_desc ),
505
			esc_html( number_format_i18n( $repeat_type_query->post_count ) )
506
		);
507
508
		// Add current class to the link to highlight it when it's selected.
509
		$class_html = ( get_repeat_type_url_param() === $repeat_type ) ? ' class="current"' : '';
510
511
		$link_html = sprintf(
512
			'<a href="%s"%s>%s</a>',
513
			esc_url( add_query_arg( $url_args, 'edit.php' ) ),
514
			$class_html, // html - hardcoded, no need to escape.
515
			$link_label  // html - escaped earlier in the code.
516
		);
517
518
		$views[ $repeat_type ] = $link_html;
519
	}
520
521
	return $views;
522
}
523
524
/**
525
 * Customizes main admin query to get posts of specified repeat type
526
 * to be displayed in the admin table.
527
 *
528
 * @param \WP_Query $wp_query Main admin query.
529
 *
530
 * @return mixed Main admin query with edited params to get posts of specified repeat type.
531
 */
532
function admin_table_repeat_type_posts_query( $wp_query ) {
533
534
	// Stop - if not admin or not main query (there are secondary WP_Query for counting posts for view links, etc).
535
	if ( ! is_admin() || ! $wp_query->is_main_query() ) {
536
		return $wp_query;
537
	}
538
539
	// Get URL query param for repeat type and check it's valid.
540
	$repeat_type = get_repeat_type_url_param();
541
542
	if ( ! $repeat_type || ! is_allowed_repeat_type( $repeat_type ) ) {
543
		return $wp_query;
544
	}
545
546
	// Add a table view link per each repeat type.
547
	foreach ( get_repeat_type_query_params( $repeat_type ) as $key => $value ) {
548
		$wp_query->set( $key, $value );
549
	}
550
551
	return $wp_query;
552
}
553
554
/**
555
 * Returns array of custom WP_Query params to get posts of specified repeat type.
556
 * Works for all CPT that support Repeatable Posts.
557
 *
558
 * @param string $repeat_type Repeat type of posts to get.
559
 *
560
 * @return array Array of custom WP_Query params.
561
 */
562
function get_repeat_type_query_params( $repeat_type ) {
563
564
	$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...
565
566
	// Construct custom query to get posts of specified repeat type.
567
	$query['meta_query'] = array(
568
			array(
569
					'key'     => 'hm-post-repeat',
570
					'compare' => 'EXISTS',
571
			),
572
	);
573
574
	if ( $repeat_type === 'repeat' ) {
575
		$query['post_parent__not_in'] = array( 0 );
576
577
	} elseif ( $repeat_type === 'repeating' ) {
578
		$query['post_parent__in'] = array( 0 );
579
	}
580
581
	return $query;
582
}
583
584
/**
585
 * Get URL query param for the repeat type of posts being displayed
586
 * in the admin post table.
587
 *
588
 * @return string Sanitized string of repeat type being displayed.
589
 */
590
function get_repeat_type_url_param() {
591
	return isset( $_GET['hm-post-repeat'] ) ? sanitize_text_field( $_GET['hm-post-repeat'] ) : '';
592
}
593
594
/**
595
 * Return available repeat types, i.e. repeating or repeat.
596
 *
597
 * @return array Available repeat types.
598
 */
599
function get_available_repeat_types() {
600
	return array(
601
		'repeating' => __( 'Repeating', 'hm-post-repeat' ),
602
		'repeat'    => __( 'Repeat', 'hm-post-repeat' ),
603
	);
604
}
605
606
/**
607
 * Check if a repeat type is valid.
608
 *
609
 * @param string $repeat_type Repeat type to check.
610
 *
611
 * @return bool True if repeat type is valid,
612
 *              False otherwise.
613
 */
614
function is_allowed_repeat_type( $repeat_type ) {
615
	return in_array( $repeat_type, array_keys( get_available_repeat_types() ) );
616
}
617