Completed
Push — dev/6.0.0 ( ee7fd2...7ea4f4 )
by Sudar
12:00
created

PostsModule   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 289
Duplicated Lines 0 %

Test Coverage

Coverage 15.38%

Importance

Changes 0
Metric Value
dl 0
loc 289
ccs 14
cts 91
cp 0.1538
rs 10
c 0
b 0
f 0
wmc 24

16 Methods

Rating   Name   Duplication   Size   Complexity  
A get_tags() 0 13 2
A filter_js_array() 0 22 1
A get_categories() 0 11 1
A delete_posts_by_id() 0 12 3
A do_delete() 0 9 2
A are_sticky_post_present() 0 4 1
A are_tags_present() 0 4 1
A render_sticky_post_dropdown() 0 21 2
A parse_common_filters() 0 11 1
A get_sticky_posts() 0 4 1
A render_category_dropdown() 0 18 2
A delete_posts_from_query() 0 5 1
A render_tags_dropdown() 0 18 2
A render_post_type_dropdown() 0 2 1
A render_private_post_settings() 0 2 1
A delete_sticky_posts() 0 8 2
1
<?php
2
namespace BulkWP\BulkDelete\Core\Posts;
3
4
use BulkWP\BulkDelete\Core\Base\BaseModule;
5
6 1
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
7
8
/**
9
 * Module for deleting posts.
10
 *
11
 * @since 6.0.0
12
 */
