Completed
Branch BETA-4.9-message-activity (793322)
by
unknown
18:25 queued 10s
created

EE_Cron_Tasks   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 361
Duplicated Lines 15.24 %

Coupling/Cohesion

Components 3
Dependencies 11

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 37
c 1
b 0
f 0
lcom 3
cbo 11
dl 55
loc 361
rs 8.6

10 Methods

Rating   Name   Duplication   Size   Complexity  
A instance() 0 6 2
B __construct() 0 39 4
C log_scheduled_ee_crons() 0 23 7
A schedule_update_transaction_with_payment() 17 17 3
A setup_update_for_transaction_with_payment() 11 11 2
B update_transaction_with_payment() 0 32 6
A schedule_finalize_abandoned_transactions_check() 16 16 3
A check_for_abandoned_transactions() 11 11 2
B finalize_abandoned_transactions() 0 37 6
A clean_out_junk_transactions() 0 7 2

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 if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); }
2
/**
3
 *
4
 * Class EE_Cron_Tasks
5
 *
6
 * @package 			Event Espresso
7
 * @subpackage 	core
8
 * @author 				Brent Christensen
9
 *
10
 */
11
class EE_Cron_Tasks extends EE_BASE {
12
13
	/**
14
	 * WordPress doesn't allow duplicate crons within 10 minutes of the original,
15
	 * so we'll set our retry time for just over 10 minutes to avoid that
16
	 */
17
	const reschedule_timeout = 605;
18
19
20
	/**
21
	 * @var EE_Cron_Tasks
22
	 */
23
	private static $_instance;
24
25
26
27
	/**
28
	 * @return EE_Cron_Tasks
29
	 */
30
	public static function instance() {
31
		if ( ! self::$_instance instanceof EE_Cron_Tasks ) {
32
			self::$_instance = new self();
33
		}
34
		return self::$_instance;
35
	}
36
37
38
39
	/**
40
	 * @access private
41
	 * @return EE_Cron_Tasks
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
42
	 */
43
	private function __construct() {
44
		do_action( 'AHEE_log', __CLASS__, __FUNCTION__ );
45
		// verify that WP Cron is enabled
46
		if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON && is_admin() ) {
47
			EE_Error::add_persistent_admin_notice(
48
				'wp_cron_disabled',
49
				sprintf(
50
					__(
51
						'Event Espresso has detected that wp_cron is disabled. It\'s important that wp_cron is enabled because Event Espresso depends on wp_cron for critical scheduled tasks.%1$sSince it\'s possible that your site may have an alternative task scheduler set up, we strongly suggest that you inform the website host, or developer that set up the site, about this issue.',
52
						'event_espresso'
53
					),
54
					'<br />'
55
				)
56
			);
57
		}
58
		// UPDATE TRANSACTION WITH PAYMENT
59
		add_action(
60
			'AHEE__EE_Cron_Tasks__update_transaction_with_payment_2',
61
			array( 'EE_Cron_Tasks', 'setup_update_for_transaction_with_payment' ),
62
			10, 2
63
		);
64
		// FINALIZE ABANDONED TRANSACTIONS
65
		add_action(
66
			'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions',
67
			array( 'EE_Cron_Tasks', 'check_for_abandoned_transactions' ),
68
			10, 1
69
		);
70
		// CLEAN OUT JUNK TRANSACTIONS AND RELATED DATA
71
		add_action(
72
				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
73
				array( 'EE_Cron_Tasks', 'clean_out_junk_transactions' )
74
		);
75
		// logging
76
		add_action(
77
			'AHEE__EE_System__load_core_configuration__complete',
78
			array( 'EE_Cron_Tasks', 'log_scheduled_ee_crons' )
79
		);
80
		EE_Registry::instance()->load_lib( 'Messages_Scheduler' );
81
	}
82
83
84
85
	/**
86
	 * @access protected
87
	 * @return void
88
	 */
