Completed
Pull Request — dev/6.0.0 (#319)
by Rajan
16:17 queued 11:55
created

BaseModule::get_enhanced_select_threshold()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 9
ccs 0
cts 0
cp 0
crap 2
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
namespace BulkWP\BulkDelete\Core\Base;
4
5
use BulkWP\BulkDelete\Core\Base\Mixin\Renderer;
6
7 1
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
8
9
/**
10
 * Encapsulates the Bulk Delete Meta box Module Logic.
11
 *
12
 * All Bulk Delete Meta box Modules should extend this class.
13
 * This class extends Renderer Mixin class since Bulk Delete still supports PHP 5.3.
14
 * Once PHP 5.3 support is dropped, Renderer will be implemented as a Trait and this class will `use` it.
15
 *
16
 * @since 6.0.0
17
 */
18
abstract class BaseModule extends Renderer {
19
	/**
20
	 * Item Type. Possible values 'posts', 'pages', 'users' etc.
21
	 *
22
	 * @var string
23
	 */
24
	protected $item_type;
25
26
	/**
27
	 * The hook suffix of the screen where this meta box would be shown.
28
	 *
29
	 * @var string
30
	 */
31
	protected $page_hook_suffix;
32
33
	/**
34
	 * Slug of the page where this module will be shown.
35
	 *
36
	 * @var string
37
	 */
38
	protected $page_slug;
39
40
	/**
41
	 * Slug for the form fields.
42
	 *
43
	 * @var string
44
	 */
45
	protected $field_slug;
46
47
	/**
48
	 * Slug of the meta box.
49
	 *
50
	 * @var string
51
	 */
52
	protected $meta_box_slug;
53
54
	/**
55
	 * Action in which the delete operation should be performed.
56
	 *
57
	 * @var string
58
	 */
59
	protected $action;
60
61
	/**
62
	 * Hook for scheduler.
63
	 *
64
	 * @var string
65
	 */
66
	protected $cron_hook;
67
68
	/**
69
	 * Url of the scheduler addon.
70
	 *
71
	 * @var string
72
	 */
73
	protected $scheduler_url;
74
75
	/**
76
	 * Messages shown to the user.
77
	 *
78
	 * @var array
79
	 */
80
	protected $messages = array(
81
		'box_label'  => '',
82
		'cron_label' => '',
83
	);
84
85
	/**
86
	 * Initialize and setup variables.
87
	 *
88
	 * @return void
89
	 */
90
	abstract protected function initialize();
91
92
	/**
93
	 * Render the Modules.
94
	 *
95
	 * @return void
96
	 */
97
	abstract public function render();
98
99
	/**
100
	 * Process user input and create metabox options.
101
	 *
102
	 * @param array $request Request array.
103
	 * @param array $options User options.
104
	 *
105
	 * @return array User options.
106
	 */
107
	abstract protected function convert_user_input_to_options( $request, $options );
108
109
	/**
110
	 * Perform the deletion.
111
	 *
112
	 * @param array $options Array of Delete options.
113
	 *
114
	 * @return int Number of items that were deleted.
115
	 */
116
	abstract public function delete( $options );
117
118
	/**
119
	 * Get Success Message.
120
	 *
121
	 * @param int $items_deleted Number of items that were deleted.
122
	 *
123
	 * @return string Success message.
124
	 */
125
	abstract protected function get_success_message( $items_deleted );
126
127
	/**
128
	 * Create new instances of Modules.
129
	 */
130 123
	public function __construct() {
131 123
		$this->initialize();
132 123
	}
133
134
	/**
135
	 * Register.
136
	 *
137
	 * @param string $hook_suffix Page Hook Suffix.
138
	 * @param string $page_slug   Page slug.
139
	 */
140
	public function register( $hook_suffix, $page_slug ) {
141
		$this->page_hook_suffix = $hook_suffix;
142
		$this->page_slug        = $page_slug;
143
144
		add_action( "add_meta_boxes_{$this->page_hook_suffix}", array( $this, 'setup_metabox' ) );
145
146
		add_action( 'bd_' . $this->action, array( $this, 'process' ) );
147
		add_filter( 'bd_javascript_array', array( $this, 'filter_js_array' ) );
148
	}
149
150
	/**
151
	 * Setup the meta box.
152
	 */
153
	public function setup_metabox() {
154
		add_meta_box(
155
			$this->meta_box_slug,
156
			$this->messages['box_label'],
157
			array( $this, 'render_box' ),
158
			$this->page_hook_suffix,
159
			'advanced'
160
		);
161
	}
162
163
	/**
164
	 * Render the meta box.
165
	 */
166 1
	public function render_box() {
167 1
		if ( $this->is_hidden() ) {
168
			printf(
169
				/* translators: 1 module url */
170
				__( 'This section just got enabled. Kindly <a href = "%1$s">refresh</a> the page to fully enable it.', 'bulk-delete' ),
171
				'admin.php?page=' . $this->page_slug
172
			);
173
174
			return;
175
		}
176
177 1
		$this->render();
178 1
	}
179
180
	/**
181
	 * Is the current meta box hidden by user.
182
	 *
183
	 * @return bool True, if hidden. False, otherwise.
184
	 */
185 1
	protected function is_hidden() {
186 1
		$current_user    = wp_get_current_user();
187 1
		$user_meta_field = $this->get_hidden_box_user_meta_field();
188 1
		$hidden_boxes    = get_user_meta( $current_user->ID, $user_meta_field, true );
189
190 1
		return is_array( $hidden_boxes ) && in_array( $this->meta_box_slug, $hidden_boxes, true );
191
	}
192
193
	/**
194
	 * Get the user meta field that stores the status of the hidden meta boxes.
195
	 *
196
	 * @return string Name of the User Meta field.
197
	 */
198 1
	protected function get_hidden_box_user_meta_field() {
199 1
		if ( 'posts' === $this->item_type ) {
200
			return 'metaboxhidden_toplevel_page_bulk-delete-posts';
201
		} else {
202 1
			return 'metaboxhidden_bulk-wp_page_' . $this->page_slug;
203
		}
204
	}
205
206
	/**
207
	 * Filter the js array.
208
	 *
209
	 * This function will be overridden by the child classes.
210
	 *
211
	 * @param array $js_array JavaScript Array.
212
	 *
213
	 * @return array Modified JavaScript Array
214
	 */
215
	public function filter_js_array( $js_array ) {
216
		return $js_array;
217
	}
218
219
	/**
220
	 * Render filtering table header.
221
	 */
222
	protected function render_filtering_table_header() {
223
		bd_render_filtering_table_header();
224
	}
225
226
	/**
227
	 * Render restrict settings.
228
	 */
229
	protected function render_restrict_settings() {
230
		bd_render_restrict_settings( $this->field_slug, $this->item_type );
231
	}
232
233
	/**
234
	 * Render delete settings.
235
	 */
236
	protected function render_delete_settings() {
237
		bd_render_delete_settings( $this->field_slug );
238
	}
239
240
	/**
241
	 * Render sticky settings.
242
	 */
243
	protected function render_sticky_settings() {
244
		bd_render_sticky_settings( $this->field_slug );
245
	}
246
247
	/**
248
	 * Render limit settings.
249
	 */
250
	protected function render_limit_settings() {
251
		bd_render_limit_settings( $this->field_slug, $this->item_type );
252
	}
253
254
	/**
255
	 * Render cron settings based on whether scheduler is present or not.
256
	 */
257
	protected function render_cron_settings() {
258
		$disabled_attr = 'disabled';
259
		if ( empty( $this->scheduler_url ) ) {
260
			$disabled_attr = '';
261
		}
262
		?>
263
264
		<tr>
265
			<td scope="row" colspan="2">
266
				<input name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_cron" value="false" type="radio" checked="checked"> <?php _e( 'Delete now', 'bulk-delete' ); ?>
267
				<input name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_cron" value="true" type="radio" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_cron" <?php echo esc_attr( $disabled_attr ); ?>> <?php _e( 'Schedule', 'bulk-delete' ); ?>
268
				<input name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_cron_start" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_cron_start" value="now" type="text" <?php echo esc_attr( $disabled_attr ); ?>><?php _e( 'repeat ', 'bulk-delete' ); ?>
269
270
				<select name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_cron_freq" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_cron_freq" <?php echo esc_attr( $disabled_attr ); ?>>
271
					<option value="-1"><?php _e( "Don't repeat", 'bulk-delete' ); ?></option>
272
273
					<?php
274 1
					/**
275 1
					 * List of cron schedules.
276 1
					 *
277 1
					 * @since 6.0.0
278
					 *
279 1
					 * @param array $cron_schedules List of cron schedules.
280
					 * @param \BulkWP\BulkDelete\Core\Base\BaseModule $module Module.
281
					 */
282 1
					$cron_schedules = apply_filters( 'bd_cron_schedules', wp_get_schedules(), $this );
283 1
					?>
284
285
					<?php foreach ( $cron_schedules as $key => $value ) : ?>
286 1
						<option value="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $value['display'] ); ?></option>
287 1
					<?php endforeach; ?>
288 1
				</select>
289 1
290 1
				<?php if ( ! empty( $this->scheduler_url ) ) : ?>
291
					<?php
292 1
					$pro_class = 'bd-' . str_replace( '_', '-', $this->field_slug ) . '-pro';
293
294
					/**
295
					 * HTML class of the span that displays the 'Pro only feature' message.
296
					 *
297
					 * @since 6.0.0
298
					 *
299
					 * @param string $pro_class HTML class.
300
					 * @param string $field_slug Field Slug of module.
301
					 * @param \BulkWP\BulkDelete\Core\Base\BaseModule $module Module.
302
					 */
303
					apply_filters( 'bd_pro_only_feature_class', $pro_class, $this->field_slug, $this )
304
					?>
305
306
					<span class="<?php echo sanitize_html_class( $pro_class ); ?>" style="color:red">
307
						<?php _e( 'Only available in Pro Addon', 'bulk-delete' ); ?> <a href="<?php echo esc_url( $this->scheduler_url ); ?>">Buy now</a>
308
					</span>
309
				<?php endif; ?>
310
			</td>
311
		</tr>
312
313
		<tr>
314
			<td scope="row" colspan="2">
315
				<?php _e( 'Enter time in <strong>Y-m-d H:i:s</strong> format or enter <strong>now</strong> to use current time', 'bulk-delete' ); ?>
316
			</td>
317 44
		</tr>
318 44
		<?php
319
	}
320
321
	/**
322
	 * Render submit button.
323
	 */
324
	protected function render_submit_button() {
325
		bd_render_submit_button( $this->action );
326
	}
327
328 3
	/**
329 3
	 * Helper function for processing deletion.
330
	 * Setups up cron and invokes the actual delete method.
331
	 *
332
	 * @param array $request Request array.
333
	 */
334
	public function process( $request ) {
335
		$options      = $this->parse_common_filters( $request );
336
		$options      = $this->convert_user_input_to_options( $request, $options );
337
		$cron_options = $this->parse_cron_filters( $request );
338
339
		if ( $this->is_scheduled( $cron_options ) ) {
340 32
			$msg = $this->schedule_deletion( $cron_options, $options );
341 32
		} else {
342 8
			$items_deleted = $this->delete( $options );
343
			$msg           = sprintf( $this->get_success_message( $items_deleted ), $items_deleted );
344 24
		}
345
346
		add_settings_error(
347 32
			$this->page_slug,
348
			$this->action,
349
			$msg,
350
			'updated'
351
		);
352
	}
353
354
	/**
355 32
	 * Getter for cron_hook.
356 32
	 *
357 32
	 * @return string Cron Hook name.
358 32
	 */
359
	public function get_cron_hook() {
360
		return $this->cron_hook;
361
	}
362
363
	/**
364
	 * Getter for field slug.
365
	 *
366
	 * @return string Field Slug.
367
	 */
368
	public function get_field_slug() {
369 1
		return $this->field_slug;
370 1
	}
371
372 1
	/**
373 1
	 * Getter for action.
374 1
	 *
375
	 * @return string Modules action.
376 1
	 */
377 1
	public function get_action() {
378
		return $this->action;
379 1
	}
380
381
	/**
382
	 * Is the current deletion request a scheduled request?
383
	 *
384
	 * @param array $cron_options Request object.
385
	 *
386
	 * @return bool True if it is a scheduled request, False otherwise.
387
	 */
388
	protected function is_scheduled( $cron_options ) {
389 31
		return $cron_options['is_scheduled'];
390
	}
391 31
392
	/**
393
	 * Schedule Deletion of items.
394 31
	 *
395
	 * @param array $cron_options Cron options.
396 31
	 * @param array $options      Deletion option.
397 28
	 *
398 28
	 * @return string Message.
399 28
	 */
400
	protected function schedule_deletion( $cron_options, $options ) {
401 28
		if ( '-1' === $cron_options['frequency'] ) {
402
			wp_schedule_single_event( $cron_options['start_time'], $this->cron_hook, array( $options ) );
403
		} else {
404 31
			wp_schedule_event( $cron_options['start_time'], $cron_options['frequency'], $this->cron_hook, array( $options ) );
405
		}
406
407
		return $this->messages['scheduled'] . ' ' . $this->get_task_list_link();
408
	}
409
410
	/**
411
	 * Get the link to the page that lists all the scheduled tasks.
412
	 *
413
	 * @return string Link to scheduled tasks page.
414
	 */
415
	protected function get_task_list_link() {
416
		return sprintf(
417
			__( 'See the full list of <a href = "%s">scheduled tasks</a>', 'bulk-delete' ),
418
			get_bloginfo( 'wpurl' ) . '/wp-admin/admin.php?page=' . \Bulk_Delete::CRON_PAGE_SLUG
419
		);
420
	}
421
422
	/**
423
	 * Handle common filters.
424
	 *
425
	 * @param array $request Request array.
426
	 *
427
	 * @return array User options.
428
	 */
429
	protected function parse_common_filters( $request ) {
430
		$options = array();
431
432
		$options['restrict']     = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_restrict', false );
433
		$options['limit_to']     = absint( bd_array_get( $request, 'smbd_' . $this->field_slug . '_limit_to', 0 ) );
434
		$options['force_delete'] = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_force_delete', false );
435
436
		$options['date_op'] = bd_array_get( $request, 'smbd_' . $this->field_slug . '_op' );
437
		$options['days']    = absint( bd_array_get( $request, 'smbd_' . $this->field_slug . '_days' ) );
438
439
		return $options;
440
	}
441
442
	/**
443
	 * Parse request and create cron options.
444 28
	 *
445 28
	 * @param array $request Request array.
446
	 *
447
	 * @return array Parsed cron option.
448
	 */
449
	protected function parse_cron_filters( $request ) {
450
		$cron_options = array(
451
			'is_scheduled' => false,
452
		);
453
454
		$scheduled = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_cron', false );
455
456
		if ( $scheduled ) {
457
			$cron_options['is_scheduled'] = true;
458
			$cron_options['frequency']    = sanitize_text_field( $request[ 'smbd_' . $this->field_slug . '_cron_freq' ] );
459
			$cron_options['start_time']   = bd_get_gmt_offseted_time( sanitize_text_field( $request[ 'smbd_' . $this->field_slug . '_cron_start' ] ) );
460
461
			$cron_options['cron_label'] = $this->get_cron_label();
462
		}
463
464
		return $cron_options;
465
	}
466
467
	/**
468
	 * Get the threshold after which enhanced select should be used.
469
	 *
470
	 * @return int Threshold.
471
	 */
472
	protected function get_enhanced_select_threshold() {
473
		/**
474
		 * Filter the enhanced select threshold.
475
		 *
476
		 * @since 6.0.0
477
		 *
478
		 * @param int Threshold.
479
		 */
480
		return apply_filters( 'bd_enhanced_select_threshold', 1000 );
481
	}
482
483
	/**
484
	 * Get the class name for select2 dropdown based on the number of items present.
485
	 *
486
	 * @param int    $count      The number of items present.
487
	 * @param string $class_name Primary class name.
488
	 *
489
	 * @return string Class name.
490
	 */
491
	protected function enable_ajax_if_needed_to_dropdown_class_name( $count, $class_name ) {
492
		if ( $count >= $this->get_enhanced_select_threshold() ) {
493
			$class_name .= '-ajax';
494
		}
495
496
		return $class_name;
497
	}
498
499
	/**
500
	 * Get the human readable label for the Schedule job.
501
	 *
502
	 * @return string Human readable label for schedule job.
503
	 */
504
	protected function get_cron_label() {
505
		return $this->messages['cron_label'];
506
	}
507
}
508