Completed
Branch TASK-9118-extensions-page (04eaec)
by
unknown
940:32 queued 926:38
created

EE_messages::preview_message()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 33
Code Lines 16

Duplication

Lines 8
Ratio 24.24 %
Metric Value
dl 8
loc 33
rs 8.5806
cc 4
eloc 16
nc 4
nop 4
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
		//load helper
47
		EE_Registry::instance()->load_helper('MSG_Template');
48
49
		// get list of active messengers and active message types
50
		$this->_EEM_data = EEM_Message_Template::instance();
51
		$this->_set_active_messengers_and_message_types();
52
53
		//load debug tools
54
		EE_Registry::instance()->load_helper('Debug_Tools');
55
	}
56
57
	/**
58
	 * get active messengers from db and instantiate them.
59
	 */
60
	private function _set_active_messengers_and_message_types() {
61
		// 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.
62
		$_actives = EEH_MSG_Template::get_active_messengers_in_db();
63
		$actives = is_array($_actives) ? array_keys($_actives) : $_actives;
64
		$active_names = $this->_load_files('messenger', $actives);
65
66
		if ( is_array($active_names) ) {
67
			foreach ( $active_names as $name => $class ) {
68
				$a = new ReflectionClass( $class );
69
				$active = $a->newInstance();
70
				if ( is_wp_error($active) ) {
71
					//we've got an error so let's bubble up the error_object to be caught by caller.
72
					//todo: would be better to just catch the errors and then return any aggregated errors later.
73
					EE_Error::add_error($active->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
74
				}
75
				$this->_active_messengers[$name] = $active;
76
				$this->_active_message_types[$name] = ! empty( $_actives[$name]['settings'][$name . '-message_types'] ) ? $_actives[$name]['settings'][$name . '-message_types'] : array();
77
			}
78
		}
79
	}
80
81
	/**
82
	 * Ensures that the specified messenger is currently active.
83
	 * If not, activates it and its default message types.
84
	 * @param string $messenger_name
85
	 * @return boolean TRUE if it was PREVIOUSLY active, and FALSE if it was previously inactive
86
	 */
87
	public function ensure_messenger_is_active( $messenger_name ){
88
		//note: active messengers indexed by their names
89
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
90
		if( ! isset( $active_messengers[ $messenger_name ] ) ) {
91
			$this->activate_messenger( $messenger_name );
92
			return FALSE;
93
		}else{
94
			return TRUE;
95
		}
96
	}
97
98
99
100
	/**
101
	 * Ensures that tthe specified message type for the given messenger is currently active, if not activates it.
102
	 * This ALSO ensures that the given messenger is active as well!.
103
	 *
104
	 * @param string $message_type message type name
105
	 *
106
	 * @return boolean true if it got activated (or was active) and false if not.
107
	 */
108
	public function ensure_message_type_is_active( $message_type, $messenger ) {
109
		//first validate that the incoming messenger allows this message type to be activated.
110
		$messengers = $this->get_installed_messengers();
111
		if ( ! isset( $messengers[$messenger] ) ) {
112
			throw new EE_Error( sprintf( __('The messenger sent to %s is not installed', 'event_espresso'), __METHOD__ ) );
113
		}
114
115
		$msgr = $messengers[$messenger];
116
		$valid_message_types = $msgr->get_valid_message_types();
117 View Code Duplication
		if ( ! in_array( $message_type, $valid_message_types ) ) {
118
			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 ) );
119
		}
120
121
		//all is good so let's just get it active
122
		return $this->activate_messenger( $messenger, array( $message_type ) );
123
	}
124
125
	/**
126
	 * Activates the specified messenger
127
	 * @param string $messenger_name
128
	 * @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...
129
	 *                             				included we do NOT setup the default message types (assuming
130
	 *                             				they are already setup.)
131
	 * @return boolean an array of generated templates or false if nothing generated/activated.
132
	 */
