Completed
Branch BUG-9548-transaction-completio... (b1c41e)
by
unknown
519:42 queued 503:28
created

EE_messages   D

Complexity

Total Complexity 134

Size/Duplication

Total Lines 821
Duplicated Lines 3.53 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 134
c 2
b 0
f 0
lcom 1
cbo 10
dl 29
loc 821
rs 4.4444

25 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B _set_active_messengers_and_message_types() 0 20 6
A ensure_messenger_is_active() 0 10 2
A ensure_message_type_is_active() 3 16 3
C activate_messenger() 5 63 13
B _load_files() 0 26 4
B _unset_active() 5 23 6
A _is_generating_messenger_and_active() 0 13 4
F send_message() 4 91 17
B preview_message() 8 33 4
D _send_message() 0 31 9
B send_message_with_messenger_only() 0 19 6
C _validate_setup() 4 34 8
A create_new_templates() 0 18 4
A _create_new_templates() 0 20 2
C _create_custom_template_group() 0 48 10
A get_fields() 0 20 4
D get_installed() 0 29 10
B _get_installed() 0 18 5
A get_active_messengers() 0 3 1
A get_active_message_types() 0 11 4
A get_active_message_types_per_messenger() 0 16 4
A get_active_message_type() 0 7 3
A get_installed_message_types() 0 4 2
A get_installed_messengers() 0 4 2

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EE_messages often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EE_messages, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
if (!defined('EVENT_ESPRESSO_VERSION') )
4
	exit('NO direct script access allowed');
5
6
/**
7
 * Event Espresso
8
 *
9
 * Event Registration and Management Plugin for WordPress
10
 *
11
 * @ package			Event Espresso
12
 * @ author				Seth Shoultes
13
 * @ copyright		(c) 2008-2011 Event Espresso  All Rights Reserved.
14
 * @ license				http://eventespresso.com/support/terms-conditions/   * see Plugin Licensing *
15
 * @ link					http://www.eventespresso.com
16
 * @ version		 	4.0
17
 *
18
 * ------------------------------------------------------------------------
19
 *
20
 * EE_messages class
21
 *
22
 * This class is the main controller class for EE_messages, it delegates messages to the messengers and contains other methods for obtaining various details about the active messengers and message types.
23
 *
24
 * @package			Event Espresso
25
 * @subpackage	includes/core/messages
26
 * @author				Darren Ethier, Brent Christensen
27
 *
28
 * ------------------------------------------------------------------------
29
 */
