Completed
Branch BUG-9774-email-validation (c72797)
by
unknown
680:01 queued 665:37
created

EED_Messages::instance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file contains the module for the messages system
4
 *
5
 * @since 4.5.0
6
 * @package  Event Espresso
7
 * @subpackage modules, messages
8
 */
9
if ( ! defined('EVENT_ESPRESSO_VERSION')) exit('No direct script access allowed');
10
/**
11
 *
12
 * Messages module.  Takes care of registering all the triggers for messages.
13
 *
14
 * @since 4.5.0
15
 *
16
 * @package		Event Espresso
17
 * @subpackage	modules, messages
18
 * @author 		Darren Ethier
19
 *
20
 * ------------------------------------------------------------------------
21
 */
22
class EED_Messages  extends EED_Module {
23
24
	/**
25
	 * This holds the EE_messages controller
26
	 * @deprecated 4.9.0
27
	 * @var EE_messages $_EEMSG
28
	 */
29
	protected  static $_EEMSG;
30
31
	/**
32
	 * @type EE_Message_Resource_Manager $_message_resource_manager
33
	 */
34
	protected  static $_message_resource_manager;
35
36
	/**
37
	 * This holds the EE_Messages_Processor business class.
38
	 *
39
	 * @type EE_Messages_Processor
40
	 */
41
	protected static $_MSG_PROCESSOR;
42
43
	/**
44
	 * holds all the paths for various messages components.
45
	 * Utilized by autoloader registry
46
	 *
47
	 * @var array
48
	 */
49
	protected static $_MSG_PATHS;
50
51
52
53
	/**
54
	 * This will hold an array of messages template packs that are registered in the messages system.
55
	 * Format is:
56
	 * array(
57
	 * 	'template_pack_dbref' => EE_Messages_Template_Pack (instance)
58
	 * )
59
	 *
60
	 * @var EE_Messages_Template_Pack[]
61
	 */
62
	protected static $_TMP_PACKS = array();
63
64
65
66
67
68
	/**
69
	 * @return EED_Module
70
	 */
71
	public static function instance() {
72
		return parent::get_instance( __CLASS__ );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (get_instance() instead of instance()). Are you sure this is correct? If so, you might want to change this to $this->get_instance().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
73
	}
74
75
76
77
78
	/**
79
	 *  set_hooks - for hooking into EE Core, other modules, etc
80
	 *
81
	 *  @since 4.5.0
82
	 *
83
	 *  @return 	void
84
	 */
85
	public static function set_hooks() {
86
		//actions
87
		add_action( 'AHEE__EE_Payment_Processor__update_txn_based_on_payment', array( 'EED_Messages', 'payment' ), 10, 2 );
88
		add_action( 'AHEE__EE_Registration_Processor__trigger_registration_update_notifications', array( 'EED_Messages', 'maybe_registration' ), 10, 2 );
89
		//filters
90
		add_filter( 'FHEE__EE_Registration__receipt_url__receipt_url', array( 'EED_Messages', 'registration_message_trigger_url' ), 10, 4 );
91
		add_filter( 'FHEE__EE_Registration__invoice_url__invoice_url', array( 'EED_Messages', 'registration_message_trigger_url' ), 10, 4 );
92
		//register routes
93
		self::_register_routes();
94
	}
95
96
	/**
97
	 * 	set_hooks_admin - for hooking into EE Admin Core, other modules, etc
98
	 *
99
	 *  @access 	public
100
	 *  @return 	void
101
	 */
102
	public static function set_hooks_admin() {
103
		//actions
104
		add_action( 'AHEE__EE_Payment_Processor__update_txn_based_on_payment', array( 'EED_Messages', 'payment' ), 10, 2 );
105
		add_action( 'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder', array( 'EED_Messages', 'payment_reminder' ), 10 );
106
		add_action( 'AHEE__EE_Registration_Processor__trigger_registration_update_notifications', array( 'EED_Messages', 'maybe_registration' ), 10, 3 );
107
		add_action( 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', array( 'EED_Messages', 'send_newsletter_message' ), 10, 2 );
108
		add_action( 'AHEE__EES_Espresso_Cancelled__process_shortcode__transaction', array( 'EED_Messages', 'cancelled_registration' ), 10 );
109
		add_action( 'AHEE__EE_Admin_Page___process_admin_payment_notification', array( 'EED_Messages', 'process_admin_payment' ), 10, 1 );
110
		//filters
111
		add_filter( 'FHEE__EE_Admin_Page___process_resend_registration__success', array( 'EED_Messages', 'process_resend' ), 10, 2 );
112
		add_filter( 'FHEE__EE_Registration__receipt_url__receipt_url', array( 'EED_Messages', 'registration_message_trigger_url' ), 10, 4 );
113
		add_filter( 'FHEE__EE_Registration__invoice_url__invoice_url', array( 'EED_Messages', 'registration_message_trigger_url' ), 10, 4 );
114
	}
115
116
117
118
119
	/**
120
	 * All the message triggers done by route go in here.
121
	 *
122
	 * @since 4.5.0
123
	 *
124
	 * @return void
125
	 */
126
	protected static function _register_routes() {
127
		EE_Config::register_route( 'msg_url_trigger', 'Messages', 'run' );
128
		EE_Config::register_route( 'msg_cron_trigger', 'Messages', 'execute_batch_request' );
129
		EE_Config::register_route( 'msg_browser_trigger', 'Messages', 'browser_trigger' );
130
		EE_Config::register_route( 'msg_browser_error_trigger', 'Messages', 'browser_error_trigger' );
131
		do_action( 'AHEE__EED_Messages___register_routes' );
132
	}
133
134
135
136
	/**
137
	 * This is called when a browser display trigger is executed.
138
	 * The browser display trigger is typically used when a already generated message is displayed directly in the browser.
139
	 * @since 4.9.0
140
	 * @param WP $WP
141
	 */
142
	public function browser_trigger( $WP ) {
0 ignored issues
show
Unused Code introduced by
The parameter $WP is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
143
		//ensure controller is loaded
144
		self::_load_controller();
145
		$token = EE_Registry::instance()->REQ->get( 'token' );
146
		try {
147
			$mtg = new EE_Message_Generated_From_Token( $token, 'html', self::$_message_resource_manager );
148
			self::$_MSG_PROCESSOR->generate_and_send_now( $mtg );
149
		} catch( EE_Error $e ) {
150
			$error_msg = __( 'Please note that a system message failed to send due to a technical issue.', 'event_espresso' );
151
			// add specific message for developers if WP_DEBUG in on
152
			$error_msg .= '||' . $e->getMessage();
153
			EE_Error::add_error( $error_msg, __FILE__, __FUNCTION__, __LINE__ );
154
		}
155
	}
156
157
158
159
160
161
	/**
162
	 * This is called when a browser error trigger is executed.
163
	 * When triggered this will grab the EE_Message matching the token in the request and use that to get the error message
164
	 * and display it.
165
	 *
166
	 * @since 4.9.0
167
	 * @param $WP
168
	 */
169
	public function browser_error_trigger( $WP ) {
0 ignored issues
show
Unused Code introduced by
The parameter $WP is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
170
		$token = EE_Registry::instance()->REQ->get( 'token' );
171
		if ( $token ) {
172
			$message = EEM_Message::instance()->get_one_by_token( $token );
173
			if ( $message instanceof EE_Message ) {
174
				header( 'HTTP/1.1 200 OK' );
175
				$error_msg = nl2br( $message->error_message() );
176
				?>
177
				<!DOCTYPE html>
178
				<html>
179
					<head></head>
180
					<body>
181
						<?php echo empty( $error_msg )
182
						? esc_html__( 'Unfortunately, we were unable to capture the error message for this message.', 'event_espresso' )
183
						: wp_kses(
184
							$error_msg,
185
							array(
186
								'a' => array(
187
									'href' => array(),
188
									'title' => array()
189
								),
190
								'span' => array(),
191
								'div' => array(),
192
								'p' => array(),
193
								'strong' => array(),
194
								'em' => array(),
195
								'br' => array()
196
							)
197
						); ?>
198
					</body>
199
				</html>
200
				<?php
201
				exit;
202
			}
203
		}
204
		return;
205
	}
206
207
208
209
	/**
210
	 *  This runs when the msg_url_trigger route has initiated.
211
	 *
212
	 * @since 4.5.0
213
	 * @param WP $WP
214
	 * @throws EE_Error
215
	 * @return    void
216
	 */
217
	public function run( $WP ) {
218
		//ensure controller is loaded
219
		self::_load_controller();
220
		// attempt to process message
221
		try {
222
			/** @type EE_Message_To_Generate_From_Request $message_to_generate */
223
			$message_to_generate = EE_Registry::instance()->load_lib( 'Message_To_Generate_From_Request' );
224
			self::$_MSG_PROCESSOR->generate_and_send_now( $message_to_generate );
225
		} catch ( EE_Error $e ) {
226
			$error_msg = __( 'Please note that a system message failed to send due to a technical issue.', 'event_espresso' );
227
			// add specific message for developers if WP_DEBUG in on
228
			$error_msg .= '||' . $e->getMessage();
229
			EE_Error::add_error( $error_msg, __FILE__, __FUNCTION__, __LINE__ );
230
		}
231
	}
232
233
234
	/**
235
	 * This is triggered by the 'msg_cron_trigger' route.
236
	 * @param WP $WP
237
	 */
238
	public function execute_batch_request( $WP ) {
0 ignored issues
show
Unused Code introduced by
The parameter $WP is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
239
		$this->run_cron();
240
		header( 'HTTP/1.1 200 OK' );
241
		exit();
242
	}
243
244
245
246
247
	/**
248
	 * This gets executed on wp_cron jobs or when a batch request is initated on its own separate non regular wp request.
249
	 *
250
	 */
251
	public function run_cron() {
252
		self::_load_controller();
253
		//get required vars
254
		$cron_type = EE_Registry::instance()->REQ->get( 'type' );
255
		$transient_key = EE_Registry::instance()->REQ->get( 'key' );
256
257
		//now let's verify transient, if not valid exit immediately
258
		if ( ! get_transient( $transient_key ) ) {
259
			/**
260
			 * trigger error so this gets in the error logs.  This is important because it happens on a non-user request.
261
			 */
262
			trigger_error( esc_attr__( 'Invalid Request (Transient does not exist)', 'event_espresso' ) );
263
		}
264
265
		//if made it here, lets' delete the transient to keep the db clean
266
		delete_transient( $transient_key );
267
268
		if ( apply_filters( 'FHEE__EED_Messages__run_cron__use_wp_cron', true ) ) {
269
270
			$method = 'batch_' . $cron_type . '_from_queue';
271
			if ( method_exists( self::$_MSG_PROCESSOR, $method ) ) {
272
				self::$_MSG_PROCESSOR->$method();
273
			} else {
274
				//no matching task
275
				/**
276
				 * trigger error so this gets in the error logs.  This is important because it happens on a non user request.
277
				 */
278
				trigger_error( esc_attr( sprintf( __( 'There is no task corresponding to this route %s', 'event_espresso' ), $cron_type ) ) );
279
			}
280
		}
281
282
		do_action( 'FHEE__EED_Messages__run_cron__end' );
283
	}
284
285
286
287
288
	/**
289
	 * This is used to retrieve the template pack for the given name.
290
	 * Retrieved packs are cached on the static $_TMP_PACKS array.  If there is no class matching the given name then the default template pack is returned.
291
	 *
292
	 * @deprecated 4.9.0  @see EEH_MSG_Template::get_template_pack()
293
	 *
294
	 * @param string $template_pack_name This should correspond to the dbref of the template pack (which is also used in generating the Pack class name).
295
	 *
296
	 * @return EE_Messages_Template_Pack
297
	 */
298
	public static function get_template_pack( $template_pack_name ) {
299
		EE_Registry::instance()->load_helper( 'MSG_Template' );
300
		return EEH_MSG_Template::get_template_pack( $template_pack_name );
301
	}
302
303
304
305
306
	/**
307
	 * Retrieves an array of all template packs.
308
	 * Array is in the format array( 'dbref' => EE_Messages_Template_Pack )
309
	 * @deprecated 4.9.0  @see EEH_MSG_Template_Pack::get_template_pack_collection
310
	 *
311
	 * @return EE_Messages_Template_Pack[]
312
	 */
313
	public static function get_template_packs() {
314
		EE_Registry::instance()->load_helper( 'MSG_Template' );
315
316
		//for backward compat, let's make sure this returns in the same format as originally.
317
		$template_pack_collection = EEH_MSG_Template::get_template_pack_collection();
318
		$template_pack_collection->rewind();
319
		$template_packs = array();
320
		while ( $template_pack_collection->valid() ) {
321
			$template_packs[ $template_pack_collection->current()->dbref ] = $template_pack_collection->current();
322
			$template_pack_collection->next();
323
		}
324
		return $template_packs;
325
	}
326
327
328
329
	/**
330
	 * This simply makes sure the autoloaders are registered for the EE_messages system.
331
	 *
332
	 * @since 4.5.0
333
	 *
334
	 * @return void
335
	 */
336
	public static function set_autoloaders() {
337
		if ( empty( self::$_MSG_PATHS ) ) {
338
			self::_set_messages_paths();
339
			foreach ( self::$_MSG_PATHS as $path ) {
340
				EEH_Autoloader::register_autoloaders_for_each_file_in_folder( $path );
341
			}
342
			// add aliases
343
			EEH_Autoloader::add_alias( 'EE_messages', 'EE_messages' );
344
			EEH_Autoloader::add_alias( 'EE_messenger', 'EE_messenger' );
345
		}
346
	}
347
348
349
350
351
	/**
352
	 * Take care of adding all the paths for the messages components to the $_MSG_PATHS property
353
	 * for use by the Messages Autoloaders
354
	 *
355
	 * @since 4.5.0
356
	 *
357
	 * @return void.
0 ignored issues
show
Documentation introduced by
The doc-type void. could not be parsed: Unknown type name "void." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
358
	 */
359
	protected static function _set_messages_paths() {
360
		$dir_ref = array(
361
			'messages/message_type',
362
			'messages/messenger',
363
			'messages/defaults',
364
			'messages/defaults/email',
365
			'messages/data_class',
366
			'messages/validators',
367
			'messages/validators/email',
368
			'messages/validators/html',
369
			'shortcodes',
370
			);
371
		$paths = array();
372
		foreach ( $dir_ref as $index => $dir ) {
373
			$paths[ $index ] = EE_LIBRARIES . $dir;
374
		}
375
		self::$_MSG_PATHS = apply_filters( 'FHEE__EED_Messages___set_messages_paths___MSG_PATHS', $paths );
376
	}
377
378
379
	/**
380
	 * Takes care of loading dependencies
381
	 *
382
	 * @since 4.5.0
383
	 * @return void
384
	 */
385
	protected static function _load_controller() {
386
		if ( ! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor ) {
387
			EE_Registry::instance()->load_core( 'Request_Handler' );
388
			self::set_autoloaders();
389
			self::$_EEMSG = EE_Registry::instance()->load_lib( 'messages' );
0 ignored issues
show
Documentation Bug introduced by
It seems like \EE_Registry::instance()->load_lib('messages') can also be of type boolean. However, the property $_EEMSG is declared as type object<EE_messages>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
Deprecated Code introduced by
The property EED_Messages::$_EEMSG has been deprecated with message: 4.9.0

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
390
			self::$_MSG_PROCESSOR = EE_Registry::instance()->load_lib( 'Messages_Processor' );
0 ignored issues
show
Documentation Bug introduced by
It seems like \EE_Registry::instance()...b('Messages_Processor') can also be of type boolean. However, the property $_MSG_PROCESSOR is declared as type object<EE_Messages_Processor>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
391
			self::$_message_resource_manager = EE_Registry::instance()->load_lib( 'Message_Resource_Manager' );
0 ignored issues
show
Documentation Bug introduced by
It seems like \EE_Registry::instance()...sage_Resource_Manager') can also be of type boolean. However, the property $_message_resource_manager is declared as type object<EE_Message_Resource_Manager>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
392
		}
393
	}
394
395
396
397
	/**
398
	 * @param EE_Transaction $transaction
399
	 */
400
	public static function payment_reminder( EE_Transaction $transaction ) {
401
		self::_load_controller();
402
		$data = array( $transaction, null );
403
		self::$_MSG_PROCESSOR->generate_for_all_active_messengers( 'payment_reminder', $data );
404
	}
405
406
407
408
	/**
409
	 * Any messages triggers for after successful gateway payments should go in here.
410
	 * @param  EE_Transaction object
411
	 * @param  EE_Payment object
412
	 * @return void
413
	 */
414
	public static function payment( EE_Transaction $transaction, EE_Payment $payment ) {
415
		self::_load_controller();
416
		$data = array( $transaction, $payment );
417
		EE_Registry::instance()->load_helper( 'MSG_Template' );
418
		$message_type = EEH_MSG_Template::convert_payment_status_to_message_type( $payment->STS_ID() );
419
		//if payment amount is less than 0 then switch to payment_refund message type.
420
		$message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
421
		self::$_MSG_PROCESSOR->generate_for_all_active_messengers( $message_type, $data );
422
	}
423
424
425
426
	/**
427
	 * @param EE_Transaction $transaction
428
	 */
429
	public static function cancelled_registration( EE_Transaction $transaction ) {
430
		self::_load_controller();
431
		$data = array( $transaction, null );
432
		self::$_MSG_PROCESSOR->generate_for_all_active_messengers( 'cancelled_registration', $data );
433
	}
434
435
436
437
	/**
438
	 * Trigger for Registration messages
439
	 * Note that what registration message type is sent depends on what the reg status is for the registrations on the incoming transaction.
440
	 *
441
	 * @param EE_Registration $registration
442
	 * @param array $extra_details
443
	 * @return void
444
	 */
445
	public static function maybe_registration( EE_Registration $registration, $extra_details = array() ) {
446
447
		if ( ! self::_verify_registration_notification_send( $registration, $extra_details ) ) {
448
			//no messages please
449
			return;
450
		}
451
452
453
		//get all registrations so we make sure we send messages for the right status.
454
		$all_registrations = $registration->transaction()->registrations();
455
456
		//cached array of statuses so we only trigger messages once per status.
457
		$statuses_sent = array();
458
		self::_load_controller();
459
		$mtgs = array();
460
461
		//loop through registrations and trigger messages once per status.
462
		foreach ( $all_registrations as $reg ) {
463
464
			//already triggered?
465
			if ( in_array( $reg->status_ID(), $statuses_sent ) ) {
0 ignored issues
show
Documentation Bug introduced by
The method status_ID does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
466
				continue;
467
			}
468
469
			$message_type = EEH_MSG_Template::convert_reg_status_to_message_type( $reg->status_ID() );
0 ignored issues
show
Documentation Bug introduced by
The method status_ID does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
470
			$mtgs = $mtgs + self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers( $message_type, array( $registration->transaction(), null, $reg->status_ID() ) );
0 ignored issues
show
Documentation Bug introduced by
The method status_ID does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
471
			$statuses_sent[] = $reg->status_ID();
0 ignored issues
show
Documentation Bug introduced by
The method status_ID does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
472
		}
473
474
		$mtgs = $mtgs + self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers( 'registration_summary', array( $registration->transaction(), null ) );
475
476
		//batch queue and initiate request
477
		self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist( $mtgs );
478
		self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
479
	}
480
481
482
483
	/**
484
	 * This is a helper method used to very whether a registration notification should be sent or
485
	 * not.  Prevents duplicate notifications going out for registration context notifications.
486
	 *
487
	 * @param EE_Registration $registration  [description]
488
	 * @param array           $extra_details [description]
489
	 *
490
	 * @return bool          true = send away, false = nope halt the presses.
491
	 */
492
	protected static function _verify_registration_notification_send( EE_Registration $registration, $extra_details = array() ) {
493
		 //self::log(
494
		 //	__CLASS__, __FUNCTION__, __LINE__,
495
		 //	$registration->transaction(),
496
		 //	array( '$extra_details' => $extra_details )
497
		 //);
498
		// currently only using this to send messages for the primary registrant
499
		if ( ! $registration->is_primary_registrant() ) {
500
			return false;
501
		}
502
		// first we check if we're in admin and not doing front ajax
503
		if ( is_admin() && ! EE_FRONT_AJAX ) {
504
			//make sure appropriate admin params are set for sending messages
505
			if ( empty( $_REQUEST['txn_reg_status_change']['send_notifications'] ) || ! absint( $_REQUEST['txn_reg_status_change']['send_notifications'] ) ) {
506
				//no messages sent please.
507
				return false;
508
			}
509
		} else {
510
			// frontend request (either regular or via AJAX)
511
			// TXN is NOT finalized ?
512
			if ( ! isset( $extra_details['finalized'] ) || $extra_details['finalized'] === false ) {
513
				return false;
514
			}
515
			// return visit but nothing changed ???
516
			if (
517
				isset( $extra_details['revisit'], $extra_details['status_updates'] ) &&
518
				$extra_details['revisit'] && ! $extra_details['status_updates']
519
			) {
520
				return false;
521
			}
522
			// NOT sending messages && reg status is something other than "Not-Approved"
523
			if (
524
				! apply_filters( 'FHEE__EED_Messages___maybe_registration__deliver_notifications', false ) &&
525
				$registration->status_ID() !== EEM_Registration::status_id_not_approved
526
			) {
527
				return false;
528
			}
529
		}
530
		// release the kraken
531
		return true;
532
	}
533
534
535
536
	/**
537
	 * Simply returns an array indexed by Registration Status ID and the related message_type name associated with that status id.
538
	 *
539
	 * @deprecated 4.9.0  Use EEH_MSG_Template::reg_status_to_message_type_array()
540
	 *                    or EEH_MSG_Template::convert_reg_status_to_message_type
541
	 *
542
	 * @param string $reg_status
543
	 *
544
	 * @return array
545
	 */
546
	protected static function _get_reg_status_array( $reg_status = '' ) {
547
		EE_Registry::instance()->load_helper( 'MSG_Template' );
548
		return EEH_MSG_Template::convert_reg_status_to_message_type( $reg_status )
549
			? EEH_MSG_Template::convert_reg_status_to_message_type( $reg_status )
550
			: EEH_MSG_Template::reg_status_to_message_type_array();
551
	}
552
553
554
555
	/**
556
	 * Simply returns the payment message type for the given payment status.
557
	 *
558
	 * @deprecated 4.9.0 Use EEH_MSG_Template::payment_status_to_message_type_array
559
	 *                   or EEH_MSG_Template::convert_payment_status_to_message_type
560
	 *
561
	 * @param string  $payment_status The payment status being matched.
562
	 *
563
	 * @return string|bool The payment message type slug matching the status or false if no match.
564
	 */
565
	protected static function _get_payment_message_type( $payment_status ) {
566
		EE_Registry::instance()->load_helper( 'MSG_Template' );
567
		return EEH_MSG_Template::convert_payment_status_to_message_type( $payment_status )
568
			? EEH_MSG_Template::convert_payment_status_to_message_type( $payment_status )
569
			: false;
570
	}
571
572
573
574
575
	/**
576
	 * Message triggers for a resending already sent message(s) (via EE_Message list table)
577
	 *
578
	 * @access public
579
	 * @param array $req_data This is the $_POST & $_GET data sent from EE_Admin Pages
580
	 * @return bool          success/fail
581
	 */
582
	public static function process_resend( $req_data ) {
583
		self::_load_controller();
584
585
		//if $msgID in this request then skip to the new resend_message
586
		if ( EE_Registry::instance()->REQ->get( 'MSG_ID' ) ) {
587
			return self::resend_message();
588
		}
589
590
		//make sure any incoming request data is set on the REQ so that it gets picked up later.
591
		$req_data = (array) $req_data;
592
		foreach( $req_data as $request_key => $request_value ) {
593
			EE_Registry::instance()->REQ->set( $request_key, $request_value );
594
		}
595
596
		if ( ! $messages_to_send = self::$_MSG_PROCESSOR->setup_messages_to_generate_from_registration_ids_in_request() ) {
597
			return false;
598
		}
599
600
		try {
601
			self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist( $messages_to_send );
602
			self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
603
		} catch( EE_Error $e ) {
604
			EE_Error::add_error( $e->getMessage(), __FILE__, __FUNCTION__, __LINE__ );
605
			return false;
606
		}
607
		EE_Error::add_success(
608
			__( 'Messages have been successfully queued for generation and sending.', 'event_espresso' )
609
		);
610
		return true; //everything got queued.
611
	}
612
613
614
	/**
615
	 * Message triggers for a resending already sent message(s) (via EE_Message list table)
616
	 * @return bool
617
	 */
618
	public static function resend_message() {
619
		self::_load_controller();
620
621
		$msgID = EE_Registry::instance()->REQ->get( 'MSG_ID' );
622
		if ( ! $msgID ) {
623
			EE_Error::add_error( __( 'Something went wrong because there is no "MSG_ID" value in the request', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
624
			return false;
625
		}
626
627
		self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send( (array) $msgID );
628
629
		//setup success message.
630
		$count_ready_for_resend = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue( EEM_Message::status_resend );
631
		EE_Error::add_success( sprintf(
632
			_n(
633
				'There was %d message queued for resending.',
634
				'There were %d messages queued for resending.',
635
				$count_ready_for_resend,
636
				'event_espresso'
637
			),
638
			$count_ready_for_resend
639
		) );
640
		return true;
641
	}
642
643
644
645
646
647
	/**
648
	 * Message triggers for manual payment applied by admin
649
	 * @param  EE_Payment $payment EE_payment object
650
	 * @return bool              success/fail
651
	 */
652
	public static function process_admin_payment( EE_Payment $payment ) {
653
		EE_Registry::instance()->load_helper( 'MSG_Template' );
654
		//we need to get the transaction object
655
		$transaction = $payment->transaction();
656
		if ( $transaction instanceof EE_Transaction ) {
657
			$data = array( $transaction, $payment );
658
			$message_type = EEH_MSG_Template::convert_payment_status_to_message_type( $payment->STS_ID() );
659
660
			//if payment amount is less than 0 then switch to payment_refund message type.
661
			$message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
662
663
			//if payment_refund is selected, but the status is NOT accepted.  Then change message type to false so NO message notification goes out.
664
			$message_type = $message_type == 'payment_refund' && $payment->STS_ID() != EEM_Payment::status_id_approved ? false : $message_type;
665
666
			self::_load_controller();
667
668
			self::$_MSG_PROCESSOR->generate_for_all_active_messengers( $message_type, $data );
669
670
			//get count of queued for generation
671
			$count_to_generate = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue( array( EEM_Message::status_incomplete, EEM_Message::status_idle ) );
672
673
			if ( $count_to_generate > 0 && self::$_MSG_PROCESSOR->get_queue()->get_message_repository()->count() !== 0 ) {
674
				add_filter( 'FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true' );
675
				return true;
676
			} else {
677
				$count_failed = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue( EEM_Message::instance()->stati_indicating_failed_sending() );
678
				/**
679
				 * Verify that there are actually errors.  If not then we return a success message because the queue might have been emptied due to successful
680
				 * IMMEDIATE generation.
681
				 */
682
				if ( $count_failed > 0 ) {
683
					EE_Error::add_error( sprintf(
684
						_n(
685
							'The payment notification generation failed.',
686
							'%d payment notifications failed being sent.',
687
							$count_failed,
688
							'event_espresso'
689
						),
690
						$count_failed
691
					), __FILE__, __FUNCTION__, __LINE__ );
692
693
					return false;
694
				} else {
695
					add_filter( 'FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true' );
696
					return true;
697
				}
698
			}
699
		} else {
700
			EE_Error::add_error(
701
				'Unable to generate the payment notification because the given value for the transaction is invalid.',
702
				'event_espresso'
703
			);
704
			return false;
705
		}
706
	}
707
708
709
710
	/**
711
	 * Callback for AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send_with_registrations trigger
712
	 *
713
	 * @since   4.3.0
714
	 *
715
	 * @param  EE_Registration[]  $registrations   an array of EE_Registration objects
716
	 * @param  int      	      $grp_id     a specific message template group id.
717
	 * @return void
718
	 */
719
	public static function send_newsletter_message( $registrations, $grp_id ) {
720
		//make sure mtp is id and set it in the EE_Request Handler later messages setup.
721
		EE_Registry::instance()->REQ->set( 'GRP_ID', (int) $grp_id );
722
		self::_load_controller();
723
		self::$_MSG_PROCESSOR->generate_for_all_active_messengers( 'newsletter', $registrations );
724
	}
725
726
727
	/**
728
	 * Callback for FHEE__EE_Registration__invoice_url__invoice_url or FHEE__EE_Registration__receipt_url__receipt_url
729
	 *
730
	 * @since   4.3.0
731
	 *
732
	 * @param 	string 	$registration_message_trigger_url
733
	 * @param 	EE_Registration $registration
734
	 * @param string 	$messenger
735
	 * @param string 	$message_type
736
	 * @return 	string
737
	 */
738
	public static function registration_message_trigger_url( $registration_message_trigger_url, EE_Registration $registration, $messenger = 'html', $message_type = 'invoice' ) {
739
		// whitelist $messenger
740
		switch ( $messenger ) {
741
			case 'pdf' :
742
				$sending_messenger = 'pdf';
743
				$generating_messenger = 'html';
744
				break;
745
			case 'html' :
746
			default :
747
				$sending_messenger = 'html';
748
				$generating_messenger = 'html';
749
				break;
750
		}
751
		// whitelist $message_type
752
		switch ( $message_type ) {
753
			case 'receipt' :
754
				$message_type = 'receipt';
755
				break;
756
			case 'invoice' :
757
			default :
758
				$message_type = 'invoice';
759
				break;
760
		}
761
		// verify that both the messenger AND the message type are active
762
		if ( EEH_MSG_Template::is_messenger_active( $sending_messenger ) && EEH_MSG_Template::is_mt_active( $message_type ) ) {
763
			//need to get the correct message template group for this (i.e. is there a custom invoice for the event this registration is registered for?)
764
			$template_query_params = array(
765
				'MTP_is_active' => true,
766
				'MTP_messenger' => $generating_messenger,
767
				'MTP_message_type' => $message_type,
768
				'Event.EVT_ID' => $registration->event_ID()
769
			);
770
			//get the message template group.
771
			$msg_template_group = EEM_Message_Template_Group::instance()->get_one( array( $template_query_params ) );
772
			//if we don't have an EE_Message_Template_Group then return
773
			if ( ! $msg_template_group instanceof EE_Message_Template_Group ) {
774
				// remove EVT_ID from query params so that global templates get picked up
775
				unset( $template_query_params['Event.EVT_ID'] );
776
				//get global template as the fallback
777
				$msg_template_group = EEM_Message_Template_Group::instance()->get_one( array( $template_query_params ) );
778
			}
779
			//if we don't have an EE_Message_Template_Group then return
780
			if ( ! $msg_template_group instanceof EE_Message_Template_Group ) {
781
				return '';
782
			}
783
			// generate the URL
784
			$registration_message_trigger_url = EEH_MSG_Template::generate_url_trigger(
785
				$sending_messenger,
786
				$generating_messenger,
787
				'purchaser',
788
				$message_type,
789
				$registration,
790
				$msg_template_group->ID(),
791
				$registration->transaction_ID()
792
			);
793
794
		}
795
		return $registration_message_trigger_url;
796
	}
797
798
799
800
801
	/**
802
	 * Use to generate and return a message preview!
803
	 * @param  string $type    This should correspond with a valid message type
804
	 * @param  string $context This should correspond with a valid context for the message type
805
	 * @param  string $messenger This should correspond with a valid messenger.
806
	 * @param bool 	  $send true we will do a test send using the messenger delivery, false we just do a regular preview
807
	 * @return string|bool          The body of the message or if send is requested, sends.
808
	 */
809
	public static function preview_message( $type, $context, $messenger, $send = false ) {
810
		self::_load_controller();
811
		$mtg = new EE_Message_To_Generate(
812
			$messenger,
813
			$type,
814
			array(),
815
			$context,
816
			true
817
		);
818
		$generated_preview_queue = self::$_MSG_PROCESSOR->generate_for_preview( $mtg, $send );
819
		if ( $generated_preview_queue instanceof EE_Messages_Queue ) {
820
			return $generated_preview_queue->get_message_repository()->current()->content();
821
		} else {
822
			return $generated_preview_queue;
823
		}
824
	}
825
826
827
828
829
	/**
830
	 * This is a method that allows for sending a message using a messenger matching the string given and the provided
831
	 * EE_Message_Queue object.  The EE_Message_Queue object is used to create a single aggregate EE_Message via the content
832
	 * found in the EE_Message objects in the queue.
833
	 *
834
	 * @since 4.9.0
835
	 *
836
	 * @param string               $messenger a string matching a valid active messenger in the system
837
	 * @param string $message_type Although it seems contrary to the name of the method, a message type name is
838
	 *                             still required to send along the message type to the messenger because this is used
839
	 *                             for determining what specific variations might be loaded for the generated message.
840
	 * @param EE_Messages_Queue     $queue
841
	 * @param string                $custom_subject   Can be used to set what the custom subject string will be on the aggregate
842
	 *                                                EE_Message object.
843
	 *
844
	 * @return bool          success or fail.
845
	 */
846
	public static function send_message_with_messenger_only( $messenger, $message_type, EE_Messages_Queue $queue, $custom_subject = '' ) {
847
		self::_load_controller();
848
		/** @type EE_Message_To_Generate_From_Queue $message_to_generate */
849
		$message_to_generate = EE_Registry::instance()->load_lib(
850
			'Message_To_Generate_From_Queue',
851
			array(
852
				$messenger,
853
				$message_type,
854
				$queue,
855
				$custom_subject,
856
			)
857
		);
858
		return self::$_MSG_PROCESSOR->queue_for_sending( $message_to_generate );
859
	}
860
861
862
863
864
	/**
865
	 * Generates Messages immediately for EE_Message IDs (but only for the correct status for generation)
866
	 *
867
	 * @since 4.9.0
868
	 * @param array     $message_ids An array of message ids
869
	 * @return bool | EE_Messages_Queue     false if nothing was generated, EE_Messages_Queue containing generated messages.
870
	 */
871
	public static function generate_now( $message_ids ) {
872
		self::_load_controller();
873
		$messages = EEM_Message::instance()->get_all(
874
			array(
875
				0 => array(
876
					'MSG_ID' => array( 'IN', $message_ids ),
877
					'STS_ID' => EEM_Message::status_incomplete,
878
				)
879
			)
880
		);
881
882
		$generated_queue = self::$_MSG_PROCESSOR->batch_generate_from_queue( $messages );
0 ignored issues
show
Documentation introduced by
$messages is of type array<integer,object<EE_Base_Class>>, but the function expects a array<integer,object<EE_Message>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
883
884
		if ( ! $generated_queue instanceof EE_Messages_Queue ) {
885
			EE_Error::add_error(
886
				__( 'The messages were not generated.  This is usually because there is already a batch being generated on a separate request.  You can wait a minute or two and try again.', 'event_espresso' ),
887
				__FILE__, __FUNCTION__, __LINE__
888
			);
889
		}
890
		return $generated_queue;
891
	}
892
893
894
895
896
	/**
897
	 * Sends messages immediately for the incoming message_ids that have the status of EEM_Message::status_resend or,
898
	 * EEM_Message::status_idle
899
	 *
900
	 * @since 4.9.0
901
	 * @param $message_ids
902
	 *
903
	 * @return bool | EE_Messages_Queue  false if no messages sent.
904
	 */
905
	public static function send_now( $message_ids ) {
906
		self::_load_controller();
907
		$messages = EEM_Message::instance()->get_all(
908
			array(
909
				0 => array(
910
					'MSG_ID' => array( 'IN', $message_ids ),
911
					'STS_ID' => array( 'IN', array( EEM_Message::status_idle, EEM_Message::status_resend, EEM_Message::status_retry ) )
912
				)
913
			)
914
		);
915
916
		$sent_queue = self::$_MSG_PROCESSOR->batch_send_from_queue( $messages );
0 ignored issues
show
Documentation introduced by
$messages is of type array<integer,object<EE_Base_Class>>, but the function expects a array<integer,object<EE_Message>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
917
918
		if ( ! $sent_queue instanceof EE_Messages_Queue ) {
919
			EE_Error::add_error(
920
				__( 'The messages were not sent.  This is usually because there is already a batch being sent on a separate request.  You can wait a minute or two and try again.', 'event_espresso' ),
921
				__FILE__, __FUNCTION__, __LINE__
922
			);
923
		} else {
924
			//can count how many sent by using the messages in the queue
925
			$sent_count = $sent_queue->count_STS_in_queue( EEM_Message::instance()->stati_indicating_sent() );
926 View Code Duplication
			if ( $sent_count > 0 ) {
927
				EE_Error::add_success(
928
					sprintf(
929
						_n(
930
							'There was %d message successfully sent.',
931
							'There were %d messages successfully sent.',
932
							$sent_count,
933
							'event_espresso'
934
						),
935
						$sent_count
936
					)
937
				);
938
			} else {
939
				EE_Error::overwrite_errors();
940
				EE_Error::add_error(
941
					__( 'No message was sent because of problems with sending. Either all the messages you selected were not a sendable message, they were ALREADY sent on a different scheduled task, or there was an error.
942
					If there was an error, you can look at the messages in the message activity list table for any error messages.', 'event_espresso' ),
943
					__FILE__, __FUNCTION__, __LINE__
944
				);
945
			}
946
		}
947
		return $sent_queue;
948
	}
949
950
951
952
953
954
	/**
955
	 * This will queue the incoming message ids for resending.
956
	 * Note, only message_ids corresponding to messages with the status of EEM_Message::sent will be queued.
957
	 *
958
	 * @since 4.9.0
959
	 * @param array $message_ids  An array of EE_Message IDs
960
	 *
961
	 * @return bool  true means messages were successfully queued for resending, false means none were queued for resending.
962
	 */
963
	public static function queue_for_resending( $message_ids ) {
964
		self::_load_controller();
965
		self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send( $message_ids );
966
967
		//get queue and count
968
		$queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue( EEM_Message::status_resend );
969 View Code Duplication
		if ( $queue_count > 0 ) {
970
			EE_Error::add_success(
971
				sprintf(
972
					_n(
973
						'%d message successfully queued for resending.',
974
				        '%d messages successfully queued for resending.',
975
				        $queue_count,
976
				        'event_espresso'
977
				    ),
978
				    $queue_count
979
				)
980
			);
981
		} else {
982
			EE_Error::add_error(
983
				__( 'No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.', 'event_espresso' ),
984
				__FILE__, __FUNCTION__, __LINE__
985
			);
986
		}
987
		return (bool) $queue_count;
988
	}
989
990
991
992
993
994
995
	/**
996
	 * debug
997
	 *
998
	 * @param string $class
999
	 * @param string $func
1000
	 * @param string $line
1001
	 * @param \EE_Transaction $transaction
1002
	 * @param array $info
1003
	 * @param bool $display_request
1004
	 */
1005 View Code Duplication
	protected static function log( $class = '', $func = '', $line = '', EE_Transaction $transaction, $info = array(), $display_request = false ) {
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...
1006
		if ( WP_DEBUG && false ) {
1007
			if ( $transaction instanceof EE_Transaction ) {
1008
				// don't serialize objects
1009
				$info = EEH_Debug_Tools::strip_objects( $info );
1010
				$info['TXN_status'] = $transaction->status_ID();
1011
				$info['TXN_reg_steps'] = $transaction->reg_steps();
1012
				if ( $transaction->ID() ) {
1013
					$index = 'EE_Transaction: ' . $transaction->ID();
1014
					EEH_Debug_Tools::log( $class, $func, $line, $info, $display_request, $index );
1015
				}
1016
			}
1017
		}
1018
1019
	}
1020
1021
}
1022
// End of file EED_Messages.module.php
1023
// Location: /modules/messages/EED_Messages.module.php
1024