Passed
Push — dev/6.0.0 ( 7e3069...f825f1 )
by Sudar
02:53
created

BulkDelete   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 639
Duplicated Lines 0 %

Test Coverage

Coverage 30.6%

Importance

Changes 0
Metric Value
eloc 130
dl 0
loc 639
ccs 41
cts 134
cp 0.306
rs 8.96
c 0
b 0
f 0
wmc 43

28 Methods

Rating   Name   Duplication   Size   Complexity  
A __clone() 0 2 1
A setup_actions() 0 4 1
A __construct() 0 1 1
A load_dependencies() 0 6 1
A __wakeup() 0 2 1
A get_instance() 0 6 3
A load() 0 18 2
A get_module() 0 8 2
A load_primary_pages() 0 21 1
A get_delete_posts_admin_page() 0 32 1
A set_loader() 0 2 1
A set_plugin_file() 0 3 1
A get_delete_metas_admin_page() 0 26 1
A get_delete_terms_admin_page() 0 25 1
A get_system_info_page() 0 4 1
A get_primary_pages() 0 6 2
A load_textdomain() 0 2 1
A on_admin_menu() 0 46 3
A get_secondary_pages() 0 17 2
A register_addon_namespace() 0 2 1
A get_page() 0 8 2
A get_delete_users_admin_page() 0 25 1
A get_cron_list_admin_page() 0 4 1
A get_translations_path() 0 2 1
A get_plugin_file() 0 2 1
A get_delete_pages_admin_page() 0 24 1
A get_page_hook_suffix() 0 16 4
A on_init() 0 5 4

How to fix   Complexity   

Complex Class

Complex classes like BulkDelete often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BulkDelete, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace BulkWP\BulkDelete\Core;
4
5
use BulkWP\BulkDelete\Core\Addon\Upseller;
6
use BulkWP\BulkDelete\Core\Base\BasePage;
7
use BulkWP\BulkDelete\Core\Cron\CronListPage;
8
use BulkWP\BulkDelete\Core\Metas\DeleteMetasPage;
9
use BulkWP\BulkDelete\Core\Metas\Modules\DeleteCommentMetaModule;
10
use BulkWP\BulkDelete\Core\Metas\Modules\DeletePostMetaModule;
11
use BulkWP\BulkDelete\Core\Metas\Modules\DeleteUserMetaModule;
12
use BulkWP\BulkDelete\Core\Pages\DeletePagesPage;
13
use BulkWP\BulkDelete\Core\Pages\Modules\DeletePagesByStatusModule;
14
use BulkWP\BulkDelete\Core\Posts\DeletePostsPage;
15
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByCategoryModule;
16
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByCommentsModule;
17
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByPostTypeModule;
18
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByRevisionModule;
19
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByStatusModule;
20
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByStickyPostModule;
21
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByTagModule;
22
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByTaxonomyModule;
23
use BulkWP\BulkDelete\Core\Posts\Modules\DeletePostsByURLModule;
24
use BulkWP\BulkDelete\Core\SystemInfo\SystemInfoPage;
25
use BulkWP\BulkDelete\Core\Terms\DeleteTermsPage;
26
use BulkWP\BulkDelete\Core\Terms\Modules\DeleteTermsByNameModule;
27
use BulkWP\BulkDelete\Core\Terms\Modules\DeleteTermsByPostCountModule;
28
use BulkWP\BulkDelete\Core\Users\DeleteUsersPage;
29
use BulkWP\BulkDelete\Core\Users\Modules\DeleteUsersByUserMetaModule;
30 1
use BulkWP\BulkDelete\Core\Users\Modules\DeleteUsersByUserRoleModule;
31
32
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
33
34
/**
35
 * Main Plugin class.
36
 *
37
 * @since 5.0 Converted to Singleton
38
 * @since 6.0.0 Renamed to BulkDelete and added namespace.
39
 */