89
	public static function log_scheduled_ee_crons() {
90
		$ee_crons = array(
91
			'AHEE__EE_Cron_Tasks__update_transaction_with_payment',
92
			'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions',
93
			'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
94
		);
95
		$crons = get_option( 'cron' );
96
		if ( ! is_array( $crons ) ) {
97
			return;
98
		}
99
		foreach ( $crons as $timestamp => $cron ) {
100
			foreach ( $ee_crons as $ee_cron ) {
101
				if ( isset( $cron[ $ee_cron ] ) ) {
102
					do_action( 'AHEE_log', __CLASS__, __FUNCTION__, $ee_cron, 'scheduled EE cron' );
103
					foreach ( $cron[ $ee_cron ] as $ee_cron_details ) {
104
						if ( ! empty( $ee_cron_details[ 'args' ] )) {
105
							do_action( 'AHEE_log', __CLASS__, __FUNCTION__, print_r( $ee_cron_details[ 'args' ], true ), "$ee_cron args" );
106
						}
107
					}
108
				}
109
			}
110
		}
111
	}
112
113
114
115
116
	/****************  UPDATE TRANSACTION WITH PAYMENT ****************/
117
118
119
	/**
120
	 * array of TXN IDs and the payment
121
	 * @var array
122
	 */
123
	protected static $_update_transactions_with_payment = array();
124
125
126
127
	/**
128
	 * schedule_update_transaction_with_payment
129
	 *
130
	 * sets a wp_schedule_single_event() for updating any TXNs that may
131
	 * require updating due to recently received payments
132
	 *
133
	 * @param int $timestamp
134
	 * @param int $TXN_ID
135
	 * @param int $PAY_ID
136
	 */
137 View Code Duplication
	public static function schedule_update_transaction_with_payment(
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...
138
		$timestamp,
139
		$TXN_ID,
140
		$PAY_ID
141
	) {
142
		do_action( 'AHEE_log', __CLASS__, __FUNCTION__ );
143
		// validate $TXN_ID and $timestamp
144
		$TXN_ID = absint( $TXN_ID );
145
		$timestamp = absint( $timestamp );
146
		if ( $TXN_ID && $timestamp ) {
147
			wp_schedule_single_event(
148
				$timestamp,
149
				'AHEE__EE_Cron_Tasks__update_transaction_with_payment_2',
150
				array( $TXN_ID, $PAY_ID )
151
			);
152
		}
153
	}
154
155
156
157
	/**
158
	 * setup_update_for_transaction_with_payment
159
	 *
160
	 * this is the callback for the action hook:
161
	 * 'AHEE__EE_Cron_Tasks__update_transaction_with_payment'
162
	 * which is setup by EE_Cron_Tasks::schedule_update_transaction_with_payment().
163
	 * The passed TXN_ID and associated payment gets added to an array, and then
164
	 * the EE_Cron_Tasks::update_transaction_with_payment() function is hooked into
165
	 * 'shutdown' which will actually handle the processing of any
166
	 * transactions requiring updating, because doing so now would be too early
167
	 * and the required resources may not be available
168
	 *
169
	 * @param int  $TXN_ID
170
	 * @param int $PAY_ID
171
	 */
172 View Code Duplication
	public static function setup_update_for_transaction_with_payment( $TXN_ID = 0, $PAY_ID = 0 ) {
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...
173
            do_action( 'AHEE_log', __CLASS__, __FUNCTION__, $TXN_ID, '$TXN_ID' );
174
		if ( absint( $TXN_ID )) {
175
			self::$_update_transactions_with_payment[ $TXN_ID ] = $PAY_ID;
176
			add_action(
177
				'shutdown',
178
				array( 'EE_Cron_Tasks', 'update_transaction_with_payment' ),
179
				5
180
			);
181
		}
182
	}