133
	public function activate_messenger( $messenger_name, $mts = array() ){
134
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
135
		$message_types = $this->get_installed_message_types();
136
		$installed_messengers = $this->get_installed_messengers();
137
		$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...
138
		$templates = false;
139
140
		//get has_active so we can be sure its kept up to date.
141
		$has_activated = get_option( 'ee_has_activated_messenger' );
142
143
		//grab the messenger to work with.
144
		$messenger = isset( $installed_messengers[$messenger_name] ) ? $installed_messengers[$messenger_name] : null;
145
146
		//it's inactive. Activate it.
147
148
		if( $messenger instanceof EE_messenger ) {
149
			$active_messengers[ $messenger->name ][ 'obj' ] = $messenger;
150
151
			/** @var EE_messenger[] $installed_messengers  */
152
			$mts_to_activate = ! empty( $mts ) ? $mts :  $messenger->get_default_message_types();
153
			foreach ( $mts_to_activate as $message_type ) {
154
				//we need to setup any initial settings for message types
155
				/** @var EE_message_type[] $installed_mts */
156
				$settings_fields = isset( $message_types[$message_type] ) ? $message_types[ $message_type ]->get_admin_settings_fields() : array();
157
				if ( !empty( $settings_fields ) ) {
158
					foreach ( $settings_fields as $field => $values ) {
159
						$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...
160
					}
161
				} else {
162
					$settings = array();
163
				}
164
165
				$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...
166
167
				if (  ! empty( $has_activated[$messenger->name] ) && ! in_array( $message_type, $has_activated[$messenger->name] ) ) {
168
					$has_activated[$messenger->name][] = $message_type;
169
				}
170
			}
171
172
			//setup any initial settings for the messenger
173
			$msgr_settings = $messenger->get_admin_settings_fields();
174
175 View Code Duplication
			if ( !empty( $msgr_settings ) ) {
176
				foreach ( $msgr_settings as $field => $value ) {
177
					$active_messengers[ $messenger->name ][ 'settings' ][ $field ] = $value;
178
				}
179
			}
180
181
			EEH_MSG_Template::update_active_messengers_in_db( $active_messengers );
182
			update_option( 'ee_has_activated_messenger', $has_activated );
183
184
			//make sure that the cached active_messengers is set on this object
185
			$this->_active_messengers[$messenger->name] = $messenger;
186
			$this->_active_message_types[$messenger->name] = $active_messengers[$messenger->name];
187
188
			//might need to generate new templates
189
			if ( ! empty( $mts_to_activate ) ) {
190
				$templates = EEH_MSG_Template::generate_new_templates( $messenger->name, $mts_to_activate, 0, TRUE );
191
			}
192
		}
193
194
		return $templates;
195
	}
196
197
198
199
200
201
202
	/**
203
	 * load the active files needed (key word... NEEDED)
204
	 * @param string $kind indicates what kind of files we are loading.
205
	 * @param array $actives indicates what active types of the $kind are actually to be loaded.
206
	 */
207
	private function _load_files($kind, $actives) {
208
		$active_names = array();
209
		$base_path = EE_LIBRARIES . 'messages' . DS . $kind . DS;
210
		if ( empty($actives) ) return false;
211
212
		//make sure autoloaders are set (failsafe)
213
		EED_Messages::set_autoloaders();
214
215
		//make sure $actives is an array
216
		$actives = (array) $actives;
217
218
		EE_Registry::instance()->load_helper( 'File' );
219
		foreach ( $actives as $active ) {
220
			$msg_name = 'EE_' . ucwords( str_replace( ' ', '_', $active) ) . '_' . $kind;
221
			$filename = $msg_name . '.class.php';
222
			$load_file = $base_path . DS . $filename;
223
			if ( is_readable($load_file) ) {
224
				require_once($load_file);
225
				$active_names[$active] = $msg_name;
226
			} else {
227
				$this->_unset_active($active, $kind);
228
				//set WP_Error
229
				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__ );
230
			}
231
		}
232
		return $active_names;
233
	}
234
235
236
237
238
	/**
239
	 * unsets the active if we can't find the file (failsafe)
240
	 *
241
	 * @access private
242
	 * @param  string $active_name name of messenger or message type
243
	 * @param  string $kind        messenger or message_type?
244
	 * @return void
245
	 */
