Passed
Push — dependabot/npm_and_yarn/websoc... ( 8590a4...96b769 )
by
unknown
69:06
created

BaseModule::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
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 of the meta box.
42
	 *
43
	 * @var string
44
	 */
45
	protected $meta_box_slug;
46
47
	/**
48
	 * Action in which the delete operation should be performed.
49
	 *
50
	 * @var string
51
	 */
52
	protected $action = '';
53
54
	/**
55
	 * Hook for scheduler.
56
	 *
57
	 * @var string
58
	 */
59
	protected $cron_hook;
60
61
	/**
62
	 * List of legacy cron hooks that this module should support.
63
	 *
64
	 * Legacy cron hooks usually come from older version of the add-on(s).
65
	 *
66
	 * @since 6.1.0
67
	 *
68
	 * @var array
69
	 */
70
	protected $legacy_cron_hooks = [];
71
72
	/**
73
	 * Url of the scheduler addon.
74
	 *
75
	 * @var string
76
	 */
77
	protected $scheduler_url;
78
79
	/**
80
	 * Messages shown to the user.
81
	 *
82
	 * @var array
83
	 */
84
	protected $messages = array(
85
		'box_label'         => '',
86
		'cron_label'        => '',
87
		'validation_error'  => '',
88
		'confirm_deletion'  => '',
89
		'confirm_scheduled' => '',
90
		'scheduled'         => '',
91
		'nothing_to_delete' => '',
92
		'deleted_one'       => '',
93
		'deleted_multiple'  => '',
94
	);
95
96
	/**
97
	 * Initialize and setup variables.
98
	 *
99
	 * @return void
100
	 */
101
	abstract protected function initialize();
102
103
	/**
104
	 * Render the Modules.
105
	 *
106
	 * @return void
107
	 */
108
	abstract public function render();
109
110
	/**
111
	 * Process common filters.
112
	 *
113
	 * @param array $request Request array.
114
	 *
115
	 * @return array User options.
116
	 */
117
	abstract protected function parse_common_filters( $request );
118
119
	/**
120
	 * Process user input and create metabox options.
121
	 *
122
	 * @param array $request Request array.
123
	 * @param array $options User options.
124
	 *
125
	 * @return array User options.
126
	 */
127
	abstract protected function convert_user_input_to_options( $request, $options );
128
129
	/**
130 413
	 * Perform the deletion.
131 413
	 *
132
	 * @param array $options Array of Delete options.
133
	 *
134
	 * @return int Number of items that were deleted.
135
	 */
136
	abstract protected function do_delete( $options );
137
138
	/**
139
	 * Create new instances of Modules.
140 24
	 */
141 24
	public function __construct() {
142 24
		$this->initialize();
143
	}
144 24
145
	/**
146 24
	 * Register.
147
	 *
148 24
	 * @param string $hook_suffix Page Hook Suffix.
149 24
	 * @param string $page_slug   Page slug.
150
	 */
151
	public function register( $hook_suffix, $page_slug ) {
152
		$this->page_hook_suffix = $hook_suffix;
153
		$this->page_slug        = $page_slug;
154
155
		add_action( "add_meta_boxes_{$this->page_hook_suffix}", array( $this, 'setup_metabox' ) );
156
157
		add_filter( 'bd_javascript_array', array( $this, 'filter_js_array' ) );
158
159
		if ( ! empty( $this->action ) ) {
160
			add_action( 'bd_' . $this->action, array( $this, 'process' ) );
161
		}
162
	}
163
164
	/**
165
	 * Setup the meta box.
166
	 */
167
	public function setup_metabox() {
168
		if ( array_key_exists( 'box_label', $this->messages ) ) {
169
			add_meta_box(
170
				$this->meta_box_slug,
171 1
				$this->messages['box_label'],
172 1
				array( $this, 'render_box' ),
173
				$this->page_hook_suffix,
174
				'advanced'
175
			);
176
		}
177
	}
178
179
	/**
180
	 * Render the meta box.
181
	 */
182 1
	public function render_box() {
183
		if ( $this->is_hidden() ) {
184
			printf(
185
				/* translators: 1 Module url */
186
				__( 'This section just got enabled. Kindly <a href = "%1$s">refresh</a> the page to fully enable it.', 'bulk-delete' ),
187
				'admin.php?page=' . esc_attr( $this->page_slug )
188
			);
189
190 1
			return;
191 1
		}
192 1
193 1
		$this->render();
194
	}
195 1
196
	/**
197
	 * Is the current meta box hidden by user.
198
	 *
199
	 * @return bool True, if hidden. False, otherwise.
200
	 */
201
	protected function is_hidden() {
202
		$current_user    = wp_get_current_user();
203 1
		$user_meta_field = $this->get_hidden_box_user_meta_field();
204 1
		$hidden_boxes    = get_user_meta( $current_user->ID, $user_meta_field, true );
205
206
		return is_array( $hidden_boxes ) && in_array( $this->meta_box_slug, $hidden_boxes, true );
207 1
	}