40
final class BulkDelete {
41
	/**
42
	 * The one true BulkDelete instance.
43
	 *
44
	 * @var BulkDelete
45
	 *
46
	 * @since 5.0
47
	 */
48
	private static $instance;
49
50
	/**
51
	 * Path to the main plugin file.
52
	 *
53
	 * @var string
54
	 */
55
	private $plugin_file;
56
57
	/**
58
	 * Path where translations are stored.
59
	 *
60
	 * @var string
61
	 */
62
	private $translations_path;
63
64
	/**
65
	 * Has the plugin loaded?
66
	 *
67
	 * @since 6.0.0
68
	 *
69
	 * @var bool
70
	 */
71
	private $loaded = false;
72
73
	/**
74
	 * Controller that handles all requests and nonce checks.
75
	 *
76
	 * @var \BulkWP\BulkDelete\Core\Controller
77
	 */
78
	private $controller;
79
80
	/**
81
	 * Upseller responsible for upselling add-ons.
82
	 *
83
	 * @since 6.0.0
84
	 *
85
	 * @var \BulkWP\BulkDelete\Core\Addon\Upseller
86
	 */
87
	private $upseller;
88
89
	/**
90
	 * Bulk Delete Autoloader.
91
	 *
92
	 * Will be used by add-ons to extend the namespace.
93
	 *
94
	 * @var \BulkWP\BulkDelete\BulkDeleteAutoloader
95
	 */
96
	private $loader;
97
98
	/**
99
	 * List of Primary Admin pages.
100
	 *
101
	 * @var \BulkWP\BulkDelete\Core\Base\BaseDeletePage[]
102
	 *
103
	 * @since 6.0.0
104
	 */
105
	private $primary_pages = array();
106
107
	/**
108
	 * List of Secondary Admin pages.
109
	 *
110
	 * @var BasePage[]
111
	 *
112
	 * @since 6.0.0
113
	 */
114
	private $secondary_pages = array();
115
116
	/**
117
	 * Plugin version.
118
	 */
119
	const VERSION = '6.0.0';
120
121
	/**
122
	 * Set the BulkDelete constructor as private.
123
	 *
124
	 * An instance should be created by calling the `get_instance` method.
125
	 *
126
	 * @see BulkDelete::get_instance()
127
	 */
128
	private function __construct() {}
129
130
	/**
131
	 * Main BulkDelete Instance.
132
	 *
133
	 * Insures that only one instance of BulkDelete exists in memory at any one
134
	 * time. Also prevents needing to define globals all over the place.
135
	 *
136
	 * @since     5.0
137
	 * @static
138
	 * @staticvar array $instance
139
	 *
140 5
	 * @return BulkDelete The one true instance of BulkDelete.
141 5
	 */
142 1
	public static function get_instance() {
143
		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof BulkDelete ) ) {
144
			self::$instance = new BulkDelete();
145 5
		}
146
147
		return self::$instance;
148
	}
149
150
	/**
151
	 * Load the plugin if it is not loaded.
152
	 *
153 1
	 * This function will be invoked in the `plugins_loaded` hook.
154 1
	 */
155
	public function load() {
156
		if ( $this->loaded ) {
157
			return;
158 1
		}
159 1
160
		$this->load_dependencies();
161 1
		$this->setup_actions();
162
163
		$this->loaded = true;
164
165
		/**
166
		 * Bulk Delete plugin loaded.
167
		 *
168
		 * @since 6.0.0
169
		 *
170 1
		 * @param string Plugin main file.
171 1
		 */
172
		do_action( 'bd_loaded', $this->get_plugin_file() );
173
	}
174
175
	/**
176
	 * Throw error on object clone.
177
	 *
178
	 * The whole idea of the singleton design pattern is that there is a single
179
	 * object therefore, we don't want the object to be cloned.
180
	 *
181
	 * @since  5.0
182
	 * @access protected
183
	 *
184 1
	 * @return void
185 1
	 */
186 1
	public function __clone() {
187
		_doing_it_wrong( __FUNCTION__, __( "This class can't be cloned. Use `get_instance()` method to get an instance.", 'bulk-delete' ), '5.0' );
188
	}
189
190
	/**
191
	 * Disable unserializing of the class.
192
	 *
193
	 * @since  5.0
194
	 * @access protected
195
	 *
196 1
	 * @return void
197 1
	 */
198 1
	public function __wakeup() {
199
		_doing_it_wrong( __FUNCTION__, __( "This class can't be serialized. Use `get_instance()` method to get an instance.", 'bulk-delete' ), '5.0' );
200
	}
201
202
	/**
203
	 * Load all dependencies.
204
	 *
205 1
	 * @since 6.0.0
206 1
	 */