183
184
185
186
	/**
187
	 * update_transaction_with_payment
188
	 *
189
	 * loops through the self::$_abandoned_transactions array
190
	 * and attempts to finalize any TXNs that have not been completed
191
	 * but have had their sessions expired, most likely due to a user not
192
	 * returning from an off-site payment gateway
193
	 * 
194
	 * @throws \EE_Error
195
	 */
196
	public static function update_transaction_with_payment() {
197
		do_action( 'AHEE_log', __CLASS__, __FUNCTION__ );
198
		// are there any TXNs that need cleaning up ?
199
		if ( ! empty( self::$_update_transactions_with_payment ) ) {
200
			/** @type EE_Payment_Processor $payment_processor */
201
			$payment_processor = EE_Registry::instance()->load_core( 'Payment_Processor' );
202
			// set revisit flag for payment processor
203
			$payment_processor->set_revisit( false );
204
			// load EEM_Transaction
205
			EE_Registry::instance()->load_model( 'Transaction' );
206
			foreach ( self::$_update_transactions_with_payment as $TXN_ID => $PAY_ID ) {
207
				// reschedule the cron if we can't hit the db right now
208
				if ( ! EE_Maintenance_Mode::instance()->models_can_query() ) {
209
					// reset cron job for updating the TXN
210
					EE_Cron_Tasks::schedule_update_transaction_with_payment(
211
						time() + EE_Cron_Tasks::reschedule_timeout,
212
						$TXN_ID,
213
						$PAY_ID
214
					);
215
					continue;
216
				}
217
				$transaction = EEM_Transaction::instance()->get_one_by_ID( $TXN_ID );
218
				$payment = EEM_Payment::instance()->get_one_by_ID( $PAY_ID );
219
				// verify transaction
220
				if ( $transaction instanceof EE_Transaction && $payment instanceof EE_Payment ) {
221
					// now try to update the TXN with any payments
222
					$payment_processor->update_txn_based_on_payment( $transaction, $payment, true, true );
223
				}
224
				unset( self::$_update_transactions_with_payment[ $TXN_ID ] );
225
			}
226
		}
227
	}
228
229
230
231
	/************  END OF UPDATE TRANSACTION WITH PAYMENT  ************/
232
233
234
235
	/*****************  FINALIZE ABANDONED TRANSACTIONS *****************/
236
237
238
239
	/**
240
	 * array of TXN IDs
241
	 * @var array
242
	 */
243
	protected static $_abandoned_transactions = array();
244
245
246
247
	/**
248
	 * schedule_finalize_abandoned_transactions_check
249
	 *
250
	 * sets a wp_schedule_single_event() for finalizing any TXNs that may
251
	 * have been abandoned during the registration process
252
	 *
253
	 * @param int $timestamp
254
	 * @param int $TXN_ID
255
	 */
256 View Code Duplication
	public static function schedule_finalize_abandoned_transactions_check(
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...
257
		$timestamp,
258
		$TXN_ID
259
	) {
260
		// validate $TXN_ID and $timestamp
261
		$TXN_ID = absint( $TXN_ID );
262
		$timestamp = absint( $timestamp );
263
		do_action( 'AHEE_log', __CLASS__, __FUNCTION__, $TXN_ID, '$TXN_ID' );
264
		if ( $TXN_ID && $timestamp ) {
265
			wp_schedule_single_event(
266
				$timestamp,
267
				'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions',
268
				array( $TXN_ID )
269
			);
270
		}
271
	}
272
273
274
275
	/**
276
	 * check_for_abandoned_transactions
277
	 *
278
	 * this is the callback for the action hook:
279
	 * 'AHEE__EE_Cron_Tasks__espresso_finalize_abandoned_transactions'
280
	 * which is utilized by wp_schedule_single_event()
281
	 * in EE_SPCO_Reg_Step_Payment_Options::_post_payment_processing().
282
	 * The passed TXN_ID gets added to an array, and then the
283
	 * espresso_finalize_abandoned_transactions() function is hooked into
284
	 * 'AHEE__EE_System__core_loaded_and_ready' which will actually handle the
285
	 * processing of any abandoned transactions, because doing so now would be
286
	 * too early and the required resources may not be available
287
	 *
288
	 * @param int $TXN_ID
289
	 */