246
	private function _unset_active( $active_name, $kind ) {
247
		//pluralize
248
		$active_messengers = EEH_MSG_Template::get_active_messengers_in_db();
249
		EE_Registry::instance()->load_helper( 'MSG_Template' );
250
		if ( $kind == 'messenger' ) {
251
			unset( $active_messengers[$active_name] );
252
			EEH_MSG_Template::update_to_inactive( $active_name );
253
			if ( isset( $this->_active_messengers[$active_name] ) ) {
254
				unset( $this->_active_messengers[$active_name] );
255
			}
256
		} else {
257 View Code Duplication
			foreach( $active_messengers as $messenger => $settings ) {
258
				if ( ! empty( $settings['settings'][$messenger . '-message_types'][$active_name] ) ) {
259
					unset( $active_messengers[$messenger]['settings'][$messenger . '-message_types'][$active_name] );
260
				}
261
			}
262
			EEH_MSG_Template::update_to_inactive( '', $active_name );
263
			if ( isset( $this->_active_message_types[$active_name] ) ) {
264
				unset( $this->_active_message_types[$active_name] );
265
			}
266
		}
267
268
		EEH_MSG_Template::update_active_messengers_in_db($active_messengers);
269
	}
270
271
272
273
274
	/**
275
	 * 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).
276
	 *
277
	 * @param EE_messenger $messenger    messenger used in trigger
278
	 * @param EE_messagetype $message_type message type used in trigger
279
	 *
280
	 * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
281
	 */
282
	private function _is_generating_messenger_and_active( EE_messenger $messenger, EE_message_type $message_type ) {
283
		$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...
284
		//get the $messengers the message type says it can be used with.
285
		$used_with = $message_type->with_messengers();
286
287
		foreach ( $used_with as $generating_msgr => $secondary_msgrs ) {
288
			if ( $messenger->name == $generating_msgr && isset( $this->_active_message_types[$generating_msgr][$message_type->name] ) ) {
289
				return true;
290
			}
291
		}
292
293
		return false;
294
	}
295
296
297
298
	/**
299
	 * delegates message sending to messengers
300
	 * @param  string  $type    What type of message are we sending (corresponds to message types)
301
	 * @param  mixed  $vars    Data being sent for parsing in the message
302
	 * @param  string $sending_messenger if included then we ONLY use the specified messenger for delivery.  Otherwise we cycle through all active messengers.
303
	 * @param string $generating_messenger if included then this messenger is used for generating the message templates (but not for sending).
304
	 * @param string $context If included then only a message type for a specific context will be generated.
305
	  * @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).
306
	 * @return bool
307
	 */