207 1
	private function load_dependencies() {
208
		$this->controller = new Controller();
209 1
		$this->controller->load();
210 1
211 1
		$this->upseller = new Upseller();
212
		$this->upseller->load();
213
	}
214
215
	/**
216
	 * Loads the plugin's actions and hooks.
217
	 *
218
	 * @access private
219
	 *
220
	 * @since  5.0
221
	 *
222 1
	 * @return void
223 1
	 */
224
	private function setup_actions() {
225 1
		add_action( 'init', array( $this, 'on_init' ) );
226 1
227
		add_action( 'admin_menu', array( $this, 'on_admin_menu' ) );
228
	}
229
230
	/**
231
	 * Triggered when the `init` hook is fired.
232
	 *
233 1
	 * @since 6.0.0
234 1
	 */
235 1
	public function on_init() {
236
		$this->load_textdomain();
237
238
		if ( is_admin() || defined( 'DOING_CRON' ) || isset( $_GET['doing_wp_cron'] ) ) {
239
			$this->load_primary_pages();
240
		}
241
	}
242 1
243 1
	/**
244 1
	 * Loads the plugin language files.
245
	 *
246
	 * @since  5.0
247
	 */
248
	private function load_textdomain() {
249
		load_plugin_textdomain( 'bulk-delete', false, $this->get_translations_path() );
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $deprecated of load_plugin_textdomain(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

249
		load_plugin_textdomain( 'bulk-delete', /** @scrutinizer ignore-type */ false, $this->get_translations_path() );
Loading history...
250
	}
251
252
	/**
253
	 * Triggered when the `admin_menu` hook is fired.
254
	 *
255
	 * Register all admin pages.
256
	 *
257
	 * @since 6.0.0
258
	 */
259
	public function on_admin_menu() {
260
		foreach ( $this->get_primary_pages() as $page ) {
261
			$page->register();
262
		}
263
264
		\Bulk_Delete_Misc::add_menu();
265
266
		/**
267
		 * Runs just after adding all *delete* menu items to Bulk WP main menu.
268
		 *
269
		 * This action is primarily for adding extra *delete* menu items to the Bulk WP main menu.
270
		 *
271
		 * @since 5.3
272
		 */
273
		do_action( 'bd_after_primary_menus' );
274
275
		/**
276
		 * Runs just before adding non-action menu items to Bulk WP main menu.
277
		 *
278
		 * This action is primarily for adding extra menu items before non-action menu items to the Bulk WP main menu.
279
		 *
280
		 * @since 5.3
281
		 */
282
		do_action( 'bd_before_secondary_menus' );
283
284
		foreach ( $this->get_secondary_pages() as $page ) {
285
			$page->register();
286
		}
287
288
		$this->addon_page = add_submenu_page(
0 ignored issues
show
Bug Best Practice introduced by
The property addon_page does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
289
			\Bulk_Delete::POSTS_PAGE_SLUG,
290
			__( 'Addon Licenses', 'bulk-delete' ),
291
			__( 'Addon Licenses', 'bulk-delete' ),
292
			'activate_plugins',
293
			\Bulk_Delete::ADDON_PAGE_SLUG,
294
			array( 'BD_License', 'display_addon_page' )
295
		);
296
297
		/**
298
		 * Runs just after adding all menu items to Bulk WP main menu.
299
		 *
300
		 * This action is primarily for adding extra menu items to the Bulk WP main menu.
301
		 *
302
		 * @since 5.3
303
		 */
304
		do_action( 'bd_after_all_menus' );
305
	}
306
307
	/**
308
	 * Get the list of registered admin pages.
309
	 *
310
	 * @since 6.0.0
311
	 *
312
	 * @return \BulkWP\BulkDelete\Core\Base\BaseDeletePage[] List of Primary Admin pages.
313
	 */
314
	public function get_primary_pages() {
315
		if ( empty( $this->primary_pages ) ) {
316
			$this->load_primary_pages();
317
		}
318
319
		return $this->primary_pages;
320
	}
321
322
	/**
323
	 * Load Primary admin pages.
324
	 *
325
	 * The pages need to be loaded in `init` hook, since the association between page and modules is needed in cron requests.
326
	 */
327
	private function load_primary_pages() {
328
		$posts_page = $this->get_delete_posts_admin_page();
329
		$pages_page = $this->get_delete_pages_admin_page();
330
		$users_page = $this->get_delete_users_admin_page();
331
		$metas_page = $this->get_delete_metas_admin_page();
332
		$terms_page = $this->get_delete_terms_admin_page();
333
334
		$this->primary_pages[ $posts_page->get_page_slug() ] = $posts_page;
335
		$this->primary_pages[ $pages_page->get_page_slug() ] = $pages_page;
336
		$this->primary_pages[ $users_page->get_page_slug() ] = $users_page;
337
		$this->primary_pages[ $metas_page->get_page_slug() ] = $metas_page;
338
		$this->primary_pages[ $terms_page->get_page_slug() ] = $terms_page;
339
340
		/**
341
		 * List of primary admin pages.
342
		 *
343
		 * @since 6.0.0
344
		 *
345
		 * @param \BulkWP\BulkDelete\Core\Base\BaseDeletePage[] List of Admin pages.
346
		 */
347
		$this->primary_pages = apply_filters( 'bd_primary_pages', $this->primary_pages );
348
	}
349
350
	/**
351
	 * Get Bulk Delete Posts admin page.
352
	 *
353
	 * @return \BulkWP\BulkDelete\Core\Posts\DeletePostsPage
354
	 */
355
	private function get_delete_posts_admin_page() {
356
		$posts_page = new DeletePostsPage( $this->get_plugin_file() );
357
358
		$posts_page->add_module( new DeletePostsByStatusModule() );
359
		$posts_page->add_module( new DeletePostsByCategoryModule() );
360
		$posts_page->add_module( new DeletePostsByTagModule() );
361
		$posts_page->add_module( new DeletePostsByTaxonomyModule() );
362
		$posts_page->add_module( new DeletePostsByPostTypeModule() );
363
		$posts_page->add_module( new DeletePostsByCommentsModule() );
364
		$posts_page->add_module( new DeletePostsByURLModule() );
365
		$posts_page->add_module( new DeletePostsByRevisionModule() );
366
		$posts_page->add_module( new DeletePostsByStickyPostModule() );
367
368
		/**
369
		 * After the modules are registered in the delete posts page.
370
		 *
371
		 * @since 6.0.0
372
		 *
373
		 * @param DeletePostsPage $posts_page The page in which the modules are registered.
374
		 */
375
		do_action( "bd_after_modules_{$posts_page->get_page_slug()}", $posts_page );
376
377
		/**
378
		 * After the modules are registered in a delete page.
379
		 *
380
		 * @since 6.0.0
381
		 *
382
		 * @param BasePage $posts_page The page in which the modules are registered.
383
		 */
384
		do_action( 'bd_after_modules', $posts_page );
385
386
		return $posts_page;
387
	}
388
389
	/**
390
	 * Get Bulk Delete Pages admin page.
391
	 *
392
	 * @since 6.0.0
393
	 *
394
	 * @return \BulkWP\BulkDelete\Core\Pages\DeletePagesPage
395
	 */
396
	private function get_delete_pages_admin_page() {
397
		$pages_page = new DeletePagesPage( $this->get_plugin_file() );
398
399
		$pages_page->add_module( new DeletePagesByStatusModule() );
400
401
		/**
402
		 * After the modules are registered in the delete pages page.
403
		 *
404
		 * @since 6.0.0
405
		 *
406
		 * @param DeletePagesPage $pages_page The page in which the modules are registered.
407
		 */
408
		do_action( "bd_after_modules_{$pages_page->get_page_slug()}", $pages_page );
409
410
		/**
411
		 * After the modules are registered in a delete page.
412
		 *
413
		 * @since 6.0.0
414
		 *
415
		 * @param BasePage $pages_page The page in which the modules are registered.
416
		 */
417
		do_action( 'bd_after_modules', $pages_page );
418
419
		return $pages_page;
420
	}
421
422
	/**
423
	 * Get Bulk Delete Users admin page.
424
	 *
425
	 * @since 6.0.0
426
	 *
427
	 * @return \BulkWP\BulkDelete\Core\Users\DeleteUsersPage
428
	 */
429
	private function get_delete_users_admin_page() {
430
		$users_page = new DeleteUsersPage( $this->get_plugin_file() );
431
432
		$users_page->add_module( new DeleteUsersByUserRoleModule() );
433
		$users_page->add_module( new DeleteUsersByUserMetaModule() );
434
435
		/**
436
		 * After the modules are registered in the delete users page.
437
		 *
438
		 * @since 6.0.0
439
		 *
440
		 * @param DeleteUsersPage $users_page The page in which the modules are registered.
441
		 */
442
		do_action( "bd_after_modules_{$users_page->get_page_slug()}", $users_page );
443
444
		/**
445
		 * After the modules are registered in a delete page.
446
		 *
447
		 * @since 6.0.0
448
		 *
449
		 * @param BasePage $users_page The page in which the modules are registered.
450
		 */
451
		do_action( 'bd_after_modules', $users_page );
452
453
		return $users_page;
454
	}
455
456
	/**
457
	 * Get Bulk Delete Metas admin page.
458
	 *
459
	 * @since 6.0.0
460
	 *
461
	 * @return \BulkWP\BulkDelete\Core\Metas\DeleteMetasPage
462
	 */
463
	private function get_delete_metas_admin_page() {
464
		$metas_page = new DeleteMetasPage( $this->get_plugin_file() );
465
466
		$metas_page->add_module( new DeletePostMetaModule() );
467
		$metas_page->add_module( new DeleteUserMetaModule() );
468
		$metas_page->add_module( new DeleteCommentMetaModule() );
469
470
		/**
471
		 * After the modules are registered in the delete metas page.
472
		 *
473
		 * @since 6.0.0
474
		 *
475
		 * @param DeleteMetasPage $metas_page The page in which the modules are registered.
476
		 */
477
		do_action( "bd_after_modules_{$metas_page->get_page_slug()}", $metas_page );
478
479
		/**
480
		 * After the modules are registered in a delete page.
481
		 *
482
		 * @since 6.0.0
483
		 *
484
		 * @param BasePage $metas_page The page in which the modules are registered.
485
		 */
486
		do_action( 'bd_after_modules', $metas_page );
487
488
		return $metas_page;
489
	}
490
491
	/**
492
	 * Get Bulk Delete Terms admin page.
493
	 *
494
	 * @since 6.0.0
495
	 *
496
	 * @return \BulkWP\BulkDelete\Core\Terms\DeleteTermsPage
497
	 */
498
	private function get_delete_terms_admin_page() {
499
		$terms_page = new DeleteTermsPage( $this->get_plugin_file() );
500
501
		$terms_page->add_module( new DeleteTermsByNameModule() );
502
		$terms_page->add_module( new DeleteTermsByPostCountModule() );
503
504
		/**
505
		 * After the modules are registered in the delete terms page.
506
		 *
507
		 * @since 6.0.0
508
		 *
509
		 * @param DeleteTermsPage $terms_page The page in which the modules are registered.
510
		 */
511
		do_action( "bd_after_modules_{$terms_page->get_page_slug()}", $terms_page );
512
513
		/**
514
		 * After the modules are registered in a delete page.
515
		 *
516
		 * @since 6.0.0
517
		 *
518
		 * @param BasePage $terms_page The page in which the modules are registered.
519
		 */
520
		do_action( 'bd_after_modules', $terms_page );
521
522
		return $terms_page;
523
	}
524
525
	/**
526
	 * Get the Cron List admin page.
527
	 *
528
	 * @since 6.0.0
529
	 *
530
	 * @return \BulkWP\BulkDelete\Core\Cron\CronListPage
531 2
	 */
532 2
	private function get_cron_list_admin_page() {
533
		$cron_list_page = new CronListPage( $this->get_plugin_file() );
534
535
		return $cron_list_page;
536
	}
537
538
	/**
539
	 * Get the System Info page.
540 2
	 *
541 2
	 * @since 6.0.0
542 2
	 *
543 2
	 * @return \BulkWP\BulkDelete\Core\SystemInfo\SystemInfoPage
544
	 */
545
	private function get_system_info_page() {
546
		$system_info_page = new SystemInfoPage( $this->get_plugin_file() );
547
548
		return $system_info_page;
549
	}
550 1
551 1
	/**
552
	 * Get the list of secondary pages.
553
	 *
554
	 * @return BasePage[] Secondary Pages.
555
	 */
556
	private function get_secondary_pages() {
557
		if ( empty( $this->secondary_pages ) ) {
558
			$cron_list_page   = $this->get_cron_list_admin_page();
559
			$system_info_page = $this->get_system_info_page();
560
561
			$this->secondary_pages[ $cron_list_page->get_page_slug() ]   = $cron_list_page;
562
			$this->secondary_pages[ $system_info_page->get_page_slug() ] = $system_info_page;
563
		}
564
565
		/**
566
		 * List of secondary admin pages.
567
		 *
568
		 * @since 6.0.0
569
		 *
570
		 * @param BasePage[] List of Admin pages.
571
		 */
572
		return apply_filters( 'bd_secondary_pages', $this->secondary_pages );
573
	}
574
575
	/**
576
	 * Get path to main plugin file.
577
	 *
578
	 * @return string Plugin file.
579
	 */
580
	public function get_plugin_file() {
581
		return $this->plugin_file;
582
	}
583
584
	/**
585
	 * Set path to main plugin file.
586
	 *
587
	 * @param string $plugin_file Path to main plugin file.
588
	 */
589
	public function set_plugin_file( $plugin_file ) {
590
		$this->plugin_file       = $plugin_file;
591
		$this->translations_path = dirname( plugin_basename( $this->get_plugin_file() ) ) . '/languages/';
592
	}
593
594
	/**
595
	 * Get path to translations.
596
	 *
597
	 * @return string Translations path.
598
	 */
599
	public function get_translations_path() {
600
		return $this->translations_path;
601
	}
602
603
	/**
604
	 * Get the hook suffix of a page.
605
	 *
606
	 * @param string $page_slug Page slug.
607
	 *
608
	 * @return string|null Hook suffix if found, null otherwise.
609
	 */
610
	public function get_page_hook_suffix( $page_slug ) {
611
		$admin_page = '';
612
613
		if ( array_key_exists( $page_slug, $this->get_primary_pages() ) ) {
614
			$admin_page = $this->primary_pages[ $page_slug ];
615
		}
616
617
		if ( array_key_exists( $page_slug, $this->get_secondary_pages() ) ) {
618
			$admin_page = $this->secondary_pages[ $page_slug ];
619
		}
620
621
		if ( $admin_page instanceof BasePage ) {
622
			return $admin_page->get_hook_suffix();
623
		}
624
625
		return null;
626
	}
627
628
	/**
629
	 * Register Add-on Namespace.
630
	 *
631
	 * @param \BulkWP\BulkDelete\Core\Addon\AddonInfo $addon_info Add-on Info.
632
	 */
633
	public function register_addon_namespace( $addon_info ) {
634
		$this->loader->add_namespace( 'BulkWP\BulkDelete', $addon_info->get_addon_directory() . 'includes' );
635
	}
636
637
	/**
638
	 * Setter for Autoloader.
639
	 *
640
	 * @param \BulkWP\BulkDelete\BulkDeleteAutoloader $loader Autoloader.
641
	 */
642
	public function set_loader( $loader ) {
643
		$this->loader = $loader;
644
	}
645
646
	/**
647
	 * Get the module object instance by page slug and module class name.
648
	 *
649
	 * @param string $page_slug         Page Slug.
650
	 * @param string $module_class_name Module class name.
651
	 *
652
	 * @return \BulkWP\BulkDelete\Core\Base\BaseModule|null Module object instance or null if no match found.
653
	 */
654
	public function get_module( $page_slug, $module_class_name ) {
655
		$page = $this->get_page( $page_slug );
656
657
		if ( is_null( $page ) ) {
658
			return null;
659
		}
660
661
		return $page->get_module( $module_class_name );
662
	}
663
664
	/**
665
	 * Get the page object instance by page slug.
666
	 *
667
	 * @param string $page_slug Page slug.
668
	 *
669
	 * @return \BulkWP\BulkDelete\Core\Base\BaseDeletePage|null Page object instance or null if no match found.
670
	 */
671
	public function get_page( $page_slug ) {
672
		$pages = $this->get_primary_pages();
673
674
		if ( ! isset( $pages[ $page_slug ] ) ) {
675
			return null;
676
		}
677
678
		return $pages[ $page_slug ];
679
	}
680
}
681