30
class EE_messages {
31
32
	private $_active_messengers = array();
33
	private $_active_message_types = array();
34
	private $_installed_message_types = array();
35
	private $_messenger;
36
	private $_message_type;
37
	private $_installed_messengers = array();
38
39
	/**
40
	 * holds the EEM_message_templates model for interacting with the database and retrieving active templates for the messenger
41
	 * @var object
42
	 */
43
	private $_EEM_data;
44
	// main controller
45
	function __construct() {
46
47
		// get list of active messengers and active message types
48
		$this->_EEM_data = EEM_Message_Template::instance();
49
		$this->_set_active_messengers_and_message_types();
50
51
	}
52
53
	/**
54
	 * get active messengers from db and instantiate them.
55
	 */
56
	private function _set_active_messengers_and_message_types() {
57
		// todo: right now this just gets active global messengers: at some point we'll have to get what the active messengers are for the event.
58
		$_actives = EEH_MSG_Template::get_active_messengers_in_db();
59
		$actives = is_array($_actives) ? array_keys($_actives) : $_actives;
60
		$active_names = $this->_load_files('messenger', $actives);
61
62
		if ( is_array($active_names) ) {
63
			foreach ( $active_names as $name => $class ) {
64
				$a = new ReflectionClass( $class );
65
				$active = $a->newInstance();
66
				if ( is_wp_error($active) ) {
67
					//we've got an error so let's bubble up the error_object to be caught by caller.
68
					//todo: would be better to just catch the errors and then return any aggregated errors later.
69
					EE_Error::add_error($active->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
70
				}
71
				$this->_active_messengers[$name] = $active;
72
				$this->_active_message_types[$name] = ! empty( $_actives[$name]['settings'][$name . '-message_types'] ) ? $_actives[$name]['settings'][$name . '-message_types'] : array();
73
			}
74
		}
75
	}
76
77
	/**
78
	 * Ensures that the specified messenger is currently active.
79
	 * If not, activates it and its default message types.
80
	 * @param string $messenger_name
81
	 * @return boolean TRUE if it was PREVIOUSLY active, and FALSE if it was previously inactive
82
	 */
83
	public function ensure_messenger_is_active( $messenger_name ){
84
		//note: active messengers indexed by their names
85
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
86
		if( ! isset( $active_messengers[ $messenger_name ] ) ) {
87
			$this->activate_messenger( $messenger_name );
88
			return FALSE;
89
		}else{
90
			return TRUE;
91
		}
92
	}
93
94
95
96
	/**
97
	 * Ensures that tthe specified message type for the given messenger is currently active, if not activates it.
98
	 * This ALSO ensures that the given messenger is active as well!.
99
	 *
100
	 * @param string $message_type message type name
101
	 *
102
	 * @return boolean true if it got activated (or was active) and false if not.
103
	 */
104
	public function ensure_message_type_is_active( $message_type, $messenger ) {
105
		//first validate that the incoming messenger allows this message type to be activated.
106
		$messengers = $this->get_installed_messengers();
107
		if ( ! isset( $messengers[$messenger] ) ) {
108
			throw new EE_Error( sprintf( __('The messenger sent to %s is not installed', 'event_espresso'), __METHOD__ ) );
109
		}
110
111
		$msgr = $messengers[$messenger];
112
		$valid_message_types = $msgr->get_valid_message_types();
113 View Code Duplication
		if ( ! in_array( $message_type, $valid_message_types ) ) {
114
			throw new EE_Error( sprint_f( __('The message type ($1%s) sent to $2%s is not valid for the $3%s messenger.  Doublecheck the spelling and verify that message type has been registered as a valid type with the messenger.', 'event_espresso' ), $message_type, __METHOD__, $messenger ) );
115
		}
116
117
		//all is good so let's just get it active
118
		return $this->activate_messenger( $messenger, array( $message_type ) );
119
	}
120
121
	/**
122
	 * Activates the specified messenger
123
	 * @param string $messenger_name
124
	 * @param array $message_types (optional) An array of message types to activate with this messenger.  If
0 ignored issues
show
Bug introduced by
There is no parameter named $message_types. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
125
	 *                             				included we do NOT setup the default message types (assuming
126
	 *                             				they are already setup.)
127
	 * @return boolean an array of generated templates or false if nothing generated/activated.
128
	 */
129
	public function activate_messenger( $messenger_name, $mts = array() ){
130
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
131
		$message_types = $this->get_installed_message_types();
132
		$installed_messengers = $this->get_installed_messengers();
133
		$mts_to_activate = array();
0 ignored issues
show
Unused Code introduced by
$mts_to_activate is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
134
		$templates = false;
135
136
		//get has_active so we can be sure its kept up to date.
137
		$has_activated = get_option( 'ee_has_activated_messenger' );
138
139
		//grab the messenger to work with.
140
		$messenger = isset( $installed_messengers[$messenger_name] ) ? $installed_messengers[$messenger_name] : null;
141
142
		//it's inactive. Activate it.
143
144
		if( $messenger instanceof EE_messenger ) {
145
			$active_messengers[ $messenger->name ][ 'obj' ] = $messenger;
146
147
			/** @var EE_messenger[] $installed_messengers  */
148
			$mts_to_activate = ! empty( $mts ) ? $mts :  $messenger->get_default_message_types();
149
			foreach ( $mts_to_activate as $message_type ) {
150
				//we need to setup any initial settings for message types
151
				/** @var EE_message_type[] $installed_mts */
152
				$settings_fields = isset( $message_types[$message_type] ) ? $message_types[ $message_type ]->get_admin_settings_fields() : array();
153
				if ( !empty( $settings_fields ) ) {
154
					foreach ( $settings_fields as $field => $values ) {
155
						$settings[$field] = $values[ 'default' ];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$settings was never initialized. Although not strictly required by PHP, it is generally a good practice to add $settings = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
156
					}
157
				} else {
158
					$settings = array();
159
				}
160
161
				$active_messengers[ $messenger->name ][ 'settings' ][ $messenger->name . '-message_types' ][ $message_type ][ 'settings' ] = $settings;
0 ignored issues
show
Bug introduced by
The variable $settings does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
162
163
				if (  ! empty( $has_activated[$messenger->name] ) && ! in_array( $message_type, $has_activated[$messenger->name] ) ) {
164
					$has_activated[$messenger->name][] = $message_type;
165
				}
166
			}
167
168
			//setup any initial settings for the messenger
169
			$msgr_settings = $messenger->get_admin_settings_fields();
170
171 View Code Duplication
			if ( !empty( $msgr_settings ) ) {
172
				foreach ( $msgr_settings as $field => $value ) {
173
					$active_messengers[ $messenger->name ][ 'settings' ][ $field ] = $value;
174
				}
175
			}
176
177
			EEH_MSG_Template::update_active_messengers_in_db( $active_messengers );
178
			update_option( 'ee_has_activated_messenger', $has_activated );
179
180
			//make sure that the cached active_messengers is set on this object
181
			$this->_active_messengers[$messenger->name] = $messenger;
182
			$this->_active_message_types[$messenger->name] = $active_messengers[$messenger->name];
183
184
			//might need to generate new templates
185
			if ( ! empty( $mts_to_activate ) ) {
186
				$templates = EEH_MSG_Template::generate_new_templates( $messenger->name, $mts_to_activate, 0, TRUE );
187
			}
188
		}
189
190
		return $templates;
191
	}
192
193
194
195
196
197
198
	/**
199
	 * load the active files needed (key word... NEEDED)
200
	 * @param string $kind indicates what kind of files we are loading.
201
	 * @param array $actives indicates what active types of the $kind are actually to be loaded.
202
	 */
203
	private function _load_files($kind, $actives) {
204
		$active_names = array();
205
		$base_path = EE_LIBRARIES . 'messages' . DS . $kind . DS;
206
		if ( empty($actives) ) return false;
207
208
		//make sure autoloaders are set (failsafe)
209
		EED_Messages::set_autoloaders();
210
211
		//make sure $actives is an array
212
		$actives = (array) $actives;
213
214
		foreach ( $actives as $active ) {
215
			$msg_name = 'EE_' . ucwords( str_replace( ' ', '_', $active) ) . '_' . $kind;
216
			$filename = $msg_name . '.class.php';
217
			$load_file = $base_path . DS . $filename;
218
			if ( is_readable($load_file) ) {
219
				require_once($load_file);
220
				$active_names[$active] = $msg_name;
221
			} else {
222
				$this->_unset_active($active, $kind);
223
				//set WP_Error
224
				return EE_Error::add_error( sprintf( __("Missing messages system file set as inactive: (%s) %s has been made inactive.", 'event_espresso'), $load_file, $msg_name), __FILE__, __FUNCTION__, __LINE__ );
225
			}
226
		}
227
		return $active_names;
228
	}
229
230
231
232
233
	/**
234
	 * unsets the active if we can't find the file (failsafe)
235
	 *
236
	 * @access private
237
	 * @param  string $active_name name of messenger or message type
238
	 * @param  string $kind        messenger or message_type?
239
	 * @return void
240
	 */
241
	private function _unset_active( $active_name, $kind ) {
242
		//pluralize
243
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
244
		if ( $kind == 'messenger' ) {
245
			unset( $active_messengers[$active_name] );
246
			EEH_MSG_Template::update_to_inactive( $active_name );
247
			if ( isset( $this->_active_messengers[$active_name] ) ) {
248
				unset( $this->_active_messengers[$active_name] );
249
			}
250
		} else {
251 View Code Duplication
			foreach( $active_messengers as $messenger => $settings ) {
252
				if ( ! empty( $settings['settings'][$messenger . '-message_types'][$active_name] ) ) {
253
					unset( $active_messengers[$messenger]['settings'][$messenger . '-message_types'][$active_name] );
254
				}
255
			}
256
			EEH_MSG_Template::update_to_inactive( '', $active_name );
257
			if ( isset( $this->_active_message_types[$active_name] ) ) {
258
				unset( $this->_active_message_types[$active_name] );
259
			}
260
		}
261
262
		EEH_MSG_Template::update_active_messengers_in_db($active_messengers);
263
	}
264
265
266
267
268
	/**
269
	 * Used to verify if a message can be sent for the given messenger and message type and that it is a generating messenger (used for generating message templates).
270
	 *
271
	 * @param EE_messenger $messenger    messenger used in trigger
272
	 * @param EE_messagetype $message_type message type used in trigger
273
	 *
274
	 * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
275
	 */
276
	private function _is_generating_messenger_and_active( EE_messenger $messenger, EE_message_type $message_type ) {
277
		$generating_msgrs = array();
0 ignored issues
show
Unused Code introduced by
$generating_msgrs is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
278
		//get the $messengers the message type says it can be used with.
279
		$used_with = $message_type->with_messengers();
280
281
		foreach ( $used_with as $generating_msgr => $secondary_msgrs ) {
282
			if ( $messenger->name == $generating_msgr && isset( $this->_active_message_types[$generating_msgr][$message_type->name] ) ) {
283
				return true;
284
			}
285
		}
286
287
		return false;
288
	}
289
290
291
292
	/**
293
	 * delegates message sending to messengers
294
	 * @param  string  $type    What type of message are we sending (corresponds to message types)
295
	 * @param  mixed  $vars    Data being sent for parsing in the message
296
	 * @param  string $sending_messenger if included then we ONLY use the specified messenger for delivery.  Otherwise we cycle through all active messengers.
297
	 * @param string $generating_messenger if included then this messenger is used for generating the message templates (but not for sending).
298
	 * @param string $context If included then only a message type for a specific context will be generated.
299
	  * @param bool  $send 			       Default TRUE.  If false, then this will just return the generated EE_Messages objects which might be used by the trigger to setup a batch message (typically html messenger uses it).
300
	 * @return bool
301
	 */
302
	public function send_message( $type, $vars, $sending_messenger = '', $generating_messenger='', $context='', $send = TRUE ) {
303
304
		$error = FALSE;
305
		$installed_message_types = $this->get_installed_message_types();
306
//		$debug_index = 'Messages: ' . $type;
307
//		foreach ( $vars as $var ) {
308
//			if ( method_exists( $var, 'ID' ) ) {
309
//				$debug_index = get_class( $var ) .  ': ' . $var->ID();
310
//				break;
311
//			} else if ( is_object( $var )) {
312
//				$debug_index = spl_object_hash( $var );
313
//			}
314
//		}
315
		//EEH_Debug_Tools::log(
316
		//	__CLASS__, __FUNCTION__, __LINE__,
317
		//	array(
318
		//		'message_type' => $type,
319
		//		'incoming_data' => $vars,
320
		//		'sending_messenger' => $sending_messenger,
321
		//		'generating_messenger' => $generating_messenger,
322
		//		'context' => $context,
323
		//		'send' => $send,
324
		//		'installed_message_types' => $installed_message_types
325
		//		),
326
		//	false,
327
		//	$debug_index
328
		//);
329
330
		// is that a real class ?
331
		if ( isset(  $installed_message_types[$type] ) ) {
332
			//is the messenger specified? If so then let's see if can send.  This is the check where its possible secondary messengers might be in use.
333
			if ( !empty ( $sending_messenger ) ) {
334
				$generating_messenger =  !empty( $generating_messenger ) && !empty( $this->_active_messengers[$generating_messenger] ) ? $this->_active_messengers[$generating_messenger]: NULL;
335
				$generating_messenger = empty( $generating_messenger ) && ! empty( $this->_active_messengers[$sending_messenger] ) ? $this->_active_messengers[$sending_messenger] : $generating_messenger;
336
337
				if ( !$this->_is_generating_messenger_and_active( $generating_messenger, $installed_message_types[$type] ) ) {
338
					return false;
339
				}
340
				$sending_messenger = ! empty( $this->_active_messengers[$sending_messenger] ) ? $this->_active_messengers[$sending_messenger] : NULL;
341
342
				$context = !empty( $context ) ? $context : FALSE;
343
				$success = $this->_send_message( $generating_messenger, $installed_message_types[$type], $vars, $sending_messenger, $context, $send );
0 ignored issues
show
Bug introduced by
It seems like $context defined by !empty($context) ? $context : FALSE on line 342 can also be of type string; however, EE_messages::_send_message() does only seem to accept boolean, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
344
				if ( ! $send ) {
345
					return $success; //returning generated EE_Messages objects
346
				}
347
			} else {
348
				//no messenger sent so let's just loop through active messengers (this method is only acceptable for primary messengers)
349
				$send_messages = array();
350
				foreach ( $this->_active_messengers as $active_messenger ) {
351
352
					//we ONLY continue if the given messenger is a primary messenger and is an active messenger for the given message type.  Otherwise we skip.
353
					if ( ! $this->_is_generating_messenger_and_active( $active_messenger, $installed_message_types[$type] ) ) {
354
						continue;
355
					}
356
357
					$success = $this->_send_message( $active_messenger, $installed_message_types[$type], $vars, $active_messenger );
358
					if ( $success === FALSE  ) {
359
						$error = TRUE;
360
					} else {
361
						$send_messages[] = $success;
362
					}
363
				}
364
365
				//EEH_Debug_Tools::log(
366
				//	__CLASS__, __FUNCTION__, __LINE__,
367
				//	array(
368
				//		'message_type' => $type,
369
				//		'active_messenger' => $this->_active_messengers,
370
				//		'send_messages' => $send_messages,
371
				//		'error' => $error
372
				//		),
373
				//	false,
374
				//	$debug_index
375
				//	);
376
377
				//return generated EE_Messages objects?
378
				if ( ! $send ) {
379
					return $send_messages;
380
				}
381
			}
382 View Code Duplication
		} else {
383
			EE_Error::add_error( sprintf( __('Message type: %s does not exist', 'event_espresso'), $type ), __FILE__, __FUNCTION__, __LINE__ );
384
			return false;
385
		}
386
		// add a success message
387
		if ( ! $error ) {
388
			EE_Error::add_success( sprintf( __( 'The %s message has been successfully sent.', 'event_espresso'), $installed_message_types[$type]->label['singular'] ), __FILE__, __FUNCTION__, __LINE__ );
389
		}
390
391
		return $error ? FALSE : TRUE; //yeah backwards eh?  Really what we're returning is if there is a total success for all the messages or not.  We'll modify this once we get message recording in place.
392
	}
393
394
395
396
397
	/**
398
	 * Use to generate and return a message preview!
399
	 * @param  string $type    This should correspond with a valid message type
400
	 * @param  string $context This should correspond with a valid context for the message type
401
	 * @param  string $messenger This should correspond with a valid messenger.
402
	 * @param bool 	$send true we will do a test send using the messenger delivery, false we just do a regular preview
403
	 * @return string          The body of the message.
404
	 */
405
	public function preview_message( $type, $context, $messenger, $send = FALSE ) {
406
407
		$installed_message_types = $this->get_installed_message_types();
408
409
		//does the given type match an actual message type class.
410
		if ( isset(  $installed_message_types[$type] ) ) {
411
			// valid messenger?
412
			if ( isset( $this->_active_messengers[$messenger] ) ) {
413
414
				//we ONLY continue if the given messenger has that message type active with it (note previews only come from primary messengers so no need to check secondarys)
415
				if ( !isset( $this->_active_message_types[$messenger][$type] ) )
416
					return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by EE_messages::preview_message of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
417
418
				$message = $installed_message_types[$type];
419
				$messenger = $this->_active_messengers[$messenger];
420
421
				//set data for preview
422
				$message->set_messages( array(), $messenger, $context, TRUE );
423
424
				//let's GET the message body from the messenger (instead of the normal send_message)
425
				return $messenger->get_preview( $message->messages[0], $message, $send );
426
427 View Code Duplication
			} else {
428
				EE_Error::add_error( sprintf( __('Messenger: %s does not exist', 'event_espresso'), $messenger ), __FILE__, __FUNCTION__, __LINE__ );
429
				return FALSE;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return FALSE; (false) is incompatible with the return type documented by EE_messages::preview_message of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
430
			}
431
432 View Code Duplication
		} else {
433
			EE_Error::add_error( sprintf( __('Message type: %s does not exist', 'event_espresso'), $type ), __FILE__, __FUNCTION__, __LINE__ );
434
			return FALSE;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return FALSE; (false) is incompatible with the return type documented by EE_messages::preview_message of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
435
		}
436
437
	}
438
439
440
	/**
441
	 *  Executes sending a message via the given sending messenger (but generated via the given generating messenger).
442
	 *
443
	 * @since 4.5.0
444
	 *
445
	 * @param EE_messenger $generating_messenger The messenger used for generating messages
446
	 * @param EE_message_type $message_type         The message type used for generating messages
447
	 * @param mixed  $data                 Data provided for parsing shortcodes in message templates.
448
	 * @param EE_messenger $sending_messenger    The messenger that will be used for SENDING the messages.
449
	 * @param bool   $context              If provided, then a specific context for a given template will be sent.
450
	 * @param bool  $send 			       Default TRUE.  If false, then this will just return the generated EE_Messages std_Class objects which might be used by the trigger to setup a batch message (typically html messenger uses it).
451
	 *
452
	 * @return mixed(bool|std_Class[])
0 ignored issues
show
Documentation introduced by
The doc-type mixed(bool|std_Class[]) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (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...
453
	 */
454
	private function _send_message( EE_messenger $generating_messenger, EE_message_type $message_type, $data, EE_messenger $sending_messenger, $context = FALSE, $send = TRUE ) {
455
		//can't even get started yo!
456
		if ( $message_type === FALSE || is_wp_error( $message_type ) || $message_type->set_messages( $data, $generating_messenger, $context ) === FALSE ) {
0 ignored issues
show
Documentation introduced by
$context is of type boolean, but the function expects a string.

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...
457
			return FALSE;
458
		}
459
		// if the generating messenger and the sending messengers are different...
460
		// then are there any hooks that the generating messenger sets for the sending messenger (i.e. css file swap outs etc.)
461
		if ( $sending_messenger != $generating_messenger ) {
462
			$generating_messenger->do_secondary_messenger_hooks( $sending_messenger->name );
463
		}
464
		//it is possible that the user has the messenger turned off for this type.
465
		if ( $message_type->count === 0 ) {
466
			return FALSE;
467
		}
468
		//are we just sending the EE_Messages stdClass objects back?
469
		if ( ! $send ) {
470
			return $message_type->messages;
471
		}
472
		//TODO: check count (at some point we'll use this to decide whether we send to queue or not i.e.
473
		//if ( $message_type->count > 1000 ) ... do something
474
		//else...
475
		$success = TRUE;
476
		// $success is a flag for the loop.  If there is NO error then everything is a success (true) otherwise it wasn't a success (false)
477
		foreach ( $message_type->messages as $message ) {
478
			//todo: should we do some reporting on messages gone out at some point?  I think we could have the $active_messenger object return bool for whether message was sent or not and we can compile a report based on that.
479
			// if messages send successfully then $success retains it's value, but a single fail will toggle it to FALSE
480
			$success = $sending_messenger->send_message( $message, $message_type ) === TRUE ? $success : FALSE;
481
		}
482
		unset( $message_type );
483
		return $success;
484
	}
485
486
487
488
489
490
	/**
491
	 * This is a method that allows for sending a message using a messenger matching the string given and the provided EE_Message stdClass objects.
492
	 *
493
	 * @since 4.5.0
494
	 *
495
	 * @param string       $messenger a string matching a valid active messenger in the system
496
	 * @param string       $message_type   Although it seems contrary to the name of the method, a message type name is still required to send along the message type to the messenger because this is used for determining what specific variations might be loaded for the generated message.
497
	 * @param stdClass $messages  a stdClass object in the format expected by the messenger.
0 ignored issues
show
Documentation introduced by
There is no parameter named $messages. Did you maybe mean $message?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
498
	 *
499
	 * @return bool          success or fail.
500
	 */
501
	public function send_message_with_messenger_only( $messenger, $message_type, $message ) {
502
503
		//get EE_messenger object (which also checks if its active)
504
		$msgr =  !empty( $messenger ) && !empty( $this->_active_messengers[$messenger] ) ? $this->_active_messengers[$messenger]: NULL;
505
		$installed_message_types = $this->get_installed_message_types();
506
507
		if ( ! $msgr instanceof EE_messenger ) {
508
			return false; //can't do anything without a valid messenger.
509
		}
510
511
		//check valid message type
512
		$mtype = isset(  $installed_message_types[$message_type] ) ? $installed_message_types[$message_type] : NULL;
513
514
		if( ! $mtype instanceof EE_message_type ) {
515
			return false; //can't do anything without a valid message type.
516
		}
517
518
		return $msgr->send_message( $message, $mtype );
519
	}
520
521
522
523
524
525
	/**
526
	 * _validate_setup
527
	 * @param  string $messenger    EE_messenger
528
	 * @param  string $message_type EE_message_type
529
	 * @param bool $is_global whether this is a global template or not.
530
	 * @return bool(true)|wp_error_object
0 ignored issues
show
Documentation introduced by
The doc-type bool(true)|wp_error_object could not be parsed: Expected "|" or "end of type", but got "(" at position 4. (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...
531
	 */
532
	private function _validate_setup($messenger, $message_type, $is_global = FALSE) {
533
534
		$message_type = strtolower(str_replace(' ', '_', $message_type) );
535
		$messenger = strtolower(str_replace(' ', '_', $messenger));
536
		$installed_message_types = $this->get_installed_message_types();
537
538
539
		//setup messenger and message_type object
540
		$this->_messenger = isset($this->_active_messengers[$messenger]) ? $this->_active_messengers[$messenger] : null;
541
542
543
		//message type
544
		$mt = isset($installed_message_types[$message_type]) ? $installed_message_types[$message_type] : 'message_type_not_existent';
545
546
		$this->_message_type = is_object($mt) ? $mt : null;
547
548
549
		//do we have the necessary objects loaded?
550
		if ( empty( $this->_messenger) || empty($this->_message_type) )
551
			throw new EE_Error( sprintf( __(' The %s messenger or the %s message_type are not active. Are you sure they exist?', 'event_espresso'), $messenger, $message_type ) );
552
553
		//is given message_type valid for given messenger (if this is not a global save)
554
		$types_to_check = array();
0 ignored issues
show
Unused Code introduced by
$types_to_check is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
555
		if ( !$is_global ) {
556
			$has_active = EEM_Message_Template_Group::instance()->count( array( array( 'MTP_is_active' => TRUE, 'MTP_messenger' => $this->_messenger->name, 'MTP_message_type' => $message_type ) ) );
557
558 View Code Duplication
			if ( $has_active == 0 ) {
559
				EE_Error::add_error( sprintf(__(' The %s message type is not registered with the %s messenger. Please visit the Messenger activation page to assign this message type first if you want to use it.', 'event_espresso'), $message_type, $messenger), __FILE__, __FUNCTION__, __LINE__ );
560
				return false;
561
			}
562
563
		}
564
		return true;
565
	}
566
567
	/**
568
	 * This is a wrapper for the protected _create_new_templates function
569
	 * @param  string $message_type message type that the templates are being created for
570
	 * @return array|object               if creation is succesful then we return an array of info, otherwise an error_object is returned.
571
	 */
572
	public function create_new_templates( $messenger, $message_type, $GRP_ID = 0, $is_global = false ) {
573
		$valid_mt = false;
0 ignored issues
show
Unused Code introduced by
$valid_mt is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
574
575
		$valid_mt = $this->_validate_setup($messenger, $message_type, $is_global);
576
577
		if ( is_wp_error($valid_mt) && $is_global ) {
578
			//we're setting up a brand new global templates (with messenger activation) so we're assuming that the message types sent in are valid.
579
			$valid_mt = true;
580
		}
581
582
		if ( is_wp_error($valid_mt) ) {
583
			//if we've still got no valid_mt then bubble up error object
584
			return $valid_mt;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $valid_mt; (boolean) is incompatible with the return type documented by EE_messages::create_new_templates of type array|object.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
585
		}
586
587
		//whew made it this far!  Okay, let's go ahead and create the templates then
588
		return $this->_create_new_templates($GRP_ID, $is_global);
589
	}
590
591
	protected function _create_new_templates($GRP_ID, $is_global) {
592
593
		//if we're creating a custom template then we don't need to use the defaults class
594
		if ( ! $is_global )
595
			return $this->_create_custom_template_group( $GRP_ID );
596
597
		$DFLT = new EE_Message_Template_Defaults( $this, $this->_messenger->name, $this->_message_type->name, $GRP_ID );
598
599
		//generate templates
600
		$success = $DFLT->create_new_templates();
601
602
		/**
603
		 * $success is in an array in the following format
604
		 * array(
605
		 * 	'GRP_ID' => $new_grp_id,
606
		 * 	'MTP_context' => $first_context_in_new_templates,
607
		 * )
608
		 */
609
		return $success;
610
	}
611
612
613
614
	/**
615
	 * This creates a custom template using the incoming GRP_ID
616
	 *
617
	 * @param  int     $GRP_ID GRP_ID for the template_group being used as the base
618
	 * @return  array $success             This will be an array in the format:
619
	 *                                     			array(
620
	 *                                     				'GRP_ID' => $new_grp_id,
621
	 *                                     				'MTP_context' => $first_context_in_created_template
622
	 *                                     			)
623
	 * @access private
624
	 */
625
	private function _create_custom_template_group( $GRP_ID ) {
626
		//defaults
627
		$success = array( 'GRP_ID' => NULL, 'MTP_context' => '' );
628
629
		//get the template group to use as a template from the db.  If $GRP_ID is empty then we'll assume the base will be the global template matching the messenger and message type.
630
		$mtg = empty( $GRP_ID ) ? EEM_Message_Template_Group::instance()->get_one( array( array( 'MTP_messenger' => $this->_messenger->name, 'MTP_message_type' => $this->_message_type->name, 'MTP_is_global' => TRUE ) ) ) : EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
631
632
		//if we don't have a mtg at this point then we need to bail.
633
		if ( ! $mtg instanceof EE_Message_Template_Group ) {
634
			EE_Error::add_error( sprintf( __('Something went wrong with generating the custom template from this group id: %s.  This usually happens when there is no matching message template group in the db.', 'event_espresso'), $GRP_ID ), __FILE__, __FUNCTION__, __LINE__ );
635
			return $success;
636
		}
637
638
		//let's get all the related message_template objects for this group.
639
		$mtts = $mtg->message_templates();
640
641
		//now we have what we need to setup the new template
642
		$new_mtg = clone $mtg;
643
		$new_mtg->set('GRP_ID', 0);
644
		$new_mtg->set('MTP_is_global', FALSE);
645
646
		$template_name = defined('DOING_AJAX') && !empty( $_POST['templateName'] ) ? $_POST['templateName'] : __('New Custom Template', 'event_espresso');
647
		$template_description = defined("DOING_AJAX") && !empty( $_POST['templateDescription'] ) ? $_POST['templateDescription'] : sprintf( __('This is a custom template that was created for the %s messenger and %s message type.', 'event_espresso' ), $new_mtg->messenger_obj()->label['singular'], $new_mtg->message_type_obj()->label['singular'] );
648
649
650
		$new_mtg->set('MTP_name', $template_name );
651
		$new_mtg->set('MTP_description', $template_description );
652
		//remove ALL relations on this template group so they don't get saved!
653
		$new_mtg->_remove_relations( 'Message_Template' );
654
		$new_mtg->save();
655
		$success['GRP_ID'] = $new_mtg->ID();
656
		$success['template_name'] = $template_name;
657
658
		//add new message templates and add relation to.
659
		foreach ( $mtts as $mtt ) {
660
			if ( ! $mtt instanceof EE_Message_Template )
661
				continue;
662
			$nmtt = clone $mtt;
663
			$nmtt->set('MTP_ID', 0);
664
			$nmtt->set( 'GRP_ID', $new_mtg->ID() ); //relation
665
			$nmtt->save();
666
			if ( empty( $success['MTP_context'] ) )
667
				$success['MTP_context'] = $nmtt->get('MTP_context');
668
		}
669
670
		return $success;
671
672
	}
673
674
675
676
677
	/**
678
	 * get_fields
679
	 * This takes a given messenger and message type and returns all the template fields indexed by context (and with field type).
680
	 * @param  string $messenger    EE_messenger
681
	 * @param  string $message_type EE_message_type
682
	 * @return array|wp_error_object  template fields indexed by context.
683
	 */
684
	public function get_fields($messenger, $message_type) {
685
		$template_fields = array();
686
687
		$valid_msg = $this->_validate_setup($messenger, $message_type);
0 ignored issues
show
Unused Code introduced by
$valid_msg is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
688
689
690
		//okay now let's assemble an array with the messenger template fields added to the message_type contexts.
691
		foreach ( $this->_message_type->get_contexts() as $context => $details ) {
692
			foreach ( $this->_messenger->get_template_fields() as $field => $value ) {
693
				$template_fields[$context][$field] = $value;
694
			}
695
		}
696
697
		if ( empty($template_fields) ) {
698
			EE_Error::add_error( __('Something went wrong and we couldn\'t get any templates assembled', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
699
			return FALSE;
700
		}
701
702
		return $template_fields;
703
	}
704
705
	/**
706
	 * gets an array of installed messengers and message types objects.
707
	 *
708
	 * @access public
709
	 * @param string $type we can indicate just returning installed message types or messengers (or both) via this parameter.
710
	 * @param bool  $set if true then we skip the cache and retrieve via files.
0 ignored issues
show
Bug introduced by
There is no parameter named $set. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
711
	 * @return array multidimensional array of messenger and message_type objects (messengers index, and message_type index);
712
	 */
713
	public function get_installed( $type = 'all', $skip_cache = false ) {
714
		$installed = array();
715
716
		//first let's account for caching
717
		if ( $skip_cache ) {
718
			$message_base = EE_LIBRARIES . "messages" . DS;
719
720
			$messenger_files = $type == 'all' || $type == 'messengers' ? scandir( $message_base . "messenger", 1) : NULL;
721
			$messagetype_files = $type == 'all' || $type == 'message_types' ? scandir( $message_base . "message_type", 1) : NULL;
722
723
724
			//allow plugins to filter in their messenger/message_type files
725
			$messenger_files = apply_filters('FHEE__EE_messages__get_installed__messenger_files', $messenger_files, $type );
726
			$messagetype_files = apply_filters('FHEE__EE_messages__get_installed__messagetype_files', $messagetype_files, $type );
727
728
			$installed['messengers'] = !empty($messenger_files ) ? $this->_get_installed($messenger_files) : '';
729
			$installed['message_types'] = !empty($messagetype_files) ? $this->_get_installed($messagetype_files) : '';
730
		} else {
731
			$installed['messengers'] = $this->get_installed_messengers();
732
			$installed['message_types'] = $this->get_installed_message_types();
733
		}
734
735
736
		if ( $type != 'all' ) {
737
			$installed = $type == 'messengers' ? $installed['messengers'] : $installed['message_types'];
738
		}
739
740
		return $installed;
741
	}
742
743
	/**
744
	 * _get_installed
745
	 * takes an array of filenames and returns an array of objects instantiated from the class name found in the filename.
746
	 * @param  array $filenames and array of filenames
747
	 * @return array       array of objects
748
	 */
749
	private function _get_installed($filenames) {
750
		//make sure incoming filenames are in an array.
751
		$the_goods = array();
752
		$filenames = (array) $filenames;
753
		$replace = ".class.php";
754
		foreach ( $filenames as $filename ) {
755
			$classname = preg_match("/" . $replace . "/", $filename ) ? str_replace($replace, "", $filename) : false;
756
757
			//no classname? no match? move along, nothing to see here. note, the stripos is checking to make sure the filename (classname) begins with EE.
758
			if ( !$classname || 0 !== stripos($classname, 'EE') ) continue;
759
760
			//note: I'm not sure if this will work without including the file.  We do have autoloaders so it "may" work.
761
			$a = new ReflectionClass($classname);
762
			$obj = $a->newInstance();
763
			$the_goods[$obj->name] = $obj;
764
		}
765
		return $the_goods;
766
	}
767
768
	public function get_active_messengers() {
769
		return $this->_active_messengers;
770
	}
771
772
773
	/**
774
	 * This does NOT return the _active_message_types property but simply returns an array of active message types from that property.  (The _active_message_types property is indexed by messenger and active message_types per messenger).
775
	 *
776
	 * @access public
777
	 * @return array array of message_type references
778
	 */
779
	public function get_active_message_types() {
780
		$message_types = array();
781
		foreach ( $this->_active_message_types as $messenger => $mtvalues ) {
782
			foreach ( $mtvalues as $mt => $config ) {
783
				if ( !in_array( $mt, $message_types ) )
784
					$message_types[] = $mt;
785
			}
786
		}
787
788
		return $message_types;
789
	}
790
791
792
793
794
	/**
795
	 * This checks the _active_message_types property for any active message types that are present for the given messenger and returns them.
796
	 *
797
	 * @since 4.5.0
798
	 *
799
	 * @param string $messenger The messenger being checked
800
	 *
801
	 * @return EE_message_type[]    (or empty array if none present)
802
	 */
803
	public function get_active_message_types_per_messenger( $messenger ) {
804
		$messenger = (string) $messenger;
805
		if ( empty( $this->_active_message_types[$messenger] ) ) {
806
			return array();
807
		}
808
809
		$mts = array();
810
		$message_types = $this->_active_message_types[$messenger];
811
		$installed_message_types = $this->get_installed_message_types();
812
		foreach ( $message_types as $mt => $settings ) {
813
			if ( ! empty( $installed_message_types[$mt] ) )  {
814
				$mts[] = $installed_message_types[$mt];
815
			}
816
		}
817
		return $mts;
818
	}
819
820
821
	/**
822
	 * This returns the EE_message_type from the active message types array ( if present );
823
	 *
824
	 * @param string $messenger      The string should correspond to the messenger (message types are
825
	 *                               		    assigned to a messenger in the messages settings)
826
	 * @param string $message_type The string should correspond to a message type.
827
	 *
828
	 * @return EE_Message_Type|null
829
	 */
830
	public function get_active_message_type( $messenger, $message_type ) {
831
		$installed_message_types = $this->get_installed_message_types();
832
		if ( !empty( $this->_active_message_types[$messenger][$message_type] ) && !empty( $installed_message_types[$message_type] ) )  {
833
			return $installed_message_types[$message_type];
834
		}
835
		return NULL;
836
	}
837
838
839
840
	public function get_installed_message_types() {
841
		$this->_installed_message_types = empty( $this->_installed_message_types ) ? $this->get_installed( 'message_types', true ) : $this->_installed_message_types;
842
		return $this->_installed_message_types;
843
	}
844
845
846
	public function get_installed_messengers() {
847
		$this->_installed_messengers = empty( $this->_installed_messengers ) ? $this->get_installed( 'messengers', true ) : $this->_installed_messengers;
848
		return $this->_installed_messengers;
849
	}
850
}
851
//end EE_messages class
852
853
// end of file:	includes/core/messages/EE_messages.core.php
854