308
	public function send_message( $type, $vars, $sending_messenger = '', $generating_messenger='', $context='', $send = TRUE ) {
309
310
		$error = FALSE;
311
		$installed_message_types = $this->get_installed_message_types();
312
//		$debug_index = 'Messages: ' . $type;
313
//		foreach ( $vars as $var ) {
314
//			if ( method_exists( $var, 'ID' ) ) {
315
//				$debug_index = get_class( $var ) .  ': ' . $var->ID();
316
//				break;
317
//			} else if ( is_object( $var )) {
318
//				$debug_index = spl_object_hash( $var );
319
//			}
320
//		}
321
		//EEH_Debug_Tools::log(
322
		//	__CLASS__, __FUNCTION__, __LINE__,
323
		//	array(
324
		//		'message_type' => $type,
325
		//		'incoming_data' => $vars,
326
		//		'sending_messenger' => $sending_messenger,
327
		//		'generating_messenger' => $generating_messenger,
328
		//		'context' => $context,
329
		//		'send' => $send,
330
		//		'installed_message_types' => $installed_message_types
331
		//		),
332
		//	false,
333
		//	$debug_index
334
		//);
335
336
		// is that a real class ?
337
		if ( isset(  $installed_message_types[$type] ) ) {
338
			//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.
339
			if ( !empty ( $sending_messenger ) ) {
340
				$generating_messenger =  !empty( $generating_messenger ) && !empty( $this->_active_messengers[$generating_messenger] ) ? $this->_active_messengers[$generating_messenger]: NULL;
341
				$generating_messenger = empty( $generating_messenger ) && ! empty( $this->_active_messengers[$sending_messenger] ) ? $this->_active_messengers[$sending_messenger] : $generating_messenger;
342
343
				if ( !$this->_is_generating_messenger_and_active( $generating_messenger, $installed_message_types[$type] ) ) {
344
					return false;
345
				}
346
				$sending_messenger = ! empty( $this->_active_messengers[$sending_messenger] ) ? $this->_active_messengers[$sending_messenger] : NULL;
347
348
				$context = !empty( $context ) ? $context : FALSE;
349
				$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 348 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...
350
				if ( ! $send ) {
351
					return $success; //returning generated EE_Messages objects
352
				}
353
			} else {
354
				//no messenger sent so let's just loop through active messengers (this method is only acceptable for primary messengers)
355
				$send_messages = array();
356
				foreach ( $this->_active_messengers as $active_messenger ) {
357
358
					//we ONLY continue if the given messenger is a primary messenger and is an active messenger for the given message type.  Otherwise we skip.
359
					if ( ! $this->_is_generating_messenger_and_active( $active_messenger, $installed_message_types[$type] ) ) {
360
						continue;
361
					}
362
363
					$success = $this->_send_message( $active_messenger, $installed_message_types[$type], $vars, $active_messenger );
364
					if ( $success === FALSE  ) {
365
						$error = TRUE;
366
					} else {
367
						$send_messages[] = $success;
368
					}
369
				}
370
371
				//EEH_Debug_Tools::log(
372
				//	__CLASS__, __FUNCTION__, __LINE__,
373
				//	array(
374
				//		'message_type' => $type,
375
				//		'active_messenger' => $this->_active_messengers,
376
				//		'send_messages' => $send_messages,
377
				//		'error' => $error
378
				//		),
379
				//	false,
380
				//	$debug_index
381
				//	);
382
383
				//return generated EE_Messages objects?
384
				if ( ! $send ) {
385
					return $send_messages;
386
				}
387
			}
388 View Code Duplication
		} else {
389
			EE_Error::add_error( sprintf( __('Message type: %s does not exist', 'event_espresso'), $type ), __FILE__, __FUNCTION__, __LINE__ );
390
			return false;
391
		}
392
		// add a success message
393
		if ( ! $error ) {
394
			EE_Error::add_success( sprintf( __( 'The %s message has been successfully sent.', 'event_espresso'), $installed_message_types[$type]->label['singular'] ), __FILE__, __FUNCTION__, __LINE__ );
395
		}
396
397
		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.
398
	}
399
400
401
402
403
	/**
404
	 * Use to generate and return a message preview!
405
	 * @param  string $type    This should correspond with a valid message type
406
	 * @param  string $context This should correspond with a valid context for the message type
407
	 * @param  string $messenger This should correspond with a valid messenger.
408
	 * @param bool 	$send true we will do a test send using the messenger delivery, false we just do a regular preview
409
	 * @return string          The body of the message.
410
	 */
411
	public function preview_message( $type, $context, $messenger, $send = FALSE ) {
412
413
		$installed_message_types = $this->get_installed_message_types();
414
415
		//does the given type match an actual message type class.
416
		if ( isset(  $installed_message_types[$type] ) ) {
417
			// valid messenger?
418
			if ( isset( $this->_active_messengers[$messenger] ) ) {
419
420
				//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)
421
				if ( !isset( $this->_active_message_types[$messenger][$type] ) )
422
					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...
423
424
				$message = $installed_message_types[$type];
425
				$messenger = $this->_active_messengers[$messenger];
426
427
				//set data for preview
428
				$message->set_messages( array(), $messenger, $context, TRUE );
429
430
				//let's GET the message body from the messenger (instead of the normal send_message)
431
				return $messenger->get_preview( $message->messages[0], $message, $send );
432
433 View Code Duplication
			} else {
434
				EE_Error::add_error( sprintf( __('Messenger: %s does not exist', 'event_espresso'), $messenger ), __FILE__, __FUNCTION__, __LINE__ );
435
				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...
436
			}
437
438 View Code Duplication
		} else {
439
			EE_Error::add_error( sprintf( __('Message type: %s does not exist', 'event_espresso'), $type ), __FILE__, __FUNCTION__, __LINE__ );
440
			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...
441
		}
442
443
	}
