ravinderk /
Give
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Recount single donor stats. |
||
| 4 | * |
||
| 5 | * This class handles batch processing of recounting a single donor's stats. |
||
| 6 | * |
||
| 7 | * @subpackage Admin/Tools/Give_Tools_Recount_Single_Customer_Stats |
||
| 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_Recount_Single_Customer_Stats Class |
||
| 20 | * |
||
| 21 | * @since 1.5 |
||
| 22 | */ |
||
| 23 | class Give_Tools_Recount_Single_Customer_Stats 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 = 10; |
||
| 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 | * @return bool |
||
| 53 | */ |
||
| 54 | public function get_data() { |
||
| 55 | |||
| 56 | $donor = new Give_Donor( $this->customer_id ); |
||
| 57 | $payments = $this->get_stored_data( 'give_recount_donor_payments_' . $donor->id ); |
||
| 58 | |||
| 59 | $offset = ( $this->step - 1 ) * $this->per_step; |
||
| 60 | $step_items = array_slice( $payments, $offset, $this->per_step ); |
||
| 61 | |||
| 62 | if ( count( $step_items ) > 0 ) { |
||
| 63 | $pending_total = (float) $this->get_stored_data( 'give_stats_donor_pending_total' . $donor->id ); |
||
| 64 | $step_total = 0; |
||
| 65 | |||
| 66 | $found_payment_ids = $this->get_stored_data( 'give_stats_found_payments_' . $donor->id ); |
||
| 67 | |||
| 68 | foreach ( $step_items as $payment ) { |
||
| 69 | $payment = get_post( $payment->ID ); |
||
| 70 | |||
| 71 | if ( is_null( $payment ) || is_wp_error( $payment ) || 'give_payment' !== $payment->post_type ) { |
||
| 72 | |||
| 73 | $missing_payments = $this->get_stored_data( 'give_stats_missing_payments' . $donor->id ); |
||
| 74 | $missing_payments[] = $payment->ID; |
||
| 75 | $this->store_data( 'give_stats_missing_payments' . $donor->id, $missing_payments ); |
||
| 76 | |||
| 77 | continue; |
||
| 78 | } |
||
| 79 | |||
| 80 | $should_process_payment = 'publish' == $payment->post_status ? true : false; |
||
| 81 | $should_process_payment = apply_filters( 'give_donor_recount_should_process_donation', $should_process_payment, $payment ); |
||
| 82 | |||
| 83 | if ( true === $should_process_payment ) { |
||
| 84 | |||
| 85 | $found_payment_ids[] = $payment->ID; |
||
| 86 | |||
| 87 | if ( apply_filters( 'give_donor_recount_should_increase_value', true, $payment ) ) { |
||
| 88 | $payment_amount = give_get_payment_amount( $payment->ID ); |
||
| 89 | $step_total += $payment_amount; |
||
| 90 | } |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 91 | |||
| 92 | } |
||
|
0 ignored issues
–
show
|
|||
| 93 | |||
| 94 | } |
||
| 95 | |||
| 96 | $updated_total = $pending_total + $step_total; |
||
| 97 | $this->store_data( 'give_stats_donor_pending_total' . $donor->id, $updated_total ); |
||
| 98 | $this->store_data( 'give_stats_found_payments_' . $donor->id, $found_payment_ids ); |
||
| 99 | |||
| 100 | return true; |
||
| 101 | } |
||
| 102 | |||
| 103 | return false; |
||
| 104 | |||
| 105 | } |
||
| 106 | |||
| 107 | /** |
||
| 108 | * Return the calculated completion percentage |
||
| 109 | * |
||
| 110 | * @since 1.5 |
||
| 111 | * @return int |
||
| 112 | */ |
||
| 113 | public function get_percentage_complete() { |
||
| 114 | |||
| 115 | $payments = $this->get_stored_data( 'give_recount_donor_payments_' . $this->customer_id ); |
||
| 116 | $total = count( $payments ); |
||
| 117 | |||
| 118 | $percentage = 100; |
||
| 119 | |||
| 120 | if ( $total > 0 ) { |
||
| 121 | $percentage = ( ( $this->per_step * $this->step ) / $total ) * 100; |
||
| 122 | } |
||
| 123 | |||
| 124 | if ( $percentage > 100 ) { |
||
| 125 | $percentage = 100; |
||
| 126 | } |
||
| 127 | |||
| 128 | return $percentage; |
||
| 129 | } |
||
| 130 | |||
| 131 | /** |
||
| 132 | * Set the properties specific to the payments export |
||
| 133 | * |
||
| 134 | * @since 1.5 |
||
| 135 | * |
||
| 136 | * @param array $request The Form Data passed into the batch processing |
||
| 137 | */ |
||
| 138 | public function set_properties( $request ) { |
||
| 139 | $this->customer_id = isset( $request['customer_id'] ) ? sanitize_text_field( $request['customer_id'] ) : false; |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * Process a step |
||
| 144 | * |
||
| 145 | * @since 1.5 |
||
| 146 | * @return bool |
||
| 147 | */ |
||
| 148 | public function process_step() { |
||
| 149 | |||
| 150 | if ( ! $this->can_export() ) { |
||
| 151 | wp_die( esc_html__( 'You do not have permission to recount stats.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) ); |
||
| 152 | } |
||
| 153 | |||
| 154 | $had_data = $this->get_data(); |
||
| 155 | |||
| 156 | if ( $had_data ) { |
||
| 157 | $this->done = false; |
||
| 158 | |||
| 159 | return true; |
||
| 160 | } else { |
||
| 161 | $donor = new Give_Donor( $this->customer_id ); |
||
| 162 | $payment_ids = get_option( 'give_stats_found_payments_' . $donor->id, array() ); |
||
| 163 | $this->delete_data( 'give_stats_found_payments_' . $donor->id ); |
||
| 164 | |||
| 165 | $removed_payments = array_unique( get_option( 'give_stats_missing_payments' . $donor->id, array() ) ); |
||
| 166 | |||
| 167 | // Find non-existing payments (deleted) and total up the donation count |
||
| 168 | $purchase_count = 0; |
||
| 169 | foreach ( $payment_ids as $key => $payment_id ) { |
||
| 170 | if ( in_array( $payment_id, $removed_payments ) ) { |
||
| 171 | unset( $payment_ids[ $key ] ); |
||
| 172 | continue; |
||
| 173 | } |
||
| 174 | |||
| 175 | $payment = get_post( $payment_id ); |
||
| 176 | if ( apply_filters( 'give_donor_recount_should_increase_count', true, $payment ) ) { |
||
| 177 | $purchase_count ++; |
||
| 178 | } |
||
| 179 | } |
||
| 180 | |||
| 181 | $this->delete_data( 'give_stats_missing_payments' . $donor->id ); |
||
| 182 | |||
| 183 | $pending_total = $this->get_stored_data( 'give_stats_donor_pending_total' . $donor->id ); |
||
| 184 | $this->delete_data( 'give_stats_donor_pending_total' . $donor->id ); |
||
| 185 | $this->delete_data( 'give_recount_donor_stats_' . $donor->id ); |
||
| 186 | $this->delete_data( 'give_recount_donor_payments_' . $this->customer_id ); |
||
| 187 | |||
| 188 | $payment_ids = implode( ',', $payment_ids ); |
||
| 189 | $donor->update( array( |
||
| 190 | 'payment_ids' => $payment_ids, |
||
| 191 | 'purchase_count' => $purchase_count, |
||
| 192 | 'purchase_value' => $pending_total, |
||
| 193 | ) ); |
||
| 194 | |||
| 195 | $this->done = true; |
||
| 196 | $this->message = esc_html__( 'Donor stats have been successfully recounted.', 'give' ); |
||
| 197 | |||
| 198 | return false; |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | View Code Duplication | public function headers() { |
|
|
0 ignored issues
–
show
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...
|
|||
| 203 | ignore_user_abort( true ); |
||
| 204 | |||
| 205 | if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { |
||
| 206 | set_time_limit( 0 ); |
||
| 207 | } |
||
| 208 | } |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Perform the export |
||
| 212 | * |
||
| 213 | * @access public |
||
| 214 | * @since 1.5 |
||
| 215 | * @return void |
||
| 216 | */ |
||
| 217 | public function export() { |
||
| 218 | |||
| 219 | // Set headers |
||
| 220 | $this->headers(); |
||
| 221 | |||
| 222 | give_die(); |
||
| 223 | } |
||
| 224 | |||
| 225 | /** |
||
| 226 | * Zero out the data on step one |
||
| 227 | * |
||
| 228 | * @access public |
||
| 229 | * @since 1.5 |
||
| 230 | * @return void |
||
| 231 | */ |
||
| 232 | public function pre_fetch() { |
||
| 233 | if ( $this->step === 1 ) { |
||
|
0 ignored issues
–
show
|
|||
| 234 | $allowed_payment_status = apply_filters( 'give_recount_donors_donation_statuses', give_get_payment_status_keys() ); |
||
| 235 | |||
| 236 | // Before we start, let's zero out the customer's data |
||
| 237 | $donor = new Give_Donor( $this->customer_id ); |
||
| 238 | $donor->update( array( 'purchase_value' => give_format_amount( 0, array( 'sanitize' => false ) ), 'purchase_count' => 0 ) ); |
||
| 239 | |||
| 240 | $attached_payment_ids = explode( ',', $donor->payment_ids ); |
||
| 241 | |||
| 242 | $attached_args = array( |
||
| 243 | 'post__in' => $attached_payment_ids, |
||
| 244 | 'number' => - 1, |
||
| 245 | 'status' => $allowed_payment_status, |
||
| 246 | ); |
||
| 247 | |||
| 248 | $attached_payments = give_get_payments( $attached_args ); |
||
| 249 | |||
| 250 | $unattached_args = array( |
||
| 251 | 'post__not_in' => $attached_payment_ids, |
||
| 252 | 'number' => - 1, |
||
| 253 | 'status' => $allowed_payment_status, |
||
| 254 | 'meta_query' => array( |
||
|
0 ignored issues
–
show
|
|||
| 255 | array( |
||
| 256 | 'key' => '_give_payment_user_email', |
||
| 257 | 'value' => $donor->email, |
||
| 258 | ), |
||
| 259 | ), |
||
| 260 | ); |
||
| 261 | |||
| 262 | $unattached_payments = give_get_payments( $unattached_args ); |
||
| 263 | |||
| 264 | $payments = array_merge( $attached_payments, $unattached_payments ); |
||
| 265 | |||
| 266 | $this->store_data( 'give_recount_donor_payments_' . $donor->id, $payments ); |
||
| 267 | } |
||
| 268 | } |
||
| 269 | |||
| 270 | /** |
||
| 271 | * Given a key, get the information from the Database Directly |
||
| 272 | * |
||
| 273 | * @since 1.5 |
||
| 274 | * |
||
| 275 | * @param string $key The option_name |
||
| 276 | * |
||
| 277 | * @return mixed Returns the data from the database |
||
| 278 | */ |
||
| 279 | private function get_stored_data( $key ) { |
||
| 280 | global $wpdb; |
||
| 281 | $value = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = '%s'", $key ) ); |
||
|
0 ignored issues
–
show
|
|||
| 282 | |||
| 283 | return empty( $value ) ? false : maybe_unserialize( $value ); |
||
| 284 | } |
||
| 285 | |||
| 286 | /** |
||
| 287 | * Give a key, store the value |
||
| 288 | * |
||
| 289 | * @since 1.5 |
||
| 290 | * |
||
| 291 | * @param string $key The option_name |
||
| 292 | * @param mixed $value The value to store |
||
| 293 | * |
||
| 294 | * @return void |
||
| 295 | */ |
||
| 296 | View Code Duplication | private function store_data( $key, $value ) { |
|
|
0 ignored issues
–
show
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...
|
|||
| 297 | global $wpdb; |
||
| 298 | |||
| 299 | $value = maybe_serialize( $value ); |
||
| 300 | |||
| 301 | $data = array( |
||
| 302 | 'option_name' => $key, |
||
| 303 | 'option_value' => $value, |
||
| 304 | 'autoload' => 'no', |
||
| 305 | ); |
||
| 306 | |||
| 307 | $formats = array( |
||
| 308 | '%s', |
||
| 309 | '%s', |
||
| 310 | '%s', |
||
| 311 | ); |
||
| 312 | |||
| 313 | $wpdb->replace( $wpdb->options, $data, $formats ); |
||
|
0 ignored issues
–
show
|
|||
| 314 | } |
||
| 315 | |||
| 316 | /** |
||
| 317 | * Delete an option |
||
| 318 | * |
||
| 319 | * @since 1.5 |
||
| 320 | * |
||
| 321 | * @param string $key The option_name to delete |
||
| 322 | * |
||
| 323 | * @return void |
||
| 324 | */ |
||
| 325 | private function delete_data( $key ) { |
||
| 326 | global $wpdb; |
||
| 327 | $wpdb->delete( $wpdb->options, array( 'option_name' => $key ) ); |
||
| 328 | } |
||
| 329 | |||
| 330 | } |
||
| 331 |