PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / trunk
GiveWP – Donation Plugin and Fundraising Platform vtrunk
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / admin / tools / data / class-give-tools-reset-stats.php
give / includes / admin / tools / data Last commit date
class-give-tools-delete-donations.php 6 years ago class-give-tools-delete-import-donors.php 6 years ago class-give-tools-delete-test-donors.php 6 years ago class-give-tools-delete-test-transactions.php 7 months ago class-give-tools-recount-all-stats.php 6 years ago class-give-tools-recount-donor-stats.php 6 years ago class-give-tools-recount-form-stats.php 5 years ago class-give-tools-recount-income.php 5 years ago class-give-tools-recount-single-donor-stats.php 6 years ago class-give-tools-reset-stats.php 9 months ago tools-actions.php 7 years ago
class-give-tools-reset-stats.php
488 lines
1 <?php
2 /**
3 * Recount income and stats
4 *
5 * This class handles batch processing of resetting donations and income stats.
6 *
7 * @subpackage Admin/Tools/Give_Tools_Reset_Stats
8 * @copyright Copyright (c) 2016, GiveWP
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_Reset_Stats Class
20 *
21 * @since 1.5
22 */
23 class Give_Tools_Reset_Stats extends Give_Batch_Export {
24
25 /**
26 * Our export type. Used for export-type specific filters/actions
27 *
28 * @var string
29 * @since 1.5
30 */
31 public $export_type = '';
32
33 /**
34 * Allows for a non-form batch processing to be run.
35 *
36 * @since 1.5
37 * @var boolean
38 */
39 public $is_void = true;
40
41 /**
42 * Sets the number of items to pull on each step
43 *
44 * @since 1.5
45 * @var integer
46 */
47 public $per_step = 30;
48
49 /**
50 * Success message to display when reset is complete
51 *
52 * @since 4.10.0
53 * @var string
54 */
55 public $message = '';
56
57 /**
58 * Constructor.
59 */
60 public function __construct( $_step = 1 ) {
61 parent::__construct( $_step );
62
63 $this->is_writable = true;
64 }
65
66 /**
67 * Get the Export Data
68 *
69 * @access public
70 * @since 4.10.0 Added deletion logic for campaigns, campaign pages, subscriptions, events, logs, revenue, usermeta, etc.
71 * @since 1.5
72 * @global object $wpdb Used to query the database using the WordPress
73 * Database API
74 * @return bool $data The data for the CSV file
75 */
76 public function get_data() {
77 global $wpdb;
78
79 $items = $this->get_stored_data( 'give_temp_reset_ids' );
80
81 if ( ! is_array( $items ) ) {
82 return false;
83 }
84
85 $offset = ( $this->step - 1 ) * $this->per_step;
86 $step_items = array_slice( $items, $offset, $this->per_step );
87
88 if ( $step_items ) {
89
90 $step_ids = [
91 'customers' => [],
92 'forms' => [],
93 'other' => [],
94 ];
95
96 foreach ( $step_items as $item ) {
97
98 switch ( $item['type'] ) {
99 case 'customer':
100 $step_ids['customers'][] = $item['id'];
101 break;
102 case 'forms':
103 $step_ids['give_forms'][] = $item['id'];
104 break;
105 default:
106 $item_type = apply_filters( 'give_reset_item_type', 'other', $item );
107 $step_ids[ $item_type ][] = $item['id'];
108 break;
109 }
110 }
111
112 $sql = [];
113 $meta_table = give_v20_bc_table_details( 'form' );
114
115 foreach ( $step_ids as $type => $ids ) {
116
117 if ( empty( $ids ) ) {
118 continue;
119 }
120
121 $ids = implode( ',', $ids );
122
123 switch ( $type ) {
124 case 'customers':
125 // Delete all the Give related donor and its meta.
126 $sql[] = "DELETE FROM {$wpdb->donors}";
127 $sql[] = "DELETE FROM {$wpdb->donormeta}";
128 break;
129 case 'forms':
130 $sql[] = "UPDATE {$meta_table['name']} SET meta_value = 0 WHERE meta_key = '_give_form_sales' AND {$meta_table['column']['id']} IN ($ids)";
131 $sql[] = "UPDATE {$meta_table['name']} SET meta_value = 0.00 WHERE meta_key = '_give_form_earnings' AND {$meta_table['column']['id']} IN ($ids)";
132 break;
133
134 case 'other':
135 // Delete main entries of forms and donations exists in posts table.
136 $sql[] = "DELETE FROM {$wpdb->posts} WHERE id IN ($ids)";
137
138 // Delete all the meta rows of form exists in form meta table.
139 $sql[] = "DELETE FROM {$wpdb->formmeta}";
140
141 // Delete all the meta rows of donation exists in donation meta table.
142 $sql[] = "DELETE FROM {$wpdb->prefix}give_donationmeta";
143
144 // Delete all the Give related sequential ordering entries for donations.
145 $sql[] = "DELETE FROM {$wpdb->prefix}give_sequential_ordering WHERE payment_id IN ($ids)";
146
147 // Delete all the Give related comments and its meta.
148 $sql[] = "DELETE FROM {$wpdb->give_comments}";
149 $sql[] = "DELETE FROM {$wpdb->give_commentmeta}";
150
151 // Delete all the Give sessions data.
152 $sql[] = "DELETE FROM {$wpdb->prefix}give_sessions";
153
154 // Delete all Give logs data.
155 $sql[] = "DELETE FROM {$wpdb->prefix}give_log";
156
157 // Delete all Give revenue data.
158 $sql[] = "DELETE FROM {$wpdb->prefix}give_revenue";
159
160 // Delete campaigns and related data
161 $sql[] = "DELETE FROM {$wpdb->prefix}give_campaign_forms";
162 $sql[] = "DELETE FROM {$wpdb->prefix}give_campaigns";
163
164 // Delete GiveWP Campaign Pages and their meta data
165 $sql[] = "DELETE FROM {$wpdb->posts} WHERE post_type = 'page' AND id IN (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = 'give_campaign_id')";
166 $sql[] = "DELETE FROM {$wpdb->postmeta} WHERE meta_key = 'give_campaign_id'";
167
168 // Delete subscriptions and related data
169 $sql[] = "DELETE FROM {$wpdb->prefix}give_subscriptionmeta";
170 $sql[] = "DELETE FROM {$wpdb->prefix}give_subscriptions";
171
172 // Delete events and related data
173 $sql[] = "DELETE FROM {$wpdb->prefix}give_event_tickets";
174 $sql[] = "DELETE FROM {$wpdb->prefix}give_event_ticket_types";
175 $sql[] = "DELETE FROM {$wpdb->prefix}give_events";
176
177 // Clear all Give user meta data (notices, preferences, etc.)
178 $sql[] = "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%give%'";
179
180 // Reset GiveWP options to default values (preserve essential ones)
181 // Essential options that must be preserved to prevent plugin deactivation issues
182 $essential_options = [
183 'give_version', // Plugin version - needed for upgrade detection
184 'give_completed_upgrades', // Completed upgrade routines - prevents re-running
185 'give_default_api_version', // API version - needed for API functionality
186 '_give_table_check', // Database table check - prevents table recreation
187 'give_temp_reset_ids', // Temporary reset data used by this class
188 'give_settings', // Plugin settings - preserve to avoid pages recreation
189 ];
190
191 // Create SQL placeholder string for the essential options list
192 $essential_options_placeholder = implode( "','", $essential_options );
193 // Delete all GiveWP options except the essential ones to prevent deactivation issues
194 $sql[] = "DELETE FROM {$wpdb->options} WHERE option_name LIKE '%give%' AND option_name NOT IN ('{$essential_options_placeholder}')";
195
196 // Clear Action Scheduler data related to GiveWP
197 $sql[] = "DELETE FROM {$wpdb->prefix}actionscheduler_actions WHERE hook LIKE '%give%'";
198 $sql[] = "DELETE FROM {$wpdb->prefix}actionscheduler_groups WHERE slug LIKE '%give%'";
199
200 // Delete Give related categories and tags data from taxonomy tables.
201 $sql[] = $wpdb->prepare(
202 "
203 DELETE FROM $wpdb->terms
204 WHERE $wpdb->terms.term_id IN
205 (
206 SELECT $wpdb->term_taxonomy.term_id
207 FROM $wpdb->term_taxonomy
208 WHERE $wpdb->term_taxonomy.taxonomy = %s
209 OR $wpdb->term_taxonomy.taxonomy = %s
210 )
211 ",
212 [ 'give_forms_category', 'give_forms_tag' ]
213 );
214
215 $sql[] = $wpdb->prepare(
216 "
217 DELETE FROM $wpdb->term_taxonomy
218 WHERE $wpdb->term_taxonomy.taxonomy = %s
219 OR $wpdb->term_taxonomy.taxonomy = %s
220 ",
221 [ 'give_forms_category', 'give_forms_tag' ]
222 );
223
224 break;
225 }
226
227 if ( ! in_array( $type, [ 'customers', 'forms', 'other' ] ) ) {
228 // Allows other types of custom post types to filter on their own post_type
229 // and add items to the query list, for the IDs found in their post type.
230 $sql = apply_filters( "give_reset_add_queries_{$type}", $sql, $ids );
231 }
232 }
233
234 if ( is_array( $sql ) && count( $sql ) > 0 ) {
235 foreach ( $sql as $query ) {
236 $wpdb->query( $query );
237 }
238 }
239
240 return true;
241
242 }// End if().
243
244 return false;
245
246 }
247
248 /**
249 * Return the calculated completion percentage.
250 *
251 * @since 4.10.0 Check if items are set before counting to prevent fatal errors on PHP 8
252 * @since 1.5
253 * @return int
254 */
255 public function get_percentage_complete() {
256
257 $items = $this->get_stored_data( 'give_temp_reset_ids' );
258 $total = $items ? count( $items ) : 0;
259
260 $percentage = 100;
261
262 if ( $total > 0 ) {
263 $percentage = ( ( $this->per_step * $this->step ) / $total ) * 100;
264 }
265
266 if ( $percentage > 100 ) {
267 $percentage = 100;
268 }
269
270 return $percentage;
271 }
272
273 /**
274 * Set the properties specific to the payments export.
275 *
276 * @since 1.5
277 *
278 * @param array $request The Form Data passed into the batch processing.
279 */
280 public function set_properties( $request ) {
281 }
282
283 /**
284 * Process a step
285 *
286 * @since 4.10.0 Updated success message
287 * @since 1.5
288 * @return bool
289 */
290 public function process_step() {
291
292 if ( ! $this->can_export() ) {
293 wp_die(
294 esc_html__( 'You do not have permission to reset data.', 'give' ),
295 esc_html__( 'Error', 'give' ),
296 [
297 'response' => 403,
298 ]
299 );
300 }
301
302 $had_data = $this->get_data();
303
304 if ( $had_data ) {
305 $this->done = false;
306
307 return true;
308 } else {
309 update_option( 'give_earnings_total', 0, false );
310 Give_Cache::delete( Give_Cache::get_key( 'give_estimated_monthly_stats' ) );
311
312 $this->delete_data( 'give_temp_reset_ids' );
313
314 $this->done = true;
315 $this->message = esc_html__( 'Successfully reset data for campaigns, campaign pages, donation forms, subscriptions, events, revenue, donation counts, logs, etc.', 'give' );
316
317 return false;
318 }
319 }
320
321 /**
322 * Headers
323 */
324 public function headers() {
325 give_ignore_user_abort();
326 }
327
328 /**
329 * Perform the export
330 *
331 * @access public
332 * @since 1.5
333 * @return void
334 */
335 public function export() {
336
337 // Set headers
338 $this->headers();
339
340 give_die();
341 }
342
343 /**
344 * Pre Fetch
345 */
346 public function pre_fetch() {
347
348 if ( $this->step == 1 ) {
349 $this->delete_data( 'give_temp_reset_ids' );
350 }
351
352 $items = get_option( 'give_temp_reset_ids', false );
353
354 if ( false === $items ) {
355 $items = [];
356
357 $give_types_for_reset = [ 'give_forms', 'give_payment' ];
358 $give_types_for_reset = apply_filters( 'give_reset_store_post_types', $give_types_for_reset );
359
360 $args = apply_filters(
361 'give_tools_reset_stats_total_args',
362 [
363 'post_type' => $give_types_for_reset,
364 'post_status' => 'any',
365 'posts_per_page' => - 1,
366 ]
367 );
368
369 $posts = get_posts( $args );
370 foreach ( $posts as $post ) {
371 $items[] = [
372 'id' => (int) $post->ID,
373 'type' => $post->post_type,
374 ];
375 }
376
377 $donor_args = [
378 'number' => - 1,
379 ];
380 $donors = Give()->donors->get_donors( $donor_args );
381 foreach ( $donors as $donor ) {
382 $items[] = [
383 'id' => (int) $donor->id,
384 'type' => 'customer',
385 ];
386 }
387
388
389 // Allow filtering of items to remove with an unassociative array for each item
390 // The array contains the unique ID of the item, and a 'type' for you to use in the execution of the get_data method
391 $items = apply_filters( 'give_reset_items', $items );
392
393 $this->store_data( 'give_temp_reset_ids', $items );
394 }// End if().
395
396 }
397
398 /**
399 * Given a key, get the information from the Database Directly.
400 *
401 * @since 1.5
402 *
403 * @param string $key The option_name
404 *
405 * @return mixed Returns the data from the database.
406 */
407 private function get_stored_data( $key ) {
408 global $wpdb;
409 $value = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", $key ) );
410
411 if ( empty( $value ) ) {
412 return false;
413 }
414
415 $maybe_json = json_decode( $value );
416 if ( ! is_null( $maybe_json ) ) {
417 $value = json_decode( $value, true );
418 }
419
420 return (array) $value;
421 }
422
423 /**
424 * Give a key, store the value.
425 *
426 * @since 1.5
427 *
428 * @param string $key The option_name.
429 * @param mixed $value The value to store.
430 *
431 * @return void
432 */
433 private function store_data( $key, $value ) {
434 global $wpdb;
435
436 $value = is_array( $value ) ? wp_json_encode( $value ) : esc_attr( $value );
437
438 $data = [
439 'option_name' => $key,
440 'option_value' => $value,
441 'autoload' => 'no',
442 ];
443
444 $formats = [
445 '%s',
446 '%s',
447 '%s',
448 ];
449
450 $wpdb->replace( $wpdb->options, $data, $formats );
451 }
452
453 /**
454 * Delete an option
455 *
456 * @since 1.5
457 *
458 * @param string $key The option_name to delete
459 *
460 * @return void
461 */
462 private function delete_data( $key ) {
463 global $wpdb;
464 $wpdb->delete(
465 $wpdb->options,
466 [
467 'option_name' => $key,
468 ]
469 );
470 }
471
472 /**
473 * Unset the properties specific to the donors export.
474 *
475 * @since 2.3.0
476 *
477 * @param array $request
478 * @param Give_Batch_Export $export
479 */
480 public function unset_properties( $request, $export ) {
481 if ( $export->done ) {
482 // Delete all the donation ids.
483 $this->delete_data( 'give_temp_reset_ids' );
484 }
485 }
486
487 }
488