444
445
446
	/**
447
	 *  Executes sending a message via the given sending messenger (but generated via the given generating messenger).
448
	 *
449
	 * @since 4.5.0
450
	 *
451
	 * @param EE_messenger $generating_messenger The messenger used for generating messages
452
	 * @param EE_message_type $message_type         The message type used for generating messages
453
	 * @param mixed  $data                 Data provided for parsing shortcodes in message templates.
454
	 * @param EE_messenger $sending_messenger    The messenger that will be used for SENDING the messages.
455
	 * @param bool   $context              If provided, then a specific context for a given template will be sent.
456
	 * @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).
457
	 *
458
	 * @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...
459
	 */
460
	private function _send_message( EE_messenger $generating_messenger, EE_message_type $message_type, $data, EE_messenger $sending_messenger, $context = FALSE, $send = TRUE ) {
461
		//can't even get started yo!
462
		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...
463
			return FALSE;
464
		}
465
		// if the generating messenger and the sending messengers are different...
466
		// then are there any hooks that the generating messenger sets for the sending messenger (i.e. css file swap outs etc.)
467
		if ( $sending_messenger != $generating_messenger ) {
468
			$generating_messenger->do_secondary_messenger_hooks( $sending_messenger->name );
469
		}
470
		//it is possible that the user has the messenger turned off for this type.
471
		if ( $message_type->count === 0 ) {
472
			return FALSE;
473
		}
474
		//are we just sending the EE_Messages stdClass objects back?
475
		if ( ! $send ) {
476
			return $message_type->messages;
477
		}
478
		//TODO: check count (at some point we'll use this to decide whether we send to queue or not i.e.
479
		//if ( $message_type->count > 1000 ) ... do something
480
		//else...
481
		$success = TRUE;
482
		// $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)
483
		foreach ( $message_type->messages as $message ) {
484
			//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.
485
			// if messages send successfully then $success retains it's value, but a single fail will toggle it to FALSE
486
			$success = $sending_messenger->send_message( $message, $message_type ) === TRUE ? $success : FALSE;
487
		}
488
		unset( $message_type );
489
		return $success;
490
	}
491
492
493
494
495
496
	/**
497
	 * This is a method that allows for sending a message using a messenger matching the string given and the provided EE_Message stdClass objects.
498
	 *
499
	 * @since 4.5.0
500
	 *
501
	 * @param string       $messenger a string matching a valid active messenger in the system
502
	 * @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.
503
	 * @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...
504
	 *
505
	 * @return bool          success or fail.
506
	 */
507
	public function send_message_with_messenger_only( $messenger, $message_type, $message ) {
508
509
		//get EE_messenger object (which also checks if its active)
510
		$msgr =  !empty( $messenger ) && !empty( $this->_active_messengers[$messenger] ) ? $this->_active_messengers[$messenger]: NULL;
511
		$installed_message_types = $this->get_installed_message_types();
512
513
		if ( ! $msgr instanceof EE_messenger ) {
514
			return false; //can't do anything without a valid messenger.
515
		}
516
517
		//check valid message type
518
		$mtype = isset(  $installed_message_types[$message_type] ) ? $installed_message_types[$message_type] : NULL;
519
520
		if( ! $mtype instanceof EE_message_type ) {
521
			return false; //can't do anything without a valid message type.
522
		}
523
524
		return $msgr->send_message( $message, $mtype );
525
	}
526
527
528
529
530
531
	/**
532
	 * _validate_setup
533
	 * @param  string $messenger    EE_messenger
534
	 * @param  string $message_type EE_message_type
535
	 * @param bool $is_global whether this is a global template or not.
536
	 * @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...
537
	 */
