Completed
Push — 178-feature/delete-terms--by-p... ( a8bf55...5e1501 )
by Rajan
49:40 queued 46:31
created

TermsModule::term_contains()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 15
ccs 0
cts 9
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
namespace BulkWP\BulkDelete\Core\Terms;
3
4
use BulkWP\BulkDelete\Core\Base\BaseModule;
5
6 1
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
7
8
/**
9
 * Module for deleting terms.
10
 *
11
 * @since 6.0.0
12
 */
13
abstract class TermsModule 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
	/**
26
	 * Item type.
27
	 *
28
	 * @var string Item Type. Possible values 'posts', 'pages', 'users', 'terms' etc.
29
	 */
30
	protected $item_type = 'terms';
31
32
	/**
33
	 * Handle common filters.
34
	 *
35
	 * @param array $request Request array.
36
	 *
37
	 * @return array User options.
38
	 */
39
	protected function parse_common_filters( $request ) {
40
		$options = array();
41
42
		$options['restrict']     = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_restrict', false );
43
		$options['limit_to']     = absint( bd_array_get( $request, 'smbd_' . $this->field_slug . '_limit_to', 0 ) );
44
		$options['force_delete'] = bd_array_get_bool( $request, 'smbd_' . $this->field_slug . '_force_delete', false );
45
46
		$options['date_op'] = bd_array_get( $request, 'smbd_' . $this->field_slug . '_op' );
47
		$options['days']    = absint( bd_array_get( $request, 'smbd_' . $this->field_slug . '_days' ) );
48
49
		return $options;
50
	}
51
52
	/**
53
	 * Filter the js array.
54
	 * This function will be overridden by the child classes.
55
	 *
56
	 * @since 5.5
57
	 *
58
	 * @param array $js_array JavaScript Array.
59
	 *
60
	 * @return array Modified JavaScript Array.
61
	 */
62
	public function filter_js_array( $js_array ) {
63
		return $js_array;
64
	}
65
66
	/**
67
	 * Perform the deletion.
68
	 *
69
	 * @param array $options Array of Delete options.
70
	 *
71
	 * @return int Number of items that were deleted.
72
	 */
73 4
	protected function do_delete( $options ) {
74 4
		$query = $this->build_query( $options );
75
76 4
		if ( empty( $query ) ) {
77
			// Short circuit deletion, if nothing needs to be deleted.
78
			return 0;
79
		}
80
81 4
		return $this->delete_terms_from_query( $query, $options );
82
	}
83
84
	/**
85
	 * Build the query using query params and then Delete posts.
86
	 *
87
	 * @param array $query   Params for WP Query.
88
	 * @param array $options Delete Options.
89
	 *
90
	 * @return int Number of posts deleted.
91
	 */
92 4
	protected function delete_terms_from_query( $query, $options ) {
93 4
		$term_ids = $this->term_query( $query, $options['taxonomy'] );
94
95 4
		return $this->delete_terms_by_id( $term_ids, $options );
96
	}
97
98
	/**
99
	 * Delete terms by ids.
100
	 *
101
	 * @param int[] $term_ids List of term ids to delete.
102
	 * @param mixed $options  user options.
103
	 *
104
	 * @return int Number of posts deleted.
105
	 */
106 4
	protected function delete_terms_by_id( $term_ids, $options ) {
107 4
		$count = 0;
108
109 4
		foreach ( $term_ids as $term_id ) {
110 4
			$term = get_term( $term_id, $options['taxonomy'] );
111
112 4
			if ( is_wp_error( $term ) ) {
113
				continue;
114
			}
115
116 4
			if ( isset( $options['no_posts'] ) && $term->count > 0 ) {
0 ignored issues
show
Bug introduced by
The property count does not seem to exist on WP_Error.
Loading history...
117
				continue;
118
			}
119
120 4
			wp_delete_term( $term_id, $options['taxonomy'] );
121 4
			$count ++;
122
		}
123
124 4
		return $count;
125
	}
126
127
	/**
128
	 * Custom string function use to get is string start with specified string.
129
	 *
130
	 * @param string $haystack search string.
131
	 * @param string $needle   find string.
132
	 *
133
	 * @return bool.
0 ignored issues
show
Documentation Bug introduced by
The doc comment bool. at position 0 could not be parsed: Unknown type name 'bool.' at position 0 in bool..
Loading history...
134
	 */
135
	protected function bd_starts_with( $haystack, $needle ) {
136
		$length = strlen( $needle );
137
138
		return ( substr( $haystack, 0, $length ) === $needle );
139
	}
140
141
	/**
142
	 * Custom string function use to get is string ends with specified string.
143
	 *
144
	 * @param string $haystack search string.
145
	 * @param string $needle   find string.
146
	 *
147
	 * @return bool.
0 ignored issues
show
Documentation Bug introduced by
The doc comment bool. at position 0 could not be parsed: Unknown type name 'bool.' at position 0 in bool..
Loading history...
148
	 */
149
	protected function bd_ends_with( $haystack, $needle ) {
150
		$length = strlen( $needle );
151
152
		return $length === 0 ||
153
		( substr( $haystack, -$length ) === $needle );
154
	}
155
156
	/**
157
	 * Get terms which is start with specified string.
158
	 *
159
	 * @param string $term_text user input text.
160
	 * @param array  $options   user options.
161
	 *
162
	 * @return array term ids.
163
	 */