13
abstract class PostsModule extends BaseModule {
14
	/**
15
	 * Build query params for WP_Query by using delete options.
16
	 *
17
	 * Return an empty query array to short-circuit deletion.
18
	 *
19
	 * @param array $options Delete options.
20
	 *
21
	 * @return array Query.
22
	 */
23
	abstract protected function build_query( $options );
24
25
	protected $item_type = 'posts';
26
27
	/**
28
	 * Handle common filters.
29
	 *
30
	 * @param array $request Request array.
31
	 *
32
	 * @return array User options.
33
	 */
34
	protected function parse_common_filters( $request ) {
35
		$options = array();
36
37
		$options['restrict']     = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_restrict', false );
38
		$options['limit_to']     = absint( bd_array_get( $request, 'smbd_' . $this->field_slug . '_limit_to', 0 ) );
39
		$options['force_delete'] = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_force_delete', false );
40
41
		$options['date_op'] = bd_array_get( $request, 'smbd_' . $this->field_slug . '_op' );
42
		$options['days']    = absint( bd_array_get( $request, 'smbd_' . $this->field_slug . '_days' ) );
43
44
		return $options;
45
	}
46
47
	public function filter_js_array( $js_array ) {
48
		$js_array['msg']['deletePostsWarning'] = __( 'Are you sure you want to delete all the posts based on the selected option?', 'bulk-delete' );
49
		$js_array['msg']['selectPostOption']   = __( 'Please select posts from at least one option', 'bulk-delete' );
50
51
		$js_array['validators']['delete_posts_by_category'] = 'validateSelect2';
52
		$js_array['error_msg']['delete_posts_by_category']  = 'selectCategory';
53
		$js_array['msg']['selectCategory']                  = __( 'Please select at least one category', 'bulk-delete' );
54
55
		$js_array['validators']['delete_posts_by_tag']     = 'validateSelect2';
56
		$js_array['error_msg']['delete_posts_by_category'] = 'selectTag';
57
		$js_array['msg']['selectTag']                      = __( 'Please select at least one tag', 'bulk-delete' );
58
59
		$js_array['validators']['delete_posts_by_url'] = 'validateUrl';
60
		$js_array['error_msg']['delete_posts_by_url']  = 'enterUrl';
61
		$js_array['msg']['enterUrl']                   = __( 'Please enter at least one post url', 'bulk-delete' );
62
63
		$js_array['dt_iterators'][] = '_cats';
64
		$js_array['dt_iterators'][] = '_tags';
65
		$js_array['dt_iterators'][] = '_taxs';
66
		$js_array['dt_iterators'][] = '_post_status';
67
68
		return $js_array;
69
	}
70
71 44
	protected function do_delete( $options ) {
72 44
		$query = $this->build_query( $options );
73
74 44
		if ( empty( $query ) ) {
75
			// Short circuit deletion, if nothing needs to be deleted.
76
			return 0;
77
		}
78
79 44
		return $this->delete_posts_from_query( $query, $options );
80
	}
81
82
	/**
83
	 * Build the query using query params and then Delete posts.
84
	 *
85
	 * @param array $query   Params for WP Query.
86
	 * @param array $options Delete Options.
87
	 *
88
	 * @return int Number of posts deleted.
89
	 */
90 44
	protected function delete_posts_from_query( $query, $options ) {
91 44
		$query    = bd_build_query_options( $options, $query );
92 44
		$post_ids = bd_query( $query );
93
94 44
		return $this->delete_posts_by_id( $post_ids, $options['force_delete'] );
95
	}
96
97
	/**
98
	 * Render the "private post" setting fields.
99
	 */
100
	protected function render_private_post_settings() {
101
		bd_render_private_post_settings( $this->field_slug );
102
	}
103
104
	/**
105
	 * Render Post type dropdown.
106
	 */
107
	protected function render_post_type_dropdown() {
108
		bd_render_post_type_dropdown( $this->field_slug );
109
	}
110
111
	/**
112
	 * Render Category dropdown.
113
	 */
114
	protected function render_category_dropdown() {
115
		$categories = $this->get_categories();
116
		?>
117
118
		<select name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_category[]" data-placeholder="<?php _e( 'Select Categories', 'bulk-delete' ); ?>"
119
				class="<?php echo sanitize_html_class( $this->enable_ajax_if_needed_to_dropdown_class_name( count( $categories ), 'select2-taxonomy' ) ); ?>"
120
				data-taxonomy="category" multiple>
121
122
			<option value="all">
123
				<?php _e( 'All Categories', 'bulk-delete' ); ?>
124
			</option>
125
126
			<?php foreach ( $categories as $category ) : ?>
127
				<option value="<?php echo absint( $category->cat_ID ); ?>">
128
					<?php echo esc_html( $category->cat_name ), ' (', absint( $category->count ), ' ', __( 'Posts', 'bulk-delete' ), ')'; ?>
129
				</option>
130
			<?php endforeach; ?>
131
132
		</select>
133
	<?php
134
	}
135
136
	/**
137
	 * Render Tags dropdown.
138
	 */
139
	protected function render_tags_dropdown() {
140
		$tags = $this->get_tags();
141
		?>
142
143
		<select name="smbd_<?php echo esc_attr( $this->field_slug ); ?>[]" data-placeholder="<?php _e( 'Select Tags', 'bulk-delete' ); ?>"
144
				class="<?php echo sanitize_html_class( $this->enable_ajax_if_needed_to_dropdown_class_name( count( $tags ), 'select2-taxonomy' ) ); ?>"
145
				data-taxonomy="post_tag" multiple>
146
147
			<option value="all">
148
				<?php _e( 'All Tags', 'bulk-delete' ); ?>
149
			</option>
150
151
			<?php foreach ( $tags as $tag ) : ?>
152
				<option value="<?php echo absint( $tag->term_id ); ?>">
153
					<?php echo esc_html( $tag->name ), ' (', absint( $tag->count ), ' ', __( 'Posts', 'bulk-delete' ), ')'; ?>
154
				</option>
155
			<?php endforeach; ?>
156
		</select>
157
	<?php
158
	}
159
160
	/**
161
	 * Render Sticky Posts dropdown.
162
	 */
163
	protected function render_sticky_post_dropdown() {
164
		$posts = $this->get_sticky_posts();
165
		?>
166
		<table class="optiontable">
167
			<tr>
168
				<td scope="row">
169
					<input type="checkbox" class="smbd_sticky_post_options" name="smbd_<?php echo esc_attr( $this->field_slug ); ?>[]" value="All">
170
					<label>All</label>
171
				</td>
172
			</tr>
173
			<?php foreach ( $posts as $post ) :
174
			$user = get_userdata( $post->post_author );
175
			?>
176
			<tr>
177
				<td scope="row">
178
				<input type="checkbox" class="smbd_sticky_post_options" name="smbd_<?php echo esc_attr( $this->field_slug ); ?>[]" value="<?php echo absint( $post->ID ); ?>">
179
				<label><?php echo esc_html( $post->post_title . ' Published by ' . $user->display_name . ' on ' . $post->post_date ); ?></label>
180
				</td>
181
			</tr>
182
			<?php endforeach; ?>
183
		</table>
184
	<?php
185
	}
186
187
	/**
188
	 * Get the list of sticky posts.
189
	 *
190
	 * @return array List of sticky posts.
191
	 */
192
	protected function get_sticky_posts(){
193
		$posts = get_posts( array( 'post__in' => get_option( 'sticky_posts' ) ) );
194
195
		return $posts;
196
	}
197
198
	/**
199
	 * Get the list of categories.
200
	 *
201
	 * @return array List of categories.
202
	 */
203
	protected function get_categories() {
204
		$enhanced_select_threshold = $this->get_enhanced_select_threshold();
205
206
		$categories = get_categories(
207
			array(
208
				'hide_empty' => false,
209
				'number'     => $enhanced_select_threshold,
210
			)
211
		);
212
213
		return $categories;
214
	}
215
216
	/**
217
	 * Are tags present in this WordPress installation?
218
	 *
219
	 * Only one tag is retrieved to check if tags are present for performance reasons.
220
	 *
221
	 * @return bool True if tags are present, False otherwise.
222
	 */
223
	protected function are_tags_present() {
224
		$tags = $this->get_tags( 1 );
225
226
		return ( count( $tags ) > 0 );
227
	}
228
229
	/**
230
	 * Are sticky post present in this WordPress?
231
	 *
232
	 * Only one post is retrieved to check if stick post are present for performance reasons.
233
	 *
234
	 * @return bool True if posts are present, False otherwise.
235
	 */
236
	protected function are_sticky_post_present() {
237
		$sticky_post_ids = get_option( 'sticky_posts' );
238
239
		return ( count( $sticky_post_ids ) > 0 );
0 ignored issues
show
Bug introduced by
It seems like $sticky_post_ids can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

239
		return ( count( /** @scrutinizer ignore-type */ $sticky_post_ids ) > 0 );
Loading history...
240
	}
241
242
	/**
243
	 * Get the list of tags.
244
	 *
245
	 * @param int $max_count The maximum number of tags to be returned (Optional). Default 0.
246
	 *                       If 0 then the maximum number of tags specified in `get_enhanced_select_threshold` will be returned.
247
	 *
248
	 * @return array List of tags.
249
	 */
250
	protected function get_tags( $max_count = 0 ) {
251
		if ( absint( $max_count ) === 0 ) {
252
			$max_count = $this->get_enhanced_select_threshold();
253
		}
254
255
		$tags = get_tags(
256
			array(
257
				'hide_empty' => false,
258
				'number'     => $max_count,
259
			)
260
		);
261
262
		return $tags;
263
	}
264
265
	/**
266
	 * Delete sticky posts.
267
	 *
268
	 * @param bool $force_delete Whether to bypass trash and force deletion.
269
	 *
270
	 * @return int Number of posts deleted.
271
	 */
272
	protected function delete_sticky_posts( $force_delete ) {
273
		$sticky_post_ids = get_option( 'sticky_posts' );
274
275
		if ( ! is_array( $sticky_post_ids ) ) {
276
			return 0;
277
		}
278
279
		return $this->delete_posts_by_id( $sticky_post_ids, $force_delete );
280
	}
281
282
	/**
283
	 * Delete posts by ids.
284
	 *
285
	 * @param int[] $post_ids     List of post ids to delete.
286
	 * @param bool  $force_delete True to force delete posts, False otherwise.
287
	 *
288
	 * @return int Number of posts deleted.
289
	 */
290 44
	protected function delete_posts_by_id( $post_ids, $force_delete ) {
291 44
		foreach ( $post_ids as $post_id ) {
292
			// `$force_delete` parameter to `wp_delete_post` won't work for custom post types.
293
			// See https://core.trac.wordpress.org/ticket/43672
294 44
			if ( $force_delete ) {
295 12
				wp_delete_post( $post_id, true );
296
			} else {
297 44
				wp_trash_post( $post_id );
298
			}
299
		}
300
301 44
		return count( $post_ids );
302
	}
303
}
304