538
	private function _validate_setup($messenger, $message_type, $is_global = FALSE) {
539
540
		$message_type = strtolower(str_replace(' ', '_', $message_type) );
541
		$messenger = strtolower(str_replace(' ', '_', $messenger));
542
		$installed_message_types = $this->get_installed_message_types();
543
544
545
		//setup messenger and message_type object
546
		$this->_messenger = isset($this->_active_messengers[$messenger]) ? $this->_active_messengers[$messenger] : null;
547
548
549
		//message type
550
		$mt = isset($installed_message_types[$message_type]) ? $installed_message_types[$message_type] : 'message_type_not_existent';
551
552
		$this->_message_type = is_object($mt) ? $mt : null;
553
554
555
		//do we have the necessary objects loaded?
556
		if ( empty( $this->_messenger) || empty($this->_message_type) )
557
			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 ) );
558
559
		//is given message_type valid for given messenger (if this is not a global save)
560
		$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...
561
		if ( !$is_global ) {
562
			$has_active = EEM_Message_Template_Group::instance()->count( array( array( 'MTP_is_active' => TRUE, 'MTP_messenger' => $this->_messenger->name, 'MTP_message_type' => $message_type ) ) );
563
564 View Code Duplication
			if ( $has_active == 0 ) {
565
				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__ );
566
				return false;
567
			}
568
569
		}
570
		return true;
571
	}
572
573
	/**
574
	 * This is a wrapper for the protected _create_new_templates function
575
	 * @param  string $message_type message type that the templates are being created for
576
	 * @return array|object               if creation is succesful then we return an array of info, otherwise an error_object is returned.
577
	 */
578
	public function create_new_templates( $messenger, $message_type, $GRP_ID = 0, $is_global = false ) {
579
		$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...
580
581
		$valid_mt = $this->_validate_setup($messenger, $message_type, $is_global);
582
583
		if ( is_wp_error($valid_mt) && $is_global ) {
584
			//we're setting up a brand new global templates (with messenger activation) so we're assuming that the message types sent in are valid.
585
			$valid_mt = true;
586
		}
587
588
		if ( is_wp_error($valid_mt) ) {
589
			//if we've still got no valid_mt then bubble up error object
590
			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...
591
		}
592
593
		//whew made it this far!  Okay, let's go ahead and create the templates then
594
		return $this->_create_new_templates($GRP_ID, $is_global);
595
	}
596
597
	protected function _create_new_templates($GRP_ID, $is_global) {
598
599
		//if we're creating a custom template then we don't need to use the defaults class
600
		if ( ! $is_global )
601
			return $this->_create_custom_template_group( $GRP_ID );
602
603
		$DFLT = new EE_Message_Template_Defaults( $this, $this->_messenger->name, $this->_message_type->name, $GRP_ID );
604
605
		//generate templates
606
		$success = $DFLT->create_new_templates();
607
608
		/**
609
		 * $success is in an array in the following format
610
		 * array(
611
		 * 	'GRP_ID' => $new_grp_id,
612
		 * 	'MTP_context' => $first_context_in_new_templates,
613
		 * )
614
		 */
615
		return $success;
616
	}
617
618
619
620
	/**
621
	 * This creates a custom template using the incoming GRP_ID
622
	 *
623
	 * @param  int     $GRP_ID GRP_ID for the template_group being used as the base
624
	 * @return  array $success             This will be an array in the format:
625
	 *                                     			array(
626
	 *                                     				'GRP_ID' => $new_grp_id,
627
	 *                                     				'MTP_context' => $first_context_in_created_template
628
	 *                                     			)
629
	 * @access private
630
	 */
631
	private function _create_custom_template_group( $GRP_ID ) {
632
		//defaults
633
		$success = array( 'GRP_ID' => NULL, 'MTP_context' => '' );
634
635
		//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.
636
		$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 );
637
638
		//if we don't have a mtg at this point then we need to bail.
639
		if ( ! $mtg instanceof EE_Message_Template_Group ) {
640
			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__ );
641
			return $success;
642
		}
643
644
		//let's get all the related message_template objects for this group.
645
		$mtts = $mtg->message_templates();
646
647
		//now we have what we need to setup the new template
