PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.16.1
GiveWP – Donation Plugin and Fundraising Platform v4.16.1
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 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 All 256 releases
give / includes / payments / class-give-sequential-donation-number.php

class-give-sequential-donation-number.php in GiveWP – Donation Plugin and Fundraising Platform 4.16.1, at includes/payments/class-give-sequential-donation-number.php

389 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if access directly.
3 use Give\Framework\Database\DB;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 class Give_Sequential_Donation_Number {
10 /**
11 * Instance.
12 *
13 * @since 2.1.0
14 * @access private
15 * @var
16 */
17 private static $instance;
18
19 /**
20 * Donation tile prefix
21 *
22 * @since 2.1.0
23 * @var string
24 */
25 private $donation_title_prefix = 'give-donation-';
26
27 /**
28 * Singleton pattern.
29 *
30 * @since 2.1.0
31 * @access private
32 */
33 private function __construct() {
34 }
35
36
37 /**
38 * Get instance.
39 *
40 * @since 2.1.0
41 * @access public
42 * @return Give_Sequential_Donation_Number
43 */
44 public static function get_instance() {
45 if ( null === static::$instance ) {
46 self::$instance = new static();
47
48 self::$instance->init();
49 }
50
51 return self::$instance;
52 }
53
54 /**
55 * Initialize the plugin, bailing if any required conditions are not met,
56 * including minimum WooCommerce version
57 *
58 * @since 2.1.0
59 */
60 public function init() {
61 add_action('wp_insert_post', array($this, 'save_donation_title'), 10, 3);
62 add_action('after_delete_post', array($this, 'remove_serial_number'), 10, 1);
63 }
64
65 /**
66 * Set serialize donation number as donation title.
67 * Note: only for internal use
68 *
69 * @since 4.9.0 rename function - PHP 8 compatibility
70 * @since 3.0.0 replace wp_update_post with DB::update to avoid affecting the post update date and invalidating the donation model's updatedAt date
71 * @since 2.1.0
72 * @access public
73 *
74 * @param int $donation_id
75 * @param WP_Post $post
76 * @param bool $existing_donation_updated
77 *
78 * @return void
79 */
80 public function save_donation_title( $donation_id, $post, $existing_donation_updated ) {
81 // Bailout
82 if (
83 ! give_is_setting_enabled( give_get_option( 'sequential-ordering_status', 'disabled' ) )
84 || $existing_donation_updated
85 || 'give_payment' !== $post->post_type
86 ) {
87 return;
88 }
89
90 $serial_number = $this->set_donation_number( $donation_id );
91 $serial_code = $this->set_number_padding( $serial_number );
92
93 // Add prefix.
94 if ( $prefix = give_get_option( 'sequential-ordering_number_prefix', '' ) ) {
95 $serial_code = $prefix . $serial_code;
96 }
97
98 // Add suffix.
99 if ( $suffix = give_get_option( 'sequential-ordering_number_suffix', '' ) ) {
100 $serial_code = $serial_code . $suffix;
101 }
102
103 /**
104 * Filter the donation number
105 *
106 * @since 2.1.0
107 */
108 $serial_code = apply_filters(
109 'give_set_sequential_donation_title',
110 give_time_do_tags( $serial_code ),
111 $donation_id,
112 $post,
113 $existing_donation_updated,
114 array(
115 $serial_number,
116 $prefix,
117 $suffix,
118 )
119 );
120
121 try {
122 DB::table('posts')
123 ->where('ID', $donation_id)
124 ->update([
125 'post_title' => trim($serial_code),
126 'post_name' => "{$this->donation_title_prefix}-{$serial_number}",
127 ]);
128 clean_post_cache($donation_id);
129
130 give_update_option( 'sequential-ordering_number', ( $serial_number + 1 ) );
131 } catch ( Exception $e ) {
132 error_log( "GiveWP caught exception: {$e->getMessage()}" );
133 }
134 }
135
136 /**
137 * Set donation number
138 * Note: only for internal use
139 *
140 * @since 4.9.0 rename function - PHP 8 compatibility
141 * @since 2.1.0
142 * @access public
143 *
144 * @param int $donation_id
145 *
146 * @return int
147 */
148 public function set_donation_number( $donation_id ) {
149 $table_data = array(
150 'payment_id' => $donation_id,
151 );
152
153 // Customize sequential donation number starting point if needed.
154 if (
155 get_option( '_give_reset_sequential_number' ) &&
156 ( $number = give_get_option( 'sequential-ordering_number', 0 ) )
157 ) {
158 if ( Give()->sequential_donation_db->get_id_auto_increment_val() <= $number ) {
159 delete_option( '_give_reset_sequential_number' );
160 }
161
162 $table_data['id'] = $number;
163 }
164
165 /**
166 * Filter the donation number
167 *
168 * @since 2.1
169 */
170 return apply_filters(
171 'give_set_sequential_donation_number',
172 Give()->sequential_donation_db->insert( $table_data ),
173 $table_data
174 );
175 }
176
177
178 /**
179 * Remove sequential donation data
180 * Note: only internal use.
181 *
182 * @since 4.9.0 rename function - PHP 8 compatibility
183 * @since 2.1.0
184 * @access public
185 *
186 * @param $donation_id
187 *
188 * @return bool
189 */
190 public function remove_serial_number( $donation_id ) {
191 return Give()->sequential_donation_db->delete( $this->get_serial_number( $donation_id ) );
192 }
193
194 /**
195 * Set number padding in serial code.
196 *
197 * @since
198 * @access public
199 *
200 * @param $serial_number
201 *
202 * @return string
203 */
204 public function set_number_padding( $serial_number ) {
205 if ( $number_padding = give_get_option( 'sequential-ordering_number_padding', 0 ) ) {
206 $serial_number = str_pad( $serial_number, $number_padding, '0', STR_PAD_LEFT );
207 }
208
209 return $serial_number;
210 }
211
212 /**
213 * Get donation number serial code
214 *
215 * @since 2.1.0
216 * @access public
217 *
218 * @param int|Give_Payment|WP_Post $donation
219 * @param array $args
220 *
221 * @return string
222 */
223 public function get_serial_code( $donation, $args = array() ) {
224 // Get id from object.
225 if ( ! is_numeric( $donation ) ) {
226 if ( $donation instanceof Give_Payment ) {
227 $donation = $donation->ID;
228 } elseif ( $donation instanceof WP_Post ) {
229 $donation = $donation->ID;
230 }
231 }
232
233 // Set default params.
234 $args = wp_parse_args(
235 $args,
236 array(
237 'with_hash' => false,
238 'default' => true,
239 )
240 );
241
242 $serial_code = $args['default'] ? $donation : '';
243
244 if ( $donation_number = $this->get_serial_number( $donation ) ) {
245 $serial_code = get_the_title( $donation );
246 }
247
248 $serial_code = $args['with_hash'] ? "#{$serial_code}" : $serial_code;
249
250 /**
251 * Filter the donation serial code
252 *
253 * @since 2.1.0
254 *
255 * @param string $serial_code
256 * @param string $donation Donation ID
257 * @param array $args
258 * @param string $donation_number
259 */
260 return apply_filters( 'give_get_donation_serial_code', $serial_code, $donation, $args, $donation_number );
261 }
262
263 /**
264 * Get serial number
265 *
266 * @since 2.1.0
267 * @access public
268 *
269 * @param int $donation_id_or_serial_code
270 *
271 * @return string
272 */
273 public function get_serial_number( $donation_id_or_serial_code ) {
274 if ( is_numeric( $donation_id_or_serial_code ) ) {
275 return Give()->sequential_donation_db->get_column_by( 'id', 'payment_id', $donation_id_or_serial_code );
276 }
277
278 return $this->get_serial_number( $this->get_donation_id( $donation_id_or_serial_code ) );
279 }
280
281
282 /**
283 * Get donation id with donation number or serial code
284 *
285 * @since 2.1.0
286 * @access public
287 *
288 * @param string $donation_number_or_serial_code
289 *
290 * @return string
291 */
292 public function get_donation_id( $donation_number_or_serial_code ) {
293 global $wpdb;
294
295 if ( is_numeric( $donation_number_or_serial_code ) ) {
296 return Give()->sequential_donation_db->get_column_by(
297 'payment_id',
298 'id',
299 $donation_number_or_serial_code
300 );
301 }
302
303 return $wpdb->get_var(
304 $wpdb->prepare(
305 "
306 SELECT ID
307 FROM $wpdb->posts
308 WHERE post_title=%s
309 ",
310 $donation_number_or_serial_code
311 )
312 );
313 }
314
315 /**
316 * Get maximum donation number
317 *
318 * @since 2.1.0
319 * @access public
320 *
321 * @return int
322 */
323 public function get_max_number() {
324 global $wpdb;
325 $table_name = Give()->sequential_donation_db->table_name;
326
327 return absint(
328 $wpdb->get_var(
329 "
330 SELECT ID
331 FROM {$table_name}
332 ORDER BY id DESC
333 LIMIT 1
334 "
335 )
336 );
337 }
338
339 /**
340 * Get maximum donation id
341 *
342 * @since 2.1.0
343 * @access public
344 *
345 * @return int
346 */
347 public function get_max_donation_id() {
348 global $wpdb;
349
350 return absint(
351 $wpdb->get_var(
352 $wpdb->prepare(
353 "
354 SELECT ID
355 FROM {$wpdb->posts}
356 WHERE post_type=%s
357 AND post_status=%s
358 ORDER BY id DESC
359 LIMIT 1
360 ",
361 'give_payment',
362 'publish'
363 )
364 )
365 );
366 }
367
368 /**
369 * Get maximum donation number
370 *
371 * @since 2.1.0
372 * @access public
373 *
374 * @return int
375 */
376 public function get_next_number() {
377 $donation_id = $this->get_max_donation_id();
378 $next_number = $this->get_max_number();
379
380 if ( ! $this->get_serial_number( $donation_id ) ) {
381 $next_number = $donation_id && ( $next_number < $donation_id ) ?
382 $donation_id :
383 $this->get_max_number();
384 }
385
386 return ( $next_number + 1 );
387 }
388 }
389