Test Failed
Push — feature/update-process ( bd4647 )
by Ravinder
04:45
created

Give_DB_Meta::__rename_meta_table_name()   C

Complexity

Conditions 8
Paths 3

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 22
nc 3
nop 2
dl 0
loc 38
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/**
3
 * Give DB Meta
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_DB_Meta
7
 * @copyright   Copyright (c) 2017, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       2.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
class Give_DB_Meta extends Give_DB {
18
	/**
19
	 * Post type
20
	 *
21
	 * @since  2.0
22
	 * @access protected
23
	 * @var bool
24
	 */
25
	protected $post_type = '';
26
27
	/**
28
	 * Meta type
29
	 *
30
	 * @since  2.0
31
	 * @access protected
32
	 * @var bool
33
	 */
34
	protected $meta_type = '';
35
36
	/**
37
	 * Flag to handle result type
38
	 *
39
	 * @since  2.0
40
	 * @access protected
41
	 */
42
	protected $raw_result = false;
43
44
	/**
45
	 * Flag for short circuit of meta function
46
	 *
47
	 * @since  2.0
48
	 * @access protected
49
	 */
50
	protected $check = false;
51
52
53
	/**
54
	 * Meta supports.
55
	 *
56
	 * @since  2.0
57
	 * @access protected
58
	 * @var array
59
	 */
60
	protected $supports = array(
61
		'add_post_metadata',
62
		'get_post_metadata',
63
		'update_post_metadata',
64
		'delete_post_metadata',
65
		'posts_where',
66
		'posts_join',
67
		'posts_groupby',
68
		'posts_orderby'
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
69
	);
70
71
	/**
72
	 * Give_DB_Meta constructor.
73
	 *
74
	 * @since 2.0
75
	 */
76
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
77
		// Bailout.
78
		if ( empty( $this->supports ) || ! $this->is_custom_meta_table_active() ) {
79
			return;
80
		}
81
82
		if ( in_array( 'add_post_metadata', $this->supports ) ) {
83
			add_filter( 'add_post_metadata', array( $this, '__add_meta' ), 0, 5 );
84
		}
85
86
		if ( in_array( 'get_post_metadata', $this->supports ) ) {
87
			add_filter( 'get_post_metadata', array( $this, '__get_meta' ), 0, 4 );
88
		}
89
90
		if ( in_array( 'update_post_metadata', $this->supports ) ) {
91
			add_filter( 'update_post_metadata', array( $this, '__update_meta' ), 0, 5 );
92
		}
93
94
		if ( in_array( 'delete_post_metadata', $this->supports ) ) {
95
			add_filter( 'delete_post_metadata', array( $this, '__delete_meta' ), 0, 5 );
96
		}