648
		$new_mtg = clone $mtg;
649
		$new_mtg->set('GRP_ID', 0);
650
		$new_mtg->set('MTP_is_global', FALSE);
651
652
		$template_name = defined('DOING_AJAX') && !empty( $_POST['templateName'] ) ? $_POST['templateName'] : __('New Custom Template', 'event_espresso');
653
		$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'] );
654
655
656
		$new_mtg->set('MTP_name', $template_name );
657
		$new_mtg->set('MTP_description', $template_description );
658
		//remove ALL relations on this template group so they don't get saved!
659
		$new_mtg->_remove_relations( 'Message_Template' );
660
		$new_mtg->save();
661
		$success['GRP_ID'] = $new_mtg->ID();
662
		$success['template_name'] = $template_name;
663
664
		//add new message templates and add relation to.
665
		foreach ( $mtts as $mtt ) {
666
			if ( ! $mtt instanceof EE_Message_Template )
667
				continue;
668
			$nmtt = clone $mtt;
669
			$nmtt->set('MTP_ID', 0);
670
			$nmtt->set( 'GRP_ID', $new_mtg->ID() ); //relation
671
			$nmtt->save();
672
			if ( empty( $success['MTP_context'] ) )
673
				$success['MTP_context'] = $nmtt->get('MTP_context');
674
		}
675
676
		return $success;
677
678
	}
679
680
681
682
683
	/**
684
	 * get_fields
685
	 * This takes a given messenger and message type and returns all the template fields indexed by context (and with field type).
686
	 * @param  string $messenger    EE_messenger
687
	 * @param  string $message_type EE_message_type
688
	 * @return array|wp_error_object  template fields indexed by context.
689
	 */
