Passed
Push — 190-feature/delete-posts-by-cu... ( 3b8c06...5cea16 )
by Sudar
22:49 queued 19:43
created

PostsMetabox::get_post_statuses()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
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 2
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace BulkWP\BulkDelete\Core\Posts;
3
4
use BulkWP\BulkDelete\Core\Base\BaseMetabox;
5
6 1
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
7
8
/**
9
 * Metabox for deleting posts.
10
 *
11
 * @since 6.0.0
12
 */
13
abstract class PostsMetabox extends BaseMetabox {
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
	public function filter_js_array( $js_array ) {
28
		$js_array['msg']['deletePostsWarning'] = __( 'Are you sure you want to delete all the posts based on the selected option?', 'bulk-delete' );
29
		$js_array['msg']['selectPostOption']   = __( 'Please select posts from at least one option', 'bulk-delete' );
30
31
		$js_array['validators']['delete_posts_by_category'] = 'validateSelect2';
32
		$js_array['error_msg']['delete_posts_by_category']  = 'selectCategory';
33
		$js_array['msg']['selectCategory']                  = __( 'Please select at least one category', 'bulk-delete' );
34
35
		$js_array['validators']['delete_posts_by_tag']     = 'validateSelect2';
36
		$js_array['error_msg']['delete_posts_by_category'] = 'selectTag';
37
		$js_array['msg']['selectTag']                      = __( 'Please select at least one tag', 'bulk-delete' );
38
39
		$js_array['validators']['delete_posts_by_url'] = 'validateUrl';
40
		$js_array['error_msg']['delete_posts_by_url']  = 'enterUrl';
41
		$js_array['msg']['enterUrl']                   = __( 'Please enter at least one post url', 'bulk-delete' );
42
43
		$js_array['dt_iterators'][] = '_cats';
44
		$js_array['dt_iterators'][] = '_tags';
45
		$js_array['dt_iterators'][] = '_taxs';
46
		$js_array['dt_iterators'][] = '_types';
47
		$js_array['dt_iterators'][] = '_post_status';
48
49
		return $js_array;
50
	}
51
52 36
	public function delete( $options ) {
53
		/**
54
		 * Filter delete options before deleting posts.
55
		 *
56
		 * @since 6.0.0 Added `Metabox` parameter.
57
		 *
58
		 * @param array $options Delete options.
59
		 * @param \BulkWP\BulkDelete\Core\Base\BaseMetabox Metabox that is triggering deletion.
60
		 */
61 36
		$options = apply_filters( 'bd_delete_options', $options, $this );
62
63 36
		$query = $this->build_query( $options );
64
65 36
		if ( empty( $query ) ) {
66
			// Short circuit deletion, if nothing needs to be deleted.
67
			return 0;
68
		}
69
70 36
		return $this->delete_posts_from_query( $query, $options );
71
	}
72
73
	/**
74
	 * Build the query using query params and then Delete posts.
75
	 *
76
	 * @param array $query   Params for WP Query.
77
	 * @param array $options Delete Options.
78
	 *
79
	 * @return int Number of posts deleted.
80
	 */
81 36
	protected function delete_posts_from_query( $query, $options ) {
82 36
		$query    = bd_build_query_options( $options, $query );
83 36
		$post_ids = bd_query( $query );
84
85 36
		return $this->delete_posts_by_id( $post_ids, $options['force_delete'] );
86
	}
87
88
	/**
89
	 * Render the "private post" setting fields.
90
	 */
91
	protected function render_private_post_settings() {
92
		bd_render_private_post_settings( $this->field_slug );
93
	}
94
95
	/**
96
	 * Render Post type dropdown.
97
	 */
98
	protected function render_post_type_dropdown() {
99
		bd_render_post_type_dropdown( $this->field_slug );
100
	}
101
102
	/**
103
	 * Render Category dropdown.
104
	 */
105
	protected function render_category_dropdown() {
106
		$categories = $this->get_categories();
107
		?>
108
109
		<select name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_category[]" data-placeholder="<?php _e( 'Select Categories', 'bulk-delete' ); ?>"
110
				class="<?php echo sanitize_html_class( $this->enable_ajax_if_needed_to_dropdown_class_name( count( $categories ), 'select2-taxonomy' ) ); ?>"
111
				data-taxonomy="category" multiple>
112
113
			<option value="all">
114
				<?php _e( 'All Categories', 'bulk-delete' ); ?>
115
			</option>
116
117
			<?php foreach ( $categories as $category ) : ?>
118
				<option value="<?php echo absint( $category->cat_ID ); ?>">
119
					<?php echo esc_html( $category->cat_name ), ' (', absint( $category->count ), ' ', __( 'Posts', 'bulk-delete' ), ')'; ?>
120
				</option>
121
			<?php endforeach; ?>
122
123
		</select>
124
	<?php
125
	}
126
127
	/**
128
	 * Render Tags dropdown.
129
	 */
130
	protected function render_tags_dropdown() {
131
		$tags = $this->get_tags();
132
		?>
133
134
		<select name="smbd_<?php echo esc_attr( $this->field_slug ); ?>[]" data-placeholder="<?php _e( 'Select Tags', 'bulk-delete' ); ?>"
135
				class="<?php echo sanitize_html_class( $this->enable_ajax_if_needed_to_dropdown_class_name( count( $tags ), 'select2-taxonomy' ) ); ?>"
136
				data-taxonomy="post_tag" multiple>
137
138
			<option value="all">
139
				<?php _e( 'All Tags', 'bulk-delete' ); ?>
140
			</option>
141
142
			<?php foreach ( $tags as $tag ) : ?>
143
				<option value="<?php echo absint( $tag->term_id ); ?>">
144
					<?php echo esc_html( $tag->name ), ' (', absint( $tag->count ), ' ', __( 'Posts', 'bulk-delete' ), ')'; ?>
145
				</option>
146
			<?php endforeach; ?>
147
		</select>
148
	<?php
149
	}
150
151
	/**
152
	 * Get the list of post statuses.
153
	 *
154
	 * This includes all custom post status, but excludes built-in private posts.
155
	 *
156
	 * @return array List of post status objects.
157
	 */
158
	protected function get_post_statuses() {
159
		return bd_get_post_statuses();
160
	}
161
162
	/**
163
	 * Get the list of categories.
164
	 *
165
	 * @return array List of categories.
166
	 */
167
	protected function get_categories() {
168
		$enhanced_select_threshold = $this->get_enhanced_select_threshold();
169
170
		$categories = get_categories(
171
			array(
172
				'hide_empty' => false,
173
				'number'     => $enhanced_select_threshold,
174
			)
175
		);
176
177
		return $categories;
178
	}
179
180
	/**
181
	 * Are tags present in this WordPress installation?
182
	 *
183
	 * Only one tag is retrieved to check if tags are present for performance reasons.
184
	 *
185
	 * @return bool True if tags are present, False otherwise.
186
	 */
187
	protected function are_tags_present() {
188
		$tags = $this->get_tags( 1 );
189
190
		return ( count( $tags ) > 0 );
191
	}
192
193
	/**
194
	 * Get the list of tags.
195
	 *
196
	 * @param int $max_count The maximum number of tags to be returned (Optional). Default 0.
197
	 *                       If 0 then the maximum number of tags specified in `get_enhanced_select_threshold` will be returned.
198
	 *
199
	 * @return array List of tags.
200
	 */
201
	protected function get_tags( $max_count = 0 ) {
202
		if ( absint( $max_count ) === 0 ) {
203
			$max_count = $this->get_enhanced_select_threshold();
204
		}
205
206
		$tags = get_tags(
207
			array(
208
				'hide_empty' => false,
209
				'number'     => $max_count,
210
			)
211
		);
212
213
		return $tags;
214
	}
215
216
	/**
217
	 * Delete sticky posts.
218
	 *
219
	 * @param bool $force_delete Whether to bypass trash and force deletion.
220
	 *
221
	 * @return int Number of posts deleted.
222
	 */
223
	protected function delete_sticky_posts( $force_delete ) {
224
		$sticky_post_ids = get_option( 'sticky_posts' );
225
226
		if ( ! is_array( $sticky_post_ids ) ) {
227
			return 0;
228
		}
229
230
		return $this->delete_posts_by_id( $sticky_post_ids, $force_delete );
231
	}
232
233
	/**
234
	 * Delete posts by ids.
235
	 *
236
	 * @param int[] $post_ids     List of post ids to delete.
237
	 * @param bool  $force_delete True to force delete posts, False otherwise.
238
	 *
239
	 * @return int Number of posts deleted.
240
	 */
241 36
	protected function delete_posts_by_id( $post_ids, $force_delete ) {
242 36
		foreach ( $post_ids as $post_id ) {
243
			// `$force_delete` parameter to `wp_delete_post` won't work for custom post types.
244
			// See https://core.trac.wordpress.org/ticket/43672
245 36
			if ( $force_delete ) {
246 10
				wp_delete_post( $post_id, true );
247
			} else {
248 36
				wp_trash_post( $post_id );
249
			}
250
		}
251
252 36
		return count( $post_ids );
253
	}
254
255
	/**
256
	 * Generate display name from post type and status.
257
	 *
258
	 * @static
259
	 *
260
	 * @param string $str
261
	 *
262
	 * @return string Label
263
	 */
264
	protected function display_post_type_status( $str ) {
265
		$type_status = self::split_post_type_status( $str );
0 ignored issues
show
Bug Best Practice introduced by
The method BulkWP\BulkDelete\Core\P...plit_post_type_status() is not static, but was called statically. ( Ignorable by Annotation )

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

265
		/** @scrutinizer ignore-call */ 
266
  $type_status = self::split_post_type_status( $str );
Loading history...
266
267
		$status = $type_status['status'];
268
		$type   = $type_status['type'];
269
		$label  = '';
270
271
		switch ( $status ) {
272
			case 'private':
273
				$label = $type . ' - Private Posts';
274
				break;
275
			case 'future':
276
				$label = $type . ' - Scheduled Posts';
277
				break;
278
			case 'draft':
279
				$label = $type . ' - Draft Posts';
280
				break;
281
			case 'pending':
282
				$label = $type . ' - Pending Posts';
283
				break;
284
			case 'publish':
285
				$label = $type . ' - Published Posts';
286
				break;
287
		}
288
289
		return $label;
290
	}
291
292
	/**
293
	 * Split post type and status.
294
	 *
295
	 * @static
296
	 * @access public
297
	 *
298
	 * @param string $str
299
	 *
300
	 * @return array
301
	 */
302
	protected function split_post_type_status( $str ) {
303
		$type_status = array();
304
305
		$str_arr = explode( '-', $str );
306
307
		if ( count( $str_arr ) > 1 ) {
308
			$type_status['status'] = end( $str_arr );
309
			$type_status['type']   = implode( '-', array_slice( $str_arr, 0, -1 ) );
310
		} else {
311
			$type_status['status'] = 'publish';
312
			$type_status['type']   = $str;
313
		}
314
315
		return $type_status;
316
	}
317
}
318