208
209
	/**
210
	 * Get the user meta field that stores the status of the hidden meta boxes.
211
	 *
212
	 * @return string Name of the User Meta field.
213
	 */
214
	protected function get_hidden_box_user_meta_field() {
215
		if ( 'posts' === $this->item_type ) {
216
			return 'metaboxhidden_toplevel_page_bulk-delete-posts';
217
		} else {
218
			return 'metaboxhidden_bulk-wp_page_' . $this->page_slug;
219
		}
220
	}
221
222
	/**
223
	 * Filter the js array.
224
	 *
225
	 * Use `append_to_js_array` function to append any module specific js options.
226
	 *
227
	 * @see $this->append_to_js_array
228
	 *
229
	 * @param array $js_array JavaScript Array.
230
	 *
231
	 * @return array Modified JavaScript Array
232
	 */
233
	public function filter_js_array( $js_array ) {
234
		$js_array['dt_iterators'][] = '_' . $this->field_slug;
235
236
		$js_array['pre_delete_msg'][ $this->action ] = $this->action . '_confirm_deletion';
237
		$js_array['error_msg'][ $this->action ]      = $this->action . '_error';
238
239
		$js_array['msg'][ $this->action . '_confirm_deletion' ] = __( 'Are you sure you want to delete all the posts based on the selected option?', 'bulk-delete' );
240
		$js_array['msg'][ $this->action . '_error' ]            = __( 'Please select posts from at least one option', 'bulk-delete' );
241
242
		if ( ! empty( $this->messages['confirm_deletion'] ) ) {
243
			$js_array['msg'][ $this->action . '_confirm_deletion' ] = $this->messages['confirm_deletion'];
244
		}
245
246
		if ( ! empty( $this->messages['confirm_scheduled'] ) ) {
247
			$js_array['pre_schedule_msg'][ $this->action ] = $this->action . '_confirm_scheduled';
248
249
			$js_array['msg'][ $this->action . '_confirm_scheduled' ] = $this->messages['confirm_scheduled'];
250
		}
251
252
		if ( ! empty( $this->messages['validation_error'] ) ) {
253
			$js_array['msg'][ $this->action . '_error' ] = $this->messages['validation_error'];
254
		}
255
256
		return $this->append_to_js_array( $js_array );
257
	}
258
259
	/**
260
	 * Append any module specific options to JS array.
261
	 *
262
	 * This function will be overridden by the child classes.
263
	 *
264
	 * @param array $js_array JavaScript Array.
265
	 *
266
	 * @return array Modified JavaScript Array
267 1
	 */
268 1
	protected function append_to_js_array( $js_array ) {
269 1
		return $js_array;
270 1
	}
271
272
	/**
273
	 * Helper function for processing deletion.
274
	 * Setups up cron and invokes the actual delete method.
275
	 *
276
	 * @param array $request Request array.
277
	 */
278
	public function process( $request ) {
279
		$options      = $this->parse_common_filters( $request );
280
		$options      = $this->convert_user_input_to_options( $request, $options );
281 1
		$cron_options = $this->parse_cron_filters( $request );
282
283 1
		/**
284
		 * Filter the processed delete options.
285
		 *
286 1
		 * @since 6.0.0
287 1
		 *
288
		 * @param array $options Processed options.
289
		 * @param array $request Request array.
290 1
		 * @param \BulkWP\BulkDelete\Core\Base\BaseModule The delete module.
291 1
		 */
292 1
		$options = apply_filters( 'bd_processed_delete_options', $options, $request, $this );
293
294 1
		if ( $this->is_scheduled( $cron_options ) ) {
295
			$msg = $this->schedule_deletion( $cron_options, $options );
296
		} else {
297
			$items_deleted = $this->delete( $options );
298
			$msg           = sprintf( $this->get_success_message( $items_deleted ), $items_deleted );
299
		}
300
301
		add_settings_error(
302
			$this->page_slug,
303
			$this->action,
304
			$msg,
305 330
			'updated'
306
		);
307
	}
308
309
	/**
310
	 * Delete items based on delete options.
311
	 *
312
	 * @param array $options Delete Options.
313
	 *
314 330
	 * @return int Number of items deleted.
315
	 */
316 330
	public function delete( $options ) {
317
		/**
318
		 * Filter delete options before deleting items.
319
		 *
320
		 * @since 6.0.0 Added `Modules` parameter.
321
		 *
322
		 * @param array $options Delete options.
323
		 * @param \BulkWP\BulkDelete\Core\Base\BaseModule Modules that is triggering deletion.
324
		 */
325
		$options = apply_filters( 'bd_delete_options', $options, $this );
326 1
327 1
		return $this->do_delete( $options );
328
	}
329
330
	/**
331
	 * Get Success Message.
332
	 *
333 1
	 * @param int $items_deleted Number of items that were deleted.
334
	 *
335
	 * @return string Success message.
336
	 */