690
	public function get_fields($messenger, $message_type) {
691
		$template_fields = array();
692
693
		$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...
694
695
696
		//okay now let's assemble an array with the messenger template fields added to the message_type contexts.
697
		foreach ( $this->_message_type->get_contexts() as $context => $details ) {
698
			foreach ( $this->_messenger->get_template_fields() as $field => $value ) {
699
				$template_fields[$context][$field] = $value;
700
			}
701
		}
702
703
		if ( empty($template_fields) ) {
704
			EE_Error::add_error( __('Something went wrong and we couldn\'t get any templates assembled', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
705
			return FALSE;
706
		}
707
708
		return $template_fields;
709
	}
710
711
	/**
712
	 * gets an array of installed messengers and message types objects.
713
	 *
714
	 * @access public
715
	 * @param string $type we can indicate just returning installed message types or messengers (or both) via this parameter.
716
	 * @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...
717
	 * @return array multidimensional array of messenger and message_type objects (messengers index, and message_type index);
718
	 */
719
	public function get_installed( $type = 'all', $skip_cache = false ) {
720
		$installed = array();
721
722
		//first let's account for caching
723
		if ( $skip_cache ) {
724
			$message_base = EE_LIBRARIES . "messages" . DS;
725
726
			$messenger_files = $type == 'all' || $type == 'messengers' ? scandir( $message_base . "messenger", 1) : NULL;
727
			$messagetype_files = $type == 'all' || $type == 'message_types' ? scandir( $message_base . "message_type", 1) : NULL;
728
729
730
			//allow plugins to filter in their messenger/message_type files
731
			$messenger_files = apply_filters('FHEE__EE_messages__get_installed__messenger_files', $messenger_files, $type );
732
			$messagetype_files = apply_filters('FHEE__EE_messages__get_installed__messagetype_files', $messagetype_files, $type );
733
734
			$installed['messengers'] = !empty($messenger_files ) ? $this->_get_installed($messenger_files) : '';
735
			$installed['message_types'] = !empty($messagetype_files) ? $this->_get_installed($messagetype_files) : '';
736
		} else {
737
			$installed['messengers'] = $this->get_installed_messengers();
738
			$installed['message_types'] = $this->get_installed_message_types();
739
		}
740
741
742
		if ( $type != 'all' ) {
743
			$installed = $type == 'messengers' ? $installed['messengers'] : $installed['message_types'];
744
		}
745
746
		return $installed;
747
	}
748
749
	/**
750
	 * _get_installed
751
	 * takes an array of filenames and returns an array of objects instantiated from the class name found in the filename.
752
	 * @param  array $filenames and array of filenames
753
	 * @return array       array of objects
754
	 */
755
	private function _get_installed($filenames) {
756
		//make sure incoming filenames are in an array.
757
		$the_goods = array();
758
		$filenames = (array) $filenames;
759
		$replace = ".class.php";
760
		foreach ( $filenames as $filename ) {
761
			$classname = preg_match("/" . $replace . "/", $filename ) ? str_replace($replace, "", $filename) : false;
762
763
			//no classname? no match? move along, nothing to see here. note, the stripos is checking to make sure the filename (classname) begins with EE.
764
			if ( !$classname || 0 !== stripos($classname, 'EE') ) continue;
765
766
			//note: I'm not sure if this will work without including the file.  We do have autoloaders so it "may" work.
767
			$a = new ReflectionClass($classname);
768
			$obj = $a->newInstance();
769
			$the_goods[$obj->name] = $obj;
770
		}
771
		return $the_goods;
772
	}
773
774
	public function get_active_messengers() {
775
		return $this->_active_messengers;
776
	}
777
778
779
	/**
780
	 * 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).
781
	 *
782
	 * @access public
783
	 * @return array array of message_type references
784
	 */
785
	public function get_active_message_types() {
786
		$message_types = array();
787
		foreach ( $this->_active_message_types as $messenger => $mtvalues ) {
788
			foreach ( $mtvalues as $mt => $config ) {
789
				if ( !in_array( $mt, $message_types ) )
790
					$message_types[] = $mt;
791
			}
792
		}
793
794
		return $message_types;
795
	}
796
797
798
799
800
	/**
801
	 * This checks the _active_message_types property for any active message types that are present for the given messenger and returns them.
802
	 *
803
	 * @since 4.5.0
804
	 *
805
	 * @param string $messenger The messenger being checked
806
	 *
807
	 * @return EE_message_type[]    (or empty array if none present)
808
	 */
809
	public function get_active_message_types_per_messenger( $messenger ) {
810
		$messenger = (string) $messenger;
811
		if ( empty( $this->_active_message_types[$messenger] ) ) {
812
			return array();
813
		}
814
815
		$mts = array();
816
		$message_types = $this->_active_message_types[$messenger];
817
		$installed_message_types = $this->get_installed_message_types();
818
		foreach ( $message_types as $mt => $settings ) {
819
			if ( ! empty( $installed_message_types[$mt] ) )  {
820
				$mts[] = $installed_message_types[$mt];
821
			}
822
		}
823
		return $mts;
824
	}
825
826
827
	/**
828
	 * This returns the EE_message_type from the active message types array ( if present );
829
	 *
830
	 * @param string $messenger      The string should correspond to the messenger (message types are
831
	 *                               		    assigned to a messenger in the messages settings)
832
	 * @param string $message_type The string should correspond to a message type.
833
	 *
834
	 * @return EE_Message_Type|null
835
	 */
836
	public function get_active_message_type( $messenger, $message_type ) {
837
		$installed_message_types = $this->get_installed_message_types();
838
		if ( !empty( $this->_active_message_types[$messenger][$message_type] ) && !empty( $installed_message_types[$message_type] ) )  {
839
			return $installed_message_types[$message_type];
840
		}
841
		return NULL;
842
	}
843
844
845
846
	public function get_installed_message_types() {
847
		$this->_installed_message_types = empty( $this->_installed_message_types ) ? $this->get_installed( 'message_types', true ) : $this->_installed_message_types;
848
		return $this->_installed_message_types;
849
	}
850
851
852
	public function get_installed_messengers() {
853
		$this->_installed_messengers = empty( $this->_installed_messengers ) ? $this->get_installed( 'messengers', true ) : $this->_installed_messengers;
854
		return $this->_installed_messengers;
855
	}
856
}
857
//end EE_messages class
858
859
// end of file:	includes/core/messages/EE_messages.core.php
860