290 View Code Duplication
	public static function check_for_abandoned_transactions(	$TXN_ID = 0 ) {
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...
291
		do_action( 'AHEE_log', __CLASS__, __FUNCTION__, $TXN_ID, '$TXN_ID' );
292
		if ( absint( $TXN_ID )) {
293
			self::$_abandoned_transactions[]  = $TXN_ID;
294
			add_action(
295
				'shutdown',
296
				array( 'EE_Cron_Tasks', 'finalize_abandoned_transactions' ),
297
				5
298
			);
299
		}
300
	}
301
302
303
304
	/**
305
	 * finalize_abandoned_transactions
306
	 
307
	 * loops through the self::$_abandoned_transactions array
308
	 * and attempts to finalize any TXNs that have not been completed
309
	 * but have had their sessions expired, most likely due to a user not
310
	 * returning from an off-site payment gateway
311
	 *
312
	 * @throws \EE_Error
313
	 */
314
	public static function finalize_abandoned_transactions() {
315
		do_action( 'AHEE_log', __CLASS__, __FUNCTION__ );
316
		// are there any TXNs that need cleaning up ?
317
		if ( ! empty( self::$_abandoned_transactions ) ) {
318
			/** @type EE_Transaction_Processor $transaction_processor */
319
			$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
320
			// set revisit flag for txn processor
321
			$transaction_processor->set_revisit( false );
322
			/** @type EE_Payment_Processor $payment_processor */
323
			$payment_processor = EE_Registry::instance()->load_core( 'Payment_Processor' );
324
			// load EEM_Transaction
325
			EE_Registry::instance()->load_model( 'Transaction' );
326
			foreach ( self::$_abandoned_transactions as $TXN_ID ) {
327
				do_action( 'AHEE_log', __CLASS__, __FUNCTION__, $TXN_ID, '$TXN_ID' );
328
				// reschedule the cron if we can't hit the db right now
329
				if ( ! EE_Maintenance_Mode::instance()->models_can_query() ) {
330
					// reset cron job for finalizing the TXN
331
					EE_Cron_Tasks::schedule_finalize_abandoned_transactions_check(
332
						time() + EE_Cron_Tasks::reschedule_timeout,
333
						$TXN_ID
334
					);
335
					continue;
336
				}
337
				$transaction = EEM_Transaction::instance()->get_one_by_ID( $TXN_ID );
338
				// verify transaction
339
				if ( $transaction instanceof EE_Transaction ) {
340
					// don't finalize the TXN if it has already been completed
341
					if ( $transaction_processor->all_reg_steps_completed( $transaction ) === true ) {
342
						continue;
343
					}
344
					// let's simulate an IPN here which will trigger any notifications that need to go out
345
					$payment_processor->update_txn_based_on_payment( $transaction, $transaction->last_payment(), true, true );
346
				}
347
				unset( self::$_abandoned_transactions[ $TXN_ID ] );
348
			}
349
		}
350
	}
351
352
353
354
	/*************  END OF FINALIZE ABANDONED TRANSACTIONS  *************/
355
356
357
358
	/************* START CLEAN UP BOT TRANSACTIONS **********************/
359
360
	//when a transaction is initially made, schedule this check.
361
	//if it has NO REG data by the time it has expired, forget about it
362
	public static function clean_out_junk_transactions() {
363
		if( EE_Maintenance_Mode::instance()->models_can_query() ) {
364
			EEM_Transaction::instance('')->delete_junk_transactions();
365
			EEM_Registration::instance('')->delete_registrations_with_no_transaction();
366
			EEM_Line_Item::instance('')->delete_line_items_with_no_transaction();
367
		}
368
	}
369
370
371
}
372
// End of file EE_Cron_Tasks.core.php
373
// Location: /EE_Cron_Tasks.core.php
374