Test Failed
Push — backup/issues/1132 ( b1d18b )
by Ravinder
05:29
created

Give_Tools_Delete_Test_Transactions   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 305
Duplicated Lines 18.03 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 55
loc 305
rs 9.8
c 0
b 0
f 0
wmc 31
lcom 1
cbo 3

10 Methods

Rating   Name   Duplication   Size   Complexity  
C get_data() 0 74 11
A get_percentage_complete() 0 17 3
A set_properties() 0 2 1
B process_step() 29 29 4
A headers() 7 7 3
A export() 0 7 1
B pre_fetch() 0 37 4
A get_stored_data() 0 6 2
A store_data() 19 19 1
A delete_data() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Delete Test Transactions
4
 *
5
 * This class handles batch processing of deleting test transactions
6
 *
7
 * @subpackage  Admin/Tools/Give_Tools_Delete_Test_Transactions
8
 * @copyright   Copyright (c) 2016, WordImpress
9
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
10
 * @since       1.5
11
 */
12
13
// Exit if accessed directly.
14
if ( ! defined( 'ABSPATH' ) ) {
15
	exit;
16
}
17
18
/**
19
 * Give_Tools_Delete_Test_Transactions Class
20
 *
21
 * @since 1.5
22
 */
23
class Give_Tools_Delete_Test_Transactions extends Give_Batch_Export {
24
25
	/**
26
	 * Our export type. Used for export-type specific filters/actions
27
	 * @var string
28
	 * @since 1.5
29
	 */
30
	public $export_type = '';
31
32
	/**
33
	 * Allows for a non-form batch processing to be run.
34
	 * @since  1.5
35
	 * @var boolean
36
	 */
37
	public $is_void = true;
38
39
	/**
40
	 * Sets the number of items to pull on each step
41
	 * @since  1.5
42
	 * @var integer
43
	 */
44
	public $per_step = 30;
45
46
	/**
47
	 * Get the Export Data
48
	 *
49
	 * @access public
50
	 * @since 1.5
51
	 * @global object $wpdb Used to query the database using the WordPress Database API
52
	 *
53
	 * @return array|bool $data The data for the CSV file
54
	 */
55
	public function get_data() {
56
		global $wpdb;
57
58
		$items = $this->get_stored_data( 'give_temp_delete_test_ids' );
59
60
		if ( ! is_array( $items ) ) {
61
			return false;
62
		}
63
64
		$offset     = ( $this->step - 1 ) * $this->per_step;
65
		$step_items = array_slice( $items, $offset, $this->per_step );
66
		$meta_table = __give_v20_bc_table_details( 'payment' );
67
68
		if ( $step_items ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $step_items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
69
70
			$step_ids = array(
71
				'other' => array(),
72
			);
73
74
			foreach ( $step_items as $item ) {
75
76
				$step_ids['other'][] = $item['id'];
77
78
			}
79
80
			$sql = array();
81
82
			foreach ( $step_ids as $type => $ids ) {
83
84
				if ( empty( $ids ) ) {
85
					continue;
86
				}
87
88
				$parent_query = '';
0 ignored issues
show
Unused Code introduced by
$parent_query is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
89
90
				switch ( $type ) {
91
					case 'other':
92
93
						$temp_ids = implode( ',', $ids );
94
95
						// Get all the test logs of the donations ids.
96
						$parent_query = "SELECT DISTINCT post_id as id FROM $wpdb->postmeta WHERE meta_key = '_give_log_payment_id' AND meta_value IN ( $temp_ids )";
97
						$parent_ids   = $wpdb->get_results( $parent_query, 'ARRAY_A' );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
98
99
						// List of all test logs.
100
						if ( $parent_ids ) {
101
							foreach ( $parent_ids as $parent_id ) {
102
								// Adding all the test log in post ids that are going to get deleted.
103
								$ids[] = $parent_id['id'];
104
							}
105
						}
106
						$ids = implode( ',', $ids );
107
108
						$sql[] = "DELETE FROM $wpdb->posts WHERE id IN ($ids)";
109
						$sql[] = "DELETE FROM {$meta_table['name']} WHERE {$meta_table['column']['id']} IN ($ids)";
110
						$sql[] = "DELETE FROM $wpdb->comments WHERE comment_post_ID IN ($ids)";
111
						$sql[] = "DELETE FROM $wpdb->commentmeta WHERE comment_id NOT IN (SELECT comment_ID FROM $wpdb->comments)";
112
						break;
113
				}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
114
115
			}
116
117
			if ( ! empty( $sql ) ) {
118
				foreach ( $sql as $query ) {
119
					$wpdb->query( $query );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
120
				}
121
				do_action( 'give_delete_log_cache' );
122
			}
123
124
			return true;
125
		}
126
127
		return false;
128
	}
129
130
	/**
131
	 * Return the calculated completion percentage
132
	 *
133
	 * @since 1.5
134
	 * @return int
135
	 */
136
	public function get_percentage_complete() {
137
138
		$items = $this->get_stored_data( 'give_temp_delete_test_ids', false );
0 ignored issues
show
Unused Code introduced by
The call to Give_Tools_Delete_Test_T...ions::get_stored_data() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
139
		$total = count( $items );
140
141
		$percentage = 100;
142
143
		if ( $total > 0 ) {
144
			$percentage = ( ( $this->per_step * $this->step ) / $total ) * 100;
145
		}
146
147
		if ( $percentage > 100 ) {
148
			$percentage = 100;
149
		}
150
151
		return $percentage;
152
	}
153
154
	/**
155
	 * Set the properties specific to the payments export
156
	 *
157
	 * @since 1.5
158
	 *
159
	 * @param array $request The Form Data passed into the batch processing
160
	 */
161
	public function set_properties( $request ) {
162
	}
163
164
	/**
165
	 * Process a step
166
	 *
167
	 * @since 1.5
168
	 * @return bool
169
	 */
170 View Code Duplication
	public function process_step() {
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...
171
172
		if ( ! $this->can_export() ) {
173
			wp_die( __( 'You do not have permission to delete test transactions.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
174
		}
175
176
		$had_data = $this->get_data();
177
178
		if ( $had_data ) {
179
			$this->done = false;
180
181
			return true;
182
		} else {
183
			update_option( 'give_earnings_total', give_get_total_earnings( true ) );
184
			Give_Cache::delete( Give_Cache::get_key( 'give_estimated_monthly_stats' ) );
185
186
			$this->delete_data( 'give_temp_delete_test_ids' );
187
188
			// Reset the sequential order numbers
189
			if ( give_get_option( 'enable_sequential' ) ) {
190
				delete_option( 'give_last_payment_number' );
191
			}
192
193
			$this->done    = true;
194
			$this->message = __( 'Test transactions successfully deleted.', 'give' );
195
196
			return false;
197
		}
198
	}
199
200
	/**
201
	 * Headers
202
	 */
203 View Code Duplication
	public function headers() {
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...
204
		ignore_user_abort( true );
205
206
		if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
207
			set_time_limit( 0 );
208
		}
209
	}
210
211
	/**
212
	 * Perform the export
213
	 *
214
	 * @access public
215
	 * @since 1.5
216
	 * @return void
217
	 */
218
	public function export() {
219
220
		// Set headers
221
		$this->headers();
222
223
		give_die();
224
	}
225
226
	/**
227
	 * Pre Fetch
228
	 */
229
	public function pre_fetch() {
230
231
		if ( $this->step == 1 ) {
0 ignored issues
show
introduced by
Found "== 1". Use Yoda Condition checks, you must
Loading history...
232
			$this->delete_data( 'give_temp_delete_test_ids' );
233
		}
234
235
		$items = get_option( 'give_temp_delete_test_ids', false );
236
237
		if ( false === $items ) {
238
			$items = array();
239
240
			$args = apply_filters( 'give_tools_reset_stats_total_args', array(
241
				'post_status' => 'any',
242
				'number'      => - 1,
243
				'meta_key'    => '_give_payment_mode',
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
244
				'meta_value'  => 'test'
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
introduced by
Each line in an array declaration must end in a comma
Loading history...
245
			) );
246
247
			$posts    = new Give_Payments_Query( $args );
248
			$payments = $posts->get_payments();
249
250
			/* @var Give_Payment $payment */
251
			foreach ( $payments as $payment ) {
252
				$items[] = array(
253
					'id'   => (int) $payment->ID,
254
					'type' => 'give_payment',
255
				);
256
			}
257
			
258
			// Allow filtering of items to remove with an unassociative array for each item.
259
			// The array contains the unique ID of the item, and a 'type' for you to use in the execution of the get_data method.
260
			$items = apply_filters( 'give_delete_test_items', $items );
261
262
			$this->store_data( 'give_temp_delete_test_ids', $items );
263
		}
264
265
	}
266
267
	/**
268
	 * Given a key, get the information from the Database Directly
269
	 *
270
	 * @since  1.5
271
	 *
272
	 * @param  string $key The option_name
273
	 *
274
	 * @return mixed       Returns the data from the database
275
	 */
276
	private function get_stored_data( $key ) {
277
		global $wpdb;
278
		$value = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = '%s'", $key ) );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
279
280
		return empty( $value ) ? false : maybe_unserialize( $value );
281
	}
282
283
	/**
284
	 * Give a key, store the value
285
	 *
286
	 * @since  1.5
287
	 *
288
	 * @param  string $key The option_name
289
	 * @param  mixed $value The value to store
290
	 *
291
	 * @return void
292
	 */
293 View Code Duplication
	private function store_data( $key, $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...
294
		global $wpdb;
295
296
		$value = maybe_serialize( $value );
297
298
		$data = array(
299
			'option_name'  => $key,
300
			'option_value' => $value,
301
			'autoload'     => 'no',
302
		);
303
304
		$formats = array(
305
			'%s',
306
			'%s',
307
			'%s',
308
		);
309
310
		$wpdb->replace( $wpdb->options, $data, $formats );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
311
	}
312
313
	/**
314
	 * Delete an option
315
	 *
316
	 * @since  1.5
317
	 *
318
	 * @param  string $key The option_name to delete
319
	 *
320
	 * @return void
321
	 */
322
	private function delete_data( $key ) {
323
		global $wpdb;
324
		$wpdb->delete( $wpdb->options, array( 'option_name' => $key ) );
325
	}
326
327
}
328