337
	protected function get_success_message( $items_deleted ) {
338
		if ( 0 === $items_deleted ) {
339
			if ( ! empty( $this->messages['nothing_to_delete'] ) ) {
340
				return $this->messages['nothing_to_delete'];
341
			}
342
		}
343
344
		return _n( $this->messages['deleted_one'], $this->messages['deleted_multiple'], $items_deleted, 'bulk-delete' ); // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralSingle, WordPress.WP.I18n.NonSingularStringLiteralPlural
345
	}
346
347
	/**
348
	 * Getter for cron_hook.
349
	 *
350
	 * @return string Cron Hook name.
351
	 */
352
	public function get_cron_hook() {
353
		return $this->cron_hook;
354
	}
355
356
	/**
357
	 * Getter for legacy cron_hooks.
358
	 *
359 340
	 * @since 6.1.0
360 340
	 *
361
	 * @return array Legacy cron Hooks.
362
	 */
363
	public function get_legacy_cron_hooks() {
364
		return $this->legacy_cron_hooks;
365
	}
366
367
	/**
368
	 * Getter for field slug.
369
	 *
370 3
	 * @return string Field Slug.
371 3
	 */
372
	public function get_field_slug() {
373
		return $this->field_slug;
374
	}
375
376
	/**
377
	 * Getter for action.
378
	 *
379
	 * @return string Modules action.
380
	 */
381
	public function get_action() {
382 32
		return $this->action;
383 32
	}
384
385 32
	/**
386 8
	 * Is the current deletion request a scheduled request?
387
	 *
388 24
	 * @param array $cron_options Request object.
389
	 *
390
	 * @return bool True if it is a scheduled request, False otherwise.
391 32
	 */
392
	protected function is_scheduled( $cron_options ) {
393
		return $cron_options['is_scheduled'];
394
	}
395
396
	/**
397
	 * Schedule Deletion of items.
398
	 *
399 32
	 * @param array $cron_options Cron options.
400 32
	 * @param array $options      Deletion option.
401
	 *
402 32
	 * @return string Message.
403 32
	 */
404
	protected function schedule_deletion( $cron_options, $options ) {
405
		$options['cron_label'] = $cron_options['cron_label'];
406
407
		if ( '-1' === $cron_options['frequency'] ) {
408
			wp_schedule_single_event( $cron_options['start_time'], $this->cron_hook, array( $options ) );
409
		} else {
410
			wp_schedule_event( $cron_options['start_time'], $cron_options['frequency'], $this->cron_hook, array( $options ) );
411
		}
412
413
		return $this->messages['scheduled'] . ' ' . $this->get_task_list_link();
414 31
	}
415
416 31
	/**
417
	 * Get the link to the page that lists all the scheduled tasks.
418
	 *
419 31
	 * @return string Link to scheduled tasks page.
420
	 */
421 31
	protected function get_task_list_link() {
422 28
		return sprintf(
423 28
			/* translators: 1 Cron page url */
424 28
			__( 'See the full list of <a href = "%s">scheduled tasks</a>', 'bulk-delete' ),
425
			get_bloginfo( 'wpurl' ) . '/wp-admin/admin.php?page=' . \Bulk_Delete::CRON_PAGE_SLUG
426 28
		);
427
	}
428
429 31
	/**
430
	 * Parse request and create cron options.
431
	 *
432
	 * @param array $request Request array.
433
	 *
434
	 * @return array Parsed cron option.
435
	 */
436
	protected function parse_cron_filters( $request ) {
437 28
		$cron_options = array(
438 28
			'is_scheduled' => false,
439
		);
440
441
		$scheduled = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_cron', false );
442
443
		if ( $scheduled ) {
444
			$cron_options['is_scheduled'] = true;
445
			$cron_options['frequency']    = sanitize_text_field( $request[ 'smbd_' . $this->field_slug . '_cron_freq' ] );
446
			$cron_options['start_time']   = bd_get_gmt_offseted_time( sanitize_text_field( $request[ 'smbd_' . $this->field_slug . '_cron_start' ] ) );
447
448
			$cron_options['cron_label'] = $this->get_cron_label();
449
		}
450
451
		return $cron_options;
452
	}
453
454
	/**
455
	 * Get the human readable label for the Schedule job.
456
	 *
457
	 * @return string Human readable label for schedule job.
458
	 */
459
	public function get_cron_label() {
460
		return $this->messages['cron_label'];
461
	}
462
463
	/**
464
	 * Get the name of the module.
465
	 *
466
	 * This is used as the key to identify the module from page.
467
	 *
468
	 * @return string Module name.
469
	 */
470
	public function get_name() {
471
		return bd_get_short_class_name( $this );
472
	}
473
474
	/**
475
	 * Get the page slug of the module.
476
	 *
477
	 * @since 6.0.1
478
	 *
479
	 * @return string Page slug.
480
	 */
481
	public function get_page_slug() {
482
		return $this->page_slug;
483
	}
484
}
485