164
	protected function term_starts( $term_text, $options ) {
165
		$term_ids = array();
166
		$terms    = get_terms(
167
			$options['taxonomy'], array(
168
				'hide_empty' => false,
169
			)
170
		);
171
172
		foreach ( $terms as $term ) {
173
			if ( $this->bd_starts_with( $term->name, $term_text ) ) {
174
				$term_ids[] = $term->term_id;
175
			}
176
		}
177
178
		return $term_ids;
179
	}
180
181
	/**
182
	 * Get terms which is ends with specified string.
183
	 *
184
	 * @param string $term_text user input text.
185
	 * @param array  $options   user options.
186
	 *
187
	 * @return array term ids.
188
	 */
189
	protected function term_ends( $term_text, $options ) {
190
		$term_ids = array();
191
		$terms    = get_terms(
192
			$options['taxonomy'], array(
193
				'hide_empty' => false,
194
			)
195
		);
196
197
		foreach ( $terms as $term ) {
198
			if ( $this->bd_ends_with( $term->name, $term_text ) ) {
199
				$term_ids[] = $term->term_id;
200
			}
201
		}
202
203
		return $term_ids;
204
	}
205
206
	/**
207
	 * Get terms which is contain specified string.
208
	 *
209
	 * @param string $term_text user input text.
210
	 * @param array  $options   user options.
211
	 *
212
	 * @return array term ids.
213
	 */
214
	protected function term_contains( $term_text, $options ) {
215
		$term_ids = array();
216
		$terms    = get_terms(
217
			$options['taxonomy'], array(
218
				'hide_empty' => false,
219
			)
220
		);
221
222
		foreach ( $terms as $term ) {
223
			if ( strpos( $term->name, $term_text ) !== false ) {
224
				$term_ids[] = $term->term_id;
225
			}
226
		}
227
228
		return $term_ids;
229
	}
230
231
	/**
232
	 * Get term ids which is have the sepcified post count .
233
	 *
234
	 * @param array $options user options.
235
	 *
236
	 * @return array term ids.
237
	 */
238 4
	protected function term_count_query( $options ) {
239 4
		$term_ids = array();
240 4
		$terms    = get_terms(
241 4
			$options['taxonomy'], array(
242 4
				'hide_empty' => false,
243
			)
244
		);
245
246 4
		foreach ( $terms as $term ) {
247
			$args = array(
248 4
				'post_type' => 'post',
249
				'tax_query' => array(
250
					array(
251 4
						'taxonomy' => $options['taxonomy'],
252 4
						'field'    => 'slug',
253 4
						'terms'    => $term->slug,
254
					),
255
				),
256
			);
257
258 4
			$posts = get_posts( $args );
259
260 4
			$term_ids[] = $this->get_term_id_by_name( $options['term_text'], $options['term_opt'], $term->term_id, count( $posts ) );
261
		}
262
263 4
		return $term_ids;
264
	}
265
266
	/**
267
	 * Get term id by name.
268
	 *
269
	 * @param string $term_text  user text input.
270
	 * @param array  $term_opt   user options.
271
	 * @param int    $term_id    term id.
272
	 * @param int    $post_count post count.
273
	 *
274
	 * @return int term id.
275
	 */
276 4
	protected function get_term_id_by_name( $term_text, $term_opt, $term_id, $post_count ) {
277 4
		switch ( $term_opt ) {
278 4
			case 'equal_to':
279 1
				if ( $post_count === $term_text ) {
280
					return $term_id;
281
				}
282 1
				break;
283
284 3
			case 'not_equal_to':
285 1
				if ( $post_count !== $term_text ) {
286 1
					return $term_id;
287
				}
288
				break;
289
290 2
			case 'less_than':
291 1
				if ( $post_count < $term_text ) {
292 1
					return $term_id;
293
				}
294
				break;
295
296 1
			case 'greater_than':
297 1
				if ( $post_count > $term_text ) {
298
					return $term_id;
299
				}
300 1
				break;
301
		}
302 2
	}
303
304
	/**
305
	 * Wrapper for WP_Term.
306
	 *
307
	 * Adds some performance enhancing defaults.
308
	 *
309
	 * @since  6.0
310
	 *
311
	 * @param array $options  List of options.
312
	 * @param mixed $taxonomy List of Taxonomies.
313
	 *
314
	 * @return array Result array
315
	 */
316 4
	public function term_query( $options, $taxonomy ) {
317
		$defaults = array(
318 4
			'fields'     => 'ids', // retrieve only ids.
319 4
			'taxonomy'   => $taxonomy,
320 4
			'hide_empty' => 0,
321
			'count'      => true,
322
		);
323 4
		$options  = wp_parse_args( $options, $defaults );
324
325 4
		$term_query = new \WP_Term_Query();
326
327
		/**
328
		 * This action runs before the query happens.
329
		 *
330
		 * @since 5.5
331
		 * @since 5.6 added $term_query param.
332
		 *
333
		 * @param \WP_Query $term_query Query object.
334
		 */
335 4
		do_action( 'bd_before_term_query', $term_query );
336
337 4
		$terms = $term_query->query( $options );
338
339
		/**
340
		 * This action runs after the query happens.
341
		 *
342
		 * @since 5.5
343
		 * @since 5.6 added $term_query param.
344
		 *
345
		 * @param \WP_Query $term_query Query object.
346
		 */
347 4
		do_action( 'bd_after_term_query', $term_query );
348
349 4
		return $terms;
350
	}
351
}
352