97
98 View Code Duplication
		if ( in_array( 'posts_where', $this->supports ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
99
			add_filter( 'posts_where', array( $this, '__rename_meta_table_name_in_query' ), 99999, 2 );
100
		}
101
102 View Code Duplication
		if ( in_array( 'posts_join', $this->supports ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
			add_filter( 'posts_join', array( $this, '__rename_meta_table_name_in_query' ), 99999, 2 );
104
		}
105
106 View Code Duplication
		if ( in_array( 'posts_groupby', $this->supports ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
			add_filter( 'posts_groupby', array( $this, '__rename_meta_table_name_in_query' ), 99999, 2 );
108
		}
109
110 View Code Duplication
		if ( in_array( 'posts_orderby', $this->supports ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
			add_filter( 'posts_orderby', array( $this, '__rename_meta_table_name_in_query' ), 99999, 2 );
112
		}
113
	}
114
115
116
	/**
117
	 * Retrieve payment meta field for a payment.
118
	 *
119
	 * @access  public
120
	 * @since   2.0
121
	 *
122
	 * @param   int    $id       Pst Type  ID.
123
	 * @param   string $meta_key The meta key to retrieve.
124
	 * @param   bool   $single   Whether to return a single value.
125
	 *
126
	 * @return  mixed                 Will be an array if $single is false. Will be value of meta data field if $single
127
	 *                                is true.
128
	 */
129
	public function get_meta( $id = 0, $meta_key = '', $single = false ) {
130
		$id = $this->sanitize_id( $id );
131
132
		// Bailout.
133
		if ( ! $this->is_valid_post_type( $id ) ) {
134
			return $this->check;
135
		}
136
137
		if ( $this->raw_result ) {
138
			if ( ! ( $value = get_metadata( $this->meta_type, $id, $meta_key, false ) ) ) {
139
				$value = '';
140
			}
141
142
			// Reset flag.
143
			$this->raw_result = false;
144
145
		} else {
146
			$value = get_metadata( $this->meta_type, $id, $meta_key, $single );
147
		}
148
149
		return $value;
150
	}
151
152
153
	/**
154
	 * Add meta data field to a payment.
155
	 *
156
	 * For internal use only. Use Give_Payment->add_meta() for public usage.
157
	 *
158
	 * @access  private
159
	 * @since   2.0
160
	 *
161
	 * @param   int    $id         Post Type ID.
162
	 * @param   string $meta_key   Metadata name.
163
	 * @param   mixed  $meta_value Metadata value.
164
	 * @param   bool   $unique     Optional, default is false. Whether the same key should not be added.
165
	 *
166
	 * @return  int|bool                  False for failure. True for success.
167
	 */
168 View Code Duplication
	public function add_meta( $id = 0, $meta_key = '', $meta_value, $unique = false ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
169
		$id = $this->sanitize_id( $id );
170
171
		// Bailout.
172
		if ( ! $this->is_valid_post_type( $id ) ) {
173
			return $this->check;
174
		}
175
176
		$meta_id = add_metadata( $this->meta_type, $id, $meta_key, $meta_value, $unique );
177
178
		if ( $meta_id ) {
179
			$this->delete_cache( $id );
0 ignored issues
show
Bug introduced by
It seems like $id defined by $this->sanitize_id($id) on line 169 can also be of type boolean; however, Give_DB_Meta::delete_cache() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
180
		}
181
182
		return $meta_id;
183
	}
184
185
	/**
186
	 * Update payment meta field based on Post Type ID.
187
	 *
188
	 * For internal use only. Use Give_Payment->update_meta() for public usage.
189
	 *
190
	 * Use the $prev_value parameter to differentiate between meta fields with the
191
	 * same key and Post Type ID.
192
	 *
193
	 * If the meta field for the payment does not exist, it will be added.
194
	 *
195
	 * @access  public
196
	 * @since   2.0
197
	 *
198
	 * @param   int    $id         Post Type ID.
199
	 * @param   string $meta_key   Metadata key.
200
	 * @param   mixed  $meta_value Metadata value.
201
	 * @param   mixed  $prev_value Optional. Previous value to check before removing.
202
	 *
203
	 * @return  int|bool                  False on failure, true if success.
204
	 */
205 View Code Duplication
	public function update_meta( $id = 0, $meta_key = '', $meta_value, $prev_value = '' ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
206
		$id = $this->sanitize_id( $id );
207
208
		// Bailout.
209
		if ( ! $this->is_valid_post_type( $id ) ) {
210
			return $this->check;
211
		}
212
213
		$meta_id = update_metadata( $this->meta_type, $id, $meta_key, $meta_value, $prev_value );
214
215
		if ( $meta_id ) {
216
			$this->delete_cache( $id );
0 ignored issues
show
Bug introduced by
It seems like $id defined by $this->sanitize_id($id) on line 206 can also be of type boolean; however, Give_DB_Meta::delete_cache() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
217
		}
218
219
		return $meta_id;
220
	}
221
222
	/**
223
	 * Remove metadata matching criteria from a payment.
224
	 *
225
	 * You can match based on the key, or key and value. Removing based on key and
226
	 * value, will keep from removing duplicate metadata with the same key. It also
227
	 * allows removing all metadata matching key, if needed.
228
	 *
229
	 * @access  public
230
	 * @since   2.0
231
	 *
232
	 * @param   int    $id         Post Type ID.
233
	 * @param   string $meta_key   Metadata name.
234
	 * @param   mixed  $meta_value Optional. Metadata value.
235
	 * @param   mixed  $delete_all Optional.
236
	 *
237
	 * @return  bool                  False for failure. True for success.
238
	 */
239 View Code Duplication
	public function delete_meta( $id = 0, $meta_key = '', $meta_value = '', $delete_all = '' ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
240
		$id = $this->sanitize_id( $id );
241
242
		// Bailout.
243
		if ( ! $this->is_valid_post_type( $id ) ) {
244
			return $this->check;
245
		}
246
247
		$is_meta_deleted = delete_metadata( $this->meta_type, $id, $meta_key, $meta_value, $delete_all );
248
249
		if ( $is_meta_deleted ) {
250
			$this->delete_cache( $id );
0 ignored issues
show
Bug introduced by
It seems like $id defined by $this->sanitize_id($id) on line 240 can also be of type boolean; however, Give_DB_Meta::delete_cache() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
251
		}
252
253
		return $is_meta_deleted;
254
	}
255
256
	/**
257
	 * Rename query clauses of every query for new meta table
258
	 *
259
	 * @since  2.0
260
	 * @access public
261
	 *
262
	 * @param string   $clause
263
	 * @param WP_Query $wp_query
264
	 *
265
	 * @return string
266
	 */
267
	public function __rename_meta_table_name_in_query( $clause, $wp_query ) {
0 ignored issues
show
Coding Style introduced by
Method name "Give_DB_Meta::__rename_meta_table_name_in_query" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
268
		// Add new table to sql query.
269
		if ( $this->is_post_type_query( $wp_query ) && ! empty( $wp_query->meta_query->queries ) ) {
270
			$clause = $this->__rename_meta_table_name( $clause, current_filter() );
271
		}
272
273
		return $clause;
274
	}
275
276
277
	/**
278
	 * Rename query clauses for new meta table
279
	 *
280
	 * @param $clause
281
	 * @param $filter
282
	 *
283
	 * @return mixed
284
	 */
285
	public function __rename_meta_table_name( $clause, $filter ){
0 ignored issues
show
Coding Style introduced by
Method name "Give_DB_Meta::__rename_meta_table_name" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
286
		global $wpdb;
287
288
		$clause = str_replace( "{$wpdb->postmeta}.post_id", "{$this->table_name}.{$this->meta_type}_id", $clause );
289
		$clause = str_replace( $wpdb->postmeta, $this->table_name, $clause );
290
291
		switch( $filter ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
292
			case 'posts_join':
293
				$joins = array( 'INNER JOIN', 'LEFT JOIN' );
294
295
				foreach ( $joins as $join ) {
296
					if( false !== strpos( $clause, $join ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
297
						$clause = explode( $join, $clause );
298
299
						foreach ( $clause as $key => $clause_part ) {
300
							if( empty( $clause_part ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
301
								continue;
302
							}
303
304
							preg_match( '/' . $wpdb->prefix . 'give_' . $this->meta_type . 'meta AS (.*) ON/', $clause_part, $alias_table_name );
305
306
							if( isset( $alias_table_name[1] ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
307
								$clause[$key] = str_replace( "{$alias_table_name[1]}.post_id", "{$alias_table_name[1]}.{$this->meta_type}_id", $clause_part );
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
308
							}
309
						}
310
311
						$clause = implode( "{$join} ", $clause );
312
					}
313
				}
314
				break;
315
316
			case 'posts_where':
317
				$clause = str_replace( array( 'mt2.post_id', 'mt1.post_id' ), array( "mt2.{$this->meta_type}_id", "mt1.{$this->meta_type}_id" ), $clause );
318
				break;
319
		}
320
321
		return $clause;
322
	}
323
324
325
	/**
326
	 * Check if current query for post type or not.
327
	 *
328
	 * @since  2.0
329
	 * @access protected
330
	 *
331
	 * @param WP_Query $wp_query
332
	 *
333
	 * @return bool
334
	 */
335
	protected function is_post_type_query( $wp_query ) {
336
		$status = false;
337
338
		// Check if it is payment query.
339
		if ( ! empty( $wp_query->query['post_type'] ) ) {
340
			if (
341
				is_string( $wp_query->query['post_type'] ) &&
342
				$this->post_type === $wp_query->query['post_type']
343
			) {
344
				$status = true;
345
			} elseif (
346
				is_array( $wp_query->query['post_type'] ) &&
347
				in_array( $this->post_type, $wp_query->query['post_type'] )
348
			) {
349
				$status = true;
350
			}
351
		}
352
353
		return $status;
354
	}
355
356
	/**
357
	 * Check if current id of post type or not
358
	 *
359
	 * @since  2.0
360
	 * @access protected
361
	 *
362
	 * @param $ID
363
	 *
364
	 * @return bool
365
	 */
366
	protected function is_valid_post_type( $ID ) {
367
		return $ID && ( $this->post_type === get_post_type( $ID ) );
368
	}
369
370
	/**
371
	 * check if custom meta table enabled or not.
372
	 *
373
	 * @since  2.0
374
	 * @access protected
375
	 * @return bool
376
	 */
377
	protected function is_custom_meta_table_active() {
378
		return false;
379
	}
380
381
382
	/**
383
	 * Update last_changed key
384
	 *
385
	 * @since  2.0
386
	 * @access private
387
	 *
388
	 * @param int    $id
389
	 * @param string $meta_type
390
	 *
391
	 * @return void
392
	 */
393
	private function delete_cache( $id, $meta_type = '' ) {
394
		$meta_type = empty( $meta_type ) ? $this->meta_type : $meta_type;
395
396
		$group = array(
397
			// 'form'    => 'give-forms',
398
			'payment'  => 'give-donations',
399
			'donor'    => 'give-donors',
400
			'customer' => 'give-donors', // Backward compatibility for pre upgrade in 2.0
401
			// 'log'     => 'give-logs',
402
		);
403
404
		if ( array_key_exists( $meta_type, $group ) ) {
405
			Give_Cache::delete_group( $id, $group[ $meta_type ] );
406
		}
407
	}
408
409
	/**
410
	 * Add support for hidden functions.
411
	 *
412
	 * @since  2.0
413
	 * @access public
414
	 *
415
	 * @param $name
416
	 * @param $arguments
417
	 *
418
	 * @return mixed
419
	 */
420
	public function __call( $name, $arguments ) {
421
		switch ( $name ) {
422 View Code Duplication
			case '__add_meta':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
423
				$this->check = $arguments[0];
424
				$id          = $arguments[1];
425
				$meta_key    = $arguments[2];
426
				$meta_value  = $arguments[3];
427
				$unique      = $arguments[4];
428
429
				// Bailout.
430
				if ( ! $this->is_valid_post_type( $id ) ) {
431
					return $this->check;
432
				}
433
434
				return $this->add_meta( $id, $meta_key, $meta_value, $unique );
435
436
			case '__get_meta':
437
				$this->check = $arguments[0];
438
				$id          = $arguments[1];
439
				$meta_key    = $arguments[2];
440
				$single      = $arguments[3];
441
442
				// Bailout.
443
				if ( ! $this->is_valid_post_type( $id ) ) {
444
					return $this->check;
445
				}
446
447
				$this->raw_result = true;
448
449
				return $this->get_meta( $id, $meta_key, $single );
450
451
			case '__update_meta':
452
				$this->check = $arguments[0];
453
				$id          = $arguments[1];
454
				$meta_key    = $arguments[2];
455
				$meta_value  = $arguments[3];
456
457
				// Bailout.
458
				if ( ! $this->is_valid_post_type( $id ) ) {
459
					return $this->check;
460
				}
461
462
				return $this->update_meta( $id, $meta_key, $meta_value );
463
464 View Code Duplication
			case '__delete_meta':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
465
				$this->check = $arguments[0];
466
				$id          = $arguments[1];
467
				$meta_key    = $arguments[2];
468
				$meta_value  = $arguments[3];
469
				$delete_all  = $arguments[3];
470
471
				// Bailout.
472
				if ( ! $this->is_valid_post_type( $id ) ) {
473
					return $this->check;
474
				}
475
476
				return $this->delete_meta( $id, $meta_key, $meta_value, $delete_all );
477
		}
478
	}
479
}