Completed
Branch dev (8e0980)
by
unknown
21:42 queued 19:29
created
core/libraries/plugin_api/EE_Register_Message_Type.lib.php 2 patches
Indentation   +449 added lines, -449 removed lines patch added patch discarded remove patch
@@ -12,479 +12,479 @@
 block discarded – undo
12 12
 {
13 13
 
14 14
 
15
-    /**
16
-     * Holds values for registered message types
17
-     *
18
-     * @var array
19
-     */
20
-    protected static $_ee_message_type_registry = [];
15
+	/**
16
+	 * Holds values for registered message types
17
+	 *
18
+	 * @var array
19
+	 */
20
+	protected static $_ee_message_type_registry = [];
21 21
 
22 22
 
23
-    /**
24
-     * Method for registering new message types in the EE_messages system.
25
-     * Note:  All message types must have the following files in order to work:
26
-     * Template files for default templates getting setup.
27
-     * See /core/libraries/messages/defaults/default/ for examples
28
-     * (note that template files match a specific naming schema).
29
-     * These templates will need to be registered with the default template pack.
30
-     * - EE_Messages_Validator extended class(es).  See /core/libraries/messages/validators/email/
31
-     *      for examples.  Note for any new message types, there will need to be a validator for each
32
-     *      messenger combo this message type can activate with.
33
-     * - And of course the main EE_{Message_Type_Name}_message_type class that defines the new
34
-     *      message type and its properties.
35
-     *
36
-     * @param string $addon_name    Whatever is defined for the $name property of
37
-     *                              the message type you are registering (eg.
38
-     *                              declined_registration). Required.
39
-     * @param array  $setup_args    An array of arguments provided for registering the message type.
40
-     * @throws EE_Error
41
-     *                              }
42
-     * @see      inline docs in the register method for what can be passed in as arguments.
43
-     * @since    4.3.0
44
-     */
45
-    public static function register(string $addon_name = '', array $setup_args = []): bool
46
-    {
47
-        // required fields MUST be present, so let's make sure they are.
48
-        if (! isset($addon_name)
49
-            || ! is_array($setup_args)
50
-            || empty($setup_args['mtfilename'])
51
-            || empty($setup_args['autoloadpaths'])
52
-        ) {
53
-            throw new EE_Error(
54
-                __(
55
-                    'In order to register a message type with EE_Register_Message_Type::register, you must include a unique name for the message type, plus an array containing the following keys: "mtfilename", "autoloadpaths"',
56
-                    'event_espresso'
57
-                )
58
-            );
59
-        }
23
+	/**
24
+	 * Method for registering new message types in the EE_messages system.
25
+	 * Note:  All message types must have the following files in order to work:
26
+	 * Template files for default templates getting setup.
27
+	 * See /core/libraries/messages/defaults/default/ for examples
28
+	 * (note that template files match a specific naming schema).
29
+	 * These templates will need to be registered with the default template pack.
30
+	 * - EE_Messages_Validator extended class(es).  See /core/libraries/messages/validators/email/
31
+	 *      for examples.  Note for any new message types, there will need to be a validator for each
32
+	 *      messenger combo this message type can activate with.
33
+	 * - And of course the main EE_{Message_Type_Name}_message_type class that defines the new
34
+	 *      message type and its properties.
35
+	 *
36
+	 * @param string $addon_name    Whatever is defined for the $name property of
37
+	 *                              the message type you are registering (eg.
38
+	 *                              declined_registration). Required.
39
+	 * @param array  $setup_args    An array of arguments provided for registering the message type.
40
+	 * @throws EE_Error
41
+	 *                              }
42
+	 * @see      inline docs in the register method for what can be passed in as arguments.
43
+	 * @since    4.3.0
44
+	 */
45
+	public static function register(string $addon_name = '', array $setup_args = []): bool
46
+	{
47
+		// required fields MUST be present, so let's make sure they are.
48
+		if (! isset($addon_name)
49
+			|| ! is_array($setup_args)
50
+			|| empty($setup_args['mtfilename'])
51
+			|| empty($setup_args['autoloadpaths'])
52
+		) {
53
+			throw new EE_Error(
54
+				__(
55
+					'In order to register a message type with EE_Register_Message_Type::register, you must include a unique name for the message type, plus an array containing the following keys: "mtfilename", "autoloadpaths"',
56
+					'event_espresso'
57
+				)
58
+			);
59
+		}
60 60
 
61
-        // make sure we don't register twice
62
-        if (isset(self::$_ee_message_type_registry[ $addon_name ])) {
63
-            return true;
64
-        }
61
+		// make sure we don't register twice
62
+		if (isset(self::$_ee_message_type_registry[ $addon_name ])) {
63
+			return true;
64
+		}
65 65
 
66
-        // make sure this was called in the right place!
67
-        if (
68
-            ! did_action('EE_Brewing_Regular___messages_caf')
69
-            || did_action('AHEE__EE_System__perform_activations_upgrades_and_migrations')
70
-        ) {
71
-            EE_Error::doing_it_wrong(
72
-                __METHOD__,
73
-                sprintf(
74
-                    __(
75
-                        'A message type named "%s" has been attempted to be registered with the EE Messages System.  It may or may not work because it should be only called on the "EE_Brewing_Regular___messages_caf" hook.',
76
-                        'event_espresso'
77
-                    ),
78
-                    $addon_name
79
-                ),
80
-                '4.3.0'
81
-            );
82
-        }
83
-        // setup $__ee_message_type_registry array from incoming values.
84
-        self::$_ee_message_type_registry[ $addon_name ] = [
85
-            /**
86
-             * The file name for the message type being registered.
87
-             * Required.
88
-             *
89
-             * @type string
90
-             */
91
-            'mtfilename'                                       => (string) $setup_args['mtfilename'],
92
-            /**
93
-             * Autoload paths for classes used by the message type.
94
-             * Required.
95
-             *
96
-             * @type array
97
-             */
98
-            'autoloadpaths'                                    => (array) $setup_args['autoloadpaths'],
99
-            /**
100
-             * Messengers that the message type should be able to activate with.
101
-             * Use messenger slugs.
102
-             *
103
-             * @type array
104
-             */
105
-            'messengers_to_activate_with'                      => ! empty($setup_args['messengers_to_activate_with'])
106
-                ? (array) $setup_args['messengers_to_activate_with']
107
-                : [],
108
-            /**
109
-             * Messengers that the message type should validate with.
110
-             * Use messenger slugs.
111
-             *
112
-             * @type array
113
-             */
114
-            'messengers_to_validate_with'                      => ! empty($setup_args['messengers_to_validate_with'])
115
-                ? (array) $setup_args['messengers_to_validate_with']
116
-                : [],
117
-            /**
118
-             * Whether to force activate this message type the first time it is registered.
119
-             *
120
-             * @type bool   False means its not activated by default and left up to the end user to activate.
121
-             */
122
-            'force_activation'                                 => ! empty($setup_args['force_activation'])
123
-                                                                  && $setup_args['force_activation'],
124
-            /**
125
-             * What messengers this message type supports the default template pack for.
126
-             * Note: If you do not set this (or any of the following template pack/variation related arguments) to true,
127
-             * then it is expected that the message type being registered is doing its own custom default template
128
-             * pack/variation registration.
129
-             *
130
-             * If this is set and has values, then it is expected that the following arguments are also set in the incoming options
131
-             * $setup_arguments array as well:
132
-             * - 'base_path_for_default_templates'
133
-             *
134
-             * @type array   Expect an array of messengers this supports default template packs for.
135
-             */
136
-            'messengers_supporting_default_template_pack_with' => isset($setup_args['messengers_supporting_default_template_pack_with'])
137
-                ? (array) $setup_args['messengers_supporting_default_template_pack_with']
138
-                : [],
139
-            /**
140
-             * The base path where the default templates for this message type can be found.
141
-             *
142
-             * @type string
143
-             */
144
-            'base_path_for_default_templates'                  => $setup_args['base_path_for_default_templates'] ?? '',
145
-            /**
146
-             * The base path where the default variations for this message type can be found.
147
-             *
148
-             * @type string
149
-             */
150
-            'base_path_for_default_variation'                  => $setup_args['base_path_for_default_variation'] ?? '',
151
-            /**
152
-             * The base url for the default variations for this message type.
153
-             *
154
-             * @type string
155
-             */
156
-            'base_url_for_default_variation'                   => $setup_args['base_url_for_default_variation'] ?? '',
157
-        ];
158
-        // add filters but only if they haven't already been set (these filters only need to be registered ONCE because
159
-        // the callback handles all registered message types.
160
-        if (false === has_filter(
161
-                'FHEE__EED_Messages___set_messages_paths___MSG_PATHS',
162
-                ['EE_Register_Message_Type', 'register_msgs_autoload_paths']
163
-            )) {
164
-            add_filter(
165
-                'FHEE__EED_Messages___set_messages_paths___MSG_PATHS',
166
-                ['EE_Register_Message_Type', 'register_msgs_autoload_paths'],
167
-                10
168
-            );
169
-            add_filter(
170
-                'FHEE__EE_messages__get_installed__messagetype_files',
171
-                ['EE_Register_Message_Type', 'register_messagetype_files'],
172
-                10,
173
-                1
174
-            );
175
-            add_filter(
176
-                'FHEE__EE_messenger__get_default_message_types__default_types',
177
-                ['EE_Register_Message_Type', 'register_messengers_to_activate_mt_with'],
178
-                10,
179
-                2
180
-            );
181
-            add_filter(
182
-                'FHEE__EE_messenger__get_valid_message_types__valid_types',
183
-                ['EE_Register_Message_Type', 'register_messengers_to_validate_mt_with'],
184
-                10,
185
-                2
186
-            );
187
-            // actions
188
-            add_action(
189
-                'AHEE__EE_Addon__initialize_default_data__begin',
190
-                ['EE_Register_Message_Type', 'set_defaults']
191
-            );
66
+		// make sure this was called in the right place!
67
+		if (
68
+			! did_action('EE_Brewing_Regular___messages_caf')
69
+			|| did_action('AHEE__EE_System__perform_activations_upgrades_and_migrations')
70
+		) {
71
+			EE_Error::doing_it_wrong(
72
+				__METHOD__,
73
+				sprintf(
74
+					__(
75
+						'A message type named "%s" has been attempted to be registered with the EE Messages System.  It may or may not work because it should be only called on the "EE_Brewing_Regular___messages_caf" hook.',
76
+						'event_espresso'
77
+					),
78
+					$addon_name
79
+				),
80
+				'4.3.0'
81
+			);
82
+		}
83
+		// setup $__ee_message_type_registry array from incoming values.
84
+		self::$_ee_message_type_registry[ $addon_name ] = [
85
+			/**
86
+			 * The file name for the message type being registered.
87
+			 * Required.
88
+			 *
89
+			 * @type string
90
+			 */
91
+			'mtfilename'                                       => (string) $setup_args['mtfilename'],
92
+			/**
93
+			 * Autoload paths for classes used by the message type.
94
+			 * Required.
95
+			 *
96
+			 * @type array
97
+			 */
98
+			'autoloadpaths'                                    => (array) $setup_args['autoloadpaths'],
99
+			/**
100
+			 * Messengers that the message type should be able to activate with.
101
+			 * Use messenger slugs.
102
+			 *
103
+			 * @type array
104
+			 */
105
+			'messengers_to_activate_with'                      => ! empty($setup_args['messengers_to_activate_with'])
106
+				? (array) $setup_args['messengers_to_activate_with']
107
+				: [],
108
+			/**
109
+			 * Messengers that the message type should validate with.
110
+			 * Use messenger slugs.
111
+			 *
112
+			 * @type array
113
+			 */
114
+			'messengers_to_validate_with'                      => ! empty($setup_args['messengers_to_validate_with'])
115
+				? (array) $setup_args['messengers_to_validate_with']
116
+				: [],
117
+			/**
118
+			 * Whether to force activate this message type the first time it is registered.
119
+			 *
120
+			 * @type bool   False means its not activated by default and left up to the end user to activate.
121
+			 */
122
+			'force_activation'                                 => ! empty($setup_args['force_activation'])
123
+																  && $setup_args['force_activation'],
124
+			/**
125
+			 * What messengers this message type supports the default template pack for.
126
+			 * Note: If you do not set this (or any of the following template pack/variation related arguments) to true,
127
+			 * then it is expected that the message type being registered is doing its own custom default template
128
+			 * pack/variation registration.
129
+			 *
130
+			 * If this is set and has values, then it is expected that the following arguments are also set in the incoming options
131
+			 * $setup_arguments array as well:
132
+			 * - 'base_path_for_default_templates'
133
+			 *
134
+			 * @type array   Expect an array of messengers this supports default template packs for.
135
+			 */
136
+			'messengers_supporting_default_template_pack_with' => isset($setup_args['messengers_supporting_default_template_pack_with'])
137
+				? (array) $setup_args['messengers_supporting_default_template_pack_with']
138
+				: [],
139
+			/**
140
+			 * The base path where the default templates for this message type can be found.
141
+			 *
142
+			 * @type string
143
+			 */
144
+			'base_path_for_default_templates'                  => $setup_args['base_path_for_default_templates'] ?? '',
145
+			/**
146
+			 * The base path where the default variations for this message type can be found.
147
+			 *
148
+			 * @type string
149
+			 */
150
+			'base_path_for_default_variation'                  => $setup_args['base_path_for_default_variation'] ?? '',
151
+			/**
152
+			 * The base url for the default variations for this message type.
153
+			 *
154
+			 * @type string
155
+			 */
156
+			'base_url_for_default_variation'                   => $setup_args['base_url_for_default_variation'] ?? '',
157
+		];
158
+		// add filters but only if they haven't already been set (these filters only need to be registered ONCE because
159
+		// the callback handles all registered message types.
160
+		if (false === has_filter(
161
+				'FHEE__EED_Messages___set_messages_paths___MSG_PATHS',
162
+				['EE_Register_Message_Type', 'register_msgs_autoload_paths']
163
+			)) {
164
+			add_filter(
165
+				'FHEE__EED_Messages___set_messages_paths___MSG_PATHS',
166
+				['EE_Register_Message_Type', 'register_msgs_autoload_paths'],
167
+				10
168
+			);
169
+			add_filter(
170
+				'FHEE__EE_messages__get_installed__messagetype_files',
171
+				['EE_Register_Message_Type', 'register_messagetype_files'],
172
+				10,
173
+				1
174
+			);
175
+			add_filter(
176
+				'FHEE__EE_messenger__get_default_message_types__default_types',
177
+				['EE_Register_Message_Type', 'register_messengers_to_activate_mt_with'],
178
+				10,
179
+				2
180
+			);
181
+			add_filter(
182
+				'FHEE__EE_messenger__get_valid_message_types__valid_types',
183
+				['EE_Register_Message_Type', 'register_messengers_to_validate_mt_with'],
184
+				10,
185
+				2
186
+			);
187
+			// actions
188
+			add_action(
189
+				'AHEE__EE_Addon__initialize_default_data__begin',
190
+				['EE_Register_Message_Type', 'set_defaults']
191
+			);
192 192
 
193
-            // default template packs and variations related
194
-            add_filter(
195
-                'FHEE__EE_Messages_Template_Pack_Default__get_supports',
196
-                ['EE_Register_Message_Type', 'register_default_template_pack_supports']
197
-            );
198
-            add_filter(
199
-                'FHEE__EE_Template_Pack___get_specific_template__filtered_base_path',
200
-                ['EE_Register_Message_Type', 'register_base_template_path'],
201
-                10,
202
-                6
203
-            );
204
-            add_filter(
205
-                'FHEE__EE_Messages_Template_Pack__get_variation__base_path_or_url',
206
-                ['EE_Register_Message_Type', 'register_variation_base_path_or_url'],
207
-                10,
208
-                8
209
-            );
210
-            add_filter(
211
-                'FHEE__EE_Messages_Template_Pack__get_variation__base_path',
212
-                ['EE_Register_Message_Type', 'register_variation_base_path_or_url'],
213
-                10,
214
-                8
215
-            );
216
-        }
217
-        return true;
218
-    }
193
+			// default template packs and variations related
194
+			add_filter(
195
+				'FHEE__EE_Messages_Template_Pack_Default__get_supports',
196
+				['EE_Register_Message_Type', 'register_default_template_pack_supports']
197
+			);
198
+			add_filter(
199
+				'FHEE__EE_Template_Pack___get_specific_template__filtered_base_path',
200
+				['EE_Register_Message_Type', 'register_base_template_path'],
201
+				10,
202
+				6
203
+			);
204
+			add_filter(
205
+				'FHEE__EE_Messages_Template_Pack__get_variation__base_path_or_url',
206
+				['EE_Register_Message_Type', 'register_variation_base_path_or_url'],
207
+				10,
208
+				8
209
+			);
210
+			add_filter(
211
+				'FHEE__EE_Messages_Template_Pack__get_variation__base_path',
212
+				['EE_Register_Message_Type', 'register_variation_base_path_or_url'],
213
+				10,
214
+				8
215
+			);
216
+		}
217
+		return true;
218
+	}
219 219
 
220 220
 
221
-    /**
222
-     * This just ensures that when an addon registers a message type that on initial activation/reactivation the
223
-     * defaults the addon sets are taken care of.
224
-     *
225
-     * @throws EE_Error
226
-     * @throws ReflectionException
227
-     */
228
-    public static function set_defaults()
229
-    {
230
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
231
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
221
+	/**
222
+	 * This just ensures that when an addon registers a message type that on initial activation/reactivation the
223
+	 * defaults the addon sets are taken care of.
224
+	 *
225
+	 * @throws EE_Error
226
+	 * @throws ReflectionException
227
+	 */
228
+	public static function set_defaults()
229
+	{
230
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
231
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
232 232
 
233
-        // for any message types with force activation, let's ensure they are activated
234
-        foreach (self::$_ee_message_type_registry as $addon_name => $settings) {
235
-            if ($settings['force_activation']) {
236
-                foreach ($settings['messengers_to_activate_with'] as $messenger) {
237
-                    // DO not force activation if this message type has already been activated in the system
238
-                    if (! $message_resource_manager->has_message_type_been_activated_for_messenger(
239
-                        $addon_name,
240
-                        $messenger
241
-                    )
242
-                    ) {
243
-                        $message_resource_manager->ensure_message_type_is_active($addon_name, $messenger);
244
-                    }
245
-                }
246
-            }
247
-        }
248
-    }
233
+		// for any message types with force activation, let's ensure they are activated
234
+		foreach (self::$_ee_message_type_registry as $addon_name => $settings) {
235
+			if ($settings['force_activation']) {
236
+				foreach ($settings['messengers_to_activate_with'] as $messenger) {
237
+					// DO not force activation if this message type has already been activated in the system
238
+					if (! $message_resource_manager->has_message_type_been_activated_for_messenger(
239
+						$addon_name,
240
+						$messenger
241
+					)
242
+					) {
243
+						$message_resource_manager->ensure_message_type_is_active($addon_name, $messenger);
244
+					}
245
+				}
246
+			}
247
+		}
248
+	}
249 249
 
250 250
 
251
-    /**
252
-     * This deregisters a message type that was previously registered with a specific message_type_name.
253
-     *
254
-     * @param string $addon_name the name for the message type that was previously registered
255
-     * @return void
256
-     * @throws EE_Error
257
-     * @throws ReflectionException
258
-     * @since    4.3.0
259
-     */
260
-    public static function deregister(string $addon_name = '')
261
-    {
262
-        if (! empty(self::$_ee_message_type_registry[ $addon_name ])) {
263
-            // let's make sure that we remove any place this message type was made active
264
-            /** @var EE_Message_Resource_Manager $Message_Resource_Manager */
265
-            $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
266
-            // ensures that if this message type is registered again that it retains its previous active state vs
267
-            // remaining inactive.
268
-            $Message_Resource_Manager->remove_message_type_has_been_activated_from_all_messengers(
269
-                $addon_name,
270
-                true
271
-            );
272
-            $Message_Resource_Manager->deactivate_message_type($addon_name, false);
273
-        }
274
-        unset(self::$_ee_message_type_registry[ $addon_name ]);
275
-    }
251
+	/**
252
+	 * This deregisters a message type that was previously registered with a specific message_type_name.
253
+	 *
254
+	 * @param string $addon_name the name for the message type that was previously registered
255
+	 * @return void
256
+	 * @throws EE_Error
257
+	 * @throws ReflectionException
258
+	 * @since    4.3.0
259
+	 */
260
+	public static function deregister(string $addon_name = '')
261
+	{
262
+		if (! empty(self::$_ee_message_type_registry[ $addon_name ])) {
263
+			// let's make sure that we remove any place this message type was made active
264
+			/** @var EE_Message_Resource_Manager $Message_Resource_Manager */
265
+			$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
266
+			// ensures that if this message type is registered again that it retains its previous active state vs
267
+			// remaining inactive.
268
+			$Message_Resource_Manager->remove_message_type_has_been_activated_from_all_messengers(
269
+				$addon_name,
270
+				true
271
+			);
272
+			$Message_Resource_Manager->deactivate_message_type($addon_name, false);
273
+		}
274
+		unset(self::$_ee_message_type_registry[ $addon_name ]);
275
+	}
276 276
 
277 277
 
278
-    /**
279
-     * callback for FHEE__EE_messages__get_installed__messagetype_files filter.
280
-     *
281
-     * @param array $messagetype_files The current array of message type file names
282
-     * @return  array                                 Array of message type file names
283
-     * @since   4.3.0
284
-     */
285
-    public static function register_messagetype_files(array $messagetype_files): array
286
-    {
287
-        if (empty(self::$_ee_message_type_registry)) {
288
-            return $messagetype_files;
289
-        }
290
-        foreach (self::$_ee_message_type_registry as $mt_reg) {
291
-            if (empty($mt_reg['mtfilename'])) {
292
-                continue;
293
-            }
294
-            $messagetype_files[] = $mt_reg['mtfilename'];
295
-        }
296
-        return $messagetype_files;
297
-    }
278
+	/**
279
+	 * callback for FHEE__EE_messages__get_installed__messagetype_files filter.
280
+	 *
281
+	 * @param array $messagetype_files The current array of message type file names
282
+	 * @return  array                                 Array of message type file names
283
+	 * @since   4.3.0
284
+	 */
285
+	public static function register_messagetype_files(array $messagetype_files): array
286
+	{
287
+		if (empty(self::$_ee_message_type_registry)) {
288
+			return $messagetype_files;
289
+		}
290
+		foreach (self::$_ee_message_type_registry as $mt_reg) {
291
+			if (empty($mt_reg['mtfilename'])) {
292
+				continue;
293
+			}
294
+			$messagetype_files[] = $mt_reg['mtfilename'];
295
+		}
296
+		return $messagetype_files;
297
+	}
298 298
 
299 299
 
300
-    /**
301
-     * callback for FHEE__EED_Messages___set_messages_paths___MSG_PATHS filter.
302
-     *
303
-     * @param array $paths array of paths to be checked by EE_messages autoloader.
304
-     * @return array
305
-     * @since    4.3.0
306
-     */
307
-    public static function register_msgs_autoload_paths(array $paths): array
308
-    {
309
-        $autoload_paths = [];
310
-        if (! empty(self::$_ee_message_type_registry)) {
311
-            foreach (self::$_ee_message_type_registry as $mt_reg) {
312
-                if (empty($mt_reg['autoloadpaths'])) {
313
-                    continue;
314
-                }
315
-                $autoload_paths[] = $mt_reg['autoloadpaths'];
316
-            }
317
-        }
318
-        return array_merge($paths, ...$autoload_paths);
319
-    }
300
+	/**
301
+	 * callback for FHEE__EED_Messages___set_messages_paths___MSG_PATHS filter.
302
+	 *
303
+	 * @param array $paths array of paths to be checked by EE_messages autoloader.
304
+	 * @return array
305
+	 * @since    4.3.0
306
+	 */
307
+	public static function register_msgs_autoload_paths(array $paths): array
308
+	{
309
+		$autoload_paths = [];
310
+		if (! empty(self::$_ee_message_type_registry)) {
311
+			foreach (self::$_ee_message_type_registry as $mt_reg) {
312
+				if (empty($mt_reg['autoloadpaths'])) {
313
+					continue;
314
+				}
315
+				$autoload_paths[] = $mt_reg['autoloadpaths'];
316
+			}
317
+		}
318
+		return array_merge($paths, ...$autoload_paths);
319
+	}
320 320
 
321 321
 
322
-    /**
323
-     * callback for FHEE__EE_messenger__get_default_message_types__default_types filter.
324
-     *
325
-     * @param array        $default_types   array of message types activated with messenger (
326
-     *                                      corresponds to the $name property of message type)
327
-     * @param EE_messenger $messenger       The EE_messenger the filter is called from.
328
-     * @return array
329
-     * @since  4.3.0
330
-     */
331
-    public static function register_messengers_to_activate_mt_with(array $default_types, EE_messenger $messenger): array
332
-    {
333
-        if (empty(self::$_ee_message_type_registry)) {
334
-            return $default_types;
335
-        }
336
-        foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
337
-            if (empty($mt_reg['messengers_to_activate_with']) || empty($mt_reg['mtfilename'])) {
338
-                continue;
339
-            }
340
-            // loop through each of the messengers and if it matches the loaded class
341
-            // then we add this message type to the
342
-            foreach ($mt_reg['messengers_to_activate_with'] as $msgr) {
343
-                if ($messenger->name == $msgr) {
344
-                    $default_types[] = $addon_name;
345
-                }
346
-            }
347
-        }
322
+	/**
323
+	 * callback for FHEE__EE_messenger__get_default_message_types__default_types filter.
324
+	 *
325
+	 * @param array        $default_types   array of message types activated with messenger (
326
+	 *                                      corresponds to the $name property of message type)
327
+	 * @param EE_messenger $messenger       The EE_messenger the filter is called from.
328
+	 * @return array
329
+	 * @since  4.3.0
330
+	 */
331
+	public static function register_messengers_to_activate_mt_with(array $default_types, EE_messenger $messenger): array
332
+	{
333
+		if (empty(self::$_ee_message_type_registry)) {
334
+			return $default_types;
335
+		}
336
+		foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
337
+			if (empty($mt_reg['messengers_to_activate_with']) || empty($mt_reg['mtfilename'])) {
338
+				continue;
339
+			}
340
+			// loop through each of the messengers and if it matches the loaded class
341
+			// then we add this message type to the
342
+			foreach ($mt_reg['messengers_to_activate_with'] as $msgr) {
343
+				if ($messenger->name == $msgr) {
344
+					$default_types[] = $addon_name;
345
+				}
346
+			}
347
+		}
348 348
 
349
-        return $default_types;
350
-    }
349
+		return $default_types;
350
+	}
351 351
 
352 352
 
353
-    /**
354
-     * callback for FHEE__EE_messenger__get_valid_message_types__default_types filter.
355
-     *
356
-     * @param array        $valid_types     array of message types valid with messenger (
357
-     *                                      corresponds to the $name property of message type)
358
-     * @param EE_messenger $messenger       The EE_messenger the filter is called from.
359
-     * @return  array
360
-     * @since   4.3.0
361
-     */
362
-    public static function register_messengers_to_validate_mt_with(array $valid_types, EE_messenger $messenger): array
363
-    {
364
-        if (empty(self::$_ee_message_type_registry)) {
365
-            return $valid_types;
366
-        }
367
-        foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
368
-            if (empty($mt_reg['messengers_to_validate_with']) || empty($mt_reg['mtfilename'])) {
369
-                continue;
370
-            }
371
-            // loop through each of the messengers and if it matches the loaded class
372
-            // then we add this message type to the
373
-            foreach ($mt_reg['messengers_to_validate_with'] as $msgr) {
374
-                if ($messenger->name == $msgr) {
375
-                    $valid_types[] = $addon_name;
376
-                }
377
-            }
378
-        }
353
+	/**
354
+	 * callback for FHEE__EE_messenger__get_valid_message_types__default_types filter.
355
+	 *
356
+	 * @param array        $valid_types     array of message types valid with messenger (
357
+	 *                                      corresponds to the $name property of message type)
358
+	 * @param EE_messenger $messenger       The EE_messenger the filter is called from.
359
+	 * @return  array
360
+	 * @since   4.3.0
361
+	 */
362
+	public static function register_messengers_to_validate_mt_with(array $valid_types, EE_messenger $messenger): array
363
+	{
364
+		if (empty(self::$_ee_message_type_registry)) {
365
+			return $valid_types;
366
+		}
367
+		foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
368
+			if (empty($mt_reg['messengers_to_validate_with']) || empty($mt_reg['mtfilename'])) {
369
+				continue;
370
+			}
371
+			// loop through each of the messengers and if it matches the loaded class
372
+			// then we add this message type to the
373
+			foreach ($mt_reg['messengers_to_validate_with'] as $msgr) {
374
+				if ($messenger->name == $msgr) {
375
+					$valid_types[] = $addon_name;
376
+				}
377
+			}
378
+		}
379 379
 
380
-        return $valid_types;
381
-    }
380
+		return $valid_types;
381
+	}
382 382
 
383 383
 
384
-    /**
385
-     * Callback for `FHEE__EE_Messages_Template_Pack_Default__get_supports` filter to register this message type as
386
-     * supporting the default template pack
387
-     *
388
-     * @param array $supports
389
-     *
390
-     * @return array
391
-     */
392
-    public static function register_default_template_pack_supports(array $supports): array
393
-    {
394
-        foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
395
-            if (empty($mt_reg['messengers_supporting_default_template_pack_with'])) {
396
-                continue;
397
-            }
398
-            foreach ($mt_reg['messengers_supporting_default_template_pack_with'] as $messenger_slug) {
399
-                $supports[ $messenger_slug ][] = $addon_name;
400
-            }
401
-        }
402
-        return $supports;
403
-    }
384
+	/**
385
+	 * Callback for `FHEE__EE_Messages_Template_Pack_Default__get_supports` filter to register this message type as
386
+	 * supporting the default template pack
387
+	 *
388
+	 * @param array $supports
389
+	 *
390
+	 * @return array
391
+	 */
392
+	public static function register_default_template_pack_supports(array $supports): array
393
+	{
394
+		foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
395
+			if (empty($mt_reg['messengers_supporting_default_template_pack_with'])) {
396
+				continue;
397
+			}
398
+			foreach ($mt_reg['messengers_supporting_default_template_pack_with'] as $messenger_slug) {
399
+				$supports[ $messenger_slug ][] = $addon_name;
400
+			}
401
+		}
402
+		return $supports;
403
+	}
404 404
 
405 405
 
406
-    /**
407
-     * Callback for FHEE__EE_Template_Pack___get_specific_template__filtered_base_path
408
-     *
409
-     * @param string                    $base_path The original base path for message templates
410
-     * @param EE_messenger              $messenger
411
-     * @param EE_message_type           $message_type
412
-     * @param string                    $field     The field requesting a template
413
-     * @param string                    $context   The context requesting a template
414
-     * @param EE_Messages_Template_Pack $template_pack
415
-     *
416
-     * @return string
417
-     */
418
-    public static function register_base_template_path(
419
-        string $base_path,
420
-        EE_messenger $messenger,
421
-        EE_message_type $message_type,
422
-        string $field,
423
-        string $context,
424
-        EE_Messages_Template_Pack $template_pack
425
-    ): string {
426
-        if (! $template_pack instanceof EE_Messages_Template_Pack_Default
427
-            || ! $message_type instanceof EE_message_type
428
-        ) {
429
-            return $base_path;
430
-        }
431
-        foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
432
-            if ($message_type->name === $addon_name
433
-                && ! empty($mt_reg['base_path_for_default_templates'])
434
-            ) {
435
-                return $mt_reg['base_path_for_default_templates'];
436
-            }
437
-        }
438
-        return $base_path;
439
-    }
406
+	/**
407
+	 * Callback for FHEE__EE_Template_Pack___get_specific_template__filtered_base_path
408
+	 *
409
+	 * @param string                    $base_path The original base path for message templates
410
+	 * @param EE_messenger              $messenger
411
+	 * @param EE_message_type           $message_type
412
+	 * @param string                    $field     The field requesting a template
413
+	 * @param string                    $context   The context requesting a template
414
+	 * @param EE_Messages_Template_Pack $template_pack
415
+	 *
416
+	 * @return string
417
+	 */
418
+	public static function register_base_template_path(
419
+		string $base_path,
420
+		EE_messenger $messenger,
421
+		EE_message_type $message_type,
422
+		string $field,
423
+		string $context,
424
+		EE_Messages_Template_Pack $template_pack
425
+	): string {
426
+		if (! $template_pack instanceof EE_Messages_Template_Pack_Default
427
+			|| ! $message_type instanceof EE_message_type
428
+		) {
429
+			return $base_path;
430
+		}
431
+		foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
432
+			if ($message_type->name === $addon_name
433
+				&& ! empty($mt_reg['base_path_for_default_templates'])
434
+			) {
435
+				return $mt_reg['base_path_for_default_templates'];
436
+			}
437
+		}
438
+		return $base_path;
439
+	}
440 440
 
441 441
 
442
-    /**
443
-     * Callback for FHEE__EE_Messages_Template_Pack__get_variation__base_path and
444
-     * FHEE__EE_Messages_Template_Pack__get_variation__base_path_or_url hooks
445
-     *
446
-     * @param string                    $base_path_or_url  The original incoming base url or path
447
-     * @param string                    $messenger_slug    The slug of the messenger the template is being generated
448
-     *                                                     for.
449
-     * @param string                    $message_type_slug The slug of the message type the template is being generated
450
-     *                                                     for.
451
-     * @param string                    $type              The "type" of css being requested.
452
-     * @param string                    $variation         The variation being requested.
453
-     * @param bool                      $url               whether a url or path is being requested.
454
-     * @param string                    $file_extension    What file extension is expected for the variation file.
455
-     * @param EE_Messages_Template_Pack $template_pack
456
-     *
457
-     * @return string
458
-     */
459
-    public static function register_variation_base_path_or_url(
460
-        string $base_path_or_url,
461
-        string $messenger_slug,
462
-        string $message_type_slug,
463
-        string $type,
464
-        string $variation,
465
-        bool $url,
466
-        string $file_extension,
467
-        EE_Messages_Template_Pack $template_pack
468
-    ): string {
469
-        if (! $template_pack instanceof EE_Messages_Template_Pack_Default) {
470
-            return $base_path_or_url;
471
-        }
472
-        foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
473
-            if ($addon_name === $message_type_slug
474
-            ) {
475
-                if (
476
-                    $url
477
-                    && ! empty($mt_reg['base_url_for_default_variation'])
478
-                ) {
479
-                    return $mt_reg['base_url_for_default_variation'];
480
-                } elseif (
481
-                    ! $url
482
-                    && ! empty($mt_reg['base_path_for_default_variation'])
483
-                ) {
484
-                    return $mt_reg['base_path_for_default_variation'];
485
-                }
486
-            }
487
-        }
488
-        return $base_path_or_url;
489
-    }
442
+	/**
443
+	 * Callback for FHEE__EE_Messages_Template_Pack__get_variation__base_path and
444
+	 * FHEE__EE_Messages_Template_Pack__get_variation__base_path_or_url hooks
445
+	 *
446
+	 * @param string                    $base_path_or_url  The original incoming base url or path
447
+	 * @param string                    $messenger_slug    The slug of the messenger the template is being generated
448
+	 *                                                     for.
449
+	 * @param string                    $message_type_slug The slug of the message type the template is being generated
450
+	 *                                                     for.
451
+	 * @param string                    $type              The "type" of css being requested.
452
+	 * @param string                    $variation         The variation being requested.
453
+	 * @param bool                      $url               whether a url or path is being requested.
454
+	 * @param string                    $file_extension    What file extension is expected for the variation file.
455
+	 * @param EE_Messages_Template_Pack $template_pack
456
+	 *
457
+	 * @return string
458
+	 */
459
+	public static function register_variation_base_path_or_url(
460
+		string $base_path_or_url,
461
+		string $messenger_slug,
462
+		string $message_type_slug,
463
+		string $type,
464
+		string $variation,
465
+		bool $url,
466
+		string $file_extension,
467
+		EE_Messages_Template_Pack $template_pack
468
+	): string {
469
+		if (! $template_pack instanceof EE_Messages_Template_Pack_Default) {
470
+			return $base_path_or_url;
471
+		}
472
+		foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
473
+			if ($addon_name === $message_type_slug
474
+			) {
475
+				if (
476
+					$url
477
+					&& ! empty($mt_reg['base_url_for_default_variation'])
478
+				) {
479
+					return $mt_reg['base_url_for_default_variation'];
480
+				} elseif (
481
+					! $url
482
+					&& ! empty($mt_reg['base_path_for_default_variation'])
483
+				) {
484
+					return $mt_reg['base_path_for_default_variation'];
485
+				}
486
+			}
487
+		}
488
+		return $base_path_or_url;
489
+	}
490 490
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
     public static function register(string $addon_name = '', array $setup_args = []): bool
46 46
     {
47 47
         // required fields MUST be present, so let's make sure they are.
48
-        if (! isset($addon_name)
48
+        if ( ! isset($addon_name)
49 49
             || ! is_array($setup_args)
50 50
             || empty($setup_args['mtfilename'])
51 51
             || empty($setup_args['autoloadpaths'])
@@ -59,7 +59,7 @@  discard block
 block discarded – undo
59 59
         }
60 60
 
61 61
         // make sure we don't register twice
62
-        if (isset(self::$_ee_message_type_registry[ $addon_name ])) {
62
+        if (isset(self::$_ee_message_type_registry[$addon_name])) {
63 63
             return true;
64 64
         }
65 65
 
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
             );
82 82
         }
83 83
         // setup $__ee_message_type_registry array from incoming values.
84
-        self::$_ee_message_type_registry[ $addon_name ] = [
84
+        self::$_ee_message_type_registry[$addon_name] = [
85 85
             /**
86 86
              * The file name for the message type being registered.
87 87
              * Required.
@@ -235,7 +235,7 @@  discard block
 block discarded – undo
235 235
             if ($settings['force_activation']) {
236 236
                 foreach ($settings['messengers_to_activate_with'] as $messenger) {
237 237
                     // DO not force activation if this message type has already been activated in the system
238
-                    if (! $message_resource_manager->has_message_type_been_activated_for_messenger(
238
+                    if ( ! $message_resource_manager->has_message_type_been_activated_for_messenger(
239 239
                         $addon_name,
240 240
                         $messenger
241 241
                     )
@@ -259,7 +259,7 @@  discard block
 block discarded – undo
259 259
      */
260 260
     public static function deregister(string $addon_name = '')
261 261
     {
262
-        if (! empty(self::$_ee_message_type_registry[ $addon_name ])) {
262
+        if ( ! empty(self::$_ee_message_type_registry[$addon_name])) {
263 263
             // let's make sure that we remove any place this message type was made active
264 264
             /** @var EE_Message_Resource_Manager $Message_Resource_Manager */
265 265
             $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
@@ -271,7 +271,7 @@  discard block
 block discarded – undo
271 271
             );
272 272
             $Message_Resource_Manager->deactivate_message_type($addon_name, false);
273 273
         }
274
-        unset(self::$_ee_message_type_registry[ $addon_name ]);
274
+        unset(self::$_ee_message_type_registry[$addon_name]);
275 275
     }
276 276
 
277 277
 
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
     public static function register_msgs_autoload_paths(array $paths): array
308 308
     {
309 309
         $autoload_paths = [];
310
-        if (! empty(self::$_ee_message_type_registry)) {
310
+        if ( ! empty(self::$_ee_message_type_registry)) {
311 311
             foreach (self::$_ee_message_type_registry as $mt_reg) {
312 312
                 if (empty($mt_reg['autoloadpaths'])) {
313 313
                     continue;
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
                 continue;
397 397
             }
398 398
             foreach ($mt_reg['messengers_supporting_default_template_pack_with'] as $messenger_slug) {
399
-                $supports[ $messenger_slug ][] = $addon_name;
399
+                $supports[$messenger_slug][] = $addon_name;
400 400
             }
401 401
         }
402 402
         return $supports;
@@ -423,7 +423,7 @@  discard block
 block discarded – undo
423 423
         string $context,
424 424
         EE_Messages_Template_Pack $template_pack
425 425
     ): string {
426
-        if (! $template_pack instanceof EE_Messages_Template_Pack_Default
426
+        if ( ! $template_pack instanceof EE_Messages_Template_Pack_Default
427 427
             || ! $message_type instanceof EE_message_type
428 428
         ) {
429 429
             return $base_path;
@@ -466,7 +466,7 @@  discard block
 block discarded – undo
466 466
         string $file_extension,
467 467
         EE_Messages_Template_Pack $template_pack
468 468
     ): string {
469
-        if (! $template_pack instanceof EE_Messages_Template_Pack_Default) {
469
+        if ( ! $template_pack instanceof EE_Messages_Template_Pack_Default) {
470 470
             return $base_path_or_url;
471 471
         }
472 472
         foreach (self::$_ee_message_type_registry as $addon_name => $mt_reg) {
Please login to merge, or discard this patch.
core/libraries/messages/EE_Message_Resource_Manager.lib.php 2 patches
Indentation   +1118 added lines, -1118 removed lines patch added patch discarded remove patch
@@ -12,1122 +12,1122 @@
 block discarded – undo
12 12
 class EE_Message_Resource_Manager
13 13
 {
14 14
 
15
-    /**
16
-     * This option in the database is used to keep a record of message types that have been activated for a messenger
17
-     * at some point in the history of the site.  It is utilized by the implementation of the 'force' flag in
18
-     * EE_Register_Message_Type.  The force flag is an indication of whether a message type should be activated by
19
-     * default when the message type is registered.  However, if a user has explicitly deactivated a message type, then
20
-     * the force flag is ignored.  The method by which the code knows whether to ignore this flag is via this option.
21
-     * Note, that this is NOT a historical record.  Its entirely possible for a message type to have been activated for
22
-     * a messenger and yet not have a record in this option.  This occurs when a message type is inactivated through an
23
-     * automated process (when an add-on registering the message type deactivates, or when some other code calls the
24
-     * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to ensure
25
-     * the "force" flag is respected if that message type is later re-registered.
26
-     *
27
-     * This option should NOT be used to determine the current "active" state of a message type for a given messenger.
28
-     *
29
-     * The name of this option (and related methods/properties) is due to matching the original intended purpose for the
30
-     * option that got superseded by later behaviour requirements.
31
-     */
32
-    const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger';
33
-
34
-    /**
35
-     * @type boolean $_initialized
36
-     */
37
-    protected $_initialized = false;
38
-
39
-    /**
40
-     * @type EE_Messenger_Collection $_messenger_collection_loader
41
-     */
42
-    protected $_messenger_collection_loader;
43
-
44
-    /**
45
-     * @type EE_Message_Type_Collection $_message_type_collection_loader
46
-     */
47
-    protected $_message_type_collection_loader;
48
-
49
-    /**
50
-     * @type EEM_Message_Template_Group $_message_template_group_model
51
-     */
52
-    protected $_message_template_group_model;
53
-
54
-    /**
55
-     * @type EE_messenger[]
56
-     */
57
-    protected $_installed_messengers = array();
58
-
59
-    /**
60
-     * @type EE_message_type[]
61
-     */
62
-    protected $_installed_message_types = array();
63
-
64
-    /**
65
-     * Array of active messengers.
66
-     * Format is this:
67
-     * array(
68
-     *      'messenger_name' => EE_messenger
69
-     * )
70
-     *
71
-     * @type EE_messenger[]
72
-     */
73
-    protected $_active_messengers = array();
74
-
75
-    /**
76
-     * Formatted array of active message types grouped per messenger.
77
-     * Format is this:
78
-     * array(
79
-     *      'messenger_name' => array(
80
-     *          'settings' => array(
81
-     *              '{messenger_name}-message_types' => array(
82
-     *                  'message_type_name' => array() //variable array of settings corresponding to message type.
83
-     *              )
84
-     *          )
85
-     *      )
86
-     * )
87
-     *
88
-     * @type array
89
-     */
90
-    protected $_active_message_types = array();
91
-
92
-
93
-    /**
94
-     * This holds the array of messengers and their corresponding message types that have
95
-     * been activated on a site at some point.  This is an important record that helps the messages system
96
-     * not accidentally reactivate something that was intentionally deactivated by a user.
97
-     *
98
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
99
-     *
100
-     * @type array
101
-     */
102
-    protected $_has_activated_messengers_and_message_types = array();
103
-
104
-    /**
105
-     * An array of unique message type contexts across all active message types.
106
-     * The array will be indexed by either 'slugs' or 'all'.
107
-     * The slugs index contains an array indexed by unique context slugs with the latest label representation for that
108
-     * slug. array(
109
-     *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
110
-     * );
111
-     * The all index returns an array in this format:
112
-     * array(
113
-     *      'message_type_name' => array(
114
-     *          'context_slug' => array(
115
-     *              'label' => 'localized label for context',
116
-     *              'description' => 'localized description for context'
117
-     *          )
118
-     *      )
119
-     * );
120
-     *
121
-     * @type array
122
-     */
123
-    protected $_contexts = array();
124
-
125
-
126
-    /**
127
-     * EE_Message_Resource_Manager constructor.
128
-     *
129
-     * @param \EE_Messenger_Collection_Loader    $Messenger_Collection_Loader
130
-     * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader
131
-     * @param \EEM_Message_Template_Group        $Message_Template_Group_Model
132
-     */
133
-    public function __construct(
134
-        EE_Messenger_Collection_Loader $Messenger_Collection_Loader,
135
-        EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader,
136
-        EEM_Message_Template_Group $Message_Template_Group_Model
137
-    ) {
138
-        $this->_messenger_collection_loader    = $Messenger_Collection_Loader;
139
-        $this->_message_type_collection_loader = $Message_Type_Collection_Loader;
140
-        $this->_message_template_group_model   = $Message_Template_Group_Model;
141
-    }
142
-
143
-
144
-    /**
145
-     * @return void
146
-     */
147
-    protected function _initialize_collections()
148
-    {
149
-        if ($this->_initialized) {
150
-            return;
151
-        }
152
-        $this->_initialized = true;
153
-        $this->_messenger_collection_loader->load_messengers_from_folder();
154
-        $this->_message_type_collection_loader->load_message_types_from_folder();
155
-        $this->get_has_activated_messengers_option(true);
156
-        $this->_set_active_messengers_and_message_types();
157
-    }
158
-
159
-
160
-    /**
161
-     * @return EE_Messenger_Collection
162
-     */
163
-    public function messenger_collection()
164
-    {
165
-        $this->_initialize_collections();
166
-        return $this->_messenger_collection_loader->messenger_collection();
167
-    }
168
-
169
-
170
-    /**
171
-     * @return EE_messenger[]
172
-     */
173
-    public function active_messengers()
174
-    {
175
-        $this->_initialize_collections();
176
-        return $this->_active_messengers;
177
-    }
178
-
179
-
180
-    /**
181
-     * @param string $messenger_name
182
-     * @return \EE_messenger
183
-     */
184
-    public function get_messenger($messenger_name)
185
-    {
186
-        return $this->messenger_collection()->get_by_info($messenger_name);
187
-    }
188
-
189
-
190
-    /**
191
-     * This returns the corresponding EE_messenger object for the given string if it is active.
192
-     *
193
-     * @param string $messenger
194
-     * @return EE_messenger | null
195
-     */
196
-    public function get_active_messenger($messenger)
197
-    {
198
-        $this->_initialize_collections();
199
-        return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
200
-    }
201
-
202
-
203
-    /**
204
-     * @return \EE_messenger[]
205
-     */
206
-    public function installed_messengers()
207
-    {
208
-        if (empty($this->_installed_messengers)) {
209
-            $this->_installed_messengers = array();
210
-            $this->messenger_collection()->rewind();
211
-            while ($this->messenger_collection()->valid()) {
212
-                $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
213
-                $this->messenger_collection()->next();
214
-            }
215
-        }
216
-        return $this->_installed_messengers;
217
-    }
218
-
219
-
220
-    /**
221
-     * @param string $messenger_name
222
-     * @return \EE_messenger
223
-     * @throws EE_Error
224
-     */
225
-    public function valid_messenger($messenger_name)
226
-    {
227
-        $messenger = $this->get_messenger($messenger_name);
228
-        if ($messenger instanceof EE_messenger) {
229
-            return $messenger;
230
-        }
231
-        throw new EE_Error(
232
-            sprintf(
233
-                __('The "%1$s" messenger is either invalid or not installed', 'event_espresso'),
234
-                $messenger_name
235
-            )
236
-        );
237
-    }
238
-
239
-
240
-    /**
241
-     * @return EE_Message_Type_Collection
242
-     */
243
-    public function message_type_collection()
244
-    {
245
-        $this->_initialize_collections();
246
-        return $this->_message_type_collection_loader->message_type_collection();
247
-    }
248
-
249
-
250
-    /**
251
-     * @return array
252
-     */
253
-    public function active_message_types()
254
-    {
255
-        $this->_initialize_collections();
256
-        return $this->_active_message_types;
257
-    }
258
-
259
-
260
-    /**
261
-     * @param string $message_type_name
262
-     * @return \EE_message_type
263
-     */
264
-    public function get_message_type($message_type_name)
265
-    {
266
-        return $this->message_type_collection()->get_by_info($message_type_name);
267
-    }
268
-
269
-
270
-    /**
271
-     * This returns the EE_message_type from the active message types array ( if present );
272
-     *
273
-     * @param string $messenger_name
274
-     * @param string $message_type_name
275
-     * @return \EE_message_type|null
276
-     */
277
-    public function get_active_message_type_for_messenger($messenger_name, $message_type_name)
278
-    {
279
-        return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
280
-            ? $this->get_message_type($message_type_name)
281
-            : null;
282
-    }
283
-
284
-
285
-    /**
286
-     * Returns whether the given message type is active for the given messenger.
287
-     *
288
-     * @param string $messenger_name
289
-     * @param string $message_type_name
290
-     * @return bool
291
-     */
292
-    public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293
-    {
294
-        $this->_initialize_collections();
295
-        return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
296
-    }
297
-
298
-
299
-    /**
300
-     * Returns whether the given messenger is active.
301
-     *
302
-     * @param string $messenger_name the name of the messenger to check if active.
303
-     * @return bool
304
-     */
305
-    public function is_messenger_active($messenger_name)
306
-    {
307
-        $this->_initialize_collections();
308
-        return ! empty($this->_active_message_types[ $messenger_name ]);
309
-    }
310
-
311
-
312
-    /**
313
-     * This returns any settings that might be on a message type for a messenger
314
-     *
315
-     * @param string $messenger_name    The slug of the messenger
316
-     * @param string $message_type_name The slug of the message type getting the settings for.
317
-     * @return array
318
-     */
319
-    public function get_message_type_settings_for_messenger($messenger_name, $message_type_name)
320
-    {
321
-        $settings = array();
322
-        if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
-            $settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
-                ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
325
-                : array();
326
-        }
327
-        return $settings;
328
-    }
329
-
330
-
331
-    /**
332
-     * Returns whether the given messenger name has active message types on it.
333
-     * Infers whether the messenger is active or not as well.
334
-     *
335
-     * @param string $messenger_name
336
-     * @return bool
337
-     */
338
-    public function messenger_has_active_message_types($messenger_name)
339
-    {
340
-        $this->_initialize_collections();
341
-        return
342
-            ! empty($this->_active_message_types[ $messenger_name ])
343
-            && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
344
-    }
345
-
346
-
347
-    /**
348
-     * This checks the _active_message_types property for any active message types
349
-     * that are present for the given messenger and returns them.
350
-     *
351
-     * @since 4.9.0
352
-     * @param string $messenger_name The messenger being checked
353
-     * @return EE_message_type[]|array    (empty array if no active_message_types)
354
-     */
355
-    public function get_active_message_types_for_messenger($messenger_name)
356
-    {
357
-        $message_types = array();
358
-        if (! $this->messenger_has_active_message_types($messenger_name)) {
359
-            return $message_types;
360
-        }
361
-        $installed_message_types = $this->installed_message_types();
362
-        foreach ($installed_message_types as $message_type_name => $message_type) {
363
-            if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
-                $message_types[ $message_type_name ] = $message_type;
365
-            }
366
-        }
367
-        return $message_types;
368
-    }
369
-
370
-
371
-    /**
372
-     * This does NOT return the _active_message_types property but
373
-     * simply returns an array of active message type names from that property.
374
-     * (The _active_message_types property is indexed by messenger and active message_types per messenger).
375
-     *
376
-     * @return array message_type references (string)
377
-     */
378
-    public function list_of_active_message_types()
379
-    {
380
-        $active_message_type_names = array();
381
-        $this->_initialize_collections();
382
-        foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
-            if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
384
-                continue;
385
-            }
386
-            foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
-                if (! in_array($message_type_name, $active_message_type_names)) {
388
-                    $active_message_type_names[] = $message_type_name;
389
-                }
390
-            }
391
-        }
392
-        return $active_message_type_names;
393
-    }
394
-
395
-
396
-    /**
397
-     * Same as list_of_active_message_types() except this returns actual EE_message_type objects
398
-     *
399
-     * @since 4.9.0
400
-     * @return \EE_message_type[]
401
-     */
402
-    public function get_active_message_type_objects()
403
-    {
404
-        $active_message_types      = array();
405
-        $installed_message_types   = $this->installed_message_types();
406
-        $active_message_type_names = $this->list_of_active_message_types();
407
-        foreach ($active_message_type_names as $active_message_type_name) {
408
-            if (isset($installed_message_types[ $active_message_type_name ])) {
409
-                $active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
410
-            }
411
-        }
412
-        return $active_message_types;
413
-    }
414
-
415
-
416
-    /**
417
-     * @return \EE_message_type[]
418
-     */
419
-    public function installed_message_types()
420
-    {
421
-        if (empty($this->_installed_message_types)) {
422
-            $this->message_type_collection()->rewind();
423
-            while ($this->message_type_collection()->valid()) {
424
-                $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
425
-                $this->message_type_collection()->next();
426
-            }
427
-        }
428
-        return $this->_installed_message_types;
429
-    }
430
-
431
-
432
-    /**
433
-     * @param string $message_type_name
434
-     * @return \EE_message_type
435
-     * @throws EE_Error
436
-     */
437
-    public function valid_message_type($message_type_name)
438
-    {
439
-        $message_type = $this->get_message_type($message_type_name);
440
-        if ($message_type instanceof EE_message_type) {
441
-            return $message_type;
442
-        }
443
-        throw new EE_Error(
444
-            sprintf(
445
-                __('The "%1$s" message type is either invalid or not installed', 'event_espresso'),
446
-                $message_type_name
447
-            )
448
-        );
449
-    }
450
-
451
-
452
-    /**
453
-     * valid_message_type_for_messenger
454
-     *
455
-     * @param EE_messenger $messenger
456
-     * @param string       $message_type_name
457
-     * @return boolean
458
-     * @throws EE_Error
459
-     */
460
-    public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461
-    {
462
-        $valid_message_types = $messenger->get_valid_message_types();
463
-        if (! in_array($message_type_name, $valid_message_types)) {
464
-            throw new EE_Error(
465
-                sprintf(
466
-                    __(
467
-                        'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger.  Double-check the spelling and verify that message type has been registered as a valid type with the messenger.',
468
-                        'event_espresso'
469
-                    ),
470
-                    $message_type_name,
471
-                    __METHOD__,
472
-                    $messenger->name
473
-                )
474
-            );
475
-        }
476
-        return true;
477
-    }
478
-
479
-
480
-    /**
481
-     * Used to return active messengers array stored in the wp options table.
482
-     * If no value is present in the option then an empty array is returned.
483
-     *
484
-     * @param   bool $reset     If true then we ignore whether the option is cached on the _active_message_types
485
-     *                          property and pull directly from the db.  Otherwise whatever is currently on the
486
-     *                          $_active_message_types property is pulled.
487
-     * @return array
488
-     */
489
-    public function get_active_messengers_option($reset = false)
490
-    {
491
-        if ($reset) {
492
-            $this->_active_message_types = get_option('ee_active_messengers', array());
493
-        }
494
-        return $this->_active_message_types;
495
-    }
496
-
497
-
498
-    /**
499
-     * Used to update the active messengers array stored in the wp options table.
500
-     *
501
-     * @param array $active_messenger_settings Incoming data to save.  If empty, then the internal cached property
502
-     *                                         representing this data is used.
503
-     * @return bool FALSE if not updated, TRUE if updated.
504
-     */
505
-    public function update_active_messengers_option($active_messenger_settings = array())
506
-    {
507
-        $active_messenger_settings = empty($active_messenger_settings) ? $this->_active_message_types : $active_messenger_settings;
508
-        // make sure _active_message_types is updated (this is the internal cache for the settings).
509
-        $this->_active_message_types = $active_messenger_settings;
510
-        return update_option('ee_active_messengers', $active_messenger_settings);
511
-    }
512
-
513
-
514
-    /**
515
-     * Used to return has activated message types for messengers array stored in the wp options table.
516
-     * If no value is present in the option then an empty array is returned.
517
-     * The value is cached on the $_has_activated_messengers_and_message_types property for future calls.
518
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
519
-     *
520
-     * @param   bool $reset Used to indicate that any cached value should be ignored.
521
-     * @return array
522
-     */
523
-    public function get_has_activated_messengers_option($reset = false)
524
-    {
525
-        if ($reset || empty($this->_has_activated_messengers_and_message_types)) {
526
-            $this->_has_activated_messengers_and_message_types = get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, array());
527
-        }
528
-        return $this->_has_activated_messengers_and_message_types;
529
-    }
530
-
531
-
532
-    /**
533
-     * Used to update the has activated option in the db.
534
-     *
535
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
536
-     *
537
-     * @param array $has_activated_messengers Incoming data to save.  If empty, then the internal cached property
538
-     *                                        representing this data is used.
539
-     * @return bool FALSE if not updated, TRUE if updated.
540
-     */
541
-    public function update_has_activated_messengers_option($has_activated_messengers = array())
542
-    {
543
-        // make sure the option has been retrieved from first so we don't overwrite it accidentally.
544
-        if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) {
545
-            $this->get_has_activated_messengers_option();
546
-        }
547
-        $has_activated_messengers = empty($has_activated_messengers)
548
-            ? $this->_has_activated_messengers_and_message_types
549
-            : $has_activated_messengers;
550
-        return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers);
551
-    }
552
-
553
-
554
-    /**
555
-     * wrapper for _set_active_messengers_and_message_types()
556
-     */
557
-    public function reset_active_messengers_and_message_types()
558
-    {
559
-        $this->_set_active_messengers_and_message_types();
560
-    }
561
-
562
-
563
-    /**
564
-     * Generate list of active messengers and message types from collection.
565
-     * This sets up the active messengers from what is present in the database.
566
-     */
567
-    protected function _set_active_messengers_and_message_types()
568
-    {
569
-        // echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n";
570
-        // list of activated messengers as set via the admin
571
-        // note calling `get_active_messengers_options` also initializes the _active_message_types property.
572
-        $this->get_active_messengers_option(true);
573
-        $this->ensure_messengers_are_active(array(), false, true);
574
-        $this->update_active_messengers_option();
575
-        $this->update_has_activated_messengers_option();
576
-    }
577
-
578
-
579
-    /**
580
-     * Ensures that the specified messenger is currently active.
581
-     * If not, activates it and its default message types.
582
-     *
583
-     * @param string $messenger_name
584
-     * @param bool   $update_option Whether to update the option in the db or not.
585
-     * @return boolean true if either already active or successfully activated.
586
-     */
587
-    public function ensure_messenger_is_active($messenger_name, $update_option = true)
588
-    {
589
-        if (! isset($this->_active_messengers[ $messenger_name ])) {
590
-            try {
591
-                $this->activate_messenger($messenger_name, array(), $update_option);
592
-            } catch (EE_Error $e) {
593
-                EE_Error::add_error(
594
-                    $e->getMessage(),
595
-                    __FILE__,
596
-                    __FUNCTION__,
597
-                    __LINE__
598
-                );
599
-                return false;
600
-            }
601
-        }
602
-        return true;
603
-    }
604
-
605
-
606
-    /**
607
-     * This ensures the given array of messenger names is active in the system.
608
-     * Note, this method will not activate any NEW message types for the messenger when it is called. Instead,
609
-     * it will automatically activate the default message types for the messenger if its not active.
610
-     *
611
-     * @param array $messenger_names  Array of messenger names for messengers to be activated.  If an empty array
612
-     *                                (default) then will attempt to set the active messengers from the
613
-     *                                activated_messengers option
614
-     *                                (stored in $_active_message_types property).
615
-     * @param bool  $update_option    Whether to update the related active messengers option.
616
-     * @param bool  $verify           Whether to verify the messengers are installed before activating. Note if this is
617
-     *                                set to true and a messenger is indicated as active, but is NOT installed, then it
618
-     *                                will automatically be deactivated.
619
-     */
620
-    public function ensure_messengers_are_active($messenger_names = array(), $update_option = true, $verify = false)
621
-    {
622
-        $messenger_names = empty($messenger_names) ? array_keys($this->_active_message_types) : $messenger_names;
623
-
624
-        $not_installed = array();
625
-        foreach ($messenger_names as $messenger_name) {
626
-            if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) {
627
-                $not_installed[] = $messenger_name;
628
-                $this->deactivate_messenger($messenger_name);
629
-                continue;
630
-            }
631
-            $this->ensure_messenger_is_active($messenger_name, $update_option);
632
-        }
633
-
634
-        if (! empty($not_installed)) {
635
-            EE_Error::add_error(
636
-                sprintf(
637
-                    __('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
638
-                    '<br />',
639
-                    implode(', ', $not_installed)
640
-                ),
641
-                __FILE__,
642
-                __FUNCTION__,
643
-                __LINE__
644
-            );
645
-        }
646
-    }
647
-
648
-
649
-    /**
650
-     * Ensures that the specified message type for the given messenger is currently active, if not activates it.
651
-     * This ALSO ensures that the given messenger is active as well!
652
-     *
653
-     * @param string $message_type_name message type name.
654
-     * @param        $messenger_name
655
-     * @param bool   $update_option     Whether to update the option in the db or not.
656
-     * @return bool  Returns true if already is active or if was activated successfully.
657
-     * @throws EE_Error
658
-     */
659
-    public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true)
660
-    {
661
-        // grab the messenger to work with.
662
-        $messenger = $this->valid_messenger($messenger_name);
663
-        if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) {
664
-            // ensure messenger is active (that's an inherent coupling between active message types and the
665
-            // messenger they are being activated for.
666
-            try {
667
-                if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668
-                    // all is good so let's just get it active
669
-                    $this->activate_messenger($messenger, array($message_type_name), $update_option);
670
-                }
671
-            } catch (EE_Error $e) {
672
-                EE_Error::add_error(
673
-                    $e->getMessage(),
674
-                    __FILE__,
675
-                    __FUNCTION__,
676
-                    __LINE__
677
-                );
678
-                return false;
679
-            }
680
-        }
681
-        return true;
682
-    }
683
-
684
-
685
-    /**
686
-     * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a
687
-     * messenger are active in one go.
688
-     *
689
-     * @param array  $message_type_names Array of message type names to ensure are active.
690
-     * @param string $messenger_name     The name of the messenger that the message types are to be activated on.
691
-     * @param bool   $update_option      Whether to persist the activation to the database or not (default true).
692
-     */
693
-    public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true)
694
-    {
695
-        $message_type_names = (array) $message_type_names;
696
-        foreach ($message_type_names as $message_type_name) {
697
-            // note, intentionally not updating option here because we're in a loop.
698
-            // We'll follow the instructions of the incoming $update_option argument after the loop.
699
-            $this->ensure_message_type_is_active($message_type_name, $messenger_name, false);
700
-        }
701
-        if ($update_option) {
702
-            $this->update_active_messengers_option();
703
-            $this->update_has_activated_messengers_option();
704
-        }
705
-    }
706
-
707
-
708
-    /**
709
-     * Activates the specified messenger.
710
-     *
711
-     * @param EE_messenger|string $messenger    Instantiated EE_messenger OR messenger name if not already loaded!
712
-     * @param array  $message_type_names        An array of message type names to activate with this messenger.
713
-     *                                          If included we do NOT setup the default message types
714
-     *                                          (assuming they are already setup.)
715
-     * @param bool   $update_active_messengers_option
716
-     * @return array of generated templates
717
-     * @throws EE_Error
718
-     */
719
-    public function activate_messenger(
720
-        $messenger,
721
-        $message_type_names = array(),
722
-        $update_active_messengers_option = true
723
-    ) {
724
-        $templates = array();
725
-        // grab the messenger to work with.
726
-        $messenger = $messenger instanceof EE_messenger
727
-            ? $messenger
728
-            : $this->messenger_collection()->get_by_info($messenger);
729
-        // it's inactive. Activate it.
730
-        if ($messenger instanceof EE_messenger) {
731
-            $this->_active_messengers[ $messenger->name ] = $messenger;
732
-            // activate incoming message types set to be activated with messenger.
733
-            $message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734
-            // setup any initial settings for the messenger if necessary.
735
-            $this->add_settings_for_messenger($messenger->name);
736
-            if ($update_active_messengers_option) {
737
-                $this->update_active_messengers_option();
738
-                $this->update_has_activated_messengers_option();
739
-            }
740
-            // generate new templates if necessary and ensure all related templates that are already in the database are
741
-            // marked active.  Note, this will also deactivate a message type for a messenger if the template
742
-            // cannot be successfully created during its attempt (only happens for global template attempts).
743
-            if (! empty($message_type_names)) {
744
-                $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745
-                EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746
-            }
747
-        }
748
-        return $templates;
749
-    }
750
-
751
-
752
-    /**
753
-     * Activates given message types for the given EE_messenger object.
754
-     * Note: (very important) This method does not persist the activation to the database.
755
-     * See code implementing this method in this class for examples of how to persist.
756
-     *
757
-     * @param \EE_messenger $messenger
758
-     * @param  array        $message_type_names
759
-     * @return array
760
-     */
761
-    protected function _activate_message_types(EE_messenger $messenger, $message_type_names = array())
762
-    {
763
-        // If $message_type_names is empty, AND $this->_active_message_types is empty, then that means
764
-        // things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765
-        // So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766
-        // only override _active_message_types when an explicit array of $message_type_names has been provided.
767
-        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
768
-            ? $messenger->get_default_message_types()
769
-            : (array) $message_type_names;
770
-
771
-        // now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
-        if (! isset($this->_active_message_types[ $messenger->name ])) {
773
-            $this->_active_message_types[ $messenger->name ]['settings'] = array();
774
-        }
775
-
776
-        if ($message_type_names) {
777
-            // cycle thru message types
778
-            foreach ($message_type_names as $message_type_name) {
779
-                // only register the message type as active IF it isn't already active
780
-                // and if its actually installed.
781
-                if (
782
-                    ! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
783
-                ) {
784
-                    $this->add_settings_for_message_type($messenger->name, $message_type_name);
785
-                    $this->_set_messenger_has_activated_message_type(
786
-                        $messenger,
787
-                        $message_type_name
788
-                    );
789
-                }
790
-            }
791
-        }
792
-        return $message_type_names;
793
-    }
794
-
795
-
796
-    /**
797
-     * add_settings_for_message_type
798
-     * NOTE This does NOT automatically persist any settings to the db.  Client code should call
799
-     * $this->update_active_messengers_option to persist.
800
-     *
801
-     * @param  string $messenger_name    The name of the messenger adding the settings for
802
-     * @param  string $message_type_name The name of the message type adding the settings for
803
-     * @param  array  $new_settings      Any new settings being set for the message type and messenger
804
-     */
805
-    public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = array())
806
-    {
807
-        // get installed message type from collection
808
-        $message_type      = $this->message_type_collection()->get_by_info($message_type_name);
809
-        $existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name);
810
-        // we need to setup any initial settings for message types
811
-        if ($message_type instanceof EE_message_type) {
812
-            $default_settings = $message_type->get_admin_settings_fields();
813
-            foreach ($default_settings as $field => $values) {
814
-                if (isset($new_settings[ $field ])) {
815
-                    $existing_settings[ $field ] = $new_settings[ $field ];
816
-                    continue;
817
-                }
818
-                if (! isset($existing_settings[ $field ])) {
819
-                    $existing_settings[ $field ] = $values['default'];
820
-                }
821
-            }
822
-        }
823
-        $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
824
-    }
825
-
826
-
827
-    /**
828
-     * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger
829
-     * and message type.
830
-     *
831
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
832
-     *
833
-     * @access protected
834
-     * @param \EE_messenger $messenger
835
-     * @param string        $message_type_name
836
-     */
837
-    protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name)
838
-    {
839
-
840
-        // if _has_activated_messengers_and_message_types is empty then lets ensure its initialized
841
-        if (empty($this->_has_activated_messengers_and_message_types)) {
842
-            $this->get_has_activated_messengers_option();
843
-        }
844
-
845
-        // make sure this messenger has a record in the has_activated array
846
-        if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
847
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
848
-        }
849
-        // check if message type has already been added
850
-        if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
851
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
852
-        }
853
-    }
854
-
855
-
856
-    /**
857
-     * add_settings_for_messenger
858
-     * NOTE This does NOT automatically persist any settings to the db.  Client code should call
859
-     * $this->update_active_messengers_option to persist.
860
-     *
861
-     * @param string $messenger_name The name of the messenger the settings is being added for.
862
-     * @param array  $new_settings   An array of settings to update the existing settings.
863
-     */
864
-    public function add_settings_for_messenger($messenger_name, $new_settings = array())
865
-    {
866
-        $messenger = $this->get_messenger($messenger_name);
867
-        if ($messenger instanceof EE_messenger) {
868
-            $msgr_settings = $messenger->get_admin_settings_fields();
869
-            if (! empty($msgr_settings)) {
870
-                foreach ($msgr_settings as $field => $value) {
871
-                    // is there a new setting for this?
872
-                    if (isset($new_settings[ $field ])) {
873
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
874
-                        continue;
875
-                    }
876
-                    // only set the default if it isn't already set.
877
-                    if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
878
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
879
-                    }
880
-                }
881
-            }
882
-        }
883
-    }
884
-
885
-
886
-    /**
887
-     * deactivate_messenger
888
-     *
889
-     * @param  string|EE_messenger $messenger_name name of messenger
890
-     * @return void
891
-     */
892
-    public function deactivate_messenger($messenger_name)
893
-    {
894
-        $this->_initialize_collections();
895
-        if ($messenger_name instanceof EE_messenger) {
896
-            $messenger_name = $messenger_name->name;
897
-        }
898
-        unset($this->_active_messengers[ $messenger_name ]);
899
-        unset($this->_active_message_types[ $messenger_name ]);
900
-        $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
901
-        $this->update_active_messengers_option();
902
-    }
903
-
904
-
905
-    /**
906
-     * Deactivates a message type (note this will deactivate across all messenger's it is active on.
907
-     *
908
-     * @param  string $message_type_name     name of message type being deactivated
909
-     * @param bool    $set_has_active_record By default we always record the has_active record when deactivating a message
910
-     *                                       type.  However, this can be overridden if we don't want this set (usually when
911
-     *                                       this is called as a part of deregistration of a custom message type)
912
-     */
913
-    public function deactivate_message_type($message_type_name, $set_has_active_record = true)
914
-    {
915
-        $this->_initialize_collections();
916
-        if ($message_type_name instanceof EE_message_type) {
917
-            $message_type_name = $message_type_name->name;
918
-        }
919
-        foreach ($this->_active_message_types as $messenger_name => $settings) {
920
-            unset(
921
-                $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
922
-            );
923
-
924
-            // we always record (even on deactivation) that a message type has been activated because there should at
925
-            // least be a record in the "has_activated" option that it WAS active at one point.
926
-            if ($set_has_active_record) {
927
-                $messenger = $this->get_messenger($messenger_name);
928
-                $this->_set_messenger_has_activated_message_type($messenger, $message_type_name);
929
-            }
930
-        }
931
-        $this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name);
932
-        $this->update_active_messengers_option();
933
-        $this->update_has_activated_messengers_option();
934
-    }
935
-
936
-
937
-    /**
938
-     * Deactivates a message type for a specific messenger as opposed to all messengers.
939
-     *
940
-     * @param string $message_type_name Name of message type being deactivated.
941
-     * @param string $messenger_name    Name of messenger the message type is being deactivated for.
942
-     */
943
-    public function deactivate_message_type_for_messenger($message_type_name, $messenger_name)
944
-    {
945
-        $this->_initialize_collections();
946
-        if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
947
-            unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
948
-        }
949
-        $this->_message_template_group_model->deactivate_message_template_groups_for(
950
-            array($messenger_name),
951
-            array($message_type_name)
952
-        );
953
-        $this->update_active_messengers_option();
954
-    }
955
-
956
-
957
-    /**
958
-     * Used to verify if a message can be sent for the given messenger and message type
959
-     * and that it is a generating messenger (used for generating message templates).
960
-     *
961
-     * @param EE_messenger    $messenger    messenger used in trigger
962
-     * @param EE_message_type $message_type message type used in trigger
963
-     * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
964
-     */
965
-    public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type)
966
-    {
967
-        // get the $messengers the message type says it can be used with.
968
-        foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) {
969
-            if (
970
-                $messenger->name === $generating_messenger
971
-                && $this->is_message_type_active_for_messenger($messenger->name, $message_type->name)
972
-            ) {
973
-                return true;
974
-            }
975
-        }
976
-        return false;
977
-    }
978
-
979
-
980
-    /**
981
-     * This returns all the contexts that are registered by all message types.
982
-     * If $slugs_only is true,
983
-     * then just an array indexed by unique context slugs with the latest label representation for that slug.
984
-     * array(
985
-     *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
986
-     * );
987
-     * If $slugs_only is false, then the format is:
988
-     * array(
989
-     *      'message_type_name' => array(
990
-     *          'context_slug' => array(
991
-     *              'label' => 'localized label for context',
992
-     *              'description' => 'localized description for context'
993
-     *          )
994
-     *      )
995
-     * );
996
-     * Keep in mind that although different message types may share the same context slugs,
997
-     * it is possible that the context is described differently by the message type.
998
-     *
999
-     * @since 4.9.0
1000
-     * @param   bool $slugs_only Whether to return an array of just slugs and labels (true)
1001
-     *                           or all contexts indexed by message type.
1002
-     * @return array
1003
-     */
1004
-    public function get_all_contexts($slugs_only = true)
1005
-    {
1006
-        $key = $slugs_only ? 'slugs' : 'all';
1007
-        // check if contexts has been setup yet.
1008
-        if (empty($this->_contexts[ $key ])) {
1009
-            // So let's get all active message type objects and loop through to get all unique contexts
1010
-            foreach ($this->get_active_message_type_objects() as $message_type) {
1011
-                if ($message_type instanceof EE_message_type) {
1012
-                    $message_type_contexts = $message_type->get_contexts();
1013
-                    if ($slugs_only) {
1014
-                        foreach ($message_type_contexts as $context => $context_details) {
1015
-                            $this->_contexts[ $key ][ $context ] = $context_details['label'];
1016
-                        }
1017
-                    } else {
1018
-                        $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1019
-                    }
1020
-                }
1021
-            }
1022
-        }
1023
-        return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1024
-    }
1025
-
1026
-
1027
-    /**
1028
-     * This checks the internal record of what message types are considered "active" and verifies that
1029
-     * there is an installed class definition for that message type.  If the active message type does not have a
1030
-     * corresponding accessible message type class then it will be deactivated from all messengers it is active on and
1031
-     * any related message templates will be inactivated as well.
1032
-     *
1033
-     * @return bool   true means all active message types are valid, false means at least one message type was
1034
-     *                deactivated.
1035
-     */
1036
-    public function validate_active_message_types_are_installed()
1037
-    {
1038
-        $list_of_active_message_type_names = $this->list_of_active_message_types();
1039
-        $installed_message_types           = $this->installed_message_types();
1040
-        $all_message_types_valid           = true;
1041
-        // loop through list of active message types and verify they are installed.
1042
-        foreach ($list_of_active_message_type_names as $message_type_name) {
1043
-            if (! isset($installed_message_types[ $message_type_name ])) {
1044
-                $this->remove_message_type_has_been_activated_from_all_messengers(
1045
-                    $message_type_name,
1046
-                    true
1047
-                );
1048
-                $this->deactivate_message_type($message_type_name, false);
1049
-                $all_message_types_valid = false;
1050
-            }
1051
-        }
1052
-        return $all_message_types_valid;
1053
-    }
1054
-
1055
-
1056
-    /**
1057
-     * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been
1058
-     * activated for the given messenger.  This can be called by client code on plugin updates etc to determine whether
1059
-     * to attempt automatically reactivating message types that should be activated by default or not.
1060
-     *
1061
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1062
-     *
1063
-     * @param $message_type_name
1064
-     * @param $messenger_name
1065
-     * @return bool
1066
-     */
1067
-    public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1068
-    {
1069
-        $has_activated = $this->get_has_activated_messengers_option();
1070
-        return isset($has_activated[ $messenger_name ])
1071
-               && in_array($message_type_name, $has_activated[ $messenger_name ]);
1072
-    }
1073
-
1074
-
1075
-    /**
1076
-     * This method unsets a message type from the given messenger has activated option.
1077
-     *
1078
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1079
-     *
1080
-     * @param string $message_type_name
1081
-     * @param string $messenger_name
1082
-     * @param bool   $consider_current_state  Whether to consider whether the  message type is currently active or not.
1083
-     *                                        If it is currently active, then remove.  Otherwise leave it alone.
1084
-     */
1085
-    public function remove_message_type_has_been_activated_for_messenger(
1086
-        $message_type_name,
1087
-        $messenger_name,
1088
-        $consider_current_state = false
1089
-    ) {
1090
-        if (
1091
-            $consider_current_state
1092
-            && ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
1093
-        ) {
1094
-            // when consider current state is true, this means we don't want to change anything on the "has_activated"
1095
-            // record if the message type is currently active for this messenger.  This is used when we want to retain
1096
-            // the record for user initiated inactivations of the message type.
1097
-            return;
1098
-        }
1099
-        $has_activated = $this->get_has_activated_messengers_option();
1100
-        $key_for_message_type = isset($has_activated[ $messenger_name ])
1101
-            ? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1102
-            : false;
1103
-        if ($key_for_message_type !== false) {
1104
-            unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1105
-            $this->update_has_activated_messengers_option($has_activated);
1106
-            // reset the internal cached property
1107
-            $this->get_has_activated_messengers_option(true);
1108
-        }
1109
-    }
1110
-
1111
-
1112
-    /**
1113
-     * Removes a message type active record from all messengers it is attached to.
1114
-     *
1115
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1116
-     *
1117
-     * @param      $message_type_name
1118
-     * @param bool $consider_current_state  Whether to consider whether the  message type is currently active or not.
1119
-     *                                      If it is currently active, then remove.  Otherwise leave it alone.
1120
-     */
1121
-    public function remove_message_type_has_been_activated_from_all_messengers(
1122
-        $message_type_name,
1123
-        $consider_current_state = false
1124
-    ) {
1125
-        foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) {
1126
-            $this->remove_message_type_has_been_activated_for_messenger(
1127
-                $message_type_name,
1128
-                $messenger_name,
1129
-                $consider_current_state
1130
-            );
1131
-        }
1132
-    }
15
+	/**
16
+	 * This option in the database is used to keep a record of message types that have been activated for a messenger
17
+	 * at some point in the history of the site.  It is utilized by the implementation of the 'force' flag in
18
+	 * EE_Register_Message_Type.  The force flag is an indication of whether a message type should be activated by
19
+	 * default when the message type is registered.  However, if a user has explicitly deactivated a message type, then
20
+	 * the force flag is ignored.  The method by which the code knows whether to ignore this flag is via this option.
21
+	 * Note, that this is NOT a historical record.  Its entirely possible for a message type to have been activated for
22
+	 * a messenger and yet not have a record in this option.  This occurs when a message type is inactivated through an
23
+	 * automated process (when an add-on registering the message type deactivates, or when some other code calls the
24
+	 * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to ensure
25
+	 * the "force" flag is respected if that message type is later re-registered.
26
+	 *
27
+	 * This option should NOT be used to determine the current "active" state of a message type for a given messenger.
28
+	 *
29
+	 * The name of this option (and related methods/properties) is due to matching the original intended purpose for the
30
+	 * option that got superseded by later behaviour requirements.
31
+	 */
32
+	const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger';
33
+
34
+	/**
35
+	 * @type boolean $_initialized
36
+	 */
37
+	protected $_initialized = false;
38
+
39
+	/**
40
+	 * @type EE_Messenger_Collection $_messenger_collection_loader
41
+	 */
42
+	protected $_messenger_collection_loader;
43
+
44
+	/**
45
+	 * @type EE_Message_Type_Collection $_message_type_collection_loader
46
+	 */
47
+	protected $_message_type_collection_loader;
48
+
49
+	/**
50
+	 * @type EEM_Message_Template_Group $_message_template_group_model
51
+	 */
52
+	protected $_message_template_group_model;
53
+
54
+	/**
55
+	 * @type EE_messenger[]
56
+	 */
57
+	protected $_installed_messengers = array();
58
+
59
+	/**
60
+	 * @type EE_message_type[]
61
+	 */
62
+	protected $_installed_message_types = array();
63
+
64
+	/**
65
+	 * Array of active messengers.
66
+	 * Format is this:
67
+	 * array(
68
+	 *      'messenger_name' => EE_messenger
69
+	 * )
70
+	 *
71
+	 * @type EE_messenger[]
72
+	 */
73
+	protected $_active_messengers = array();
74
+
75
+	/**
76
+	 * Formatted array of active message types grouped per messenger.
77
+	 * Format is this:
78
+	 * array(
79
+	 *      'messenger_name' => array(
80
+	 *          'settings' => array(
81
+	 *              '{messenger_name}-message_types' => array(
82
+	 *                  'message_type_name' => array() //variable array of settings corresponding to message type.
83
+	 *              )
84
+	 *          )
85
+	 *      )
86
+	 * )
87
+	 *
88
+	 * @type array
89
+	 */
90
+	protected $_active_message_types = array();
91
+
92
+
93
+	/**
94
+	 * This holds the array of messengers and their corresponding message types that have
95
+	 * been activated on a site at some point.  This is an important record that helps the messages system
96
+	 * not accidentally reactivate something that was intentionally deactivated by a user.
97
+	 *
98
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
99
+	 *
100
+	 * @type array
101
+	 */
102
+	protected $_has_activated_messengers_and_message_types = array();
103
+
104
+	/**
105
+	 * An array of unique message type contexts across all active message types.
106
+	 * The array will be indexed by either 'slugs' or 'all'.
107
+	 * The slugs index contains an array indexed by unique context slugs with the latest label representation for that
108
+	 * slug. array(
109
+	 *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
110
+	 * );
111
+	 * The all index returns an array in this format:
112
+	 * array(
113
+	 *      'message_type_name' => array(
114
+	 *          'context_slug' => array(
115
+	 *              'label' => 'localized label for context',
116
+	 *              'description' => 'localized description for context'
117
+	 *          )
118
+	 *      )
119
+	 * );
120
+	 *
121
+	 * @type array
122
+	 */
123
+	protected $_contexts = array();
124
+
125
+
126
+	/**
127
+	 * EE_Message_Resource_Manager constructor.
128
+	 *
129
+	 * @param \EE_Messenger_Collection_Loader    $Messenger_Collection_Loader
130
+	 * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader
131
+	 * @param \EEM_Message_Template_Group        $Message_Template_Group_Model
132
+	 */
133
+	public function __construct(
134
+		EE_Messenger_Collection_Loader $Messenger_Collection_Loader,
135
+		EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader,
136
+		EEM_Message_Template_Group $Message_Template_Group_Model
137
+	) {
138
+		$this->_messenger_collection_loader    = $Messenger_Collection_Loader;
139
+		$this->_message_type_collection_loader = $Message_Type_Collection_Loader;
140
+		$this->_message_template_group_model   = $Message_Template_Group_Model;
141
+	}
142
+
143
+
144
+	/**
145
+	 * @return void
146
+	 */
147
+	protected function _initialize_collections()
148
+	{
149
+		if ($this->_initialized) {
150
+			return;
151
+		}
152
+		$this->_initialized = true;
153
+		$this->_messenger_collection_loader->load_messengers_from_folder();
154
+		$this->_message_type_collection_loader->load_message_types_from_folder();
155
+		$this->get_has_activated_messengers_option(true);
156
+		$this->_set_active_messengers_and_message_types();
157
+	}
158
+
159
+
160
+	/**
161
+	 * @return EE_Messenger_Collection
162
+	 */
163
+	public function messenger_collection()
164
+	{
165
+		$this->_initialize_collections();
166
+		return $this->_messenger_collection_loader->messenger_collection();
167
+	}
168
+
169
+
170
+	/**
171
+	 * @return EE_messenger[]
172
+	 */
173
+	public function active_messengers()
174
+	{
175
+		$this->_initialize_collections();
176
+		return $this->_active_messengers;
177
+	}
178
+
179
+
180
+	/**
181
+	 * @param string $messenger_name
182
+	 * @return \EE_messenger
183
+	 */
184
+	public function get_messenger($messenger_name)
185
+	{
186
+		return $this->messenger_collection()->get_by_info($messenger_name);
187
+	}
188
+
189
+
190
+	/**
191
+	 * This returns the corresponding EE_messenger object for the given string if it is active.
192
+	 *
193
+	 * @param string $messenger
194
+	 * @return EE_messenger | null
195
+	 */
196
+	public function get_active_messenger($messenger)
197
+	{
198
+		$this->_initialize_collections();
199
+		return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
200
+	}
201
+
202
+
203
+	/**
204
+	 * @return \EE_messenger[]
205
+	 */
206
+	public function installed_messengers()
207
+	{
208
+		if (empty($this->_installed_messengers)) {
209
+			$this->_installed_messengers = array();
210
+			$this->messenger_collection()->rewind();
211
+			while ($this->messenger_collection()->valid()) {
212
+				$this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
213
+				$this->messenger_collection()->next();
214
+			}
215
+		}
216
+		return $this->_installed_messengers;
217
+	}
218
+
219
+
220
+	/**
221
+	 * @param string $messenger_name
222
+	 * @return \EE_messenger
223
+	 * @throws EE_Error
224
+	 */
225
+	public function valid_messenger($messenger_name)
226
+	{
227
+		$messenger = $this->get_messenger($messenger_name);
228
+		if ($messenger instanceof EE_messenger) {
229
+			return $messenger;
230
+		}
231
+		throw new EE_Error(
232
+			sprintf(
233
+				__('The "%1$s" messenger is either invalid or not installed', 'event_espresso'),
234
+				$messenger_name
235
+			)
236
+		);
237
+	}
238
+
239
+
240
+	/**
241
+	 * @return EE_Message_Type_Collection
242
+	 */
243
+	public function message_type_collection()
244
+	{
245
+		$this->_initialize_collections();
246
+		return $this->_message_type_collection_loader->message_type_collection();
247
+	}
248
+
249
+
250
+	/**
251
+	 * @return array
252
+	 */
253
+	public function active_message_types()
254
+	{
255
+		$this->_initialize_collections();
256
+		return $this->_active_message_types;
257
+	}
258
+
259
+
260
+	/**
261
+	 * @param string $message_type_name
262
+	 * @return \EE_message_type
263
+	 */
264
+	public function get_message_type($message_type_name)
265
+	{
266
+		return $this->message_type_collection()->get_by_info($message_type_name);
267
+	}
268
+
269
+
270
+	/**
271
+	 * This returns the EE_message_type from the active message types array ( if present );
272
+	 *
273
+	 * @param string $messenger_name
274
+	 * @param string $message_type_name
275
+	 * @return \EE_message_type|null
276
+	 */
277
+	public function get_active_message_type_for_messenger($messenger_name, $message_type_name)
278
+	{
279
+		return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
280
+			? $this->get_message_type($message_type_name)
281
+			: null;
282
+	}
283
+
284
+
285
+	/**
286
+	 * Returns whether the given message type is active for the given messenger.
287
+	 *
288
+	 * @param string $messenger_name
289
+	 * @param string $message_type_name
290
+	 * @return bool
291
+	 */
292
+	public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293
+	{
294
+		$this->_initialize_collections();
295
+		return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
296
+	}
297
+
298
+
299
+	/**
300
+	 * Returns whether the given messenger is active.
301
+	 *
302
+	 * @param string $messenger_name the name of the messenger to check if active.
303
+	 * @return bool
304
+	 */
305
+	public function is_messenger_active($messenger_name)
306
+	{
307
+		$this->_initialize_collections();
308
+		return ! empty($this->_active_message_types[ $messenger_name ]);
309
+	}
310
+
311
+
312
+	/**
313
+	 * This returns any settings that might be on a message type for a messenger
314
+	 *
315
+	 * @param string $messenger_name    The slug of the messenger
316
+	 * @param string $message_type_name The slug of the message type getting the settings for.
317
+	 * @return array
318
+	 */
319
+	public function get_message_type_settings_for_messenger($messenger_name, $message_type_name)
320
+	{
321
+		$settings = array();
322
+		if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
+			$settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
+				? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
325
+				: array();
326
+		}
327
+		return $settings;
328
+	}
329
+
330
+
331
+	/**
332
+	 * Returns whether the given messenger name has active message types on it.
333
+	 * Infers whether the messenger is active or not as well.
334
+	 *
335
+	 * @param string $messenger_name
336
+	 * @return bool
337
+	 */
338
+	public function messenger_has_active_message_types($messenger_name)
339
+	{
340
+		$this->_initialize_collections();
341
+		return
342
+			! empty($this->_active_message_types[ $messenger_name ])
343
+			&& ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
344
+	}
345
+
346
+
347
+	/**
348
+	 * This checks the _active_message_types property for any active message types
349
+	 * that are present for the given messenger and returns them.
350
+	 *
351
+	 * @since 4.9.0
352
+	 * @param string $messenger_name The messenger being checked
353
+	 * @return EE_message_type[]|array    (empty array if no active_message_types)
354
+	 */
355
+	public function get_active_message_types_for_messenger($messenger_name)
356
+	{
357
+		$message_types = array();
358
+		if (! $this->messenger_has_active_message_types($messenger_name)) {
359
+			return $message_types;
360
+		}
361
+		$installed_message_types = $this->installed_message_types();
362
+		foreach ($installed_message_types as $message_type_name => $message_type) {
363
+			if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
+				$message_types[ $message_type_name ] = $message_type;
365
+			}
366
+		}
367
+		return $message_types;
368
+	}
369
+
370
+
371
+	/**
372
+	 * This does NOT return the _active_message_types property but
373
+	 * simply returns an array of active message type names from that property.
374
+	 * (The _active_message_types property is indexed by messenger and active message_types per messenger).
375
+	 *
376
+	 * @return array message_type references (string)
377
+	 */
378
+	public function list_of_active_message_types()
379
+	{
380
+		$active_message_type_names = array();
381
+		$this->_initialize_collections();
382
+		foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
+			if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
384
+				continue;
385
+			}
386
+			foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
+				if (! in_array($message_type_name, $active_message_type_names)) {
388
+					$active_message_type_names[] = $message_type_name;
389
+				}
390
+			}
391
+		}
392
+		return $active_message_type_names;
393
+	}
394
+
395
+
396
+	/**
397
+	 * Same as list_of_active_message_types() except this returns actual EE_message_type objects
398
+	 *
399
+	 * @since 4.9.0
400
+	 * @return \EE_message_type[]
401
+	 */
402
+	public function get_active_message_type_objects()
403
+	{
404
+		$active_message_types      = array();
405
+		$installed_message_types   = $this->installed_message_types();
406
+		$active_message_type_names = $this->list_of_active_message_types();
407
+		foreach ($active_message_type_names as $active_message_type_name) {
408
+			if (isset($installed_message_types[ $active_message_type_name ])) {
409
+				$active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
410
+			}
411
+		}
412
+		return $active_message_types;
413
+	}
414
+
415
+
416
+	/**
417
+	 * @return \EE_message_type[]
418
+	 */
419
+	public function installed_message_types()
420
+	{
421
+		if (empty($this->_installed_message_types)) {
422
+			$this->message_type_collection()->rewind();
423
+			while ($this->message_type_collection()->valid()) {
424
+				$this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
425
+				$this->message_type_collection()->next();
426
+			}
427
+		}
428
+		return $this->_installed_message_types;
429
+	}
430
+
431
+
432
+	/**
433
+	 * @param string $message_type_name
434
+	 * @return \EE_message_type
435
+	 * @throws EE_Error
436
+	 */
437
+	public function valid_message_type($message_type_name)
438
+	{
439
+		$message_type = $this->get_message_type($message_type_name);
440
+		if ($message_type instanceof EE_message_type) {
441
+			return $message_type;
442
+		}
443
+		throw new EE_Error(
444
+			sprintf(
445
+				__('The "%1$s" message type is either invalid or not installed', 'event_espresso'),
446
+				$message_type_name
447
+			)
448
+		);
449
+	}
450
+
451
+
452
+	/**
453
+	 * valid_message_type_for_messenger
454
+	 *
455
+	 * @param EE_messenger $messenger
456
+	 * @param string       $message_type_name
457
+	 * @return boolean
458
+	 * @throws EE_Error
459
+	 */
460
+	public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461
+	{
462
+		$valid_message_types = $messenger->get_valid_message_types();
463
+		if (! in_array($message_type_name, $valid_message_types)) {
464
+			throw new EE_Error(
465
+				sprintf(
466
+					__(
467
+						'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger.  Double-check the spelling and verify that message type has been registered as a valid type with the messenger.',
468
+						'event_espresso'
469
+					),
470
+					$message_type_name,
471
+					__METHOD__,
472
+					$messenger->name
473
+				)
474
+			);
475
+		}
476
+		return true;
477
+	}
478
+
479
+
480
+	/**
481
+	 * Used to return active messengers array stored in the wp options table.
482
+	 * If no value is present in the option then an empty array is returned.
483
+	 *
484
+	 * @param   bool $reset     If true then we ignore whether the option is cached on the _active_message_types
485
+	 *                          property and pull directly from the db.  Otherwise whatever is currently on the
486
+	 *                          $_active_message_types property is pulled.
487
+	 * @return array
488
+	 */
489
+	public function get_active_messengers_option($reset = false)
490
+	{
491
+		if ($reset) {
492
+			$this->_active_message_types = get_option('ee_active_messengers', array());
493
+		}
494
+		return $this->_active_message_types;
495
+	}
496
+
497
+
498
+	/**
499
+	 * Used to update the active messengers array stored in the wp options table.
500
+	 *
501
+	 * @param array $active_messenger_settings Incoming data to save.  If empty, then the internal cached property
502
+	 *                                         representing this data is used.
503
+	 * @return bool FALSE if not updated, TRUE if updated.
504
+	 */
505
+	public function update_active_messengers_option($active_messenger_settings = array())
506
+	{
507
+		$active_messenger_settings = empty($active_messenger_settings) ? $this->_active_message_types : $active_messenger_settings;
508
+		// make sure _active_message_types is updated (this is the internal cache for the settings).
509
+		$this->_active_message_types = $active_messenger_settings;
510
+		return update_option('ee_active_messengers', $active_messenger_settings);
511
+	}
512
+
513
+
514
+	/**
515
+	 * Used to return has activated message types for messengers array stored in the wp options table.
516
+	 * If no value is present in the option then an empty array is returned.
517
+	 * The value is cached on the $_has_activated_messengers_and_message_types property for future calls.
518
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
519
+	 *
520
+	 * @param   bool $reset Used to indicate that any cached value should be ignored.
521
+	 * @return array
522
+	 */
523
+	public function get_has_activated_messengers_option($reset = false)
524
+	{
525
+		if ($reset || empty($this->_has_activated_messengers_and_message_types)) {
526
+			$this->_has_activated_messengers_and_message_types = get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, array());
527
+		}
528
+		return $this->_has_activated_messengers_and_message_types;
529
+	}
530
+
531
+
532
+	/**
533
+	 * Used to update the has activated option in the db.
534
+	 *
535
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
536
+	 *
537
+	 * @param array $has_activated_messengers Incoming data to save.  If empty, then the internal cached property
538
+	 *                                        representing this data is used.
539
+	 * @return bool FALSE if not updated, TRUE if updated.
540
+	 */
541
+	public function update_has_activated_messengers_option($has_activated_messengers = array())
542
+	{
543
+		// make sure the option has been retrieved from first so we don't overwrite it accidentally.
544
+		if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) {
545
+			$this->get_has_activated_messengers_option();
546
+		}
547
+		$has_activated_messengers = empty($has_activated_messengers)
548
+			? $this->_has_activated_messengers_and_message_types
549
+			: $has_activated_messengers;
550
+		return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers);
551
+	}
552
+
553
+
554
+	/**
555
+	 * wrapper for _set_active_messengers_and_message_types()
556
+	 */
557
+	public function reset_active_messengers_and_message_types()
558
+	{
559
+		$this->_set_active_messengers_and_message_types();
560
+	}
561
+
562
+
563
+	/**
564
+	 * Generate list of active messengers and message types from collection.
565
+	 * This sets up the active messengers from what is present in the database.
566
+	 */
567
+	protected function _set_active_messengers_and_message_types()
568
+	{
569
+		// echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n";
570
+		// list of activated messengers as set via the admin
571
+		// note calling `get_active_messengers_options` also initializes the _active_message_types property.
572
+		$this->get_active_messengers_option(true);
573
+		$this->ensure_messengers_are_active(array(), false, true);
574
+		$this->update_active_messengers_option();
575
+		$this->update_has_activated_messengers_option();
576
+	}
577
+
578
+
579
+	/**
580
+	 * Ensures that the specified messenger is currently active.
581
+	 * If not, activates it and its default message types.
582
+	 *
583
+	 * @param string $messenger_name
584
+	 * @param bool   $update_option Whether to update the option in the db or not.
585
+	 * @return boolean true if either already active or successfully activated.
586
+	 */
587
+	public function ensure_messenger_is_active($messenger_name, $update_option = true)
588
+	{
589
+		if (! isset($this->_active_messengers[ $messenger_name ])) {
590
+			try {
591
+				$this->activate_messenger($messenger_name, array(), $update_option);
592
+			} catch (EE_Error $e) {
593
+				EE_Error::add_error(
594
+					$e->getMessage(),
595
+					__FILE__,
596
+					__FUNCTION__,
597
+					__LINE__
598
+				);
599
+				return false;
600
+			}
601
+		}
602
+		return true;
603
+	}
604
+
605
+
606
+	/**
607
+	 * This ensures the given array of messenger names is active in the system.
608
+	 * Note, this method will not activate any NEW message types for the messenger when it is called. Instead,
609
+	 * it will automatically activate the default message types for the messenger if its not active.
610
+	 *
611
+	 * @param array $messenger_names  Array of messenger names for messengers to be activated.  If an empty array
612
+	 *                                (default) then will attempt to set the active messengers from the
613
+	 *                                activated_messengers option
614
+	 *                                (stored in $_active_message_types property).
615
+	 * @param bool  $update_option    Whether to update the related active messengers option.
616
+	 * @param bool  $verify           Whether to verify the messengers are installed before activating. Note if this is
617
+	 *                                set to true and a messenger is indicated as active, but is NOT installed, then it
618
+	 *                                will automatically be deactivated.
619
+	 */
620
+	public function ensure_messengers_are_active($messenger_names = array(), $update_option = true, $verify = false)
621
+	{
622
+		$messenger_names = empty($messenger_names) ? array_keys($this->_active_message_types) : $messenger_names;
623
+
624
+		$not_installed = array();
625
+		foreach ($messenger_names as $messenger_name) {
626
+			if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) {
627
+				$not_installed[] = $messenger_name;
628
+				$this->deactivate_messenger($messenger_name);
629
+				continue;
630
+			}
631
+			$this->ensure_messenger_is_active($messenger_name, $update_option);
632
+		}
633
+
634
+		if (! empty($not_installed)) {
635
+			EE_Error::add_error(
636
+				sprintf(
637
+					__('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
638
+					'<br />',
639
+					implode(', ', $not_installed)
640
+				),
641
+				__FILE__,
642
+				__FUNCTION__,
643
+				__LINE__
644
+			);
645
+		}
646
+	}
647
+
648
+
649
+	/**
650
+	 * Ensures that the specified message type for the given messenger is currently active, if not activates it.
651
+	 * This ALSO ensures that the given messenger is active as well!
652
+	 *
653
+	 * @param string $message_type_name message type name.
654
+	 * @param        $messenger_name
655
+	 * @param bool   $update_option     Whether to update the option in the db or not.
656
+	 * @return bool  Returns true if already is active or if was activated successfully.
657
+	 * @throws EE_Error
658
+	 */
659
+	public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true)
660
+	{
661
+		// grab the messenger to work with.
662
+		$messenger = $this->valid_messenger($messenger_name);
663
+		if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) {
664
+			// ensure messenger is active (that's an inherent coupling between active message types and the
665
+			// messenger they are being activated for.
666
+			try {
667
+				if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668
+					// all is good so let's just get it active
669
+					$this->activate_messenger($messenger, array($message_type_name), $update_option);
670
+				}
671
+			} catch (EE_Error $e) {
672
+				EE_Error::add_error(
673
+					$e->getMessage(),
674
+					__FILE__,
675
+					__FUNCTION__,
676
+					__LINE__
677
+				);
678
+				return false;
679
+			}
680
+		}
681
+		return true;
682
+	}
683
+
684
+
685
+	/**
686
+	 * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a
687
+	 * messenger are active in one go.
688
+	 *
689
+	 * @param array  $message_type_names Array of message type names to ensure are active.
690
+	 * @param string $messenger_name     The name of the messenger that the message types are to be activated on.
691
+	 * @param bool   $update_option      Whether to persist the activation to the database or not (default true).
692
+	 */
693
+	public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true)
694
+	{
695
+		$message_type_names = (array) $message_type_names;
696
+		foreach ($message_type_names as $message_type_name) {
697
+			// note, intentionally not updating option here because we're in a loop.
698
+			// We'll follow the instructions of the incoming $update_option argument after the loop.
699
+			$this->ensure_message_type_is_active($message_type_name, $messenger_name, false);
700
+		}
701
+		if ($update_option) {
702
+			$this->update_active_messengers_option();
703
+			$this->update_has_activated_messengers_option();
704
+		}
705
+	}
706
+
707
+
708
+	/**
709
+	 * Activates the specified messenger.
710
+	 *
711
+	 * @param EE_messenger|string $messenger    Instantiated EE_messenger OR messenger name if not already loaded!
712
+	 * @param array  $message_type_names        An array of message type names to activate with this messenger.
713
+	 *                                          If included we do NOT setup the default message types
714
+	 *                                          (assuming they are already setup.)
715
+	 * @param bool   $update_active_messengers_option
716
+	 * @return array of generated templates
717
+	 * @throws EE_Error
718
+	 */
719
+	public function activate_messenger(
720
+		$messenger,
721
+		$message_type_names = array(),
722
+		$update_active_messengers_option = true
723
+	) {
724
+		$templates = array();
725
+		// grab the messenger to work with.
726
+		$messenger = $messenger instanceof EE_messenger
727
+			? $messenger
728
+			: $this->messenger_collection()->get_by_info($messenger);
729
+		// it's inactive. Activate it.
730
+		if ($messenger instanceof EE_messenger) {
731
+			$this->_active_messengers[ $messenger->name ] = $messenger;
732
+			// activate incoming message types set to be activated with messenger.
733
+			$message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734
+			// setup any initial settings for the messenger if necessary.
735
+			$this->add_settings_for_messenger($messenger->name);
736
+			if ($update_active_messengers_option) {
737
+				$this->update_active_messengers_option();
738
+				$this->update_has_activated_messengers_option();
739
+			}
740
+			// generate new templates if necessary and ensure all related templates that are already in the database are
741
+			// marked active.  Note, this will also deactivate a message type for a messenger if the template
742
+			// cannot be successfully created during its attempt (only happens for global template attempts).
743
+			if (! empty($message_type_names)) {
744
+				$templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745
+				EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746
+			}
747
+		}
748
+		return $templates;
749
+	}
750
+
751
+
752
+	/**
753
+	 * Activates given message types for the given EE_messenger object.
754
+	 * Note: (very important) This method does not persist the activation to the database.
755
+	 * See code implementing this method in this class for examples of how to persist.
756
+	 *
757
+	 * @param \EE_messenger $messenger
758
+	 * @param  array        $message_type_names
759
+	 * @return array
760
+	 */
761
+	protected function _activate_message_types(EE_messenger $messenger, $message_type_names = array())
762
+	{
763
+		// If $message_type_names is empty, AND $this->_active_message_types is empty, then that means
764
+		// things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765
+		// So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766
+		// only override _active_message_types when an explicit array of $message_type_names has been provided.
767
+		$message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
768
+			? $messenger->get_default_message_types()
769
+			: (array) $message_type_names;
770
+
771
+		// now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
+		if (! isset($this->_active_message_types[ $messenger->name ])) {
773
+			$this->_active_message_types[ $messenger->name ]['settings'] = array();
774
+		}
775
+
776
+		if ($message_type_names) {
777
+			// cycle thru message types
778
+			foreach ($message_type_names as $message_type_name) {
779
+				// only register the message type as active IF it isn't already active
780
+				// and if its actually installed.
781
+				if (
782
+					! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
783
+				) {
784
+					$this->add_settings_for_message_type($messenger->name, $message_type_name);
785
+					$this->_set_messenger_has_activated_message_type(
786
+						$messenger,
787
+						$message_type_name
788
+					);
789
+				}
790
+			}
791
+		}
792
+		return $message_type_names;
793
+	}
794
+
795
+
796
+	/**
797
+	 * add_settings_for_message_type
798
+	 * NOTE This does NOT automatically persist any settings to the db.  Client code should call
799
+	 * $this->update_active_messengers_option to persist.
800
+	 *
801
+	 * @param  string $messenger_name    The name of the messenger adding the settings for
802
+	 * @param  string $message_type_name The name of the message type adding the settings for
803
+	 * @param  array  $new_settings      Any new settings being set for the message type and messenger
804
+	 */
805
+	public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = array())
806
+	{
807
+		// get installed message type from collection
808
+		$message_type      = $this->message_type_collection()->get_by_info($message_type_name);
809
+		$existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name);
810
+		// we need to setup any initial settings for message types
811
+		if ($message_type instanceof EE_message_type) {
812
+			$default_settings = $message_type->get_admin_settings_fields();
813
+			foreach ($default_settings as $field => $values) {
814
+				if (isset($new_settings[ $field ])) {
815
+					$existing_settings[ $field ] = $new_settings[ $field ];
816
+					continue;
817
+				}
818
+				if (! isset($existing_settings[ $field ])) {
819
+					$existing_settings[ $field ] = $values['default'];
820
+				}
821
+			}
822
+		}
823
+		$this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
824
+	}
825
+
826
+
827
+	/**
828
+	 * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger
829
+	 * and message type.
830
+	 *
831
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
832
+	 *
833
+	 * @access protected
834
+	 * @param \EE_messenger $messenger
835
+	 * @param string        $message_type_name
836
+	 */
837
+	protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name)
838
+	{
839
+
840
+		// if _has_activated_messengers_and_message_types is empty then lets ensure its initialized
841
+		if (empty($this->_has_activated_messengers_and_message_types)) {
842
+			$this->get_has_activated_messengers_option();
843
+		}
844
+
845
+		// make sure this messenger has a record in the has_activated array
846
+		if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
847
+			$this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
848
+		}
849
+		// check if message type has already been added
850
+		if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
851
+			$this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
852
+		}
853
+	}
854
+
855
+
856
+	/**
857
+	 * add_settings_for_messenger
858
+	 * NOTE This does NOT automatically persist any settings to the db.  Client code should call
859
+	 * $this->update_active_messengers_option to persist.
860
+	 *
861
+	 * @param string $messenger_name The name of the messenger the settings is being added for.
862
+	 * @param array  $new_settings   An array of settings to update the existing settings.
863
+	 */
864
+	public function add_settings_for_messenger($messenger_name, $new_settings = array())
865
+	{
866
+		$messenger = $this->get_messenger($messenger_name);
867
+		if ($messenger instanceof EE_messenger) {
868
+			$msgr_settings = $messenger->get_admin_settings_fields();
869
+			if (! empty($msgr_settings)) {
870
+				foreach ($msgr_settings as $field => $value) {
871
+					// is there a new setting for this?
872
+					if (isset($new_settings[ $field ])) {
873
+						$this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
874
+						continue;
875
+					}
876
+					// only set the default if it isn't already set.
877
+					if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
878
+						$this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
879
+					}
880
+				}
881
+			}
882
+		}
883
+	}
884
+
885
+
886
+	/**
887
+	 * deactivate_messenger
888
+	 *
889
+	 * @param  string|EE_messenger $messenger_name name of messenger
890
+	 * @return void
891
+	 */
892
+	public function deactivate_messenger($messenger_name)
893
+	{
894
+		$this->_initialize_collections();
895
+		if ($messenger_name instanceof EE_messenger) {
896
+			$messenger_name = $messenger_name->name;
897
+		}
898
+		unset($this->_active_messengers[ $messenger_name ]);
899
+		unset($this->_active_message_types[ $messenger_name ]);
900
+		$this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
901
+		$this->update_active_messengers_option();
902
+	}
903
+
904
+
905
+	/**
906
+	 * Deactivates a message type (note this will deactivate across all messenger's it is active on.
907
+	 *
908
+	 * @param  string $message_type_name     name of message type being deactivated
909
+	 * @param bool    $set_has_active_record By default we always record the has_active record when deactivating a message
910
+	 *                                       type.  However, this can be overridden if we don't want this set (usually when
911
+	 *                                       this is called as a part of deregistration of a custom message type)
912
+	 */
913
+	public function deactivate_message_type($message_type_name, $set_has_active_record = true)
914
+	{
915
+		$this->_initialize_collections();
916
+		if ($message_type_name instanceof EE_message_type) {
917
+			$message_type_name = $message_type_name->name;
918
+		}
919
+		foreach ($this->_active_message_types as $messenger_name => $settings) {
920
+			unset(
921
+				$this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
922
+			);
923
+
924
+			// we always record (even on deactivation) that a message type has been activated because there should at
925
+			// least be a record in the "has_activated" option that it WAS active at one point.
926
+			if ($set_has_active_record) {
927
+				$messenger = $this->get_messenger($messenger_name);
928
+				$this->_set_messenger_has_activated_message_type($messenger, $message_type_name);
929
+			}
930
+		}
931
+		$this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name);
932
+		$this->update_active_messengers_option();
933
+		$this->update_has_activated_messengers_option();
934
+	}
935
+
936
+
937
+	/**
938
+	 * Deactivates a message type for a specific messenger as opposed to all messengers.
939
+	 *
940
+	 * @param string $message_type_name Name of message type being deactivated.
941
+	 * @param string $messenger_name    Name of messenger the message type is being deactivated for.
942
+	 */
943
+	public function deactivate_message_type_for_messenger($message_type_name, $messenger_name)
944
+	{
945
+		$this->_initialize_collections();
946
+		if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
947
+			unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
948
+		}
949
+		$this->_message_template_group_model->deactivate_message_template_groups_for(
950
+			array($messenger_name),
951
+			array($message_type_name)
952
+		);
953
+		$this->update_active_messengers_option();
954
+	}
955
+
956
+
957
+	/**
958
+	 * Used to verify if a message can be sent for the given messenger and message type
959
+	 * and that it is a generating messenger (used for generating message templates).
960
+	 *
961
+	 * @param EE_messenger    $messenger    messenger used in trigger
962
+	 * @param EE_message_type $message_type message type used in trigger
963
+	 * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
964
+	 */
965
+	public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type)
966
+	{
967
+		// get the $messengers the message type says it can be used with.
968
+		foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) {
969
+			if (
970
+				$messenger->name === $generating_messenger
971
+				&& $this->is_message_type_active_for_messenger($messenger->name, $message_type->name)
972
+			) {
973
+				return true;
974
+			}
975
+		}
976
+		return false;
977
+	}
978
+
979
+
980
+	/**
981
+	 * This returns all the contexts that are registered by all message types.
982
+	 * If $slugs_only is true,
983
+	 * then just an array indexed by unique context slugs with the latest label representation for that slug.
984
+	 * array(
985
+	 *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
986
+	 * );
987
+	 * If $slugs_only is false, then the format is:
988
+	 * array(
989
+	 *      'message_type_name' => array(
990
+	 *          'context_slug' => array(
991
+	 *              'label' => 'localized label for context',
992
+	 *              'description' => 'localized description for context'
993
+	 *          )
994
+	 *      )
995
+	 * );
996
+	 * Keep in mind that although different message types may share the same context slugs,
997
+	 * it is possible that the context is described differently by the message type.
998
+	 *
999
+	 * @since 4.9.0
1000
+	 * @param   bool $slugs_only Whether to return an array of just slugs and labels (true)
1001
+	 *                           or all contexts indexed by message type.
1002
+	 * @return array
1003
+	 */
1004
+	public function get_all_contexts($slugs_only = true)
1005
+	{
1006
+		$key = $slugs_only ? 'slugs' : 'all';
1007
+		// check if contexts has been setup yet.
1008
+		if (empty($this->_contexts[ $key ])) {
1009
+			// So let's get all active message type objects and loop through to get all unique contexts
1010
+			foreach ($this->get_active_message_type_objects() as $message_type) {
1011
+				if ($message_type instanceof EE_message_type) {
1012
+					$message_type_contexts = $message_type->get_contexts();
1013
+					if ($slugs_only) {
1014
+						foreach ($message_type_contexts as $context => $context_details) {
1015
+							$this->_contexts[ $key ][ $context ] = $context_details['label'];
1016
+						}
1017
+					} else {
1018
+						$this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1019
+					}
1020
+				}
1021
+			}
1022
+		}
1023
+		return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1024
+	}
1025
+
1026
+
1027
+	/**
1028
+	 * This checks the internal record of what message types are considered "active" and verifies that
1029
+	 * there is an installed class definition for that message type.  If the active message type does not have a
1030
+	 * corresponding accessible message type class then it will be deactivated from all messengers it is active on and
1031
+	 * any related message templates will be inactivated as well.
1032
+	 *
1033
+	 * @return bool   true means all active message types are valid, false means at least one message type was
1034
+	 *                deactivated.
1035
+	 */
1036
+	public function validate_active_message_types_are_installed()
1037
+	{
1038
+		$list_of_active_message_type_names = $this->list_of_active_message_types();
1039
+		$installed_message_types           = $this->installed_message_types();
1040
+		$all_message_types_valid           = true;
1041
+		// loop through list of active message types and verify they are installed.
1042
+		foreach ($list_of_active_message_type_names as $message_type_name) {
1043
+			if (! isset($installed_message_types[ $message_type_name ])) {
1044
+				$this->remove_message_type_has_been_activated_from_all_messengers(
1045
+					$message_type_name,
1046
+					true
1047
+				);
1048
+				$this->deactivate_message_type($message_type_name, false);
1049
+				$all_message_types_valid = false;
1050
+			}
1051
+		}
1052
+		return $all_message_types_valid;
1053
+	}
1054
+
1055
+
1056
+	/**
1057
+	 * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been
1058
+	 * activated for the given messenger.  This can be called by client code on plugin updates etc to determine whether
1059
+	 * to attempt automatically reactivating message types that should be activated by default or not.
1060
+	 *
1061
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1062
+	 *
1063
+	 * @param $message_type_name
1064
+	 * @param $messenger_name
1065
+	 * @return bool
1066
+	 */
1067
+	public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1068
+	{
1069
+		$has_activated = $this->get_has_activated_messengers_option();
1070
+		return isset($has_activated[ $messenger_name ])
1071
+			   && in_array($message_type_name, $has_activated[ $messenger_name ]);
1072
+	}
1073
+
1074
+
1075
+	/**
1076
+	 * This method unsets a message type from the given messenger has activated option.
1077
+	 *
1078
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1079
+	 *
1080
+	 * @param string $message_type_name
1081
+	 * @param string $messenger_name
1082
+	 * @param bool   $consider_current_state  Whether to consider whether the  message type is currently active or not.
1083
+	 *                                        If it is currently active, then remove.  Otherwise leave it alone.
1084
+	 */
1085
+	public function remove_message_type_has_been_activated_for_messenger(
1086
+		$message_type_name,
1087
+		$messenger_name,
1088
+		$consider_current_state = false
1089
+	) {
1090
+		if (
1091
+			$consider_current_state
1092
+			&& ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
1093
+		) {
1094
+			// when consider current state is true, this means we don't want to change anything on the "has_activated"
1095
+			// record if the message type is currently active for this messenger.  This is used when we want to retain
1096
+			// the record for user initiated inactivations of the message type.
1097
+			return;
1098
+		}
1099
+		$has_activated = $this->get_has_activated_messengers_option();
1100
+		$key_for_message_type = isset($has_activated[ $messenger_name ])
1101
+			? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1102
+			: false;
1103
+		if ($key_for_message_type !== false) {
1104
+			unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1105
+			$this->update_has_activated_messengers_option($has_activated);
1106
+			// reset the internal cached property
1107
+			$this->get_has_activated_messengers_option(true);
1108
+		}
1109
+	}
1110
+
1111
+
1112
+	/**
1113
+	 * Removes a message type active record from all messengers it is attached to.
1114
+	 *
1115
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1116
+	 *
1117
+	 * @param      $message_type_name
1118
+	 * @param bool $consider_current_state  Whether to consider whether the  message type is currently active or not.
1119
+	 *                                      If it is currently active, then remove.  Otherwise leave it alone.
1120
+	 */
1121
+	public function remove_message_type_has_been_activated_from_all_messengers(
1122
+		$message_type_name,
1123
+		$consider_current_state = false
1124
+	) {
1125
+		foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) {
1126
+			$this->remove_message_type_has_been_activated_for_messenger(
1127
+				$message_type_name,
1128
+				$messenger_name,
1129
+				$consider_current_state
1130
+			);
1131
+		}
1132
+	}
1133 1133
 }
Please login to merge, or discard this patch.
Spacing   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
     public function get_active_messenger($messenger)
197 197
     {
198 198
         $this->_initialize_collections();
199
-        return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
199
+        return ! empty($this->_active_messengers[$messenger]) ? $this->_active_messengers[$messenger] : null;
200 200
     }
201 201
 
202 202
 
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
             $this->_installed_messengers = array();
210 210
             $this->messenger_collection()->rewind();
211 211
             while ($this->messenger_collection()->valid()) {
212
-                $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
212
+                $this->_installed_messengers[$this->messenger_collection()->current()->name] = $this->messenger_collection()->current();
213 213
                 $this->messenger_collection()->next();
214 214
             }
215 215
         }
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
     public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293 293
     {
294 294
         $this->_initialize_collections();
295
-        return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
295
+        return ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]);
296 296
     }
297 297
 
298 298
 
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
     public function is_messenger_active($messenger_name)
306 306
     {
307 307
         $this->_initialize_collections();
308
-        return ! empty($this->_active_message_types[ $messenger_name ]);
308
+        return ! empty($this->_active_message_types[$messenger_name]);
309 309
     }
310 310
 
311 311
 
@@ -320,8 +320,8 @@  discard block
 block discarded – undo
320 320
     {
321 321
         $settings = array();
322 322
         if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
-            $settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
-                ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
323
+            $settings = isset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'])
324
+                ? $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings']
325 325
                 : array();
326 326
         }
327 327
         return $settings;
@@ -339,8 +339,8 @@  discard block
 block discarded – undo
339 339
     {
340 340
         $this->_initialize_collections();
341 341
         return
342
-            ! empty($this->_active_message_types[ $messenger_name ])
343
-            && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
342
+            ! empty($this->_active_message_types[$messenger_name])
343
+            && ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types']);
344 344
     }
345 345
 
346 346
 
@@ -355,13 +355,13 @@  discard block
 block discarded – undo
355 355
     public function get_active_message_types_for_messenger($messenger_name)
356 356
     {
357 357
         $message_types = array();
358
-        if (! $this->messenger_has_active_message_types($messenger_name)) {
358
+        if ( ! $this->messenger_has_active_message_types($messenger_name)) {
359 359
             return $message_types;
360 360
         }
361 361
         $installed_message_types = $this->installed_message_types();
362 362
         foreach ($installed_message_types as $message_type_name => $message_type) {
363 363
             if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
-                $message_types[ $message_type_name ] = $message_type;
364
+                $message_types[$message_type_name] = $message_type;
365 365
             }
366 366
         }
367 367
         return $message_types;
@@ -380,11 +380,11 @@  discard block
 block discarded – undo
380 380
         $active_message_type_names = array();
381 381
         $this->_initialize_collections();
382 382
         foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
-            if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
383
+            if ( ! isset($messenger_settings['settings'][$messenger.'-message_types'])) {
384 384
                 continue;
385 385
             }
386
-            foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
-                if (! in_array($message_type_name, $active_message_type_names)) {
386
+            foreach ($messenger_settings['settings'][$messenger.'-message_types'] as $message_type_name => $message_type_config) {
387
+                if ( ! in_array($message_type_name, $active_message_type_names)) {
388 388
                     $active_message_type_names[] = $message_type_name;
389 389
                 }
390 390
             }
@@ -405,8 +405,8 @@  discard block
 block discarded – undo
405 405
         $installed_message_types   = $this->installed_message_types();
406 406
         $active_message_type_names = $this->list_of_active_message_types();
407 407
         foreach ($active_message_type_names as $active_message_type_name) {
408
-            if (isset($installed_message_types[ $active_message_type_name ])) {
409
-                $active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
408
+            if (isset($installed_message_types[$active_message_type_name])) {
409
+                $active_message_types[$active_message_type_name] = $installed_message_types[$active_message_type_name];
410 410
             }
411 411
         }
412 412
         return $active_message_types;
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
         if (empty($this->_installed_message_types)) {
422 422
             $this->message_type_collection()->rewind();
423 423
             while ($this->message_type_collection()->valid()) {
424
-                $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
424
+                $this->_installed_message_types[$this->message_type_collection()->current()->name] = $this->message_type_collection()->current();
425 425
                 $this->message_type_collection()->next();
426 426
             }
427 427
         }
@@ -460,7 +460,7 @@  discard block
 block discarded – undo
460 460
     public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461 461
     {
462 462
         $valid_message_types = $messenger->get_valid_message_types();
463
-        if (! in_array($message_type_name, $valid_message_types)) {
463
+        if ( ! in_array($message_type_name, $valid_message_types)) {
464 464
             throw new EE_Error(
465 465
                 sprintf(
466 466
                     __(
@@ -586,7 +586,7 @@  discard block
 block discarded – undo
586 586
      */
587 587
     public function ensure_messenger_is_active($messenger_name, $update_option = true)
588 588
     {
589
-        if (! isset($this->_active_messengers[ $messenger_name ])) {
589
+        if ( ! isset($this->_active_messengers[$messenger_name])) {
590 590
             try {
591 591
                 $this->activate_messenger($messenger_name, array(), $update_option);
592 592
             } catch (EE_Error $e) {
@@ -631,7 +631,7 @@  discard block
 block discarded – undo
631 631
             $this->ensure_messenger_is_active($messenger_name, $update_option);
632 632
         }
633 633
 
634
-        if (! empty($not_installed)) {
634
+        if ( ! empty($not_installed)) {
635 635
             EE_Error::add_error(
636 636
                 sprintf(
637 637
                     __('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
@@ -664,7 +664,7 @@  discard block
 block discarded – undo
664 664
             // ensure messenger is active (that's an inherent coupling between active message types and the
665 665
             // messenger they are being activated for.
666 666
             try {
667
-                if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
667
+                if ( ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668 668
                     // all is good so let's just get it active
669 669
                     $this->activate_messenger($messenger, array($message_type_name), $update_option);
670 670
                 }
@@ -728,7 +728,7 @@  discard block
 block discarded – undo
728 728
             : $this->messenger_collection()->get_by_info($messenger);
729 729
         // it's inactive. Activate it.
730 730
         if ($messenger instanceof EE_messenger) {
731
-            $this->_active_messengers[ $messenger->name ] = $messenger;
731
+            $this->_active_messengers[$messenger->name] = $messenger;
732 732
             // activate incoming message types set to be activated with messenger.
733 733
             $message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734 734
             // setup any initial settings for the messenger if necessary.
@@ -740,7 +740,7 @@  discard block
 block discarded – undo
740 740
             // generate new templates if necessary and ensure all related templates that are already in the database are
741 741
             // marked active.  Note, this will also deactivate a message type for a messenger if the template
742 742
             // cannot be successfully created during its attempt (only happens for global template attempts).
743
-            if (! empty($message_type_names)) {
743
+            if ( ! empty($message_type_names)) {
744 744
                 $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745 745
                 EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746 746
             }
@@ -764,13 +764,13 @@  discard block
 block discarded – undo
764 764
         // things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765 765
         // So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766 766
         // only override _active_message_types when an explicit array of $message_type_names has been provided.
767
-        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
767
+        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[$messenger->name])
768 768
             ? $messenger->get_default_message_types()
769 769
             : (array) $message_type_names;
770 770
 
771 771
         // now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
-        if (! isset($this->_active_message_types[ $messenger->name ])) {
773
-            $this->_active_message_types[ $messenger->name ]['settings'] = array();
772
+        if ( ! isset($this->_active_message_types[$messenger->name])) {
773
+            $this->_active_message_types[$messenger->name]['settings'] = array();
774 774
         }
775 775
 
776 776
         if ($message_type_names) {
@@ -811,16 +811,16 @@  discard block
 block discarded – undo
811 811
         if ($message_type instanceof EE_message_type) {
812 812
             $default_settings = $message_type->get_admin_settings_fields();
813 813
             foreach ($default_settings as $field => $values) {
814
-                if (isset($new_settings[ $field ])) {
815
-                    $existing_settings[ $field ] = $new_settings[ $field ];
814
+                if (isset($new_settings[$field])) {
815
+                    $existing_settings[$field] = $new_settings[$field];
816 816
                     continue;
817 817
                 }
818
-                if (! isset($existing_settings[ $field ])) {
819
-                    $existing_settings[ $field ] = $values['default'];
818
+                if ( ! isset($existing_settings[$field])) {
819
+                    $existing_settings[$field] = $values['default'];
820 820
                 }
821 821
             }
822 822
         }
823
-        $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
823
+        $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'] = $existing_settings;
824 824
     }
825 825
 
826 826
 
@@ -843,12 +843,12 @@  discard block
 block discarded – undo
843 843
         }
844 844
 
845 845
         // make sure this messenger has a record in the has_activated array
846
-        if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
847
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
846
+        if ( ! isset($this->_has_activated_messengers_and_message_types[$messenger->name])) {
847
+            $this->_has_activated_messengers_and_message_types[$messenger->name] = array();
848 848
         }
849 849
         // check if message type has already been added
850
-        if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
851
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
850
+        if ( ! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[$messenger->name])) {
851
+            $this->_has_activated_messengers_and_message_types[$messenger->name][] = $message_type_name;
852 852
         }
853 853
     }
854 854
 
@@ -866,16 +866,16 @@  discard block
 block discarded – undo
866 866
         $messenger = $this->get_messenger($messenger_name);
867 867
         if ($messenger instanceof EE_messenger) {
868 868
             $msgr_settings = $messenger->get_admin_settings_fields();
869
-            if (! empty($msgr_settings)) {
869
+            if ( ! empty($msgr_settings)) {
870 870
                 foreach ($msgr_settings as $field => $value) {
871 871
                     // is there a new setting for this?
872
-                    if (isset($new_settings[ $field ])) {
873
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
872
+                    if (isset($new_settings[$field])) {
873
+                        $this->_active_message_types[$messenger->name]['settings'][$field] = $new_settings[$field];
874 874
                         continue;
875 875
                     }
876 876
                     // only set the default if it isn't already set.
877
-                    if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
878
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
877
+                    if ( ! isset($this->_active_message_types[$messenger->name]['settings'][$field])) {
878
+                        $this->_active_message_types[$messenger->name]['settings'][$field] = $value;
879 879
                     }
880 880
                 }
881 881
             }
@@ -895,8 +895,8 @@  discard block
 block discarded – undo
895 895
         if ($messenger_name instanceof EE_messenger) {
896 896
             $messenger_name = $messenger_name->name;
897 897
         }
898
-        unset($this->_active_messengers[ $messenger_name ]);
899
-        unset($this->_active_message_types[ $messenger_name ]);
898
+        unset($this->_active_messengers[$messenger_name]);
899
+        unset($this->_active_message_types[$messenger_name]);
900 900
         $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
901 901
         $this->update_active_messengers_option();
902 902
     }
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
         }
919 919
         foreach ($this->_active_message_types as $messenger_name => $settings) {
920 920
             unset(
921
-                $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
921
+                $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]
922 922
             );
923 923
 
924 924
             // we always record (even on deactivation) that a message type has been activated because there should at
@@ -944,7 +944,7 @@  discard block
 block discarded – undo
944 944
     {
945 945
         $this->_initialize_collections();
946 946
         if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
947
-            unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
947
+            unset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]);
948 948
         }
949 949
         $this->_message_template_group_model->deactivate_message_template_groups_for(
950 950
             array($messenger_name),
@@ -1005,22 +1005,22 @@  discard block
 block discarded – undo
1005 1005
     {
1006 1006
         $key = $slugs_only ? 'slugs' : 'all';
1007 1007
         // check if contexts has been setup yet.
1008
-        if (empty($this->_contexts[ $key ])) {
1008
+        if (empty($this->_contexts[$key])) {
1009 1009
             // So let's get all active message type objects and loop through to get all unique contexts
1010 1010
             foreach ($this->get_active_message_type_objects() as $message_type) {
1011 1011
                 if ($message_type instanceof EE_message_type) {
1012 1012
                     $message_type_contexts = $message_type->get_contexts();
1013 1013
                     if ($slugs_only) {
1014 1014
                         foreach ($message_type_contexts as $context => $context_details) {
1015
-                            $this->_contexts[ $key ][ $context ] = $context_details['label'];
1015
+                            $this->_contexts[$key][$context] = $context_details['label'];
1016 1016
                         }
1017 1017
                     } else {
1018
-                        $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1018
+                        $this->_contexts[$key][$message_type->name] = $message_type_contexts;
1019 1019
                     }
1020 1020
                 }
1021 1021
             }
1022 1022
         }
1023
-        return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1023
+        return ! empty($this->_contexts[$key]) ? $this->_contexts[$key] : array();
1024 1024
     }
1025 1025
 
1026 1026
 
@@ -1040,7 +1040,7 @@  discard block
 block discarded – undo
1040 1040
         $all_message_types_valid           = true;
1041 1041
         // loop through list of active message types and verify they are installed.
1042 1042
         foreach ($list_of_active_message_type_names as $message_type_name) {
1043
-            if (! isset($installed_message_types[ $message_type_name ])) {
1043
+            if ( ! isset($installed_message_types[$message_type_name])) {
1044 1044
                 $this->remove_message_type_has_been_activated_from_all_messengers(
1045 1045
                     $message_type_name,
1046 1046
                     true
@@ -1067,8 +1067,8 @@  discard block
 block discarded – undo
1067 1067
     public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1068 1068
     {
1069 1069
         $has_activated = $this->get_has_activated_messengers_option();
1070
-        return isset($has_activated[ $messenger_name ])
1071
-               && in_array($message_type_name, $has_activated[ $messenger_name ]);
1070
+        return isset($has_activated[$messenger_name])
1071
+               && in_array($message_type_name, $has_activated[$messenger_name]);
1072 1072
     }
1073 1073
 
1074 1074
 
@@ -1097,11 +1097,11 @@  discard block
 block discarded – undo
1097 1097
             return;
1098 1098
         }
1099 1099
         $has_activated = $this->get_has_activated_messengers_option();
1100
-        $key_for_message_type = isset($has_activated[ $messenger_name ])
1101
-            ? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1100
+        $key_for_message_type = isset($has_activated[$messenger_name])
1101
+            ? array_search($message_type_name, $has_activated[$messenger_name], true)
1102 1102
             : false;
1103 1103
         if ($key_for_message_type !== false) {
1104
-            unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1104
+            unset($has_activated[$messenger_name][$key_for_message_type]);
1105 1105
             $this->update_has_activated_messengers_option($has_activated);
1106 1106
             // reset the internal cached property
1107 1107
             $this->get_has_activated_messengers_option(true);
Please login to merge, or discard this patch.
core/helpers/EEH_Activation.helper.php 1 patch
Indentation   +1617 added lines, -1617 removed lines patch added patch discarded remove patch
@@ -15,234 +15,234 @@  discard block
 block discarded – undo
15 15
 class EEH_Activation implements ResettableInterface
16 16
 {
17 17
 
18
-    /**
19
-     * constant used to indicate a cron task is no longer in use
20
-     */
21
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
22
-
23
-    /**
24
-     * WP_User->ID
25
-     *
26
-     * @var int
27
-     */
28
-    private static $_default_creator_id;
29
-
30
-    /**
31
-     * indicates whether or not we've already verified core's default data during this request,
32
-     * because after migrations are done, any addons activated while in maintenance mode
33
-     * will want to setup their own default data, and they might hook into core's default data
34
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
35
-     * This prevents doing that for EVERY single addon.
36
-     *
37
-     * @var boolean
38
-     */
39
-    protected static $_initialized_db_content_already_in_this_request = false;
40
-
41
-    /**
42
-     * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
43
-     */
44
-    private static $table_analysis;
45
-
46
-    /**
47
-     * @var \EventEspresso\core\services\database\TableManager $table_manager
48
-     */
49
-    private static $table_manager;
50
-
51
-
52
-    /**
53
-     * @return \EventEspresso\core\services\database\TableAnalysis
54
-     */
55
-    public static function getTableAnalysis()
56
-    {
57
-        if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
58
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
59
-        }
60
-        return self::$table_analysis;
61
-    }
62
-
63
-
64
-    /**
65
-     * @return \EventEspresso\core\services\database\TableManager
66
-     */
67
-    public static function getTableManager()
68
-    {
69
-        if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
70
-            self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
71
-        }
72
-        return self::$table_manager;
73
-    }
74
-
75
-
76
-    /**
77
-     *    _ensure_table_name_has_prefix
78
-     *
79
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
80
-     * @access     public
81
-     * @static
82
-     * @param $table_name
83
-     * @return string
84
-     */
85
-    public static function ensure_table_name_has_prefix($table_name)
86
-    {
87
-        return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
88
-    }
89
-
90
-
91
-    /**
92
-     *    system_initialization
93
-     *    ensures the EE configuration settings are loaded with at least default options set
94
-     *    and that all critical EE pages have been generated with the appropriate shortcodes in place
95
-     *
96
-     * @access public
97
-     * @static
98
-     * @return void
99
-     */
100
-    public static function system_initialization()
101
-    {
102
-        EEH_Activation::reset_and_update_config();
103
-        // which is fired BEFORE activation of plugin anyways
104
-        EEH_Activation::verify_default_pages_exist();
105
-    }
106
-
107
-
108
-    /**
109
-     * Sets the database schema and creates folders. This should
110
-     * be called on plugin activation and reactivation
111
-     *
112
-     * @return boolean success, whether the database and folders are setup properly
113
-     * @throws \EE_Error
114
-     */
115
-    public static function initialize_db_and_folders()
116
-    {
117
-        return EEH_Activation::create_database_tables();
118
-    }
119
-
120
-
121
-    /**
122
-     * assuming we have an up-to-date database schema, this will populate it
123
-     * with default and initial data. This should be called
124
-     * upon activation of a new plugin, reactivation, and at the end
125
-     * of running migration scripts
126
-     *
127
-     * @throws \EE_Error
128
-     */
129
-    public static function initialize_db_content()
130
-    {
131
-        // let's avoid doing all this logic repeatedly, especially when addons are requesting it
132
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
133
-            return;
134
-        }
135
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
136
-
137
-        EEH_Activation::initialize_system_questions();
138
-        EEH_Activation::insert_default_status_codes();
139
-        EEH_Activation::generate_default_message_templates();
140
-        EEH_Activation::create_no_ticket_prices_array();
141
-        EEH_Activation::removeEmailConfirmFromAddressGroup();
142
-
143
-        EEH_Activation::validate_messages_system();
144
-        EEH_Activation::insert_default_payment_methods();
145
-        // in case we've
146
-        EEH_Activation::remove_cron_tasks();
147
-        EEH_Activation::create_cron_tasks();
148
-        // remove all TXN locks since that is being done via extra meta now
149
-        delete_option('ee_locked_transactions');
150
-        // also, check for CAF default db content
151
-        do_action('AHEE__EEH_Activation__initialize_db_content');
152
-        // also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
153
-        // which users really won't care about on initial activation
154
-        EE_Error::overwrite_success();
155
-    }
156
-
157
-
158
-    /**
159
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
160
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
161
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
162
-     * (null)
163
-     *
164
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
165
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
166
-     * @return array
167
-     * @throws \EE_Error
168
-     */
169
-    public static function get_cron_tasks($which_to_include)
170
-    {
171
-        $cron_tasks = apply_filters(
172
-            'FHEE__EEH_Activation__get_cron_tasks',
173
-            array(
174
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
175
-            //              'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
176
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
177
-                // there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
178
-                'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
179
-            )
180
-        );
181
-        if ($which_to_include === 'old') {
182
-            $cron_tasks = array_filter(
183
-                $cron_tasks,
184
-                function ($value) {
185
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
186
-                }
187
-            );
188
-        } elseif ($which_to_include === 'current') {
189
-            $cron_tasks = array_filter($cron_tasks);
190
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
191
-            throw new EE_Error(
192
-                sprintf(
193
-                    __(
194
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
195
-                        'event_espresso'
196
-                    ),
197
-                    $which_to_include
198
-                )
199
-            );
200
-        }
201
-        return $cron_tasks;
202
-    }
203
-
204
-
205
-    /**
206
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
207
-     *
208
-     * @throws \EE_Error
209
-     */
210
-    public static function create_cron_tasks()
211
-    {
212
-
213
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
214
-            if (! wp_next_scheduled($hook_name)) {
215
-                /**
216
-                 * This allows client code to define the initial start timestamp for this schedule.
217
-                 */
218
-                if (
219
-                    is_array($frequency)
220
-                    && count($frequency) === 2
221
-                    && isset($frequency[0], $frequency[1])
222
-                ) {
223
-                    $start_timestamp = $frequency[0];
224
-                    $frequency = $frequency[1];
225
-                } else {
226
-                    $start_timestamp = time();
227
-                }
228
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
229
-            }
230
-        }
231
-    }
232
-
233
-
234
-    /**
235
-     * Remove the currently-existing and now-removed cron tasks.
236
-     *
237
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
238
-     * @throws \EE_Error
239
-     */
240
-    public static function remove_cron_tasks($remove_all = true)
241
-    {
242
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
243
-        $crons                = _get_cron_array();
244
-        $crons                = is_array($crons) ? $crons : array();
245
-        /* reminder of what $crons look like:
18
+	/**
19
+	 * constant used to indicate a cron task is no longer in use
20
+	 */
21
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
22
+
23
+	/**
24
+	 * WP_User->ID
25
+	 *
26
+	 * @var int
27
+	 */
28
+	private static $_default_creator_id;
29
+
30
+	/**
31
+	 * indicates whether or not we've already verified core's default data during this request,
32
+	 * because after migrations are done, any addons activated while in maintenance mode
33
+	 * will want to setup their own default data, and they might hook into core's default data
34
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
35
+	 * This prevents doing that for EVERY single addon.
36
+	 *
37
+	 * @var boolean
38
+	 */
39
+	protected static $_initialized_db_content_already_in_this_request = false;
40
+
41
+	/**
42
+	 * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
43
+	 */
44
+	private static $table_analysis;
45
+
46
+	/**
47
+	 * @var \EventEspresso\core\services\database\TableManager $table_manager
48
+	 */
49
+	private static $table_manager;
50
+
51
+
52
+	/**
53
+	 * @return \EventEspresso\core\services\database\TableAnalysis
54
+	 */
55
+	public static function getTableAnalysis()
56
+	{
57
+		if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
58
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
59
+		}
60
+		return self::$table_analysis;
61
+	}
62
+
63
+
64
+	/**
65
+	 * @return \EventEspresso\core\services\database\TableManager
66
+	 */
67
+	public static function getTableManager()
68
+	{
69
+		if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
70
+			self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
71
+		}
72
+		return self::$table_manager;
73
+	}
74
+
75
+
76
+	/**
77
+	 *    _ensure_table_name_has_prefix
78
+	 *
79
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
80
+	 * @access     public
81
+	 * @static
82
+	 * @param $table_name
83
+	 * @return string
84
+	 */
85
+	public static function ensure_table_name_has_prefix($table_name)
86
+	{
87
+		return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
88
+	}
89
+
90
+
91
+	/**
92
+	 *    system_initialization
93
+	 *    ensures the EE configuration settings are loaded with at least default options set
94
+	 *    and that all critical EE pages have been generated with the appropriate shortcodes in place
95
+	 *
96
+	 * @access public
97
+	 * @static
98
+	 * @return void
99
+	 */
100
+	public static function system_initialization()
101
+	{
102
+		EEH_Activation::reset_and_update_config();
103
+		// which is fired BEFORE activation of plugin anyways
104
+		EEH_Activation::verify_default_pages_exist();
105
+	}
106
+
107
+
108
+	/**
109
+	 * Sets the database schema and creates folders. This should
110
+	 * be called on plugin activation and reactivation
111
+	 *
112
+	 * @return boolean success, whether the database and folders are setup properly
113
+	 * @throws \EE_Error
114
+	 */
115
+	public static function initialize_db_and_folders()
116
+	{
117
+		return EEH_Activation::create_database_tables();
118
+	}
119
+
120
+
121
+	/**
122
+	 * assuming we have an up-to-date database schema, this will populate it
123
+	 * with default and initial data. This should be called
124
+	 * upon activation of a new plugin, reactivation, and at the end
125
+	 * of running migration scripts
126
+	 *
127
+	 * @throws \EE_Error
128
+	 */
129
+	public static function initialize_db_content()
130
+	{
131
+		// let's avoid doing all this logic repeatedly, especially when addons are requesting it
132
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
133
+			return;
134
+		}
135
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
136
+
137
+		EEH_Activation::initialize_system_questions();
138
+		EEH_Activation::insert_default_status_codes();
139
+		EEH_Activation::generate_default_message_templates();
140
+		EEH_Activation::create_no_ticket_prices_array();
141
+		EEH_Activation::removeEmailConfirmFromAddressGroup();
142
+
143
+		EEH_Activation::validate_messages_system();
144
+		EEH_Activation::insert_default_payment_methods();
145
+		// in case we've
146
+		EEH_Activation::remove_cron_tasks();
147
+		EEH_Activation::create_cron_tasks();
148
+		// remove all TXN locks since that is being done via extra meta now
149
+		delete_option('ee_locked_transactions');
150
+		// also, check for CAF default db content
151
+		do_action('AHEE__EEH_Activation__initialize_db_content');
152
+		// also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
153
+		// which users really won't care about on initial activation
154
+		EE_Error::overwrite_success();
155
+	}
156
+
157
+
158
+	/**
159
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
160
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
161
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
162
+	 * (null)
163
+	 *
164
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
165
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
166
+	 * @return array
167
+	 * @throws \EE_Error
168
+	 */
169
+	public static function get_cron_tasks($which_to_include)
170
+	{
171
+		$cron_tasks = apply_filters(
172
+			'FHEE__EEH_Activation__get_cron_tasks',
173
+			array(
174
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
175
+			//              'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
176
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
177
+				// there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
178
+				'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
179
+			)
180
+		);
181
+		if ($which_to_include === 'old') {
182
+			$cron_tasks = array_filter(
183
+				$cron_tasks,
184
+				function ($value) {
185
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
186
+				}
187
+			);
188
+		} elseif ($which_to_include === 'current') {
189
+			$cron_tasks = array_filter($cron_tasks);
190
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
191
+			throw new EE_Error(
192
+				sprintf(
193
+					__(
194
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
195
+						'event_espresso'
196
+					),
197
+					$which_to_include
198
+				)
199
+			);
200
+		}
201
+		return $cron_tasks;
202
+	}
203
+
204
+
205
+	/**
206
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
207
+	 *
208
+	 * @throws \EE_Error
209
+	 */
210
+	public static function create_cron_tasks()
211
+	{
212
+
213
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
214
+			if (! wp_next_scheduled($hook_name)) {
215
+				/**
216
+				 * This allows client code to define the initial start timestamp for this schedule.
217
+				 */
218
+				if (
219
+					is_array($frequency)
220
+					&& count($frequency) === 2
221
+					&& isset($frequency[0], $frequency[1])
222
+				) {
223
+					$start_timestamp = $frequency[0];
224
+					$frequency = $frequency[1];
225
+				} else {
226
+					$start_timestamp = time();
227
+				}
228
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
229
+			}
230
+		}
231
+	}
232
+
233
+
234
+	/**
235
+	 * Remove the currently-existing and now-removed cron tasks.
236
+	 *
237
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
238
+	 * @throws \EE_Error
239
+	 */
240
+	public static function remove_cron_tasks($remove_all = true)
241
+	{
242
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
243
+		$crons                = _get_cron_array();
244
+		$crons                = is_array($crons) ? $crons : array();
245
+		/* reminder of what $crons look like:
246 246
          * Top-level keys are timestamps, and their values are arrays.
247 247
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
248 248
          * and their values are arrays.
@@ -259,928 +259,928 @@  discard block
 block discarded – undo
259 259
          *                  ...
260 260
          *      ...
261 261
          */
262
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
263
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
264
-            if (is_array($hooks_to_fire_at_time)) {
265
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
266
-                    if (
267
-                        isset($ee_cron_tasks_to_remove[ $hook_name ])
268
-                        && is_array($ee_cron_tasks_to_remove[ $hook_name ])
269
-                    ) {
270
-                        unset($crons[ $timestamp ][ $hook_name ]);
271
-                    }
272
-                }
273
-                // also take care of any empty cron timestamps.
274
-                if (empty($hooks_to_fire_at_time)) {
275
-                    unset($crons[ $timestamp ]);
276
-                }
277
-            }
278
-        }
279
-        _set_cron_array($crons);
280
-    }
281
-
282
-
283
-    /**
284
-     *    CPT_initialization
285
-     *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
286
-     *
287
-     * @access public
288
-     * @static
289
-     * @return void
290
-     */
291
-    public static function CPT_initialization()
292
-    {
293
-        // register Custom Post Types
294
-        EE_Registry::instance()->load_core('Register_CPTs');
295
-        flush_rewrite_rules();
296
-    }
297
-
298
-
299
-
300
-    /**
301
-     *    reset_and_update_config
302
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
303
-     * If there is old calendar config data saved, then it will get converted on activation.
304
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
305
-     *
306
-     * @access public
307
-     * @static
308
-     * @return void
309
-     */
310
-    public static function reset_and_update_config()
311
-    {
312
-        do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
313
-        add_filter(
314
-            'FHEE__EE_Config___load_core_config__config_settings',
315
-            array('EEH_Activation', 'migrate_old_config_data'),
316
-            10,
317
-            3
318
-        );
319
-        // EE_Config::reset();
320
-        if (! EE_Config::logging_enabled()) {
321
-            delete_option(EE_Config::LOG_NAME);
322
-        }
323
-    }
324
-
325
-
326
-    /**
327
-     *    load_calendar_config
328
-     *
329
-     * @access    public
330
-     * @return    void
331
-     */
332
-    public static function load_calendar_config()
333
-    {
334
-        // grab array of all plugin folders and loop thru it
335
-        $plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
336
-        if (empty($plugins)) {
337
-            return;
338
-        }
339
-        foreach ($plugins as $plugin_path) {
340
-            // grab plugin folder name from path
341
-            $plugin = basename($plugin_path);
342
-            // drill down to Espresso plugins
343
-            // then to calendar related plugins
344
-            if (
345
-                strpos($plugin, 'espresso') !== false
346
-                || strpos($plugin, 'Espresso') !== false
347
-                || strpos($plugin, 'ee4') !== false
348
-                || strpos($plugin, 'EE4') !== false
349
-                || strpos($plugin, 'calendar') !== false
350
-            ) {
351
-                // this is what we are looking for
352
-                $calendar_config = $plugin_path . '/EE_Calendar_Config.php';
353
-                // does it exist in this folder ?
354
-                if (is_readable($calendar_config)) {
355
-                    // YEAH! let's load it
356
-                    require_once($calendar_config);
357
-                }
358
-            }
359
-        }
360
-    }
361
-
362
-
363
-
364
-    /**
365
-     *    _migrate_old_config_data
366
-     *
367
-     * @access    public
368
-     * @param array|stdClass $settings
369
-     * @param string         $config
370
-     * @param \EE_Config     $EE_Config
371
-     * @return \stdClass
372
-     */
373
-    public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
374
-    {
375
-        $convert_from_array = array('addons');
376
-        // in case old settings were saved as an array
377
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
378
-            // convert existing settings to an object
379
-            $config_array = $settings;
380
-            $settings = new stdClass();
381
-            foreach ($config_array as $key => $value) {
382
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
383
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
384
-                } else {
385
-                    $settings->{$key} = $value;
386
-                }
387
-            }
388
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
389
-        }
390
-        return $settings;
391
-    }
392
-
393
-
394
-    /**
395
-     * deactivate_event_espresso
396
-     *
397
-     * @access public
398
-     * @static
399
-     * @return void
400
-     */
401
-    public static function deactivate_event_espresso()
402
-    {
403
-        // check permissions
404
-        if (current_user_can('activate_plugins')) {
405
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
406
-        }
407
-    }
408
-
409
-
410
-
411
-    /**
412
-     * verify_default_pages_exist
413
-     *
414
-     * @access public
415
-     * @static
416
-     * @return void
417
-     * @throws InvalidDataTypeException
418
-     */
419
-    public static function verify_default_pages_exist()
420
-    {
421
-        $critical_page_problem = false;
422
-        $critical_pages = array(
423
-            array(
424
-                'id'   => 'reg_page_id',
425
-                'name' => __('Registration Checkout', 'event_espresso'),
426
-                'post' => null,
427
-                'code' => 'ESPRESSO_CHECKOUT',
428
-            ),
429
-            array(
430
-                'id'   => 'txn_page_id',
431
-                'name' => __('Transactions', 'event_espresso'),
432
-                'post' => null,
433
-                'code' => 'ESPRESSO_TXN_PAGE',
434
-            ),
435
-            array(
436
-                'id'   => 'thank_you_page_id',
437
-                'name' => __('Thank You', 'event_espresso'),
438
-                'post' => null,
439
-                'code' => 'ESPRESSO_THANK_YOU',
440
-            ),
441
-            array(
442
-                'id'   => 'cancel_page_id',
443
-                'name' => __('Registration Cancelled', 'event_espresso'),
444
-                'post' => null,
445
-                'code' => 'ESPRESSO_CANCELLED',
446
-            ),
447
-        );
448
-        $EE_Core_Config = EE_Registry::instance()->CFG->core;
449
-        foreach ($critical_pages as $critical_page) {
450
-            // is critical page ID set in config ?
451
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
452
-                // attempt to find post by ID
453
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
454
-            }
455
-            // no dice?
456
-            if ($critical_page['post'] === null) {
457
-                // attempt to find post by title
458
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
459
-                // still nothing?
460
-                if ($critical_page['post'] === null) {
461
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
462
-                    // REALLY? Still nothing ??!?!?
463
-                    if ($critical_page['post'] === null) {
464
-                        $msg = __(
465
-                            'The Event Espresso critical page configuration settings could not be updated.',
466
-                            'event_espresso'
467
-                        );
468
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
469
-                        break;
470
-                    }
471
-                }
472
-            }
473
-            // check that Post ID matches critical page ID in config
474
-            if (
475
-                isset($critical_page['post']->ID)
476
-                && $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
477
-            ) {
478
-                // update Config with post ID
479
-                $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
480
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
481
-                    $msg = __(
482
-                        'The Event Espresso critical page configuration settings could not be updated.',
483
-                        'event_espresso'
484
-                    );
485
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
486
-                }
487
-            }
488
-            $critical_page_problem =
489
-                ! isset($critical_page['post']->post_status)
490
-                || $critical_page['post']->post_status !== 'publish'
491
-                || strpos($critical_page['post']->post_content, $critical_page['code']) === false
492
-                    ? true
493
-                    : $critical_page_problem;
494
-        }
495
-        if ($critical_page_problem) {
496
-            new PersistentAdminNotice(
497
-                'critical_page_problem',
498
-                sprintf(
499
-                    esc_html__(
500
-                        'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
501
-                        'event_espresso'
502
-                    ),
503
-                    '<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
504
-                    . __('Event Espresso Critical Pages Settings', 'event_espresso')
505
-                    . '</a>'
506
-                )
507
-            );
508
-        }
509
-        if (EE_Error::has_notices()) {
510
-            EE_Error::get_notices(false, true, true);
511
-        }
512
-    }
513
-
514
-
515
-
516
-    /**
517
-     * Returns the first post which uses the specified shortcode
518
-     *
519
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
520
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
521
-     *                             "[ESPRESSO_THANK_YOU"
522
-     *                             (we don't search for the closing shortcode bracket because they might have added
523
-     *                             parameter to the shortcode
524
-     * @return WP_Post or NULl
525
-     */
526
-    public static function get_page_by_ee_shortcode($ee_shortcode)
527
-    {
528
-        global $wpdb;
529
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
530
-        $post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
531
-        if ($post_id) {
532
-            return get_post($post_id);
533
-        } else {
534
-            return null;
535
-        }
536
-    }
537
-
538
-
539
-    /**
540
-     *    This function generates a post for critical espresso pages
541
-     *
542
-     * @access public
543
-     * @static
544
-     * @param array $critical_page
545
-     * @return array
546
-     */
547
-    public static function create_critical_page($critical_page)
548
-    {
549
-
550
-        $post_args = array(
551
-            'post_title'     => $critical_page['name'],
552
-            'post_status'    => 'publish',
553
-            'post_type'      => 'page',
554
-            'comment_status' => 'closed',
555
-            'post_content'   => '[' . $critical_page['code'] . ']',
556
-        );
557
-
558
-        $post_id = wp_insert_post($post_args);
559
-        if (! $post_id) {
560
-            $msg = sprintf(
561
-                __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
562
-                $critical_page['name']
563
-            );
564
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
565
-            return $critical_page;
566
-        }
567
-        // get newly created post's details
568
-        if (! $critical_page['post'] = get_post($post_id)) {
569
-            $msg = sprintf(
570
-                __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
571
-                $critical_page['name']
572
-            );
573
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
574
-        }
575
-
576
-        return $critical_page;
577
-    }
578
-
579
-
580
-
581
-
582
-    /**
583
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
584
-     * The role being used to check is filterable.
585
-     *
586
-     * @since  4.6.0
587
-     * @global WPDB $wpdb
588
-     * @return mixed null|int WP_user ID or NULL
589
-     */
590
-    public static function get_default_creator_id()
591
-    {
592
-        global $wpdb;
593
-        if (! empty(self::$_default_creator_id)) {
594
-            return self::$_default_creator_id;
595
-        }/**/
596
-        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
597
-        // let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
598
-        $pre_filtered_id = apply_filters(
599
-            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
600
-            false,
601
-            $role_to_check
602
-        );
603
-        if ($pre_filtered_id !== false) {
604
-            return (int) $pre_filtered_id;
605
-        }
606
-        $capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
607
-        $query = $wpdb->prepare(
608
-            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
609
-            '%' . $role_to_check . '%'
610
-        );
611
-        $user_id = $wpdb->get_var($query);
612
-        $user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
613
-        if ($user_id && (int) $user_id) {
614
-            self::$_default_creator_id = (int) $user_id;
615
-            return self::$_default_creator_id;
616
-        } else {
617
-            return null;
618
-        }
619
-    }
620
-
621
-
622
-
623
-    /**
624
-     * used by EE and EE addons during plugin activation to create tables.
625
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
626
-     * but includes extra logic regarding activations.
627
-     *
628
-     * @access public
629
-     * @static
630
-     * @param string  $table_name              without the $wpdb->prefix
631
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
632
-     *                                         table query)
633
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
634
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
635
-     *                                         and new once this function is done (ie, you really do want to CREATE a
636
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
637
-     *                                         you just want to verify the table exists and matches this definition
638
-     *                                         (and if it HAS data in it you want to leave it be)
639
-     * @return void
640
-     * @throws EE_Error if there are database errors
641
-     */
642
-    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
643
-    {
644
-        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
645
-            return;
646
-        }
647
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
648
-        if (! function_exists('dbDelta')) {
649
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
650
-        }
651
-        $tableAnalysis = \EEH_Activation::getTableAnalysis();
652
-        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
653
-        // do we need to first delete an existing version of this table ?
654
-        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
655
-            // ok, delete the table... but ONLY if it's empty
656
-            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
657
-            // table is NOT empty, are you SURE you want to delete this table ???
658
-            if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
659
-                \EEH_Activation::getTableManager()->dropTable($wp_table_name);
660
-            } elseif (! $deleted_safely) {
661
-                // so we should be more cautious rather than just dropping tables so easily
662
-                error_log(
663
-                    sprintf(
664
-                        __(
665
-                            'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
666
-                            'event_espresso'
667
-                        ),
668
-                        $wp_table_name,
669
-                        '<br/>',
670
-                        'espresso_db_update'
671
-                    )
672
-                );
673
-            }
674
-        }
675
-        $engine = str_replace('ENGINE=', '', $engine);
676
-        \EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
677
-    }
678
-
679
-
680
-
681
-    /**
682
-     *    add_column_if_it_doesn't_exist
683
-     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
684
-     *
685
-     * @access     public
686
-     * @static
687
-     * @deprecated instead use TableManager::addColumn()
688
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
689
-     * @param string $column_name
690
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
691
-     *                            'VARCHAR(10)'
692
-     * @return bool|int
693
-     */
694
-    public static function add_column_if_it_doesnt_exist(
695
-        $table_name,
696
-        $column_name,
697
-        $column_info = 'INT UNSIGNED NOT NULL'
698
-    ) {
699
-        return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
700
-    }
701
-
702
-
703
-    /**
704
-     * get_fields_on_table
705
-     * Gets all the fields on the database table.
706
-     *
707
-     * @access     public
708
-     * @deprecated instead use TableManager::getTableColumns()
709
-     * @static
710
-     * @param string $table_name , without prefixed $wpdb->prefix
711
-     * @return array of database column names
712
-     */
713
-    public static function get_fields_on_table($table_name = null)
714
-    {
715
-        return \EEH_Activation::getTableManager()->getTableColumns($table_name);
716
-    }
717
-
718
-
719
-    /**
720
-     * db_table_is_empty
721
-     *
722
-     * @access     public\
723
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
724
-     * @static
725
-     * @param string $table_name
726
-     * @return bool
727
-     */
728
-    public static function db_table_is_empty($table_name)
729
-    {
730
-        return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
731
-    }
732
-
733
-
734
-    /**
735
-     * delete_db_table_if_empty
736
-     *
737
-     * @access public
738
-     * @static
739
-     * @param string $table_name
740
-     * @return bool | int
741
-     */
742
-    public static function delete_db_table_if_empty($table_name)
743
-    {
744
-        if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
745
-            return \EEH_Activation::getTableManager()->dropTable($table_name);
746
-        }
747
-        return false;
748
-    }
749
-
750
-
751
-    /**
752
-     * delete_unused_db_table
753
-     *
754
-     * @access     public
755
-     * @static
756
-     * @deprecated instead use TableManager::dropTable()
757
-     * @param string $table_name
758
-     * @return bool | int
759
-     */
760
-    public static function delete_unused_db_table($table_name)
761
-    {
762
-        return \EEH_Activation::getTableManager()->dropTable($table_name);
763
-    }
764
-
765
-
766
-    /**
767
-     * drop_index
768
-     *
769
-     * @access     public
770
-     * @static
771
-     * @deprecated instead use TableManager::dropIndex()
772
-     * @param string $table_name
773
-     * @param string $index_name
774
-     * @return bool | int
775
-     */
776
-    public static function drop_index($table_name, $index_name)
777
-    {
778
-        return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
779
-    }
780
-
781
-
782
-
783
-    /**
784
-     * create_database_tables
785
-     *
786
-     * @access public
787
-     * @static
788
-     * @throws EE_Error
789
-     * @return boolean success (whether database is setup properly or not)
790
-     */
791
-    public static function create_database_tables()
792
-    {
793
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
794
-        // find the migration script that sets the database to be compatible with the code
795
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
796
-        if ($dms_name) {
797
-            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
798
-            $current_data_migration_script->set_migrating(false);
799
-            $current_data_migration_script->schema_changes_before_migration();
800
-            $current_data_migration_script->schema_changes_after_migration();
801
-            if ($current_data_migration_script->get_errors()) {
802
-                if (WP_DEBUG) {
803
-                    foreach ($current_data_migration_script->get_errors() as $error) {
804
-                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
805
-                    }
806
-                } else {
807
-                    EE_Error::add_error(
808
-                        __(
809
-                            'There were errors creating the Event Espresso database tables and Event Espresso has been 
262
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
263
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
264
+			if (is_array($hooks_to_fire_at_time)) {
265
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
266
+					if (
267
+						isset($ee_cron_tasks_to_remove[ $hook_name ])
268
+						&& is_array($ee_cron_tasks_to_remove[ $hook_name ])
269
+					) {
270
+						unset($crons[ $timestamp ][ $hook_name ]);
271
+					}
272
+				}
273
+				// also take care of any empty cron timestamps.
274
+				if (empty($hooks_to_fire_at_time)) {
275
+					unset($crons[ $timestamp ]);
276
+				}
277
+			}
278
+		}
279
+		_set_cron_array($crons);
280
+	}
281
+
282
+
283
+	/**
284
+	 *    CPT_initialization
285
+	 *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
286
+	 *
287
+	 * @access public
288
+	 * @static
289
+	 * @return void
290
+	 */
291
+	public static function CPT_initialization()
292
+	{
293
+		// register Custom Post Types
294
+		EE_Registry::instance()->load_core('Register_CPTs');
295
+		flush_rewrite_rules();
296
+	}
297
+
298
+
299
+
300
+	/**
301
+	 *    reset_and_update_config
302
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
303
+	 * If there is old calendar config data saved, then it will get converted on activation.
304
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
305
+	 *
306
+	 * @access public
307
+	 * @static
308
+	 * @return void
309
+	 */
310
+	public static function reset_and_update_config()
311
+	{
312
+		do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
313
+		add_filter(
314
+			'FHEE__EE_Config___load_core_config__config_settings',
315
+			array('EEH_Activation', 'migrate_old_config_data'),
316
+			10,
317
+			3
318
+		);
319
+		// EE_Config::reset();
320
+		if (! EE_Config::logging_enabled()) {
321
+			delete_option(EE_Config::LOG_NAME);
322
+		}
323
+	}
324
+
325
+
326
+	/**
327
+	 *    load_calendar_config
328
+	 *
329
+	 * @access    public
330
+	 * @return    void
331
+	 */
332
+	public static function load_calendar_config()
333
+	{
334
+		// grab array of all plugin folders and loop thru it
335
+		$plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
336
+		if (empty($plugins)) {
337
+			return;
338
+		}
339
+		foreach ($plugins as $plugin_path) {
340
+			// grab plugin folder name from path
341
+			$plugin = basename($plugin_path);
342
+			// drill down to Espresso plugins
343
+			// then to calendar related plugins
344
+			if (
345
+				strpos($plugin, 'espresso') !== false
346
+				|| strpos($plugin, 'Espresso') !== false
347
+				|| strpos($plugin, 'ee4') !== false
348
+				|| strpos($plugin, 'EE4') !== false
349
+				|| strpos($plugin, 'calendar') !== false
350
+			) {
351
+				// this is what we are looking for
352
+				$calendar_config = $plugin_path . '/EE_Calendar_Config.php';
353
+				// does it exist in this folder ?
354
+				if (is_readable($calendar_config)) {
355
+					// YEAH! let's load it
356
+					require_once($calendar_config);
357
+				}
358
+			}
359
+		}
360
+	}
361
+
362
+
363
+
364
+	/**
365
+	 *    _migrate_old_config_data
366
+	 *
367
+	 * @access    public
368
+	 * @param array|stdClass $settings
369
+	 * @param string         $config
370
+	 * @param \EE_Config     $EE_Config
371
+	 * @return \stdClass
372
+	 */
373
+	public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
374
+	{
375
+		$convert_from_array = array('addons');
376
+		// in case old settings were saved as an array
377
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
378
+			// convert existing settings to an object
379
+			$config_array = $settings;
380
+			$settings = new stdClass();
381
+			foreach ($config_array as $key => $value) {
382
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
383
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
384
+				} else {
385
+					$settings->{$key} = $value;
386
+				}
387
+			}
388
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
389
+		}
390
+		return $settings;
391
+	}
392
+
393
+
394
+	/**
395
+	 * deactivate_event_espresso
396
+	 *
397
+	 * @access public
398
+	 * @static
399
+	 * @return void
400
+	 */
401
+	public static function deactivate_event_espresso()
402
+	{
403
+		// check permissions
404
+		if (current_user_can('activate_plugins')) {
405
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
406
+		}
407
+	}
408
+
409
+
410
+
411
+	/**
412
+	 * verify_default_pages_exist
413
+	 *
414
+	 * @access public
415
+	 * @static
416
+	 * @return void
417
+	 * @throws InvalidDataTypeException
418
+	 */
419
+	public static function verify_default_pages_exist()
420
+	{
421
+		$critical_page_problem = false;
422
+		$critical_pages = array(
423
+			array(
424
+				'id'   => 'reg_page_id',
425
+				'name' => __('Registration Checkout', 'event_espresso'),
426
+				'post' => null,
427
+				'code' => 'ESPRESSO_CHECKOUT',
428
+			),
429
+			array(
430
+				'id'   => 'txn_page_id',
431
+				'name' => __('Transactions', 'event_espresso'),
432
+				'post' => null,
433
+				'code' => 'ESPRESSO_TXN_PAGE',
434
+			),
435
+			array(
436
+				'id'   => 'thank_you_page_id',
437
+				'name' => __('Thank You', 'event_espresso'),
438
+				'post' => null,
439
+				'code' => 'ESPRESSO_THANK_YOU',
440
+			),
441
+			array(
442
+				'id'   => 'cancel_page_id',
443
+				'name' => __('Registration Cancelled', 'event_espresso'),
444
+				'post' => null,
445
+				'code' => 'ESPRESSO_CANCELLED',
446
+			),
447
+		);
448
+		$EE_Core_Config = EE_Registry::instance()->CFG->core;
449
+		foreach ($critical_pages as $critical_page) {
450
+			// is critical page ID set in config ?
451
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
452
+				// attempt to find post by ID
453
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
454
+			}
455
+			// no dice?
456
+			if ($critical_page['post'] === null) {
457
+				// attempt to find post by title
458
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
459
+				// still nothing?
460
+				if ($critical_page['post'] === null) {
461
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
462
+					// REALLY? Still nothing ??!?!?
463
+					if ($critical_page['post'] === null) {
464
+						$msg = __(
465
+							'The Event Espresso critical page configuration settings could not be updated.',
466
+							'event_espresso'
467
+						);
468
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
469
+						break;
470
+					}
471
+				}
472
+			}
473
+			// check that Post ID matches critical page ID in config
474
+			if (
475
+				isset($critical_page['post']->ID)
476
+				&& $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
477
+			) {
478
+				// update Config with post ID
479
+				$EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
480
+				if (! EE_Config::instance()->update_espresso_config(false, false)) {
481
+					$msg = __(
482
+						'The Event Espresso critical page configuration settings could not be updated.',
483
+						'event_espresso'
484
+					);
485
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
486
+				}
487
+			}
488
+			$critical_page_problem =
489
+				! isset($critical_page['post']->post_status)
490
+				|| $critical_page['post']->post_status !== 'publish'
491
+				|| strpos($critical_page['post']->post_content, $critical_page['code']) === false
492
+					? true
493
+					: $critical_page_problem;
494
+		}
495
+		if ($critical_page_problem) {
496
+			new PersistentAdminNotice(
497
+				'critical_page_problem',
498
+				sprintf(
499
+					esc_html__(
500
+						'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
501
+						'event_espresso'
502
+					),
503
+					'<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
504
+					. __('Event Espresso Critical Pages Settings', 'event_espresso')
505
+					. '</a>'
506
+				)
507
+			);
508
+		}
509
+		if (EE_Error::has_notices()) {
510
+			EE_Error::get_notices(false, true, true);
511
+		}
512
+	}
513
+
514
+
515
+
516
+	/**
517
+	 * Returns the first post which uses the specified shortcode
518
+	 *
519
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
520
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
521
+	 *                             "[ESPRESSO_THANK_YOU"
522
+	 *                             (we don't search for the closing shortcode bracket because they might have added
523
+	 *                             parameter to the shortcode
524
+	 * @return WP_Post or NULl
525
+	 */
526
+	public static function get_page_by_ee_shortcode($ee_shortcode)
527
+	{
528
+		global $wpdb;
529
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
530
+		$post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
531
+		if ($post_id) {
532
+			return get_post($post_id);
533
+		} else {
534
+			return null;
535
+		}
536
+	}
537
+
538
+
539
+	/**
540
+	 *    This function generates a post for critical espresso pages
541
+	 *
542
+	 * @access public
543
+	 * @static
544
+	 * @param array $critical_page
545
+	 * @return array
546
+	 */
547
+	public static function create_critical_page($critical_page)
548
+	{
549
+
550
+		$post_args = array(
551
+			'post_title'     => $critical_page['name'],
552
+			'post_status'    => 'publish',
553
+			'post_type'      => 'page',
554
+			'comment_status' => 'closed',
555
+			'post_content'   => '[' . $critical_page['code'] . ']',
556
+		);
557
+
558
+		$post_id = wp_insert_post($post_args);
559
+		if (! $post_id) {
560
+			$msg = sprintf(
561
+				__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
562
+				$critical_page['name']
563
+			);
564
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
565
+			return $critical_page;
566
+		}
567
+		// get newly created post's details
568
+		if (! $critical_page['post'] = get_post($post_id)) {
569
+			$msg = sprintf(
570
+				__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
571
+				$critical_page['name']
572
+			);
573
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
574
+		}
575
+
576
+		return $critical_page;
577
+	}
578
+
579
+
580
+
581
+
582
+	/**
583
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
584
+	 * The role being used to check is filterable.
585
+	 *
586
+	 * @since  4.6.0
587
+	 * @global WPDB $wpdb
588
+	 * @return mixed null|int WP_user ID or NULL
589
+	 */
590
+	public static function get_default_creator_id()
591
+	{
592
+		global $wpdb;
593
+		if (! empty(self::$_default_creator_id)) {
594
+			return self::$_default_creator_id;
595
+		}/**/
596
+		$role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
597
+		// let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
598
+		$pre_filtered_id = apply_filters(
599
+			'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
600
+			false,
601
+			$role_to_check
602
+		);
603
+		if ($pre_filtered_id !== false) {
604
+			return (int) $pre_filtered_id;
605
+		}
606
+		$capabilities_key = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
607
+		$query = $wpdb->prepare(
608
+			"SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
609
+			'%' . $role_to_check . '%'
610
+		);
611
+		$user_id = $wpdb->get_var($query);
612
+		$user_id = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
613
+		if ($user_id && (int) $user_id) {
614
+			self::$_default_creator_id = (int) $user_id;
615
+			return self::$_default_creator_id;
616
+		} else {
617
+			return null;
618
+		}
619
+	}
620
+
621
+
622
+
623
+	/**
624
+	 * used by EE and EE addons during plugin activation to create tables.
625
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
626
+	 * but includes extra logic regarding activations.
627
+	 *
628
+	 * @access public
629
+	 * @static
630
+	 * @param string  $table_name              without the $wpdb->prefix
631
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
632
+	 *                                         table query)
633
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
634
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
635
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
636
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
637
+	 *                                         you just want to verify the table exists and matches this definition
638
+	 *                                         (and if it HAS data in it you want to leave it be)
639
+	 * @return void
640
+	 * @throws EE_Error if there are database errors
641
+	 */
642
+	public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
643
+	{
644
+		if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
645
+			return;
646
+		}
647
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
648
+		if (! function_exists('dbDelta')) {
649
+			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
650
+		}
651
+		$tableAnalysis = \EEH_Activation::getTableAnalysis();
652
+		$wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
653
+		// do we need to first delete an existing version of this table ?
654
+		if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
655
+			// ok, delete the table... but ONLY if it's empty
656
+			$deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
657
+			// table is NOT empty, are you SURE you want to delete this table ???
658
+			if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
659
+				\EEH_Activation::getTableManager()->dropTable($wp_table_name);
660
+			} elseif (! $deleted_safely) {
661
+				// so we should be more cautious rather than just dropping tables so easily
662
+				error_log(
663
+					sprintf(
664
+						__(
665
+							'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
666
+							'event_espresso'
667
+						),
668
+						$wp_table_name,
669
+						'<br/>',
670
+						'espresso_db_update'
671
+					)
672
+				);
673
+			}
674
+		}
675
+		$engine = str_replace('ENGINE=', '', $engine);
676
+		\EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
677
+	}
678
+
679
+
680
+
681
+	/**
682
+	 *    add_column_if_it_doesn't_exist
683
+	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
684
+	 *
685
+	 * @access     public
686
+	 * @static
687
+	 * @deprecated instead use TableManager::addColumn()
688
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
689
+	 * @param string $column_name
690
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
691
+	 *                            'VARCHAR(10)'
692
+	 * @return bool|int
693
+	 */
694
+	public static function add_column_if_it_doesnt_exist(
695
+		$table_name,
696
+		$column_name,
697
+		$column_info = 'INT UNSIGNED NOT NULL'
698
+	) {
699
+		return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
700
+	}
701
+
702
+
703
+	/**
704
+	 * get_fields_on_table
705
+	 * Gets all the fields on the database table.
706
+	 *
707
+	 * @access     public
708
+	 * @deprecated instead use TableManager::getTableColumns()
709
+	 * @static
710
+	 * @param string $table_name , without prefixed $wpdb->prefix
711
+	 * @return array of database column names
712
+	 */
713
+	public static function get_fields_on_table($table_name = null)
714
+	{
715
+		return \EEH_Activation::getTableManager()->getTableColumns($table_name);
716
+	}
717
+
718
+
719
+	/**
720
+	 * db_table_is_empty
721
+	 *
722
+	 * @access     public\
723
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
724
+	 * @static
725
+	 * @param string $table_name
726
+	 * @return bool
727
+	 */
728
+	public static function db_table_is_empty($table_name)
729
+	{
730
+		return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
731
+	}
732
+
733
+
734
+	/**
735
+	 * delete_db_table_if_empty
736
+	 *
737
+	 * @access public
738
+	 * @static
739
+	 * @param string $table_name
740
+	 * @return bool | int
741
+	 */
742
+	public static function delete_db_table_if_empty($table_name)
743
+	{
744
+		if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
745
+			return \EEH_Activation::getTableManager()->dropTable($table_name);
746
+		}
747
+		return false;
748
+	}
749
+
750
+
751
+	/**
752
+	 * delete_unused_db_table
753
+	 *
754
+	 * @access     public
755
+	 * @static
756
+	 * @deprecated instead use TableManager::dropTable()
757
+	 * @param string $table_name
758
+	 * @return bool | int
759
+	 */
760
+	public static function delete_unused_db_table($table_name)
761
+	{
762
+		return \EEH_Activation::getTableManager()->dropTable($table_name);
763
+	}
764
+
765
+
766
+	/**
767
+	 * drop_index
768
+	 *
769
+	 * @access     public
770
+	 * @static
771
+	 * @deprecated instead use TableManager::dropIndex()
772
+	 * @param string $table_name
773
+	 * @param string $index_name
774
+	 * @return bool | int
775
+	 */
776
+	public static function drop_index($table_name, $index_name)
777
+	{
778
+		return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
779
+	}
780
+
781
+
782
+
783
+	/**
784
+	 * create_database_tables
785
+	 *
786
+	 * @access public
787
+	 * @static
788
+	 * @throws EE_Error
789
+	 * @return boolean success (whether database is setup properly or not)
790
+	 */
791
+	public static function create_database_tables()
792
+	{
793
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
794
+		// find the migration script that sets the database to be compatible with the code
795
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
796
+		if ($dms_name) {
797
+			$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
798
+			$current_data_migration_script->set_migrating(false);
799
+			$current_data_migration_script->schema_changes_before_migration();
800
+			$current_data_migration_script->schema_changes_after_migration();
801
+			if ($current_data_migration_script->get_errors()) {
802
+				if (WP_DEBUG) {
803
+					foreach ($current_data_migration_script->get_errors() as $error) {
804
+						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
805
+					}
806
+				} else {
807
+					EE_Error::add_error(
808
+						__(
809
+							'There were errors creating the Event Espresso database tables and Event Espresso has been 
810 810
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
811
-                            'event_espresso'
812
-                        )
813
-                    );
814
-                }
815
-                return false;
816
-            }
817
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
818
-        } else {
819
-            EE_Error::add_error(
820
-                __(
821
-                    'Could not determine most up-to-date data migration script from which to pull database schema
811
+							'event_espresso'
812
+						)
813
+					);
814
+				}
815
+				return false;
816
+			}
817
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
818
+		} else {
819
+			EE_Error::add_error(
820
+				__(
821
+					'Could not determine most up-to-date data migration script from which to pull database schema
822 822
                      structure. So database is probably not setup properly',
823
-                    'event_espresso'
824
-                ),
825
-                __FILE__,
826
-                __FUNCTION__,
827
-                __LINE__
828
-            );
829
-            return false;
830
-        }
831
-        return true;
832
-    }
833
-
834
-
835
-
836
-    /**
837
-     * initialize_system_questions
838
-     *
839
-     * @access public
840
-     * @static
841
-     * @return void
842
-     */
843
-    public static function initialize_system_questions()
844
-    {
845
-        // QUESTION GROUPS
846
-        global $wpdb;
847
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
848
-        $SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
849
-        // what we have
850
-        $question_groups = $wpdb->get_col($SQL);
851
-        // check the response
852
-        $question_groups = is_array($question_groups) ? $question_groups : array();
853
-        // what we should have
854
-        $QSG_systems = array(1, 2);
855
-        // loop thru what we should have and compare to what we have
856
-        foreach ($QSG_systems as $QSG_system) {
857
-            // reset values array
858
-            $QSG_values = array();
859
-            // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
860
-            if (! in_array("$QSG_system", $question_groups)) {
861
-                // add it
862
-                switch ($QSG_system) {
863
-                    case 1:
864
-                        $QSG_values = array(
865
-                            'QSG_name'            => __('Personal Information', 'event_espresso'),
866
-                            'QSG_identifier'      => 'personal-information-' . time(),
867
-                            'QSG_desc'            => '',
868
-                            'QSG_order'           => 1,
869
-                            'QSG_show_group_name' => 1,
870
-                            'QSG_show_group_desc' => 1,
871
-                            'QSG_system'          => EEM_Question_Group::system_personal,
872
-                            'QSG_deleted'         => 0,
873
-                        );
874
-                        break;
875
-                    case 2:
876
-                        $QSG_values = array(
877
-                            'QSG_name'            => __('Address Information', 'event_espresso'),
878
-                            'QSG_identifier'      => 'address-information-' . time(),
879
-                            'QSG_desc'            => '',
880
-                            'QSG_order'           => 2,
881
-                            'QSG_show_group_name' => 1,
882
-                            'QSG_show_group_desc' => 1,
883
-                            'QSG_system'          => EEM_Question_Group::system_address,
884
-                            'QSG_deleted'         => 0,
885
-                        );
886
-                        break;
887
-                }
888
-                // make sure we have some values before inserting them
889
-                if (! empty($QSG_values)) {
890
-                    // insert system question
891
-                    $wpdb->insert(
892
-                        $table_name,
893
-                        $QSG_values,
894
-                        array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
895
-                    );
896
-                    $QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
897
-                }
898
-            }
899
-        }
900
-        // QUESTIONS
901
-        global $wpdb;
902
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
903
-        $SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
904
-        // what we have
905
-        $questions = $wpdb->get_col($SQL);
906
-        // all system questions
907
-        $personal_system_group_questions = ['fname', 'lname', 'email'];
908
-        $address_system_group_questions = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
909
-        $system_questions_not_in_group = ['email_confirm'];
910
-        // merge all of the system questions we should have
911
-        $QST_systems = array_merge(
912
-            $personal_system_group_questions,
913
-            $address_system_group_questions,
914
-            $system_questions_not_in_group
915
-        );
916
-        $order_for_group_1 = 1;
917
-        $order_for_group_2 = 1;
918
-        // loop thru what we should have and compare to what we have
919
-        foreach ($QST_systems as $QST_system) {
920
-            // reset values array
921
-            $QST_values = array();
922
-            // if we don't have what we should have
923
-            if (! in_array($QST_system, $questions)) {
924
-                // add it
925
-                switch ($QST_system) {
926
-                    case 'fname':
927
-                        $QST_values = array(
928
-                            'QST_display_text'  => __('First Name', 'event_espresso'),
929
-                            'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
930
-                            'QST_system'        => 'fname',
931
-                            'QST_type'          => 'TEXT',
932
-                            'QST_required'      => 1,
933
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
934
-                            'QST_order'         => 1,
935
-                            'QST_admin_only'    => 0,
936
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
937
-                            'QST_wp_user'       => self::get_default_creator_id(),
938
-                            'QST_deleted'       => 0,
939
-                        );
940
-                        break;
941
-                    case 'lname':
942
-                        $QST_values = array(
943
-                            'QST_display_text'  => __('Last Name', 'event_espresso'),
944
-                            'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
945
-                            'QST_system'        => 'lname',
946
-                            'QST_type'          => 'TEXT',
947
-                            'QST_required'      => 1,
948
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
949
-                            'QST_order'         => 2,
950
-                            'QST_admin_only'    => 0,
951
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
952
-                            'QST_wp_user'       => self::get_default_creator_id(),
953
-                            'QST_deleted'       => 0,
954
-                        );
955
-                        break;
956
-                    case 'email':
957
-                        $QST_values = array(
958
-                            'QST_display_text'  => __('Email Address', 'event_espresso'),
959
-                            'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
960
-                            'QST_system'        => 'email',
961
-                            'QST_type'          => 'EMAIL',
962
-                            'QST_required'      => 1,
963
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
964
-                            'QST_order'         => 3,
965
-                            'QST_admin_only'    => 0,
966
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
967
-                            'QST_wp_user'       => self::get_default_creator_id(),
968
-                            'QST_deleted'       => 0,
969
-                        );
970
-                        break;
971
-                    case 'email_confirm':
972
-                        $QST_values = array(
973
-                            'QST_display_text'  => __('Confirm Email Address', 'event_espresso'),
974
-                            'QST_admin_label'   => __('Confirm Email Address - System Question', 'event_espresso'),
975
-                            'QST_system'        => 'email_confirm',
976
-                            'QST_type'          => 'EMAIL_CONFIRM',
977
-                            'QST_required'      => 1,
978
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
979
-                            'QST_order'         => 4,
980
-                            'QST_admin_only'    => 0,
981
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
982
-                            'QST_wp_user'       => self::get_default_creator_id(),
983
-                            'QST_deleted'       => 0,
984
-                        );
985
-                        break;
986
-                    case 'address':
987
-                        $QST_values = array(
988
-                            'QST_display_text'  => __('Address', 'event_espresso'),
989
-                            'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
990
-                            'QST_system'        => 'address',
991
-                            'QST_type'          => 'TEXT',
992
-                            'QST_required'      => 0,
993
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
994
-                            'QST_order'         => 5,
995
-                            'QST_admin_only'    => 0,
996
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
997
-                            'QST_wp_user'       => self::get_default_creator_id(),
998
-                            'QST_deleted'       => 0,
999
-                        );
1000
-                        break;
1001
-                    case 'address2':
1002
-                        $QST_values = array(
1003
-                            'QST_display_text'  => __('Address2', 'event_espresso'),
1004
-                            'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1005
-                            'QST_system'        => 'address2',
1006
-                            'QST_type'          => 'TEXT',
1007
-                            'QST_required'      => 0,
1008
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1009
-                            'QST_order'         => 6,
1010
-                            'QST_admin_only'    => 0,
1011
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1012
-                            'QST_wp_user'       => self::get_default_creator_id(),
1013
-                            'QST_deleted'       => 0,
1014
-                        );
1015
-                        break;
1016
-                    case 'city':
1017
-                        $QST_values = array(
1018
-                            'QST_display_text'  => __('City', 'event_espresso'),
1019
-                            'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1020
-                            'QST_system'        => 'city',
1021
-                            'QST_type'          => 'TEXT',
1022
-                            'QST_required'      => 0,
1023
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1024
-                            'QST_order'         => 7,
1025
-                            'QST_admin_only'    => 0,
1026
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1027
-                            'QST_wp_user'       => self::get_default_creator_id(),
1028
-                            'QST_deleted'       => 0,
1029
-                        );
1030
-                        break;
1031
-                    case 'country':
1032
-                        $QST_values = array(
1033
-                            'QST_display_text'  => __('Country', 'event_espresso'),
1034
-                            'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1035
-                            'QST_system'        => 'country',
1036
-                            'QST_type'          => 'COUNTRY',
1037
-                            'QST_required'      => 0,
1038
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1039
-                            'QST_order'         => 8,
1040
-                            'QST_admin_only'    => 0,
1041
-                            'QST_wp_user'       => self::get_default_creator_id(),
1042
-                            'QST_deleted'       => 0,
1043
-                        );
1044
-                        break;
1045
-                    case 'state':
1046
-                        $QST_values = array(
1047
-                            'QST_display_text'  => __('State/Province', 'event_espresso'),
1048
-                            'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1049
-                            'QST_system'        => 'state',
1050
-                            'QST_type'          => 'STATE',
1051
-                            'QST_required'      => 0,
1052
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1053
-                            'QST_order'         => 9,
1054
-                            'QST_admin_only'    => 0,
1055
-                            'QST_wp_user'       => self::get_default_creator_id(),
1056
-                            'QST_deleted'       => 0,
1057
-                        );
1058
-                        break;
1059
-                    case 'zip':
1060
-                        $QST_values = array(
1061
-                            'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1062
-                            'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1063
-                            'QST_system'        => 'zip',
1064
-                            'QST_type'          => 'TEXT',
1065
-                            'QST_required'      => 0,
1066
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1067
-                            'QST_order'         => 10,
1068
-                            'QST_admin_only'    => 0,
1069
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1070
-                            'QST_wp_user'       => self::get_default_creator_id(),
1071
-                            'QST_deleted'       => 0,
1072
-                        );
1073
-                        break;
1074
-                    case 'phone':
1075
-                        $QST_values = array(
1076
-                            'QST_display_text'  => __('Phone Number', 'event_espresso'),
1077
-                            'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1078
-                            'QST_system'        => 'phone',
1079
-                            'QST_type'          => 'TEXT',
1080
-                            'QST_required'      => 0,
1081
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1082
-                            'QST_order'         => 11,
1083
-                            'QST_admin_only'    => 0,
1084
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1085
-                            'QST_wp_user'       => self::get_default_creator_id(),
1086
-                            'QST_deleted'       => 0,
1087
-                        );
1088
-                        break;
1089
-                }
1090
-                if (! empty($QST_values)) {
1091
-                    // insert system question
1092
-                    $wpdb->insert(
1093
-                        $table_name,
1094
-                        $QST_values,
1095
-                        array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1096
-                    );
1097
-                    $QST_ID = $wpdb->insert_id;
1098
-
1099
-                    // QUESTION GROUP QUESTIONS
1100
-                    if (in_array($QST_system, $personal_system_group_questions)) {
1101
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1102
-                    } elseif (in_array($QST_system, $address_system_group_questions)) {
1103
-                        $system_question_we_want = EEM_Question_Group::system_address;
1104
-                    } else {
1105
-                        // QST_system should not be assigned to any group
1106
-                        continue;
1107
-                    }
1108
-                    if (isset($QSG_IDs[ $system_question_we_want ])) {
1109
-                        $QSG_ID = $QSG_IDs[ $system_question_we_want ];
1110
-                    } else {
1111
-                        $id_col = EEM_Question_Group::instance()
1112
-                                                    ->get_col(array(array('QSG_system' => $system_question_we_want)));
1113
-                        if (is_array($id_col)) {
1114
-                            $QSG_ID = reset($id_col);
1115
-                        } else {
1116
-                            // ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1117
-                            EE_Log::instance()->log(
1118
-                                __FILE__,
1119
-                                __FUNCTION__,
1120
-                                sprintf(
1121
-                                    __(
1122
-                                        'Could not associate question %1$s to a question group because no system question
823
+					'event_espresso'
824
+				),
825
+				__FILE__,
826
+				__FUNCTION__,
827
+				__LINE__
828
+			);
829
+			return false;
830
+		}
831
+		return true;
832
+	}
833
+
834
+
835
+
836
+	/**
837
+	 * initialize_system_questions
838
+	 *
839
+	 * @access public
840
+	 * @static
841
+	 * @return void
842
+	 */
843
+	public static function initialize_system_questions()
844
+	{
845
+		// QUESTION GROUPS
846
+		global $wpdb;
847
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
848
+		$SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
849
+		// what we have
850
+		$question_groups = $wpdb->get_col($SQL);
851
+		// check the response
852
+		$question_groups = is_array($question_groups) ? $question_groups : array();
853
+		// what we should have
854
+		$QSG_systems = array(1, 2);
855
+		// loop thru what we should have and compare to what we have
856
+		foreach ($QSG_systems as $QSG_system) {
857
+			// reset values array
858
+			$QSG_values = array();
859
+			// if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
860
+			if (! in_array("$QSG_system", $question_groups)) {
861
+				// add it
862
+				switch ($QSG_system) {
863
+					case 1:
864
+						$QSG_values = array(
865
+							'QSG_name'            => __('Personal Information', 'event_espresso'),
866
+							'QSG_identifier'      => 'personal-information-' . time(),
867
+							'QSG_desc'            => '',
868
+							'QSG_order'           => 1,
869
+							'QSG_show_group_name' => 1,
870
+							'QSG_show_group_desc' => 1,
871
+							'QSG_system'          => EEM_Question_Group::system_personal,
872
+							'QSG_deleted'         => 0,
873
+						);
874
+						break;
875
+					case 2:
876
+						$QSG_values = array(
877
+							'QSG_name'            => __('Address Information', 'event_espresso'),
878
+							'QSG_identifier'      => 'address-information-' . time(),
879
+							'QSG_desc'            => '',
880
+							'QSG_order'           => 2,
881
+							'QSG_show_group_name' => 1,
882
+							'QSG_show_group_desc' => 1,
883
+							'QSG_system'          => EEM_Question_Group::system_address,
884
+							'QSG_deleted'         => 0,
885
+						);
886
+						break;
887
+				}
888
+				// make sure we have some values before inserting them
889
+				if (! empty($QSG_values)) {
890
+					// insert system question
891
+					$wpdb->insert(
892
+						$table_name,
893
+						$QSG_values,
894
+						array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
895
+					);
896
+					$QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
897
+				}
898
+			}
899
+		}
900
+		// QUESTIONS
901
+		global $wpdb;
902
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
903
+		$SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
904
+		// what we have
905
+		$questions = $wpdb->get_col($SQL);
906
+		// all system questions
907
+		$personal_system_group_questions = ['fname', 'lname', 'email'];
908
+		$address_system_group_questions = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
909
+		$system_questions_not_in_group = ['email_confirm'];
910
+		// merge all of the system questions we should have
911
+		$QST_systems = array_merge(
912
+			$personal_system_group_questions,
913
+			$address_system_group_questions,
914
+			$system_questions_not_in_group
915
+		);
916
+		$order_for_group_1 = 1;
917
+		$order_for_group_2 = 1;
918
+		// loop thru what we should have and compare to what we have
919
+		foreach ($QST_systems as $QST_system) {
920
+			// reset values array
921
+			$QST_values = array();
922
+			// if we don't have what we should have
923
+			if (! in_array($QST_system, $questions)) {
924
+				// add it
925
+				switch ($QST_system) {
926
+					case 'fname':
927
+						$QST_values = array(
928
+							'QST_display_text'  => __('First Name', 'event_espresso'),
929
+							'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
930
+							'QST_system'        => 'fname',
931
+							'QST_type'          => 'TEXT',
932
+							'QST_required'      => 1,
933
+							'QST_required_text' => __('This field is required', 'event_espresso'),
934
+							'QST_order'         => 1,
935
+							'QST_admin_only'    => 0,
936
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
937
+							'QST_wp_user'       => self::get_default_creator_id(),
938
+							'QST_deleted'       => 0,
939
+						);
940
+						break;
941
+					case 'lname':
942
+						$QST_values = array(
943
+							'QST_display_text'  => __('Last Name', 'event_espresso'),
944
+							'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
945
+							'QST_system'        => 'lname',
946
+							'QST_type'          => 'TEXT',
947
+							'QST_required'      => 1,
948
+							'QST_required_text' => __('This field is required', 'event_espresso'),
949
+							'QST_order'         => 2,
950
+							'QST_admin_only'    => 0,
951
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
952
+							'QST_wp_user'       => self::get_default_creator_id(),
953
+							'QST_deleted'       => 0,
954
+						);
955
+						break;
956
+					case 'email':
957
+						$QST_values = array(
958
+							'QST_display_text'  => __('Email Address', 'event_espresso'),
959
+							'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
960
+							'QST_system'        => 'email',
961
+							'QST_type'          => 'EMAIL',
962
+							'QST_required'      => 1,
963
+							'QST_required_text' => __('This field is required', 'event_espresso'),
964
+							'QST_order'         => 3,
965
+							'QST_admin_only'    => 0,
966
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
967
+							'QST_wp_user'       => self::get_default_creator_id(),
968
+							'QST_deleted'       => 0,
969
+						);
970
+						break;
971
+					case 'email_confirm':
972
+						$QST_values = array(
973
+							'QST_display_text'  => __('Confirm Email Address', 'event_espresso'),
974
+							'QST_admin_label'   => __('Confirm Email Address - System Question', 'event_espresso'),
975
+							'QST_system'        => 'email_confirm',
976
+							'QST_type'          => 'EMAIL_CONFIRM',
977
+							'QST_required'      => 1,
978
+							'QST_required_text' => __('This field is required', 'event_espresso'),
979
+							'QST_order'         => 4,
980
+							'QST_admin_only'    => 0,
981
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
982
+							'QST_wp_user'       => self::get_default_creator_id(),
983
+							'QST_deleted'       => 0,
984
+						);
985
+						break;
986
+					case 'address':
987
+						$QST_values = array(
988
+							'QST_display_text'  => __('Address', 'event_espresso'),
989
+							'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
990
+							'QST_system'        => 'address',
991
+							'QST_type'          => 'TEXT',
992
+							'QST_required'      => 0,
993
+							'QST_required_text' => __('This field is required', 'event_espresso'),
994
+							'QST_order'         => 5,
995
+							'QST_admin_only'    => 0,
996
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
997
+							'QST_wp_user'       => self::get_default_creator_id(),
998
+							'QST_deleted'       => 0,
999
+						);
1000
+						break;
1001
+					case 'address2':
1002
+						$QST_values = array(
1003
+							'QST_display_text'  => __('Address2', 'event_espresso'),
1004
+							'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1005
+							'QST_system'        => 'address2',
1006
+							'QST_type'          => 'TEXT',
1007
+							'QST_required'      => 0,
1008
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1009
+							'QST_order'         => 6,
1010
+							'QST_admin_only'    => 0,
1011
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1012
+							'QST_wp_user'       => self::get_default_creator_id(),
1013
+							'QST_deleted'       => 0,
1014
+						);
1015
+						break;
1016
+					case 'city':
1017
+						$QST_values = array(
1018
+							'QST_display_text'  => __('City', 'event_espresso'),
1019
+							'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1020
+							'QST_system'        => 'city',
1021
+							'QST_type'          => 'TEXT',
1022
+							'QST_required'      => 0,
1023
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1024
+							'QST_order'         => 7,
1025
+							'QST_admin_only'    => 0,
1026
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1027
+							'QST_wp_user'       => self::get_default_creator_id(),
1028
+							'QST_deleted'       => 0,
1029
+						);
1030
+						break;
1031
+					case 'country':
1032
+						$QST_values = array(
1033
+							'QST_display_text'  => __('Country', 'event_espresso'),
1034
+							'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1035
+							'QST_system'        => 'country',
1036
+							'QST_type'          => 'COUNTRY',
1037
+							'QST_required'      => 0,
1038
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1039
+							'QST_order'         => 8,
1040
+							'QST_admin_only'    => 0,
1041
+							'QST_wp_user'       => self::get_default_creator_id(),
1042
+							'QST_deleted'       => 0,
1043
+						);
1044
+						break;
1045
+					case 'state':
1046
+						$QST_values = array(
1047
+							'QST_display_text'  => __('State/Province', 'event_espresso'),
1048
+							'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1049
+							'QST_system'        => 'state',
1050
+							'QST_type'          => 'STATE',
1051
+							'QST_required'      => 0,
1052
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1053
+							'QST_order'         => 9,
1054
+							'QST_admin_only'    => 0,
1055
+							'QST_wp_user'       => self::get_default_creator_id(),
1056
+							'QST_deleted'       => 0,
1057
+						);
1058
+						break;
1059
+					case 'zip':
1060
+						$QST_values = array(
1061
+							'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1062
+							'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1063
+							'QST_system'        => 'zip',
1064
+							'QST_type'          => 'TEXT',
1065
+							'QST_required'      => 0,
1066
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1067
+							'QST_order'         => 10,
1068
+							'QST_admin_only'    => 0,
1069
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1070
+							'QST_wp_user'       => self::get_default_creator_id(),
1071
+							'QST_deleted'       => 0,
1072
+						);
1073
+						break;
1074
+					case 'phone':
1075
+						$QST_values = array(
1076
+							'QST_display_text'  => __('Phone Number', 'event_espresso'),
1077
+							'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1078
+							'QST_system'        => 'phone',
1079
+							'QST_type'          => 'TEXT',
1080
+							'QST_required'      => 0,
1081
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1082
+							'QST_order'         => 11,
1083
+							'QST_admin_only'    => 0,
1084
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1085
+							'QST_wp_user'       => self::get_default_creator_id(),
1086
+							'QST_deleted'       => 0,
1087
+						);
1088
+						break;
1089
+				}
1090
+				if (! empty($QST_values)) {
1091
+					// insert system question
1092
+					$wpdb->insert(
1093
+						$table_name,
1094
+						$QST_values,
1095
+						array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1096
+					);
1097
+					$QST_ID = $wpdb->insert_id;
1098
+
1099
+					// QUESTION GROUP QUESTIONS
1100
+					if (in_array($QST_system, $personal_system_group_questions)) {
1101
+						$system_question_we_want = EEM_Question_Group::system_personal;
1102
+					} elseif (in_array($QST_system, $address_system_group_questions)) {
1103
+						$system_question_we_want = EEM_Question_Group::system_address;
1104
+					} else {
1105
+						// QST_system should not be assigned to any group
1106
+						continue;
1107
+					}
1108
+					if (isset($QSG_IDs[ $system_question_we_want ])) {
1109
+						$QSG_ID = $QSG_IDs[ $system_question_we_want ];
1110
+					} else {
1111
+						$id_col = EEM_Question_Group::instance()
1112
+													->get_col(array(array('QSG_system' => $system_question_we_want)));
1113
+						if (is_array($id_col)) {
1114
+							$QSG_ID = reset($id_col);
1115
+						} else {
1116
+							// ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1117
+							EE_Log::instance()->log(
1118
+								__FILE__,
1119
+								__FUNCTION__,
1120
+								sprintf(
1121
+									__(
1122
+										'Could not associate question %1$s to a question group because no system question
1123 1123
                                          group existed',
1124
-                                        'event_espresso'
1125
-                                    ),
1126
-                                    $QST_ID
1127
-                                ),
1128
-                                'error'
1129
-                            );
1130
-                            continue;
1131
-                        }
1132
-                    }
1133
-                    // add system questions to groups
1134
-                    $wpdb->insert(
1135
-                        \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1136
-                        array(
1137
-                            'QSG_ID'    => $QSG_ID,
1138
-                            'QST_ID'    => $QST_ID,
1139
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1140
-                        ),
1141
-                        array('%d', '%d', '%d')
1142
-                    );
1143
-                }
1144
-            }
1145
-        }
1146
-    }
1147
-
1148
-
1149
-    /**
1150
-     * Makes sure the default payment method (Invoice) is active.
1151
-     * This used to be done automatically as part of constructing the old gateways config
1152
-     *
1153
-     * @throws \EE_Error
1154
-     */
1155
-    public static function insert_default_payment_methods()
1156
-    {
1157
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1158
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1159
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1160
-        } else {
1161
-            EEM_Payment_Method::instance()->verify_button_urls();
1162
-        }
1163
-    }
1164
-
1165
-    /**
1166
-     * insert_default_status_codes
1167
-     *
1168
-     * @access public
1169
-     * @static
1170
-     * @return void
1171
-     */
1172
-    public static function insert_default_status_codes()
1173
-    {
1174
-
1175
-        global $wpdb;
1176
-
1177
-        if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1178
-            $table_name = EEM_Status::instance()->table();
1179
-
1180
-            $SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1181
-            $wpdb->query($SQL);
1182
-
1183
-            $SQL = "INSERT INTO $table_name
1124
+										'event_espresso'
1125
+									),
1126
+									$QST_ID
1127
+								),
1128
+								'error'
1129
+							);
1130
+							continue;
1131
+						}
1132
+					}
1133
+					// add system questions to groups
1134
+					$wpdb->insert(
1135
+						\EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1136
+						array(
1137
+							'QSG_ID'    => $QSG_ID,
1138
+							'QST_ID'    => $QST_ID,
1139
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1140
+						),
1141
+						array('%d', '%d', '%d')
1142
+					);
1143
+				}
1144
+			}
1145
+		}
1146
+	}
1147
+
1148
+
1149
+	/**
1150
+	 * Makes sure the default payment method (Invoice) is active.
1151
+	 * This used to be done automatically as part of constructing the old gateways config
1152
+	 *
1153
+	 * @throws \EE_Error
1154
+	 */
1155
+	public static function insert_default_payment_methods()
1156
+	{
1157
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1158
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1159
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1160
+		} else {
1161
+			EEM_Payment_Method::instance()->verify_button_urls();
1162
+		}
1163
+	}
1164
+
1165
+	/**
1166
+	 * insert_default_status_codes
1167
+	 *
1168
+	 * @access public
1169
+	 * @static
1170
+	 * @return void
1171
+	 */
1172
+	public static function insert_default_status_codes()
1173
+	{
1174
+
1175
+		global $wpdb;
1176
+
1177
+		if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1178
+			$table_name = EEM_Status::instance()->table();
1179
+
1180
+			$SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1181
+			$wpdb->query($SQL);
1182
+
1183
+			$SQL = "INSERT INTO $table_name
1184 1184
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1185 1185
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1186 1186
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1220,477 +1220,477 @@  discard block
 block discarded – undo
1220 1220
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1221 1221
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1222 1222
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1223
-            $wpdb->query($SQL);
1224
-        }
1225
-    }
1226
-
1227
-
1228
-    /**
1229
-     * generate_default_message_templates
1230
-     *
1231
-     * @static
1232
-     * @throws EE_Error
1233
-     * @return bool     true means new templates were created.
1234
-     *                  false means no templates were created.
1235
-     *                  This is NOT an error flag. To check for errors you will want
1236
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1237
-     */
1238
-    public static function generate_default_message_templates()
1239
-    {
1240
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1241
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1242
-        /*
1223
+			$wpdb->query($SQL);
1224
+		}
1225
+	}
1226
+
1227
+
1228
+	/**
1229
+	 * generate_default_message_templates
1230
+	 *
1231
+	 * @static
1232
+	 * @throws EE_Error
1233
+	 * @return bool     true means new templates were created.
1234
+	 *                  false means no templates were created.
1235
+	 *                  This is NOT an error flag. To check for errors you will want
1236
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1237
+	 */
1238
+	public static function generate_default_message_templates()
1239
+	{
1240
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1241
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1242
+		/*
1243 1243
          * This first method is taking care of ensuring any default messengers
1244 1244
          * that should be made active and have templates generated are done.
1245 1245
          */
1246
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1247
-            $message_resource_manager
1248
-        );
1249
-        /**
1250
-         * This method is verifying there are no NEW default message types
1251
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1252
-         */
1253
-        $new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1254
-            $message_resource_manager
1255
-        );
1256
-        // after all is done, let's persist these changes to the db.
1257
-        $message_resource_manager->update_has_activated_messengers_option();
1258
-        $message_resource_manager->update_active_messengers_option();
1259
-        // will return true if either of these are true.  Otherwise will return false.
1260
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1261
-    }
1262
-
1263
-
1264
-
1265
-    /**
1266
-     * @param \EE_Message_Resource_Manager $message_resource_manager
1267
-     * @return array|bool
1268
-     * @throws \EE_Error
1269
-     */
1270
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1271
-        EE_Message_Resource_Manager $message_resource_manager
1272
-    ) {
1273
-        /** @type EE_messenger[] $active_messengers */
1274
-        $active_messengers = $message_resource_manager->active_messengers();
1275
-        $installed_message_types = $message_resource_manager->installed_message_types();
1276
-        $templates_created = false;
1277
-        foreach ($active_messengers as $active_messenger) {
1278
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1279
-            $default_message_type_names_to_activate = array();
1280
-            // looping through each default message type reported by the messenger
1281
-            // and setup the actual message types to activate.
1282
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1283
-                // if already active or has already been activated before we skip
1284
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1285
-                // we also skip if the message type is not installed.
1286
-                if (
1287
-                    $message_resource_manager->has_message_type_been_activated_for_messenger(
1288
-                        $default_message_type_name_for_messenger,
1289
-                        $active_messenger->name
1290
-                    )
1291
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1292
-                        $active_messenger->name,
1293
-                        $default_message_type_name_for_messenger
1294
-                    )
1295
-                    || ! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1296
-                ) {
1297
-                    continue;
1298
-                }
1299
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1300
-            }
1301
-            // let's activate!
1302
-            $message_resource_manager->ensure_message_types_are_active(
1303
-                $default_message_type_names_to_activate,
1304
-                $active_messenger->name,
1305
-                false
1306
-            );
1307
-            // activate the templates for these message types
1308
-            if (! empty($default_message_type_names_to_activate)) {
1309
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1310
-                    $active_messenger->name,
1311
-                    $default_message_type_names_for_messenger,
1312
-                    '',
1313
-                    true
1314
-                );
1315
-            }
1316
-        }
1317
-        return $templates_created;
1318
-    }
1319
-
1320
-
1321
-
1322
-    /**
1323
-     * This will activate and generate default messengers and default message types for those messengers.
1324
-     *
1325
-     * @param EE_message_Resource_Manager $message_resource_manager
1326
-     * @return array|bool  True means there were default messengers and message type templates generated.
1327
-     *                     False means that there were no templates generated
1328
-     *                     (which could simply mean there are no default message types for a messenger).
1329
-     * @throws EE_Error
1330
-     */
1331
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1332
-        EE_Message_Resource_Manager $message_resource_manager
1333
-    ) {
1334
-        /** @type EE_messenger[] $messengers_to_generate */
1335
-        $messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1336
-        $installed_message_types = $message_resource_manager->installed_message_types();
1337
-        $templates_generated = false;
1338
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1339
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1340
-            // verify the default message types match an installed message type.
1341
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1342
-                if (
1343
-                    ! isset($installed_message_types[ $name ])
1344
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1345
-                        $name,
1346
-                        $messenger_to_generate->name
1347
-                    )
1348
-                ) {
1349
-                    unset($default_message_type_names_for_messenger[ $key ]);
1350
-                }
1351
-            }
1352
-            // in previous iterations, the active_messengers option in the db
1353
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1354
-            // This comment is left here just in case we discover that we _do_ need to update before
1355
-            // passing off to create templates (after the refactor is done).
1356
-            // @todo remove this comment when determined not necessary.
1357
-            $message_resource_manager->activate_messenger(
1358
-                $messenger_to_generate,
1359
-                $default_message_type_names_for_messenger,
1360
-                false
1361
-            );
1362
-            // create any templates needing created (or will reactivate templates already generated as necessary).
1363
-            if (! empty($default_message_type_names_for_messenger)) {
1364
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1365
-                    $messenger_to_generate->name,
1366
-                    $default_message_type_names_for_messenger,
1367
-                    '',
1368
-                    true
1369
-                );
1370
-            }
1371
-        }
1372
-        return $templates_generated;
1373
-    }
1374
-
1375
-
1376
-    /**
1377
-     * This returns the default messengers to generate templates for on activation of EE.
1378
-     * It considers:
1379
-     * - whether a messenger is already active in the db.
1380
-     * - whether a messenger has been made active at any time in the past.
1381
-     *
1382
-     * @static
1383
-     * @param  EE_Message_Resource_Manager $message_resource_manager
1384
-     * @return EE_messenger[]
1385
-     */
1386
-    protected static function _get_default_messengers_to_generate_on_activation(
1387
-        EE_Message_Resource_Manager $message_resource_manager
1388
-    ) {
1389
-        $active_messengers    = $message_resource_manager->active_messengers();
1390
-        $installed_messengers = $message_resource_manager->installed_messengers();
1391
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1392
-
1393
-        $messengers_to_generate = array();
1394
-        foreach ($installed_messengers as $installed_messenger) {
1395
-            // if installed messenger is a messenger that should be activated on install
1396
-            // and is not already active
1397
-            // and has never been activated
1398
-            if (
1399
-                ! $installed_messenger->activate_on_install
1400
-                || isset($active_messengers[ $installed_messenger->name ])
1401
-                || isset($has_activated[ $installed_messenger->name ])
1402
-            ) {
1403
-                continue;
1404
-            }
1405
-            $messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1406
-        }
1407
-        return $messengers_to_generate;
1408
-    }
1409
-
1410
-
1411
-    /**
1412
-     * This simply validates active message types to ensure they actually match installed
1413
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1414
-     * rows are set inactive.
1415
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1416
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1417
-     * are still handled in here.
1418
-     *
1419
-     * @since 4.3.1
1420
-     * @return void
1421
-     */
1422
-    public static function validate_messages_system()
1423
-    {
1424
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1425
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1426
-        $message_resource_manager->validate_active_message_types_are_installed();
1427
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1428
-    }
1429
-
1430
-
1431
-    /**
1432
-     * create_no_ticket_prices_array
1433
-     *
1434
-     * @access public
1435
-     * @static
1436
-     * @return void
1437
-     */
1438
-    public static function create_no_ticket_prices_array()
1439
-    {
1440
-        // this creates an array for tracking events that have no active ticket prices created
1441
-        // this allows us to warn admins of the situation so that it can be corrected
1442
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1443
-        if (! $espresso_no_ticket_prices) {
1444
-            add_option('ee_no_ticket_prices', array(), '', false);
1445
-        }
1446
-    }
1447
-
1448
-
1449
-    /**
1450
-     * plugin_deactivation
1451
-     *
1452
-     * @access public
1453
-     * @static
1454
-     * @return void
1455
-     */
1456
-    public static function plugin_deactivation()
1457
-    {
1458
-    }
1459
-
1460
-
1461
-    /**
1462
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1463
-     * (like post meta or term relations)
1464
-     *
1465
-     * @global wpdb $wpdb
1466
-     * @throws \EE_Error
1467
-     */
1468
-    public static function delete_all_espresso_cpt_data()
1469
-    {
1470
-        global $wpdb;
1471
-        // get all the CPT post_types
1472
-        $ee_post_types = array();
1473
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1474
-            if (method_exists($model_name, 'instance')) {
1475
-                $model_obj = call_user_func(array($model_name, 'instance'));
1476
-                if ($model_obj instanceof EEM_CPT_Base) {
1477
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1478
-                }
1479
-            }
1480
-        }
1481
-        // get all our CPTs
1482
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1483
-        $cpt_ids = $wpdb->get_col($query);
1484
-        // delete each post meta and term relations too
1485
-        foreach ($cpt_ids as $post_id) {
1486
-            wp_delete_post($post_id, true);
1487
-        }
1488
-    }
1489
-
1490
-    /**
1491
-     * Deletes all EE custom tables
1492
-     *
1493
-     * @return array
1494
-     */
1495
-    public static function drop_espresso_tables()
1496
-    {
1497
-        $tables = array();
1498
-        // load registry
1499
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1500
-            if (method_exists($model_name, 'instance')) {
1501
-                $model_obj = call_user_func(array($model_name, 'instance'));
1502
-                if ($model_obj instanceof EEM_Base) {
1503
-                    foreach ($model_obj->get_tables() as $table) {
1504
-                        if (
1505
-                            strpos($table->get_table_name(), 'esp_')
1506
-                            &&
1507
-                            (
1508
-                                is_main_site()// main site? nuke them all
1509
-                                || ! $table->is_global()// not main site,but not global either. nuke it
1510
-                            )
1511
-                        ) {
1512
-                            $tables[ $table->get_table_name() ] = $table->get_table_name();
1513
-                        }
1514
-                    }
1515
-                }
1516
-            }
1517
-        }
1518
-
1519
-        // there are some tables whose models were removed.
1520
-        // they should be removed when removing all EE core's data
1521
-        $tables_without_models = array(
1522
-            'esp_promotion',
1523
-            'esp_promotion_applied',
1524
-            'esp_promotion_object',
1525
-            'esp_promotion_rule',
1526
-            'esp_rule',
1527
-        );
1528
-        foreach ($tables_without_models as $table) {
1529
-            $tables[ $table ] = $table;
1530
-        }
1531
-        return \EEH_Activation::getTableManager()->dropTables($tables);
1532
-    }
1533
-
1534
-
1535
-
1536
-    /**
1537
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1538
-     * each table name provided has a wpdb prefix attached, and that it exists.
1539
-     * Returns the list actually deleted
1540
-     *
1541
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1542
-     * @global WPDB $wpdb
1543
-     * @param array $table_names
1544
-     * @return array of table names which we deleted
1545
-     */
1546
-    public static function drop_tables($table_names)
1547
-    {
1548
-        return \EEH_Activation::getTableManager()->dropTables($table_names);
1549
-    }
1550
-
1551
-
1552
-
1553
-    /**
1554
-     * plugin_uninstall
1555
-     *
1556
-     * @access public
1557
-     * @static
1558
-     * @param bool $remove_all
1559
-     * @return void
1560
-     */
1561
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1562
-    {
1563
-        global $wpdb;
1564
-        self::drop_espresso_tables();
1565
-        $wp_options_to_delete = array(
1566
-            'ee_no_ticket_prices'                => true,
1567
-            'ee_active_messengers'               => true,
1568
-            'ee_has_activated_messenger'         => true,
1569
-            RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1570
-            'ee_config'                          => false,
1571
-            'ee_data_migration_current_db_state' => true,
1572
-            'ee_data_migration_mapping_'         => false,
1573
-            'ee_data_migration_script_'          => false,
1574
-            'ee_data_migrations'                 => true,
1575
-            'ee_dms_map'                         => false,
1576
-            'ee_notices'                         => true,
1577
-            'lang_file_check_'                   => false,
1578
-            'ee_maintenance_mode'                => true,
1579
-            'ee_ueip_optin'                      => true,
1580
-            'ee_ueip_has_notified'               => true,
1581
-            'ee_plugin_activation_errors'        => true,
1582
-            'ee_id_mapping_from'                 => false,
1583
-            'espresso_persistent_admin_notices'  => true,
1584
-            'ee_encryption_key'                  => true,
1585
-            'pue_force_upgrade_'                 => false,
1586
-            'pue_json_error_'                    => false,
1587
-            'pue_install_key_'                   => false,
1588
-            'pue_verification_error_'            => false,
1589
-            'pu_dismissed_upgrade_'              => false,
1590
-            'external_updates-'                  => false,
1591
-            'ee_extra_data'                      => true,
1592
-            'ee_ssn_'                            => false,
1593
-            'ee_rss_'                            => false,
1594
-            'ee_rte_n_tx_'                       => false,
1595
-            'ee_pers_admin_notices'              => true,
1596
-            'ee_job_parameters_'                 => false,
1597
-            'ee_upload_directories_incomplete'   => true,
1598
-            'ee_verified_db_collations'          => true,
1599
-        );
1600
-        if (is_main_site()) {
1601
-            $wp_options_to_delete['ee_network_config'] = true;
1602
-        }
1603
-        $undeleted_options = array();
1604
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1605
-            if ($no_wildcard) {
1606
-                if (! delete_option($option_name)) {
1607
-                    $undeleted_options[] = $option_name;
1608
-                }
1609
-            } else {
1610
-                $option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1611
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1612
-                    if (! delete_option($option_name_from_wildcard)) {
1613
-                        $undeleted_options[] = $option_name_from_wildcard;
1614
-                    }
1615
-                }
1616
-            }
1617
-        }
1618
-        // also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1619
-        remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1620
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1621
-            $db_update_sans_ee4 = array();
1622
-            foreach ($espresso_db_update as $version => $times_activated) {
1623
-                if ((string) $version[0] === '3') {// if its NON EE4
1624
-                    $db_update_sans_ee4[ $version ] = $times_activated;
1625
-                }
1626
-            }
1627
-            update_option('espresso_db_update', $db_update_sans_ee4);
1628
-        }
1629
-        $errors = '';
1630
-        if (! empty($undeleted_options)) {
1631
-            $errors .= sprintf(
1632
-                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1633
-                '<br/>',
1634
-                implode(',<br/>', $undeleted_options)
1635
-            );
1636
-        }
1637
-        if (! empty($errors)) {
1638
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1639
-        }
1640
-    }
1641
-
1642
-    /**
1643
-     * Gets the mysql error code from the last used query by wpdb
1644
-     *
1645
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1646
-     */
1647
-    public static function last_wpdb_error_code()
1648
-    {
1649
-        global $wpdb;
1650
-        return $wpdb->use_mysqli ? mysqli_errno($wpdb->dbh) : 0;
1651
-    }
1652
-
1653
-    /**
1654
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1655
-     *
1656
-     * @global wpdb  $wpdb
1657
-     * @deprecated instead use TableAnalysis::tableExists()
1658
-     * @param string $table_name with or without $wpdb->prefix
1659
-     * @return boolean
1660
-     */
1661
-    public static function table_exists($table_name)
1662
-    {
1663
-        return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1664
-    }
1665
-
1666
-    /**
1667
-     * Resets the cache on EEH_Activation
1668
-     */
1669
-    public static function reset()
1670
-    {
1671
-        self::$_default_creator_id                             = null;
1672
-        self::$_initialized_db_content_already_in_this_request = false;
1673
-    }
1674
-
1675
-    /**
1676
-     * Removes 'email_confirm' from the Address info question group on activation
1677
-     * @return void
1678
-     */
1679
-    public static function removeEmailConfirmFromAddressGroup()
1680
-    {
1681
-
1682
-        // Pull the email_confirm question ID.
1683
-        $email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1684
-            EEM_Attendee::system_question_email_confirm
1685
-        );
1686
-        // Remove the email_confirm question group from the address group questions.
1687
-        EEM_Question_Group_Question::instance()->delete(
1688
-            array(
1689
-                array(
1690
-                    'QST_ID' => $email_confirm_question_id,
1691
-                    'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1692
-                ),
1693
-            )
1694
-        );
1695
-    }
1246
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1247
+			$message_resource_manager
1248
+		);
1249
+		/**
1250
+		 * This method is verifying there are no NEW default message types
1251
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1252
+		 */
1253
+		$new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1254
+			$message_resource_manager
1255
+		);
1256
+		// after all is done, let's persist these changes to the db.
1257
+		$message_resource_manager->update_has_activated_messengers_option();
1258
+		$message_resource_manager->update_active_messengers_option();
1259
+		// will return true if either of these are true.  Otherwise will return false.
1260
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1261
+	}
1262
+
1263
+
1264
+
1265
+	/**
1266
+	 * @param \EE_Message_Resource_Manager $message_resource_manager
1267
+	 * @return array|bool
1268
+	 * @throws \EE_Error
1269
+	 */
1270
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1271
+		EE_Message_Resource_Manager $message_resource_manager
1272
+	) {
1273
+		/** @type EE_messenger[] $active_messengers */
1274
+		$active_messengers = $message_resource_manager->active_messengers();
1275
+		$installed_message_types = $message_resource_manager->installed_message_types();
1276
+		$templates_created = false;
1277
+		foreach ($active_messengers as $active_messenger) {
1278
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1279
+			$default_message_type_names_to_activate = array();
1280
+			// looping through each default message type reported by the messenger
1281
+			// and setup the actual message types to activate.
1282
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1283
+				// if already active or has already been activated before we skip
1284
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1285
+				// we also skip if the message type is not installed.
1286
+				if (
1287
+					$message_resource_manager->has_message_type_been_activated_for_messenger(
1288
+						$default_message_type_name_for_messenger,
1289
+						$active_messenger->name
1290
+					)
1291
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1292
+						$active_messenger->name,
1293
+						$default_message_type_name_for_messenger
1294
+					)
1295
+					|| ! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1296
+				) {
1297
+					continue;
1298
+				}
1299
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1300
+			}
1301
+			// let's activate!
1302
+			$message_resource_manager->ensure_message_types_are_active(
1303
+				$default_message_type_names_to_activate,
1304
+				$active_messenger->name,
1305
+				false
1306
+			);
1307
+			// activate the templates for these message types
1308
+			if (! empty($default_message_type_names_to_activate)) {
1309
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1310
+					$active_messenger->name,
1311
+					$default_message_type_names_for_messenger,
1312
+					'',
1313
+					true
1314
+				);
1315
+			}
1316
+		}
1317
+		return $templates_created;
1318
+	}
1319
+
1320
+
1321
+
1322
+	/**
1323
+	 * This will activate and generate default messengers and default message types for those messengers.
1324
+	 *
1325
+	 * @param EE_message_Resource_Manager $message_resource_manager
1326
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1327
+	 *                     False means that there were no templates generated
1328
+	 *                     (which could simply mean there are no default message types for a messenger).
1329
+	 * @throws EE_Error
1330
+	 */
1331
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1332
+		EE_Message_Resource_Manager $message_resource_manager
1333
+	) {
1334
+		/** @type EE_messenger[] $messengers_to_generate */
1335
+		$messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1336
+		$installed_message_types = $message_resource_manager->installed_message_types();
1337
+		$templates_generated = false;
1338
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1339
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1340
+			// verify the default message types match an installed message type.
1341
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1342
+				if (
1343
+					! isset($installed_message_types[ $name ])
1344
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1345
+						$name,
1346
+						$messenger_to_generate->name
1347
+					)
1348
+				) {
1349
+					unset($default_message_type_names_for_messenger[ $key ]);
1350
+				}
1351
+			}
1352
+			// in previous iterations, the active_messengers option in the db
1353
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1354
+			// This comment is left here just in case we discover that we _do_ need to update before
1355
+			// passing off to create templates (after the refactor is done).
1356
+			// @todo remove this comment when determined not necessary.
1357
+			$message_resource_manager->activate_messenger(
1358
+				$messenger_to_generate,
1359
+				$default_message_type_names_for_messenger,
1360
+				false
1361
+			);
1362
+			// create any templates needing created (or will reactivate templates already generated as necessary).
1363
+			if (! empty($default_message_type_names_for_messenger)) {
1364
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1365
+					$messenger_to_generate->name,
1366
+					$default_message_type_names_for_messenger,
1367
+					'',
1368
+					true
1369
+				);
1370
+			}
1371
+		}
1372
+		return $templates_generated;
1373
+	}
1374
+
1375
+
1376
+	/**
1377
+	 * This returns the default messengers to generate templates for on activation of EE.
1378
+	 * It considers:
1379
+	 * - whether a messenger is already active in the db.
1380
+	 * - whether a messenger has been made active at any time in the past.
1381
+	 *
1382
+	 * @static
1383
+	 * @param  EE_Message_Resource_Manager $message_resource_manager
1384
+	 * @return EE_messenger[]
1385
+	 */
1386
+	protected static function _get_default_messengers_to_generate_on_activation(
1387
+		EE_Message_Resource_Manager $message_resource_manager
1388
+	) {
1389
+		$active_messengers    = $message_resource_manager->active_messengers();
1390
+		$installed_messengers = $message_resource_manager->installed_messengers();
1391
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1392
+
1393
+		$messengers_to_generate = array();
1394
+		foreach ($installed_messengers as $installed_messenger) {
1395
+			// if installed messenger is a messenger that should be activated on install
1396
+			// and is not already active
1397
+			// and has never been activated
1398
+			if (
1399
+				! $installed_messenger->activate_on_install
1400
+				|| isset($active_messengers[ $installed_messenger->name ])
1401
+				|| isset($has_activated[ $installed_messenger->name ])
1402
+			) {
1403
+				continue;
1404
+			}
1405
+			$messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1406
+		}
1407
+		return $messengers_to_generate;
1408
+	}
1409
+
1410
+
1411
+	/**
1412
+	 * This simply validates active message types to ensure they actually match installed
1413
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1414
+	 * rows are set inactive.
1415
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1416
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1417
+	 * are still handled in here.
1418
+	 *
1419
+	 * @since 4.3.1
1420
+	 * @return void
1421
+	 */
1422
+	public static function validate_messages_system()
1423
+	{
1424
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1425
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1426
+		$message_resource_manager->validate_active_message_types_are_installed();
1427
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1428
+	}
1429
+
1430
+
1431
+	/**
1432
+	 * create_no_ticket_prices_array
1433
+	 *
1434
+	 * @access public
1435
+	 * @static
1436
+	 * @return void
1437
+	 */
1438
+	public static function create_no_ticket_prices_array()
1439
+	{
1440
+		// this creates an array for tracking events that have no active ticket prices created
1441
+		// this allows us to warn admins of the situation so that it can be corrected
1442
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1443
+		if (! $espresso_no_ticket_prices) {
1444
+			add_option('ee_no_ticket_prices', array(), '', false);
1445
+		}
1446
+	}
1447
+
1448
+
1449
+	/**
1450
+	 * plugin_deactivation
1451
+	 *
1452
+	 * @access public
1453
+	 * @static
1454
+	 * @return void
1455
+	 */
1456
+	public static function plugin_deactivation()
1457
+	{
1458
+	}
1459
+
1460
+
1461
+	/**
1462
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1463
+	 * (like post meta or term relations)
1464
+	 *
1465
+	 * @global wpdb $wpdb
1466
+	 * @throws \EE_Error
1467
+	 */
1468
+	public static function delete_all_espresso_cpt_data()
1469
+	{
1470
+		global $wpdb;
1471
+		// get all the CPT post_types
1472
+		$ee_post_types = array();
1473
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1474
+			if (method_exists($model_name, 'instance')) {
1475
+				$model_obj = call_user_func(array($model_name, 'instance'));
1476
+				if ($model_obj instanceof EEM_CPT_Base) {
1477
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1478
+				}
1479
+			}
1480
+		}
1481
+		// get all our CPTs
1482
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1483
+		$cpt_ids = $wpdb->get_col($query);
1484
+		// delete each post meta and term relations too
1485
+		foreach ($cpt_ids as $post_id) {
1486
+			wp_delete_post($post_id, true);
1487
+		}
1488
+	}
1489
+
1490
+	/**
1491
+	 * Deletes all EE custom tables
1492
+	 *
1493
+	 * @return array
1494
+	 */
1495
+	public static function drop_espresso_tables()
1496
+	{
1497
+		$tables = array();
1498
+		// load registry
1499
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1500
+			if (method_exists($model_name, 'instance')) {
1501
+				$model_obj = call_user_func(array($model_name, 'instance'));
1502
+				if ($model_obj instanceof EEM_Base) {
1503
+					foreach ($model_obj->get_tables() as $table) {
1504
+						if (
1505
+							strpos($table->get_table_name(), 'esp_')
1506
+							&&
1507
+							(
1508
+								is_main_site()// main site? nuke them all
1509
+								|| ! $table->is_global()// not main site,but not global either. nuke it
1510
+							)
1511
+						) {
1512
+							$tables[ $table->get_table_name() ] = $table->get_table_name();
1513
+						}
1514
+					}
1515
+				}
1516
+			}
1517
+		}
1518
+
1519
+		// there are some tables whose models were removed.
1520
+		// they should be removed when removing all EE core's data
1521
+		$tables_without_models = array(
1522
+			'esp_promotion',
1523
+			'esp_promotion_applied',
1524
+			'esp_promotion_object',
1525
+			'esp_promotion_rule',
1526
+			'esp_rule',
1527
+		);
1528
+		foreach ($tables_without_models as $table) {
1529
+			$tables[ $table ] = $table;
1530
+		}
1531
+		return \EEH_Activation::getTableManager()->dropTables($tables);
1532
+	}
1533
+
1534
+
1535
+
1536
+	/**
1537
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1538
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1539
+	 * Returns the list actually deleted
1540
+	 *
1541
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1542
+	 * @global WPDB $wpdb
1543
+	 * @param array $table_names
1544
+	 * @return array of table names which we deleted
1545
+	 */
1546
+	public static function drop_tables($table_names)
1547
+	{
1548
+		return \EEH_Activation::getTableManager()->dropTables($table_names);
1549
+	}
1550
+
1551
+
1552
+
1553
+	/**
1554
+	 * plugin_uninstall
1555
+	 *
1556
+	 * @access public
1557
+	 * @static
1558
+	 * @param bool $remove_all
1559
+	 * @return void
1560
+	 */
1561
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1562
+	{
1563
+		global $wpdb;
1564
+		self::drop_espresso_tables();
1565
+		$wp_options_to_delete = array(
1566
+			'ee_no_ticket_prices'                => true,
1567
+			'ee_active_messengers'               => true,
1568
+			'ee_has_activated_messenger'         => true,
1569
+			RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1570
+			'ee_config'                          => false,
1571
+			'ee_data_migration_current_db_state' => true,
1572
+			'ee_data_migration_mapping_'         => false,
1573
+			'ee_data_migration_script_'          => false,
1574
+			'ee_data_migrations'                 => true,
1575
+			'ee_dms_map'                         => false,
1576
+			'ee_notices'                         => true,
1577
+			'lang_file_check_'                   => false,
1578
+			'ee_maintenance_mode'                => true,
1579
+			'ee_ueip_optin'                      => true,
1580
+			'ee_ueip_has_notified'               => true,
1581
+			'ee_plugin_activation_errors'        => true,
1582
+			'ee_id_mapping_from'                 => false,
1583
+			'espresso_persistent_admin_notices'  => true,
1584
+			'ee_encryption_key'                  => true,
1585
+			'pue_force_upgrade_'                 => false,
1586
+			'pue_json_error_'                    => false,
1587
+			'pue_install_key_'                   => false,
1588
+			'pue_verification_error_'            => false,
1589
+			'pu_dismissed_upgrade_'              => false,
1590
+			'external_updates-'                  => false,
1591
+			'ee_extra_data'                      => true,
1592
+			'ee_ssn_'                            => false,
1593
+			'ee_rss_'                            => false,
1594
+			'ee_rte_n_tx_'                       => false,
1595
+			'ee_pers_admin_notices'              => true,
1596
+			'ee_job_parameters_'                 => false,
1597
+			'ee_upload_directories_incomplete'   => true,
1598
+			'ee_verified_db_collations'          => true,
1599
+		);
1600
+		if (is_main_site()) {
1601
+			$wp_options_to_delete['ee_network_config'] = true;
1602
+		}
1603
+		$undeleted_options = array();
1604
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1605
+			if ($no_wildcard) {
1606
+				if (! delete_option($option_name)) {
1607
+					$undeleted_options[] = $option_name;
1608
+				}
1609
+			} else {
1610
+				$option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1611
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1612
+					if (! delete_option($option_name_from_wildcard)) {
1613
+						$undeleted_options[] = $option_name_from_wildcard;
1614
+					}
1615
+				}
1616
+			}
1617
+		}
1618
+		// also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1619
+		remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1620
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1621
+			$db_update_sans_ee4 = array();
1622
+			foreach ($espresso_db_update as $version => $times_activated) {
1623
+				if ((string) $version[0] === '3') {// if its NON EE4
1624
+					$db_update_sans_ee4[ $version ] = $times_activated;
1625
+				}
1626
+			}
1627
+			update_option('espresso_db_update', $db_update_sans_ee4);
1628
+		}
1629
+		$errors = '';
1630
+		if (! empty($undeleted_options)) {
1631
+			$errors .= sprintf(
1632
+				__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1633
+				'<br/>',
1634
+				implode(',<br/>', $undeleted_options)
1635
+			);
1636
+		}
1637
+		if (! empty($errors)) {
1638
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1639
+		}
1640
+	}
1641
+
1642
+	/**
1643
+	 * Gets the mysql error code from the last used query by wpdb
1644
+	 *
1645
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1646
+	 */
1647
+	public static function last_wpdb_error_code()
1648
+	{
1649
+		global $wpdb;
1650
+		return $wpdb->use_mysqli ? mysqli_errno($wpdb->dbh) : 0;
1651
+	}
1652
+
1653
+	/**
1654
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1655
+	 *
1656
+	 * @global wpdb  $wpdb
1657
+	 * @deprecated instead use TableAnalysis::tableExists()
1658
+	 * @param string $table_name with or without $wpdb->prefix
1659
+	 * @return boolean
1660
+	 */
1661
+	public static function table_exists($table_name)
1662
+	{
1663
+		return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1664
+	}
1665
+
1666
+	/**
1667
+	 * Resets the cache on EEH_Activation
1668
+	 */
1669
+	public static function reset()
1670
+	{
1671
+		self::$_default_creator_id                             = null;
1672
+		self::$_initialized_db_content_already_in_this_request = false;
1673
+	}
1674
+
1675
+	/**
1676
+	 * Removes 'email_confirm' from the Address info question group on activation
1677
+	 * @return void
1678
+	 */
1679
+	public static function removeEmailConfirmFromAddressGroup()
1680
+	{
1681
+
1682
+		// Pull the email_confirm question ID.
1683
+		$email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1684
+			EEM_Attendee::system_question_email_confirm
1685
+		);
1686
+		// Remove the email_confirm question group from the address group questions.
1687
+		EEM_Question_Group_Question::instance()->delete(
1688
+			array(
1689
+				array(
1690
+					'QST_ID' => $email_confirm_question_id,
1691
+					'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1692
+				),
1693
+			)
1694
+		);
1695
+	}
1696 1696
 }
Please login to merge, or discard this patch.
core/EE_System.core.php 1 patch
Indentation   +1162 added lines, -1162 removed lines patch added patch discarded remove patch
@@ -25,1166 +25,1166 @@
 block discarded – undo
25 25
 final class EE_System implements ResettableInterface
26 26
 {
27 27
 
28
-    /**
29
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
30
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
31
-     */
32
-    const req_type_normal = 0;
33
-
34
-    /**
35
-     * Indicates this is a brand new installation of EE so we should install
36
-     * tables and default data etc
37
-     */
38
-    const req_type_new_activation = 1;
39
-
40
-    /**
41
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
42
-     * and we just exited maintenance mode). We MUST check the database is setup properly
43
-     * and that default data is setup too
44
-     */
45
-    const req_type_reactivation = 2;
46
-
47
-    /**
48
-     * indicates that EE has been upgraded since its previous request.
49
-     * We may have data migration scripts to call and will want to trigger maintenance mode
50
-     */
51
-    const req_type_upgrade = 3;
52
-
53
-    /**
54
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
55
-     */
56
-    const req_type_downgrade = 4;
57
-
58
-    /**
59
-     * @deprecated since version 4.6.0.dev.006
60
-     * Now whenever a new_activation is detected the request type is still just
61
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
62
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
63
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
64
-     * (Specifically, when the migration manager indicates migrations are finished
65
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
66
-     */
67
-    const req_type_activation_but_not_installed = 5;
68
-
69
-    /**
70
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
71
-     */
72
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
73
-
74
-    /**
75
-     * @var AddonManager $addon_manager
76
-     */
77
-    private $addon_manager;
78
-
79
-    /**
80
-     * @var EE_System $_instance
81
-     */
82
-    private static $_instance;
83
-
84
-    /**
85
-     * @var EE_Registry $registry
86
-     */
87
-    private $registry;
88
-
89
-    /**
90
-     * @var LoaderInterface $loader
91
-     */
92
-    private $loader;
93
-
94
-    /**
95
-     * @var EE_Capabilities $capabilities
96
-     */
97
-    private $capabilities;
98
-
99
-    /**
100
-     * @var EE_Maintenance_Mode $maintenance_mode
101
-     */
102
-    private $maintenance_mode;
103
-
104
-    /**
105
-     * @var RequestInterface $request
106
-     */
107
-    private $request;
108
-
109
-    /**
110
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
111
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
112
-     *
113
-     * @var int $_req_type
114
-     */
115
-    private $_req_type;
116
-
117
-    /**
118
-     * Whether or not there was a non-micro version change in EE core version during this request
119
-     *
120
-     * @var boolean $_major_version_change
121
-     */
122
-    private $_major_version_change = false;
123
-
124
-    /**
125
-     * @var Router $router
126
-     */
127
-    private $router;
128
-
129
-
130
-    /**
131
-     * @singleton method used to instantiate class object
132
-     * @param LoaderInterface|null     $loader
133
-     * @param EE_Maintenance_Mode|null $maintenance_mode
134
-     * @param EE_Registry|null         $registry
135
-     * @param RequestInterface|null    $request
136
-     * @param Router|null              $router
137
-     * @return EE_System
138
-     */
139
-    public static function instance(
140
-        LoaderInterface $loader = null,
141
-        EE_Maintenance_Mode $maintenance_mode = null,
142
-        EE_Registry $registry = null,
143
-        RequestInterface $request = null,
144
-        Router $router = null
145
-    ): EE_System {
146
-        // check if class object is instantiated
147
-        if (! self::$_instance instanceof EE_System) {
148
-            self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
149
-        }
150
-        return self::$_instance;
151
-    }
152
-
153
-
154
-    /**
155
-     * resets the instance and returns it
156
-     *
157
-     * @return EE_System
158
-     */
159
-    public static function reset(): EE_System
160
-    {
161
-        self::$_instance->_req_type = null;
162
-        // make sure none of the old hooks are left hanging around
163
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
164
-        // we need to reset the migration manager in order for it to detect DMSs properly
165
-        EE_Data_Migration_Manager::reset();
166
-        self::instance()->detect_activations_or_upgrades();
167
-        self::instance()->perform_activations_upgrades_and_migrations();
168
-        return self::instance();
169
-    }
170
-
171
-
172
-    /**
173
-     * sets hooks for running rest of system
174
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
175
-     * starting EE Addons from any other point may lead to problems
176
-     *
177
-     * @param LoaderInterface     $loader
178
-     * @param EE_Maintenance_Mode $maintenance_mode
179
-     * @param EE_Registry         $registry
180
-     * @param RequestInterface    $request
181
-     * @param Router              $router
182
-     */
183
-    private function __construct(
184
-        LoaderInterface $loader,
185
-        EE_Maintenance_Mode $maintenance_mode,
186
-        EE_Registry $registry,
187
-        RequestInterface $request,
188
-        Router $router
189
-    ) {
190
-        $this->registry         = $registry;
191
-        $this->loader           = $loader;
192
-        $this->request          = $request;
193
-        $this->router           = $router;
194
-        $this->maintenance_mode = $maintenance_mode;
195
-        do_action('AHEE__EE_System__construct__begin', $this);
196
-        add_action(
197
-            'AHEE__EE_Bootstrap__load_espresso_addons',
198
-            [$this, 'loadCapabilities'],
199
-            5
200
-        );
201
-        add_action(
202
-            'AHEE__EE_Bootstrap__load_espresso_addons',
203
-            [$this, 'loadCommandBus'],
204
-            7
205
-        );
206
-        add_action(
207
-            'AHEE__EE_Bootstrap__load_espresso_addons',
208
-            [$this, 'loadPluginApi'],
209
-            9
210
-        );
211
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
212
-        add_action(
213
-            'AHEE__EE_Bootstrap__load_espresso_addons',
214
-            [$this, 'load_espresso_addons']
215
-        );
216
-        // when an ee addon is activated, we want to call the core hook(s) again
217
-        // because the newly-activated addon didn't get a chance to run at all
218
-        add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
219
-        // detect whether install or upgrade
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
222
-            [$this, 'detect_activations_or_upgrades'],
223
-            3
224
-        );
225
-        // load EE_Config, EE_Textdomain, etc
226
-        add_action(
227
-            'AHEE__EE_Bootstrap__load_core_configuration',
228
-            [$this, 'load_core_configuration'],
229
-            5
230
-        );
231
-        // load specifications for matching routes to current request
232
-        add_action(
233
-            'AHEE__EE_Bootstrap__load_core_configuration',
234
-            [$this, 'loadRouteMatchSpecifications']
235
-        );
236
-        // load EE_Config, EE_Textdomain, etc
237
-        add_action(
238
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
239
-            [$this, 'register_shortcodes_modules_and_widgets'],
240
-            7
241
-        );
242
-        // you wanna get going? I wanna get going... let's get going!
243
-        add_action(
244
-            'AHEE__EE_Bootstrap__brew_espresso',
245
-            [$this, 'brew_espresso'],
246
-            9
247
-        );
248
-        // other housekeeping
249
-        // exclude EE critical pages from wp_list_pages
250
-        add_filter(
251
-            'wp_list_pages_excludes',
252
-            [$this, 'remove_pages_from_wp_list_pages'],
253
-            10
254
-        );
255
-        // ALL EE Addons should use the following hook point to attach their initial setup too
256
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
257
-        do_action('AHEE__EE_System__construct__complete', $this);
258
-    }
259
-
260
-
261
-    /**
262
-     * load and setup EE_Capabilities
263
-     *
264
-     * @return void
265
-     */
266
-    public function loadCapabilities()
267
-    {
268
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
269
-        add_action(
270
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
271
-            function () {
272
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273
-            }
274
-        );
275
-    }
276
-
277
-
278
-    /**
279
-     * create and cache the CommandBus, and also add middleware
280
-     * The CapChecker middleware requires the use of EE_Capabilities
281
-     * which is why we need to load the CommandBus after Caps are set up
282
-     *
283
-     * @return void
284
-     */
285
-    public function loadCommandBus()
286
-    {
287
-        $this->loader->getShared(
288
-            'CommandBusInterface',
289
-            [
290
-                null,
291
-                apply_filters(
292
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
293
-                    [
294
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
295
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
296
-                    ]
297
-                ),
298
-            ]
299
-        );
300
-    }
301
-
302
-
303
-    /**
304
-     * @return void
305
-     * @throws Exception
306
-     */
307
-    public function loadPluginApi()
308
-    {
309
-        $this->addon_manager = $this->loader->getShared(AddonManager::class);
310
-        $this->addon_manager->initialize();
311
-        $this->loader->getShared('EE_Request_Handler');
312
-    }
313
-
314
-
315
-    /**
316
-     * load_espresso_addons
317
-     * allow addons to load first so that they can set hooks for running DMS's, etc
318
-     * this is hooked into both:
319
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
320
-     *        which runs during the WP 'plugins_loaded' action at priority 5
321
-     *    and the WP 'activate_plugin' hook point
322
-     *
323
-     * @return void
324
-     * @throws Exception
325
-     */
326
-    public function load_espresso_addons()
327
-    {
328
-        // looking for hooks? they've been moved into the AddonManager to maintain compatibility
329
-        $this->addon_manager->loadAddons();
330
-    }
331
-
332
-
333
-    /**
334
-     * detect_activations_or_upgrades
335
-     * Checks for activation or upgrade of core first;
336
-     * then also checks if any registered addons have been activated or upgraded
337
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
338
-     * which runs during the WP 'plugins_loaded' action at priority 3
339
-     *
340
-     * @access public
341
-     * @return void
342
-     */
343
-    public function detect_activations_or_upgrades()
344
-    {
345
-        // first off: let's make sure to handle core
346
-        $this->detect_if_activation_or_upgrade();
347
-        foreach ($this->registry->addons as $addon) {
348
-            if ($addon instanceof EE_Addon) {
349
-                // detect teh request type for that addon
350
-                $addon->detect_req_type();
351
-            }
352
-        }
353
-    }
354
-
355
-
356
-    /**
357
-     * detect_if_activation_or_upgrade
358
-     * Takes care of detecting whether this is a brand new install or code upgrade,
359
-     * and either setting up the DB or setting up maintenance mode etc.
360
-     *
361
-     * @access public
362
-     * @return void
363
-     */
364
-    public function detect_if_activation_or_upgrade()
365
-    {
366
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
367
-        // check if db has been updated, or if its a brand-new installation
368
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
369
-        $request_type       = $this->detect_req_type($espresso_db_update);
370
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
371
-        switch ($request_type) {
372
-            case EE_System::req_type_new_activation:
373
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
374
-                $this->_handle_core_version_change($espresso_db_update);
375
-                break;
376
-            case EE_System::req_type_reactivation:
377
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
378
-                $this->_handle_core_version_change($espresso_db_update);
379
-                break;
380
-            case EE_System::req_type_upgrade:
381
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
382
-                // migrations may be required now that we've upgraded
383
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
384
-                $this->_handle_core_version_change($espresso_db_update);
385
-                break;
386
-            case EE_System::req_type_downgrade:
387
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
388
-                // its possible migrations are no longer required
389
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
390
-                $this->_handle_core_version_change($espresso_db_update);
391
-                break;
392
-            case EE_System::req_type_normal:
393
-            default:
394
-                break;
395
-        }
396
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
397
-    }
398
-
399
-
400
-    /**
401
-     * Updates the list of installed versions and sets hooks for
402
-     * initializing the database later during the request
403
-     *
404
-     * @param array $espresso_db_update
405
-     */
406
-    private function _handle_core_version_change(array $espresso_db_update)
407
-    {
408
-        $this->update_list_of_installed_versions($espresso_db_update);
409
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
410
-        add_action(
411
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
412
-            [$this, 'initialize_db_if_no_migrations_required']
413
-        );
414
-    }
415
-
416
-
417
-    /**
418
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
419
-     * information about what versions of EE have been installed and activated,
420
-     * NOT necessarily the state of the database
421
-     *
422
-     * @param mixed $espresso_db_update           the value of the WordPress option.
423
-     *                                            If not supplied, fetches it from the options table
424
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
425
-     */
426
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
427
-    {
428
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
429
-        if (! $espresso_db_update) {
430
-            $espresso_db_update = get_option('espresso_db_update');
431
-        }
432
-        // check that option is an array
433
-        if (! is_array($espresso_db_update)) {
434
-            // if option is FALSE, then it never existed
435
-            if ($espresso_db_update === false) {
436
-                // make $espresso_db_update an array and save option with autoload OFF
437
-                $espresso_db_update = [];
438
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
439
-            } else {
440
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
441
-                $espresso_db_update = [$espresso_db_update => []];
442
-                update_option('espresso_db_update', $espresso_db_update);
443
-            }
444
-        } else {
445
-            $corrected_db_update = [];
446
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
447
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
448
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
449
-                    // the key is an int, and the value IS NOT an array
450
-                    // so it must be numerically-indexed, where values are versions installed...
451
-                    // fix it!
452
-                    $version_string                         = $should_be_array;
453
-                    $corrected_db_update[ $version_string ] = ['unknown-date'];
454
-                } else {
455
-                    // ok it checks out
456
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
457
-                }
458
-            }
459
-            $espresso_db_update = $corrected_db_update;
460
-            update_option('espresso_db_update', $espresso_db_update);
461
-        }
462
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
463
-        return ! empty($espresso_db_update) ? $espresso_db_update : [];
464
-    }
465
-
466
-
467
-    /**
468
-     * Does the traditional work of setting up the plugin's database and adding default data.
469
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
470
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
471
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
472
-     * so that it will be done when migrations are finished
473
-     *
474
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
475
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
476
-     *                                       This is a resource-intensive job
477
-     *                                       so we prefer to only do it when necessary
478
-     * @return void
479
-     * @throws EE_Error
480
-     * @throws ReflectionException
481
-     */
482
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
483
-    {
484
-        $request_type = $this->detect_req_type();
485
-        // only initialize system if we're not in maintenance mode.
486
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
487
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
488
-            $rewrite_rules = $this->loader->getShared(
489
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
490
-            );
491
-            $rewrite_rules->flush();
492
-            if ($verify_schema) {
493
-                EEH_Activation::initialize_db_and_folders();
494
-            }
495
-            EEH_Activation::initialize_db_content();
496
-            EEH_Activation::system_initialization();
497
-            if ($initialize_addons_too) {
498
-                $this->initialize_addons();
499
-            }
500
-        } else {
501
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
502
-        }
503
-        if (
504
-            $request_type === EE_System::req_type_new_activation
505
-            || $request_type === EE_System::req_type_reactivation
506
-            || (
507
-                $request_type === EE_System::req_type_upgrade
508
-                && $this->is_major_version_change()
509
-            )
510
-        ) {
511
-            add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
512
-        }
513
-    }
514
-
515
-
516
-    /**
517
-     * Initializes the db for all registered addons
518
-     *
519
-     * @throws EE_Error
520
-     * @throws ReflectionException
521
-     */
522
-    public function initialize_addons()
523
-    {
524
-        // foreach registered addon, make sure its db is up-to-date too
525
-        foreach ($this->registry->addons as $addon) {
526
-            if ($addon instanceof EE_Addon) {
527
-                $addon->initialize_db_if_no_migrations_required();
528
-            }
529
-        }
530
-    }
531
-
532
-
533
-    /**
534
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
535
-     *
536
-     * @param array  $version_history
537
-     * @param string $current_version_to_add version to be added to the version history
538
-     * @return    boolean success as to whether or not this option was changed
539
-     */
540
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
541
-    {
542
-        if (! $version_history) {
543
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
544
-        }
545
-        if ($current_version_to_add === null) {
546
-            $current_version_to_add = espresso_version();
547
-        }
548
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
549
-        // re-save
550
-        return update_option('espresso_db_update', $version_history);
551
-    }
552
-
553
-
554
-    /**
555
-     * Detects if the current version indicated in the has existed in the list of
556
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
557
-     *
558
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
559
-     *                                  If not supplied, fetches it from the options table.
560
-     *                                  Also, caches its result so later parts of the code can also know whether
561
-     *                                  there's been an update or not. This way we can add the current version to
562
-     *                                  espresso_db_update, but still know if this is a new install or not
563
-     * @return int one of the constants on EE_System::req_type_
564
-     */
565
-    public function detect_req_type($espresso_db_update = null): int
566
-    {
567
-        if ($this->_req_type === null) {
568
-            $espresso_db_update          = ! empty($espresso_db_update)
569
-                ? $espresso_db_update
570
-                : $this->fix_espresso_db_upgrade_option();
571
-            $this->_req_type             = EE_System::detect_req_type_given_activation_history(
572
-                $espresso_db_update,
573
-                'ee_espresso_activation',
574
-                espresso_version()
575
-            );
576
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
577
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
578
-        }
579
-        return $this->_req_type;
580
-    }
581
-
582
-
583
-    /**
584
-     * Returns whether or not there was a non-micro version change (ie, change in either
585
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
586
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
587
-     *
588
-     * @param $activation_history
589
-     * @return bool
590
-     */
591
-    private function _detect_major_version_change($activation_history): bool
592
-    {
593
-        $previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
594
-        $previous_version_parts = explode('.', $previous_version);
595
-        $current_version_parts  = explode('.', espresso_version());
596
-        return isset(
597
-            $previous_version_parts[0],
598
-            $previous_version_parts[1],
599
-            $current_version_parts[0],
600
-            $current_version_parts[1]
601
-        ) && (
602
-            $previous_version_parts[0] !== $current_version_parts[0]
603
-            || $previous_version_parts[1] !== $current_version_parts[1]
604
-        );
605
-    }
606
-
607
-
608
-    /**
609
-     * Returns true if either the major or minor version of EE changed during this request.
610
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
611
-     *
612
-     * @return bool
613
-     */
614
-    public function is_major_version_change(): bool
615
-    {
616
-        return $this->_major_version_change;
617
-    }
618
-
619
-
620
-    /**
621
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
622
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
623
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
624
-     * just activated to (for core that will always be espresso_version())
625
-     *
626
-     * @param array|null $activation_history             the option's value which stores the activation history for
627
-     *                                                 this
628
-     *                                                 ee plugin. for core that's 'espresso_db_update'
629
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
630
-     *                                                 indicate that this plugin was just activated
631
-     * @param string $current_version                  the version that was just upgraded to (for core that will be
632
-     *                                                 espresso_version())
633
-     * @return int one of the constants on EE_System::req_type_
634
-     */
635
-    public static function detect_req_type_given_activation_history(
636
-        array $activation_history,
637
-        string $activation_indicator_option_name,
638
-        string $current_version
639
-    ): int {
640
-        $version_change = self::compareVersionWithPrevious($activation_history, $current_version);
641
-        $is_activation  = get_option($activation_indicator_option_name, false);
642
-        $req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
643
-        if ($is_activation) {
644
-            // cleanup in aisle 6
645
-            delete_option($activation_indicator_option_name);
646
-        }
647
-        return $req_type;
648
-    }
649
-
650
-
651
-    /**
652
-     * @param array  $activation_history
653
-     * @param int    $version_change
654
-     * @param bool   $is_activation
655
-     * @return int
656
-     * @since $VID:$
657
-     */
658
-    private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
659
-    {
660
-        // if no previous activation history exists, then this is a brand new install
661
-        if (empty($activation_history)) {
662
-            return EE_System::req_type_new_activation;
663
-        }
664
-        // current version is higher than previous version, so it's an upgrade
665
-        if ($version_change === 1) {
666
-            return EE_System::req_type_upgrade;
667
-        }
668
-        // current version is lower than previous version, so it's a downgrade
669
-        if ($version_change === -1) {
670
-            return EE_System::req_type_downgrade;
671
-        }
672
-        // version hasn't changed since last version so check if the activation indicator is set
673
-        // to determine if it's a reactivation, or just a normal request
674
-        return $is_activation
675
-            ? EE_System::req_type_reactivation
676
-            : EE_System::req_type_normal;
677
-    }
678
-
679
-
680
-    /**
681
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
682
-     * the $activation_history_for_addon
683
-     *
684
-     * @param array  $activation_history    array where keys are versions,
685
-     *                                      values are arrays of times activated (sometimes 'unknown-date')
686
-     * @param string $current_version
687
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
688
-     *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
689
-     *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
690
-     *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
691
-     */
692
-    private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
693
-    {
694
-        // find the most recently-activated version
695
-        $most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
696
-        return version_compare($current_version, $most_recently_active_version);
697
-    }
698
-
699
-
700
-    /**
701
-     * Gets the most recently active version listed in the activation history,
702
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
703
-     *
704
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
705
-     *                                   sometimes containing 'unknown-date'
706
-     * @return string
707
-     */
708
-    private static function getMostRecentlyActiveVersion(array $activation_history): string
709
-    {
710
-        $most_recent_activation_date  = '1970-01-01 00:00:00';
711
-        $most_recently_active_version = '0.0.0.dev.000';
712
-        if (is_array($activation_history)) {
713
-            foreach ($activation_history as $version => $activation_dates) {
714
-                // check there is a record of when this version was activated.
715
-                // Otherwise, mark it as unknown
716
-                if (! $activation_dates) {
717
-                    $activation_dates = ['unknown-date'];
718
-                }
719
-                $activation_dates = is_string($activation_dates) ? [$activation_dates] : $activation_dates;
720
-                foreach ($activation_dates as $activation_date) {
721
-                    if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
722
-                        $most_recently_active_version = $version;
723
-                        $most_recent_activation_date  = $activation_date;
724
-                    }
725
-                }
726
-            }
727
-        }
728
-        return $most_recently_active_version;
729
-    }
730
-
731
-
732
-    /**
733
-     * This redirects to the about EE page after activation
734
-     *
735
-     * @return void
736
-     */
737
-    public function redirect_to_about_ee()
738
-    {
739
-        $notices = EE_Error::get_notices(false);
740
-        // if current user is an admin and it's not an ajax or rest request
741
-        if (
742
-            ! isset($notices['errors'])
743
-            && $this->request->isAdmin()
744
-            && apply_filters(
745
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
746
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
747
-            )
748
-        ) {
749
-            $query_params = ['page' => 'espresso_about'];
750
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
751
-                $query_params['new_activation'] = true;
752
-            }
753
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
754
-                $query_params['reactivation'] = true;
755
-            }
756
-            $url = add_query_arg($query_params, admin_url('admin.php'));
757
-            EEH_URL::safeRedirectAndExit($url);
758
-        }
759
-    }
760
-
761
-
762
-    /**
763
-     * load_core_configuration
764
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
765
-     * which runs during the WP 'plugins_loaded' action at priority 5
766
-     *
767
-     * @return void
768
-     * @throws ReflectionException
769
-     * @throws Exception
770
-     */
771
-    public function load_core_configuration()
772
-    {
773
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
774
-        $this->loader->getShared('EE_Load_Textdomain');
775
-        // load textdomain
776
-        EE_Load_Textdomain::load_textdomain();
777
-        // load caf stuff a chance to play during the activation process too.
778
-        $this->_maybe_brew_regular();
779
-        // load and setup EE_Config and EE_Network_Config
780
-        $config = $this->loader->getShared('EE_Config');
781
-        $this->loader->getShared('EE_Network_Config');
782
-        // setup autoloaders
783
-        // enable logging?
784
-        if ($config->admin->use_remote_logging) {
785
-            $this->loader->getShared('EE_Log');
786
-        }
787
-        // check for activation errors
788
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
789
-        if ($activation_errors) {
790
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
791
-            update_option('ee_plugin_activation_errors', false);
792
-        }
793
-        // get model names
794
-        $this->_parse_model_names();
795
-        // configure custom post type definitions
796
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
797
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
798
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
799
-    }
800
-
801
-
802
-    /**
803
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
804
-     *
805
-     * @return void
806
-     * @throws ReflectionException
807
-     */
808
-    private function _parse_model_names()
809
-    {
810
-        // get all the files in the EE_MODELS folder that end in .model.php
811
-        $models                 = glob(EE_MODELS . '*.model.php');
812
-        $model_names            = [];
813
-        $non_abstract_db_models = [];
814
-        foreach ($models as $model) {
815
-            // get model classname
816
-            $classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
817
-            $short_name      = str_replace('EEM_', '', $classname);
818
-            $reflectionClass = new ReflectionClass($classname);
819
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
820
-                $non_abstract_db_models[ $short_name ] = $classname;
821
-            }
822
-            $model_names[ $short_name ] = $classname;
823
-        }
824
-        $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
825
-        $this->registry->non_abstract_db_models = apply_filters(
826
-            'FHEE__EE_System__parse_implemented_model_names',
827
-            $non_abstract_db_models
828
-        );
829
-    }
830
-
831
-
832
-    /**
833
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
834
-     * that need to be setup before our EE_System launches.
835
-     *
836
-     * @return void
837
-     * @throws DomainException
838
-     * @throws InvalidArgumentException
839
-     * @throws InvalidDataTypeException
840
-     * @throws InvalidInterfaceException
841
-     * @throws InvalidClassException
842
-     * @throws InvalidFilePathException
843
-     */
844
-    private function _maybe_brew_regular()
845
-    {
846
-        /** @var Domain $domain */
847
-        $domain = DomainFactory::getEventEspressoCoreDomain();
848
-        if ($domain->isCaffeinated()) {
849
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
850
-        }
851
-    }
852
-
853
-
854
-    /**
855
-     * @throws Exception
856
-     * @since 4.9.71.p
857
-     */
858
-    public function loadRouteMatchSpecifications()
859
-    {
860
-        try {
861
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
862
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
863
-            $this->router->loadPrimaryRoutes();
864
-        } catch (Exception $exception) {
865
-            new ExceptionStackTraceDisplay($exception);
866
-        }
867
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
868
-    }
869
-
870
-
871
-    /**
872
-     * register_shortcodes_modules_and_widgets
873
-     * generate lists of shortcodes and modules, then verify paths and classes
874
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
875
-     * which runs during the WP 'plugins_loaded' action at priority 7
876
-     *
877
-     * @access public
878
-     * @return void
879
-     * @throws Exception
880
-     */
881
-    public function register_shortcodes_modules_and_widgets()
882
-    {
883
-        $this->router->registerShortcodesModulesAndWidgets();
884
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
885
-        // check for addons using old hook point
886
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
887
-            $this->_incompatible_addon_error();
888
-        }
889
-    }
890
-
891
-
892
-    /**
893
-     * _incompatible_addon_error
894
-     *
895
-     * @access public
896
-     * @return void
897
-     */
898
-    private function _incompatible_addon_error()
899
-    {
900
-        // get array of classes hooking into here
901
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
902
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
903
-        );
904
-        if (! empty($class_names)) {
905
-            $msg = __(
906
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
907
-                'event_espresso'
908
-            );
909
-            $msg .= '<ul>';
910
-            foreach ($class_names as $class_name) {
911
-                $msg .= '<li><b>Event Espresso - '
912
-                        . str_replace(
913
-                            ['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
914
-                            '',
915
-                            $class_name
916
-                        ) . '</b></li>';
917
-            }
918
-            $msg .= '</ul>';
919
-            $msg .= __(
920
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
921
-                'event_espresso'
922
-            );
923
-            // save list of incompatible addons to wp-options for later use
924
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
925
-            if (is_admin()) {
926
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
927
-            }
928
-        }
929
-    }
930
-
931
-
932
-    /**
933
-     * brew_espresso
934
-     * begins the process of setting hooks for initializing EE in the correct order
935
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
936
-     * which runs during the WP 'plugins_loaded' action at priority 9
937
-     *
938
-     * @return void
939
-     * @throws Exception
940
-     */
941
-    public function brew_espresso()
942
-    {
943
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
944
-        // load some final core systems
945
-        add_action('init', [$this, 'set_hooks_for_core'], 1);
946
-        add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
947
-        add_action('init', [$this, 'load_CPTs_and_session'], 5);
948
-        add_action('init', [$this, 'load_controllers'], 7);
949
-        add_action('init', [$this, 'core_loaded_and_ready'], 9);
950
-        add_action('init', [$this, 'initialize'], 10);
951
-        add_action('init', [$this, 'initialize_last'], 100);
952
-        $this->router->brewEspresso();
953
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
954
-    }
955
-
956
-
957
-    /**
958
-     *    set_hooks_for_core
959
-     *
960
-     * @access public
961
-     * @return    void
962
-     * @throws EE_Error
963
-     */
964
-    public function set_hooks_for_core()
965
-    {
966
-        $this->_deactivate_incompatible_addons();
967
-        do_action('AHEE__EE_System__set_hooks_for_core');
968
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
969
-        // caps need to be initialized on every request so that capability maps are set.
970
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
971
-        $this->registry->CAP->init_caps();
972
-    }
973
-
974
-
975
-    /**
976
-     * Using the information gathered in EE_System::_incompatible_addon_error,
977
-     * deactivates any addons considered incompatible with the current version of EE
978
-     */
979
-    private function _deactivate_incompatible_addons()
980
-    {
981
-        $incompatible_addons = get_option('ee_incompatible_addons', []);
982
-        if (! empty($incompatible_addons)) {
983
-            $active_plugins = get_option('active_plugins', []);
984
-            foreach ($active_plugins as $active_plugin) {
985
-                foreach ($incompatible_addons as $incompatible_addon) {
986
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
987
-                        unset($_GET['activate']);
988
-                        espresso_deactivate_plugin($active_plugin);
989
-                    }
990
-                }
991
-            }
992
-        }
993
-    }
994
-
995
-
996
-    /**
997
-     *    perform_activations_upgrades_and_migrations
998
-     *
999
-     * @access public
1000
-     * @return    void
1001
-     */
1002
-    public function perform_activations_upgrades_and_migrations()
1003
-    {
1004
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1005
-    }
1006
-
1007
-
1008
-    /**
1009
-     * @return void
1010
-     * @throws DomainException
1011
-     */
1012
-    public function load_CPTs_and_session()
1013
-    {
1014
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1015
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1016
-        $register_custom_taxonomies = $this->loader->getShared(
1017
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1018
-        );
1019
-        $register_custom_taxonomies->registerCustomTaxonomies();
1020
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1021
-        $register_custom_post_types = $this->loader->getShared(
1022
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1023
-        );
1024
-        $register_custom_post_types->registerCustomPostTypes();
1025
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1026
-        $register_custom_taxonomy_terms = $this->loader->getShared(
1027
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1028
-        );
1029
-        $register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1030
-        // load legacy Custom Post Types and Taxonomies
1031
-        $this->loader->getShared('EE_Register_CPTs');
1032
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1033
-    }
1034
-
1035
-
1036
-    /**
1037
-     * load_controllers
1038
-     * this is the best place to load any additional controllers that needs access to EE core.
1039
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1040
-     * time
1041
-     *
1042
-     * @access public
1043
-     * @return void
1044
-     * @throws Exception
1045
-     */
1046
-    public function load_controllers()
1047
-    {
1048
-        do_action('AHEE__EE_System__load_controllers__start');
1049
-        $this->router->loadControllers();
1050
-        do_action('AHEE__EE_System__load_controllers__complete');
1051
-    }
1052
-
1053
-
1054
-    /**
1055
-     * core_loaded_and_ready
1056
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1057
-     *
1058
-     * @access public
1059
-     * @return void
1060
-     * @throws Exception
1061
-     */
1062
-    public function core_loaded_and_ready()
1063
-    {
1064
-        $this->router->coreLoadedAndReady();
1065
-        // integrate WP_Query with the EE models
1066
-        $this->loader->getShared('EE_CPT_Strategy');
1067
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1068
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1069
-        // builders require these even on the front-end
1070
-        require_once EE_PUBLIC . 'template_tags.php';
1071
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1072
-    }
1073
-
1074
-
1075
-    /**
1076
-     * initialize
1077
-     * this is the best place to begin initializing client code
1078
-     *
1079
-     * @access public
1080
-     * @return void
1081
-     */
1082
-    public function initialize()
1083
-    {
1084
-        do_action('AHEE__EE_System__initialize');
1085
-    }
1086
-
1087
-
1088
-    /**
1089
-     * initialize_last
1090
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1091
-     * initialize has done so
1092
-     *
1093
-     * @access public
1094
-     * @return void
1095
-     * @throws Exception
1096
-     */
1097
-    public function initialize_last()
1098
-    {
1099
-        do_action('AHEE__EE_System__initialize_last');
1100
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1101
-        $rewrite_rules = $this->loader->getShared(
1102
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1103
-        );
1104
-        $rewrite_rules->flushRewriteRules();
1105
-        $this->router->initializeLast();
1106
-        add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1107
-    }
1108
-
1109
-
1110
-    /**
1111
-     * @return void
1112
-     */
1113
-    public function addEspressoToolbar()
1114
-    {
1115
-        $this->loader->getShared(
1116
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1117
-            [$this->registry->CAP]
1118
-        );
1119
-    }
1120
-
1121
-
1122
-    /**
1123
-     * do_not_cache
1124
-     * sets no cache headers and defines no cache constants for WP plugins
1125
-     *
1126
-     * @access public
1127
-     * @return void
1128
-     */
1129
-    public static function do_not_cache()
1130
-    {
1131
-        // set no cache constants
1132
-        if (! defined('DONOTCACHEPAGE')) {
1133
-            define('DONOTCACHEPAGE', true);
1134
-        }
1135
-        if (! defined('DONOTCACHCEOBJECT')) {
1136
-            define('DONOTCACHCEOBJECT', true);
1137
-        }
1138
-        if (! defined('DONOTCACHEDB')) {
1139
-            define('DONOTCACHEDB', true);
1140
-        }
1141
-        // add no cache headers
1142
-        add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1143
-        // plus a little extra for nginx and Google Chrome
1144
-        add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1145
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1146
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1147
-    }
1148
-
1149
-
1150
-    /**
1151
-     *    extra_nocache_headers
1152
-     *
1153
-     * @access    public
1154
-     * @param $headers
1155
-     * @return    array
1156
-     */
1157
-    public static function extra_nocache_headers($headers): array
1158
-    {
1159
-        // for NGINX
1160
-        $headers['X-Accel-Expires'] = 0;
1161
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1162
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1163
-        return $headers;
1164
-    }
1165
-
1166
-
1167
-    /**
1168
-     *    nocache_headers
1169
-     *
1170
-     * @access    public
1171
-     * @return    void
1172
-     */
1173
-    public static function nocache_headers()
1174
-    {
1175
-        nocache_headers();
1176
-    }
1177
-
1178
-
1179
-    /**
1180
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1181
-     * never returned with the function.
1182
-     *
1183
-     * @param array $exclude_array any existing pages being excluded are in this array.
1184
-     * @return array
1185
-     */
1186
-    public function remove_pages_from_wp_list_pages(array $exclude_array): array
1187
-    {
1188
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1189
-    }
28
+	/**
29
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
30
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
31
+	 */
32
+	const req_type_normal = 0;
33
+
34
+	/**
35
+	 * Indicates this is a brand new installation of EE so we should install
36
+	 * tables and default data etc
37
+	 */
38
+	const req_type_new_activation = 1;
39
+
40
+	/**
41
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
42
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
43
+	 * and that default data is setup too
44
+	 */
45
+	const req_type_reactivation = 2;
46
+
47
+	/**
48
+	 * indicates that EE has been upgraded since its previous request.
49
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
50
+	 */
51
+	const req_type_upgrade = 3;
52
+
53
+	/**
54
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
55
+	 */
56
+	const req_type_downgrade = 4;
57
+
58
+	/**
59
+	 * @deprecated since version 4.6.0.dev.006
60
+	 * Now whenever a new_activation is detected the request type is still just
61
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
62
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
63
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
64
+	 * (Specifically, when the migration manager indicates migrations are finished
65
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
66
+	 */
67
+	const req_type_activation_but_not_installed = 5;
68
+
69
+	/**
70
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
71
+	 */
72
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
73
+
74
+	/**
75
+	 * @var AddonManager $addon_manager
76
+	 */
77
+	private $addon_manager;
78
+
79
+	/**
80
+	 * @var EE_System $_instance
81
+	 */
82
+	private static $_instance;
83
+
84
+	/**
85
+	 * @var EE_Registry $registry
86
+	 */
87
+	private $registry;
88
+
89
+	/**
90
+	 * @var LoaderInterface $loader
91
+	 */
92
+	private $loader;
93
+
94
+	/**
95
+	 * @var EE_Capabilities $capabilities
96
+	 */
97
+	private $capabilities;
98
+
99
+	/**
100
+	 * @var EE_Maintenance_Mode $maintenance_mode
101
+	 */
102
+	private $maintenance_mode;
103
+
104
+	/**
105
+	 * @var RequestInterface $request
106
+	 */
107
+	private $request;
108
+
109
+	/**
110
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
111
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
112
+	 *
113
+	 * @var int $_req_type
114
+	 */
115
+	private $_req_type;
116
+
117
+	/**
118
+	 * Whether or not there was a non-micro version change in EE core version during this request
119
+	 *
120
+	 * @var boolean $_major_version_change
121
+	 */
122
+	private $_major_version_change = false;
123
+
124
+	/**
125
+	 * @var Router $router
126
+	 */
127
+	private $router;
128
+
129
+
130
+	/**
131
+	 * @singleton method used to instantiate class object
132
+	 * @param LoaderInterface|null     $loader
133
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
134
+	 * @param EE_Registry|null         $registry
135
+	 * @param RequestInterface|null    $request
136
+	 * @param Router|null              $router
137
+	 * @return EE_System
138
+	 */
139
+	public static function instance(
140
+		LoaderInterface $loader = null,
141
+		EE_Maintenance_Mode $maintenance_mode = null,
142
+		EE_Registry $registry = null,
143
+		RequestInterface $request = null,
144
+		Router $router = null
145
+	): EE_System {
146
+		// check if class object is instantiated
147
+		if (! self::$_instance instanceof EE_System) {
148
+			self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
149
+		}
150
+		return self::$_instance;
151
+	}
152
+
153
+
154
+	/**
155
+	 * resets the instance and returns it
156
+	 *
157
+	 * @return EE_System
158
+	 */
159
+	public static function reset(): EE_System
160
+	{
161
+		self::$_instance->_req_type = null;
162
+		// make sure none of the old hooks are left hanging around
163
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
164
+		// we need to reset the migration manager in order for it to detect DMSs properly
165
+		EE_Data_Migration_Manager::reset();
166
+		self::instance()->detect_activations_or_upgrades();
167
+		self::instance()->perform_activations_upgrades_and_migrations();
168
+		return self::instance();
169
+	}
170
+
171
+
172
+	/**
173
+	 * sets hooks for running rest of system
174
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
175
+	 * starting EE Addons from any other point may lead to problems
176
+	 *
177
+	 * @param LoaderInterface     $loader
178
+	 * @param EE_Maintenance_Mode $maintenance_mode
179
+	 * @param EE_Registry         $registry
180
+	 * @param RequestInterface    $request
181
+	 * @param Router              $router
182
+	 */
183
+	private function __construct(
184
+		LoaderInterface $loader,
185
+		EE_Maintenance_Mode $maintenance_mode,
186
+		EE_Registry $registry,
187
+		RequestInterface $request,
188
+		Router $router
189
+	) {
190
+		$this->registry         = $registry;
191
+		$this->loader           = $loader;
192
+		$this->request          = $request;
193
+		$this->router           = $router;
194
+		$this->maintenance_mode = $maintenance_mode;
195
+		do_action('AHEE__EE_System__construct__begin', $this);
196
+		add_action(
197
+			'AHEE__EE_Bootstrap__load_espresso_addons',
198
+			[$this, 'loadCapabilities'],
199
+			5
200
+		);
201
+		add_action(
202
+			'AHEE__EE_Bootstrap__load_espresso_addons',
203
+			[$this, 'loadCommandBus'],
204
+			7
205
+		);
206
+		add_action(
207
+			'AHEE__EE_Bootstrap__load_espresso_addons',
208
+			[$this, 'loadPluginApi'],
209
+			9
210
+		);
211
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
212
+		add_action(
213
+			'AHEE__EE_Bootstrap__load_espresso_addons',
214
+			[$this, 'load_espresso_addons']
215
+		);
216
+		// when an ee addon is activated, we want to call the core hook(s) again
217
+		// because the newly-activated addon didn't get a chance to run at all
218
+		add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
219
+		// detect whether install or upgrade
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
222
+			[$this, 'detect_activations_or_upgrades'],
223
+			3
224
+		);
225
+		// load EE_Config, EE_Textdomain, etc
226
+		add_action(
227
+			'AHEE__EE_Bootstrap__load_core_configuration',
228
+			[$this, 'load_core_configuration'],
229
+			5
230
+		);
231
+		// load specifications for matching routes to current request
232
+		add_action(
233
+			'AHEE__EE_Bootstrap__load_core_configuration',
234
+			[$this, 'loadRouteMatchSpecifications']
235
+		);
236
+		// load EE_Config, EE_Textdomain, etc
237
+		add_action(
238
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
239
+			[$this, 'register_shortcodes_modules_and_widgets'],
240
+			7
241
+		);
242
+		// you wanna get going? I wanna get going... let's get going!
243
+		add_action(
244
+			'AHEE__EE_Bootstrap__brew_espresso',
245
+			[$this, 'brew_espresso'],
246
+			9
247
+		);
248
+		// other housekeeping
249
+		// exclude EE critical pages from wp_list_pages
250
+		add_filter(
251
+			'wp_list_pages_excludes',
252
+			[$this, 'remove_pages_from_wp_list_pages'],
253
+			10
254
+		);
255
+		// ALL EE Addons should use the following hook point to attach their initial setup too
256
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
257
+		do_action('AHEE__EE_System__construct__complete', $this);
258
+	}
259
+
260
+
261
+	/**
262
+	 * load and setup EE_Capabilities
263
+	 *
264
+	 * @return void
265
+	 */
266
+	public function loadCapabilities()
267
+	{
268
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
269
+		add_action(
270
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
271
+			function () {
272
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
273
+			}
274
+		);
275
+	}
276
+
277
+
278
+	/**
279
+	 * create and cache the CommandBus, and also add middleware
280
+	 * The CapChecker middleware requires the use of EE_Capabilities
281
+	 * which is why we need to load the CommandBus after Caps are set up
282
+	 *
283
+	 * @return void
284
+	 */
285
+	public function loadCommandBus()
286
+	{
287
+		$this->loader->getShared(
288
+			'CommandBusInterface',
289
+			[
290
+				null,
291
+				apply_filters(
292
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
293
+					[
294
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
295
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
296
+					]
297
+				),
298
+			]
299
+		);
300
+	}
301
+
302
+
303
+	/**
304
+	 * @return void
305
+	 * @throws Exception
306
+	 */
307
+	public function loadPluginApi()
308
+	{
309
+		$this->addon_manager = $this->loader->getShared(AddonManager::class);
310
+		$this->addon_manager->initialize();
311
+		$this->loader->getShared('EE_Request_Handler');
312
+	}
313
+
314
+
315
+	/**
316
+	 * load_espresso_addons
317
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
318
+	 * this is hooked into both:
319
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
320
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
321
+	 *    and the WP 'activate_plugin' hook point
322
+	 *
323
+	 * @return void
324
+	 * @throws Exception
325
+	 */
326
+	public function load_espresso_addons()
327
+	{
328
+		// looking for hooks? they've been moved into the AddonManager to maintain compatibility
329
+		$this->addon_manager->loadAddons();
330
+	}
331
+
332
+
333
+	/**
334
+	 * detect_activations_or_upgrades
335
+	 * Checks for activation or upgrade of core first;
336
+	 * then also checks if any registered addons have been activated or upgraded
337
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
338
+	 * which runs during the WP 'plugins_loaded' action at priority 3
339
+	 *
340
+	 * @access public
341
+	 * @return void
342
+	 */
343
+	public function detect_activations_or_upgrades()
344
+	{
345
+		// first off: let's make sure to handle core
346
+		$this->detect_if_activation_or_upgrade();
347
+		foreach ($this->registry->addons as $addon) {
348
+			if ($addon instanceof EE_Addon) {
349
+				// detect teh request type for that addon
350
+				$addon->detect_req_type();
351
+			}
352
+		}
353
+	}
354
+
355
+
356
+	/**
357
+	 * detect_if_activation_or_upgrade
358
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
359
+	 * and either setting up the DB or setting up maintenance mode etc.
360
+	 *
361
+	 * @access public
362
+	 * @return void
363
+	 */
364
+	public function detect_if_activation_or_upgrade()
365
+	{
366
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
367
+		// check if db has been updated, or if its a brand-new installation
368
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
369
+		$request_type       = $this->detect_req_type($espresso_db_update);
370
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
371
+		switch ($request_type) {
372
+			case EE_System::req_type_new_activation:
373
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
374
+				$this->_handle_core_version_change($espresso_db_update);
375
+				break;
376
+			case EE_System::req_type_reactivation:
377
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
378
+				$this->_handle_core_version_change($espresso_db_update);
379
+				break;
380
+			case EE_System::req_type_upgrade:
381
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
382
+				// migrations may be required now that we've upgraded
383
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
384
+				$this->_handle_core_version_change($espresso_db_update);
385
+				break;
386
+			case EE_System::req_type_downgrade:
387
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
388
+				// its possible migrations are no longer required
389
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
390
+				$this->_handle_core_version_change($espresso_db_update);
391
+				break;
392
+			case EE_System::req_type_normal:
393
+			default:
394
+				break;
395
+		}
396
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
397
+	}
398
+
399
+
400
+	/**
401
+	 * Updates the list of installed versions and sets hooks for
402
+	 * initializing the database later during the request
403
+	 *
404
+	 * @param array $espresso_db_update
405
+	 */
406
+	private function _handle_core_version_change(array $espresso_db_update)
407
+	{
408
+		$this->update_list_of_installed_versions($espresso_db_update);
409
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
410
+		add_action(
411
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
412
+			[$this, 'initialize_db_if_no_migrations_required']
413
+		);
414
+	}
415
+
416
+
417
+	/**
418
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
419
+	 * information about what versions of EE have been installed and activated,
420
+	 * NOT necessarily the state of the database
421
+	 *
422
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
423
+	 *                                            If not supplied, fetches it from the options table
424
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
425
+	 */
426
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
427
+	{
428
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
429
+		if (! $espresso_db_update) {
430
+			$espresso_db_update = get_option('espresso_db_update');
431
+		}
432
+		// check that option is an array
433
+		if (! is_array($espresso_db_update)) {
434
+			// if option is FALSE, then it never existed
435
+			if ($espresso_db_update === false) {
436
+				// make $espresso_db_update an array and save option with autoload OFF
437
+				$espresso_db_update = [];
438
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
439
+			} else {
440
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
441
+				$espresso_db_update = [$espresso_db_update => []];
442
+				update_option('espresso_db_update', $espresso_db_update);
443
+			}
444
+		} else {
445
+			$corrected_db_update = [];
446
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
447
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
448
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
449
+					// the key is an int, and the value IS NOT an array
450
+					// so it must be numerically-indexed, where values are versions installed...
451
+					// fix it!
452
+					$version_string                         = $should_be_array;
453
+					$corrected_db_update[ $version_string ] = ['unknown-date'];
454
+				} else {
455
+					// ok it checks out
456
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
457
+				}
458
+			}
459
+			$espresso_db_update = $corrected_db_update;
460
+			update_option('espresso_db_update', $espresso_db_update);
461
+		}
462
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
463
+		return ! empty($espresso_db_update) ? $espresso_db_update : [];
464
+	}
465
+
466
+
467
+	/**
468
+	 * Does the traditional work of setting up the plugin's database and adding default data.
469
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
470
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
471
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
472
+	 * so that it will be done when migrations are finished
473
+	 *
474
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
475
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
476
+	 *                                       This is a resource-intensive job
477
+	 *                                       so we prefer to only do it when necessary
478
+	 * @return void
479
+	 * @throws EE_Error
480
+	 * @throws ReflectionException
481
+	 */
482
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
483
+	{
484
+		$request_type = $this->detect_req_type();
485
+		// only initialize system if we're not in maintenance mode.
486
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
487
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
488
+			$rewrite_rules = $this->loader->getShared(
489
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
490
+			);
491
+			$rewrite_rules->flush();
492
+			if ($verify_schema) {
493
+				EEH_Activation::initialize_db_and_folders();
494
+			}
495
+			EEH_Activation::initialize_db_content();
496
+			EEH_Activation::system_initialization();
497
+			if ($initialize_addons_too) {
498
+				$this->initialize_addons();
499
+			}
500
+		} else {
501
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
502
+		}
503
+		if (
504
+			$request_type === EE_System::req_type_new_activation
505
+			|| $request_type === EE_System::req_type_reactivation
506
+			|| (
507
+				$request_type === EE_System::req_type_upgrade
508
+				&& $this->is_major_version_change()
509
+			)
510
+		) {
511
+			add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
512
+		}
513
+	}
514
+
515
+
516
+	/**
517
+	 * Initializes the db for all registered addons
518
+	 *
519
+	 * @throws EE_Error
520
+	 * @throws ReflectionException
521
+	 */
522
+	public function initialize_addons()
523
+	{
524
+		// foreach registered addon, make sure its db is up-to-date too
525
+		foreach ($this->registry->addons as $addon) {
526
+			if ($addon instanceof EE_Addon) {
527
+				$addon->initialize_db_if_no_migrations_required();
528
+			}
529
+		}
530
+	}
531
+
532
+
533
+	/**
534
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
535
+	 *
536
+	 * @param array  $version_history
537
+	 * @param string $current_version_to_add version to be added to the version history
538
+	 * @return    boolean success as to whether or not this option was changed
539
+	 */
540
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
541
+	{
542
+		if (! $version_history) {
543
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
544
+		}
545
+		if ($current_version_to_add === null) {
546
+			$current_version_to_add = espresso_version();
547
+		}
548
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
549
+		// re-save
550
+		return update_option('espresso_db_update', $version_history);
551
+	}
552
+
553
+
554
+	/**
555
+	 * Detects if the current version indicated in the has existed in the list of
556
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
557
+	 *
558
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
559
+	 *                                  If not supplied, fetches it from the options table.
560
+	 *                                  Also, caches its result so later parts of the code can also know whether
561
+	 *                                  there's been an update or not. This way we can add the current version to
562
+	 *                                  espresso_db_update, but still know if this is a new install or not
563
+	 * @return int one of the constants on EE_System::req_type_
564
+	 */
565
+	public function detect_req_type($espresso_db_update = null): int
566
+	{
567
+		if ($this->_req_type === null) {
568
+			$espresso_db_update          = ! empty($espresso_db_update)
569
+				? $espresso_db_update
570
+				: $this->fix_espresso_db_upgrade_option();
571
+			$this->_req_type             = EE_System::detect_req_type_given_activation_history(
572
+				$espresso_db_update,
573
+				'ee_espresso_activation',
574
+				espresso_version()
575
+			);
576
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
577
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
578
+		}
579
+		return $this->_req_type;
580
+	}
581
+
582
+
583
+	/**
584
+	 * Returns whether or not there was a non-micro version change (ie, change in either
585
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
586
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
587
+	 *
588
+	 * @param $activation_history
589
+	 * @return bool
590
+	 */
591
+	private function _detect_major_version_change($activation_history): bool
592
+	{
593
+		$previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
594
+		$previous_version_parts = explode('.', $previous_version);
595
+		$current_version_parts  = explode('.', espresso_version());
596
+		return isset(
597
+			$previous_version_parts[0],
598
+			$previous_version_parts[1],
599
+			$current_version_parts[0],
600
+			$current_version_parts[1]
601
+		) && (
602
+			$previous_version_parts[0] !== $current_version_parts[0]
603
+			|| $previous_version_parts[1] !== $current_version_parts[1]
604
+		);
605
+	}
606
+
607
+
608
+	/**
609
+	 * Returns true if either the major or minor version of EE changed during this request.
610
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
611
+	 *
612
+	 * @return bool
613
+	 */
614
+	public function is_major_version_change(): bool
615
+	{
616
+		return $this->_major_version_change;
617
+	}
618
+
619
+
620
+	/**
621
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
622
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
623
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
624
+	 * just activated to (for core that will always be espresso_version())
625
+	 *
626
+	 * @param array|null $activation_history             the option's value which stores the activation history for
627
+	 *                                                 this
628
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
629
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
630
+	 *                                                 indicate that this plugin was just activated
631
+	 * @param string $current_version                  the version that was just upgraded to (for core that will be
632
+	 *                                                 espresso_version())
633
+	 * @return int one of the constants on EE_System::req_type_
634
+	 */
635
+	public static function detect_req_type_given_activation_history(
636
+		array $activation_history,
637
+		string $activation_indicator_option_name,
638
+		string $current_version
639
+	): int {
640
+		$version_change = self::compareVersionWithPrevious($activation_history, $current_version);
641
+		$is_activation  = get_option($activation_indicator_option_name, false);
642
+		$req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
643
+		if ($is_activation) {
644
+			// cleanup in aisle 6
645
+			delete_option($activation_indicator_option_name);
646
+		}
647
+		return $req_type;
648
+	}
649
+
650
+
651
+	/**
652
+	 * @param array  $activation_history
653
+	 * @param int    $version_change
654
+	 * @param bool   $is_activation
655
+	 * @return int
656
+	 * @since $VID:$
657
+	 */
658
+	private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
659
+	{
660
+		// if no previous activation history exists, then this is a brand new install
661
+		if (empty($activation_history)) {
662
+			return EE_System::req_type_new_activation;
663
+		}
664
+		// current version is higher than previous version, so it's an upgrade
665
+		if ($version_change === 1) {
666
+			return EE_System::req_type_upgrade;
667
+		}
668
+		// current version is lower than previous version, so it's a downgrade
669
+		if ($version_change === -1) {
670
+			return EE_System::req_type_downgrade;
671
+		}
672
+		// version hasn't changed since last version so check if the activation indicator is set
673
+		// to determine if it's a reactivation, or just a normal request
674
+		return $is_activation
675
+			? EE_System::req_type_reactivation
676
+			: EE_System::req_type_normal;
677
+	}
678
+
679
+
680
+	/**
681
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
682
+	 * the $activation_history_for_addon
683
+	 *
684
+	 * @param array  $activation_history    array where keys are versions,
685
+	 *                                      values are arrays of times activated (sometimes 'unknown-date')
686
+	 * @param string $current_version
687
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
688
+	 *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
689
+	 *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
690
+	 *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
691
+	 */
692
+	private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
693
+	{
694
+		// find the most recently-activated version
695
+		$most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
696
+		return version_compare($current_version, $most_recently_active_version);
697
+	}
698
+
699
+
700
+	/**
701
+	 * Gets the most recently active version listed in the activation history,
702
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
703
+	 *
704
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
705
+	 *                                   sometimes containing 'unknown-date'
706
+	 * @return string
707
+	 */
708
+	private static function getMostRecentlyActiveVersion(array $activation_history): string
709
+	{
710
+		$most_recent_activation_date  = '1970-01-01 00:00:00';
711
+		$most_recently_active_version = '0.0.0.dev.000';
712
+		if (is_array($activation_history)) {
713
+			foreach ($activation_history as $version => $activation_dates) {
714
+				// check there is a record of when this version was activated.
715
+				// Otherwise, mark it as unknown
716
+				if (! $activation_dates) {
717
+					$activation_dates = ['unknown-date'];
718
+				}
719
+				$activation_dates = is_string($activation_dates) ? [$activation_dates] : $activation_dates;
720
+				foreach ($activation_dates as $activation_date) {
721
+					if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
722
+						$most_recently_active_version = $version;
723
+						$most_recent_activation_date  = $activation_date;
724
+					}
725
+				}
726
+			}
727
+		}
728
+		return $most_recently_active_version;
729
+	}
730
+
731
+
732
+	/**
733
+	 * This redirects to the about EE page after activation
734
+	 *
735
+	 * @return void
736
+	 */
737
+	public function redirect_to_about_ee()
738
+	{
739
+		$notices = EE_Error::get_notices(false);
740
+		// if current user is an admin and it's not an ajax or rest request
741
+		if (
742
+			! isset($notices['errors'])
743
+			&& $this->request->isAdmin()
744
+			&& apply_filters(
745
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
746
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
747
+			)
748
+		) {
749
+			$query_params = ['page' => 'espresso_about'];
750
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
751
+				$query_params['new_activation'] = true;
752
+			}
753
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
754
+				$query_params['reactivation'] = true;
755
+			}
756
+			$url = add_query_arg($query_params, admin_url('admin.php'));
757
+			EEH_URL::safeRedirectAndExit($url);
758
+		}
759
+	}
760
+
761
+
762
+	/**
763
+	 * load_core_configuration
764
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
765
+	 * which runs during the WP 'plugins_loaded' action at priority 5
766
+	 *
767
+	 * @return void
768
+	 * @throws ReflectionException
769
+	 * @throws Exception
770
+	 */
771
+	public function load_core_configuration()
772
+	{
773
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
774
+		$this->loader->getShared('EE_Load_Textdomain');
775
+		// load textdomain
776
+		EE_Load_Textdomain::load_textdomain();
777
+		// load caf stuff a chance to play during the activation process too.
778
+		$this->_maybe_brew_regular();
779
+		// load and setup EE_Config and EE_Network_Config
780
+		$config = $this->loader->getShared('EE_Config');
781
+		$this->loader->getShared('EE_Network_Config');
782
+		// setup autoloaders
783
+		// enable logging?
784
+		if ($config->admin->use_remote_logging) {
785
+			$this->loader->getShared('EE_Log');
786
+		}
787
+		// check for activation errors
788
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
789
+		if ($activation_errors) {
790
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
791
+			update_option('ee_plugin_activation_errors', false);
792
+		}
793
+		// get model names
794
+		$this->_parse_model_names();
795
+		// configure custom post type definitions
796
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
797
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
798
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
799
+	}
800
+
801
+
802
+	/**
803
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
804
+	 *
805
+	 * @return void
806
+	 * @throws ReflectionException
807
+	 */
808
+	private function _parse_model_names()
809
+	{
810
+		// get all the files in the EE_MODELS folder that end in .model.php
811
+		$models                 = glob(EE_MODELS . '*.model.php');
812
+		$model_names            = [];
813
+		$non_abstract_db_models = [];
814
+		foreach ($models as $model) {
815
+			// get model classname
816
+			$classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
817
+			$short_name      = str_replace('EEM_', '', $classname);
818
+			$reflectionClass = new ReflectionClass($classname);
819
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
820
+				$non_abstract_db_models[ $short_name ] = $classname;
821
+			}
822
+			$model_names[ $short_name ] = $classname;
823
+		}
824
+		$this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
825
+		$this->registry->non_abstract_db_models = apply_filters(
826
+			'FHEE__EE_System__parse_implemented_model_names',
827
+			$non_abstract_db_models
828
+		);
829
+	}
830
+
831
+
832
+	/**
833
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
834
+	 * that need to be setup before our EE_System launches.
835
+	 *
836
+	 * @return void
837
+	 * @throws DomainException
838
+	 * @throws InvalidArgumentException
839
+	 * @throws InvalidDataTypeException
840
+	 * @throws InvalidInterfaceException
841
+	 * @throws InvalidClassException
842
+	 * @throws InvalidFilePathException
843
+	 */
844
+	private function _maybe_brew_regular()
845
+	{
846
+		/** @var Domain $domain */
847
+		$domain = DomainFactory::getEventEspressoCoreDomain();
848
+		if ($domain->isCaffeinated()) {
849
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
850
+		}
851
+	}
852
+
853
+
854
+	/**
855
+	 * @throws Exception
856
+	 * @since 4.9.71.p
857
+	 */
858
+	public function loadRouteMatchSpecifications()
859
+	{
860
+		try {
861
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
862
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
863
+			$this->router->loadPrimaryRoutes();
864
+		} catch (Exception $exception) {
865
+			new ExceptionStackTraceDisplay($exception);
866
+		}
867
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
868
+	}
869
+
870
+
871
+	/**
872
+	 * register_shortcodes_modules_and_widgets
873
+	 * generate lists of shortcodes and modules, then verify paths and classes
874
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
875
+	 * which runs during the WP 'plugins_loaded' action at priority 7
876
+	 *
877
+	 * @access public
878
+	 * @return void
879
+	 * @throws Exception
880
+	 */
881
+	public function register_shortcodes_modules_and_widgets()
882
+	{
883
+		$this->router->registerShortcodesModulesAndWidgets();
884
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
885
+		// check for addons using old hook point
886
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
887
+			$this->_incompatible_addon_error();
888
+		}
889
+	}
890
+
891
+
892
+	/**
893
+	 * _incompatible_addon_error
894
+	 *
895
+	 * @access public
896
+	 * @return void
897
+	 */
898
+	private function _incompatible_addon_error()
899
+	{
900
+		// get array of classes hooking into here
901
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
902
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
903
+		);
904
+		if (! empty($class_names)) {
905
+			$msg = __(
906
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
907
+				'event_espresso'
908
+			);
909
+			$msg .= '<ul>';
910
+			foreach ($class_names as $class_name) {
911
+				$msg .= '<li><b>Event Espresso - '
912
+						. str_replace(
913
+							['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
914
+							'',
915
+							$class_name
916
+						) . '</b></li>';
917
+			}
918
+			$msg .= '</ul>';
919
+			$msg .= __(
920
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
921
+				'event_espresso'
922
+			);
923
+			// save list of incompatible addons to wp-options for later use
924
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
925
+			if (is_admin()) {
926
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
927
+			}
928
+		}
929
+	}
930
+
931
+
932
+	/**
933
+	 * brew_espresso
934
+	 * begins the process of setting hooks for initializing EE in the correct order
935
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
936
+	 * which runs during the WP 'plugins_loaded' action at priority 9
937
+	 *
938
+	 * @return void
939
+	 * @throws Exception
940
+	 */
941
+	public function brew_espresso()
942
+	{
943
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
944
+		// load some final core systems
945
+		add_action('init', [$this, 'set_hooks_for_core'], 1);
946
+		add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
947
+		add_action('init', [$this, 'load_CPTs_and_session'], 5);
948
+		add_action('init', [$this, 'load_controllers'], 7);
949
+		add_action('init', [$this, 'core_loaded_and_ready'], 9);
950
+		add_action('init', [$this, 'initialize'], 10);
951
+		add_action('init', [$this, 'initialize_last'], 100);
952
+		$this->router->brewEspresso();
953
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
954
+	}
955
+
956
+
957
+	/**
958
+	 *    set_hooks_for_core
959
+	 *
960
+	 * @access public
961
+	 * @return    void
962
+	 * @throws EE_Error
963
+	 */
964
+	public function set_hooks_for_core()
965
+	{
966
+		$this->_deactivate_incompatible_addons();
967
+		do_action('AHEE__EE_System__set_hooks_for_core');
968
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
969
+		// caps need to be initialized on every request so that capability maps are set.
970
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
971
+		$this->registry->CAP->init_caps();
972
+	}
973
+
974
+
975
+	/**
976
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
977
+	 * deactivates any addons considered incompatible with the current version of EE
978
+	 */
979
+	private function _deactivate_incompatible_addons()
980
+	{
981
+		$incompatible_addons = get_option('ee_incompatible_addons', []);
982
+		if (! empty($incompatible_addons)) {
983
+			$active_plugins = get_option('active_plugins', []);
984
+			foreach ($active_plugins as $active_plugin) {
985
+				foreach ($incompatible_addons as $incompatible_addon) {
986
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
987
+						unset($_GET['activate']);
988
+						espresso_deactivate_plugin($active_plugin);
989
+					}
990
+				}
991
+			}
992
+		}
993
+	}
994
+
995
+
996
+	/**
997
+	 *    perform_activations_upgrades_and_migrations
998
+	 *
999
+	 * @access public
1000
+	 * @return    void
1001
+	 */
1002
+	public function perform_activations_upgrades_and_migrations()
1003
+	{
1004
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1005
+	}
1006
+
1007
+
1008
+	/**
1009
+	 * @return void
1010
+	 * @throws DomainException
1011
+	 */
1012
+	public function load_CPTs_and_session()
1013
+	{
1014
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1015
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1016
+		$register_custom_taxonomies = $this->loader->getShared(
1017
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1018
+		);
1019
+		$register_custom_taxonomies->registerCustomTaxonomies();
1020
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1021
+		$register_custom_post_types = $this->loader->getShared(
1022
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1023
+		);
1024
+		$register_custom_post_types->registerCustomPostTypes();
1025
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1026
+		$register_custom_taxonomy_terms = $this->loader->getShared(
1027
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1028
+		);
1029
+		$register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1030
+		// load legacy Custom Post Types and Taxonomies
1031
+		$this->loader->getShared('EE_Register_CPTs');
1032
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1033
+	}
1034
+
1035
+
1036
+	/**
1037
+	 * load_controllers
1038
+	 * this is the best place to load any additional controllers that needs access to EE core.
1039
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1040
+	 * time
1041
+	 *
1042
+	 * @access public
1043
+	 * @return void
1044
+	 * @throws Exception
1045
+	 */
1046
+	public function load_controllers()
1047
+	{
1048
+		do_action('AHEE__EE_System__load_controllers__start');
1049
+		$this->router->loadControllers();
1050
+		do_action('AHEE__EE_System__load_controllers__complete');
1051
+	}
1052
+
1053
+
1054
+	/**
1055
+	 * core_loaded_and_ready
1056
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1057
+	 *
1058
+	 * @access public
1059
+	 * @return void
1060
+	 * @throws Exception
1061
+	 */
1062
+	public function core_loaded_and_ready()
1063
+	{
1064
+		$this->router->coreLoadedAndReady();
1065
+		// integrate WP_Query with the EE models
1066
+		$this->loader->getShared('EE_CPT_Strategy');
1067
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1068
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1069
+		// builders require these even on the front-end
1070
+		require_once EE_PUBLIC . 'template_tags.php';
1071
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1072
+	}
1073
+
1074
+
1075
+	/**
1076
+	 * initialize
1077
+	 * this is the best place to begin initializing client code
1078
+	 *
1079
+	 * @access public
1080
+	 * @return void
1081
+	 */
1082
+	public function initialize()
1083
+	{
1084
+		do_action('AHEE__EE_System__initialize');
1085
+	}
1086
+
1087
+
1088
+	/**
1089
+	 * initialize_last
1090
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1091
+	 * initialize has done so
1092
+	 *
1093
+	 * @access public
1094
+	 * @return void
1095
+	 * @throws Exception
1096
+	 */
1097
+	public function initialize_last()
1098
+	{
1099
+		do_action('AHEE__EE_System__initialize_last');
1100
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1101
+		$rewrite_rules = $this->loader->getShared(
1102
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1103
+		);
1104
+		$rewrite_rules->flushRewriteRules();
1105
+		$this->router->initializeLast();
1106
+		add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1107
+	}
1108
+
1109
+
1110
+	/**
1111
+	 * @return void
1112
+	 */
1113
+	public function addEspressoToolbar()
1114
+	{
1115
+		$this->loader->getShared(
1116
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1117
+			[$this->registry->CAP]
1118
+		);
1119
+	}
1120
+
1121
+
1122
+	/**
1123
+	 * do_not_cache
1124
+	 * sets no cache headers and defines no cache constants for WP plugins
1125
+	 *
1126
+	 * @access public
1127
+	 * @return void
1128
+	 */
1129
+	public static function do_not_cache()
1130
+	{
1131
+		// set no cache constants
1132
+		if (! defined('DONOTCACHEPAGE')) {
1133
+			define('DONOTCACHEPAGE', true);
1134
+		}
1135
+		if (! defined('DONOTCACHCEOBJECT')) {
1136
+			define('DONOTCACHCEOBJECT', true);
1137
+		}
1138
+		if (! defined('DONOTCACHEDB')) {
1139
+			define('DONOTCACHEDB', true);
1140
+		}
1141
+		// add no cache headers
1142
+		add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1143
+		// plus a little extra for nginx and Google Chrome
1144
+		add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1145
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1146
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1147
+	}
1148
+
1149
+
1150
+	/**
1151
+	 *    extra_nocache_headers
1152
+	 *
1153
+	 * @access    public
1154
+	 * @param $headers
1155
+	 * @return    array
1156
+	 */
1157
+	public static function extra_nocache_headers($headers): array
1158
+	{
1159
+		// for NGINX
1160
+		$headers['X-Accel-Expires'] = 0;
1161
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1162
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1163
+		return $headers;
1164
+	}
1165
+
1166
+
1167
+	/**
1168
+	 *    nocache_headers
1169
+	 *
1170
+	 * @access    public
1171
+	 * @return    void
1172
+	 */
1173
+	public static function nocache_headers()
1174
+	{
1175
+		nocache_headers();
1176
+	}
1177
+
1178
+
1179
+	/**
1180
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1181
+	 * never returned with the function.
1182
+	 *
1183
+	 * @param array $exclude_array any existing pages being excluded are in this array.
1184
+	 * @return array
1185
+	 */
1186
+	public function remove_pages_from_wp_list_pages(array $exclude_array): array
1187
+	{
1188
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1189
+	}
1190 1190
 }
Please login to merge, or discard this patch.
core/EE_Addon.core.php 2 patches
Indentation   +856 added lines, -856 removed lines patch added patch discarded remove patch
@@ -19,807 +19,807 @@  discard block
 block discarded – undo
19 19
 {
20 20
 
21 21
 
22
-    /**
23
-     * prefix to be added onto an addon's plugin slug to make a wp option name
24
-     * which will be used to store the plugin's activation history
25
-     */
26
-    const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
-
28
-    /**
29
-     * @var $_version
30
-     * @type string
31
-     */
32
-    protected $_version = '';
33
-
34
-    /**
35
-     * @var $_min_core_version
36
-     * @type string
37
-     */
38
-    protected $_min_core_version = '';
39
-
40
-    /**
41
-     * derived from plugin 'main_file_path using plugin_basename()
42
-     *
43
-     * @type string $_plugin_basename
44
-     */
45
-    protected $_plugin_basename = '';
46
-
47
-    /**
48
-     * A non-internationalized name to identify this addon for use in URLs, etc
49
-     *
50
-     * @type string $_plugin_slug
51
-     */
52
-    protected $_plugin_slug = '';
53
-
54
-    /**
55
-     * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
-     *
57
-     * @type string _addon_name
58
-     */
59
-    protected $_addon_name = '';
60
-
61
-    /**
62
-     * one of the EE_System::req_type_* constants
63
-     *
64
-     * @type int $_req_type
65
-     */
66
-    protected $_req_type;
67
-
68
-    /**
69
-     * page slug to be used when generating the "Settings" link on the WP plugin page
70
-     *
71
-     * @type string $_plugin_action_slug
72
-     */
73
-    protected $_plugin_action_slug = '';
74
-
75
-    /**
76
-     * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
-     * that can be used for adding upgrading/marketing info
78
-     *
79
-     * @type array $_plugins_page_row
80
-     */
81
-    protected $_plugins_page_row = [];
82
-
83
-
84
-    /**
85
-     *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
-     *
87
-     * @type string
88
-     */
89
-    protected $_main_plugin_file;
90
-
91
-    /**
92
-     *    This is the slug used to identify this add-on within the plugin update engine.
93
-     *
94
-     * @type string
95
-     */
96
-    protected $pue_slug = '';
97
-
98
-
99
-    /**
100
-     * @var EE_Dependency_Map $dependency_map
101
-     */
102
-    private $dependency_map;
103
-
104
-
105
-    /**
106
-     * @var DomainInterface $domain
107
-     */
108
-    private $domain;
109
-
110
-
111
-    /**
112
-     * @param EE_Dependency_Map|null $dependency_map [optional]
113
-     * @param DomainInterface|null   $domain         [optional]
114
-     */
115
-    public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
-    {
117
-        if ($dependency_map instanceof EE_Dependency_Map) {
118
-            $this->setDependencyMap($dependency_map);
119
-        }
120
-        if ($domain instanceof DomainInterface) {
121
-            $this->setDomain($domain);
122
-        }
123
-        add_action('AHEE__EE_System__load_controllers__load_admin_controllers', [$this, 'admin_init']);
124
-    }
125
-
126
-
127
-    /**
128
-     * @param EE_Dependency_Map $dependency_map
129
-     */
130
-    public function setDependencyMap($dependency_map)
131
-    {
132
-        $this->dependency_map = $dependency_map;
133
-    }
134
-
135
-
136
-    /**
137
-     * @return EE_Dependency_Map
138
-     */
139
-    public function dependencyMap(): ?EE_Dependency_Map
140
-    {
141
-        return $this->dependency_map;
142
-    }
143
-
144
-
145
-    /**
146
-     * @param DomainInterface $domain
147
-     */
148
-    public function setDomain(DomainInterface $domain)
149
-    {
150
-        $this->domain = $domain;
151
-    }
152
-
153
-
154
-    /**
155
-     * @return DomainInterface
156
-     */
157
-    public function domain(): ?DomainInterface
158
-    {
159
-        return $this->domain;
160
-    }
161
-
162
-
163
-    /**
164
-     * @param string $version
165
-     */
166
-    public function set_version(string $version = '')
167
-    {
168
-        $this->_version = $version;
169
-    }
170
-
171
-
172
-    /**
173
-     * get__version
174
-     *
175
-     * @return string
176
-     */
177
-    public function version(): string
178
-    {
179
-        return $this->_version;
180
-    }
181
-
182
-
183
-    /**
184
-     * @param mixed $min_core_version
185
-     */
186
-    public function set_min_core_version($min_core_version = null)
187
-    {
188
-        $this->_min_core_version = $min_core_version;
189
-    }
190
-
191
-
192
-    /**
193
-     * get__min_core_version
194
-     *
195
-     * @return string
196
-     */
197
-    public function min_core_version(): string
198
-    {
199
-        return $this->_min_core_version;
200
-    }
201
-
202
-
203
-    /**
204
-     * Sets addon_name
205
-     *
206
-     * @param string $addon_name
207
-     */
208
-    public function set_name(string $addon_name)
209
-    {
210
-        $this->_addon_name = $addon_name;
211
-    }
212
-
213
-
214
-    /**
215
-     * Gets addon_name
216
-     *
217
-     * @return string
218
-     */
219
-    public function name()
220
-    {
221
-        return $this->_addon_name;
222
-    }
223
-
224
-
225
-    /**
226
-     * @return string
227
-     */
228
-    public function plugin_basename(): string
229
-    {
230
-
231
-        return $this->_plugin_basename;
232
-    }
233
-
234
-
235
-    /**
236
-     * @param string $plugin_basename
237
-     */
238
-    public function set_plugin_basename(string $plugin_basename)
239
-    {
240
-
241
-        $this->_plugin_basename = $plugin_basename;
242
-    }
243
-
244
-
245
-    /**
246
-     * @return string
247
-     */
248
-    public function plugin_slug(): string
249
-    {
250
-
251
-        return $this->_plugin_slug;
252
-    }
253
-
254
-
255
-    /**
256
-     * @param string $plugin_slug
257
-     */
258
-    public function set_plugin_slug(string $plugin_slug)
259
-    {
260
-
261
-        $this->_plugin_slug = $plugin_slug;
262
-    }
263
-
264
-
265
-    /**
266
-     * @return string
267
-     */
268
-    public function plugin_action_slug(): string
269
-    {
270
-
271
-        return $this->_plugin_action_slug;
272
-    }
273
-
274
-
275
-    /**
276
-     * @param string $plugin_action_slug
277
-     */
278
-    public function set_plugin_action_slug(string $plugin_action_slug)
279
-    {
280
-
281
-        $this->_plugin_action_slug = $plugin_action_slug;
282
-    }
283
-
284
-
285
-    /**
286
-     * @return array
287
-     */
288
-    public function get_plugins_page_row(): array
289
-    {
290
-
291
-        return $this->_plugins_page_row;
292
-    }
293
-
294
-
295
-    /**
296
-     * @param array|string $plugins_page_row
297
-     */
298
-    public function set_plugins_page_row(array $plugins_page_row = [])
299
-    {
300
-        // sigh.... check for example content that I stupidly merged to master and remove it if found
301
-        if (
302
-            ! is_array($plugins_page_row)
303
-            && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
304
-        ) {
305
-            $plugins_page_row = [];
306
-        }
307
-        $this->_plugins_page_row = (array) $plugins_page_row;
308
-    }
309
-
310
-
311
-    /**
312
-     * Called when EE core detects this addon has been activated for the first time.
313
-     * If the site isn't in maintenance mode, should setup the addon's database
314
-     *
315
-     * @return void
316
-     */
317
-    public function new_install()
318
-    {
319
-        $classname = get_class($this);
320
-        do_action("AHEE__{$classname}__new_install");
321
-        do_action('AHEE__EE_Addon__new_install', $this);
322
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
323
-        add_action(
324
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
325
-            [$this, 'initialize_db_if_no_migrations_required']
326
-        );
327
-    }
328
-
329
-
330
-    /**
331
-     * Called when EE core detects this addon has been reactivated. When this happens,
332
-     * it's good to just check that your data is still intact
333
-     *
334
-     * @return void
335
-     */
336
-    public function reactivation()
337
-    {
338
-        $classname = get_class($this);
339
-        do_action("AHEE__{$classname}__reactivation");
340
-        do_action('AHEE__EE_Addon__reactivation', $this);
341
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
342
-        add_action(
343
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
344
-            [$this, 'initialize_db_if_no_migrations_required']
345
-        );
346
-    }
347
-
348
-
349
-    /**
350
-     * Called when the registered deactivation hook for this addon fires.
351
-     *
352
-     * @throws EE_Error
353
-     */
354
-    public function deactivation()
355
-    {
356
-        $classname = get_class($this);
357
-        do_action("AHEE__{$classname}__deactivation");
358
-        do_action('AHEE__EE_Addon__deactivation', $this);
359
-        // check if the site no longer needs to be in maintenance mode
360
-        EE_Register_Addon::deregister($this->name());
361
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
362
-    }
363
-
364
-
365
-    /**
366
-     * Takes care of double-checking that we're not in maintenance mode, and then
367
-     * initializing this addon's necessary initial data. This is called by default on new activations
368
-     * and reactivations.
369
-     *
370
-     * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
371
-     *                               This is a resource-intensive job so we prefer to only do it when necessary
372
-     * @return void
373
-     * @throws EE_Error
374
-     * @throws InvalidInterfaceException
375
-     * @throws InvalidDataTypeException
376
-     * @throws InvalidArgumentException
377
-     * @throws ReflectionException
378
-     */
379
-    public function initialize_db_if_no_migrations_required($verify_schema = true)
380
-    {
381
-        if ($verify_schema === '') {
382
-            // wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
383
-            // (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
384
-            // calls them with an argument of an empty string (ie ""), which evaluates to false
385
-            // so we need to treat the empty string as if nothing had been passed, and should instead use the default
386
-            $verify_schema = true;
387
-        }
388
-        if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
389
-            if ($verify_schema) {
390
-                $this->initialize_db();
391
-            }
392
-            $this->initialize_default_data();
393
-            // @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
394
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to(
395
-                [
396
-                    'slug'    => $this->name(),
397
-                    'version' => $this->version(),
398
-                ]
399
-            );
400
-            /* make sure core's data is a-ok
22
+	/**
23
+	 * prefix to be added onto an addon's plugin slug to make a wp option name
24
+	 * which will be used to store the plugin's activation history
25
+	 */
26
+	const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
+
28
+	/**
29
+	 * @var $_version
30
+	 * @type string
31
+	 */
32
+	protected $_version = '';
33
+
34
+	/**
35
+	 * @var $_min_core_version
36
+	 * @type string
37
+	 */
38
+	protected $_min_core_version = '';
39
+
40
+	/**
41
+	 * derived from plugin 'main_file_path using plugin_basename()
42
+	 *
43
+	 * @type string $_plugin_basename
44
+	 */
45
+	protected $_plugin_basename = '';
46
+
47
+	/**
48
+	 * A non-internationalized name to identify this addon for use in URLs, etc
49
+	 *
50
+	 * @type string $_plugin_slug
51
+	 */
52
+	protected $_plugin_slug = '';
53
+
54
+	/**
55
+	 * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
+	 *
57
+	 * @type string _addon_name
58
+	 */
59
+	protected $_addon_name = '';
60
+
61
+	/**
62
+	 * one of the EE_System::req_type_* constants
63
+	 *
64
+	 * @type int $_req_type
65
+	 */
66
+	protected $_req_type;
67
+
68
+	/**
69
+	 * page slug to be used when generating the "Settings" link on the WP plugin page
70
+	 *
71
+	 * @type string $_plugin_action_slug
72
+	 */
73
+	protected $_plugin_action_slug = '';
74
+
75
+	/**
76
+	 * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
+	 * that can be used for adding upgrading/marketing info
78
+	 *
79
+	 * @type array $_plugins_page_row
80
+	 */
81
+	protected $_plugins_page_row = [];
82
+
83
+
84
+	/**
85
+	 *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
+	 *
87
+	 * @type string
88
+	 */
89
+	protected $_main_plugin_file;
90
+
91
+	/**
92
+	 *    This is the slug used to identify this add-on within the plugin update engine.
93
+	 *
94
+	 * @type string
95
+	 */
96
+	protected $pue_slug = '';
97
+
98
+
99
+	/**
100
+	 * @var EE_Dependency_Map $dependency_map
101
+	 */
102
+	private $dependency_map;
103
+
104
+
105
+	/**
106
+	 * @var DomainInterface $domain
107
+	 */
108
+	private $domain;
109
+
110
+
111
+	/**
112
+	 * @param EE_Dependency_Map|null $dependency_map [optional]
113
+	 * @param DomainInterface|null   $domain         [optional]
114
+	 */
115
+	public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
+	{
117
+		if ($dependency_map instanceof EE_Dependency_Map) {
118
+			$this->setDependencyMap($dependency_map);
119
+		}
120
+		if ($domain instanceof DomainInterface) {
121
+			$this->setDomain($domain);
122
+		}
123
+		add_action('AHEE__EE_System__load_controllers__load_admin_controllers', [$this, 'admin_init']);
124
+	}
125
+
126
+
127
+	/**
128
+	 * @param EE_Dependency_Map $dependency_map
129
+	 */
130
+	public function setDependencyMap($dependency_map)
131
+	{
132
+		$this->dependency_map = $dependency_map;
133
+	}
134
+
135
+
136
+	/**
137
+	 * @return EE_Dependency_Map
138
+	 */
139
+	public function dependencyMap(): ?EE_Dependency_Map
140
+	{
141
+		return $this->dependency_map;
142
+	}
143
+
144
+
145
+	/**
146
+	 * @param DomainInterface $domain
147
+	 */
148
+	public function setDomain(DomainInterface $domain)
149
+	{
150
+		$this->domain = $domain;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @return DomainInterface
156
+	 */
157
+	public function domain(): ?DomainInterface
158
+	{
159
+		return $this->domain;
160
+	}
161
+
162
+
163
+	/**
164
+	 * @param string $version
165
+	 */
166
+	public function set_version(string $version = '')
167
+	{
168
+		$this->_version = $version;
169
+	}
170
+
171
+
172
+	/**
173
+	 * get__version
174
+	 *
175
+	 * @return string
176
+	 */
177
+	public function version(): string
178
+	{
179
+		return $this->_version;
180
+	}
181
+
182
+
183
+	/**
184
+	 * @param mixed $min_core_version
185
+	 */
186
+	public function set_min_core_version($min_core_version = null)
187
+	{
188
+		$this->_min_core_version = $min_core_version;
189
+	}
190
+
191
+
192
+	/**
193
+	 * get__min_core_version
194
+	 *
195
+	 * @return string
196
+	 */
197
+	public function min_core_version(): string
198
+	{
199
+		return $this->_min_core_version;
200
+	}
201
+
202
+
203
+	/**
204
+	 * Sets addon_name
205
+	 *
206
+	 * @param string $addon_name
207
+	 */
208
+	public function set_name(string $addon_name)
209
+	{
210
+		$this->_addon_name = $addon_name;
211
+	}
212
+
213
+
214
+	/**
215
+	 * Gets addon_name
216
+	 *
217
+	 * @return string
218
+	 */
219
+	public function name()
220
+	{
221
+		return $this->_addon_name;
222
+	}
223
+
224
+
225
+	/**
226
+	 * @return string
227
+	 */
228
+	public function plugin_basename(): string
229
+	{
230
+
231
+		return $this->_plugin_basename;
232
+	}
233
+
234
+
235
+	/**
236
+	 * @param string $plugin_basename
237
+	 */
238
+	public function set_plugin_basename(string $plugin_basename)
239
+	{
240
+
241
+		$this->_plugin_basename = $plugin_basename;
242
+	}
243
+
244
+
245
+	/**
246
+	 * @return string
247
+	 */
248
+	public function plugin_slug(): string
249
+	{
250
+
251
+		return $this->_plugin_slug;
252
+	}
253
+
254
+
255
+	/**
256
+	 * @param string $plugin_slug
257
+	 */
258
+	public function set_plugin_slug(string $plugin_slug)
259
+	{
260
+
261
+		$this->_plugin_slug = $plugin_slug;
262
+	}
263
+
264
+
265
+	/**
266
+	 * @return string
267
+	 */
268
+	public function plugin_action_slug(): string
269
+	{
270
+
271
+		return $this->_plugin_action_slug;
272
+	}
273
+
274
+
275
+	/**
276
+	 * @param string $plugin_action_slug
277
+	 */
278
+	public function set_plugin_action_slug(string $plugin_action_slug)
279
+	{
280
+
281
+		$this->_plugin_action_slug = $plugin_action_slug;
282
+	}
283
+
284
+
285
+	/**
286
+	 * @return array
287
+	 */
288
+	public function get_plugins_page_row(): array
289
+	{
290
+
291
+		return $this->_plugins_page_row;
292
+	}
293
+
294
+
295
+	/**
296
+	 * @param array|string $plugins_page_row
297
+	 */
298
+	public function set_plugins_page_row(array $plugins_page_row = [])
299
+	{
300
+		// sigh.... check for example content that I stupidly merged to master and remove it if found
301
+		if (
302
+			! is_array($plugins_page_row)
303
+			&& strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
304
+		) {
305
+			$plugins_page_row = [];
306
+		}
307
+		$this->_plugins_page_row = (array) $plugins_page_row;
308
+	}
309
+
310
+
311
+	/**
312
+	 * Called when EE core detects this addon has been activated for the first time.
313
+	 * If the site isn't in maintenance mode, should setup the addon's database
314
+	 *
315
+	 * @return void
316
+	 */
317
+	public function new_install()
318
+	{
319
+		$classname = get_class($this);
320
+		do_action("AHEE__{$classname}__new_install");
321
+		do_action('AHEE__EE_Addon__new_install', $this);
322
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
323
+		add_action(
324
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
325
+			[$this, 'initialize_db_if_no_migrations_required']
326
+		);
327
+	}
328
+
329
+
330
+	/**
331
+	 * Called when EE core detects this addon has been reactivated. When this happens,
332
+	 * it's good to just check that your data is still intact
333
+	 *
334
+	 * @return void
335
+	 */
336
+	public function reactivation()
337
+	{
338
+		$classname = get_class($this);
339
+		do_action("AHEE__{$classname}__reactivation");
340
+		do_action('AHEE__EE_Addon__reactivation', $this);
341
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
342
+		add_action(
343
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
344
+			[$this, 'initialize_db_if_no_migrations_required']
345
+		);
346
+	}
347
+
348
+
349
+	/**
350
+	 * Called when the registered deactivation hook for this addon fires.
351
+	 *
352
+	 * @throws EE_Error
353
+	 */
354
+	public function deactivation()
355
+	{
356
+		$classname = get_class($this);
357
+		do_action("AHEE__{$classname}__deactivation");
358
+		do_action('AHEE__EE_Addon__deactivation', $this);
359
+		// check if the site no longer needs to be in maintenance mode
360
+		EE_Register_Addon::deregister($this->name());
361
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
362
+	}
363
+
364
+
365
+	/**
366
+	 * Takes care of double-checking that we're not in maintenance mode, and then
367
+	 * initializing this addon's necessary initial data. This is called by default on new activations
368
+	 * and reactivations.
369
+	 *
370
+	 * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
371
+	 *                               This is a resource-intensive job so we prefer to only do it when necessary
372
+	 * @return void
373
+	 * @throws EE_Error
374
+	 * @throws InvalidInterfaceException
375
+	 * @throws InvalidDataTypeException
376
+	 * @throws InvalidArgumentException
377
+	 * @throws ReflectionException
378
+	 */
379
+	public function initialize_db_if_no_migrations_required($verify_schema = true)
380
+	{
381
+		if ($verify_schema === '') {
382
+			// wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
383
+			// (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
384
+			// calls them with an argument of an empty string (ie ""), which evaluates to false
385
+			// so we need to treat the empty string as if nothing had been passed, and should instead use the default
386
+			$verify_schema = true;
387
+		}
388
+		if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
389
+			if ($verify_schema) {
390
+				$this->initialize_db();
391
+			}
392
+			$this->initialize_default_data();
393
+			// @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
394
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to(
395
+				[
396
+					'slug'    => $this->name(),
397
+					'version' => $this->version(),
398
+				]
399
+			);
400
+			/* make sure core's data is a-ok
401 401
              * (at the time of writing, we especially want to verify all the caps are present
402 402
              * because payment method type capabilities are added dynamically, and it's
403 403
              * possible this addon added a payment method. But it's also possible
404 404
              * other data needs to be verified)
405 405
              */
406
-            EEH_Activation::initialize_db_content();
407
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
408
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
409
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
410
-            );
411
-            $rewrite_rules->flushRewriteRules();
412
-            // in case there are lots of addons being activated at once, let's force garbage collection
413
-            // to help avoid memory limit errors
414
-            // EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
415
-            gc_collect_cycles();
416
-        } else {
417
-            // ask the data migration manager to init this addon's data
418
-            // when migrations are finished because we can't do it now
419
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
420
-        }
421
-    }
422
-
423
-
424
-    /**
425
-     * Used to setup this addon's database tables, but not necessarily any default
426
-     * data in them. The default is to actually use the most up-to-date data migration script
427
-     * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
428
-     * methods to setup the db.
429
-     *
430
-     * @throws EE_Error
431
-     * @throws ReflectionException
432
-     */
433
-    public function initialize_db()
434
-    {
435
-        // find the migration script that sets the database to be compatible with the code
436
-        $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
437
-        if ($current_dms_name) {
438
-            $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
439
-            $current_data_migration_script->set_migrating(false);
440
-            $current_data_migration_script->schema_changes_before_migration();
441
-            $current_data_migration_script->schema_changes_after_migration();
442
-            if ($current_data_migration_script->get_errors()) {
443
-                foreach ($current_data_migration_script->get_errors() as $error) {
444
-                    EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
445
-                }
446
-            }
447
-        }
448
-        // if not DMS was found that should be ok. This addon just doesn't require any database changes
449
-        EE_Data_Migration_Manager::instance()->update_current_database_state_to(
450
-            [
451
-                'slug'    => $this->name(),
452
-                'version' => $this->version(),
453
-            ]
454
-        );
455
-    }
456
-
457
-
458
-    /**
459
-     * If you want to setup default data for the addon, override this method, and call
460
-     * parent::initialize_default_data() from within it. This is normally called
461
-     * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
462
-     * and should verify default data is present (but this is also called
463
-     * on reactivations and just after migrations, so please verify you actually want
464
-     * to ADD default data, because it may already be present).
465
-     * However, please call this parent (currently it just fires a hook which other
466
-     * addons may be depending on)
467
-     */
468
-    public function initialize_default_data()
469
-    {
470
-        /**
471
-         * Called when an addon is ensuring its default data is set (possibly called
472
-         * on a reactivation, so first check for the absence of other data before setting
473
-         * default data)
474
-         *
475
-         * @param EE_Addon $addon the addon that called this
476
-         */
477
-        do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
478
-        // override to insert default data. It is safe to use the models here
479
-        // because the site should not be in maintenance mode
480
-    }
481
-
482
-
483
-    /**
484
-     * EE Core detected that this addon has been upgraded. We should check if there
485
-     * are any new migration scripts, and if so put the site into maintenance mode until
486
-     * they're ran
487
-     *
488
-     * @return void
489
-     */
490
-    public function upgrade()
491
-    {
492
-        $classname = get_class($this);
493
-        do_action("AHEE__{$classname}__upgrade");
494
-        do_action('AHEE__EE_Addon__upgrade', $this);
495
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
496
-        // also it's possible there is new default data that needs to be added
497
-        add_action(
498
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
499
-            [$this, 'initialize_db_if_no_migrations_required']
500
-        );
501
-    }
502
-
503
-
504
-    /**
505
-     * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
506
-     */
507
-    public function downgrade()
508
-    {
509
-        $classname = get_class($this);
510
-        do_action("AHEE__{$classname}__downgrade");
511
-        do_action('AHEE__EE_Addon__downgrade', $this);
512
-        // it's possible there's old default data that needs to be double-checked
513
-        add_action(
514
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
515
-            [$this, 'initialize_db_if_no_migrations_required']
516
-        );
517
-    }
518
-
519
-
520
-    /**
521
-     * set_db_update_option_name
522
-     * Until we do something better, we'll just check for migration scripts upon
523
-     * plugin activation only. In the future, we'll want to do it on plugin updates too
524
-     *
525
-     * @return bool
526
-     */
527
-    public function set_db_update_option_name(): bool
528
-    {
529
-        EE_Error::doing_it_wrong(
530
-            __FUNCTION__,
531
-            esc_html__(
532
-                'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
533
-                'event_espresso'
534
-            ),
535
-            '4.3.0.alpha.016'
536
-        );
537
-        // let's just handle this on the next request, ok? right now we're just not really ready
538
-        return $this->set_activation_indicator_option();
539
-    }
540
-
541
-
542
-    /**
543
-     * Returns the name of the activation indicator option
544
-     * (an option which is set temporarily to indicate that this addon was just activated)
545
-     *
546
-     * @return string
547
-     * @deprecated since version 4.3.0.alpha.016
548
-     */
549
-    public function get_db_update_option_name(): string
550
-    {
551
-        EE_Error::doing_it_wrong(
552
-            __FUNCTION__,
553
-            esc_html__(
554
-                'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
555
-                'event_espresso'
556
-            ),
557
-            '4.3.0.alpha.016'
558
-        );
559
-        return $this->get_activation_indicator_option_name();
560
-    }
561
-
562
-
563
-    /**
564
-     * When the addon is activated, this should be called to set a wordpress option that
565
-     * indicates it was activated. This is especially useful for detecting reactivations.
566
-     *
567
-     * @return bool
568
-     */
569
-    public function set_activation_indicator_option(): bool
570
-    {
571
-        // let's just handle this on the next request, ok? right now we're just not really ready
572
-        return update_option($this->get_activation_indicator_option_name(), true);
573
-    }
574
-
575
-
576
-    /**
577
-     * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
578
-     *
579
-     * @return string
580
-     */
581
-    public function get_activation_indicator_option_name(): string
582
-    {
583
-        return 'ee_activation_' . $this->name();
584
-    }
585
-
586
-
587
-    /**
588
-     * Used by EE_System to set the request type of this addon. Should not be used by addon developers
589
-     *
590
-     * @param int $req_type
591
-     */
592
-    public function set_req_type(int $req_type)
593
-    {
594
-        $this->_req_type = $req_type;
595
-    }
596
-
597
-
598
-    /**
599
-     * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
600
-     * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
601
-     * EE_System when it is checking for new install or upgrades of addons
602
-     */
603
-    public function detect_req_type($redetect = false): int
604
-    {
605
-        if ($this->_req_type === null || $redetect) {
606
-            $this->detect_activation_or_upgrade();
607
-        }
608
-        return $this->_req_type;
609
-    }
610
-
611
-
612
-    /**
613
-     * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
614
-     * Should only be called once per request
615
-     *
616
-     * @return void
617
-     */
618
-    public function detect_activation_or_upgrade()
619
-    {
620
-        $activation_history_for_addon = $this->get_activation_history();
621
-        $request_type                 = EE_System::detect_req_type_given_activation_history(
622
-            $activation_history_for_addon,
623
-            $this->get_activation_indicator_option_name(),
624
-            $this->version()
625
-        );
626
-        $this->set_req_type($request_type);
627
-        $classname = get_class($this);
628
-        switch ($request_type) {
629
-            case EE_System::req_type_new_activation:
630
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
631
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
632
-                $this->new_install();
633
-                $this->update_list_of_installed_versions($activation_history_for_addon);
634
-                break;
635
-            case EE_System::req_type_reactivation:
636
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
637
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
638
-                $this->reactivation();
639
-                $this->update_list_of_installed_versions($activation_history_for_addon);
640
-                break;
641
-            case EE_System::req_type_upgrade:
642
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
643
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
644
-                $this->upgrade();
645
-                $this->update_list_of_installed_versions($activation_history_for_addon);
646
-                break;
647
-            case EE_System::req_type_downgrade:
648
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
649
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
650
-                $this->downgrade();
651
-                $this->update_list_of_installed_versions($activation_history_for_addon);
652
-                break;
653
-            case EE_System::req_type_normal:
654
-            default:
655
-                break;
656
-        }
657
-
658
-        do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
659
-    }
660
-
661
-
662
-    /**
663
-     * Updates the version history for this addon
664
-     *
665
-     * @param array  $version_history
666
-     * @param string $current_version_to_add
667
-     * @return boolean success
668
-     */
669
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
670
-    {
671
-        if (! $version_history) {
672
-            $version_history = $this->get_activation_history();
673
-        }
674
-        if ($current_version_to_add === null) {
675
-            $current_version_to_add = $this->version();
676
-        }
677
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
678
-        return update_option($this->get_activation_history_option_name(), $version_history);
679
-    }
680
-
681
-
682
-    /**
683
-     * Gets the name of the wp option that stores the activation history
684
-     * of this addon
685
-     *
686
-     * @return string
687
-     */
688
-    public function get_activation_history_option_name(): string
689
-    {
690
-        return self::ee_addon_version_history_option_prefix . $this->name();
691
-    }
692
-
693
-
694
-    /**
695
-     * Gets the wp option which stores the activation history for this addon
696
-     *
697
-     * @return array
698
-     */
699
-    public function get_activation_history(): array
700
-    {
701
-        return get_option($this->get_activation_history_option_name(), []);
702
-    }
703
-
704
-
705
-    /**
706
-     * @param string $config_section
707
-     */
708
-    public function set_config_section($config_section = '')
709
-    {
710
-        $this->_config_section = ! empty($config_section) ? $config_section : 'addons';
711
-    }
712
-
713
-
714
-    /**
715
-     * Sets the filepath to the main plugin file
716
-     *
717
-     * @param string $filepath
718
-     */
719
-    public function set_main_plugin_file(string $filepath)
720
-    {
721
-        $this->_main_plugin_file = $filepath;
722
-    }
723
-
724
-
725
-    /**
726
-     * gets the filepath to teh main file
727
-     *
728
-     * @return string
729
-     */
730
-    public function get_main_plugin_file(): string
731
-    {
732
-        return $this->_main_plugin_file;
733
-    }
734
-
735
-
736
-    /**
737
-     * Gets the filename (no path) of the main file (the main file loaded
738
-     * by WP)
739
-     *
740
-     * @return string
741
-     */
742
-    public function get_main_plugin_file_basename(): string
743
-    {
744
-        return plugin_basename($this->get_main_plugin_file());
745
-    }
746
-
747
-
748
-    /**
749
-     * Gets the folder name which contains the main plugin file
750
-     *
751
-     * @return string
752
-     */
753
-    public function get_main_plugin_file_dirname(): string
754
-    {
755
-        return dirname($this->get_main_plugin_file());
756
-    }
757
-
758
-
759
-    /**
760
-     * sets hooks used in the admin
761
-     *
762
-     * @return void
763
-     */
764
-    public function admin_init()
765
-    {
766
-        // is admin and not in M-Mode ?
767
-        if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
768
-            add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
769
-            add_filter('after_plugin_row_' . $this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
770
-        }
771
-    }
772
-
773
-
774
-    /**
775
-     * plugin_actions
776
-     * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
777
-     *
778
-     * @param array  $links
779
-     * @param string $file
780
-     * @return array
781
-     */
782
-    public function plugin_action_links(array $links, string $file): array
783
-    {
784
-        if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
785
-            // before other links
786
-            array_unshift(
787
-                $links,
788
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
789
-                . esc_html__('Settings', 'event_espresso')
790
-                . '</a>'
791
-            );
792
-        }
793
-        return $links;
794
-    }
795
-
796
-
797
-    /**
798
-     * after_plugin_row
799
-     * Add additional content to the plugins page plugin row
800
-     * Inserts another row
801
-     *
802
-     * @param string $plugin_file
803
-     * @param array  $plugin_data
804
-     * @param string $status
805
-     * @return void
806
-     */
807
-    public function after_plugin_row(string $plugin_file, array $plugin_data, string $status)
808
-    {
809
-        $after_plugin_row = '';
810
-        $plugins_page_row = $this->get_plugins_page_row();
811
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
812
-            $class       = $status ? 'active' : 'inactive';
813
-            $link_text   = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
814
-            $link_url    = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
815
-            $description = isset($plugins_page_row['description'])
816
-                ? $plugins_page_row['description']
817
-                : '';
818
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
819
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
820
-                $after_plugin_row .= '<th class="check-column" scope="row"></th>';
821
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
822
-                $after_plugin_row .= '<style>
406
+			EEH_Activation::initialize_db_content();
407
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
408
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
409
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
410
+			);
411
+			$rewrite_rules->flushRewriteRules();
412
+			// in case there are lots of addons being activated at once, let's force garbage collection
413
+			// to help avoid memory limit errors
414
+			// EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
415
+			gc_collect_cycles();
416
+		} else {
417
+			// ask the data migration manager to init this addon's data
418
+			// when migrations are finished because we can't do it now
419
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
420
+		}
421
+	}
422
+
423
+
424
+	/**
425
+	 * Used to setup this addon's database tables, but not necessarily any default
426
+	 * data in them. The default is to actually use the most up-to-date data migration script
427
+	 * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
428
+	 * methods to setup the db.
429
+	 *
430
+	 * @throws EE_Error
431
+	 * @throws ReflectionException
432
+	 */
433
+	public function initialize_db()
434
+	{
435
+		// find the migration script that sets the database to be compatible with the code
436
+		$current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
437
+		if ($current_dms_name) {
438
+			$current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
439
+			$current_data_migration_script->set_migrating(false);
440
+			$current_data_migration_script->schema_changes_before_migration();
441
+			$current_data_migration_script->schema_changes_after_migration();
442
+			if ($current_data_migration_script->get_errors()) {
443
+				foreach ($current_data_migration_script->get_errors() as $error) {
444
+					EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
445
+				}
446
+			}
447
+		}
448
+		// if not DMS was found that should be ok. This addon just doesn't require any database changes
449
+		EE_Data_Migration_Manager::instance()->update_current_database_state_to(
450
+			[
451
+				'slug'    => $this->name(),
452
+				'version' => $this->version(),
453
+			]
454
+		);
455
+	}
456
+
457
+
458
+	/**
459
+	 * If you want to setup default data for the addon, override this method, and call
460
+	 * parent::initialize_default_data() from within it. This is normally called
461
+	 * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
462
+	 * and should verify default data is present (but this is also called
463
+	 * on reactivations and just after migrations, so please verify you actually want
464
+	 * to ADD default data, because it may already be present).
465
+	 * However, please call this parent (currently it just fires a hook which other
466
+	 * addons may be depending on)
467
+	 */
468
+	public function initialize_default_data()
469
+	{
470
+		/**
471
+		 * Called when an addon is ensuring its default data is set (possibly called
472
+		 * on a reactivation, so first check for the absence of other data before setting
473
+		 * default data)
474
+		 *
475
+		 * @param EE_Addon $addon the addon that called this
476
+		 */
477
+		do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
478
+		// override to insert default data. It is safe to use the models here
479
+		// because the site should not be in maintenance mode
480
+	}
481
+
482
+
483
+	/**
484
+	 * EE Core detected that this addon has been upgraded. We should check if there
485
+	 * are any new migration scripts, and if so put the site into maintenance mode until
486
+	 * they're ran
487
+	 *
488
+	 * @return void
489
+	 */
490
+	public function upgrade()
491
+	{
492
+		$classname = get_class($this);
493
+		do_action("AHEE__{$classname}__upgrade");
494
+		do_action('AHEE__EE_Addon__upgrade', $this);
495
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
496
+		// also it's possible there is new default data that needs to be added
497
+		add_action(
498
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
499
+			[$this, 'initialize_db_if_no_migrations_required']
500
+		);
501
+	}
502
+
503
+
504
+	/**
505
+	 * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
506
+	 */
507
+	public function downgrade()
508
+	{
509
+		$classname = get_class($this);
510
+		do_action("AHEE__{$classname}__downgrade");
511
+		do_action('AHEE__EE_Addon__downgrade', $this);
512
+		// it's possible there's old default data that needs to be double-checked
513
+		add_action(
514
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
515
+			[$this, 'initialize_db_if_no_migrations_required']
516
+		);
517
+	}
518
+
519
+
520
+	/**
521
+	 * set_db_update_option_name
522
+	 * Until we do something better, we'll just check for migration scripts upon
523
+	 * plugin activation only. In the future, we'll want to do it on plugin updates too
524
+	 *
525
+	 * @return bool
526
+	 */
527
+	public function set_db_update_option_name(): bool
528
+	{
529
+		EE_Error::doing_it_wrong(
530
+			__FUNCTION__,
531
+			esc_html__(
532
+				'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
533
+				'event_espresso'
534
+			),
535
+			'4.3.0.alpha.016'
536
+		);
537
+		// let's just handle this on the next request, ok? right now we're just not really ready
538
+		return $this->set_activation_indicator_option();
539
+	}
540
+
541
+
542
+	/**
543
+	 * Returns the name of the activation indicator option
544
+	 * (an option which is set temporarily to indicate that this addon was just activated)
545
+	 *
546
+	 * @return string
547
+	 * @deprecated since version 4.3.0.alpha.016
548
+	 */
549
+	public function get_db_update_option_name(): string
550
+	{
551
+		EE_Error::doing_it_wrong(
552
+			__FUNCTION__,
553
+			esc_html__(
554
+				'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
555
+				'event_espresso'
556
+			),
557
+			'4.3.0.alpha.016'
558
+		);
559
+		return $this->get_activation_indicator_option_name();
560
+	}
561
+
562
+
563
+	/**
564
+	 * When the addon is activated, this should be called to set a wordpress option that
565
+	 * indicates it was activated. This is especially useful for detecting reactivations.
566
+	 *
567
+	 * @return bool
568
+	 */
569
+	public function set_activation_indicator_option(): bool
570
+	{
571
+		// let's just handle this on the next request, ok? right now we're just not really ready
572
+		return update_option($this->get_activation_indicator_option_name(), true);
573
+	}
574
+
575
+
576
+	/**
577
+	 * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
578
+	 *
579
+	 * @return string
580
+	 */
581
+	public function get_activation_indicator_option_name(): string
582
+	{
583
+		return 'ee_activation_' . $this->name();
584
+	}
585
+
586
+
587
+	/**
588
+	 * Used by EE_System to set the request type of this addon. Should not be used by addon developers
589
+	 *
590
+	 * @param int $req_type
591
+	 */
592
+	public function set_req_type(int $req_type)
593
+	{
594
+		$this->_req_type = $req_type;
595
+	}
596
+
597
+
598
+	/**
599
+	 * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
600
+	 * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
601
+	 * EE_System when it is checking for new install or upgrades of addons
602
+	 */
603
+	public function detect_req_type($redetect = false): int
604
+	{
605
+		if ($this->_req_type === null || $redetect) {
606
+			$this->detect_activation_or_upgrade();
607
+		}
608
+		return $this->_req_type;
609
+	}
610
+
611
+
612
+	/**
613
+	 * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
614
+	 * Should only be called once per request
615
+	 *
616
+	 * @return void
617
+	 */
618
+	public function detect_activation_or_upgrade()
619
+	{
620
+		$activation_history_for_addon = $this->get_activation_history();
621
+		$request_type                 = EE_System::detect_req_type_given_activation_history(
622
+			$activation_history_for_addon,
623
+			$this->get_activation_indicator_option_name(),
624
+			$this->version()
625
+		);
626
+		$this->set_req_type($request_type);
627
+		$classname = get_class($this);
628
+		switch ($request_type) {
629
+			case EE_System::req_type_new_activation:
630
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
631
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
632
+				$this->new_install();
633
+				$this->update_list_of_installed_versions($activation_history_for_addon);
634
+				break;
635
+			case EE_System::req_type_reactivation:
636
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
637
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
638
+				$this->reactivation();
639
+				$this->update_list_of_installed_versions($activation_history_for_addon);
640
+				break;
641
+			case EE_System::req_type_upgrade:
642
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
643
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
644
+				$this->upgrade();
645
+				$this->update_list_of_installed_versions($activation_history_for_addon);
646
+				break;
647
+			case EE_System::req_type_downgrade:
648
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
649
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
650
+				$this->downgrade();
651
+				$this->update_list_of_installed_versions($activation_history_for_addon);
652
+				break;
653
+			case EE_System::req_type_normal:
654
+			default:
655
+				break;
656
+		}
657
+
658
+		do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
659
+	}
660
+
661
+
662
+	/**
663
+	 * Updates the version history for this addon
664
+	 *
665
+	 * @param array  $version_history
666
+	 * @param string $current_version_to_add
667
+	 * @return boolean success
668
+	 */
669
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
670
+	{
671
+		if (! $version_history) {
672
+			$version_history = $this->get_activation_history();
673
+		}
674
+		if ($current_version_to_add === null) {
675
+			$current_version_to_add = $this->version();
676
+		}
677
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
678
+		return update_option($this->get_activation_history_option_name(), $version_history);
679
+	}
680
+
681
+
682
+	/**
683
+	 * Gets the name of the wp option that stores the activation history
684
+	 * of this addon
685
+	 *
686
+	 * @return string
687
+	 */
688
+	public function get_activation_history_option_name(): string
689
+	{
690
+		return self::ee_addon_version_history_option_prefix . $this->name();
691
+	}
692
+
693
+
694
+	/**
695
+	 * Gets the wp option which stores the activation history for this addon
696
+	 *
697
+	 * @return array
698
+	 */
699
+	public function get_activation_history(): array
700
+	{
701
+		return get_option($this->get_activation_history_option_name(), []);
702
+	}
703
+
704
+
705
+	/**
706
+	 * @param string $config_section
707
+	 */
708
+	public function set_config_section($config_section = '')
709
+	{
710
+		$this->_config_section = ! empty($config_section) ? $config_section : 'addons';
711
+	}
712
+
713
+
714
+	/**
715
+	 * Sets the filepath to the main plugin file
716
+	 *
717
+	 * @param string $filepath
718
+	 */
719
+	public function set_main_plugin_file(string $filepath)
720
+	{
721
+		$this->_main_plugin_file = $filepath;
722
+	}
723
+
724
+
725
+	/**
726
+	 * gets the filepath to teh main file
727
+	 *
728
+	 * @return string
729
+	 */
730
+	public function get_main_plugin_file(): string
731
+	{
732
+		return $this->_main_plugin_file;
733
+	}
734
+
735
+
736
+	/**
737
+	 * Gets the filename (no path) of the main file (the main file loaded
738
+	 * by WP)
739
+	 *
740
+	 * @return string
741
+	 */
742
+	public function get_main_plugin_file_basename(): string
743
+	{
744
+		return plugin_basename($this->get_main_plugin_file());
745
+	}
746
+
747
+
748
+	/**
749
+	 * Gets the folder name which contains the main plugin file
750
+	 *
751
+	 * @return string
752
+	 */
753
+	public function get_main_plugin_file_dirname(): string
754
+	{
755
+		return dirname($this->get_main_plugin_file());
756
+	}
757
+
758
+
759
+	/**
760
+	 * sets hooks used in the admin
761
+	 *
762
+	 * @return void
763
+	 */
764
+	public function admin_init()
765
+	{
766
+		// is admin and not in M-Mode ?
767
+		if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
768
+			add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
769
+			add_filter('after_plugin_row_' . $this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
770
+		}
771
+	}
772
+
773
+
774
+	/**
775
+	 * plugin_actions
776
+	 * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
777
+	 *
778
+	 * @param array  $links
779
+	 * @param string $file
780
+	 * @return array
781
+	 */
782
+	public function plugin_action_links(array $links, string $file): array
783
+	{
784
+		if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
785
+			// before other links
786
+			array_unshift(
787
+				$links,
788
+				'<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
789
+				. esc_html__('Settings', 'event_espresso')
790
+				. '</a>'
791
+			);
792
+		}
793
+		return $links;
794
+	}
795
+
796
+
797
+	/**
798
+	 * after_plugin_row
799
+	 * Add additional content to the plugins page plugin row
800
+	 * Inserts another row
801
+	 *
802
+	 * @param string $plugin_file
803
+	 * @param array  $plugin_data
804
+	 * @param string $status
805
+	 * @return void
806
+	 */
807
+	public function after_plugin_row(string $plugin_file, array $plugin_data, string $status)
808
+	{
809
+		$after_plugin_row = '';
810
+		$plugins_page_row = $this->get_plugins_page_row();
811
+		if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
812
+			$class       = $status ? 'active' : 'inactive';
813
+			$link_text   = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
814
+			$link_url    = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
815
+			$description = isset($plugins_page_row['description'])
816
+				? $plugins_page_row['description']
817
+				: '';
818
+			if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
819
+				$after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
820
+				$after_plugin_row .= '<th class="check-column" scope="row"></th>';
821
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
822
+				$after_plugin_row .= '<style>
823 823
 .ee-button,
824 824
 .ee-button:active,
825 825
 .ee-button:visited {
@@ -856,67 +856,67 @@  discard block
 block discarded – undo
856 856
 }
857 857
 .ee-button:active { top:0; }
858 858
 </style>';
859
-                $after_plugin_row .= '
859
+				$after_plugin_row .= '
860 860
 <p class="ee-addon-upsell-info-dv">
861 861
 	<a class="ee-button" href="' . $link_url . '">'
862
-                                     . $link_text
863
-                                     . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
864
-                                     . '</a>
862
+									 . $link_text
863
+									 . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
864
+									 . '</a>
865 865
 </p>';
866
-                $after_plugin_row .= '</td>';
867
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
868
-                $after_plugin_row .= $description;
869
-                $after_plugin_row .= '</td>';
870
-                $after_plugin_row .= '</tr>';
871
-            } else {
872
-                $after_plugin_row .= $description;
873
-            }
874
-        }
875
-
876
-        echo $after_plugin_row;
877
-    }
878
-
879
-
880
-    /**
881
-     * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
882
-     * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
883
-     * for back compat reasons.
884
-     *
885
-     * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
886
-     *
887
-     * It is recommended, if client code is `de-registering` an add-on, then do it on the
888
-     * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
889
-     * callback does not get run/set in that request.
890
-     *
891
-     * Also, keep in mind that if a registered add-on happens to be deactivated via
892
-     * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
893
-     * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
894
-     * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
895
-     * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
896
-     * to call `parent::deactivation`.
897
-     *
898
-     * @since 4.9.26
899
-     */
900
-    public function after_registration()
901
-    {
902
-        // cricket chirp... cricket chirp...
903
-    }
904
-
905
-
906
-    /**
907
-     * @return string
908
-     */
909
-    public function getPueSlug(): string
910
-    {
911
-        return $this->pue_slug;
912
-    }
913
-
914
-
915
-    /**
916
-     * @param string $pue_slug
917
-     */
918
-    public function setPueSlug(string $pue_slug)
919
-    {
920
-        $this->pue_slug = $pue_slug;
921
-    }
866
+				$after_plugin_row .= '</td>';
867
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
868
+				$after_plugin_row .= $description;
869
+				$after_plugin_row .= '</td>';
870
+				$after_plugin_row .= '</tr>';
871
+			} else {
872
+				$after_plugin_row .= $description;
873
+			}
874
+		}
875
+
876
+		echo $after_plugin_row;
877
+	}
878
+
879
+
880
+	/**
881
+	 * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
882
+	 * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
883
+	 * for back compat reasons.
884
+	 *
885
+	 * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
886
+	 *
887
+	 * It is recommended, if client code is `de-registering` an add-on, then do it on the
888
+	 * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
889
+	 * callback does not get run/set in that request.
890
+	 *
891
+	 * Also, keep in mind that if a registered add-on happens to be deactivated via
892
+	 * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
893
+	 * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
894
+	 * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
895
+	 * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
896
+	 * to call `parent::deactivation`.
897
+	 *
898
+	 * @since 4.9.26
899
+	 */
900
+	public function after_registration()
901
+	{
902
+		// cricket chirp... cricket chirp...
903
+	}
904
+
905
+
906
+	/**
907
+	 * @return string
908
+	 */
909
+	public function getPueSlug(): string
910
+	{
911
+		return $this->pue_slug;
912
+	}
913
+
914
+
915
+	/**
916
+	 * @param string $pue_slug
917
+	 */
918
+	public function setPueSlug(string $pue_slug)
919
+	{
920
+		$this->pue_slug = $pue_slug;
921
+	}
922 922
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
      */
581 581
     public function get_activation_indicator_option_name(): string
582 582
     {
583
-        return 'ee_activation_' . $this->name();
583
+        return 'ee_activation_'.$this->name();
584 584
     }
585 585
 
586 586
 
@@ -668,13 +668,13 @@  discard block
 block discarded – undo
668 668
      */
669 669
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
670 670
     {
671
-        if (! $version_history) {
671
+        if ( ! $version_history) {
672 672
             $version_history = $this->get_activation_history();
673 673
         }
674 674
         if ($current_version_to_add === null) {
675 675
             $current_version_to_add = $this->version();
676 676
         }
677
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
677
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
678 678
         return update_option($this->get_activation_history_option_name(), $version_history);
679 679
     }
680 680
 
@@ -687,7 +687,7 @@  discard block
 block discarded – undo
687 687
      */
688 688
     public function get_activation_history_option_name(): string
689 689
     {
690
-        return self::ee_addon_version_history_option_prefix . $this->name();
690
+        return self::ee_addon_version_history_option_prefix.$this->name();
691 691
     }
692 692
 
693 693
 
@@ -766,7 +766,7 @@  discard block
 block discarded – undo
766 766
         // is admin and not in M-Mode ?
767 767
         if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
768 768
             add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
769
-            add_filter('after_plugin_row_' . $this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
769
+            add_filter('after_plugin_row_'.$this->_plugin_basename, [$this, 'after_plugin_row'], 10, 3);
770 770
         }
771 771
     }
772 772
 
@@ -785,7 +785,7 @@  discard block
 block discarded – undo
785 785
             // before other links
786 786
             array_unshift(
787 787
                 $links,
788
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
788
+                '<a href="admin.php?page='.$this->plugin_action_slug().'">'
789 789
                 . esc_html__('Settings', 'event_espresso')
790 790
                 . '</a>'
791 791
             );
@@ -808,15 +808,15 @@  discard block
 block discarded – undo
808 808
     {
809 809
         $after_plugin_row = '';
810 810
         $plugins_page_row = $this->get_plugins_page_row();
811
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
811
+        if ( ! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
812 812
             $class       = $status ? 'active' : 'inactive';
813 813
             $link_text   = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
814 814
             $link_url    = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
815 815
             $description = isset($plugins_page_row['description'])
816 816
                 ? $plugins_page_row['description']
817 817
                 : '';
818
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
819
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
818
+            if ( ! empty($link_text) && ! empty($link_url) && ! empty($description)) {
819
+                $after_plugin_row .= '<tr id="'.sanitize_title($plugin_file).'-ee-addon" class="'.$class.'">';
820 820
                 $after_plugin_row .= '<th class="check-column" scope="row"></th>';
821 821
                 $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
822 822
                 $after_plugin_row .= '<style>
@@ -858,7 +858,7 @@  discard block
 block discarded – undo
858 858
 </style>';
859 859
                 $after_plugin_row .= '
860 860
 <p class="ee-addon-upsell-info-dv">
861
-	<a class="ee-button" href="' . $link_url . '">'
861
+	<a class="ee-button" href="' . $link_url.'">'
862 862
                                      . $link_text
863 863
                                      . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
864 864
                                      . '</a>
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 1 patch
Indentation   +4555 added lines, -4555 removed lines patch added patch discarded remove patch
@@ -19,2650 +19,2650 @@  discard block
 block discarded – undo
19 19
 class Messages_Admin_Page extends EE_Admin_Page
20 20
 {
21 21
 
22
-    /**
23
-     * @type EE_Message_Resource_Manager $_message_resource_manager
24
-     */
25
-    protected $_message_resource_manager;
26
-
27
-    /**
28
-     * @type string $_active_message_type_name
29
-     */
30
-    protected $_active_message_type_name = '';
31
-
32
-    /**
33
-     * @type EE_messenger $_active_messenger
34
-     */
35
-    protected $_active_messenger;
36
-    protected $_activate_state;
37
-    protected $_activate_meta_box_type;
38
-    protected $_current_message_meta_box;
39
-    protected $_current_message_meta_box_object;
40
-    protected $_context_switcher;
41
-    protected $_shortcodes = array();
42
-    protected $_active_messengers = array();
43
-    protected $_active_message_types = array();
44
-
45
-    /**
46
-     * @var EE_Message_Template_Group $_message_template_group
47
-     */
48
-    protected $_message_template_group;
49
-    protected $_m_mt_settings = array();
50
-
51
-
52
-    /**
53
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
-     * IF there is no group then it gets automatically set to the Default template pack.
55
-     *
56
-     * @since 4.5.0
57
-     *
58
-     * @var EE_Messages_Template_Pack
59
-     */
60
-    protected $_template_pack;
61
-
62
-
63
-    /**
64
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
-     * group is.  If there is no group then it automatically gets set to default.
66
-     *
67
-     * @since 4.5.0
68
-     *
69
-     * @var string
70
-     */
71
-    protected $_variation;
72
-
73
-
74
-    /**
75
-     * @param bool $routing
76
-     * @throws EE_Error
77
-     */
78
-    public function __construct($routing = true)
79
-    {
80
-        // make sure messages autoloader is running
81
-        EED_Messages::set_autoloaders();
82
-        parent::__construct($routing);
83
-    }
84
-
85
-
86
-    protected function _init_page_props()
87
-    {
88
-        $this->page_slug = EE_MSG_PG_SLUG;
89
-        $this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
-        $this->_admin_base_url = EE_MSG_ADMIN_URL;
91
-        $this->_admin_base_path = EE_MSG_ADMIN;
92
-
93
-        $this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
-            : array();
95
-
96
-        $this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
-        $this->_load_message_resource_manager();
98
-    }
99
-
100
-
101
-    /**
102
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
-     *
104
-     * @throws EE_Error
105
-     * @throws InvalidDataTypeException
106
-     * @throws InvalidInterfaceException
107
-     * @throws InvalidArgumentException
108
-     * @throws ReflectionException
109
-     */
110
-    protected function _load_message_resource_manager()
111
-    {
112
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
-    }
114
-
115
-
116
-    /**
117
-     * @deprecated 4.9.9.rc.014
118
-     * @return array
119
-     * @throws EE_Error
120
-     * @throws InvalidArgumentException
121
-     * @throws InvalidDataTypeException
122
-     * @throws InvalidInterfaceException
123
-     */
124
-    public function get_messengers_for_list_table()
125
-    {
126
-        EE_Error::doing_it_wrong(
127
-            __METHOD__,
128
-            sprintf(
129
-                esc_html__(
130
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
131
-                    'event_espresso'
132
-                ),
133
-                'Messages_Admin_Page::get_messengers_select_input()'
134
-            ),
135
-            '4.9.9.rc.014'
136
-        );
137
-
138
-        $m_values = array();
139
-        $active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
-        // setup messengers for selects
141
-        $i = 1;
142
-        foreach ($active_messengers as $active_messenger) {
143
-            if ($active_messenger instanceof EE_Message) {
144
-                $m_values[ $i ]['id'] = $active_messenger->messenger();
145
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
-                $i++;
147
-            }
148
-        }
149
-
150
-        return $m_values;
151
-    }
152
-
153
-
154
-    /**
155
-     * @deprecated 4.9.9.rc.014
156
-     * @return array
157
-     * @throws EE_Error
158
-     * @throws InvalidArgumentException
159
-     * @throws InvalidDataTypeException
160
-     * @throws InvalidInterfaceException
161
-     */
162
-    public function get_message_types_for_list_table()
163
-    {
164
-        EE_Error::doing_it_wrong(
165
-            __METHOD__,
166
-            sprintf(
167
-                esc_html__(
168
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
169
-                    'event_espresso'
170
-                ),
171
-                'Messages_Admin_Page::get_message_types_select_input()'
172
-            ),
173
-            '4.9.9.rc.014'
174
-        );
175
-
176
-        $mt_values = array();
177
-        $active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
-        $i = 1;
179
-        foreach ($active_messages as $active_message) {
180
-            if ($active_message instanceof EE_Message) {
181
-                $mt_values[ $i ]['id'] = $active_message->message_type();
182
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
-                $i++;
184
-            }
185
-        }
186
-
187
-        return $mt_values;
188
-    }
189
-
190
-
191
-    /**
192
-     * @deprecated 4.9.9.rc.014
193
-     * @return array
194
-     * @throws EE_Error
195
-     * @throws InvalidArgumentException
196
-     * @throws InvalidDataTypeException
197
-     * @throws InvalidInterfaceException
198
-     */
199
-    public function get_contexts_for_message_types_for_list_table()
200
-    {
201
-        EE_Error::doing_it_wrong(
202
-            __METHOD__,
203
-            sprintf(
204
-                esc_html__(
205
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
206
-                    'event_espresso'
207
-                ),
208
-                'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
-            ),
210
-            '4.9.9.rc.014'
211
-        );
212
-
213
-        $contexts = array();
214
-        $active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
-        foreach ($active_message_contexts as $active_message) {
216
-            if ($active_message instanceof EE_Message) {
217
-                $message_type = $active_message->message_type_object();
218
-                if ($message_type instanceof EE_message_type) {
219
-                    $message_type_contexts = $message_type->get_contexts();
220
-                    foreach ($message_type_contexts as $context => $context_details) {
221
-                        $contexts[ $context ] = $context_details['label'];
222
-                    }
223
-                }
224
-            }
225
-        }
226
-
227
-        return $contexts;
228
-    }
229
-
230
-
231
-    /**
232
-     * Generate select input with provided messenger options array.
233
-     *
234
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
-     *                                 labels.
236
-     * @return string
237
-     * @throws EE_Error
238
-     */
239
-    public function get_messengers_select_input($messenger_options)
240
-    {
241
-        // if empty or just one value then just return an empty string
242
-        if (
243
-            empty($messenger_options)
244
-            || ! is_array($messenger_options)
245
-            || count($messenger_options) === 1
246
-        ) {
247
-            return '';
248
-        }
249
-        // merge in default
250
-        $messenger_options = array_merge(
251
-            array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
252
-            $messenger_options
253
-        );
254
-        $input = new EE_Select_Input(
255
-            $messenger_options,
256
-            array(
257
-                'html_name'  => 'ee_messenger_filter_by',
258
-                'html_id'    => 'ee_messenger_filter_by',
259
-                'html_class' => 'wide',
260
-                'default'    => isset($this->_req_data['ee_messenger_filter_by'])
261
-                    ? sanitize_title($this->_req_data['ee_messenger_filter_by'])
262
-                    : 'none_selected',
263
-            )
264
-        );
265
-
266
-        return $input->get_html_for_input();
267
-    }
268
-
269
-
270
-    /**
271
-     * Generate select input with provided message type options array.
272
-     *
273
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
274
-     *                                    message type labels
275
-     * @return string
276
-     * @throws EE_Error
277
-     */
278
-    public function get_message_types_select_input($message_type_options)
279
-    {
280
-        // if empty or count of options is 1 then just return an empty string
281
-        if (
282
-            empty($message_type_options)
283
-            || ! is_array($message_type_options)
284
-            || count($message_type_options) === 1
285
-        ) {
286
-            return '';
287
-        }
288
-        // merge in default
289
-        $message_type_options = array_merge(
290
-            array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
291
-            $message_type_options
292
-        );
293
-        $input = new EE_Select_Input(
294
-            $message_type_options,
295
-            array(
296
-                'html_name'  => 'ee_message_type_filter_by',
297
-                'html_id'    => 'ee_message_type_filter_by',
298
-                'html_class' => 'wide',
299
-                'default'    => isset($this->_req_data['ee_message_type_filter_by'])
300
-                    ? sanitize_title($this->_req_data['ee_message_type_filter_by'])
301
-                    : 'none_selected',
302
-            )
303
-        );
304
-
305
-        return $input->get_html_for_input();
306
-    }
307
-
308
-
309
-    /**
310
-     * Generate select input with provide message type contexts array.
311
-     *
312
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
313
-     *                               context label.
314
-     * @return string
315
-     * @throws EE_Error
316
-     */
317
-    public function get_contexts_for_message_types_select_input($context_options)
318
-    {
319
-        // if empty or count of options is one then just return empty string
320
-        if (
321
-            empty($context_options)
322
-            || ! is_array($context_options)
323
-            || count($context_options) === 1
324
-        ) {
325
-            return '';
326
-        }
327
-        // merge in default
328
-        $context_options = array_merge(
329
-            array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
330
-            $context_options
331
-        );
332
-        $input = new EE_Select_Input(
333
-            $context_options,
334
-            array(
335
-                'html_name'  => 'ee_context_filter_by',
336
-                'html_id'    => 'ee_context_filter_by',
337
-                'html_class' => 'wide',
338
-                'default'    => isset($this->_req_data['ee_context_filter_by'])
339
-                    ? sanitize_title($this->_req_data['ee_context_filter_by'])
340
-                    : 'none_selected',
341
-            )
342
-        );
343
-
344
-        return $input->get_html_for_input();
345
-    }
346
-
347
-
348
-    protected function _ajax_hooks()
349
-    {
350
-        add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
351
-        add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
352
-        add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
353
-        add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
354
-        add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
355
-        add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
356
-    }
357
-
358
-
359
-    protected function _define_page_props()
360
-    {
361
-        $this->_admin_page_title = $this->page_label;
362
-        $this->_labels = array(
363
-            'buttons'    => array(
364
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
365
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
366
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
367
-            ),
368
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
369
-        );
370
-    }
371
-
372
-
373
-    /**
374
-     *        an array for storing key => value pairs of request actions and their corresponding methods
375
-     *
376
-     * @access protected
377
-     * @return void
378
-     */
379
-    protected function _set_page_routes()
380
-    {
381
-        $grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
382
-            ? $this->_req_data['GRP_ID']
383
-            : 0;
384
-        $grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
385
-            ? $this->_req_data['id']
386
-            : $grp_id;
387
-        $msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
388
-            ? $this->_req_data['MSG_ID']
389
-            : 0;
390
-
391
-        $this->_page_routes = array(
392
-            'default'                          => array(
393
-                'func'       => '_message_queue_list_table',
394
-                'capability' => 'ee_read_global_messages',
395
-            ),
396
-            'global_mtps'                      => array(
397
-                'func'       => '_ee_default_messages_overview_list_table',
398
-                'capability' => 'ee_read_global_messages',
399
-            ),
400
-            'custom_mtps'                      => array(
401
-                'func'       => '_custom_mtps_preview',
402
-                'capability' => 'ee_read_messages',
403
-            ),
404
-            'add_new_message_template'         => array(
405
-                'func'       => '_add_message_template',
406
-                'capability' => 'ee_edit_messages',
407
-                'noheader'   => true,
408
-            ),
409
-            'edit_message_template'            => array(
410
-                'func'       => '_edit_message_template',
411
-                'capability' => 'ee_edit_message',
412
-                'obj_id'     => $grp_id,
413
-            ),
414
-            'preview_message'                  => array(
415
-                'func'               => '_preview_message',
416
-                'capability'         => 'ee_read_message',
417
-                'obj_id'             => $grp_id,
418
-                'noheader'           => true,
419
-                'headers_sent_route' => 'display_preview_message',
420
-            ),
421
-            'display_preview_message'          => array(
422
-                'func'       => '_display_preview_message',
423
-                'capability' => 'ee_read_message',
424
-                'obj_id'     => $grp_id,
425
-            ),
426
-            'insert_message_template'          => array(
427
-                'func'       => '_insert_or_update_message_template',
428
-                'capability' => 'ee_edit_messages',
429
-                'args'       => array('new_template' => true),
430
-                'noheader'   => true,
431
-            ),
432
-            'update_message_template'          => array(
433
-                'func'       => '_insert_or_update_message_template',
434
-                'capability' => 'ee_edit_message',
435
-                'obj_id'     => $grp_id,
436
-                'args'       => array('new_template' => false),
437
-                'noheader'   => true,
438
-            ),
439
-            'trash_message_template'           => array(
440
-                'func'       => '_trash_or_restore_message_template',
441
-                'capability' => 'ee_delete_message',
442
-                'obj_id'     => $grp_id,
443
-                'args'       => array('trash' => true, 'all' => true),
444
-                'noheader'   => true,
445
-            ),
446
-            'trash_message_template_context'   => array(
447
-                'func'       => '_trash_or_restore_message_template',
448
-                'capability' => 'ee_delete_message',
449
-                'obj_id'     => $grp_id,
450
-                'args'       => array('trash' => true),
451
-                'noheader'   => true,
452
-            ),
453
-            'restore_message_template'         => array(
454
-                'func'       => '_trash_or_restore_message_template',
455
-                'capability' => 'ee_delete_message',
456
-                'obj_id'     => $grp_id,
457
-                'args'       => array('trash' => false, 'all' => true),
458
-                'noheader'   => true,
459
-            ),
460
-            'restore_message_template_context' => array(
461
-                'func'       => '_trash_or_restore_message_template',
462
-                'capability' => 'ee_delete_message',
463
-                'obj_id'     => $grp_id,
464
-                'args'       => array('trash' => false),
465
-                'noheader'   => true,
466
-            ),
467
-            'delete_message_template'          => array(
468
-                'func'       => '_delete_message_template',
469
-                'capability' => 'ee_delete_message',
470
-                'obj_id'     => $grp_id,
471
-                'noheader'   => true,
472
-            ),
473
-            'reset_to_default'                 => array(
474
-                'func'       => '_reset_to_default_template',
475
-                'capability' => 'ee_edit_message',
476
-                'obj_id'     => $grp_id,
477
-                'noheader'   => true,
478
-            ),
479
-            'settings'                         => array(
480
-                'func'       => '_settings',
481
-                'capability' => 'manage_options',
482
-            ),
483
-            'update_global_settings'           => array(
484
-                'func'       => '_update_global_settings',
485
-                'capability' => 'manage_options',
486
-                'noheader'   => true,
487
-            ),
488
-            'generate_now'                     => array(
489
-                'func'       => '_generate_now',
490
-                'capability' => 'ee_send_message',
491
-                'noheader'   => true,
492
-            ),
493
-            'generate_and_send_now'            => array(
494
-                'func'       => '_generate_and_send_now',
495
-                'capability' => 'ee_send_message',
496
-                'noheader'   => true,
497
-            ),
498
-            'queue_for_resending'              => array(
499
-                'func'       => '_queue_for_resending',
500
-                'capability' => 'ee_send_message',
501
-                'noheader'   => true,
502
-            ),
503
-            'send_now'                         => array(
504
-                'func'       => '_send_now',
505
-                'capability' => 'ee_send_message',
506
-                'noheader'   => true,
507
-            ),
508
-            'delete_ee_message'                => array(
509
-                'func'       => '_delete_ee_messages',
510
-                'capability' => 'ee_delete_messages',
511
-                'noheader'   => true,
512
-            ),
513
-            'delete_ee_messages'               => array(
514
-                'func'       => '_delete_ee_messages',
515
-                'capability' => 'ee_delete_messages',
516
-                'noheader'   => true,
517
-                'obj_id'     => $msg_id,
518
-            ),
519
-        );
520
-    }
521
-
522
-
523
-    protected function _set_page_config()
524
-    {
525
-        $this->_page_config = array(
526
-            'default'                  => array(
527
-                'nav'           => array(
528
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
529
-                    'order' => 10,
530
-                ),
531
-                'list_table'    => 'EE_Message_List_Table',
532
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
533
-                'require_nonce' => false,
534
-            ),
535
-            'global_mtps'              => array(
536
-                'nav'           => array(
537
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
538
-                    'order' => 20,
539
-                ),
540
-                'list_table'    => 'Messages_Template_List_Table',
541
-                'help_tabs'     => array(
542
-                    'messages_overview_help_tab'                                => array(
543
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
544
-                        'filename' => 'messages_overview',
545
-                    ),
546
-                    'messages_overview_messages_table_column_headings_help_tab' => array(
547
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
548
-                        'filename' => 'messages_overview_table_column_headings',
549
-                    ),
550
-                    'messages_overview_messages_filters_help_tab'               => array(
551
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
552
-                        'filename' => 'messages_overview_filters',
553
-                    ),
554
-                    'messages_overview_messages_views_help_tab'                 => array(
555
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
556
-                        'filename' => 'messages_overview_views',
557
-                    ),
558
-                    'message_overview_message_types_help_tab'                   => array(
559
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
560
-                        'filename' => 'messages_overview_types',
561
-                    ),
562
-                    'messages_overview_messengers_help_tab'                     => array(
563
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
564
-                        'filename' => 'messages_overview_messengers',
565
-                    ),
566
-                ),
567
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
568
-                // 'help_tour'     => array('Messages_Overview_Help_Tour'),
569
-                'require_nonce' => false,
570
-            ),
571
-            'custom_mtps'              => array(
572
-                'nav'           => array(
573
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
574
-                    'order' => 30,
575
-                ),
576
-                'help_tabs'     => array(),
577
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
578
-                // 'help_tour'     => array(),
579
-                'require_nonce' => false,
580
-            ),
581
-            'add_new_message_template' => array(
582
-                'nav'           => array(
583
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
584
-                    'order'      => 5,
585
-                    'persistent' => false,
586
-                ),
587
-                'require_nonce' => false,
588
-            ),
589
-            'edit_message_template'    => array(
590
-                'labels'        => array(
591
-                    'buttons'    => array(
592
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
593
-                    ),
594
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
595
-                ),
596
-                'nav'           => array(
597
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
598
-                    'order'      => 5,
599
-                    'persistent' => false,
600
-                    'url'        => '',
601
-                ),
602
-                'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
603
-                'has_metaboxes' => true,
604
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
605
-                // 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
606
-                'help_tabs'     => array(
607
-                    'edit_message_template'            => array(
608
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
609
-                        'callback' => 'edit_message_template_help_tab',
610
-                    ),
611
-                    'message_templates_help_tab'       => array(
612
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
613
-                        'filename' => 'messages_templates',
614
-                    ),
615
-                    'message_template_shortcodes'      => array(
616
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
617
-                        'callback' => 'message_template_shortcodes_help_tab',
618
-                    ),
619
-                    'message_preview_help_tab'         => array(
620
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
621
-                        'filename' => 'messages_preview',
622
-                    ),
623
-                    'messages_overview_other_help_tab' => array(
624
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
625
-                        'filename' => 'messages_overview_other',
626
-                    ),
627
-                ),
628
-                'require_nonce' => false,
629
-            ),
630
-            'display_preview_message'  => array(
631
-                'nav'           => array(
632
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
633
-                    'order'      => 5,
634
-                    'url'        => '',
635
-                    'persistent' => false,
636
-                ),
637
-                'help_tabs'     => array(
638
-                    'preview_message' => array(
639
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
640
-                        'callback' => 'preview_message_help_tab',
641
-                    ),
642
-                ),
643
-                'require_nonce' => false,
644
-            ),
645
-            'settings'                 => array(
646
-                'nav'           => array(
647
-                    'label' => esc_html__('Settings', 'event_espresso'),
648
-                    'order' => 40,
649
-                ),
650
-                'metaboxes'     => array('_messages_settings_metaboxes'),
651
-                'help_tabs'     => array(
652
-                    'messages_settings_help_tab'               => array(
653
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
654
-                        'filename' => 'messages_settings',
655
-                    ),
656
-                    'messages_settings_message_types_help_tab' => array(
657
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
658
-                        'filename' => 'messages_settings_message_types',
659
-                    ),
660
-                    'messages_settings_messengers_help_tab'    => array(
661
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
662
-                        'filename' => 'messages_settings_messengers',
663
-                    ),
664
-                ),
665
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
666
-                // 'help_tour'     => array('Messages_Settings_Help_Tour'),
667
-                'require_nonce' => false,
668
-            ),
669
-        );
670
-    }
671
-
672
-
673
-    protected function _add_screen_options()
674
-    {
675
-        // todo
676
-    }
677
-
678
-
679
-    protected function _add_screen_options_global_mtps()
680
-    {
681
-        /**
682
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
683
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
684
-         */
685
-        $page_title = $this->_admin_page_title;
686
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
687
-        $this->_per_page_screen_option();
688
-        $this->_admin_page_title = $page_title;
689
-    }
690
-
691
-
692
-    protected function _add_screen_options_default()
693
-    {
694
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
695
-        $this->_per_page_screen_option();
696
-    }
697
-
698
-
699
-    // none of the below group are currently used for Messages
700
-    protected function _add_feature_pointers()
701
-    {
702
-    }
703
-
704
-    public function admin_init()
705
-    {
706
-    }
707
-
708
-    public function admin_notices()
709
-    {
710
-    }
711
-
712
-    public function admin_footer_scripts()
713
-    {
714
-    }
715
-
716
-
717
-    public function messages_help_tab()
718
-    {
719
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
720
-    }
721
-
722
-
723
-    public function messengers_help_tab()
724
-    {
725
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
726
-    }
727
-
728
-
729
-    public function message_types_help_tab()
730
-    {
731
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
732
-    }
733
-
734
-
735
-    public function messages_overview_help_tab()
736
-    {
737
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
738
-    }
739
-
740
-
741
-    public function message_templates_help_tab()
742
-    {
743
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
744
-    }
745
-
746
-
747
-    public function edit_message_template_help_tab()
748
-    {
749
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
750
-                        . esc_attr__('Editor Title', 'event_espresso')
751
-                        . '" />';
752
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
753
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
754
-                        . '" />';
755
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
756
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
757
-                        . '" />';
758
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
759
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
760
-                        . '" />';
761
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
762
-                        . esc_attr__('Publish Metabox', 'event_espresso')
763
-                        . '" />';
764
-        EEH_Template::display_template(
765
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
766
-            $args
767
-        );
768
-    }
769
-
770
-
771
-    public function message_template_shortcodes_help_tab()
772
-    {
773
-        $this->_set_shortcodes();
774
-        $args['shortcodes'] = $this->_shortcodes;
775
-        EEH_Template::display_template(
776
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
777
-            $args
778
-        );
779
-    }
780
-
781
-
782
-    public function preview_message_help_tab()
783
-    {
784
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
785
-    }
786
-
787
-
788
-    public function settings_help_tab()
789
-    {
790
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
791
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
792
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
793
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
794
-        $args['img3'] = '<div class="switch">'
795
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
796
-                        . ' type="checkbox" checked="checked">'
797
-                        . '<label for="ee-on-off-toggle-on"></label>'
798
-                        . '</div>';
799
-        $args['img4'] = '<div class="switch">'
800
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
801
-                        . ' type="checkbox">'
802
-                        . '<label for="ee-on-off-toggle-on"></label>'
803
-                        . '</div>';
804
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
805
-    }
806
-
807
-
808
-    public function load_scripts_styles()
809
-    {
810
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
811
-        wp_enqueue_style('espresso_ee_msg');
812
-
813
-        wp_register_script(
814
-            'ee-messages-settings',
815
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
816
-            array('jquery-ui-droppable', 'ee-serialize-full-array'),
817
-            EVENT_ESPRESSO_VERSION,
818
-            true
819
-        );
820
-        wp_register_script(
821
-            'ee-msg-list-table-js',
822
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
823
-            array('ee-dialog'),
824
-            EVENT_ESPRESSO_VERSION
825
-        );
826
-    }
827
-
828
-
829
-    public function load_scripts_styles_default()
830
-    {
831
-        wp_enqueue_script('ee-msg-list-table-js');
832
-    }
833
-
834
-
835
-    public function wp_editor_css($mce_css)
836
-    {
837
-        // if we're on the edit_message_template route
838
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
839
-            $message_type_name = $this->_active_message_type_name;
840
-
841
-            // we're going to REPLACE the existing mce css
842
-            // we need to get the css file location from the active messenger
843
-            $mce_css = $this->_active_messenger->get_variation(
844
-                $this->_template_pack,
845
-                $message_type_name,
846
-                true,
847
-                'wpeditor',
848
-                $this->_variation
849
-            );
850
-        }
851
-
852
-        return $mce_css;
853
-    }
854
-
855
-
856
-    public function load_scripts_styles_edit_message_template()
857
-    {
858
-
859
-        $this->_set_shortcodes();
860
-
861
-        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
862
-            esc_html__(
863
-                'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
864
-                'event_espresso'
865
-            ),
866
-            $this->_message_template_group->messenger_obj()->label['singular'],
867
-            $this->_message_template_group->message_type_obj()->label['singular']
868
-        );
869
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
870
-            'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
871
-            'event_espresso'
872
-        );
873
-        EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
874
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
875
-            'event_espresso'
876
-        );
877
-
878
-        wp_register_script(
879
-            'ee_msgs_edit_js',
880
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
881
-            array('jquery'),
882
-            EVENT_ESPRESSO_VERSION
883
-        );
884
-
885
-        wp_enqueue_script('ee_admin_js');
886
-        wp_enqueue_script('ee_msgs_edit_js');
887
-
888
-        // add in special css for tiny_mce
889
-        add_filter('mce_css', array($this, 'wp_editor_css'));
890
-    }
891
-
892
-
893
-    public function load_scripts_styles_display_preview_message()
894
-    {
895
-
896
-        $this->_set_message_template_group();
897
-
898
-        if (isset($this->_req_data['messenger'])) {
899
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
900
-                $this->_req_data['messenger']
901
-            );
902
-        }
903
-
904
-        $message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
905
-
906
-
907
-        wp_enqueue_style(
908
-            'espresso_preview_css',
909
-            $this->_active_messenger->get_variation(
910
-                $this->_template_pack,
911
-                $message_type_name,
912
-                true,
913
-                'preview',
914
-                $this->_variation
915
-            )
916
-        );
917
-    }
918
-
919
-
920
-    public function load_scripts_styles_settings()
921
-    {
922
-        wp_register_style(
923
-            'ee-message-settings',
924
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
925
-            array(),
926
-            EVENT_ESPRESSO_VERSION
927
-        );
928
-        wp_enqueue_style('ee-text-links');
929
-        wp_enqueue_style('ee-message-settings');
930
-        wp_enqueue_script('ee-messages-settings');
931
-    }
932
-
933
-
934
-    /**
935
-     * set views array for List Table
936
-     */
937
-    public function _set_list_table_views_global_mtps()
938
-    {
939
-        $this->_views = array(
940
-            'in_use' => array(
941
-                'slug'  => 'in_use',
942
-                'label' => esc_html__('In Use', 'event_espresso'),
943
-                'count' => 0,
944
-            ),
945
-        );
946
-    }
947
-
948
-
949
-    /**
950
-     * Set views array for the Custom Template List Table
951
-     */
952
-    public function _set_list_table_views_custom_mtps()
953
-    {
954
-        $this->_set_list_table_views_global_mtps();
955
-        $this->_views['in_use']['bulk_action'] = array(
956
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
957
-        );
958
-    }
959
-
960
-
961
-    /**
962
-     * set views array for message queue list table
963
-     *
964
-     * @throws InvalidDataTypeException
965
-     * @throws InvalidInterfaceException
966
-     * @throws InvalidArgumentException
967
-     * @throws EE_Error
968
-     * @throws ReflectionException
969
-     */
970
-    public function _set_list_table_views_default()
971
-    {
972
-        EE_Registry::instance()->load_helper('Template');
973
-
974
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
975
-            'ee_send_message',
976
-            'message_list_table_bulk_actions'
977
-        )
978
-            ? array(
979
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
980
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
981
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
982
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
983
-            )
984
-            : array();
985
-
986
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
987
-            'ee_delete_messages',
988
-            'message_list_table_bulk_actions'
989
-        )
990
-            ? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
991
-            : array();
992
-
993
-
994
-        $this->_views = array(
995
-            'all' => array(
996
-                'slug'        => 'all',
997
-                'label'       => esc_html__('All', 'event_espresso'),
998
-                'count'       => 0,
999
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1000
-            ),
1001
-        );
1002
-
1003
-
1004
-        foreach (EEM_Message::instance()->all_statuses() as $status) {
1005
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1006
-                continue;
1007
-            }
1008
-            $status_bulk_actions = $common_bulk_actions;
1009
-            // unset bulk actions not applying to status
1010
-            if (! empty($status_bulk_actions)) {
1011
-                switch ($status) {
1012
-                    case EEM_Message::status_idle:
1013
-                    case EEM_Message::status_resend:
1014
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1015
-                        break;
1016
-
1017
-                    case EEM_Message::status_failed:
1018
-                    case EEM_Message::status_debug_only:
1019
-                    case EEM_Message::status_messenger_executing:
1020
-                        $status_bulk_actions = array();
1021
-                        break;
1022
-
1023
-                    case EEM_Message::status_incomplete:
1024
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1025
-                        break;
1026
-
1027
-                    case EEM_Message::status_retry:
1028
-                    case EEM_Message::status_sent:
1029
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1030
-                        break;
1031
-                }
1032
-            }
1033
-
1034
-            // skip adding messenger executing status to views because it will be included with the Failed view.
1035
-            if ($status === EEM_Message::status_messenger_executing) {
1036
-                continue;
1037
-            }
1038
-
1039
-            $this->_views[ strtolower($status) ] = array(
1040
-                'slug'        => strtolower($status),
1041
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1042
-                'count'       => 0,
1043
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1044
-            );
1045
-        }
1046
-    }
1047
-
1048
-
1049
-    protected function _ee_default_messages_overview_list_table()
1050
-    {
1051
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1052
-        $this->display_admin_list_table_page_with_no_sidebar();
1053
-    }
1054
-
1055
-
1056
-    protected function _message_queue_list_table()
1057
-    {
1058
-        $this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1059
-        $this->_template_args['per_column'] = 6;
1060
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1061
-        $this->_template_args['before_list_table'] = '<h3>'
1062
-                                                     . EEM_Message::instance()->get_pretty_label_for_results()
1063
-                                                     . '</h3>';
1064
-        $this->display_admin_list_table_page_with_no_sidebar();
1065
-    }
1066
-
1067
-
1068
-    protected function _message_legend_items()
1069
-    {
1070
-
1071
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1072
-        $action_items = array();
1073
-
1074
-        foreach ($action_css_classes as $action_item => $action_details) {
1075
-            if ($action_item === 'see_notifications_for') {
1076
-                continue;
1077
-            }
1078
-            $action_items[ $action_item ] = array(
1079
-                'class' => $action_details['css_class'],
1080
-                'desc'  => $action_details['label'],
1081
-            );
1082
-        }
1083
-
1084
-        /** @type array $status_items status legend setup */
1085
-        $status_items = array(
1086
-            'incomplete_status'          => array(
1087
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1088
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1089
-            ),
1090
-            'idle_status'                => array(
1091
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1092
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1093
-            ),
1094
-            'resend_status'              => array(
1095
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1096
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1097
-            ),
1098
-            'messenger_executing_status' => array(
1099
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1100
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1101
-            ),
1102
-            'sent_status'                => array(
1103
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1104
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1105
-            ),
1106
-            'retry_status'               => array(
1107
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1108
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1109
-            ),
1110
-            'failed_status'              => array(
1111
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1112
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1113
-            ),
1114
-        );
1115
-        if (EEM_Message::debug()) {
1116
-            $status_items['debug_only_status'] = array(
1117
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1118
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1119
-            );
1120
-        }
1121
-
1122
-        return array_merge($action_items, $status_items);
1123
-    }
1124
-
1125
-
1126
-    protected function _custom_mtps_preview()
1127
-    {
1128
-        $this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1129
-        $this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1130
-                                               . ' alt="' . esc_attr__(
1131
-                                                   'Preview Custom Message Templates screenshot',
1132
-                                                   'event_espresso'
1133
-                                               ) . '" />';
1134
-        $this->_template_args['preview_text'] = '<strong>'
1135
-                                                . esc_html__(
1136
-                                                    'Custom Message Templates is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1137
-                                                    'event_espresso'
1138
-                                                )
1139
-                                                . '</strong>';
1140
-
1141
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1142
-    }
1143
-
1144
-
1145
-    /**
1146
-     * get_message_templates
1147
-     * This gets all the message templates for listing on the overview list.
1148
-     *
1149
-     * @access public
1150
-     * @param int    $perpage the amount of templates groups to show per page
1151
-     * @param string $type    the current _view we're getting templates for
1152
-     * @param bool   $count   return count?
1153
-     * @param bool   $all     disregard any paging info (get all data);
1154
-     * @param bool   $global  whether to return just global (true) or custom templates (false)
1155
-     * @return array
1156
-     * @throws EE_Error
1157
-     * @throws InvalidArgumentException
1158
-     * @throws InvalidDataTypeException
1159
-     * @throws InvalidInterfaceException
1160
-     */
1161
-    public function get_message_templates(
1162
-        $perpage = 10,
1163
-        $type = 'in_use',
1164
-        $count = false,
1165
-        $all = false,
1166
-        $global = true
1167
-    ) {
1168
-
1169
-        $MTP = EEM_Message_Template_Group::instance();
1170
-
1171
-        $this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1172
-        $orderby = $this->_req_data['orderby'];
1173
-
1174
-        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1175
-            ? $this->_req_data['order']
1176
-            : 'ASC';
1177
-
1178
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1179
-            ? $this->_req_data['paged']
1180
-            : 1;
1181
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1182
-            ? $this->_req_data['perpage']
1183
-            : $perpage;
1184
-
1185
-        $offset = ($current_page - 1) * $per_page;
1186
-        $limit = $all ? null : array($offset, $per_page);
1187
-
1188
-
1189
-        // options will match what is in the _views array property
1190
-        switch ($type) {
1191
-            case 'in_use':
1192
-                $templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1193
-                break;
1194
-            default:
1195
-                $templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1196
-        }
1197
-
1198
-        return $templates;
1199
-    }
1200
-
1201
-
1202
-    /**
1203
-     * filters etc might need a list of installed message_types
1204
-     *
1205
-     * @return array an array of message type objects
1206
-     */
1207
-    public function get_installed_message_types()
1208
-    {
1209
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1210
-        $installed = array();
1211
-
1212
-        foreach ($installed_message_types as $message_type) {
1213
-            $installed[ $message_type->name ] = $message_type;
1214
-        }
1215
-
1216
-        return $installed;
1217
-    }
1218
-
1219
-
1220
-    /**
1221
-     * _add_message_template
1222
-     *
1223
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1224
-     *
1225
-     * @param string $message_type
1226
-     * @param string $messenger
1227
-     * @param string $GRP_ID
1228
-     *
1229
-     * @throws EE_error
1230
-     */
1231
-    protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1232
-    {
1233
-        // set values override any request data
1234
-        $message_type = ! empty($message_type) ? $message_type : '';
1235
-        $message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1236
-            ? $this->_req_data['message_type']
1237
-            : $message_type;
1238
-
1239
-        $messenger = ! empty($messenger) ? $messenger : '';
1240
-        $messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1241
-            ? $this->_req_data['messenger']
1242
-            : $messenger;
1243
-
1244
-        $GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1245
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1246
-
1247
-        // we need messenger and message type.  They should be coming from the event editor. If not here then return error
1248
-        if (empty($message_type) || empty($messenger)) {
1249
-            throw new EE_Error(
1250
-                esc_html__(
1251
-                    'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1252
-                    'event_espresso'
1253
-                )
1254
-            );
1255
-        }
1256
-
1257
-        // we need the GRP_ID for the template being used as the base for the new template
1258
-        if (empty($GRP_ID)) {
1259
-            throw new EE_Error(
1260
-                esc_html__(
1261
-                    'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1262
-                    'event_espresso'
1263
-                )
1264
-            );
1265
-        }
1266
-
1267
-        // let's just make sure the template gets generated!
1268
-
1269
-        // we need to reassign some variables for what the insert is expecting
1270
-        $this->_req_data['MTP_messenger'] = $messenger;
1271
-        $this->_req_data['MTP_message_type'] = $message_type;
1272
-        $this->_req_data['GRP_ID'] = $GRP_ID;
1273
-        $this->_insert_or_update_message_template(true);
1274
-    }
1275
-
1276
-
1277
-    /**
1278
-     * public wrapper for the _add_message_template method
1279
-     *
1280
-     * @param string $message_type     message type slug
1281
-     * @param string $messenger        messenger slug
1282
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1283
-     *                                 off of.
1284
-     * @throws EE_error
1285
-     */
1286
-    public function add_message_template($message_type, $messenger, $GRP_ID)
1287
-    {
1288
-        $this->_add_message_template($message_type, $messenger, $GRP_ID);
1289
-    }
1290
-
1291
-
1292
-    /**
1293
-     * _edit_message_template
1294
-     *
1295
-     * @access protected
1296
-     * @return void
1297
-     * @throws InvalidIdentifierException
1298
-     * @throws DomainException
1299
-     * @throws EE_Error
1300
-     * @throws InvalidArgumentException
1301
-     * @throws ReflectionException
1302
-     * @throws InvalidDataTypeException
1303
-     * @throws InvalidInterfaceException
1304
-     */
1305
-    protected function _edit_message_template()
1306
-    {
1307
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1308
-        $template_fields = '';
1309
-        $sidebar_fields = '';
1310
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1311
-        // valid html in the templates.
1312
-        add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1313
-
1314
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1315
-            ? absint($this->_req_data['id'])
1316
-            : false;
1317
-
1318
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1319
-        ? absint($this->_req_data['evt_id'])
1320
-        : false;
1321
-
1322
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1323
-        $message_template_group = $this->_message_template_group;
1324
-        $c_label = $message_template_group->context_label();
1325
-        $c_config = $message_template_group->contexts_config();
1326
-
1327
-        reset($c_config);
1328
-        $context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1329
-            ? strtolower($this->_req_data['context'])
1330
-            : key($c_config);
1331
-
1332
-
1333
-        if (empty($GRP_ID)) {
1334
-            $action = 'insert_message_template';
1335
-            $edit_message_template_form_url = add_query_arg(
1336
-                array('action' => $action, 'noheader' => true),
1337
-                EE_MSG_ADMIN_URL
1338
-            );
1339
-        } else {
1340
-            $action = 'update_message_template';
1341
-            $edit_message_template_form_url = add_query_arg(
1342
-                array('action' => $action, 'noheader' => true),
1343
-                EE_MSG_ADMIN_URL
1344
-            );
1345
-        }
1346
-
1347
-        // set active messenger for this view
1348
-        $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1349
-            $message_template_group->messenger()
1350
-        );
1351
-        $this->_active_message_type_name = $message_template_group->message_type();
1352
-
1353
-
1354
-        // Do we have any validation errors?
1355
-        $validators = $this->_get_transient();
1356
-        $v_fields = ! empty($validators) ? array_keys($validators) : array();
1357
-
1358
-
1359
-        // we need to assemble the title from Various details
1360
-        $context_label = sprintf(
1361
-            esc_html__('(%s %s)', 'event_espresso'),
1362
-            $c_config[ $context ]['label'],
1363
-            ucwords($c_label['label'])
1364
-        );
1365
-
1366
-        $title = sprintf(
1367
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1368
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1369
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1370
-            $context_label
1371
-        );
1372
-
1373
-        $this->_template_args['GRP_ID'] = $GRP_ID;
1374
-        $this->_template_args['message_template'] = $message_template_group;
1375
-        $this->_template_args['is_extra_fields'] = false;
1376
-
1377
-
1378
-        // let's get EEH_MSG_Template so we can get template form fields
1379
-        $template_field_structure = EEH_MSG_Template::get_fields(
1380
-            $message_template_group->messenger(),
1381
-            $message_template_group->message_type()
1382
-        );
1383
-
1384
-        if (! $template_field_structure) {
1385
-            $template_field_structure = false;
1386
-            $template_fields = esc_html__(
1387
-                'There was an error in assembling the fields for this display (you should see an error message)',
1388
-                'event_espresso'
1389
-            );
1390
-        }
1391
-
1392
-
1393
-        $message_templates = $message_template_group->context_templates();
1394
-
1395
-
1396
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1397
-        // will get handled in the "extra" array.
1398
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1399
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1400
-                unset($template_field_structure[ $context ][ $reference_field ]);
1401
-            }
1402
-        }
1403
-
1404
-        // let's loop through the template_field_structure and actually assemble the input fields!
1405
-        if (! empty($template_field_structure)) {
1406
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1407
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1408
-                // the extra array and reset them.
1409
-                if ($template_field === 'extra') {
1410
-                    $this->_template_args['is_extra_fields'] = true;
1411
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1412
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1413
-                        $content = $message_template instanceof EE_Message_Template
1414
-                            ? $message_template->get('MTP_content')
1415
-                            : '';
1416
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1417
-                            // let's verify if we need this extra field via the shortcodes parameter.
1418
-                            $continue = false;
1419
-                            if (isset($extra_array['shortcodes_required'])) {
1420
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1421
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1422
-                                        $continue = true;
1423
-                                    }
1424
-                                }
1425
-                                if ($continue) {
1426
-                                    continue;
1427
-                                }
1428
-                            }
1429
-
1430
-                            $field_id = $reference_field
1431
-                                        . '-'
1432
-                                        . $extra_field
1433
-                                        . '-content';
1434
-                            $template_form_fields[ $field_id ] = $extra_array;
1435
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1436
-                                                                         . $reference_field
1437
-                                                                         . '][content]['
1438
-                                                                         . $extra_field . ']';
1439
-                            $css_class = isset($extra_array['css_class'])
1440
-                                ? $extra_array['css_class']
1441
-                                : '';
1442
-
1443
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1444
-                                                                              && in_array($extra_field, $v_fields, true)
1445
-                                                                              &&
1446
-                                                                              (
1447
-                                                                                  is_array($validators[ $extra_field ])
1448
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1449
-                                                                              )
1450
-                                ? 'validate-error ' . $css_class
1451
-                                : $css_class;
1452
-
1453
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1454
-                                                                          && isset($content[ $extra_field ])
1455
-                                ? $content[ $extra_field ]
1456
-                                : '';
1457
-
1458
-                            // do we have a validation error?  if we do then let's use that value instead
1459
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1460
-                                ? $validators[ $extra_field ]['value']
1461
-                                : $template_form_fields[ $field_id ]['value'];
1462
-
1463
-
1464
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1465
-
1466
-                            // shortcode selector
1467
-                            $field_name_to_use = $extra_field === 'main'
1468
-                                ? 'content'
1469
-                                : $extra_field;
1470
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1471
-                                $field_name_to_use,
1472
-                                $field_id
1473
-                            );
1474
-
1475
-                            if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1476
-                                // we want to decode the entities
1477
-                                $template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1478
-                            }/**/
1479
-                        }
1480
-                        $templatefield_MTP_id = $reference_field . '-MTP_ID';
1481
-                        $templatefield_templatename_id = $reference_field . '-name';
1482
-
1483
-                        $template_form_fields[ $templatefield_MTP_id ] = array(
1484
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1485
-                            'label'      => null,
1486
-                            'input'      => 'hidden',
1487
-                            'type'       => 'int',
1488
-                            'required'   => false,
1489
-                            'validation' => false,
1490
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1491
-                            'css_class'  => '',
1492
-                            'format'     => '%d',
1493
-                            'db-col'     => 'MTP_ID',
1494
-                        );
1495
-
1496
-                        $template_form_fields[ $templatefield_templatename_id ] = array(
1497
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1498
-                            'label'      => null,
1499
-                            'input'      => 'hidden',
1500
-                            'type'       => 'string',
1501
-                            'required'   => false,
1502
-                            'validation' => true,
1503
-                            'value'      => $reference_field,
1504
-                            'css_class'  => '',
1505
-                            'format'     => '%s',
1506
-                            'db-col'     => 'MTP_template_field',
1507
-                        );
1508
-                    }
1509
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1510
-                } else {
1511
-                    $field_id = $template_field . '-content';
1512
-                    $template_form_fields[ $field_id ] = $field_setup_array;
1513
-                    $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1514
-                    $message_template = isset($message_templates[ $context ][ $template_field ])
1515
-                        ? $message_templates[ $context ][ $template_field ]
1516
-                        : null;
1517
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1518
-                                                                  && is_array($message_templates[ $context ])
1519
-                                                                  && $message_template instanceof EE_Message_Template
1520
-                        ? $message_template->get('MTP_content')
1521
-                        : '';
1522
-
1523
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1524
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1525
-                        ? $validators[ $template_field ]['value']
1526
-                        : $template_form_fields[ $field_id ]['value'];
1527
-
1528
-
1529
-                    $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1530
-                    $css_class = isset($field_setup_array['css_class'])
1531
-                        ? $field_setup_array['css_class']
1532
-                        : '';
1533
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1534
-                                                                      && in_array($template_field, $v_fields, true)
1535
-                                                                      && isset($validators[ $template_field ]['msg'])
1536
-                        ? 'validate-error ' . $css_class
1537
-                        : $css_class;
1538
-
1539
-                    // shortcode selector
1540
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1541
-                        $template_field,
1542
-                        $field_id
1543
-                    );
1544
-                }
1545
-
1546
-                // k took care of content field(s) now let's take care of others.
1547
-
1548
-                $templatefield_MTP_id = $template_field . '-MTP_ID';
1549
-                $templatefield_field_templatename_id = $template_field . '-name';
1550
-
1551
-                // foreach template field there are actually two form fields created
1552
-                $template_form_fields[ $templatefield_MTP_id ] = array(
1553
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1554
-                    'label'      => null,
1555
-                    'input'      => 'hidden',
1556
-                    'type'       => 'int',
1557
-                    'required'   => false,
1558
-                    'validation' => true,
1559
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1560
-                    'css_class'  => '',
1561
-                    'format'     => '%d',
1562
-                    'db-col'     => 'MTP_ID',
1563
-                );
1564
-
1565
-                $template_form_fields[ $templatefield_field_templatename_id ] = array(
1566
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1567
-                    'label'      => null,
1568
-                    'input'      => 'hidden',
1569
-                    'type'       => 'string',
1570
-                    'required'   => false,
1571
-                    'validation' => true,
1572
-                    'value'      => $template_field,
1573
-                    'css_class'  => '',
1574
-                    'format'     => '%s',
1575
-                    'db-col'     => 'MTP_template_field',
1576
-                );
1577
-            }
1578
-
1579
-            // add other fields
1580
-            $template_form_fields['ee-msg-current-context'] = array(
1581
-                'name'       => 'MTP_context',
1582
-                'label'      => null,
1583
-                'input'      => 'hidden',
1584
-                'type'       => 'string',
1585
-                'required'   => false,
1586
-                'validation' => true,
1587
-                'value'      => $context,
1588
-                'css_class'  => '',
1589
-                'format'     => '%s',
1590
-                'db-col'     => 'MTP_context',
1591
-            );
1592
-
1593
-            $template_form_fields['ee-msg-grp-id'] = array(
1594
-                'name'       => 'GRP_ID',
1595
-                'label'      => null,
1596
-                'input'      => 'hidden',
1597
-                'type'       => 'int',
1598
-                'required'   => false,
1599
-                'validation' => true,
1600
-                'value'      => $GRP_ID,
1601
-                'css_class'  => '',
1602
-                'format'     => '%d',
1603
-                'db-col'     => 'GRP_ID',
1604
-            );
1605
-
1606
-            $template_form_fields['ee-msg-messenger'] = array(
1607
-                'name'       => 'MTP_messenger',
1608
-                'label'      => null,
1609
-                'input'      => 'hidden',
1610
-                'type'       => 'string',
1611
-                'required'   => false,
1612
-                'validation' => true,
1613
-                'value'      => $message_template_group->messenger(),
1614
-                'css_class'  => '',
1615
-                'format'     => '%s',
1616
-                'db-col'     => 'MTP_messenger',
1617
-            );
1618
-
1619
-            $template_form_fields['ee-msg-message-type'] = array(
1620
-                'name'       => 'MTP_message_type',
1621
-                'label'      => null,
1622
-                'input'      => 'hidden',
1623
-                'type'       => 'string',
1624
-                'required'   => false,
1625
-                'validation' => true,
1626
-                'value'      => $message_template_group->message_type(),
1627
-                'css_class'  => '',
1628
-                'format'     => '%s',
1629
-                'db-col'     => 'MTP_message_type',
1630
-            );
1631
-
1632
-            $sidebar_form_fields['ee-msg-is-global'] = array(
1633
-                'name'       => 'MTP_is_global',
1634
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1635
-                'input'      => 'hidden',
1636
-                'type'       => 'int',
1637
-                'required'   => false,
1638
-                'validation' => true,
1639
-                'value'      => $message_template_group->get('MTP_is_global'),
1640
-                'css_class'  => '',
1641
-                'format'     => '%d',
1642
-                'db-col'     => 'MTP_is_global',
1643
-            );
1644
-
1645
-            $sidebar_form_fields['ee-msg-is-override'] = array(
1646
-                'name'       => 'MTP_is_override',
1647
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1648
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1649
-                'type'       => 'int',
1650
-                'required'   => false,
1651
-                'validation' => true,
1652
-                'value'      => $message_template_group->get('MTP_is_override'),
1653
-                'css_class'  => '',
1654
-                'format'     => '%d',
1655
-                'db-col'     => 'MTP_is_override',
1656
-            );
1657
-
1658
-            $sidebar_form_fields['ee-msg-is-active'] = array(
1659
-                'name'       => 'MTP_is_active',
1660
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1661
-                'input'      => 'hidden',
1662
-                'type'       => 'int',
1663
-                'required'   => false,
1664
-                'validation' => true,
1665
-                'value'      => $message_template_group->is_active(),
1666
-                'css_class'  => '',
1667
-                'format'     => '%d',
1668
-                'db-col'     => 'MTP_is_active',
1669
-            );
1670
-
1671
-            $sidebar_form_fields['ee-msg-deleted'] = array(
1672
-                'name'       => 'MTP_deleted',
1673
-                'label'      => null,
1674
-                'input'      => 'hidden',
1675
-                'type'       => 'int',
1676
-                'required'   => false,
1677
-                'validation' => true,
1678
-                'value'      => $message_template_group->get('MTP_deleted'),
1679
-                'css_class'  => '',
1680
-                'format'     => '%d',
1681
-                'db-col'     => 'MTP_deleted',
1682
-            );
1683
-            $sidebar_form_fields['ee-msg-author'] = array(
1684
-                'name'       => 'MTP_user_id',
1685
-                'label'      => esc_html__('Author', 'event_espresso'),
1686
-                'input'      => 'hidden',
1687
-                'type'       => 'int',
1688
-                'required'   => false,
1689
-                'validation' => false,
1690
-                'value'      => $message_template_group->user(),
1691
-                'format'     => '%d',
1692
-                'db-col'     => 'MTP_user_id',
1693
-            );
1694
-
1695
-            $sidebar_form_fields['ee-msg-route'] = array(
1696
-                'name'  => 'action',
1697
-                'input' => 'hidden',
1698
-                'type'  => 'string',
1699
-                'value' => $action,
1700
-            );
1701
-
1702
-            $sidebar_form_fields['ee-msg-id'] = array(
1703
-                'name'  => 'id',
1704
-                'input' => 'hidden',
1705
-                'type'  => 'int',
1706
-                'value' => $GRP_ID,
1707
-            );
1708
-            $sidebar_form_fields['ee-msg-evt-nonce'] = array(
1709
-                'name'  => $action . '_nonce',
1710
-                'input' => 'hidden',
1711
-                'type'  => 'string',
1712
-                'value' => wp_create_nonce($action . '_nonce'),
1713
-            );
1714
-
1715
-            if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1716
-                $sidebar_form_fields['ee-msg-template-switch'] = array(
1717
-                    'name'  => 'template_switch',
1718
-                    'input' => 'hidden',
1719
-                    'type'  => 'int',
1720
-                    'value' => 1,
1721
-                );
1722
-            }
1723
-
1724
-
1725
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1726
-            $sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1727
-        } //end if ( !empty($template_field_structure) )
1728
-
1729
-        // set extra content for publish box
1730
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1731
-        $this->_set_publish_post_box_vars(
1732
-            'id',
1733
-            $GRP_ID,
1734
-            false,
1735
-            add_query_arg(
1736
-                array('action' => 'global_mtps'),
1737
-                $this->_admin_base_url
1738
-            )
1739
-        );
1740
-
1741
-        // add preview button
1742
-        $preview_url = parent::add_query_args_and_nonce(
1743
-            array(
1744
-                'message_type' => $message_template_group->message_type(),
1745
-                'messenger'    => $message_template_group->messenger(),
1746
-                'context'      => $context,
1747
-                'GRP_ID'       => $GRP_ID,
1748
-                'evt_id'       => $EVT_ID,
1749
-                'action'       => 'preview_message',
1750
-            ),
1751
-            $this->_admin_base_url
1752
-        );
1753
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1754
-                          . esc_html__('Preview', 'event_espresso')
1755
-                          . '</a>';
1756
-
1757
-
1758
-        // setup context switcher
1759
-        $context_switcher_args = array(
1760
-            'page'    => 'espresso_messages',
1761
-            'action'  => 'edit_message_template',
1762
-            'id'      => $GRP_ID,
1763
-            'evt_id'  => $EVT_ID,
1764
-            'context' => $context,
1765
-            'extra'   => $preview_button,
1766
-        );
1767
-        $this->_set_context_switcher($message_template_group, $context_switcher_args);
1768
-
1769
-
1770
-        // main box
1771
-        $this->_template_args['template_fields'] = $template_fields;
1772
-        $this->_template_args['sidebar_box_id'] = 'details';
1773
-        $this->_template_args['action'] = $action;
1774
-        $this->_template_args['context'] = $context;
1775
-        $this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1776
-        $this->_template_args['learn_more_about_message_templates_link'] =
1777
-            $this->_learn_more_about_message_templates_link();
1778
-
1779
-
1780
-        $this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1781
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1782
-            $message_template_group,
1783
-            $context,
1784
-            $context_label
1785
-        );
1786
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1787
-        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1788
-
1789
-        $this->_template_path = $this->_template_args['GRP_ID']
1790
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1791
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1792
-
1793
-        // send along EE_Message_Template_Group object for further template use.
1794
-        $this->_template_args['MTP'] = $message_template_group;
1795
-
1796
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1797
-            $this->_template_path,
1798
-            $this->_template_args,
1799
-            true
1800
-        );
1801
-
1802
-
1803
-        // finally, let's set the admin_page title
1804
-        $this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1805
-
1806
-
1807
-        // we need to take care of setting the shortcodes property for use elsewhere.
1808
-        $this->_set_shortcodes();
1809
-
1810
-
1811
-        // final template wrapper
1812
-        $this->display_admin_page_with_sidebar();
1813
-    }
1814
-
1815
-
1816
-    public function filter_tinymce_init($mceInit, $editor_id)
1817
-    {
1818
-        return $mceInit;
1819
-    }
1820
-
1821
-
1822
-    public function add_context_switcher()
1823
-    {
1824
-        return $this->_context_switcher;
1825
-    }
1826
-
1827
-
1828
-    /**
1829
-     * Adds the activation/deactivation toggle for the message template context.
1830
-     *
1831
-     * @param EE_Message_Template_Group $message_template_group
1832
-     * @param string                    $context
1833
-     * @param string                    $context_label
1834
-     * @return string
1835
-     * @throws DomainException
1836
-     * @throws EE_Error
1837
-     * @throws InvalidIdentifierException
1838
-     */
1839
-    protected function add_active_context_element(
1840
-        EE_Message_Template_Group $message_template_group,
1841
-        $context,
1842
-        $context_label
1843
-    ) {
1844
-        $template_args = array(
1845
-            'context'                   => $context,
1846
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1847
-            'is_active'                 => $message_template_group->is_context_active($context),
1848
-            'on_off_action'             => $message_template_group->is_context_active($context)
1849
-                ? 'context-off'
1850
-                : 'context-on',
1851
-            'context_label'             => str_replace(array('(', ')'), '', $context_label),
1852
-            'message_template_group_id' => $message_template_group->ID(),
1853
-        );
1854
-        return EEH_Template::display_template(
1855
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1856
-            $template_args,
1857
-            true
1858
-        );
1859
-    }
1860
-
1861
-
1862
-    /**
1863
-     * Ajax callback for `toggle_context_template` ajax action.
1864
-     * Handles toggling the message context on or off.
1865
-     *
1866
-     * @throws EE_Error
1867
-     * @throws InvalidArgumentException
1868
-     * @throws InvalidDataTypeException
1869
-     * @throws InvalidIdentifierException
1870
-     * @throws InvalidInterfaceException
1871
-     */
1872
-    public function toggle_context_template()
1873
-    {
1874
-        $success = true;
1875
-        // check for required data
1876
-        if (
1877
-            ! isset(
1878
-                $this->_req_data['message_template_group_id'],
1879
-                $this->_req_data['context'],
1880
-                $this->_req_data['status']
1881
-            )
1882
-        ) {
1883
-            EE_Error::add_error(
1884
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1885
-                __FILE__,
1886
-                __FUNCTION__,
1887
-                __LINE__
1888
-            );
1889
-            $success = false;
1890
-        }
1891
-
1892
-        $nonce = isset($this->_req_data['toggle_context_nonce'])
1893
-            ? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1894
-            : '';
1895
-        $nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1896
-        $this->_verify_nonce($nonce, $nonce_ref);
1897
-        $status = $this->_req_data['status'];
1898
-        if ($status !== 'off' && $status !== 'on') {
1899
-            EE_Error::add_error(
1900
-                sprintf(
1901
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1902
-                    $this->_req_data['status']
1903
-                ),
1904
-                __FILE__,
1905
-                __FUNCTION__,
1906
-                __LINE__
1907
-            );
1908
-            $success = false;
1909
-        }
1910
-        $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1911
-            $this->_req_data['message_template_group_id']
1912
-        );
1913
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1914
-            EE_Error::add_error(
1915
-                sprintf(
1916
-                    esc_html__(
1917
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1918
-                        'event_espresso'
1919
-                    ),
1920
-                    $this->_req_data['message_template_group_id'],
1921
-                    'EE_Message_Template_Group'
1922
-                ),
1923
-                __FILE__,
1924
-                __FUNCTION__,
1925
-                __LINE__
1926
-            );
1927
-            $success = false;
1928
-        }
1929
-        if ($success) {
1930
-            $success = $status === 'off'
1931
-                ? $message_template_group->deactivate_context($this->_req_data['context'])
1932
-                : $message_template_group->activate_context($this->_req_data['context']);
1933
-        }
1934
-        $this->_template_args['success'] = $success;
1935
-        $this->_return_json();
1936
-    }
1937
-
1938
-
1939
-    public function _add_form_element_before()
1940
-    {
1941
-        return '<form method="post" action="'
1942
-               . $this->_template_args["edit_message_template_form_url"]
1943
-               . '" id="ee-msg-edit-frm">';
1944
-    }
1945
-
1946
-    public function _add_form_element_after()
1947
-    {
1948
-        return '</form>';
1949
-    }
1950
-
1951
-
1952
-    /**
1953
-     * This executes switching the template pack for a message template.
1954
-     *
1955
-     * @since 4.5.0
1956
-     * @throws EE_Error
1957
-     * @throws InvalidDataTypeException
1958
-     * @throws InvalidInterfaceException
1959
-     * @throws InvalidArgumentException
1960
-     * @throws ReflectionException
1961
-     */
1962
-    public function switch_template_pack()
1963
-    {
1964
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1965
-        $template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1966
-
1967
-        // verify we have needed values.
1968
-        if (empty($GRP_ID) || empty($template_pack)) {
1969
-            $this->_template_args['error'] = true;
1970
-            EE_Error::add_error(
1971
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1972
-                __FILE__,
1973
-                __FUNCTION__,
1974
-                __LINE__
1975
-            );
1976
-        } else {
1977
-            // get template, set the new template_pack and then reset to default
1978
-            /** @type EE_Message_Template_Group $message_template_group */
1979
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1980
-
1981
-            $message_template_group->set_template_pack_name($template_pack);
1982
-            $this->_req_data['msgr'] = $message_template_group->messenger();
1983
-            $this->_req_data['mt'] = $message_template_group->message_type();
1984
-
1985
-            $query_args = $this->_reset_to_default_template();
1986
-
1987
-            if (empty($query_args['id'])) {
1988
-                EE_Error::add_error(
1989
-                    esc_html__(
1990
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
1991
-                        'event_espresso'
1992
-                    ),
1993
-                    __FILE__,
1994
-                    __FUNCTION__,
1995
-                    __LINE__
1996
-                );
1997
-                $this->_template_args['error'] = true;
1998
-            } else {
1999
-                $template_label = $message_template_group->get_template_pack()->label;
2000
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2001
-                EE_Error::add_success(
2002
-                    sprintf(
2003
-                        esc_html__(
2004
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2005
-                            'event_espresso'
2006
-                        ),
2007
-                        $template_label,
2008
-                        $template_pack_labels->template_pack
2009
-                    )
2010
-                );
2011
-                // generate the redirect url for js.
2012
-                $url = self::add_query_args_and_nonce(
2013
-                    $query_args,
2014
-                    $this->_admin_base_url
2015
-                );
2016
-                $this->_template_args['data']['redirect_url'] = $url;
2017
-                $this->_template_args['success'] = true;
2018
-            }
2019
-
2020
-            $this->_return_json();
2021
-        }
2022
-    }
2023
-
2024
-
2025
-    /**
2026
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2027
-     * they want.
2028
-     *
2029
-     * @access protected
2030
-     * @return array|null
2031
-     * @throws EE_Error
2032
-     * @throws InvalidArgumentException
2033
-     * @throws InvalidDataTypeException
2034
-     * @throws InvalidInterfaceException
2035
-     */
2036
-    protected function _reset_to_default_template()
2037
-    {
2038
-
2039
-        $templates = array();
2040
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2041
-        // we need to make sure we've got the info we need.
2042
-        if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2043
-            EE_Error::add_error(
2044
-                esc_html__(
2045
-                    'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
2046
-                    'event_espresso'
2047
-                ),
2048
-                __FILE__,
2049
-                __FUNCTION__,
2050
-                __LINE__
2051
-            );
2052
-        }
2053
-
2054
-        // all templates will be reset to whatever the defaults are
2055
-        // for the global template matching the messenger and message type.
2056
-        $success = ! empty($GRP_ID) ? true : false;
2057
-
2058
-        if ($success) {
2059
-            // let's first determine if the incoming template is a global template,
2060
-            // if it isn't then we need to get the global template matching messenger and message type.
2061
-            // $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2062
-
2063
-
2064
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2065
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
2066
-
2067
-            if ($success) {
2068
-                // if successfully deleted, lets generate the new ones.
2069
-                // Note. We set GLOBAL to true, because resets on ANY template
2070
-                // will use the related global template defaults for regeneration.
2071
-                // This means that if a custom template is reset it resets to whatever the related global template is.
2072
-                // HOWEVER, we DO keep the template pack and template variation set
2073
-                // for the current custom template when resetting.
2074
-                $templates = $this->_generate_new_templates(
2075
-                    $this->_req_data['msgr'],
2076
-                    $this->_req_data['mt'],
2077
-                    $GRP_ID,
2078
-                    true
2079
-                );
2080
-            }
2081
-        }
2082
-
2083
-        // any error messages?
2084
-        if (! $success) {
2085
-            EE_Error::add_error(
2086
-                esc_html__(
2087
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
2088
-                    'event_espresso'
2089
-                ),
2090
-                __FILE__,
2091
-                __FUNCTION__,
2092
-                __LINE__
2093
-            );
2094
-        }
2095
-
2096
-        // all good, let's add a success message!
2097
-        if ($success && ! empty($templates)) {
2098
-            // the info for the template we generated is the first element in the returned array
2099
-            // $templates = $templates[0];
2100
-            EE_Error::overwrite_success();
2101
-            EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2102
-        }
2103
-
2104
-
2105
-        $query_args = array(
2106
-            'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2107
-            'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2108
-            'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2109
-        );
2110
-
2111
-        // if called via ajax then we return query args otherwise redirect
2112
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2113
-            return $query_args;
2114
-        } else {
2115
-            $this->_redirect_after_action(false, '', '', $query_args, true);
2116
-
2117
-            return null;
2118
-        }
2119
-    }
2120
-
2121
-
2122
-    /**
2123
-     * Retrieve and set the message preview for display.
2124
-     *
2125
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2126
-     * @return string
2127
-     * @throws ReflectionException
2128
-     * @throws EE_Error
2129
-     * @throws InvalidArgumentException
2130
-     * @throws InvalidDataTypeException
2131
-     * @throws InvalidInterfaceException
2132
-     */
2133
-    public function _preview_message($send = false)
2134
-    {
2135
-        // first make sure we've got the necessary parameters
2136
-        if (
2137
-            ! isset(
2138
-                $this->_req_data['message_type'],
2139
-                $this->_req_data['messenger'],
2140
-                $this->_req_data['messenger'],
2141
-                $this->_req_data['GRP_ID']
2142
-            )
2143
-        ) {
2144
-            EE_Error::add_error(
2145
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2146
-                __FILE__,
2147
-                __FUNCTION__,
2148
-                __LINE__
2149
-            );
2150
-        }
2151
-
2152
-        EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
2153
-
2154
-        // if we have an evt_id set on the request, use it.
2155
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2156
-        ? absint($this->_req_data['evt_id'])
2157
-        : false;
2158
-
2159
-
2160
-        // get the preview!
2161
-        $preview = EED_Messages::preview_message(
2162
-            $this->_req_data['message_type'],
2163
-            $this->_req_data['context'],
2164
-            $this->_req_data['messenger'],
2165
-            $send
2166
-        );
2167
-
2168
-        if ($send) {
2169
-            return $preview;
2170
-        }
2171
-
2172
-        // let's add a button to go back to the edit view
2173
-        $query_args = array(
2174
-            'id'      => $this->_req_data['GRP_ID'],
2175
-            'evt_id'  => $EVT_ID,
2176
-            'context' => $this->_req_data['context'],
2177
-            'action'  => 'edit_message_template',
2178
-        );
2179
-        $go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2180
-        $preview_button = '<a href="'
2181
-                          . $go_back_url
2182
-                          . '" class="button-secondary messages-preview-go-back-button">'
2183
-                          . esc_html__('Go Back to Edit', 'event_espresso')
2184
-                          . '</a>';
2185
-        $message_types = $this->get_installed_message_types();
2186
-        $active_messenger = $this->_message_resource_manager->get_active_messenger(
2187
-            $this->_req_data['messenger']
2188
-        );
2189
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2190
-            ? ucwords($active_messenger->label['singular'])
2191
-            : esc_html__('Unknown Messenger', 'event_espresso');
2192
-        // let's provide a helpful title for context
2193
-        $preview_title = sprintf(
2194
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2195
-            $active_messenger_label,
2196
-            ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2197
-        );
2198
-        if (empty($preview)) {
2199
-            $this->noEventsErrorMessage();
2200
-        }
2201
-        // setup display of preview.
2202
-        $this->_admin_page_title = $preview_title;
2203
-        $this->_template_args['admin_page_title'] = $preview_title;
2204
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2205
-        $this->_template_args['data']['force_json'] = true;
2206
-
2207
-        return '';
2208
-    }
2209
-
2210
-
2211
-    /**
2212
-     * Used to set an error if there are no events available for generating a preview/test send.
2213
-     *
2214
-     * @param bool $test_send  Whether the error should be generated for the context of a test send.
2215
-     */
2216
-    protected function noEventsErrorMessage($test_send = false)
2217
-    {
2218
-        $events_url = parent::add_query_args_and_nonce(
2219
-            array(
2220
-                'action' => 'default',
2221
-                'page'   => 'espresso_events',
2222
-            ),
2223
-            admin_url('admin.php')
2224
-        );
2225
-        $message = $test_send
2226
-            ? __(
2227
-                'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2228
-                'event_espresso'
2229
-            )
2230
-            : __(
2231
-                'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2232
-                'event_espresso'
2233
-            );
2234
-
2235
-        EE_Error::add_attention(
2236
-            sprintf(
2237
-                $message,
2238
-                "<a href='{$events_url}'>",
2239
-                '</a>'
2240
-            )
2241
-        );
2242
-    }
2243
-
2244
-
2245
-    /**
2246
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2247
-     * gets called automatically.
2248
-     *
2249
-     * @since 4.5.0
2250
-     *
2251
-     * @return string
2252
-     */
2253
-    protected function _display_preview_message()
2254
-    {
2255
-        $this->display_admin_page_with_no_sidebar();
2256
-    }
2257
-
2258
-
2259
-    /**
2260
-     * registers metaboxes that should show up on the "edit_message_template" page
2261
-     *
2262
-     * @access protected
2263
-     * @return void
2264
-     */
2265
-    protected function _register_edit_meta_boxes()
2266
-    {
2267
-        add_meta_box(
2268
-            'mtp_valid_shortcodes',
2269
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2270
-            array($this, 'shortcode_meta_box'),
2271
-            $this->_current_screen->id,
2272
-            'side',
2273
-            'default'
2274
-        );
2275
-        add_meta_box(
2276
-            'mtp_extra_actions',
2277
-            esc_html__('Extra Actions', 'event_espresso'),
2278
-            array($this, 'extra_actions_meta_box'),
2279
-            $this->_current_screen->id,
2280
-            'side',
2281
-            'high'
2282
-        );
2283
-        add_meta_box(
2284
-            'mtp_templates',
2285
-            esc_html__('Template Styles', 'event_espresso'),
2286
-            array($this, 'template_pack_meta_box'),
2287
-            $this->_current_screen->id,
2288
-            'side',
2289
-            'high'
2290
-        );
2291
-    }
2292
-
2293
-
2294
-    /**
2295
-     * metabox content for all template pack and variation selection.
2296
-     *
2297
-     * @since 4.5.0
2298
-     * @return string
2299
-     * @throws DomainException
2300
-     * @throws EE_Error
2301
-     * @throws InvalidArgumentException
2302
-     * @throws ReflectionException
2303
-     * @throws InvalidDataTypeException
2304
-     * @throws InvalidInterfaceException
2305
-     */
2306
-    public function template_pack_meta_box()
2307
-    {
2308
-        $this->_set_message_template_group();
2309
-
2310
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2311
-
2312
-        $tp_select_values = array();
2313
-
2314
-        foreach ($tp_collection as $tp) {
2315
-            // only include template packs that support this messenger and message type!
2316
-            $supports = $tp->get_supports();
2317
-            if (
2318
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2319
-                || ! in_array(
2320
-                    $this->_message_template_group->message_type(),
2321
-                    $supports[ $this->_message_template_group->messenger() ],
2322
-                    true
2323
-                )
2324
-            ) {
2325
-                // not supported
2326
-                continue;
2327
-            }
2328
-
2329
-            $tp_select_values[] = array(
2330
-                'text' => $tp->label,
2331
-                'id'   => $tp->dbref,
2332
-            );
2333
-        }
2334
-
2335
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2336
-        // the default template pack.  This still allows for the odd template pack to override.
2337
-        if (empty($tp_select_values)) {
2338
-            $tp_select_values[] = array(
2339
-                'text' => esc_html__('Default', 'event_espresso'),
2340
-                'id'   => 'default',
2341
-            );
2342
-        }
2343
-
2344
-        // setup variation select values for the currently selected template.
2345
-        $variations = $this->_message_template_group->get_template_pack()->get_variations(
2346
-            $this->_message_template_group->messenger(),
2347
-            $this->_message_template_group->message_type()
2348
-        );
2349
-        $variations_select_values = array();
2350
-        foreach ($variations as $variation => $label) {
2351
-            $variations_select_values[] = array(
2352
-                'text' => $label,
2353
-                'id'   => $variation,
2354
-            );
2355
-        }
2356
-
2357
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2358
-
2359
-        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2360
-            'MTP_template_pack',
2361
-            $tp_select_values,
2362
-            $this->_message_template_group->get_template_pack_name()
2363
-        );
2364
-        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
2365
-            'MTP_template_variation',
2366
-            $variations_select_values,
2367
-            $this->_message_template_group->get_template_pack_variation()
2368
-        );
2369
-        $template_args['template_pack_label'] = $template_pack_labels->template_pack;
2370
-        $template_args['template_variation_label'] = $template_pack_labels->template_variation;
2371
-        $template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2372
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2373
-
2374
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2375
-
2376
-        EEH_Template::display_template($template, $template_args);
2377
-    }
2378
-
2379
-
2380
-    /**
2381
-     * This meta box holds any extra actions related to Message Templates
2382
-     * For now, this includes Resetting templates to defaults and sending a test email.
2383
-     *
2384
-     * @access  public
2385
-     * @return void
2386
-     * @throws EE_Error
2387
-     */
2388
-    public function extra_actions_meta_box()
2389
-    {
2390
-        $template_form_fields = array();
2391
-
2392
-        $extra_args = array(
2393
-            'msgr'   => $this->_message_template_group->messenger(),
2394
-            'mt'     => $this->_message_template_group->message_type(),
2395
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2396
-        );
2397
-        // first we need to see if there are any fields
2398
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2399
-
2400
-        if (! empty($fields)) {
2401
-            // yup there be fields
2402
-            foreach ($fields as $field => $config) {
2403
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2404
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2405
-                $default = isset($config['default']) ? $config['default'] : '';
2406
-                $default = isset($config['value']) ? $config['value'] : $default;
2407
-
2408
-                // if type is hidden and the value is empty
2409
-                // something may have gone wrong so let's correct with the defaults
2410
-                $fix = $config['input'] === 'hidden'
2411
-                       && isset($existing[ $field ])
2412
-                       && empty($existing[ $field ])
2413
-                    ? $default
2414
-                    : '';
2415
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2416
-                    ? $existing[ $field ]
2417
-                    : $fix;
2418
-
2419
-                $template_form_fields[ $field_id ] = array(
2420
-                    'name'       => 'test_settings_fld[' . $field . ']',
2421
-                    'label'      => $config['label'],
2422
-                    'input'      => $config['input'],
2423
-                    'type'       => $config['type'],
2424
-                    'required'   => $config['required'],
2425
-                    'validation' => $config['validation'],
2426
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2427
-                    'css_class'  => $config['css_class'],
2428
-                    'options'    => isset($config['options']) ? $config['options'] : array(),
2429
-                    'default'    => $default,
2430
-                    'format'     => $config['format'],
2431
-                );
2432
-            }
2433
-        }
2434
-
2435
-        $test_settings_fields = ! empty($template_form_fields)
2436
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2437
-            : '';
2438
-
2439
-        $test_settings_html = '';
2440
-        // print out $test_settings_fields
2441
-        if (! empty($test_settings_fields)) {
2442
-            echo $test_settings_fields;
2443
-            $test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2444
-            $test_settings_html .= 'name="test_button" value="';
2445
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2446
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2447
-        }
2448
-
2449
-        // and button
2450
-        $test_settings_html .= '<p>'
2451
-                               . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2452
-                               . '</p>';
2453
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2454
-        $test_settings_html .= $this->get_action_link_or_button(
2455
-            'reset_to_default',
2456
-            'reset',
2457
-            $extra_args,
2458
-            'button-primary reset-default-button'
2459
-        );
2460
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2461
-        echo $test_settings_html;
2462
-    }
2463
-
2464
-
2465
-    /**
2466
-     * This returns the shortcode selector skeleton for a given context and field.
2467
-     *
2468
-     * @since 4.9.rc.000
2469
-     * @param string $field           The name of the field retrieving shortcodes for.
2470
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2471
-     * @return string
2472
-     * @throws DomainException
2473
-     * @throws EE_Error
2474
-     * @throws InvalidArgumentException
2475
-     * @throws ReflectionException
2476
-     * @throws InvalidDataTypeException
2477
-     * @throws InvalidInterfaceException
2478
-     */
2479
-    protected function _get_shortcode_selector($field, $linked_input_id)
2480
-    {
2481
-        $template_args = array(
2482
-            'shortcodes'      => $this->_get_shortcodes(array($field), true),
2483
-            'fieldname'       => $field,
2484
-            'linked_input_id' => $linked_input_id,
2485
-        );
2486
-
2487
-        return EEH_Template::display_template(
2488
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2489
-            $template_args,
2490
-            true
2491
-        );
2492
-    }
2493
-
2494
-
2495
-    /**
2496
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2497
-     * page)
2498
-     *
2499
-     * @access public
2500
-     * @return void
2501
-     * @throws EE_Error
2502
-     * @throws InvalidArgumentException
2503
-     * @throws ReflectionException
2504
-     * @throws InvalidDataTypeException
2505
-     * @throws InvalidInterfaceException
2506
-     */
2507
-    public function shortcode_meta_box()
2508
-    {
2509
-        $shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2510
-        // $messenger = $this->_message_template_group->messenger_obj();
2511
-        // now let's set the content depending on the status of the shortcodes array
2512
-        if (empty($shortcodes)) {
2513
-            $content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2514
-            echo $content;
2515
-        } else {
2516
-            // $alt = 0;
2517
-            ?>
22
+	/**
23
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
24
+	 */
25
+	protected $_message_resource_manager;
26
+
27
+	/**
28
+	 * @type string $_active_message_type_name
29
+	 */
30
+	protected $_active_message_type_name = '';
31
+
32
+	/**
33
+	 * @type EE_messenger $_active_messenger
34
+	 */
35
+	protected $_active_messenger;
36
+	protected $_activate_state;
37
+	protected $_activate_meta_box_type;
38
+	protected $_current_message_meta_box;
39
+	protected $_current_message_meta_box_object;
40
+	protected $_context_switcher;
41
+	protected $_shortcodes = array();
42
+	protected $_active_messengers = array();
43
+	protected $_active_message_types = array();
44
+
45
+	/**
46
+	 * @var EE_Message_Template_Group $_message_template_group
47
+	 */
48
+	protected $_message_template_group;
49
+	protected $_m_mt_settings = array();
50
+
51
+
52
+	/**
53
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
+	 * IF there is no group then it gets automatically set to the Default template pack.
55
+	 *
56
+	 * @since 4.5.0
57
+	 *
58
+	 * @var EE_Messages_Template_Pack
59
+	 */
60
+	protected $_template_pack;
61
+
62
+
63
+	/**
64
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
+	 * group is.  If there is no group then it automatically gets set to default.
66
+	 *
67
+	 * @since 4.5.0
68
+	 *
69
+	 * @var string
70
+	 */
71
+	protected $_variation;
72
+
73
+
74
+	/**
75
+	 * @param bool $routing
76
+	 * @throws EE_Error
77
+	 */
78
+	public function __construct($routing = true)
79
+	{
80
+		// make sure messages autoloader is running
81
+		EED_Messages::set_autoloaders();
82
+		parent::__construct($routing);
83
+	}
84
+
85
+
86
+	protected function _init_page_props()
87
+	{
88
+		$this->page_slug = EE_MSG_PG_SLUG;
89
+		$this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
+		$this->_admin_base_url = EE_MSG_ADMIN_URL;
91
+		$this->_admin_base_path = EE_MSG_ADMIN;
92
+
93
+		$this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
+			: array();
95
+
96
+		$this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
+		$this->_load_message_resource_manager();
98
+	}
99
+
100
+
101
+	/**
102
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
+	 *
104
+	 * @throws EE_Error
105
+	 * @throws InvalidDataTypeException
106
+	 * @throws InvalidInterfaceException
107
+	 * @throws InvalidArgumentException
108
+	 * @throws ReflectionException
109
+	 */
110
+	protected function _load_message_resource_manager()
111
+	{
112
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
+	}
114
+
115
+
116
+	/**
117
+	 * @deprecated 4.9.9.rc.014
118
+	 * @return array
119
+	 * @throws EE_Error
120
+	 * @throws InvalidArgumentException
121
+	 * @throws InvalidDataTypeException
122
+	 * @throws InvalidInterfaceException
123
+	 */
124
+	public function get_messengers_for_list_table()
125
+	{
126
+		EE_Error::doing_it_wrong(
127
+			__METHOD__,
128
+			sprintf(
129
+				esc_html__(
130
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
131
+					'event_espresso'
132
+				),
133
+				'Messages_Admin_Page::get_messengers_select_input()'
134
+			),
135
+			'4.9.9.rc.014'
136
+		);
137
+
138
+		$m_values = array();
139
+		$active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
+		// setup messengers for selects
141
+		$i = 1;
142
+		foreach ($active_messengers as $active_messenger) {
143
+			if ($active_messenger instanceof EE_Message) {
144
+				$m_values[ $i ]['id'] = $active_messenger->messenger();
145
+				$m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
+				$i++;
147
+			}
148
+		}
149
+
150
+		return $m_values;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @deprecated 4.9.9.rc.014
156
+	 * @return array
157
+	 * @throws EE_Error
158
+	 * @throws InvalidArgumentException
159
+	 * @throws InvalidDataTypeException
160
+	 * @throws InvalidInterfaceException
161
+	 */
162
+	public function get_message_types_for_list_table()
163
+	{
164
+		EE_Error::doing_it_wrong(
165
+			__METHOD__,
166
+			sprintf(
167
+				esc_html__(
168
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
169
+					'event_espresso'
170
+				),
171
+				'Messages_Admin_Page::get_message_types_select_input()'
172
+			),
173
+			'4.9.9.rc.014'
174
+		);
175
+
176
+		$mt_values = array();
177
+		$active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
+		$i = 1;
179
+		foreach ($active_messages as $active_message) {
180
+			if ($active_message instanceof EE_Message) {
181
+				$mt_values[ $i ]['id'] = $active_message->message_type();
182
+				$mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
+				$i++;
184
+			}
185
+		}
186
+
187
+		return $mt_values;
188
+	}
189
+
190
+
191
+	/**
192
+	 * @deprecated 4.9.9.rc.014
193
+	 * @return array
194
+	 * @throws EE_Error
195
+	 * @throws InvalidArgumentException
196
+	 * @throws InvalidDataTypeException
197
+	 * @throws InvalidInterfaceException
198
+	 */
199
+	public function get_contexts_for_message_types_for_list_table()
200
+	{
201
+		EE_Error::doing_it_wrong(
202
+			__METHOD__,
203
+			sprintf(
204
+				esc_html__(
205
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
206
+					'event_espresso'
207
+				),
208
+				'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
+			),
210
+			'4.9.9.rc.014'
211
+		);
212
+
213
+		$contexts = array();
214
+		$active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
+		foreach ($active_message_contexts as $active_message) {
216
+			if ($active_message instanceof EE_Message) {
217
+				$message_type = $active_message->message_type_object();
218
+				if ($message_type instanceof EE_message_type) {
219
+					$message_type_contexts = $message_type->get_contexts();
220
+					foreach ($message_type_contexts as $context => $context_details) {
221
+						$contexts[ $context ] = $context_details['label'];
222
+					}
223
+				}
224
+			}
225
+		}
226
+
227
+		return $contexts;
228
+	}
229
+
230
+
231
+	/**
232
+	 * Generate select input with provided messenger options array.
233
+	 *
234
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
+	 *                                 labels.
236
+	 * @return string
237
+	 * @throws EE_Error
238
+	 */
239
+	public function get_messengers_select_input($messenger_options)
240
+	{
241
+		// if empty or just one value then just return an empty string
242
+		if (
243
+			empty($messenger_options)
244
+			|| ! is_array($messenger_options)
245
+			|| count($messenger_options) === 1
246
+		) {
247
+			return '';
248
+		}
249
+		// merge in default
250
+		$messenger_options = array_merge(
251
+			array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
252
+			$messenger_options
253
+		);
254
+		$input = new EE_Select_Input(
255
+			$messenger_options,
256
+			array(
257
+				'html_name'  => 'ee_messenger_filter_by',
258
+				'html_id'    => 'ee_messenger_filter_by',
259
+				'html_class' => 'wide',
260
+				'default'    => isset($this->_req_data['ee_messenger_filter_by'])
261
+					? sanitize_title($this->_req_data['ee_messenger_filter_by'])
262
+					: 'none_selected',
263
+			)
264
+		);
265
+
266
+		return $input->get_html_for_input();
267
+	}
268
+
269
+
270
+	/**
271
+	 * Generate select input with provided message type options array.
272
+	 *
273
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
274
+	 *                                    message type labels
275
+	 * @return string
276
+	 * @throws EE_Error
277
+	 */
278
+	public function get_message_types_select_input($message_type_options)
279
+	{
280
+		// if empty or count of options is 1 then just return an empty string
281
+		if (
282
+			empty($message_type_options)
283
+			|| ! is_array($message_type_options)
284
+			|| count($message_type_options) === 1
285
+		) {
286
+			return '';
287
+		}
288
+		// merge in default
289
+		$message_type_options = array_merge(
290
+			array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
291
+			$message_type_options
292
+		);
293
+		$input = new EE_Select_Input(
294
+			$message_type_options,
295
+			array(
296
+				'html_name'  => 'ee_message_type_filter_by',
297
+				'html_id'    => 'ee_message_type_filter_by',
298
+				'html_class' => 'wide',
299
+				'default'    => isset($this->_req_data['ee_message_type_filter_by'])
300
+					? sanitize_title($this->_req_data['ee_message_type_filter_by'])
301
+					: 'none_selected',
302
+			)
303
+		);
304
+
305
+		return $input->get_html_for_input();
306
+	}
307
+
308
+
309
+	/**
310
+	 * Generate select input with provide message type contexts array.
311
+	 *
312
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
313
+	 *                               context label.
314
+	 * @return string
315
+	 * @throws EE_Error
316
+	 */
317
+	public function get_contexts_for_message_types_select_input($context_options)
318
+	{
319
+		// if empty or count of options is one then just return empty string
320
+		if (
321
+			empty($context_options)
322
+			|| ! is_array($context_options)
323
+			|| count($context_options) === 1
324
+		) {
325
+			return '';
326
+		}
327
+		// merge in default
328
+		$context_options = array_merge(
329
+			array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
330
+			$context_options
331
+		);
332
+		$input = new EE_Select_Input(
333
+			$context_options,
334
+			array(
335
+				'html_name'  => 'ee_context_filter_by',
336
+				'html_id'    => 'ee_context_filter_by',
337
+				'html_class' => 'wide',
338
+				'default'    => isset($this->_req_data['ee_context_filter_by'])
339
+					? sanitize_title($this->_req_data['ee_context_filter_by'])
340
+					: 'none_selected',
341
+			)
342
+		);
343
+
344
+		return $input->get_html_for_input();
345
+	}
346
+
347
+
348
+	protected function _ajax_hooks()
349
+	{
350
+		add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
351
+		add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
352
+		add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
353
+		add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
354
+		add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
355
+		add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
356
+	}
357
+
358
+
359
+	protected function _define_page_props()
360
+	{
361
+		$this->_admin_page_title = $this->page_label;
362
+		$this->_labels = array(
363
+			'buttons'    => array(
364
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
365
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
366
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
367
+			),
368
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
369
+		);
370
+	}
371
+
372
+
373
+	/**
374
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
375
+	 *
376
+	 * @access protected
377
+	 * @return void
378
+	 */
379
+	protected function _set_page_routes()
380
+	{
381
+		$grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
382
+			? $this->_req_data['GRP_ID']
383
+			: 0;
384
+		$grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
385
+			? $this->_req_data['id']
386
+			: $grp_id;
387
+		$msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
388
+			? $this->_req_data['MSG_ID']
389
+			: 0;
390
+
391
+		$this->_page_routes = array(
392
+			'default'                          => array(
393
+				'func'       => '_message_queue_list_table',
394
+				'capability' => 'ee_read_global_messages',
395
+			),
396
+			'global_mtps'                      => array(
397
+				'func'       => '_ee_default_messages_overview_list_table',
398
+				'capability' => 'ee_read_global_messages',
399
+			),
400
+			'custom_mtps'                      => array(
401
+				'func'       => '_custom_mtps_preview',
402
+				'capability' => 'ee_read_messages',
403
+			),
404
+			'add_new_message_template'         => array(
405
+				'func'       => '_add_message_template',
406
+				'capability' => 'ee_edit_messages',
407
+				'noheader'   => true,
408
+			),
409
+			'edit_message_template'            => array(
410
+				'func'       => '_edit_message_template',
411
+				'capability' => 'ee_edit_message',
412
+				'obj_id'     => $grp_id,
413
+			),
414
+			'preview_message'                  => array(
415
+				'func'               => '_preview_message',
416
+				'capability'         => 'ee_read_message',
417
+				'obj_id'             => $grp_id,
418
+				'noheader'           => true,
419
+				'headers_sent_route' => 'display_preview_message',
420
+			),
421
+			'display_preview_message'          => array(
422
+				'func'       => '_display_preview_message',
423
+				'capability' => 'ee_read_message',
424
+				'obj_id'     => $grp_id,
425
+			),
426
+			'insert_message_template'          => array(
427
+				'func'       => '_insert_or_update_message_template',
428
+				'capability' => 'ee_edit_messages',
429
+				'args'       => array('new_template' => true),
430
+				'noheader'   => true,
431
+			),
432
+			'update_message_template'          => array(
433
+				'func'       => '_insert_or_update_message_template',
434
+				'capability' => 'ee_edit_message',
435
+				'obj_id'     => $grp_id,
436
+				'args'       => array('new_template' => false),
437
+				'noheader'   => true,
438
+			),
439
+			'trash_message_template'           => array(
440
+				'func'       => '_trash_or_restore_message_template',
441
+				'capability' => 'ee_delete_message',
442
+				'obj_id'     => $grp_id,
443
+				'args'       => array('trash' => true, 'all' => true),
444
+				'noheader'   => true,
445
+			),
446
+			'trash_message_template_context'   => array(
447
+				'func'       => '_trash_or_restore_message_template',
448
+				'capability' => 'ee_delete_message',
449
+				'obj_id'     => $grp_id,
450
+				'args'       => array('trash' => true),
451
+				'noheader'   => true,
452
+			),
453
+			'restore_message_template'         => array(
454
+				'func'       => '_trash_or_restore_message_template',
455
+				'capability' => 'ee_delete_message',
456
+				'obj_id'     => $grp_id,
457
+				'args'       => array('trash' => false, 'all' => true),
458
+				'noheader'   => true,
459
+			),
460
+			'restore_message_template_context' => array(
461
+				'func'       => '_trash_or_restore_message_template',
462
+				'capability' => 'ee_delete_message',
463
+				'obj_id'     => $grp_id,
464
+				'args'       => array('trash' => false),
465
+				'noheader'   => true,
466
+			),
467
+			'delete_message_template'          => array(
468
+				'func'       => '_delete_message_template',
469
+				'capability' => 'ee_delete_message',
470
+				'obj_id'     => $grp_id,
471
+				'noheader'   => true,
472
+			),
473
+			'reset_to_default'                 => array(
474
+				'func'       => '_reset_to_default_template',
475
+				'capability' => 'ee_edit_message',
476
+				'obj_id'     => $grp_id,
477
+				'noheader'   => true,
478
+			),
479
+			'settings'                         => array(
480
+				'func'       => '_settings',
481
+				'capability' => 'manage_options',
482
+			),
483
+			'update_global_settings'           => array(
484
+				'func'       => '_update_global_settings',
485
+				'capability' => 'manage_options',
486
+				'noheader'   => true,
487
+			),
488
+			'generate_now'                     => array(
489
+				'func'       => '_generate_now',
490
+				'capability' => 'ee_send_message',
491
+				'noheader'   => true,
492
+			),
493
+			'generate_and_send_now'            => array(
494
+				'func'       => '_generate_and_send_now',
495
+				'capability' => 'ee_send_message',
496
+				'noheader'   => true,
497
+			),
498
+			'queue_for_resending'              => array(
499
+				'func'       => '_queue_for_resending',
500
+				'capability' => 'ee_send_message',
501
+				'noheader'   => true,
502
+			),
503
+			'send_now'                         => array(
504
+				'func'       => '_send_now',
505
+				'capability' => 'ee_send_message',
506
+				'noheader'   => true,
507
+			),
508
+			'delete_ee_message'                => array(
509
+				'func'       => '_delete_ee_messages',
510
+				'capability' => 'ee_delete_messages',
511
+				'noheader'   => true,
512
+			),
513
+			'delete_ee_messages'               => array(
514
+				'func'       => '_delete_ee_messages',
515
+				'capability' => 'ee_delete_messages',
516
+				'noheader'   => true,
517
+				'obj_id'     => $msg_id,
518
+			),
519
+		);
520
+	}
521
+
522
+
523
+	protected function _set_page_config()
524
+	{
525
+		$this->_page_config = array(
526
+			'default'                  => array(
527
+				'nav'           => array(
528
+					'label' => esc_html__('Message Activity', 'event_espresso'),
529
+					'order' => 10,
530
+				),
531
+				'list_table'    => 'EE_Message_List_Table',
532
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
533
+				'require_nonce' => false,
534
+			),
535
+			'global_mtps'              => array(
536
+				'nav'           => array(
537
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
538
+					'order' => 20,
539
+				),
540
+				'list_table'    => 'Messages_Template_List_Table',
541
+				'help_tabs'     => array(
542
+					'messages_overview_help_tab'                                => array(
543
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
544
+						'filename' => 'messages_overview',
545
+					),
546
+					'messages_overview_messages_table_column_headings_help_tab' => array(
547
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
548
+						'filename' => 'messages_overview_table_column_headings',
549
+					),
550
+					'messages_overview_messages_filters_help_tab'               => array(
551
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
552
+						'filename' => 'messages_overview_filters',
553
+					),
554
+					'messages_overview_messages_views_help_tab'                 => array(
555
+						'title'    => esc_html__('Message Views', 'event_espresso'),
556
+						'filename' => 'messages_overview_views',
557
+					),
558
+					'message_overview_message_types_help_tab'                   => array(
559
+						'title'    => esc_html__('Message Types', 'event_espresso'),
560
+						'filename' => 'messages_overview_types',
561
+					),
562
+					'messages_overview_messengers_help_tab'                     => array(
563
+						'title'    => esc_html__('Messengers', 'event_espresso'),
564
+						'filename' => 'messages_overview_messengers',
565
+					),
566
+				),
567
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
568
+				// 'help_tour'     => array('Messages_Overview_Help_Tour'),
569
+				'require_nonce' => false,
570
+			),
571
+			'custom_mtps'              => array(
572
+				'nav'           => array(
573
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
574
+					'order' => 30,
575
+				),
576
+				'help_tabs'     => array(),
577
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
578
+				// 'help_tour'     => array(),
579
+				'require_nonce' => false,
580
+			),
581
+			'add_new_message_template' => array(
582
+				'nav'           => array(
583
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
584
+					'order'      => 5,
585
+					'persistent' => false,
586
+				),
587
+				'require_nonce' => false,
588
+			),
589
+			'edit_message_template'    => array(
590
+				'labels'        => array(
591
+					'buttons'    => array(
592
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
593
+					),
594
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
595
+				),
596
+				'nav'           => array(
597
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
598
+					'order'      => 5,
599
+					'persistent' => false,
600
+					'url'        => '',
601
+				),
602
+				'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
603
+				'has_metaboxes' => true,
604
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
605
+				// 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
606
+				'help_tabs'     => array(
607
+					'edit_message_template'            => array(
608
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
609
+						'callback' => 'edit_message_template_help_tab',
610
+					),
611
+					'message_templates_help_tab'       => array(
612
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
613
+						'filename' => 'messages_templates',
614
+					),
615
+					'message_template_shortcodes'      => array(
616
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
617
+						'callback' => 'message_template_shortcodes_help_tab',
618
+					),
619
+					'message_preview_help_tab'         => array(
620
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
621
+						'filename' => 'messages_preview',
622
+					),
623
+					'messages_overview_other_help_tab' => array(
624
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
625
+						'filename' => 'messages_overview_other',
626
+					),
627
+				),
628
+				'require_nonce' => false,
629
+			),
630
+			'display_preview_message'  => array(
631
+				'nav'           => array(
632
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
633
+					'order'      => 5,
634
+					'url'        => '',
635
+					'persistent' => false,
636
+				),
637
+				'help_tabs'     => array(
638
+					'preview_message' => array(
639
+						'title'    => esc_html__('About Previews', 'event_espresso'),
640
+						'callback' => 'preview_message_help_tab',
641
+					),
642
+				),
643
+				'require_nonce' => false,
644
+			),
645
+			'settings'                 => array(
646
+				'nav'           => array(
647
+					'label' => esc_html__('Settings', 'event_espresso'),
648
+					'order' => 40,
649
+				),
650
+				'metaboxes'     => array('_messages_settings_metaboxes'),
651
+				'help_tabs'     => array(
652
+					'messages_settings_help_tab'               => array(
653
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
654
+						'filename' => 'messages_settings',
655
+					),
656
+					'messages_settings_message_types_help_tab' => array(
657
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
658
+						'filename' => 'messages_settings_message_types',
659
+					),
660
+					'messages_settings_messengers_help_tab'    => array(
661
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
662
+						'filename' => 'messages_settings_messengers',
663
+					),
664
+				),
665
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
666
+				// 'help_tour'     => array('Messages_Settings_Help_Tour'),
667
+				'require_nonce' => false,
668
+			),
669
+		);
670
+	}
671
+
672
+
673
+	protected function _add_screen_options()
674
+	{
675
+		// todo
676
+	}
677
+
678
+
679
+	protected function _add_screen_options_global_mtps()
680
+	{
681
+		/**
682
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
683
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
684
+		 */
685
+		$page_title = $this->_admin_page_title;
686
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
687
+		$this->_per_page_screen_option();
688
+		$this->_admin_page_title = $page_title;
689
+	}
690
+
691
+
692
+	protected function _add_screen_options_default()
693
+	{
694
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
695
+		$this->_per_page_screen_option();
696
+	}
697
+
698
+
699
+	// none of the below group are currently used for Messages
700
+	protected function _add_feature_pointers()
701
+	{
702
+	}
703
+
704
+	public function admin_init()
705
+	{
706
+	}
707
+
708
+	public function admin_notices()
709
+	{
710
+	}
711
+
712
+	public function admin_footer_scripts()
713
+	{
714
+	}
715
+
716
+
717
+	public function messages_help_tab()
718
+	{
719
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
720
+	}
721
+
722
+
723
+	public function messengers_help_tab()
724
+	{
725
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
726
+	}
727
+
728
+
729
+	public function message_types_help_tab()
730
+	{
731
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
732
+	}
733
+
734
+
735
+	public function messages_overview_help_tab()
736
+	{
737
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
738
+	}
739
+
740
+
741
+	public function message_templates_help_tab()
742
+	{
743
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
744
+	}
745
+
746
+
747
+	public function edit_message_template_help_tab()
748
+	{
749
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
750
+						. esc_attr__('Editor Title', 'event_espresso')
751
+						. '" />';
752
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
753
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
754
+						. '" />';
755
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
756
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
757
+						. '" />';
758
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
759
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
760
+						. '" />';
761
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
762
+						. esc_attr__('Publish Metabox', 'event_espresso')
763
+						. '" />';
764
+		EEH_Template::display_template(
765
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
766
+			$args
767
+		);
768
+	}
769
+
770
+
771
+	public function message_template_shortcodes_help_tab()
772
+	{
773
+		$this->_set_shortcodes();
774
+		$args['shortcodes'] = $this->_shortcodes;
775
+		EEH_Template::display_template(
776
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
777
+			$args
778
+		);
779
+	}
780
+
781
+
782
+	public function preview_message_help_tab()
783
+	{
784
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
785
+	}
786
+
787
+
788
+	public function settings_help_tab()
789
+	{
790
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
791
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
792
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
793
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
794
+		$args['img3'] = '<div class="switch">'
795
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
796
+						. ' type="checkbox" checked="checked">'
797
+						. '<label for="ee-on-off-toggle-on"></label>'
798
+						. '</div>';
799
+		$args['img4'] = '<div class="switch">'
800
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
801
+						. ' type="checkbox">'
802
+						. '<label for="ee-on-off-toggle-on"></label>'
803
+						. '</div>';
804
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
805
+	}
806
+
807
+
808
+	public function load_scripts_styles()
809
+	{
810
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
811
+		wp_enqueue_style('espresso_ee_msg');
812
+
813
+		wp_register_script(
814
+			'ee-messages-settings',
815
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
816
+			array('jquery-ui-droppable', 'ee-serialize-full-array'),
817
+			EVENT_ESPRESSO_VERSION,
818
+			true
819
+		);
820
+		wp_register_script(
821
+			'ee-msg-list-table-js',
822
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
823
+			array('ee-dialog'),
824
+			EVENT_ESPRESSO_VERSION
825
+		);
826
+	}
827
+
828
+
829
+	public function load_scripts_styles_default()
830
+	{
831
+		wp_enqueue_script('ee-msg-list-table-js');
832
+	}
833
+
834
+
835
+	public function wp_editor_css($mce_css)
836
+	{
837
+		// if we're on the edit_message_template route
838
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
839
+			$message_type_name = $this->_active_message_type_name;
840
+
841
+			// we're going to REPLACE the existing mce css
842
+			// we need to get the css file location from the active messenger
843
+			$mce_css = $this->_active_messenger->get_variation(
844
+				$this->_template_pack,
845
+				$message_type_name,
846
+				true,
847
+				'wpeditor',
848
+				$this->_variation
849
+			);
850
+		}
851
+
852
+		return $mce_css;
853
+	}
854
+
855
+
856
+	public function load_scripts_styles_edit_message_template()
857
+	{
858
+
859
+		$this->_set_shortcodes();
860
+
861
+		EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
862
+			esc_html__(
863
+				'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
864
+				'event_espresso'
865
+			),
866
+			$this->_message_template_group->messenger_obj()->label['singular'],
867
+			$this->_message_template_group->message_type_obj()->label['singular']
868
+		);
869
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
870
+			'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
871
+			'event_espresso'
872
+		);
873
+		EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
874
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
875
+			'event_espresso'
876
+		);
877
+
878
+		wp_register_script(
879
+			'ee_msgs_edit_js',
880
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
881
+			array('jquery'),
882
+			EVENT_ESPRESSO_VERSION
883
+		);
884
+
885
+		wp_enqueue_script('ee_admin_js');
886
+		wp_enqueue_script('ee_msgs_edit_js');
887
+
888
+		// add in special css for tiny_mce
889
+		add_filter('mce_css', array($this, 'wp_editor_css'));
890
+	}
891
+
892
+
893
+	public function load_scripts_styles_display_preview_message()
894
+	{
895
+
896
+		$this->_set_message_template_group();
897
+
898
+		if (isset($this->_req_data['messenger'])) {
899
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
900
+				$this->_req_data['messenger']
901
+			);
902
+		}
903
+
904
+		$message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
905
+
906
+
907
+		wp_enqueue_style(
908
+			'espresso_preview_css',
909
+			$this->_active_messenger->get_variation(
910
+				$this->_template_pack,
911
+				$message_type_name,
912
+				true,
913
+				'preview',
914
+				$this->_variation
915
+			)
916
+		);
917
+	}
918
+
919
+
920
+	public function load_scripts_styles_settings()
921
+	{
922
+		wp_register_style(
923
+			'ee-message-settings',
924
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
925
+			array(),
926
+			EVENT_ESPRESSO_VERSION
927
+		);
928
+		wp_enqueue_style('ee-text-links');
929
+		wp_enqueue_style('ee-message-settings');
930
+		wp_enqueue_script('ee-messages-settings');
931
+	}
932
+
933
+
934
+	/**
935
+	 * set views array for List Table
936
+	 */
937
+	public function _set_list_table_views_global_mtps()
938
+	{
939
+		$this->_views = array(
940
+			'in_use' => array(
941
+				'slug'  => 'in_use',
942
+				'label' => esc_html__('In Use', 'event_espresso'),
943
+				'count' => 0,
944
+			),
945
+		);
946
+	}
947
+
948
+
949
+	/**
950
+	 * Set views array for the Custom Template List Table
951
+	 */
952
+	public function _set_list_table_views_custom_mtps()
953
+	{
954
+		$this->_set_list_table_views_global_mtps();
955
+		$this->_views['in_use']['bulk_action'] = array(
956
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
957
+		);
958
+	}
959
+
960
+
961
+	/**
962
+	 * set views array for message queue list table
963
+	 *
964
+	 * @throws InvalidDataTypeException
965
+	 * @throws InvalidInterfaceException
966
+	 * @throws InvalidArgumentException
967
+	 * @throws EE_Error
968
+	 * @throws ReflectionException
969
+	 */
970
+	public function _set_list_table_views_default()
971
+	{
972
+		EE_Registry::instance()->load_helper('Template');
973
+
974
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
975
+			'ee_send_message',
976
+			'message_list_table_bulk_actions'
977
+		)
978
+			? array(
979
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
980
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
981
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
982
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
983
+			)
984
+			: array();
985
+
986
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
987
+			'ee_delete_messages',
988
+			'message_list_table_bulk_actions'
989
+		)
990
+			? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
991
+			: array();
992
+
993
+
994
+		$this->_views = array(
995
+			'all' => array(
996
+				'slug'        => 'all',
997
+				'label'       => esc_html__('All', 'event_espresso'),
998
+				'count'       => 0,
999
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1000
+			),
1001
+		);
1002
+
1003
+
1004
+		foreach (EEM_Message::instance()->all_statuses() as $status) {
1005
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1006
+				continue;
1007
+			}
1008
+			$status_bulk_actions = $common_bulk_actions;
1009
+			// unset bulk actions not applying to status
1010
+			if (! empty($status_bulk_actions)) {
1011
+				switch ($status) {
1012
+					case EEM_Message::status_idle:
1013
+					case EEM_Message::status_resend:
1014
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1015
+						break;
1016
+
1017
+					case EEM_Message::status_failed:
1018
+					case EEM_Message::status_debug_only:
1019
+					case EEM_Message::status_messenger_executing:
1020
+						$status_bulk_actions = array();
1021
+						break;
1022
+
1023
+					case EEM_Message::status_incomplete:
1024
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1025
+						break;
1026
+
1027
+					case EEM_Message::status_retry:
1028
+					case EEM_Message::status_sent:
1029
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1030
+						break;
1031
+				}
1032
+			}
1033
+
1034
+			// skip adding messenger executing status to views because it will be included with the Failed view.
1035
+			if ($status === EEM_Message::status_messenger_executing) {
1036
+				continue;
1037
+			}
1038
+
1039
+			$this->_views[ strtolower($status) ] = array(
1040
+				'slug'        => strtolower($status),
1041
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1042
+				'count'       => 0,
1043
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1044
+			);
1045
+		}
1046
+	}
1047
+
1048
+
1049
+	protected function _ee_default_messages_overview_list_table()
1050
+	{
1051
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1052
+		$this->display_admin_list_table_page_with_no_sidebar();
1053
+	}
1054
+
1055
+
1056
+	protected function _message_queue_list_table()
1057
+	{
1058
+		$this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1059
+		$this->_template_args['per_column'] = 6;
1060
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1061
+		$this->_template_args['before_list_table'] = '<h3>'
1062
+													 . EEM_Message::instance()->get_pretty_label_for_results()
1063
+													 . '</h3>';
1064
+		$this->display_admin_list_table_page_with_no_sidebar();
1065
+	}
1066
+
1067
+
1068
+	protected function _message_legend_items()
1069
+	{
1070
+
1071
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1072
+		$action_items = array();
1073
+
1074
+		foreach ($action_css_classes as $action_item => $action_details) {
1075
+			if ($action_item === 'see_notifications_for') {
1076
+				continue;
1077
+			}
1078
+			$action_items[ $action_item ] = array(
1079
+				'class' => $action_details['css_class'],
1080
+				'desc'  => $action_details['label'],
1081
+			);
1082
+		}
1083
+
1084
+		/** @type array $status_items status legend setup */
1085
+		$status_items = array(
1086
+			'incomplete_status'          => array(
1087
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1088
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1089
+			),
1090
+			'idle_status'                => array(
1091
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1092
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1093
+			),
1094
+			'resend_status'              => array(
1095
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1096
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1097
+			),
1098
+			'messenger_executing_status' => array(
1099
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1100
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1101
+			),
1102
+			'sent_status'                => array(
1103
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1104
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1105
+			),
1106
+			'retry_status'               => array(
1107
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1108
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1109
+			),
1110
+			'failed_status'              => array(
1111
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1112
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1113
+			),
1114
+		);
1115
+		if (EEM_Message::debug()) {
1116
+			$status_items['debug_only_status'] = array(
1117
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1118
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1119
+			);
1120
+		}
1121
+
1122
+		return array_merge($action_items, $status_items);
1123
+	}
1124
+
1125
+
1126
+	protected function _custom_mtps_preview()
1127
+	{
1128
+		$this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1129
+		$this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1130
+											   . ' alt="' . esc_attr__(
1131
+												   'Preview Custom Message Templates screenshot',
1132
+												   'event_espresso'
1133
+											   ) . '" />';
1134
+		$this->_template_args['preview_text'] = '<strong>'
1135
+												. esc_html__(
1136
+													'Custom Message Templates is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1137
+													'event_espresso'
1138
+												)
1139
+												. '</strong>';
1140
+
1141
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1142
+	}
1143
+
1144
+
1145
+	/**
1146
+	 * get_message_templates
1147
+	 * This gets all the message templates for listing on the overview list.
1148
+	 *
1149
+	 * @access public
1150
+	 * @param int    $perpage the amount of templates groups to show per page
1151
+	 * @param string $type    the current _view we're getting templates for
1152
+	 * @param bool   $count   return count?
1153
+	 * @param bool   $all     disregard any paging info (get all data);
1154
+	 * @param bool   $global  whether to return just global (true) or custom templates (false)
1155
+	 * @return array
1156
+	 * @throws EE_Error
1157
+	 * @throws InvalidArgumentException
1158
+	 * @throws InvalidDataTypeException
1159
+	 * @throws InvalidInterfaceException
1160
+	 */
1161
+	public function get_message_templates(
1162
+		$perpage = 10,
1163
+		$type = 'in_use',
1164
+		$count = false,
1165
+		$all = false,
1166
+		$global = true
1167
+	) {
1168
+
1169
+		$MTP = EEM_Message_Template_Group::instance();
1170
+
1171
+		$this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1172
+		$orderby = $this->_req_data['orderby'];
1173
+
1174
+		$order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1175
+			? $this->_req_data['order']
1176
+			: 'ASC';
1177
+
1178
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1179
+			? $this->_req_data['paged']
1180
+			: 1;
1181
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1182
+			? $this->_req_data['perpage']
1183
+			: $perpage;
1184
+
1185
+		$offset = ($current_page - 1) * $per_page;
1186
+		$limit = $all ? null : array($offset, $per_page);
1187
+
1188
+
1189
+		// options will match what is in the _views array property
1190
+		switch ($type) {
1191
+			case 'in_use':
1192
+				$templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1193
+				break;
1194
+			default:
1195
+				$templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1196
+		}
1197
+
1198
+		return $templates;
1199
+	}
1200
+
1201
+
1202
+	/**
1203
+	 * filters etc might need a list of installed message_types
1204
+	 *
1205
+	 * @return array an array of message type objects
1206
+	 */
1207
+	public function get_installed_message_types()
1208
+	{
1209
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1210
+		$installed = array();
1211
+
1212
+		foreach ($installed_message_types as $message_type) {
1213
+			$installed[ $message_type->name ] = $message_type;
1214
+		}
1215
+
1216
+		return $installed;
1217
+	}
1218
+
1219
+
1220
+	/**
1221
+	 * _add_message_template
1222
+	 *
1223
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1224
+	 *
1225
+	 * @param string $message_type
1226
+	 * @param string $messenger
1227
+	 * @param string $GRP_ID
1228
+	 *
1229
+	 * @throws EE_error
1230
+	 */
1231
+	protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1232
+	{
1233
+		// set values override any request data
1234
+		$message_type = ! empty($message_type) ? $message_type : '';
1235
+		$message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1236
+			? $this->_req_data['message_type']
1237
+			: $message_type;
1238
+
1239
+		$messenger = ! empty($messenger) ? $messenger : '';
1240
+		$messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1241
+			? $this->_req_data['messenger']
1242
+			: $messenger;
1243
+
1244
+		$GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1245
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1246
+
1247
+		// we need messenger and message type.  They should be coming from the event editor. If not here then return error
1248
+		if (empty($message_type) || empty($messenger)) {
1249
+			throw new EE_Error(
1250
+				esc_html__(
1251
+					'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1252
+					'event_espresso'
1253
+				)
1254
+			);
1255
+		}
1256
+
1257
+		// we need the GRP_ID for the template being used as the base for the new template
1258
+		if (empty($GRP_ID)) {
1259
+			throw new EE_Error(
1260
+				esc_html__(
1261
+					'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1262
+					'event_espresso'
1263
+				)
1264
+			);
1265
+		}
1266
+
1267
+		// let's just make sure the template gets generated!
1268
+
1269
+		// we need to reassign some variables for what the insert is expecting
1270
+		$this->_req_data['MTP_messenger'] = $messenger;
1271
+		$this->_req_data['MTP_message_type'] = $message_type;
1272
+		$this->_req_data['GRP_ID'] = $GRP_ID;
1273
+		$this->_insert_or_update_message_template(true);
1274
+	}
1275
+
1276
+
1277
+	/**
1278
+	 * public wrapper for the _add_message_template method
1279
+	 *
1280
+	 * @param string $message_type     message type slug
1281
+	 * @param string $messenger        messenger slug
1282
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1283
+	 *                                 off of.
1284
+	 * @throws EE_error
1285
+	 */
1286
+	public function add_message_template($message_type, $messenger, $GRP_ID)
1287
+	{
1288
+		$this->_add_message_template($message_type, $messenger, $GRP_ID);
1289
+	}
1290
+
1291
+
1292
+	/**
1293
+	 * _edit_message_template
1294
+	 *
1295
+	 * @access protected
1296
+	 * @return void
1297
+	 * @throws InvalidIdentifierException
1298
+	 * @throws DomainException
1299
+	 * @throws EE_Error
1300
+	 * @throws InvalidArgumentException
1301
+	 * @throws ReflectionException
1302
+	 * @throws InvalidDataTypeException
1303
+	 * @throws InvalidInterfaceException
1304
+	 */
1305
+	protected function _edit_message_template()
1306
+	{
1307
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1308
+		$template_fields = '';
1309
+		$sidebar_fields = '';
1310
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1311
+		// valid html in the templates.
1312
+		add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1313
+
1314
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1315
+			? absint($this->_req_data['id'])
1316
+			: false;
1317
+
1318
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1319
+		? absint($this->_req_data['evt_id'])
1320
+		: false;
1321
+
1322
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1323
+		$message_template_group = $this->_message_template_group;
1324
+		$c_label = $message_template_group->context_label();
1325
+		$c_config = $message_template_group->contexts_config();
1326
+
1327
+		reset($c_config);
1328
+		$context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1329
+			? strtolower($this->_req_data['context'])
1330
+			: key($c_config);
1331
+
1332
+
1333
+		if (empty($GRP_ID)) {
1334
+			$action = 'insert_message_template';
1335
+			$edit_message_template_form_url = add_query_arg(
1336
+				array('action' => $action, 'noheader' => true),
1337
+				EE_MSG_ADMIN_URL
1338
+			);
1339
+		} else {
1340
+			$action = 'update_message_template';
1341
+			$edit_message_template_form_url = add_query_arg(
1342
+				array('action' => $action, 'noheader' => true),
1343
+				EE_MSG_ADMIN_URL
1344
+			);
1345
+		}
1346
+
1347
+		// set active messenger for this view
1348
+		$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1349
+			$message_template_group->messenger()
1350
+		);
1351
+		$this->_active_message_type_name = $message_template_group->message_type();
1352
+
1353
+
1354
+		// Do we have any validation errors?
1355
+		$validators = $this->_get_transient();
1356
+		$v_fields = ! empty($validators) ? array_keys($validators) : array();
1357
+
1358
+
1359
+		// we need to assemble the title from Various details
1360
+		$context_label = sprintf(
1361
+			esc_html__('(%s %s)', 'event_espresso'),
1362
+			$c_config[ $context ]['label'],
1363
+			ucwords($c_label['label'])
1364
+		);
1365
+
1366
+		$title = sprintf(
1367
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1368
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1369
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1370
+			$context_label
1371
+		);
1372
+
1373
+		$this->_template_args['GRP_ID'] = $GRP_ID;
1374
+		$this->_template_args['message_template'] = $message_template_group;
1375
+		$this->_template_args['is_extra_fields'] = false;
1376
+
1377
+
1378
+		// let's get EEH_MSG_Template so we can get template form fields
1379
+		$template_field_structure = EEH_MSG_Template::get_fields(
1380
+			$message_template_group->messenger(),
1381
+			$message_template_group->message_type()
1382
+		);
1383
+
1384
+		if (! $template_field_structure) {
1385
+			$template_field_structure = false;
1386
+			$template_fields = esc_html__(
1387
+				'There was an error in assembling the fields for this display (you should see an error message)',
1388
+				'event_espresso'
1389
+			);
1390
+		}
1391
+
1392
+
1393
+		$message_templates = $message_template_group->context_templates();
1394
+
1395
+
1396
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1397
+		// will get handled in the "extra" array.
1398
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1399
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1400
+				unset($template_field_structure[ $context ][ $reference_field ]);
1401
+			}
1402
+		}
1403
+
1404
+		// let's loop through the template_field_structure and actually assemble the input fields!
1405
+		if (! empty($template_field_structure)) {
1406
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1407
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1408
+				// the extra array and reset them.
1409
+				if ($template_field === 'extra') {
1410
+					$this->_template_args['is_extra_fields'] = true;
1411
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1412
+						$message_template = $message_templates[ $context ][ $reference_field ];
1413
+						$content = $message_template instanceof EE_Message_Template
1414
+							? $message_template->get('MTP_content')
1415
+							: '';
1416
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1417
+							// let's verify if we need this extra field via the shortcodes parameter.
1418
+							$continue = false;
1419
+							if (isset($extra_array['shortcodes_required'])) {
1420
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1421
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1422
+										$continue = true;
1423
+									}
1424
+								}
1425
+								if ($continue) {
1426
+									continue;
1427
+								}
1428
+							}
1429
+
1430
+							$field_id = $reference_field
1431
+										. '-'
1432
+										. $extra_field
1433
+										. '-content';
1434
+							$template_form_fields[ $field_id ] = $extra_array;
1435
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1436
+																		 . $reference_field
1437
+																		 . '][content]['
1438
+																		 . $extra_field . ']';
1439
+							$css_class = isset($extra_array['css_class'])
1440
+								? $extra_array['css_class']
1441
+								: '';
1442
+
1443
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1444
+																			  && in_array($extra_field, $v_fields, true)
1445
+																			  &&
1446
+																			  (
1447
+																				  is_array($validators[ $extra_field ])
1448
+																				  && isset($validators[ $extra_field ]['msg'])
1449
+																			  )
1450
+								? 'validate-error ' . $css_class
1451
+								: $css_class;
1452
+
1453
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1454
+																		  && isset($content[ $extra_field ])
1455
+								? $content[ $extra_field ]
1456
+								: '';
1457
+
1458
+							// do we have a validation error?  if we do then let's use that value instead
1459
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1460
+								? $validators[ $extra_field ]['value']
1461
+								: $template_form_fields[ $field_id ]['value'];
1462
+
1463
+
1464
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1465
+
1466
+							// shortcode selector
1467
+							$field_name_to_use = $extra_field === 'main'
1468
+								? 'content'
1469
+								: $extra_field;
1470
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1471
+								$field_name_to_use,
1472
+								$field_id
1473
+							);
1474
+
1475
+							if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1476
+								// we want to decode the entities
1477
+								$template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1478
+							}/**/
1479
+						}
1480
+						$templatefield_MTP_id = $reference_field . '-MTP_ID';
1481
+						$templatefield_templatename_id = $reference_field . '-name';
1482
+
1483
+						$template_form_fields[ $templatefield_MTP_id ] = array(
1484
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1485
+							'label'      => null,
1486
+							'input'      => 'hidden',
1487
+							'type'       => 'int',
1488
+							'required'   => false,
1489
+							'validation' => false,
1490
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1491
+							'css_class'  => '',
1492
+							'format'     => '%d',
1493
+							'db-col'     => 'MTP_ID',
1494
+						);
1495
+
1496
+						$template_form_fields[ $templatefield_templatename_id ] = array(
1497
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1498
+							'label'      => null,
1499
+							'input'      => 'hidden',
1500
+							'type'       => 'string',
1501
+							'required'   => false,
1502
+							'validation' => true,
1503
+							'value'      => $reference_field,
1504
+							'css_class'  => '',
1505
+							'format'     => '%s',
1506
+							'db-col'     => 'MTP_template_field',
1507
+						);
1508
+					}
1509
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1510
+				} else {
1511
+					$field_id = $template_field . '-content';
1512
+					$template_form_fields[ $field_id ] = $field_setup_array;
1513
+					$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1514
+					$message_template = isset($message_templates[ $context ][ $template_field ])
1515
+						? $message_templates[ $context ][ $template_field ]
1516
+						: null;
1517
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1518
+																  && is_array($message_templates[ $context ])
1519
+																  && $message_template instanceof EE_Message_Template
1520
+						? $message_template->get('MTP_content')
1521
+						: '';
1522
+
1523
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1524
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1525
+						? $validators[ $template_field ]['value']
1526
+						: $template_form_fields[ $field_id ]['value'];
1527
+
1528
+
1529
+					$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1530
+					$css_class = isset($field_setup_array['css_class'])
1531
+						? $field_setup_array['css_class']
1532
+						: '';
1533
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1534
+																	  && in_array($template_field, $v_fields, true)
1535
+																	  && isset($validators[ $template_field ]['msg'])
1536
+						? 'validate-error ' . $css_class
1537
+						: $css_class;
1538
+
1539
+					// shortcode selector
1540
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1541
+						$template_field,
1542
+						$field_id
1543
+					);
1544
+				}
1545
+
1546
+				// k took care of content field(s) now let's take care of others.
1547
+
1548
+				$templatefield_MTP_id = $template_field . '-MTP_ID';
1549
+				$templatefield_field_templatename_id = $template_field . '-name';
1550
+
1551
+				// foreach template field there are actually two form fields created
1552
+				$template_form_fields[ $templatefield_MTP_id ] = array(
1553
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1554
+					'label'      => null,
1555
+					'input'      => 'hidden',
1556
+					'type'       => 'int',
1557
+					'required'   => false,
1558
+					'validation' => true,
1559
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1560
+					'css_class'  => '',
1561
+					'format'     => '%d',
1562
+					'db-col'     => 'MTP_ID',
1563
+				);
1564
+
1565
+				$template_form_fields[ $templatefield_field_templatename_id ] = array(
1566
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1567
+					'label'      => null,
1568
+					'input'      => 'hidden',
1569
+					'type'       => 'string',
1570
+					'required'   => false,
1571
+					'validation' => true,
1572
+					'value'      => $template_field,
1573
+					'css_class'  => '',
1574
+					'format'     => '%s',
1575
+					'db-col'     => 'MTP_template_field',
1576
+				);
1577
+			}
1578
+
1579
+			// add other fields
1580
+			$template_form_fields['ee-msg-current-context'] = array(
1581
+				'name'       => 'MTP_context',
1582
+				'label'      => null,
1583
+				'input'      => 'hidden',
1584
+				'type'       => 'string',
1585
+				'required'   => false,
1586
+				'validation' => true,
1587
+				'value'      => $context,
1588
+				'css_class'  => '',
1589
+				'format'     => '%s',
1590
+				'db-col'     => 'MTP_context',
1591
+			);
1592
+
1593
+			$template_form_fields['ee-msg-grp-id'] = array(
1594
+				'name'       => 'GRP_ID',
1595
+				'label'      => null,
1596
+				'input'      => 'hidden',
1597
+				'type'       => 'int',
1598
+				'required'   => false,
1599
+				'validation' => true,
1600
+				'value'      => $GRP_ID,
1601
+				'css_class'  => '',
1602
+				'format'     => '%d',
1603
+				'db-col'     => 'GRP_ID',
1604
+			);
1605
+
1606
+			$template_form_fields['ee-msg-messenger'] = array(
1607
+				'name'       => 'MTP_messenger',
1608
+				'label'      => null,
1609
+				'input'      => 'hidden',
1610
+				'type'       => 'string',
1611
+				'required'   => false,
1612
+				'validation' => true,
1613
+				'value'      => $message_template_group->messenger(),
1614
+				'css_class'  => '',
1615
+				'format'     => '%s',
1616
+				'db-col'     => 'MTP_messenger',
1617
+			);
1618
+
1619
+			$template_form_fields['ee-msg-message-type'] = array(
1620
+				'name'       => 'MTP_message_type',
1621
+				'label'      => null,
1622
+				'input'      => 'hidden',
1623
+				'type'       => 'string',
1624
+				'required'   => false,
1625
+				'validation' => true,
1626
+				'value'      => $message_template_group->message_type(),
1627
+				'css_class'  => '',
1628
+				'format'     => '%s',
1629
+				'db-col'     => 'MTP_message_type',
1630
+			);
1631
+
1632
+			$sidebar_form_fields['ee-msg-is-global'] = array(
1633
+				'name'       => 'MTP_is_global',
1634
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1635
+				'input'      => 'hidden',
1636
+				'type'       => 'int',
1637
+				'required'   => false,
1638
+				'validation' => true,
1639
+				'value'      => $message_template_group->get('MTP_is_global'),
1640
+				'css_class'  => '',
1641
+				'format'     => '%d',
1642
+				'db-col'     => 'MTP_is_global',
1643
+			);
1644
+
1645
+			$sidebar_form_fields['ee-msg-is-override'] = array(
1646
+				'name'       => 'MTP_is_override',
1647
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1648
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1649
+				'type'       => 'int',
1650
+				'required'   => false,
1651
+				'validation' => true,
1652
+				'value'      => $message_template_group->get('MTP_is_override'),
1653
+				'css_class'  => '',
1654
+				'format'     => '%d',
1655
+				'db-col'     => 'MTP_is_override',
1656
+			);
1657
+
1658
+			$sidebar_form_fields['ee-msg-is-active'] = array(
1659
+				'name'       => 'MTP_is_active',
1660
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1661
+				'input'      => 'hidden',
1662
+				'type'       => 'int',
1663
+				'required'   => false,
1664
+				'validation' => true,
1665
+				'value'      => $message_template_group->is_active(),
1666
+				'css_class'  => '',
1667
+				'format'     => '%d',
1668
+				'db-col'     => 'MTP_is_active',
1669
+			);
1670
+
1671
+			$sidebar_form_fields['ee-msg-deleted'] = array(
1672
+				'name'       => 'MTP_deleted',
1673
+				'label'      => null,
1674
+				'input'      => 'hidden',
1675
+				'type'       => 'int',
1676
+				'required'   => false,
1677
+				'validation' => true,
1678
+				'value'      => $message_template_group->get('MTP_deleted'),
1679
+				'css_class'  => '',
1680
+				'format'     => '%d',
1681
+				'db-col'     => 'MTP_deleted',
1682
+			);
1683
+			$sidebar_form_fields['ee-msg-author'] = array(
1684
+				'name'       => 'MTP_user_id',
1685
+				'label'      => esc_html__('Author', 'event_espresso'),
1686
+				'input'      => 'hidden',
1687
+				'type'       => 'int',
1688
+				'required'   => false,
1689
+				'validation' => false,
1690
+				'value'      => $message_template_group->user(),
1691
+				'format'     => '%d',
1692
+				'db-col'     => 'MTP_user_id',
1693
+			);
1694
+
1695
+			$sidebar_form_fields['ee-msg-route'] = array(
1696
+				'name'  => 'action',
1697
+				'input' => 'hidden',
1698
+				'type'  => 'string',
1699
+				'value' => $action,
1700
+			);
1701
+
1702
+			$sidebar_form_fields['ee-msg-id'] = array(
1703
+				'name'  => 'id',
1704
+				'input' => 'hidden',
1705
+				'type'  => 'int',
1706
+				'value' => $GRP_ID,
1707
+			);
1708
+			$sidebar_form_fields['ee-msg-evt-nonce'] = array(
1709
+				'name'  => $action . '_nonce',
1710
+				'input' => 'hidden',
1711
+				'type'  => 'string',
1712
+				'value' => wp_create_nonce($action . '_nonce'),
1713
+			);
1714
+
1715
+			if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1716
+				$sidebar_form_fields['ee-msg-template-switch'] = array(
1717
+					'name'  => 'template_switch',
1718
+					'input' => 'hidden',
1719
+					'type'  => 'int',
1720
+					'value' => 1,
1721
+				);
1722
+			}
1723
+
1724
+
1725
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1726
+			$sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1727
+		} //end if ( !empty($template_field_structure) )
1728
+
1729
+		// set extra content for publish box
1730
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1731
+		$this->_set_publish_post_box_vars(
1732
+			'id',
1733
+			$GRP_ID,
1734
+			false,
1735
+			add_query_arg(
1736
+				array('action' => 'global_mtps'),
1737
+				$this->_admin_base_url
1738
+			)
1739
+		);
1740
+
1741
+		// add preview button
1742
+		$preview_url = parent::add_query_args_and_nonce(
1743
+			array(
1744
+				'message_type' => $message_template_group->message_type(),
1745
+				'messenger'    => $message_template_group->messenger(),
1746
+				'context'      => $context,
1747
+				'GRP_ID'       => $GRP_ID,
1748
+				'evt_id'       => $EVT_ID,
1749
+				'action'       => 'preview_message',
1750
+			),
1751
+			$this->_admin_base_url
1752
+		);
1753
+		$preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1754
+						  . esc_html__('Preview', 'event_espresso')
1755
+						  . '</a>';
1756
+
1757
+
1758
+		// setup context switcher
1759
+		$context_switcher_args = array(
1760
+			'page'    => 'espresso_messages',
1761
+			'action'  => 'edit_message_template',
1762
+			'id'      => $GRP_ID,
1763
+			'evt_id'  => $EVT_ID,
1764
+			'context' => $context,
1765
+			'extra'   => $preview_button,
1766
+		);
1767
+		$this->_set_context_switcher($message_template_group, $context_switcher_args);
1768
+
1769
+
1770
+		// main box
1771
+		$this->_template_args['template_fields'] = $template_fields;
1772
+		$this->_template_args['sidebar_box_id'] = 'details';
1773
+		$this->_template_args['action'] = $action;
1774
+		$this->_template_args['context'] = $context;
1775
+		$this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1776
+		$this->_template_args['learn_more_about_message_templates_link'] =
1777
+			$this->_learn_more_about_message_templates_link();
1778
+
1779
+
1780
+		$this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1781
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1782
+			$message_template_group,
1783
+			$context,
1784
+			$context_label
1785
+		);
1786
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1787
+		$this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1788
+
1789
+		$this->_template_path = $this->_template_args['GRP_ID']
1790
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1791
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1792
+
1793
+		// send along EE_Message_Template_Group object for further template use.
1794
+		$this->_template_args['MTP'] = $message_template_group;
1795
+
1796
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1797
+			$this->_template_path,
1798
+			$this->_template_args,
1799
+			true
1800
+		);
1801
+
1802
+
1803
+		// finally, let's set the admin_page title
1804
+		$this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1805
+
1806
+
1807
+		// we need to take care of setting the shortcodes property for use elsewhere.
1808
+		$this->_set_shortcodes();
1809
+
1810
+
1811
+		// final template wrapper
1812
+		$this->display_admin_page_with_sidebar();
1813
+	}
1814
+
1815
+
1816
+	public function filter_tinymce_init($mceInit, $editor_id)
1817
+	{
1818
+		return $mceInit;
1819
+	}
1820
+
1821
+
1822
+	public function add_context_switcher()
1823
+	{
1824
+		return $this->_context_switcher;
1825
+	}
1826
+
1827
+
1828
+	/**
1829
+	 * Adds the activation/deactivation toggle for the message template context.
1830
+	 *
1831
+	 * @param EE_Message_Template_Group $message_template_group
1832
+	 * @param string                    $context
1833
+	 * @param string                    $context_label
1834
+	 * @return string
1835
+	 * @throws DomainException
1836
+	 * @throws EE_Error
1837
+	 * @throws InvalidIdentifierException
1838
+	 */
1839
+	protected function add_active_context_element(
1840
+		EE_Message_Template_Group $message_template_group,
1841
+		$context,
1842
+		$context_label
1843
+	) {
1844
+		$template_args = array(
1845
+			'context'                   => $context,
1846
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1847
+			'is_active'                 => $message_template_group->is_context_active($context),
1848
+			'on_off_action'             => $message_template_group->is_context_active($context)
1849
+				? 'context-off'
1850
+				: 'context-on',
1851
+			'context_label'             => str_replace(array('(', ')'), '', $context_label),
1852
+			'message_template_group_id' => $message_template_group->ID(),
1853
+		);
1854
+		return EEH_Template::display_template(
1855
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1856
+			$template_args,
1857
+			true
1858
+		);
1859
+	}
1860
+
1861
+
1862
+	/**
1863
+	 * Ajax callback for `toggle_context_template` ajax action.
1864
+	 * Handles toggling the message context on or off.
1865
+	 *
1866
+	 * @throws EE_Error
1867
+	 * @throws InvalidArgumentException
1868
+	 * @throws InvalidDataTypeException
1869
+	 * @throws InvalidIdentifierException
1870
+	 * @throws InvalidInterfaceException
1871
+	 */
1872
+	public function toggle_context_template()
1873
+	{
1874
+		$success = true;
1875
+		// check for required data
1876
+		if (
1877
+			! isset(
1878
+				$this->_req_data['message_template_group_id'],
1879
+				$this->_req_data['context'],
1880
+				$this->_req_data['status']
1881
+			)
1882
+		) {
1883
+			EE_Error::add_error(
1884
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1885
+				__FILE__,
1886
+				__FUNCTION__,
1887
+				__LINE__
1888
+			);
1889
+			$success = false;
1890
+		}
1891
+
1892
+		$nonce = isset($this->_req_data['toggle_context_nonce'])
1893
+			? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1894
+			: '';
1895
+		$nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1896
+		$this->_verify_nonce($nonce, $nonce_ref);
1897
+		$status = $this->_req_data['status'];
1898
+		if ($status !== 'off' && $status !== 'on') {
1899
+			EE_Error::add_error(
1900
+				sprintf(
1901
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1902
+					$this->_req_data['status']
1903
+				),
1904
+				__FILE__,
1905
+				__FUNCTION__,
1906
+				__LINE__
1907
+			);
1908
+			$success = false;
1909
+		}
1910
+		$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1911
+			$this->_req_data['message_template_group_id']
1912
+		);
1913
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1914
+			EE_Error::add_error(
1915
+				sprintf(
1916
+					esc_html__(
1917
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1918
+						'event_espresso'
1919
+					),
1920
+					$this->_req_data['message_template_group_id'],
1921
+					'EE_Message_Template_Group'
1922
+				),
1923
+				__FILE__,
1924
+				__FUNCTION__,
1925
+				__LINE__
1926
+			);
1927
+			$success = false;
1928
+		}
1929
+		if ($success) {
1930
+			$success = $status === 'off'
1931
+				? $message_template_group->deactivate_context($this->_req_data['context'])
1932
+				: $message_template_group->activate_context($this->_req_data['context']);
1933
+		}
1934
+		$this->_template_args['success'] = $success;
1935
+		$this->_return_json();
1936
+	}
1937
+
1938
+
1939
+	public function _add_form_element_before()
1940
+	{
1941
+		return '<form method="post" action="'
1942
+			   . $this->_template_args["edit_message_template_form_url"]
1943
+			   . '" id="ee-msg-edit-frm">';
1944
+	}
1945
+
1946
+	public function _add_form_element_after()
1947
+	{
1948
+		return '</form>';
1949
+	}
1950
+
1951
+
1952
+	/**
1953
+	 * This executes switching the template pack for a message template.
1954
+	 *
1955
+	 * @since 4.5.0
1956
+	 * @throws EE_Error
1957
+	 * @throws InvalidDataTypeException
1958
+	 * @throws InvalidInterfaceException
1959
+	 * @throws InvalidArgumentException
1960
+	 * @throws ReflectionException
1961
+	 */
1962
+	public function switch_template_pack()
1963
+	{
1964
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1965
+		$template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1966
+
1967
+		// verify we have needed values.
1968
+		if (empty($GRP_ID) || empty($template_pack)) {
1969
+			$this->_template_args['error'] = true;
1970
+			EE_Error::add_error(
1971
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1972
+				__FILE__,
1973
+				__FUNCTION__,
1974
+				__LINE__
1975
+			);
1976
+		} else {
1977
+			// get template, set the new template_pack and then reset to default
1978
+			/** @type EE_Message_Template_Group $message_template_group */
1979
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1980
+
1981
+			$message_template_group->set_template_pack_name($template_pack);
1982
+			$this->_req_data['msgr'] = $message_template_group->messenger();
1983
+			$this->_req_data['mt'] = $message_template_group->message_type();
1984
+
1985
+			$query_args = $this->_reset_to_default_template();
1986
+
1987
+			if (empty($query_args['id'])) {
1988
+				EE_Error::add_error(
1989
+					esc_html__(
1990
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
1991
+						'event_espresso'
1992
+					),
1993
+					__FILE__,
1994
+					__FUNCTION__,
1995
+					__LINE__
1996
+				);
1997
+				$this->_template_args['error'] = true;
1998
+			} else {
1999
+				$template_label = $message_template_group->get_template_pack()->label;
2000
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2001
+				EE_Error::add_success(
2002
+					sprintf(
2003
+						esc_html__(
2004
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2005
+							'event_espresso'
2006
+						),
2007
+						$template_label,
2008
+						$template_pack_labels->template_pack
2009
+					)
2010
+				);
2011
+				// generate the redirect url for js.
2012
+				$url = self::add_query_args_and_nonce(
2013
+					$query_args,
2014
+					$this->_admin_base_url
2015
+				);
2016
+				$this->_template_args['data']['redirect_url'] = $url;
2017
+				$this->_template_args['success'] = true;
2018
+			}
2019
+
2020
+			$this->_return_json();
2021
+		}
2022
+	}
2023
+
2024
+
2025
+	/**
2026
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2027
+	 * they want.
2028
+	 *
2029
+	 * @access protected
2030
+	 * @return array|null
2031
+	 * @throws EE_Error
2032
+	 * @throws InvalidArgumentException
2033
+	 * @throws InvalidDataTypeException
2034
+	 * @throws InvalidInterfaceException
2035
+	 */
2036
+	protected function _reset_to_default_template()
2037
+	{
2038
+
2039
+		$templates = array();
2040
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2041
+		// we need to make sure we've got the info we need.
2042
+		if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2043
+			EE_Error::add_error(
2044
+				esc_html__(
2045
+					'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
2046
+					'event_espresso'
2047
+				),
2048
+				__FILE__,
2049
+				__FUNCTION__,
2050
+				__LINE__
2051
+			);
2052
+		}
2053
+
2054
+		// all templates will be reset to whatever the defaults are
2055
+		// for the global template matching the messenger and message type.
2056
+		$success = ! empty($GRP_ID) ? true : false;
2057
+
2058
+		if ($success) {
2059
+			// let's first determine if the incoming template is a global template,
2060
+			// if it isn't then we need to get the global template matching messenger and message type.
2061
+			// $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2062
+
2063
+
2064
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2065
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
2066
+
2067
+			if ($success) {
2068
+				// if successfully deleted, lets generate the new ones.
2069
+				// Note. We set GLOBAL to true, because resets on ANY template
2070
+				// will use the related global template defaults for regeneration.
2071
+				// This means that if a custom template is reset it resets to whatever the related global template is.
2072
+				// HOWEVER, we DO keep the template pack and template variation set
2073
+				// for the current custom template when resetting.
2074
+				$templates = $this->_generate_new_templates(
2075
+					$this->_req_data['msgr'],
2076
+					$this->_req_data['mt'],
2077
+					$GRP_ID,
2078
+					true
2079
+				);
2080
+			}
2081
+		}
2082
+
2083
+		// any error messages?
2084
+		if (! $success) {
2085
+			EE_Error::add_error(
2086
+				esc_html__(
2087
+					'Something went wrong with deleting existing templates. Unable to reset to default',
2088
+					'event_espresso'
2089
+				),
2090
+				__FILE__,
2091
+				__FUNCTION__,
2092
+				__LINE__
2093
+			);
2094
+		}
2095
+
2096
+		// all good, let's add a success message!
2097
+		if ($success && ! empty($templates)) {
2098
+			// the info for the template we generated is the first element in the returned array
2099
+			// $templates = $templates[0];
2100
+			EE_Error::overwrite_success();
2101
+			EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2102
+		}
2103
+
2104
+
2105
+		$query_args = array(
2106
+			'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2107
+			'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2108
+			'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2109
+		);
2110
+
2111
+		// if called via ajax then we return query args otherwise redirect
2112
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2113
+			return $query_args;
2114
+		} else {
2115
+			$this->_redirect_after_action(false, '', '', $query_args, true);
2116
+
2117
+			return null;
2118
+		}
2119
+	}
2120
+
2121
+
2122
+	/**
2123
+	 * Retrieve and set the message preview for display.
2124
+	 *
2125
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2126
+	 * @return string
2127
+	 * @throws ReflectionException
2128
+	 * @throws EE_Error
2129
+	 * @throws InvalidArgumentException
2130
+	 * @throws InvalidDataTypeException
2131
+	 * @throws InvalidInterfaceException
2132
+	 */
2133
+	public function _preview_message($send = false)
2134
+	{
2135
+		// first make sure we've got the necessary parameters
2136
+		if (
2137
+			! isset(
2138
+				$this->_req_data['message_type'],
2139
+				$this->_req_data['messenger'],
2140
+				$this->_req_data['messenger'],
2141
+				$this->_req_data['GRP_ID']
2142
+			)
2143
+		) {
2144
+			EE_Error::add_error(
2145
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2146
+				__FILE__,
2147
+				__FUNCTION__,
2148
+				__LINE__
2149
+			);
2150
+		}
2151
+
2152
+		EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
2153
+
2154
+		// if we have an evt_id set on the request, use it.
2155
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2156
+		? absint($this->_req_data['evt_id'])
2157
+		: false;
2158
+
2159
+
2160
+		// get the preview!
2161
+		$preview = EED_Messages::preview_message(
2162
+			$this->_req_data['message_type'],
2163
+			$this->_req_data['context'],
2164
+			$this->_req_data['messenger'],
2165
+			$send
2166
+		);
2167
+
2168
+		if ($send) {
2169
+			return $preview;
2170
+		}
2171
+
2172
+		// let's add a button to go back to the edit view
2173
+		$query_args = array(
2174
+			'id'      => $this->_req_data['GRP_ID'],
2175
+			'evt_id'  => $EVT_ID,
2176
+			'context' => $this->_req_data['context'],
2177
+			'action'  => 'edit_message_template',
2178
+		);
2179
+		$go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2180
+		$preview_button = '<a href="'
2181
+						  . $go_back_url
2182
+						  . '" class="button-secondary messages-preview-go-back-button">'
2183
+						  . esc_html__('Go Back to Edit', 'event_espresso')
2184
+						  . '</a>';
2185
+		$message_types = $this->get_installed_message_types();
2186
+		$active_messenger = $this->_message_resource_manager->get_active_messenger(
2187
+			$this->_req_data['messenger']
2188
+		);
2189
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2190
+			? ucwords($active_messenger->label['singular'])
2191
+			: esc_html__('Unknown Messenger', 'event_espresso');
2192
+		// let's provide a helpful title for context
2193
+		$preview_title = sprintf(
2194
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2195
+			$active_messenger_label,
2196
+			ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2197
+		);
2198
+		if (empty($preview)) {
2199
+			$this->noEventsErrorMessage();
2200
+		}
2201
+		// setup display of preview.
2202
+		$this->_admin_page_title = $preview_title;
2203
+		$this->_template_args['admin_page_title'] = $preview_title;
2204
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2205
+		$this->_template_args['data']['force_json'] = true;
2206
+
2207
+		return '';
2208
+	}
2209
+
2210
+
2211
+	/**
2212
+	 * Used to set an error if there are no events available for generating a preview/test send.
2213
+	 *
2214
+	 * @param bool $test_send  Whether the error should be generated for the context of a test send.
2215
+	 */
2216
+	protected function noEventsErrorMessage($test_send = false)
2217
+	{
2218
+		$events_url = parent::add_query_args_and_nonce(
2219
+			array(
2220
+				'action' => 'default',
2221
+				'page'   => 'espresso_events',
2222
+			),
2223
+			admin_url('admin.php')
2224
+		);
2225
+		$message = $test_send
2226
+			? __(
2227
+				'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2228
+				'event_espresso'
2229
+			)
2230
+			: __(
2231
+				'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2232
+				'event_espresso'
2233
+			);
2234
+
2235
+		EE_Error::add_attention(
2236
+			sprintf(
2237
+				$message,
2238
+				"<a href='{$events_url}'>",
2239
+				'</a>'
2240
+			)
2241
+		);
2242
+	}
2243
+
2244
+
2245
+	/**
2246
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2247
+	 * gets called automatically.
2248
+	 *
2249
+	 * @since 4.5.0
2250
+	 *
2251
+	 * @return string
2252
+	 */
2253
+	protected function _display_preview_message()
2254
+	{
2255
+		$this->display_admin_page_with_no_sidebar();
2256
+	}
2257
+
2258
+
2259
+	/**
2260
+	 * registers metaboxes that should show up on the "edit_message_template" page
2261
+	 *
2262
+	 * @access protected
2263
+	 * @return void
2264
+	 */
2265
+	protected function _register_edit_meta_boxes()
2266
+	{
2267
+		add_meta_box(
2268
+			'mtp_valid_shortcodes',
2269
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2270
+			array($this, 'shortcode_meta_box'),
2271
+			$this->_current_screen->id,
2272
+			'side',
2273
+			'default'
2274
+		);
2275
+		add_meta_box(
2276
+			'mtp_extra_actions',
2277
+			esc_html__('Extra Actions', 'event_espresso'),
2278
+			array($this, 'extra_actions_meta_box'),
2279
+			$this->_current_screen->id,
2280
+			'side',
2281
+			'high'
2282
+		);
2283
+		add_meta_box(
2284
+			'mtp_templates',
2285
+			esc_html__('Template Styles', 'event_espresso'),
2286
+			array($this, 'template_pack_meta_box'),
2287
+			$this->_current_screen->id,
2288
+			'side',
2289
+			'high'
2290
+		);
2291
+	}
2292
+
2293
+
2294
+	/**
2295
+	 * metabox content for all template pack and variation selection.
2296
+	 *
2297
+	 * @since 4.5.0
2298
+	 * @return string
2299
+	 * @throws DomainException
2300
+	 * @throws EE_Error
2301
+	 * @throws InvalidArgumentException
2302
+	 * @throws ReflectionException
2303
+	 * @throws InvalidDataTypeException
2304
+	 * @throws InvalidInterfaceException
2305
+	 */
2306
+	public function template_pack_meta_box()
2307
+	{
2308
+		$this->_set_message_template_group();
2309
+
2310
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2311
+
2312
+		$tp_select_values = array();
2313
+
2314
+		foreach ($tp_collection as $tp) {
2315
+			// only include template packs that support this messenger and message type!
2316
+			$supports = $tp->get_supports();
2317
+			if (
2318
+				! isset($supports[ $this->_message_template_group->messenger() ])
2319
+				|| ! in_array(
2320
+					$this->_message_template_group->message_type(),
2321
+					$supports[ $this->_message_template_group->messenger() ],
2322
+					true
2323
+				)
2324
+			) {
2325
+				// not supported
2326
+				continue;
2327
+			}
2328
+
2329
+			$tp_select_values[] = array(
2330
+				'text' => $tp->label,
2331
+				'id'   => $tp->dbref,
2332
+			);
2333
+		}
2334
+
2335
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2336
+		// the default template pack.  This still allows for the odd template pack to override.
2337
+		if (empty($tp_select_values)) {
2338
+			$tp_select_values[] = array(
2339
+				'text' => esc_html__('Default', 'event_espresso'),
2340
+				'id'   => 'default',
2341
+			);
2342
+		}
2343
+
2344
+		// setup variation select values for the currently selected template.
2345
+		$variations = $this->_message_template_group->get_template_pack()->get_variations(
2346
+			$this->_message_template_group->messenger(),
2347
+			$this->_message_template_group->message_type()
2348
+		);
2349
+		$variations_select_values = array();
2350
+		foreach ($variations as $variation => $label) {
2351
+			$variations_select_values[] = array(
2352
+				'text' => $label,
2353
+				'id'   => $variation,
2354
+			);
2355
+		}
2356
+
2357
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2358
+
2359
+		$template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2360
+			'MTP_template_pack',
2361
+			$tp_select_values,
2362
+			$this->_message_template_group->get_template_pack_name()
2363
+		);
2364
+		$template_args['variations_selector'] = EEH_Form_Fields::select_input(
2365
+			'MTP_template_variation',
2366
+			$variations_select_values,
2367
+			$this->_message_template_group->get_template_pack_variation()
2368
+		);
2369
+		$template_args['template_pack_label'] = $template_pack_labels->template_pack;
2370
+		$template_args['template_variation_label'] = $template_pack_labels->template_variation;
2371
+		$template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2372
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2373
+
2374
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2375
+
2376
+		EEH_Template::display_template($template, $template_args);
2377
+	}
2378
+
2379
+
2380
+	/**
2381
+	 * This meta box holds any extra actions related to Message Templates
2382
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2383
+	 *
2384
+	 * @access  public
2385
+	 * @return void
2386
+	 * @throws EE_Error
2387
+	 */
2388
+	public function extra_actions_meta_box()
2389
+	{
2390
+		$template_form_fields = array();
2391
+
2392
+		$extra_args = array(
2393
+			'msgr'   => $this->_message_template_group->messenger(),
2394
+			'mt'     => $this->_message_template_group->message_type(),
2395
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2396
+		);
2397
+		// first we need to see if there are any fields
2398
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2399
+
2400
+		if (! empty($fields)) {
2401
+			// yup there be fields
2402
+			foreach ($fields as $field => $config) {
2403
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2404
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2405
+				$default = isset($config['default']) ? $config['default'] : '';
2406
+				$default = isset($config['value']) ? $config['value'] : $default;
2407
+
2408
+				// if type is hidden and the value is empty
2409
+				// something may have gone wrong so let's correct with the defaults
2410
+				$fix = $config['input'] === 'hidden'
2411
+					   && isset($existing[ $field ])
2412
+					   && empty($existing[ $field ])
2413
+					? $default
2414
+					: '';
2415
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2416
+					? $existing[ $field ]
2417
+					: $fix;
2418
+
2419
+				$template_form_fields[ $field_id ] = array(
2420
+					'name'       => 'test_settings_fld[' . $field . ']',
2421
+					'label'      => $config['label'],
2422
+					'input'      => $config['input'],
2423
+					'type'       => $config['type'],
2424
+					'required'   => $config['required'],
2425
+					'validation' => $config['validation'],
2426
+					'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2427
+					'css_class'  => $config['css_class'],
2428
+					'options'    => isset($config['options']) ? $config['options'] : array(),
2429
+					'default'    => $default,
2430
+					'format'     => $config['format'],
2431
+				);
2432
+			}
2433
+		}
2434
+
2435
+		$test_settings_fields = ! empty($template_form_fields)
2436
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2437
+			: '';
2438
+
2439
+		$test_settings_html = '';
2440
+		// print out $test_settings_fields
2441
+		if (! empty($test_settings_fields)) {
2442
+			echo $test_settings_fields;
2443
+			$test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2444
+			$test_settings_html .= 'name="test_button" value="';
2445
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2446
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2447
+		}
2448
+
2449
+		// and button
2450
+		$test_settings_html .= '<p>'
2451
+							   . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2452
+							   . '</p>';
2453
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2454
+		$test_settings_html .= $this->get_action_link_or_button(
2455
+			'reset_to_default',
2456
+			'reset',
2457
+			$extra_args,
2458
+			'button-primary reset-default-button'
2459
+		);
2460
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2461
+		echo $test_settings_html;
2462
+	}
2463
+
2464
+
2465
+	/**
2466
+	 * This returns the shortcode selector skeleton for a given context and field.
2467
+	 *
2468
+	 * @since 4.9.rc.000
2469
+	 * @param string $field           The name of the field retrieving shortcodes for.
2470
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2471
+	 * @return string
2472
+	 * @throws DomainException
2473
+	 * @throws EE_Error
2474
+	 * @throws InvalidArgumentException
2475
+	 * @throws ReflectionException
2476
+	 * @throws InvalidDataTypeException
2477
+	 * @throws InvalidInterfaceException
2478
+	 */
2479
+	protected function _get_shortcode_selector($field, $linked_input_id)
2480
+	{
2481
+		$template_args = array(
2482
+			'shortcodes'      => $this->_get_shortcodes(array($field), true),
2483
+			'fieldname'       => $field,
2484
+			'linked_input_id' => $linked_input_id,
2485
+		);
2486
+
2487
+		return EEH_Template::display_template(
2488
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2489
+			$template_args,
2490
+			true
2491
+		);
2492
+	}
2493
+
2494
+
2495
+	/**
2496
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2497
+	 * page)
2498
+	 *
2499
+	 * @access public
2500
+	 * @return void
2501
+	 * @throws EE_Error
2502
+	 * @throws InvalidArgumentException
2503
+	 * @throws ReflectionException
2504
+	 * @throws InvalidDataTypeException
2505
+	 * @throws InvalidInterfaceException
2506
+	 */
2507
+	public function shortcode_meta_box()
2508
+	{
2509
+		$shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2510
+		// $messenger = $this->_message_template_group->messenger_obj();
2511
+		// now let's set the content depending on the status of the shortcodes array
2512
+		if (empty($shortcodes)) {
2513
+			$content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2514
+			echo $content;
2515
+		} else {
2516
+			// $alt = 0;
2517
+			?>
2518 2518
             <div style="float:right; margin-top:10px"><?php
2519
-                            echo $this->_get_help_tab_link('message_template_shortcodes');
2520
-            ?></div>
2519
+							echo $this->_get_help_tab_link('message_template_shortcodes');
2520
+			?></div>
2521 2521
             <p class="small-text"><?php
2522
-                                  printf(
2523
-                                      esc_html__(
2524
-                                          'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2525
-                                          'event_espresso'
2526
-                                      ),
2527
-                                      '<span class="dashicons dashicons-menu"></span>'
2528
-                                  );
2529
-                                    ?>
2522
+								  printf(
2523
+									  esc_html__(
2524
+										  'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2525
+										  'event_espresso'
2526
+									  ),
2527
+									  '<span class="dashicons dashicons-menu"></span>'
2528
+								  );
2529
+									?>
2530 2530
             </p>
2531 2531
             <?php
2532
-        }
2533
-    }
2534
-
2535
-
2536
-    /**
2537
-     * used to set the $_shortcodes property for when its needed elsewhere.
2538
-     *
2539
-     * @access protected
2540
-     * @return void
2541
-     * @throws EE_Error
2542
-     * @throws InvalidArgumentException
2543
-     * @throws ReflectionException
2544
-     * @throws InvalidDataTypeException
2545
-     * @throws InvalidInterfaceException
2546
-     */
2547
-    protected function _set_shortcodes()
2548
-    {
2549
-
2550
-        // no need to run this if the property is already set
2551
-        if (! empty($this->_shortcodes)) {
2552
-            return;
2553
-        }
2554
-
2555
-        $this->_shortcodes = $this->_get_shortcodes();
2556
-    }
2557
-
2558
-
2559
-    /**
2560
-     * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2561
-     * property)
2562
-     *
2563
-     * @access  protected
2564
-     * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2565
-     *                         for. Defaults to all (for the given context)
2566
-     * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2567
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2568
-     *                         true just an array of shortcode/label pairs.
2569
-     * @throws EE_Error
2570
-     * @throws InvalidArgumentException
2571
-     * @throws ReflectionException
2572
-     * @throws InvalidDataTypeException
2573
-     * @throws InvalidInterfaceException
2574
-     */
2575
-    protected function _get_shortcodes($fields = array(), $merged = true)
2576
-    {
2577
-        $this->_set_message_template_group();
2578
-
2579
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2580
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2581
-            ? absint($this->_req_data['id'])
2582
-            : false;
2583
-        $context = isset($this->_req_data['context'])
2584
-            ? $this->_req_data['context']
2585
-            : key($this->_message_template_group->contexts_config());
2586
-
2587
-        return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2588
-    }
2589
-
2590
-
2591
-    /**
2592
-     * This sets the _message_template property (containing the called message_template object)
2593
-     *
2594
-     * @access protected
2595
-     * @return void
2596
-     * @throws EE_Error
2597
-     * @throws InvalidArgumentException
2598
-     * @throws ReflectionException
2599
-     * @throws InvalidDataTypeException
2600
-     * @throws InvalidInterfaceException
2601
-     */
2602
-    protected function _set_message_template_group()
2603
-    {
2604
-
2605
-        if (! empty($this->_message_template_group)) {
2606
-            return;
2607
-        } //get out if this is already set.
2608
-
2609
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2610
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2611
-
2612
-        // let's get the message templates
2613
-        $MTP = EEM_Message_Template_Group::instance();
2614
-
2615
-        if (empty($GRP_ID)) {
2616
-            $this->_message_template_group = $MTP->create_default_object();
2617
-        } else {
2618
-            $this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2619
-        }
2620
-
2621
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2622
-        $this->_variation = $this->_message_template_group->get_template_pack_variation();
2623
-    }
2624
-
2625
-
2626
-    /**
2627
-     * sets up a context switcher for edit forms
2628
-     *
2629
-     * @access  protected
2630
-     * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2631
-     * @param array                      $args                  various things the context switcher needs.
2632
-     * @throws EE_Error
2633
-     */
2634
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2635
-    {
2636
-        $context_details = $template_group_object->contexts_config();
2637
-        $context_label = $template_group_object->context_label();
2638
-        ob_start();
2639
-        ?>
2532
+		}
2533
+	}
2534
+
2535
+
2536
+	/**
2537
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2538
+	 *
2539
+	 * @access protected
2540
+	 * @return void
2541
+	 * @throws EE_Error
2542
+	 * @throws InvalidArgumentException
2543
+	 * @throws ReflectionException
2544
+	 * @throws InvalidDataTypeException
2545
+	 * @throws InvalidInterfaceException
2546
+	 */
2547
+	protected function _set_shortcodes()
2548
+	{
2549
+
2550
+		// no need to run this if the property is already set
2551
+		if (! empty($this->_shortcodes)) {
2552
+			return;
2553
+		}
2554
+
2555
+		$this->_shortcodes = $this->_get_shortcodes();
2556
+	}
2557
+
2558
+
2559
+	/**
2560
+	 * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2561
+	 * property)
2562
+	 *
2563
+	 * @access  protected
2564
+	 * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2565
+	 *                         for. Defaults to all (for the given context)
2566
+	 * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2567
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2568
+	 *                         true just an array of shortcode/label pairs.
2569
+	 * @throws EE_Error
2570
+	 * @throws InvalidArgumentException
2571
+	 * @throws ReflectionException
2572
+	 * @throws InvalidDataTypeException
2573
+	 * @throws InvalidInterfaceException
2574
+	 */
2575
+	protected function _get_shortcodes($fields = array(), $merged = true)
2576
+	{
2577
+		$this->_set_message_template_group();
2578
+
2579
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2580
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2581
+			? absint($this->_req_data['id'])
2582
+			: false;
2583
+		$context = isset($this->_req_data['context'])
2584
+			? $this->_req_data['context']
2585
+			: key($this->_message_template_group->contexts_config());
2586
+
2587
+		return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2588
+	}
2589
+
2590
+
2591
+	/**
2592
+	 * This sets the _message_template property (containing the called message_template object)
2593
+	 *
2594
+	 * @access protected
2595
+	 * @return void
2596
+	 * @throws EE_Error
2597
+	 * @throws InvalidArgumentException
2598
+	 * @throws ReflectionException
2599
+	 * @throws InvalidDataTypeException
2600
+	 * @throws InvalidInterfaceException
2601
+	 */
2602
+	protected function _set_message_template_group()
2603
+	{
2604
+
2605
+		if (! empty($this->_message_template_group)) {
2606
+			return;
2607
+		} //get out if this is already set.
2608
+
2609
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2610
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2611
+
2612
+		// let's get the message templates
2613
+		$MTP = EEM_Message_Template_Group::instance();
2614
+
2615
+		if (empty($GRP_ID)) {
2616
+			$this->_message_template_group = $MTP->create_default_object();
2617
+		} else {
2618
+			$this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2619
+		}
2620
+
2621
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2622
+		$this->_variation = $this->_message_template_group->get_template_pack_variation();
2623
+	}
2624
+
2625
+
2626
+	/**
2627
+	 * sets up a context switcher for edit forms
2628
+	 *
2629
+	 * @access  protected
2630
+	 * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2631
+	 * @param array                      $args                  various things the context switcher needs.
2632
+	 * @throws EE_Error
2633
+	 */
2634
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2635
+	{
2636
+		$context_details = $template_group_object->contexts_config();
2637
+		$context_label = $template_group_object->context_label();
2638
+		ob_start();
2639
+		?>
2640 2640
         <div class="ee-msg-switcher-container">
2641 2641
             <form method="get" action="<?php echo EE_MSG_ADMIN_URL; ?>" id="ee-msg-context-switcher-frm">
2642 2642
                 <?php
2643
-                foreach ($args as $name => $value) {
2644
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2645
-                        continue;
2646
-                    }
2647
-                    ?>
2643
+				foreach ($args as $name => $value) {
2644
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2645
+						continue;
2646
+					}
2647
+					?>
2648 2648
                     <input type="hidden" name="<?php echo $name; ?>" value="<?php echo $value; ?>"/>
2649 2649
                     <?php
2650
-                }
2651
-                // setup nonce_url
2652
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2653
-                ?>
2650
+				}
2651
+				// setup nonce_url
2652
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2653
+				?>
2654 2654
                 <select name="context">
2655 2655
                     <?php
2656
-                    $context_templates = $template_group_object->context_templates();
2657
-                    if (is_array($context_templates)) :
2658
-                        foreach ($context_templates as $context => $template_fields) :
2659
-                            $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2660
-                            ?>
2656
+					$context_templates = $template_group_object->context_templates();
2657
+					if (is_array($context_templates)) :
2658
+						foreach ($context_templates as $context => $template_fields) :
2659
+							$checked = ($context === $args['context']) ? 'selected="selected"' : '';
2660
+							?>
2661 2661
                             <option value="<?php echo $context; ?>" <?php echo $checked; ?>>
2662 2662
                                 <?php echo $context_details[ $context ]['label']; ?>
2663 2663
                             </option>
2664 2664
                         <?php endforeach;
2665
-                    endif; ?>
2665
+					endif; ?>
2666 2666
                 </select>
2667 2667
                 <?php $button_text = sprintf(__('Switch %s', 'event_espresso'), ucwords($context_label['label'])); ?>
2668 2668
                 <input id="submit-msg-context-switcher-sbmt" class="button-secondary" type="submit"
@@ -2671,1930 +2671,1930 @@  discard block
 block discarded – undo
2671 2671
             <?php echo $args['extra']; ?>
2672 2672
         </div> <!-- end .ee-msg-switcher-container -->
2673 2673
         <?php
2674
-        $output = ob_get_contents();
2675
-        ob_clean();
2676
-        $this->_context_switcher = $output;
2677
-    }
2678
-
2679
-
2680
-    /**
2681
-     * utility for sanitizing new values coming in.
2682
-     * Note: this is only used when updating a context.
2683
-     *
2684
-     * @access protected
2685
-     *
2686
-     * @param int $index This helps us know which template field to select from the request array.
2687
-     *
2688
-     * @return array
2689
-     */
2690
-    protected function _set_message_template_column_values($index)
2691
-    {
2692
-        if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2693
-            foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2694
-                $this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2695
-            }
2696
-        }
2697
-
2698
-
2699
-        $set_column_values = array(
2700
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2701
-            'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2702
-            'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2703
-            'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2704
-            'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2705
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2706
-            'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2707
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2708
-            'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2709
-                ? absint($this->_req_data['MTP_is_global'])
2710
-                : 0,
2711
-            'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2712
-                ? absint($this->_req_data['MTP_is_override'])
2713
-                : 0,
2714
-            'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2715
-            'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2716
-        );
2717
-
2718
-
2719
-        return $set_column_values;
2720
-    }
2721
-
2722
-
2723
-    protected function _insert_or_update_message_template($new = false)
2724
-    {
2725
-        $success = 0;
2726
-        $override = false;
2727
-
2728
-        // setup notices description
2729
-        $messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2730
-
2731
-        // need the message type and messenger objects to be able to use the labels for the notices
2732
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2733
-        $messenger_label = $messenger_object instanceof EE_messenger
2734
-            ? ucwords($messenger_object->label['singular'])
2735
-            : '';
2736
-
2737
-        $message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2738
-            ? $this->_req_data['MTP_message_type']
2739
-            : '';
2740
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2741
-
2742
-        $message_type_label = $message_type_object instanceof EE_message_type
2743
-            ? ucwords($message_type_object->label['singular'])
2744
-            : '';
2745
-
2746
-        $context_slug = ! empty($this->_req_data['MTP_context'])
2747
-            ? $this->_req_data['MTP_context']
2748
-            : '';
2749
-        $context = ucwords(str_replace('_', ' ', $context_slug));
2750
-
2751
-        $item_desc = $messenger_label && $message_type_label
2752
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2753
-            : '';
2754
-        $item_desc .= 'Message Template';
2755
-        $query_args = array();
2756
-        $edit_array = array();
2757
-        $action_desc = '';
2758
-
2759
-        // if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2760
-        // user to edit.
2761
-        if ($new) {
2762
-            $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2763
-            if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2764
-                if (empty($edit_array)) {
2765
-                    $success = 0;
2766
-                } else {
2767
-                    $success = 1;
2768
-                    $edit_array = $edit_array[0];
2769
-                    $query_args = array(
2770
-                        'id'      => $edit_array['GRP_ID'],
2771
-                        'context' => $edit_array['MTP_context'],
2772
-                        'action'  => 'edit_message_template',
2773
-                    );
2774
-                }
2775
-            }
2776
-            $action_desc = 'created';
2777
-        } else {
2778
-            $MTPG = EEM_Message_Template_Group::instance();
2779
-            $MTP = EEM_Message_Template::instance();
2780
-
2781
-
2782
-            // run update for each template field in displayed context
2783
-            if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2784
-                EE_Error::add_error(
2785
-                    esc_html__(
2786
-                        'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2787
-                        'event_espresso'
2788
-                    ),
2789
-                    __FILE__,
2790
-                    __FUNCTION__,
2791
-                    __LINE__
2792
-                );
2793
-                $success = 0;
2794
-            } else {
2795
-                // first validate all fields!
2796
-                // this filter allows client code to add its own validation to the template fields as well.
2797
-                // returning an empty array means everything passed validation.
2798
-                // errors in validation should be represented in an array with the following shape:
2799
-                // array(
2800
-                //   'fieldname' => array(
2801
-                //          'msg' => 'error message'
2802
-                //          'value' => 'value for field producing error'
2803
-                // )
2804
-                $custom_validation = (array) apply_filters(
2805
-                    'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2806
-                    array(),
2807
-                    $this->_req_data['MTP_template_fields'],
2808
-                    $context_slug,
2809
-                    $messenger_slug,
2810
-                    $message_type_slug
2811
-                );
2812
-
2813
-                $system_validation = $MTPG->validate(
2814
-                    $this->_req_data['MTP_template_fields'],
2815
-                    $context_slug,
2816
-                    $messenger_slug,
2817
-                    $message_type_slug
2818
-                );
2819
-
2820
-                $system_validation = ! is_array($system_validation) && $system_validation ? array()
2821
-                    : $system_validation;
2822
-                $validates = array_merge($custom_validation, $system_validation);
2823
-
2824
-                // if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2825
-                // appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2826
-                //  WE need to make sure there is no actual error messages in validates.
2827
-                if (is_array($validates) && ! empty($validates)) {
2828
-                    // add the transient so when the form loads we know which fields to highlight
2829
-                    $this->_add_transient('edit_message_template', $validates);
2830
-
2831
-                    $success = 0;
2832
-
2833
-                    // setup notices
2834
-                    foreach ($validates as $field => $error) {
2835
-                        if (isset($error['msg'])) {
2836
-                            EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2837
-                        }
2838
-                    }
2839
-                } else {
2840
-                    $set_column_values = array();
2841
-                    foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2842
-                        $set_column_values = $this->_set_message_template_column_values($template_field);
2843
-
2844
-                        $where_cols_n_values = array(
2845
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2846
-                        );
2847
-                        // if they aren't allowed to use all JS, restrict them to just posty-y tags
2848
-                        if (! current_user_can('unfiltered_html')) {
2849
-                            if (is_array($set_column_values['MTP_content'])) {
2850
-                                foreach ($set_column_values['MTP_content'] as $key => $value) {
2851
-                                    // remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2852
-                                    // only removes slashes from double-quotes, so attributes using single quotes always
2853
-                                    // appear invalid.) But currently the models expect slashed data, so after wp_kses
2854
-                                    // runs we need to re-slash the data. Sheesh. See
2855
-                                    // https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2856
-                                    $set_column_values['MTP_content'][ $key ] = addslashes(
2857
-                                        wp_kses(
2858
-                                            stripslashes($value),
2859
-                                            wp_kses_allowed_html('post')
2860
-                                        )
2861
-                                    );
2862
-                                }
2863
-                            } else {
2864
-                                $set_column_values['MTP_content'] = wp_kses(
2865
-                                    $set_column_values['MTP_content'],
2866
-                                    wp_kses_allowed_html('post')
2867
-                                );
2868
-                            }
2869
-                        }
2870
-                        $message_template_fields = array(
2871
-                            'GRP_ID'             => $set_column_values['GRP_ID'],
2872
-                            'MTP_template_field' => $set_column_values['MTP_template_field'],
2873
-                            'MTP_context'        => $set_column_values['MTP_context'],
2874
-                            'MTP_content'        => $set_column_values['MTP_content'],
2875
-                        );
2876
-                        if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2877
-                            if ($updated === false) {
2878
-                                EE_Error::add_error(
2879
-                                    sprintf(
2880
-                                        esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2881
-                                        $template_field
2882
-                                    ),
2883
-                                    __FILE__,
2884
-                                    __FUNCTION__,
2885
-                                    __LINE__
2886
-                                );
2887
-                            } else {
2888
-                                $success = 1;
2889
-                            }
2890
-                        } else {
2891
-                            // only do this logic if we don't have a MTP_ID for this field
2892
-                            if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2893
-                                // this has already been through the template field validator and sanitized, so it will be
2894
-                                // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2895
-                                // message template field in a messenger/message type and existing users don't have the
2896
-                                // default setup for it.
2897
-                                // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2898
-                                $updated = $MTP->insert($message_template_fields);
2899
-                                if (! $updated || is_wp_error($updated)) {
2900
-                                    EE_Error::add_error(
2901
-                                        sprintf(
2902
-                                            esc_html__('%s field could not be updated.', 'event_espresso'),
2903
-                                            $template_field
2904
-                                        ),
2905
-                                        __FILE__,
2906
-                                        __FUNCTION__,
2907
-                                        __LINE__
2908
-                                    );
2909
-                                    $success = 0;
2910
-                                } else {
2911
-                                    $success = 1;
2912
-                                }
2913
-                            }
2914
-                        }
2915
-                        $action_desc = 'updated';
2916
-                    }
2917
-
2918
-                    // we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2919
-                    $mtpg_fields = array(
2920
-                        'MTP_user_id'      => $set_column_values['MTP_user_id'],
2921
-                        'MTP_messenger'    => $set_column_values['MTP_messenger'],
2922
-                        'MTP_message_type' => $set_column_values['MTP_message_type'],
2923
-                        'MTP_is_global'    => $set_column_values['MTP_is_global'],
2924
-                        'MTP_is_override'  => $set_column_values['MTP_is_override'],
2925
-                        'MTP_deleted'      => $set_column_values['MTP_deleted'],
2926
-                        'MTP_is_active'    => $set_column_values['MTP_is_active'],
2927
-                        'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2928
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2929
-                            : '',
2930
-                        'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2931
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2932
-                            : '',
2933
-                    );
2934
-
2935
-                    $mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2936
-                    $updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2937
-
2938
-                    if ($updated === false) {
2939
-                        EE_Error::add_error(
2940
-                            sprintf(
2941
-                                esc_html__(
2942
-                                    'The Message Template Group (%d) was NOT updated for some reason',
2943
-                                    'event_espresso'
2944
-                                ),
2945
-                                $set_column_values['GRP_ID']
2946
-                            ),
2947
-                            __FILE__,
2948
-                            __FUNCTION__,
2949
-                            __LINE__
2950
-                        );
2951
-                    } else {
2952
-                        // k now we need to ensure the template_pack and template_variation fields are set.
2953
-                        $template_pack = ! empty($this->_req_data['MTP_template_pack'])
2954
-                            ? $this->_req_data['MTP_template_pack']
2955
-                            : 'default';
2956
-
2957
-                        $template_variation = ! empty($this->_req_data['MTP_template_variation'])
2958
-                            ? $this->_req_data['MTP_template_variation']
2959
-                            : 'default';
2960
-
2961
-                        $mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2962
-                        if ($mtpg_obj instanceof EE_Message_Template_Group) {
2963
-                            $mtpg_obj->set_template_pack_name($template_pack);
2964
-                            $mtpg_obj->set_template_pack_variation($template_variation);
2965
-                        }
2966
-                        $success = 1;
2967
-                    }
2968
-                }
2969
-            }
2970
-        }
2971
-
2972
-        // we return things differently if doing ajax
2973
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2974
-            $this->_template_args['success'] = $success;
2975
-            $this->_template_args['error'] = ! $success ? true : false;
2976
-            $this->_template_args['content'] = '';
2977
-            $this->_template_args['data'] = array(
2978
-                'grpID'        => $edit_array['GRP_ID'],
2979
-                'templateName' => $edit_array['template_name'],
2980
-            );
2981
-            if ($success) {
2982
-                EE_Error::overwrite_success();
2983
-                EE_Error::add_success(
2984
-                    esc_html__(
2985
-                        'The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2986
-                        'event_espresso'
2987
-                    )
2988
-                );
2989
-            }
2990
-
2991
-            $this->_return_json();
2992
-        }
2993
-
2994
-
2995
-        // was a test send triggered?
2996
-        if (isset($this->_req_data['test_button'])) {
2997
-            EE_Error::overwrite_success();
2998
-            $this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2999
-            $override = true;
3000
-        }
3001
-
3002
-        if (empty($query_args)) {
3003
-            $query_args = array(
3004
-                'id'      => $this->_req_data['GRP_ID'],
3005
-                'context' => $context_slug,
3006
-                'action'  => 'edit_message_template',
3007
-            );
3008
-        }
3009
-
3010
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3011
-    }
3012
-
3013
-
3014
-    /**
3015
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
3016
-     *
3017
-     * @param  string $context      what context being tested
3018
-     * @param  string $messenger    messenger being tested
3019
-     * @param  string $message_type message type being tested
3020
-     * @throws EE_Error
3021
-     * @throws InvalidArgumentException
3022
-     * @throws InvalidDataTypeException
3023
-     * @throws InvalidInterfaceException
3024
-     */
3025
-    protected function _do_test_send($context, $messenger, $message_type)
3026
-    {
3027
-        // set things up for preview
3028
-        $this->_req_data['messenger'] = $messenger;
3029
-        $this->_req_data['message_type'] = $message_type;
3030
-        $this->_req_data['context'] = $context;
3031
-        $this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3032
-        $active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3033
-
3034
-        // let's save any existing fields that might be required by the messenger
3035
-        if (
3036
-            isset($this->_req_data['test_settings_fld'])
3037
-            && $active_messenger instanceof EE_messenger
3038
-            && apply_filters(
3039
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3040
-                true,
3041
-                $this->_req_data['test_settings_fld'],
3042
-                $active_messenger
3043
-            )
3044
-        ) {
3045
-            $active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3046
-        }
3047
-
3048
-        /**
3049
-         * Use filter to add additional controls on whether message can send or not
3050
-         */
3051
-        if (
3052
-            apply_filters(
3053
-                'FHEE__Messages_Admin_Page__do_test_send__can_send',
3054
-                true,
3055
-                $context,
3056
-                $this->_req_data,
3057
-                $messenger,
3058
-                $message_type
3059
-            )
3060
-        ) {
3061
-            if (EEM_Event::instance()->count() > 0) {
3062
-                $success = $this->_preview_message(true);
3063
-                if ($success) {
3064
-                    EE_Error::add_success(__('Test message sent', 'event_espresso'));
3065
-                } else {
3066
-                    EE_Error::add_error(
3067
-                        esc_html__('The test message was not sent', 'event_espresso'),
3068
-                        __FILE__,
3069
-                        __FUNCTION__,
3070
-                        __LINE__
3071
-                    );
3072
-                }
3073
-            } else {
3074
-                $this->noEventsErrorMessage(true);
3075
-            }
3076
-        }
3077
-    }
3078
-
3079
-
3080
-    /**
3081
-     * _generate_new_templates
3082
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3083
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3084
-     * for the event.
3085
-     *
3086
-     *
3087
-     * @param  string $messenger     the messenger we are generating templates for
3088
-     * @param array   $message_types array of message types that the templates are generated for.
3089
-     * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3090
-     *                               indicate the message_template_group being used as the base.
3091
-     *
3092
-     * @param bool    $global
3093
-     *
3094
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
3095
-     *                               encountering problems.
3096
-     * @throws EE_Error
3097
-     */
3098
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3099
-    {
3100
-
3101
-        // if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3102
-        // just don't generate any templates.
3103
-        if (empty($message_types)) {
3104
-            return true;
3105
-        }
3106
-
3107
-        return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3108
-    }
3109
-
3110
-
3111
-    /**
3112
-     * [_trash_or_restore_message_template]
3113
-     *
3114
-     * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3115
-     * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3116
-     *                        an individual context (FALSE).
3117
-     * @return void
3118
-     * @throws EE_Error
3119
-     * @throws InvalidArgumentException
3120
-     * @throws InvalidDataTypeException
3121
-     * @throws InvalidInterfaceException
3122
-     */
3123
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
3124
-    {
3125
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3126
-        $MTP = EEM_Message_Template_Group::instance();
3127
-
3128
-        $success = 1;
3129
-
3130
-        // incoming GRP_IDs
3131
-        if ($all) {
3132
-            // Checkboxes
3133
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3134
-                // if array has more than one element then success message should be plural.
3135
-                // todo: what about nonce?
3136
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3137
-
3138
-                // cycle through checkboxes
3139
-                while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3140
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3141
-                    if (! $trashed_or_restored) {
3142
-                        $success = 0;
3143
-                    }
3144
-                }
3145
-            } else {
3146
-                // grab single GRP_ID and handle
3147
-                $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3148
-                if (! empty($GRP_ID)) {
3149
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3150
-                    if (! $trashed_or_restored) {
3151
-                        $success = 0;
3152
-                    }
3153
-                } else {
3154
-                    $success = 0;
3155
-                }
3156
-            }
3157
-        }
3158
-
3159
-        $action_desc = $trash
3160
-            ? esc_html__('moved to the trash', 'event_espresso')
3161
-            : esc_html__('restored', 'event_espresso');
3162
-
3163
-        $action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3164
-
3165
-        $item_desc = $all ? _n(
3166
-            'Message Template Group',
3167
-            'Message Template Groups',
3168
-            $success,
3169
-            'event_espresso'
3170
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3171
-
3172
-        $item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3173
-            'template',
3174
-            'templates',
3175
-            $success,
3176
-            'event_espresso'
3177
-        ) : $item_desc;
3178
-
3179
-        $this->_redirect_after_action($success, $item_desc, $action_desc, array());
3180
-    }
3181
-
3182
-
3183
-    /**
3184
-     * [_delete_message_template]
3185
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3186
-     *
3187
-     * @return void
3188
-     * @throws EE_Error
3189
-     * @throws InvalidArgumentException
3190
-     * @throws InvalidDataTypeException
3191
-     * @throws InvalidInterfaceException
3192
-     */
3193
-    protected function _delete_message_template()
3194
-    {
3195
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3196
-
3197
-        // checkboxes
3198
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3199
-            // if array has more than one element then success message should be plural
3200
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3201
-
3202
-            // cycle through bulk action checkboxes
3203
-            while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3204
-                $success = $this->_delete_mtp_permanently($GRP_ID);
3205
-            }
3206
-        } else {
3207
-            // grab single grp_id and delete
3208
-            $GRP_ID = absint($this->_req_data['id']);
3209
-            $success = $this->_delete_mtp_permanently($GRP_ID);
3210
-        }
3211
-
3212
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3213
-    }
3214
-
3215
-
3216
-    /**
3217
-     * helper for permanently deleting a mtP group and all related message_templates
3218
-     *
3219
-     * @param  int  $GRP_ID        The group being deleted
3220
-     * @param  bool $include_group whether to delete the Message Template Group as well.
3221
-     * @return bool boolean to indicate the success of the deletes or not.
3222
-     * @throws EE_Error
3223
-     * @throws InvalidArgumentException
3224
-     * @throws InvalidDataTypeException
3225
-     * @throws InvalidInterfaceException
3226
-     */
3227
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3228
-    {
3229
-        $success = 1;
3230
-        $MTPG = EEM_Message_Template_Group::instance();
3231
-        // first let's GET this group
3232
-        $MTG = $MTPG->get_one_by_ID($GRP_ID);
3233
-        // then delete permanently all the related Message Templates
3234
-        $deleted = $MTG->delete_related_permanently('Message_Template');
3235
-
3236
-        if ($deleted === 0) {
3237
-            $success = 0;
3238
-        }
3239
-
3240
-        // now delete permanently this particular group
3241
-
3242
-        if ($include_group && ! $MTG->delete_permanently()) {
3243
-            $success = 0;
3244
-        }
3245
-
3246
-        return $success;
3247
-    }
3248
-
3249
-
3250
-    /**
3251
-     *    _learn_more_about_message_templates_link
3252
-     *
3253
-     * @access protected
3254
-     * @return string
3255
-     */
3256
-    protected function _learn_more_about_message_templates_link()
3257
-    {
3258
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3259
-               . esc_html__('learn more about how message templates works', 'event_espresso')
3260
-               . '</a>';
3261
-    }
3262
-
3263
-
3264
-    /**
3265
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3266
-     * ajax and other routes.
3267
-     *
3268
-     * @return void
3269
-     * @throws DomainException
3270
-     */
3271
-    protected function _settings()
3272
-    {
3273
-
3274
-
3275
-        $this->_set_m_mt_settings();
3276
-
3277
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3278
-            ? $this->_req_data['selected_messenger']
3279
-            : 'email';
3280
-
3281
-        // let's setup the messenger tabs
3282
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3283
-            $this->_m_mt_settings['messenger_tabs'],
3284
-            'messenger_links',
3285
-            '|',
3286
-            $selected_messenger
3287
-        );
3288
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3289
-        $this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3290
-
3291
-        $this->display_admin_page_with_sidebar();
3292
-    }
3293
-
3294
-
3295
-    /**
3296
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3297
-     *
3298
-     * @access protected
3299
-     * @return void
3300
-     * @throws DomainException
3301
-     */
3302
-    protected function _set_m_mt_settings()
3303
-    {
3304
-        // first if this is already set then lets get out no need to regenerate data.
3305
-        if (! empty($this->_m_mt_settings)) {
3306
-            return;
3307
-        }
3308
-
3309
-        // get all installed messengers and message_types
3310
-        /** @type EE_messenger[] $messengers */
3311
-        $messengers = $this->_message_resource_manager->installed_messengers();
3312
-        /** @type EE_message_type[] $message_types */
3313
-        $message_types = $this->_message_resource_manager->installed_message_types();
3314
-
3315
-
3316
-        // assemble the array for the _tab_text_links helper
3317
-
3318
-        foreach ($messengers as $messenger) {
3319
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3320
-                'label' => ucwords($messenger->label['singular']),
3321
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3322
-                    ? 'messenger-active'
3323
-                    : '',
3324
-                'href'  => $messenger->name,
3325
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3326
-                'slug'  => $messenger->name,
3327
-                'obj'   => $messenger,
3328
-            );
3329
-
3330
-
3331
-            $message_types_for_messenger = $messenger->get_valid_message_types();
3332
-
3333
-            foreach ($message_types as $message_type) {
3334
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3335
-                // it shouldn't show in either the inactive OR active metabox.
3336
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3337
-                    continue;
3338
-                }
3339
-
3340
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3341
-                    $messenger->name,
3342
-                    $message_type->name
3343
-                )
3344
-                    ? 'active'
3345
-                    : 'inactive';
3346
-
3347
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3348
-                    'label'    => ucwords($message_type->label['singular']),
3349
-                    'class'    => 'message-type-' . $a_or_i,
3350
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3351
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3352
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3353
-                    'title'    => $a_or_i === 'active'
3354
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3355
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3356
-                    'content'  => $a_or_i === 'active'
3357
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
3358
-                        : $this->_message_type_settings_content($message_type, $messenger),
3359
-                    'slug'     => $message_type->name,
3360
-                    'active'   => $a_or_i === 'active',
3361
-                    'obj'      => $message_type,
3362
-                );
3363
-            }
3364
-        }
3365
-    }
3366
-
3367
-
3368
-    /**
3369
-     * This just prepares the content for the message type settings
3370
-     *
3371
-     * @param  EE_message_type $message_type The message type object
3372
-     * @param  EE_messenger    $messenger    The messenger object
3373
-     * @param  boolean         $active       Whether the message type is active or not
3374
-     * @return string html output for the content
3375
-     * @throws DomainException
3376
-     */
3377
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
3378
-    {
3379
-        // get message type fields
3380
-        $fields = $message_type->get_admin_settings_fields();
3381
-        $settings_template_args['template_form_fields'] = '';
3382
-
3383
-        if (! empty($fields) && $active) {
3384
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3385
-            foreach ($fields as $fldname => $fldprops) {
3386
-                $field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3387
-                $template_form_field[ $field_id ] = array(
3388
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3389
-                    'label'      => $fldprops['label'],
3390
-                    'input'      => $fldprops['field_type'],
3391
-                    'type'       => $fldprops['value_type'],
3392
-                    'required'   => $fldprops['required'],
3393
-                    'validation' => $fldprops['validation'],
3394
-                    'value'      => isset($existing_settings[ $fldname ])
3395
-                        ? $existing_settings[ $fldname ]
3396
-                        : $fldprops['default'],
3397
-                    'options'    => isset($fldprops['options'])
3398
-                        ? $fldprops['options']
3399
-                        : array(),
3400
-                    'default'    => isset($existing_settings[ $fldname ])
3401
-                        ? $existing_settings[ $fldname ]
3402
-                        : $fldprops['default'],
3403
-                    'css_class'  => 'no-drag',
3404
-                    'format'     => $fldprops['format'],
3405
-                );
3406
-            }
3407
-
3408
-
3409
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3410
-                ? $this->_generate_admin_form_fields(
3411
-                    $template_form_field,
3412
-                    'string',
3413
-                    'ee_mt_activate_form'
3414
-                )
3415
-                : '';
3416
-        }
3417
-
3418
-        $settings_template_args['description'] = $message_type->description;
3419
-        // we also need some hidden fields
3420
-        $settings_template_args['hidden_fields'] = array(
3421
-            'message_type_settings[messenger]'    => array(
3422
-                'type'  => 'hidden',
3423
-                'value' => $messenger->name,
3424
-            ),
3425
-            'message_type_settings[message_type]' => array(
3426
-                'type'  => 'hidden',
3427
-                'value' => $message_type->name,
3428
-            ),
3429
-            'type'                                => array(
3430
-                'type'  => 'hidden',
3431
-                'value' => 'message_type',
3432
-            ),
3433
-        );
3434
-
3435
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3436
-            $settings_template_args['hidden_fields'],
3437
-            'array'
3438
-        );
3439
-        $settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3440
-            ? ' hidden'
3441
-            : '';
3442
-
3443
-
3444
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3445
-        $content = EEH_Template::display_template($template, $settings_template_args, true);
3446
-
3447
-        return $content;
3448
-    }
3449
-
3450
-
3451
-    /**
3452
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3453
-     *
3454
-     * @access protected
3455
-     * @return void
3456
-     * @throws DomainException
3457
-     */
3458
-    protected function _messages_settings_metaboxes()
3459
-    {
3460
-        $this->_set_m_mt_settings();
3461
-        $m_boxes = $mt_boxes = array();
3462
-        $m_template_args = $mt_template_args = array();
3463
-
3464
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3465
-            ? $this->_req_data['selected_messenger']
3466
-            : 'email';
3467
-
3468
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3469
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3470
-                $hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3471
-                $hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3472
-                // messenger meta boxes
3473
-                $active = $selected_messenger === $messenger;
3474
-                $active_mt_tabs = isset(
3475
-                    $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3476
-                )
3477
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3478
-                    : '';
3479
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3480
-                    esc_html__('%s Settings', 'event_espresso'),
3481
-                    $tab_array['label']
3482
-                );
3483
-                $m_template_args[ $messenger . '_a_box' ] = array(
3484
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3485
-                    'inactive_message_types' => isset(
3486
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3487
-                    )
3488
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3489
-                        : '',
3490
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3491
-                    'hidden'                 => $active ? '' : ' hidden',
3492
-                    'hide_on_message'        => $hide_on_message,
3493
-                    'messenger'              => $messenger,
3494
-                    'active'                 => $active,
3495
-                );
3496
-                // message type meta boxes
3497
-                // (which is really just the inactive container for each messenger
3498
-                // showing inactive message types for that messenger)
3499
-                $mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3500
-                $mt_template_args[ $messenger . '_i_box' ] = array(
3501
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3502
-                    'inactive_message_types' => isset(
3503
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3504
-                    )
3505
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3506
-                        : '',
3507
-                    'hidden'                 => $active ? '' : ' hidden',
3508
-                    'hide_on_message'        => $hide_on_message,
3509
-                    'hide_off_message'       => $hide_off_message,
3510
-                    'messenger'              => $messenger,
3511
-                    'active'                 => $active,
3512
-                );
3513
-            }
3514
-        }
3515
-
3516
-
3517
-        // register messenger metaboxes
3518
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3519
-        foreach ($m_boxes as $box => $label) {
3520
-            $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3521
-            $msgr = str_replace('_a_box', '', $box);
3522
-            add_meta_box(
3523
-                'espresso_' . $msgr . '_settings',
3524
-                $label,
3525
-                function ($post, $metabox) {
3526
-                    echo EEH_Template::display_template(
3527
-                        $metabox["args"]["template_path"],
3528
-                        $metabox["args"]["template_args"],
3529
-                        true
3530
-                    );
3531
-                },
3532
-                $this->_current_screen->id,
3533
-                'normal',
3534
-                'high',
3535
-                $callback_args
3536
-            );
3537
-        }
3538
-
3539
-        // register message type metaboxes
3540
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3541
-        foreach ($mt_boxes as $box => $label) {
3542
-            $callback_args = array(
3543
-                'template_path' => $mt_template_path,
3544
-                'template_args' => $mt_template_args[ $box ],
3545
-            );
3546
-            $mt = str_replace('_i_box', '', $box);
3547
-            add_meta_box(
3548
-                'espresso_' . $mt . '_inactive_mts',
3549
-                $label,
3550
-                function ($post, $metabox) {
3551
-                    echo EEH_Template::display_template(
3552
-                        $metabox["args"]["template_path"],
3553
-                        $metabox["args"]["template_args"],
3554
-                        true
3555
-                    );
3556
-                },
3557
-                $this->_current_screen->id,
3558
-                'side',
3559
-                'high',
3560
-                $callback_args
3561
-            );
3562
-        }
3563
-
3564
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3565
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3566
-        if (is_main_site()) {
3567
-            add_meta_box(
3568
-                'espresso_global_message_settings',
3569
-                esc_html__('Global Message Settings', 'event_espresso'),
3570
-                array($this, 'global_messages_settings_metabox_content'),
3571
-                $this->_current_screen->id,
3572
-                'normal',
3573
-                'low',
3574
-                array()
3575
-            );
3576
-        }
3577
-    }
3578
-
3579
-
3580
-    /**
3581
-     *  This generates the content for the global messages settings metabox.
3582
-     *
3583
-     * @return string
3584
-     * @throws EE_Error
3585
-     * @throws InvalidArgumentException
3586
-     * @throws ReflectionException
3587
-     * @throws InvalidDataTypeException
3588
-     * @throws InvalidInterfaceException
3589
-     */
3590
-    public function global_messages_settings_metabox_content()
3591
-    {
3592
-        $form = $this->_generate_global_settings_form();
3593
-        echo $form->form_open(
3594
-            $this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3595
-            'POST'
3596
-        )
3597
-             . $form->get_html()
3598
-             . $form->form_close();
3599
-    }
3600
-
3601
-
3602
-    /**
3603
-     * This generates and returns the form object for the global messages settings.
3604
-     *
3605
-     * @return EE_Form_Section_Proper
3606
-     * @throws EE_Error
3607
-     * @throws InvalidArgumentException
3608
-     * @throws ReflectionException
3609
-     * @throws InvalidDataTypeException
3610
-     * @throws InvalidInterfaceException
3611
-     */
3612
-    protected function _generate_global_settings_form()
3613
-    {
3614
-        EE_Registry::instance()->load_helper('HTML');
3615
-        /** @var EE_Network_Core_Config $network_config */
3616
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3617
-
3618
-        return new EE_Form_Section_Proper(
3619
-            array(
3620
-                'name'            => 'global_messages_settings',
3621
-                'html_id'         => 'global_messages_settings',
3622
-                'html_class'      => 'form-table',
3623
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3624
-                'subsections'     => apply_filters(
3625
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3626
-                    array(
3627
-                        'do_messages_on_same_request' => new EE_Select_Input(
3628
-                            array(
3629
-                                true  => esc_html__("On the same request", "event_espresso"),
3630
-                                false => esc_html__("On a separate request", "event_espresso"),
3631
-                            ),
3632
-                            array(
3633
-                                'default'         => $network_config->do_messages_on_same_request,
3634
-                                'html_label_text' => esc_html__(
3635
-                                    'Generate and send all messages:',
3636
-                                    'event_espresso'
3637
-                                ),
3638
-                                'html_help_text'  => esc_html__(
3639
-                                    'By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3640
-                                    'event_espresso'
3641
-                                ),
3642
-                            )
3643
-                        ),
3644
-                        'delete_threshold'            => new EE_Select_Input(
3645
-                            array(
3646
-                                0  => esc_html__('Forever', 'event_espresso'),
3647
-                                3  => esc_html__('3 Months', 'event_espresso'),
3648
-                                6  => esc_html__('6 Months', 'event_espresso'),
3649
-                                9  => esc_html__('9 Months', 'event_espresso'),
3650
-                                12 => esc_html__('12 Months', 'event_espresso'),
3651
-                                24 => esc_html__('24 Months', 'event_espresso'),
3652
-                                36 => esc_html__('36 Months', 'event_espresso'),
3653
-                            ),
3654
-                            array(
3655
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3656
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3657
-                                'html_help_text'  => esc_html__(
3658
-                                    'You can control how long a record of processed messages is kept via this option.',
3659
-                                    'event_espresso'
3660
-                                ),
3661
-                            )
3662
-                        ),
3663
-                        'update_settings'             => new EE_Submit_Input(
3664
-                            array(
3665
-                                'default'         => esc_html__('Update', 'event_espresso'),
3666
-                                'html_label_text' => '&nbsp',
3667
-                            )
3668
-                        ),
3669
-                    )
3670
-                ),
3671
-            )
3672
-        );
3673
-    }
3674
-
3675
-
3676
-    /**
3677
-     * This handles updating the global settings set on the admin page.
3678
-     *
3679
-     * @throws EE_Error
3680
-     * @throws InvalidDataTypeException
3681
-     * @throws InvalidInterfaceException
3682
-     * @throws InvalidArgumentException
3683
-     * @throws ReflectionException
3684
-     */
3685
-    protected function _update_global_settings()
3686
-    {
3687
-        /** @var EE_Network_Core_Config $network_config */
3688
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3689
-        $messages_config = EE_Registry::instance()->CFG->messages;
3690
-        $form = $this->_generate_global_settings_form();
3691
-        if ($form->was_submitted()) {
3692
-            $form->receive_form_submission();
3693
-            if ($form->is_valid()) {
3694
-                $valid_data = $form->valid_data();
3695
-                foreach ($valid_data as $property => $value) {
3696
-                    $setter = 'set_' . $property;
3697
-                    if (method_exists($network_config, $setter)) {
3698
-                        $network_config->{$setter}($value);
3699
-                    } elseif (
3700
-                        property_exists($network_config, $property)
3701
-                        && $network_config->{$property} !== $value
3702
-                    ) {
3703
-                        $network_config->{$property} = $value;
3704
-                    } elseif (
3705
-                        property_exists($messages_config, $property)
3706
-                        && $messages_config->{$property} !== $value
3707
-                    ) {
3708
-                        $messages_config->{$property} = $value;
3709
-                    }
3710
-                }
3711
-                // only update if the form submission was valid!
3712
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3713
-                EE_Registry::instance()->CFG->update_espresso_config();
3714
-                EE_Error::overwrite_success();
3715
-                EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3716
-            }
3717
-        }
3718
-        $this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3719
-    }
3720
-
3721
-
3722
-    /**
3723
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3724
-     *
3725
-     * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3726
-     * @return string html formatted tabs
3727
-     * @throws DomainException
3728
-     */
3729
-    protected function _get_mt_tabs($tab_array)
3730
-    {
3731
-        $tab_array = (array) $tab_array;
3732
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3733
-        $tabs = '';
3734
-
3735
-        foreach ($tab_array as $tab) {
3736
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3737
-        }
3738
-
3739
-        return $tabs;
3740
-    }
3741
-
3742
-
3743
-    /**
3744
-     * This prepares the content of the messenger meta box admin settings
3745
-     *
3746
-     * @param  EE_messenger $messenger The messenger we're setting up content for
3747
-     * @return string html formatted content
3748
-     * @throws DomainException
3749
-     */
3750
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3751
-    {
3752
-
3753
-        $fields = $messenger->get_admin_settings_fields();
3754
-        $settings_template_args['template_form_fields'] = '';
3755
-
3756
-        // is $messenger active?
3757
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3758
-
3759
-
3760
-        if (! empty($fields)) {
3761
-            $existing_settings = $messenger->get_existing_admin_settings();
3762
-
3763
-            foreach ($fields as $fldname => $fldprops) {
3764
-                $field_id = $messenger->name . '-' . $fldname;
3765
-                $template_form_field[ $field_id ] = array(
3766
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3767
-                    'label'      => $fldprops['label'],
3768
-                    'input'      => $fldprops['field_type'],
3769
-                    'type'       => $fldprops['value_type'],
3770
-                    'required'   => $fldprops['required'],
3771
-                    'validation' => $fldprops['validation'],
3772
-                    'value'      => isset($existing_settings[ $field_id ])
3773
-                        ? $existing_settings[ $field_id ]
3774
-                        : $fldprops['default'],
3775
-                    'css_class'  => '',
3776
-                    'format'     => $fldprops['format'],
3777
-                );
3778
-            }
3779
-
3780
-
3781
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3782
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3783
-                : '';
3784
-        }
3785
-
3786
-        // we also need some hidden fields
3787
-        $settings_template_args['hidden_fields'] = array(
3788
-            'messenger_settings[messenger]' => array(
3789
-                'type'  => 'hidden',
3790
-                'value' => $messenger->name,
3791
-            ),
3792
-            'type'                          => array(
3793
-                'type'  => 'hidden',
3794
-                'value' => 'messenger',
3795
-            ),
3796
-        );
3797
-
3798
-        // make sure any active message types that are existing are included in the hidden fields
3799
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3800
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3801
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3802
-                    'type'  => 'hidden',
3803
-                    'value' => $mt,
3804
-                );
3805
-            }
3806
-        }
3807
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3808
-            $settings_template_args['hidden_fields'],
3809
-            'array'
3810
-        );
3811
-        $active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3812
-
3813
-        $settings_template_args['messenger'] = $messenger->name;
3814
-        $settings_template_args['description'] = $messenger->description;
3815
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3816
-
3817
-
3818
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3819
-            $messenger->name
3820
-        )
3821
-            ? $settings_template_args['show_hide_edit_form']
3822
-            : ' hidden';
3823
-
3824
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3825
-            ? ' hidden'
3826
-            : $settings_template_args['show_hide_edit_form'];
3827
-
3828
-
3829
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3830
-        $settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3831
-        $settings_template_args['on_off_status'] = $active ? true : false;
3832
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3833
-        $content = EEH_Template::display_template(
3834
-            $template,
3835
-            $settings_template_args,
3836
-            true
3837
-        );
3838
-
3839
-        return $content;
3840
-    }
3841
-
3842
-
3843
-    /**
3844
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3845
-     *
3846
-     * @throws DomainException
3847
-     * @throws EE_Error
3848
-     * @throws InvalidDataTypeException
3849
-     * @throws InvalidInterfaceException
3850
-     * @throws InvalidArgumentException
3851
-     * @throws ReflectionException
3852
-     */
3853
-    public function activate_messenger_toggle()
3854
-    {
3855
-        $success = true;
3856
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3857
-        // let's check that we have required data
3858
-        if (! isset($this->_req_data['messenger'])) {
3859
-            EE_Error::add_error(
3860
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3861
-                __FILE__,
3862
-                __FUNCTION__,
3863
-                __LINE__
3864
-            );
3865
-            $success = false;
3866
-        }
3867
-
3868
-        // do a nonce check here since we're not arriving via a normal route
3869
-        $nonce = isset($this->_req_data['activate_nonce'])
3870
-            ? sanitize_text_field($this->_req_data['activate_nonce'])
3871
-            : '';
3872
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3873
-
3874
-        $this->_verify_nonce($nonce, $nonce_ref);
3875
-
3876
-
3877
-        if (! isset($this->_req_data['status'])) {
3878
-            EE_Error::add_error(
3879
-                esc_html__(
3880
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3881
-                    'event_espresso'
3882
-                ),
3883
-                __FILE__,
3884
-                __FUNCTION__,
3885
-                __LINE__
3886
-            );
3887
-            $success = false;
3888
-        }
3889
-
3890
-        // do check to verify we have a valid status.
3891
-        $status = $this->_req_data['status'];
3892
-
3893
-        if ($status !== 'off' && $status !== 'on') {
3894
-            EE_Error::add_error(
3895
-                sprintf(
3896
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3897
-                    $this->_req_data['status']
3898
-                ),
3899
-                __FILE__,
3900
-                __FUNCTION__,
3901
-                __LINE__
3902
-            );
3903
-            $success = false;
3904
-        }
3905
-
3906
-        if ($success) {
3907
-            // made it here?  Stop dawdling then!!
3908
-            $success = $status === 'off'
3909
-                ? $this->_deactivate_messenger($this->_req_data['messenger'])
3910
-                : $this->_activate_messenger($this->_req_data['messenger']);
3911
-        }
3912
-
3913
-        $this->_template_args['success'] = $success;
3914
-
3915
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
3916
-        $this->_return_json();
3917
-    }
3918
-
3919
-
3920
-    /**
3921
-     * used by ajax from the messages settings page to activate|deactivate a message type
3922
-     *
3923
-     * @throws DomainException
3924
-     * @throws EE_Error
3925
-     * @throws ReflectionException
3926
-     * @throws InvalidDataTypeException
3927
-     * @throws InvalidInterfaceException
3928
-     * @throws InvalidArgumentException
3929
-     */
3930
-    public function activate_mt_toggle()
3931
-    {
3932
-        $success = true;
3933
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3934
-
3935
-        // let's make sure we have the necessary data
3936
-        if (! isset($this->_req_data['message_type'])) {
3937
-            EE_Error::add_error(
3938
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3939
-                __FILE__,
3940
-                __FUNCTION__,
3941
-                __LINE__
3942
-            );
3943
-            $success = false;
3944
-        }
3945
-
3946
-        if (! isset($this->_req_data['messenger'])) {
3947
-            EE_Error::add_error(
3948
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3949
-                __FILE__,
3950
-                __FUNCTION__,
3951
-                __LINE__
3952
-            );
3953
-            $success = false;
3954
-        }
3955
-
3956
-        if (! isset($this->_req_data['status'])) {
3957
-            EE_Error::add_error(
3958
-                esc_html__(
3959
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3960
-                    'event_espresso'
3961
-                ),
3962
-                __FILE__,
3963
-                __FUNCTION__,
3964
-                __LINE__
3965
-            );
3966
-            $success = false;
3967
-        }
3968
-
3969
-
3970
-        // do check to verify we have a valid status.
3971
-        $status = $this->_req_data['status'];
3972
-
3973
-        if ($status !== 'activate' && $status !== 'deactivate') {
3974
-            EE_Error::add_error(
3975
-                sprintf(
3976
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3977
-                    $this->_req_data['status']
3978
-                ),
3979
-                __FILE__,
3980
-                __FUNCTION__,
3981
-                __LINE__
3982
-            );
3983
-            $success = false;
3984
-        }
3985
-
3986
-
3987
-        // do a nonce check here since we're not arriving via a normal route
3988
-        $nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3989
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3990
-
3991
-        $this->_verify_nonce($nonce, $nonce_ref);
3992
-
3993
-        if ($success) {
3994
-            // made it here? um, what are you waiting for then?
3995
-            $success = $status === 'deactivate'
3996
-                ? $this->_deactivate_message_type_for_messenger(
3997
-                    $this->_req_data['messenger'],
3998
-                    $this->_req_data['message_type']
3999
-                )
4000
-                : $this->_activate_message_type_for_messenger(
4001
-                    $this->_req_data['messenger'],
4002
-                    $this->_req_data['message_type']
4003
-                );
4004
-        }
4005
-
4006
-        $this->_template_args['success'] = $success;
4007
-        $this->_return_json();
4008
-    }
4009
-
4010
-
4011
-    /**
4012
-     * Takes care of processing activating a messenger and preparing the appropriate response.
4013
-     *
4014
-     * @param string $messenger_name The name of the messenger being activated
4015
-     * @return bool
4016
-     * @throws DomainException
4017
-     * @throws EE_Error
4018
-     * @throws InvalidArgumentException
4019
-     * @throws ReflectionException
4020
-     * @throws InvalidDataTypeException
4021
-     * @throws InvalidInterfaceException
4022
-     */
4023
-    protected function _activate_messenger($messenger_name)
4024
-    {
4025
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4026
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4027
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
4028
-            ? $active_messenger->get_default_message_types()
4029
-            : array();
4030
-
4031
-        // ensure is active
4032
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4033
-
4034
-        // set response_data for reload
4035
-        foreach ($message_types_to_activate as $message_type_name) {
4036
-            /** @var EE_message_type $message_type */
4037
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4038
-            if (
4039
-                $this->_message_resource_manager->is_message_type_active_for_messenger(
4040
-                    $messenger_name,
4041
-                    $message_type_name
4042
-                )
4043
-                && $message_type instanceof EE_message_type
4044
-            ) {
4045
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
4046
-                if ($message_type->get_admin_settings_fields()) {
4047
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
4048
-                }
4049
-            }
4050
-        }
4051
-
4052
-        // add success message for activating messenger
4053
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4054
-    }
4055
-
4056
-
4057
-    /**
4058
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
4059
-     *
4060
-     * @param string $messenger_name The name of the messenger being activated
4061
-     * @return bool
4062
-     * @throws DomainException
4063
-     * @throws EE_Error
4064
-     * @throws InvalidArgumentException
4065
-     * @throws ReflectionException
4066
-     * @throws InvalidDataTypeException
4067
-     * @throws InvalidInterfaceException
4068
-     */
4069
-    protected function _deactivate_messenger($messenger_name)
4070
-    {
4071
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4072
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4073
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
4074
-
4075
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4076
-    }
4077
-
4078
-
4079
-    /**
4080
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4081
-     *
4082
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
4083
-     * @param string $message_type_name The name of the message type being activated for the messenger
4084
-     * @return bool
4085
-     * @throws DomainException
4086
-     * @throws EE_Error
4087
-     * @throws InvalidArgumentException
4088
-     * @throws ReflectionException
4089
-     * @throws InvalidDataTypeException
4090
-     * @throws InvalidInterfaceException
4091
-     */
4092
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4093
-    {
4094
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4095
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4096
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4097
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4098
-
4099
-        // ensure is active
4100
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4101
-
4102
-        // set response for load
4103
-        if (
4104
-            $this->_message_resource_manager->is_message_type_active_for_messenger(
4105
-                $messenger_name,
4106
-                $message_type_name
4107
-            )
4108
-        ) {
4109
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
4110
-            if ($message_type_to_activate->get_admin_settings_fields()) {
4111
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
4112
-            }
4113
-        }
4114
-
4115
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
4116
-            $active_messenger,
4117
-            $message_type_to_activate
4118
-        );
4119
-    }
4120
-
4121
-
4122
-    /**
4123
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4124
-     *
4125
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4126
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
4127
-     * @return bool
4128
-     * @throws DomainException
4129
-     * @throws EE_Error
4130
-     * @throws InvalidArgumentException
4131
-     * @throws ReflectionException
4132
-     * @throws InvalidDataTypeException
4133
-     * @throws InvalidInterfaceException
4134
-     */
4135
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4136
-    {
4137
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4138
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4139
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4140
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4141
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4142
-
4143
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4144
-            $active_messenger,
4145
-            $message_type_to_deactivate
4146
-        );
4147
-    }
4148
-
4149
-
4150
-    /**
4151
-     * This just initializes the defaults for activating messenger and message type responses.
4152
-     */
4153
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
4154
-    {
4155
-        $this->_template_args['data']['active_mts'] = array();
4156
-        $this->_template_args['data']['mt_reload'] = array();
4157
-    }
4158
-
4159
-
4160
-    /**
4161
-     * Setup appropriate response for activating a messenger and/or message types
4162
-     *
4163
-     * @param EE_messenger         $messenger
4164
-     * @param EE_message_type|null $message_type
4165
-     * @return bool
4166
-     * @throws DomainException
4167
-     * @throws EE_Error
4168
-     * @throws InvalidArgumentException
4169
-     * @throws ReflectionException
4170
-     * @throws InvalidDataTypeException
4171
-     * @throws InvalidInterfaceException
4172
-     */
4173
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
4174
-        $messenger,
4175
-        EE_Message_Type $message_type = null
4176
-    ) {
4177
-        // if $messenger isn't a valid messenger object then get out.
4178
-        if (! $messenger instanceof EE_Messenger) {
4179
-            EE_Error::add_error(
4180
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4181
-                __FILE__,
4182
-                __FUNCTION__,
4183
-                __LINE__
4184
-            );
4185
-
4186
-            return false;
4187
-        }
4188
-        // activated
4189
-        if ($this->_template_args['data']['active_mts']) {
4190
-            EE_Error::overwrite_success();
4191
-            // activated a message type with the messenger
4192
-            if ($message_type instanceof EE_message_type) {
4193
-                EE_Error::add_success(
4194
-                    sprintf(
4195
-                        esc_html__(
4196
-                            '%s message type has been successfully activated with the %s messenger',
4197
-                            'event_espresso'
4198
-                        ),
4199
-                        ucwords($message_type->label['singular']),
4200
-                        ucwords($messenger->label['singular'])
4201
-                    )
4202
-                );
4203
-
4204
-                // if message type was invoice then let's make sure we activate the invoice payment method.
4205
-                if ($message_type->name === 'invoice') {
4206
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
4207
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4208
-                    if ($pm instanceof EE_Payment_Method) {
4209
-                        EE_Error::add_attention(
4210
-                            esc_html__(
4211
-                                'Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
4212
-                                'event_espresso'
4213
-                            )
4214
-                        );
4215
-                    }
4216
-                }
4217
-                // just toggles the entire messenger
4218
-            } else {
4219
-                EE_Error::add_success(
4220
-                    sprintf(
4221
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4222
-                        ucwords($messenger->label['singular'])
4223
-                    )
4224
-                );
4225
-            }
4226
-
4227
-            return true;
4228
-
4229
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4230
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4231
-            // in which case we just give a success message for the messenger being successfully activated.
4232
-        } else {
4233
-            if (! $messenger->get_default_message_types()) {
4234
-                // messenger doesn't have any default message types so still a success.
4235
-                EE_Error::add_success(
4236
-                    sprintf(
4237
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4238
-                        ucwords($messenger->label['singular'])
4239
-                    )
4240
-                );
4241
-
4242
-                return true;
4243
-            } else {
4244
-                EE_Error::add_error(
4245
-                    $message_type instanceof EE_message_type
4246
-                        ? sprintf(
4247
-                            esc_html__(
4248
-                                '%s message type was not successfully activated with the %s messenger',
4249
-                                'event_espresso'
4250
-                            ),
4251
-                            ucwords($message_type->label['singular']),
4252
-                            ucwords($messenger->label['singular'])
4253
-                        )
4254
-                        : sprintf(
4255
-                            esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4256
-                            ucwords($messenger->label['singular'])
4257
-                        ),
4258
-                    __FILE__,
4259
-                    __FUNCTION__,
4260
-                    __LINE__
4261
-                );
4262
-
4263
-                return false;
4264
-            }
4265
-        }
4266
-    }
4267
-
4268
-
4269
-    /**
4270
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
4271
-     *
4272
-     * @param EE_messenger         $messenger
4273
-     * @param EE_message_type|null $message_type
4274
-     * @return bool
4275
-     * @throws DomainException
4276
-     * @throws EE_Error
4277
-     * @throws InvalidArgumentException
4278
-     * @throws ReflectionException
4279
-     * @throws InvalidDataTypeException
4280
-     * @throws InvalidInterfaceException
4281
-     */
4282
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4283
-        $messenger,
4284
-        EE_message_type $message_type = null
4285
-    ) {
4286
-        EE_Error::overwrite_success();
4287
-
4288
-        // if $messenger isn't a valid messenger object then get out.
4289
-        if (! $messenger instanceof EE_Messenger) {
4290
-            EE_Error::add_error(
4291
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4292
-                __FILE__,
4293
-                __FUNCTION__,
4294
-                __LINE__
4295
-            );
4296
-
4297
-            return false;
4298
-        }
4299
-
4300
-        if ($message_type instanceof EE_message_type) {
4301
-            $message_type_name = $message_type->name;
4302
-            EE_Error::add_success(
4303
-                sprintf(
4304
-                    esc_html__(
4305
-                        '%s message type has been successfully deactivated for the %s messenger.',
4306
-                        'event_espresso'
4307
-                    ),
4308
-                    ucwords($message_type->label['singular']),
4309
-                    ucwords($messenger->label['singular'])
4310
-                )
4311
-            );
4312
-        } else {
4313
-            $message_type_name = '';
4314
-            EE_Error::add_success(
4315
-                sprintf(
4316
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4317
-                    ucwords($messenger->label['singular'])
4318
-                )
4319
-            );
4320
-        }
4321
-
4322
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4323
-        if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4324
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
4325
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4326
-            if ($count_updated > 0) {
4327
-                $msg = $message_type_name === 'invoice'
4328
-                    ? esc_html__(
4329
-                        'Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
4330
-                        'event_espresso'
4331
-                    )
4332
-                    : esc_html__(
4333
-                        'Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
4334
-                        'event_espresso'
4335
-                    );
4336
-                EE_Error::add_attention($msg);
4337
-            }
4338
-        }
4339
-
4340
-        return true;
4341
-    }
4342
-
4343
-
4344
-    /**
4345
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4346
-     *
4347
-     * @throws DomainException
4348
-     */
4349
-    public function update_mt_form()
4350
-    {
4351
-        if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4352
-            EE_Error::add_error(
4353
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4354
-                __FILE__,
4355
-                __FUNCTION__,
4356
-                __LINE__
4357
-            );
4358
-            $this->_return_json();
4359
-        }
4360
-
4361
-        $message_types = $this->get_installed_message_types();
4362
-
4363
-        $message_type = $message_types[ $this->_req_data['message_type'] ];
4364
-        $messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4365
-
4366
-        $content = $this->_message_type_settings_content(
4367
-            $message_type,
4368
-            $messenger,
4369
-            true
4370
-        );
4371
-        $this->_template_args['success'] = true;
4372
-        $this->_template_args['content'] = $content;
4373
-        $this->_return_json();
4374
-    }
4375
-
4376
-
4377
-    /**
4378
-     * this handles saving the settings for a messenger or message type
4379
-     *
4380
-     */
4381
-    public function save_settings()
4382
-    {
4383
-        if (! isset($this->_req_data['type'])) {
4384
-            EE_Error::add_error(
4385
-                esc_html__(
4386
-                    'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4387
-                    'event_espresso'
4388
-                ),
4389
-                __FILE__,
4390
-                __FUNCTION__,
4391
-                __LINE__
4392
-            );
4393
-            $this->_template_args['error'] = true;
4394
-            $this->_return_json();
4395
-        }
4396
-
4397
-
4398
-        if ($this->_req_data['type'] === 'messenger') {
4399
-            // this should be an array.
4400
-            $settings = $this->_req_data['messenger_settings'];
4401
-            $messenger = $settings['messenger'];
4402
-            // let's setup the settings data
4403
-            foreach ($settings as $key => $value) {
4404
-                switch ($key) {
4405
-                    case 'messenger':
4406
-                        unset($settings['messenger']);
4407
-                        break;
4408
-                    case 'message_types':
4409
-                        unset($settings['message_types']);
4410
-                        break;
4411
-                    default:
4412
-                        $settings[ $key ] = $value;
4413
-                        break;
4414
-                }
4415
-            }
4416
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4417
-        } elseif ($this->_req_data['type'] === 'message_type') {
4418
-            $settings = $this->_req_data['message_type_settings'];
4419
-            $messenger = $settings['messenger'];
4420
-            $message_type = $settings['message_type'];
4421
-
4422
-            foreach ($settings as $key => $value) {
4423
-                switch ($key) {
4424
-                    case 'messenger':
4425
-                        unset($settings['messenger']);
4426
-                        break;
4427
-                    case 'message_type':
4428
-                        unset($settings['message_type']);
4429
-                        break;
4430
-                    default:
4431
-                        $settings[ $key ] = $value;
4432
-                        break;
4433
-                }
4434
-            }
4435
-
4436
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4437
-        }
4438
-
4439
-        // okay we should have the data all setup.  Now we just update!
4440
-        $success = $this->_message_resource_manager->update_active_messengers_option();
4441
-
4442
-        if ($success) {
4443
-            EE_Error::add_success(__('Settings updated', 'event_espresso'));
4444
-        } else {
4445
-            EE_Error::add_error(
4446
-                esc_html__(
4447
-                    'Settings did not get updated',
4448
-                    'event_espresso'
4449
-                ),
4450
-                __FILE__,
4451
-                __FUNCTION__,
4452
-                __LINE__
4453
-            );
4454
-        }
4455
-
4456
-        $this->_template_args['success'] = $success;
4457
-        $this->_return_json();
4458
-    }
4459
-
4460
-
4461
-
4462
-
4463
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4464
-
4465
-
4466
-    /**
4467
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4468
-     * However, this does not send immediately, it just queues for sending.
4469
-     *
4470
-     * @since 4.9.0
4471
-     * @throws EE_Error
4472
-     * @throws InvalidDataTypeException
4473
-     * @throws InvalidInterfaceException
4474
-     * @throws InvalidArgumentException
4475
-     * @throws ReflectionException
4476
-     */
4477
-    protected function _generate_now()
4478
-    {
4479
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4480
-        $this->_redirect_after_action(false, '', '', array(), true);
4481
-    }
4482
-
4483
-
4484
-    /**
4485
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4486
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4487
-     *
4488
-     * @since 4.9.0
4489
-     * @throws EE_Error
4490
-     * @throws InvalidDataTypeException
4491
-     * @throws InvalidInterfaceException
4492
-     * @throws InvalidArgumentException
4493
-     * @throws ReflectionException
4494
-     */
4495
-    protected function _generate_and_send_now()
4496
-    {
4497
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4498
-        $this->_redirect_after_action(false, '', '', array(), true);
4499
-    }
4500
-
4501
-
4502
-    /**
4503
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4504
-     *
4505
-     * @since 4.9.0
4506
-     * @throws EE_Error
4507
-     * @throws InvalidDataTypeException
4508
-     * @throws InvalidInterfaceException
4509
-     * @throws InvalidArgumentException
4510
-     * @throws ReflectionException
4511
-     */
4512
-    protected function _queue_for_resending()
4513
-    {
4514
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4515
-        $this->_redirect_after_action(false, '', '', array(), true);
4516
-    }
4517
-
4518
-
4519
-    /**
4520
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4521
-     *
4522
-     * @since 4.9.0
4523
-     * @throws EE_Error
4524
-     * @throws InvalidDataTypeException
4525
-     * @throws InvalidInterfaceException
4526
-     * @throws InvalidArgumentException
4527
-     * @throws ReflectionException
4528
-     */
4529
-    protected function _send_now()
4530
-    {
4531
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4532
-        $this->_redirect_after_action(false, '', '', array(), true);
4533
-    }
4534
-
4535
-
4536
-    /**
4537
-     * Deletes EE_messages for IDs in the request.
4538
-     *
4539
-     * @since 4.9.0
4540
-     * @throws EE_Error
4541
-     * @throws InvalidDataTypeException
4542
-     * @throws InvalidInterfaceException
4543
-     * @throws InvalidArgumentException
4544
-     */
4545
-    protected function _delete_ee_messages()
4546
-    {
4547
-        $msg_ids = $this->_get_msg_ids_from_request();
4548
-        $deleted_count = 0;
4549
-        foreach ($msg_ids as $msg_id) {
4550
-            if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4551
-                $deleted_count++;
4552
-            }
4553
-        }
4554
-        if ($deleted_count) {
4555
-            EE_Error::add_success(
4556
-                esc_html(
4557
-                    _n(
4558
-                        'Message successfully deleted',
4559
-                        'Messages successfully deleted',
4560
-                        $deleted_count,
4561
-                        'event_espresso'
4562
-                    )
4563
-                )
4564
-            );
4565
-            $this->_redirect_after_action(
4566
-                false,
4567
-                '',
4568
-                '',
4569
-                array(),
4570
-                true
4571
-            );
4572
-        } else {
4573
-            EE_Error::add_error(
4574
-                _n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4575
-                __FILE__,
4576
-                __FUNCTION__,
4577
-                __LINE__
4578
-            );
4579
-            $this->_redirect_after_action(false, '', '', array(), true);
4580
-        }
4581
-    }
4582
-
4583
-
4584
-    /**
4585
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4586
-     *
4587
-     * @since 4.9.0
4588
-     * @return array
4589
-     */
4590
-    protected function _get_msg_ids_from_request()
4591
-    {
4592
-        if (! isset($this->_req_data['MSG_ID'])) {
4593
-            return array();
4594
-        }
4595
-
4596
-        return is_array($this->_req_data['MSG_ID'])
4597
-            ? array_keys($this->_req_data['MSG_ID'])
4598
-            : array($this->_req_data['MSG_ID']);
4599
-    }
2674
+		$output = ob_get_contents();
2675
+		ob_clean();
2676
+		$this->_context_switcher = $output;
2677
+	}
2678
+
2679
+
2680
+	/**
2681
+	 * utility for sanitizing new values coming in.
2682
+	 * Note: this is only used when updating a context.
2683
+	 *
2684
+	 * @access protected
2685
+	 *
2686
+	 * @param int $index This helps us know which template field to select from the request array.
2687
+	 *
2688
+	 * @return array
2689
+	 */
2690
+	protected function _set_message_template_column_values($index)
2691
+	{
2692
+		if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2693
+			foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2694
+				$this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2695
+			}
2696
+		}
2697
+
2698
+
2699
+		$set_column_values = array(
2700
+			'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2701
+			'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2702
+			'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2703
+			'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2704
+			'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2705
+			'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2706
+			'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2707
+			'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2708
+			'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2709
+				? absint($this->_req_data['MTP_is_global'])
2710
+				: 0,
2711
+			'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2712
+				? absint($this->_req_data['MTP_is_override'])
2713
+				: 0,
2714
+			'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2715
+			'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2716
+		);
2717
+
2718
+
2719
+		return $set_column_values;
2720
+	}
2721
+
2722
+
2723
+	protected function _insert_or_update_message_template($new = false)
2724
+	{
2725
+		$success = 0;
2726
+		$override = false;
2727
+
2728
+		// setup notices description
2729
+		$messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2730
+
2731
+		// need the message type and messenger objects to be able to use the labels for the notices
2732
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2733
+		$messenger_label = $messenger_object instanceof EE_messenger
2734
+			? ucwords($messenger_object->label['singular'])
2735
+			: '';
2736
+
2737
+		$message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2738
+			? $this->_req_data['MTP_message_type']
2739
+			: '';
2740
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2741
+
2742
+		$message_type_label = $message_type_object instanceof EE_message_type
2743
+			? ucwords($message_type_object->label['singular'])
2744
+			: '';
2745
+
2746
+		$context_slug = ! empty($this->_req_data['MTP_context'])
2747
+			? $this->_req_data['MTP_context']
2748
+			: '';
2749
+		$context = ucwords(str_replace('_', ' ', $context_slug));
2750
+
2751
+		$item_desc = $messenger_label && $message_type_label
2752
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2753
+			: '';
2754
+		$item_desc .= 'Message Template';
2755
+		$query_args = array();
2756
+		$edit_array = array();
2757
+		$action_desc = '';
2758
+
2759
+		// if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2760
+		// user to edit.
2761
+		if ($new) {
2762
+			$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2763
+			if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2764
+				if (empty($edit_array)) {
2765
+					$success = 0;
2766
+				} else {
2767
+					$success = 1;
2768
+					$edit_array = $edit_array[0];
2769
+					$query_args = array(
2770
+						'id'      => $edit_array['GRP_ID'],
2771
+						'context' => $edit_array['MTP_context'],
2772
+						'action'  => 'edit_message_template',
2773
+					);
2774
+				}
2775
+			}
2776
+			$action_desc = 'created';
2777
+		} else {
2778
+			$MTPG = EEM_Message_Template_Group::instance();
2779
+			$MTP = EEM_Message_Template::instance();
2780
+
2781
+
2782
+			// run update for each template field in displayed context
2783
+			if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2784
+				EE_Error::add_error(
2785
+					esc_html__(
2786
+						'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2787
+						'event_espresso'
2788
+					),
2789
+					__FILE__,
2790
+					__FUNCTION__,
2791
+					__LINE__
2792
+				);
2793
+				$success = 0;
2794
+			} else {
2795
+				// first validate all fields!
2796
+				// this filter allows client code to add its own validation to the template fields as well.
2797
+				// returning an empty array means everything passed validation.
2798
+				// errors in validation should be represented in an array with the following shape:
2799
+				// array(
2800
+				//   'fieldname' => array(
2801
+				//          'msg' => 'error message'
2802
+				//          'value' => 'value for field producing error'
2803
+				// )
2804
+				$custom_validation = (array) apply_filters(
2805
+					'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2806
+					array(),
2807
+					$this->_req_data['MTP_template_fields'],
2808
+					$context_slug,
2809
+					$messenger_slug,
2810
+					$message_type_slug
2811
+				);
2812
+
2813
+				$system_validation = $MTPG->validate(
2814
+					$this->_req_data['MTP_template_fields'],
2815
+					$context_slug,
2816
+					$messenger_slug,
2817
+					$message_type_slug
2818
+				);
2819
+
2820
+				$system_validation = ! is_array($system_validation) && $system_validation ? array()
2821
+					: $system_validation;
2822
+				$validates = array_merge($custom_validation, $system_validation);
2823
+
2824
+				// if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2825
+				// appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2826
+				//  WE need to make sure there is no actual error messages in validates.
2827
+				if (is_array($validates) && ! empty($validates)) {
2828
+					// add the transient so when the form loads we know which fields to highlight
2829
+					$this->_add_transient('edit_message_template', $validates);
2830
+
2831
+					$success = 0;
2832
+
2833
+					// setup notices
2834
+					foreach ($validates as $field => $error) {
2835
+						if (isset($error['msg'])) {
2836
+							EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2837
+						}
2838
+					}
2839
+				} else {
2840
+					$set_column_values = array();
2841
+					foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2842
+						$set_column_values = $this->_set_message_template_column_values($template_field);
2843
+
2844
+						$where_cols_n_values = array(
2845
+							'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2846
+						);
2847
+						// if they aren't allowed to use all JS, restrict them to just posty-y tags
2848
+						if (! current_user_can('unfiltered_html')) {
2849
+							if (is_array($set_column_values['MTP_content'])) {
2850
+								foreach ($set_column_values['MTP_content'] as $key => $value) {
2851
+									// remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2852
+									// only removes slashes from double-quotes, so attributes using single quotes always
2853
+									// appear invalid.) But currently the models expect slashed data, so after wp_kses
2854
+									// runs we need to re-slash the data. Sheesh. See
2855
+									// https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2856
+									$set_column_values['MTP_content'][ $key ] = addslashes(
2857
+										wp_kses(
2858
+											stripslashes($value),
2859
+											wp_kses_allowed_html('post')
2860
+										)
2861
+									);
2862
+								}
2863
+							} else {
2864
+								$set_column_values['MTP_content'] = wp_kses(
2865
+									$set_column_values['MTP_content'],
2866
+									wp_kses_allowed_html('post')
2867
+								);
2868
+							}
2869
+						}
2870
+						$message_template_fields = array(
2871
+							'GRP_ID'             => $set_column_values['GRP_ID'],
2872
+							'MTP_template_field' => $set_column_values['MTP_template_field'],
2873
+							'MTP_context'        => $set_column_values['MTP_context'],
2874
+							'MTP_content'        => $set_column_values['MTP_content'],
2875
+						);
2876
+						if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2877
+							if ($updated === false) {
2878
+								EE_Error::add_error(
2879
+									sprintf(
2880
+										esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2881
+										$template_field
2882
+									),
2883
+									__FILE__,
2884
+									__FUNCTION__,
2885
+									__LINE__
2886
+								);
2887
+							} else {
2888
+								$success = 1;
2889
+							}
2890
+						} else {
2891
+							// only do this logic if we don't have a MTP_ID for this field
2892
+							if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2893
+								// this has already been through the template field validator and sanitized, so it will be
2894
+								// safe to insert this field.  Why insert?  This typically happens when we introduce a new
2895
+								// message template field in a messenger/message type and existing users don't have the
2896
+								// default setup for it.
2897
+								// @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2898
+								$updated = $MTP->insert($message_template_fields);
2899
+								if (! $updated || is_wp_error($updated)) {
2900
+									EE_Error::add_error(
2901
+										sprintf(
2902
+											esc_html__('%s field could not be updated.', 'event_espresso'),
2903
+											$template_field
2904
+										),
2905
+										__FILE__,
2906
+										__FUNCTION__,
2907
+										__LINE__
2908
+									);
2909
+									$success = 0;
2910
+								} else {
2911
+									$success = 1;
2912
+								}
2913
+							}
2914
+						}
2915
+						$action_desc = 'updated';
2916
+					}
2917
+
2918
+					// we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2919
+					$mtpg_fields = array(
2920
+						'MTP_user_id'      => $set_column_values['MTP_user_id'],
2921
+						'MTP_messenger'    => $set_column_values['MTP_messenger'],
2922
+						'MTP_message_type' => $set_column_values['MTP_message_type'],
2923
+						'MTP_is_global'    => $set_column_values['MTP_is_global'],
2924
+						'MTP_is_override'  => $set_column_values['MTP_is_override'],
2925
+						'MTP_deleted'      => $set_column_values['MTP_deleted'],
2926
+						'MTP_is_active'    => $set_column_values['MTP_is_active'],
2927
+						'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2928
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2929
+							: '',
2930
+						'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2931
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2932
+							: '',
2933
+					);
2934
+
2935
+					$mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2936
+					$updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2937
+
2938
+					if ($updated === false) {
2939
+						EE_Error::add_error(
2940
+							sprintf(
2941
+								esc_html__(
2942
+									'The Message Template Group (%d) was NOT updated for some reason',
2943
+									'event_espresso'
2944
+								),
2945
+								$set_column_values['GRP_ID']
2946
+							),
2947
+							__FILE__,
2948
+							__FUNCTION__,
2949
+							__LINE__
2950
+						);
2951
+					} else {
2952
+						// k now we need to ensure the template_pack and template_variation fields are set.
2953
+						$template_pack = ! empty($this->_req_data['MTP_template_pack'])
2954
+							? $this->_req_data['MTP_template_pack']
2955
+							: 'default';
2956
+
2957
+						$template_variation = ! empty($this->_req_data['MTP_template_variation'])
2958
+							? $this->_req_data['MTP_template_variation']
2959
+							: 'default';
2960
+
2961
+						$mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2962
+						if ($mtpg_obj instanceof EE_Message_Template_Group) {
2963
+							$mtpg_obj->set_template_pack_name($template_pack);
2964
+							$mtpg_obj->set_template_pack_variation($template_variation);
2965
+						}
2966
+						$success = 1;
2967
+					}
2968
+				}
2969
+			}
2970
+		}
2971
+
2972
+		// we return things differently if doing ajax
2973
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2974
+			$this->_template_args['success'] = $success;
2975
+			$this->_template_args['error'] = ! $success ? true : false;
2976
+			$this->_template_args['content'] = '';
2977
+			$this->_template_args['data'] = array(
2978
+				'grpID'        => $edit_array['GRP_ID'],
2979
+				'templateName' => $edit_array['template_name'],
2980
+			);
2981
+			if ($success) {
2982
+				EE_Error::overwrite_success();
2983
+				EE_Error::add_success(
2984
+					esc_html__(
2985
+						'The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2986
+						'event_espresso'
2987
+					)
2988
+				);
2989
+			}
2990
+
2991
+			$this->_return_json();
2992
+		}
2993
+
2994
+
2995
+		// was a test send triggered?
2996
+		if (isset($this->_req_data['test_button'])) {
2997
+			EE_Error::overwrite_success();
2998
+			$this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2999
+			$override = true;
3000
+		}
3001
+
3002
+		if (empty($query_args)) {
3003
+			$query_args = array(
3004
+				'id'      => $this->_req_data['GRP_ID'],
3005
+				'context' => $context_slug,
3006
+				'action'  => 'edit_message_template',
3007
+			);
3008
+		}
3009
+
3010
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3011
+	}
3012
+
3013
+
3014
+	/**
3015
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
3016
+	 *
3017
+	 * @param  string $context      what context being tested
3018
+	 * @param  string $messenger    messenger being tested
3019
+	 * @param  string $message_type message type being tested
3020
+	 * @throws EE_Error
3021
+	 * @throws InvalidArgumentException
3022
+	 * @throws InvalidDataTypeException
3023
+	 * @throws InvalidInterfaceException
3024
+	 */
3025
+	protected function _do_test_send($context, $messenger, $message_type)
3026
+	{
3027
+		// set things up for preview
3028
+		$this->_req_data['messenger'] = $messenger;
3029
+		$this->_req_data['message_type'] = $message_type;
3030
+		$this->_req_data['context'] = $context;
3031
+		$this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3032
+		$active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3033
+
3034
+		// let's save any existing fields that might be required by the messenger
3035
+		if (
3036
+			isset($this->_req_data['test_settings_fld'])
3037
+			&& $active_messenger instanceof EE_messenger
3038
+			&& apply_filters(
3039
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3040
+				true,
3041
+				$this->_req_data['test_settings_fld'],
3042
+				$active_messenger
3043
+			)
3044
+		) {
3045
+			$active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3046
+		}
3047
+
3048
+		/**
3049
+		 * Use filter to add additional controls on whether message can send or not
3050
+		 */
3051
+		if (
3052
+			apply_filters(
3053
+				'FHEE__Messages_Admin_Page__do_test_send__can_send',
3054
+				true,
3055
+				$context,
3056
+				$this->_req_data,
3057
+				$messenger,
3058
+				$message_type
3059
+			)
3060
+		) {
3061
+			if (EEM_Event::instance()->count() > 0) {
3062
+				$success = $this->_preview_message(true);
3063
+				if ($success) {
3064
+					EE_Error::add_success(__('Test message sent', 'event_espresso'));
3065
+				} else {
3066
+					EE_Error::add_error(
3067
+						esc_html__('The test message was not sent', 'event_espresso'),
3068
+						__FILE__,
3069
+						__FUNCTION__,
3070
+						__LINE__
3071
+					);
3072
+				}
3073
+			} else {
3074
+				$this->noEventsErrorMessage(true);
3075
+			}
3076
+		}
3077
+	}
3078
+
3079
+
3080
+	/**
3081
+	 * _generate_new_templates
3082
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3083
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3084
+	 * for the event.
3085
+	 *
3086
+	 *
3087
+	 * @param  string $messenger     the messenger we are generating templates for
3088
+	 * @param array   $message_types array of message types that the templates are generated for.
3089
+	 * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3090
+	 *                               indicate the message_template_group being used as the base.
3091
+	 *
3092
+	 * @param bool    $global
3093
+	 *
3094
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
3095
+	 *                               encountering problems.
3096
+	 * @throws EE_Error
3097
+	 */
3098
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3099
+	{
3100
+
3101
+		// if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3102
+		// just don't generate any templates.
3103
+		if (empty($message_types)) {
3104
+			return true;
3105
+		}
3106
+
3107
+		return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3108
+	}
3109
+
3110
+
3111
+	/**
3112
+	 * [_trash_or_restore_message_template]
3113
+	 *
3114
+	 * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3115
+	 * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3116
+	 *                        an individual context (FALSE).
3117
+	 * @return void
3118
+	 * @throws EE_Error
3119
+	 * @throws InvalidArgumentException
3120
+	 * @throws InvalidDataTypeException
3121
+	 * @throws InvalidInterfaceException
3122
+	 */
3123
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
3124
+	{
3125
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3126
+		$MTP = EEM_Message_Template_Group::instance();
3127
+
3128
+		$success = 1;
3129
+
3130
+		// incoming GRP_IDs
3131
+		if ($all) {
3132
+			// Checkboxes
3133
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3134
+				// if array has more than one element then success message should be plural.
3135
+				// todo: what about nonce?
3136
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3137
+
3138
+				// cycle through checkboxes
3139
+				while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3140
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3141
+					if (! $trashed_or_restored) {
3142
+						$success = 0;
3143
+					}
3144
+				}
3145
+			} else {
3146
+				// grab single GRP_ID and handle
3147
+				$GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3148
+				if (! empty($GRP_ID)) {
3149
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3150
+					if (! $trashed_or_restored) {
3151
+						$success = 0;
3152
+					}
3153
+				} else {
3154
+					$success = 0;
3155
+				}
3156
+			}
3157
+		}
3158
+
3159
+		$action_desc = $trash
3160
+			? esc_html__('moved to the trash', 'event_espresso')
3161
+			: esc_html__('restored', 'event_espresso');
3162
+
3163
+		$action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3164
+
3165
+		$item_desc = $all ? _n(
3166
+			'Message Template Group',
3167
+			'Message Template Groups',
3168
+			$success,
3169
+			'event_espresso'
3170
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3171
+
3172
+		$item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3173
+			'template',
3174
+			'templates',
3175
+			$success,
3176
+			'event_espresso'
3177
+		) : $item_desc;
3178
+
3179
+		$this->_redirect_after_action($success, $item_desc, $action_desc, array());
3180
+	}
3181
+
3182
+
3183
+	/**
3184
+	 * [_delete_message_template]
3185
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3186
+	 *
3187
+	 * @return void
3188
+	 * @throws EE_Error
3189
+	 * @throws InvalidArgumentException
3190
+	 * @throws InvalidDataTypeException
3191
+	 * @throws InvalidInterfaceException
3192
+	 */
3193
+	protected function _delete_message_template()
3194
+	{
3195
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3196
+
3197
+		// checkboxes
3198
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3199
+			// if array has more than one element then success message should be plural
3200
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3201
+
3202
+			// cycle through bulk action checkboxes
3203
+			while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3204
+				$success = $this->_delete_mtp_permanently($GRP_ID);
3205
+			}
3206
+		} else {
3207
+			// grab single grp_id and delete
3208
+			$GRP_ID = absint($this->_req_data['id']);
3209
+			$success = $this->_delete_mtp_permanently($GRP_ID);
3210
+		}
3211
+
3212
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3213
+	}
3214
+
3215
+
3216
+	/**
3217
+	 * helper for permanently deleting a mtP group and all related message_templates
3218
+	 *
3219
+	 * @param  int  $GRP_ID        The group being deleted
3220
+	 * @param  bool $include_group whether to delete the Message Template Group as well.
3221
+	 * @return bool boolean to indicate the success of the deletes or not.
3222
+	 * @throws EE_Error
3223
+	 * @throws InvalidArgumentException
3224
+	 * @throws InvalidDataTypeException
3225
+	 * @throws InvalidInterfaceException
3226
+	 */
3227
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3228
+	{
3229
+		$success = 1;
3230
+		$MTPG = EEM_Message_Template_Group::instance();
3231
+		// first let's GET this group
3232
+		$MTG = $MTPG->get_one_by_ID($GRP_ID);
3233
+		// then delete permanently all the related Message Templates
3234
+		$deleted = $MTG->delete_related_permanently('Message_Template');
3235
+
3236
+		if ($deleted === 0) {
3237
+			$success = 0;
3238
+		}
3239
+
3240
+		// now delete permanently this particular group
3241
+
3242
+		if ($include_group && ! $MTG->delete_permanently()) {
3243
+			$success = 0;
3244
+		}
3245
+
3246
+		return $success;
3247
+	}
3248
+
3249
+
3250
+	/**
3251
+	 *    _learn_more_about_message_templates_link
3252
+	 *
3253
+	 * @access protected
3254
+	 * @return string
3255
+	 */
3256
+	protected function _learn_more_about_message_templates_link()
3257
+	{
3258
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3259
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
3260
+			   . '</a>';
3261
+	}
3262
+
3263
+
3264
+	/**
3265
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3266
+	 * ajax and other routes.
3267
+	 *
3268
+	 * @return void
3269
+	 * @throws DomainException
3270
+	 */
3271
+	protected function _settings()
3272
+	{
3273
+
3274
+
3275
+		$this->_set_m_mt_settings();
3276
+
3277
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3278
+			? $this->_req_data['selected_messenger']
3279
+			: 'email';
3280
+
3281
+		// let's setup the messenger tabs
3282
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3283
+			$this->_m_mt_settings['messenger_tabs'],
3284
+			'messenger_links',
3285
+			'|',
3286
+			$selected_messenger
3287
+		);
3288
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3289
+		$this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3290
+
3291
+		$this->display_admin_page_with_sidebar();
3292
+	}
3293
+
3294
+
3295
+	/**
3296
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3297
+	 *
3298
+	 * @access protected
3299
+	 * @return void
3300
+	 * @throws DomainException
3301
+	 */
3302
+	protected function _set_m_mt_settings()
3303
+	{
3304
+		// first if this is already set then lets get out no need to regenerate data.
3305
+		if (! empty($this->_m_mt_settings)) {
3306
+			return;
3307
+		}
3308
+
3309
+		// get all installed messengers and message_types
3310
+		/** @type EE_messenger[] $messengers */
3311
+		$messengers = $this->_message_resource_manager->installed_messengers();
3312
+		/** @type EE_message_type[] $message_types */
3313
+		$message_types = $this->_message_resource_manager->installed_message_types();
3314
+
3315
+
3316
+		// assemble the array for the _tab_text_links helper
3317
+
3318
+		foreach ($messengers as $messenger) {
3319
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3320
+				'label' => ucwords($messenger->label['singular']),
3321
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3322
+					? 'messenger-active'
3323
+					: '',
3324
+				'href'  => $messenger->name,
3325
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3326
+				'slug'  => $messenger->name,
3327
+				'obj'   => $messenger,
3328
+			);
3329
+
3330
+
3331
+			$message_types_for_messenger = $messenger->get_valid_message_types();
3332
+
3333
+			foreach ($message_types as $message_type) {
3334
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3335
+				// it shouldn't show in either the inactive OR active metabox.
3336
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3337
+					continue;
3338
+				}
3339
+
3340
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3341
+					$messenger->name,
3342
+					$message_type->name
3343
+				)
3344
+					? 'active'
3345
+					: 'inactive';
3346
+
3347
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3348
+					'label'    => ucwords($message_type->label['singular']),
3349
+					'class'    => 'message-type-' . $a_or_i,
3350
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3351
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3352
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3353
+					'title'    => $a_or_i === 'active'
3354
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3355
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3356
+					'content'  => $a_or_i === 'active'
3357
+						? $this->_message_type_settings_content($message_type, $messenger, true)
3358
+						: $this->_message_type_settings_content($message_type, $messenger),
3359
+					'slug'     => $message_type->name,
3360
+					'active'   => $a_or_i === 'active',
3361
+					'obj'      => $message_type,
3362
+				);
3363
+			}
3364
+		}
3365
+	}
3366
+
3367
+
3368
+	/**
3369
+	 * This just prepares the content for the message type settings
3370
+	 *
3371
+	 * @param  EE_message_type $message_type The message type object
3372
+	 * @param  EE_messenger    $messenger    The messenger object
3373
+	 * @param  boolean         $active       Whether the message type is active or not
3374
+	 * @return string html output for the content
3375
+	 * @throws DomainException
3376
+	 */
3377
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
3378
+	{
3379
+		// get message type fields
3380
+		$fields = $message_type->get_admin_settings_fields();
3381
+		$settings_template_args['template_form_fields'] = '';
3382
+
3383
+		if (! empty($fields) && $active) {
3384
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3385
+			foreach ($fields as $fldname => $fldprops) {
3386
+				$field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3387
+				$template_form_field[ $field_id ] = array(
3388
+					'name'       => 'message_type_settings[' . $fldname . ']',
3389
+					'label'      => $fldprops['label'],
3390
+					'input'      => $fldprops['field_type'],
3391
+					'type'       => $fldprops['value_type'],
3392
+					'required'   => $fldprops['required'],
3393
+					'validation' => $fldprops['validation'],
3394
+					'value'      => isset($existing_settings[ $fldname ])
3395
+						? $existing_settings[ $fldname ]
3396
+						: $fldprops['default'],
3397
+					'options'    => isset($fldprops['options'])
3398
+						? $fldprops['options']
3399
+						: array(),
3400
+					'default'    => isset($existing_settings[ $fldname ])
3401
+						? $existing_settings[ $fldname ]
3402
+						: $fldprops['default'],
3403
+					'css_class'  => 'no-drag',
3404
+					'format'     => $fldprops['format'],
3405
+				);
3406
+			}
3407
+
3408
+
3409
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3410
+				? $this->_generate_admin_form_fields(
3411
+					$template_form_field,
3412
+					'string',
3413
+					'ee_mt_activate_form'
3414
+				)
3415
+				: '';
3416
+		}
3417
+
3418
+		$settings_template_args['description'] = $message_type->description;
3419
+		// we also need some hidden fields
3420
+		$settings_template_args['hidden_fields'] = array(
3421
+			'message_type_settings[messenger]'    => array(
3422
+				'type'  => 'hidden',
3423
+				'value' => $messenger->name,
3424
+			),
3425
+			'message_type_settings[message_type]' => array(
3426
+				'type'  => 'hidden',
3427
+				'value' => $message_type->name,
3428
+			),
3429
+			'type'                                => array(
3430
+				'type'  => 'hidden',
3431
+				'value' => 'message_type',
3432
+			),
3433
+		);
3434
+
3435
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3436
+			$settings_template_args['hidden_fields'],
3437
+			'array'
3438
+		);
3439
+		$settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3440
+			? ' hidden'
3441
+			: '';
3442
+
3443
+
3444
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3445
+		$content = EEH_Template::display_template($template, $settings_template_args, true);
3446
+
3447
+		return $content;
3448
+	}
3449
+
3450
+
3451
+	/**
3452
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3453
+	 *
3454
+	 * @access protected
3455
+	 * @return void
3456
+	 * @throws DomainException
3457
+	 */
3458
+	protected function _messages_settings_metaboxes()
3459
+	{
3460
+		$this->_set_m_mt_settings();
3461
+		$m_boxes = $mt_boxes = array();
3462
+		$m_template_args = $mt_template_args = array();
3463
+
3464
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3465
+			? $this->_req_data['selected_messenger']
3466
+			: 'email';
3467
+
3468
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3469
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3470
+				$hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3471
+				$hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3472
+				// messenger meta boxes
3473
+				$active = $selected_messenger === $messenger;
3474
+				$active_mt_tabs = isset(
3475
+					$this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3476
+				)
3477
+					? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3478
+					: '';
3479
+				$m_boxes[ $messenger . '_a_box' ] = sprintf(
3480
+					esc_html__('%s Settings', 'event_espresso'),
3481
+					$tab_array['label']
3482
+				);
3483
+				$m_template_args[ $messenger . '_a_box' ] = array(
3484
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3485
+					'inactive_message_types' => isset(
3486
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3487
+					)
3488
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3489
+						: '',
3490
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3491
+					'hidden'                 => $active ? '' : ' hidden',
3492
+					'hide_on_message'        => $hide_on_message,
3493
+					'messenger'              => $messenger,
3494
+					'active'                 => $active,
3495
+				);
3496
+				// message type meta boxes
3497
+				// (which is really just the inactive container for each messenger
3498
+				// showing inactive message types for that messenger)
3499
+				$mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3500
+				$mt_template_args[ $messenger . '_i_box' ] = array(
3501
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3502
+					'inactive_message_types' => isset(
3503
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3504
+					)
3505
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3506
+						: '',
3507
+					'hidden'                 => $active ? '' : ' hidden',
3508
+					'hide_on_message'        => $hide_on_message,
3509
+					'hide_off_message'       => $hide_off_message,
3510
+					'messenger'              => $messenger,
3511
+					'active'                 => $active,
3512
+				);
3513
+			}
3514
+		}
3515
+
3516
+
3517
+		// register messenger metaboxes
3518
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3519
+		foreach ($m_boxes as $box => $label) {
3520
+			$callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3521
+			$msgr = str_replace('_a_box', '', $box);
3522
+			add_meta_box(
3523
+				'espresso_' . $msgr . '_settings',
3524
+				$label,
3525
+				function ($post, $metabox) {
3526
+					echo EEH_Template::display_template(
3527
+						$metabox["args"]["template_path"],
3528
+						$metabox["args"]["template_args"],
3529
+						true
3530
+					);
3531
+				},
3532
+				$this->_current_screen->id,
3533
+				'normal',
3534
+				'high',
3535
+				$callback_args
3536
+			);
3537
+		}
3538
+
3539
+		// register message type metaboxes
3540
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3541
+		foreach ($mt_boxes as $box => $label) {
3542
+			$callback_args = array(
3543
+				'template_path' => $mt_template_path,
3544
+				'template_args' => $mt_template_args[ $box ],
3545
+			);
3546
+			$mt = str_replace('_i_box', '', $box);
3547
+			add_meta_box(
3548
+				'espresso_' . $mt . '_inactive_mts',
3549
+				$label,
3550
+				function ($post, $metabox) {
3551
+					echo EEH_Template::display_template(
3552
+						$metabox["args"]["template_path"],
3553
+						$metabox["args"]["template_args"],
3554
+						true
3555
+					);
3556
+				},
3557
+				$this->_current_screen->id,
3558
+				'side',
3559
+				'high',
3560
+				$callback_args
3561
+			);
3562
+		}
3563
+
3564
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3565
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3566
+		if (is_main_site()) {
3567
+			add_meta_box(
3568
+				'espresso_global_message_settings',
3569
+				esc_html__('Global Message Settings', 'event_espresso'),
3570
+				array($this, 'global_messages_settings_metabox_content'),
3571
+				$this->_current_screen->id,
3572
+				'normal',
3573
+				'low',
3574
+				array()
3575
+			);
3576
+		}
3577
+	}
3578
+
3579
+
3580
+	/**
3581
+	 *  This generates the content for the global messages settings metabox.
3582
+	 *
3583
+	 * @return string
3584
+	 * @throws EE_Error
3585
+	 * @throws InvalidArgumentException
3586
+	 * @throws ReflectionException
3587
+	 * @throws InvalidDataTypeException
3588
+	 * @throws InvalidInterfaceException
3589
+	 */
3590
+	public function global_messages_settings_metabox_content()
3591
+	{
3592
+		$form = $this->_generate_global_settings_form();
3593
+		echo $form->form_open(
3594
+			$this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3595
+			'POST'
3596
+		)
3597
+			 . $form->get_html()
3598
+			 . $form->form_close();
3599
+	}
3600
+
3601
+
3602
+	/**
3603
+	 * This generates and returns the form object for the global messages settings.
3604
+	 *
3605
+	 * @return EE_Form_Section_Proper
3606
+	 * @throws EE_Error
3607
+	 * @throws InvalidArgumentException
3608
+	 * @throws ReflectionException
3609
+	 * @throws InvalidDataTypeException
3610
+	 * @throws InvalidInterfaceException
3611
+	 */
3612
+	protected function _generate_global_settings_form()
3613
+	{
3614
+		EE_Registry::instance()->load_helper('HTML');
3615
+		/** @var EE_Network_Core_Config $network_config */
3616
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3617
+
3618
+		return new EE_Form_Section_Proper(
3619
+			array(
3620
+				'name'            => 'global_messages_settings',
3621
+				'html_id'         => 'global_messages_settings',
3622
+				'html_class'      => 'form-table',
3623
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3624
+				'subsections'     => apply_filters(
3625
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3626
+					array(
3627
+						'do_messages_on_same_request' => new EE_Select_Input(
3628
+							array(
3629
+								true  => esc_html__("On the same request", "event_espresso"),
3630
+								false => esc_html__("On a separate request", "event_espresso"),
3631
+							),
3632
+							array(
3633
+								'default'         => $network_config->do_messages_on_same_request,
3634
+								'html_label_text' => esc_html__(
3635
+									'Generate and send all messages:',
3636
+									'event_espresso'
3637
+								),
3638
+								'html_help_text'  => esc_html__(
3639
+									'By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3640
+									'event_espresso'
3641
+								),
3642
+							)
3643
+						),
3644
+						'delete_threshold'            => new EE_Select_Input(
3645
+							array(
3646
+								0  => esc_html__('Forever', 'event_espresso'),
3647
+								3  => esc_html__('3 Months', 'event_espresso'),
3648
+								6  => esc_html__('6 Months', 'event_espresso'),
3649
+								9  => esc_html__('9 Months', 'event_espresso'),
3650
+								12 => esc_html__('12 Months', 'event_espresso'),
3651
+								24 => esc_html__('24 Months', 'event_espresso'),
3652
+								36 => esc_html__('36 Months', 'event_espresso'),
3653
+							),
3654
+							array(
3655
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3656
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3657
+								'html_help_text'  => esc_html__(
3658
+									'You can control how long a record of processed messages is kept via this option.',
3659
+									'event_espresso'
3660
+								),
3661
+							)
3662
+						),
3663
+						'update_settings'             => new EE_Submit_Input(
3664
+							array(
3665
+								'default'         => esc_html__('Update', 'event_espresso'),
3666
+								'html_label_text' => '&nbsp',
3667
+							)
3668
+						),
3669
+					)
3670
+				),
3671
+			)
3672
+		);
3673
+	}
3674
+
3675
+
3676
+	/**
3677
+	 * This handles updating the global settings set on the admin page.
3678
+	 *
3679
+	 * @throws EE_Error
3680
+	 * @throws InvalidDataTypeException
3681
+	 * @throws InvalidInterfaceException
3682
+	 * @throws InvalidArgumentException
3683
+	 * @throws ReflectionException
3684
+	 */
3685
+	protected function _update_global_settings()
3686
+	{
3687
+		/** @var EE_Network_Core_Config $network_config */
3688
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3689
+		$messages_config = EE_Registry::instance()->CFG->messages;
3690
+		$form = $this->_generate_global_settings_form();
3691
+		if ($form->was_submitted()) {
3692
+			$form->receive_form_submission();
3693
+			if ($form->is_valid()) {
3694
+				$valid_data = $form->valid_data();
3695
+				foreach ($valid_data as $property => $value) {
3696
+					$setter = 'set_' . $property;
3697
+					if (method_exists($network_config, $setter)) {
3698
+						$network_config->{$setter}($value);
3699
+					} elseif (
3700
+						property_exists($network_config, $property)
3701
+						&& $network_config->{$property} !== $value
3702
+					) {
3703
+						$network_config->{$property} = $value;
3704
+					} elseif (
3705
+						property_exists($messages_config, $property)
3706
+						&& $messages_config->{$property} !== $value
3707
+					) {
3708
+						$messages_config->{$property} = $value;
3709
+					}
3710
+				}
3711
+				// only update if the form submission was valid!
3712
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3713
+				EE_Registry::instance()->CFG->update_espresso_config();
3714
+				EE_Error::overwrite_success();
3715
+				EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3716
+			}
3717
+		}
3718
+		$this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3719
+	}
3720
+
3721
+
3722
+	/**
3723
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3724
+	 *
3725
+	 * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3726
+	 * @return string html formatted tabs
3727
+	 * @throws DomainException
3728
+	 */
3729
+	protected function _get_mt_tabs($tab_array)
3730
+	{
3731
+		$tab_array = (array) $tab_array;
3732
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3733
+		$tabs = '';
3734
+
3735
+		foreach ($tab_array as $tab) {
3736
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3737
+		}
3738
+
3739
+		return $tabs;
3740
+	}
3741
+
3742
+
3743
+	/**
3744
+	 * This prepares the content of the messenger meta box admin settings
3745
+	 *
3746
+	 * @param  EE_messenger $messenger The messenger we're setting up content for
3747
+	 * @return string html formatted content
3748
+	 * @throws DomainException
3749
+	 */
3750
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3751
+	{
3752
+
3753
+		$fields = $messenger->get_admin_settings_fields();
3754
+		$settings_template_args['template_form_fields'] = '';
3755
+
3756
+		// is $messenger active?
3757
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3758
+
3759
+
3760
+		if (! empty($fields)) {
3761
+			$existing_settings = $messenger->get_existing_admin_settings();
3762
+
3763
+			foreach ($fields as $fldname => $fldprops) {
3764
+				$field_id = $messenger->name . '-' . $fldname;
3765
+				$template_form_field[ $field_id ] = array(
3766
+					'name'       => 'messenger_settings[' . $field_id . ']',
3767
+					'label'      => $fldprops['label'],
3768
+					'input'      => $fldprops['field_type'],
3769
+					'type'       => $fldprops['value_type'],
3770
+					'required'   => $fldprops['required'],
3771
+					'validation' => $fldprops['validation'],
3772
+					'value'      => isset($existing_settings[ $field_id ])
3773
+						? $existing_settings[ $field_id ]
3774
+						: $fldprops['default'],
3775
+					'css_class'  => '',
3776
+					'format'     => $fldprops['format'],
3777
+				);
3778
+			}
3779
+
3780
+
3781
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3782
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3783
+				: '';
3784
+		}
3785
+
3786
+		// we also need some hidden fields
3787
+		$settings_template_args['hidden_fields'] = array(
3788
+			'messenger_settings[messenger]' => array(
3789
+				'type'  => 'hidden',
3790
+				'value' => $messenger->name,
3791
+			),
3792
+			'type'                          => array(
3793
+				'type'  => 'hidden',
3794
+				'value' => 'messenger',
3795
+			),
3796
+		);
3797
+
3798
+		// make sure any active message types that are existing are included in the hidden fields
3799
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3800
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3801
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3802
+					'type'  => 'hidden',
3803
+					'value' => $mt,
3804
+				);
3805
+			}
3806
+		}
3807
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3808
+			$settings_template_args['hidden_fields'],
3809
+			'array'
3810
+		);
3811
+		$active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3812
+
3813
+		$settings_template_args['messenger'] = $messenger->name;
3814
+		$settings_template_args['description'] = $messenger->description;
3815
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3816
+
3817
+
3818
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3819
+			$messenger->name
3820
+		)
3821
+			? $settings_template_args['show_hide_edit_form']
3822
+			: ' hidden';
3823
+
3824
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3825
+			? ' hidden'
3826
+			: $settings_template_args['show_hide_edit_form'];
3827
+
3828
+
3829
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3830
+		$settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3831
+		$settings_template_args['on_off_status'] = $active ? true : false;
3832
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3833
+		$content = EEH_Template::display_template(
3834
+			$template,
3835
+			$settings_template_args,
3836
+			true
3837
+		);
3838
+
3839
+		return $content;
3840
+	}
3841
+
3842
+
3843
+	/**
3844
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3845
+	 *
3846
+	 * @throws DomainException
3847
+	 * @throws EE_Error
3848
+	 * @throws InvalidDataTypeException
3849
+	 * @throws InvalidInterfaceException
3850
+	 * @throws InvalidArgumentException
3851
+	 * @throws ReflectionException
3852
+	 */
3853
+	public function activate_messenger_toggle()
3854
+	{
3855
+		$success = true;
3856
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3857
+		// let's check that we have required data
3858
+		if (! isset($this->_req_data['messenger'])) {
3859
+			EE_Error::add_error(
3860
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3861
+				__FILE__,
3862
+				__FUNCTION__,
3863
+				__LINE__
3864
+			);
3865
+			$success = false;
3866
+		}
3867
+
3868
+		// do a nonce check here since we're not arriving via a normal route
3869
+		$nonce = isset($this->_req_data['activate_nonce'])
3870
+			? sanitize_text_field($this->_req_data['activate_nonce'])
3871
+			: '';
3872
+		$nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3873
+
3874
+		$this->_verify_nonce($nonce, $nonce_ref);
3875
+
3876
+
3877
+		if (! isset($this->_req_data['status'])) {
3878
+			EE_Error::add_error(
3879
+				esc_html__(
3880
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3881
+					'event_espresso'
3882
+				),
3883
+				__FILE__,
3884
+				__FUNCTION__,
3885
+				__LINE__
3886
+			);
3887
+			$success = false;
3888
+		}
3889
+
3890
+		// do check to verify we have a valid status.
3891
+		$status = $this->_req_data['status'];
3892
+
3893
+		if ($status !== 'off' && $status !== 'on') {
3894
+			EE_Error::add_error(
3895
+				sprintf(
3896
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3897
+					$this->_req_data['status']
3898
+				),
3899
+				__FILE__,
3900
+				__FUNCTION__,
3901
+				__LINE__
3902
+			);
3903
+			$success = false;
3904
+		}
3905
+
3906
+		if ($success) {
3907
+			// made it here?  Stop dawdling then!!
3908
+			$success = $status === 'off'
3909
+				? $this->_deactivate_messenger($this->_req_data['messenger'])
3910
+				: $this->_activate_messenger($this->_req_data['messenger']);
3911
+		}
3912
+
3913
+		$this->_template_args['success'] = $success;
3914
+
3915
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
3916
+		$this->_return_json();
3917
+	}
3918
+
3919
+
3920
+	/**
3921
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3922
+	 *
3923
+	 * @throws DomainException
3924
+	 * @throws EE_Error
3925
+	 * @throws ReflectionException
3926
+	 * @throws InvalidDataTypeException
3927
+	 * @throws InvalidInterfaceException
3928
+	 * @throws InvalidArgumentException
3929
+	 */
3930
+	public function activate_mt_toggle()
3931
+	{
3932
+		$success = true;
3933
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3934
+
3935
+		// let's make sure we have the necessary data
3936
+		if (! isset($this->_req_data['message_type'])) {
3937
+			EE_Error::add_error(
3938
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3939
+				__FILE__,
3940
+				__FUNCTION__,
3941
+				__LINE__
3942
+			);
3943
+			$success = false;
3944
+		}
3945
+
3946
+		if (! isset($this->_req_data['messenger'])) {
3947
+			EE_Error::add_error(
3948
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3949
+				__FILE__,
3950
+				__FUNCTION__,
3951
+				__LINE__
3952
+			);
3953
+			$success = false;
3954
+		}
3955
+
3956
+		if (! isset($this->_req_data['status'])) {
3957
+			EE_Error::add_error(
3958
+				esc_html__(
3959
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3960
+					'event_espresso'
3961
+				),
3962
+				__FILE__,
3963
+				__FUNCTION__,
3964
+				__LINE__
3965
+			);
3966
+			$success = false;
3967
+		}
3968
+
3969
+
3970
+		// do check to verify we have a valid status.
3971
+		$status = $this->_req_data['status'];
3972
+
3973
+		if ($status !== 'activate' && $status !== 'deactivate') {
3974
+			EE_Error::add_error(
3975
+				sprintf(
3976
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3977
+					$this->_req_data['status']
3978
+				),
3979
+				__FILE__,
3980
+				__FUNCTION__,
3981
+				__LINE__
3982
+			);
3983
+			$success = false;
3984
+		}
3985
+
3986
+
3987
+		// do a nonce check here since we're not arriving via a normal route
3988
+		$nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3989
+		$nonce_ref = $this->_req_data['message_type'] . '_nonce';
3990
+
3991
+		$this->_verify_nonce($nonce, $nonce_ref);
3992
+
3993
+		if ($success) {
3994
+			// made it here? um, what are you waiting for then?
3995
+			$success = $status === 'deactivate'
3996
+				? $this->_deactivate_message_type_for_messenger(
3997
+					$this->_req_data['messenger'],
3998
+					$this->_req_data['message_type']
3999
+				)
4000
+				: $this->_activate_message_type_for_messenger(
4001
+					$this->_req_data['messenger'],
4002
+					$this->_req_data['message_type']
4003
+				);
4004
+		}
4005
+
4006
+		$this->_template_args['success'] = $success;
4007
+		$this->_return_json();
4008
+	}
4009
+
4010
+
4011
+	/**
4012
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
4013
+	 *
4014
+	 * @param string $messenger_name The name of the messenger being activated
4015
+	 * @return bool
4016
+	 * @throws DomainException
4017
+	 * @throws EE_Error
4018
+	 * @throws InvalidArgumentException
4019
+	 * @throws ReflectionException
4020
+	 * @throws InvalidDataTypeException
4021
+	 * @throws InvalidInterfaceException
4022
+	 */
4023
+	protected function _activate_messenger($messenger_name)
4024
+	{
4025
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4026
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4027
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
4028
+			? $active_messenger->get_default_message_types()
4029
+			: array();
4030
+
4031
+		// ensure is active
4032
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4033
+
4034
+		// set response_data for reload
4035
+		foreach ($message_types_to_activate as $message_type_name) {
4036
+			/** @var EE_message_type $message_type */
4037
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4038
+			if (
4039
+				$this->_message_resource_manager->is_message_type_active_for_messenger(
4040
+					$messenger_name,
4041
+					$message_type_name
4042
+				)
4043
+				&& $message_type instanceof EE_message_type
4044
+			) {
4045
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
4046
+				if ($message_type->get_admin_settings_fields()) {
4047
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
4048
+				}
4049
+			}
4050
+		}
4051
+
4052
+		// add success message for activating messenger
4053
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4054
+	}
4055
+
4056
+
4057
+	/**
4058
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
4059
+	 *
4060
+	 * @param string $messenger_name The name of the messenger being activated
4061
+	 * @return bool
4062
+	 * @throws DomainException
4063
+	 * @throws EE_Error
4064
+	 * @throws InvalidArgumentException
4065
+	 * @throws ReflectionException
4066
+	 * @throws InvalidDataTypeException
4067
+	 * @throws InvalidInterfaceException
4068
+	 */
4069
+	protected function _deactivate_messenger($messenger_name)
4070
+	{
4071
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4072
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4073
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
4074
+
4075
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4076
+	}
4077
+
4078
+
4079
+	/**
4080
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4081
+	 *
4082
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
4083
+	 * @param string $message_type_name The name of the message type being activated for the messenger
4084
+	 * @return bool
4085
+	 * @throws DomainException
4086
+	 * @throws EE_Error
4087
+	 * @throws InvalidArgumentException
4088
+	 * @throws ReflectionException
4089
+	 * @throws InvalidDataTypeException
4090
+	 * @throws InvalidInterfaceException
4091
+	 */
4092
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4093
+	{
4094
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4095
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4096
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4097
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4098
+
4099
+		// ensure is active
4100
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4101
+
4102
+		// set response for load
4103
+		if (
4104
+			$this->_message_resource_manager->is_message_type_active_for_messenger(
4105
+				$messenger_name,
4106
+				$message_type_name
4107
+			)
4108
+		) {
4109
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
4110
+			if ($message_type_to_activate->get_admin_settings_fields()) {
4111
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
4112
+			}
4113
+		}
4114
+
4115
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
4116
+			$active_messenger,
4117
+			$message_type_to_activate
4118
+		);
4119
+	}
4120
+
4121
+
4122
+	/**
4123
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4124
+	 *
4125
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4126
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
4127
+	 * @return bool
4128
+	 * @throws DomainException
4129
+	 * @throws EE_Error
4130
+	 * @throws InvalidArgumentException
4131
+	 * @throws ReflectionException
4132
+	 * @throws InvalidDataTypeException
4133
+	 * @throws InvalidInterfaceException
4134
+	 */
4135
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4136
+	{
4137
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4138
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4139
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4140
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4141
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4142
+
4143
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4144
+			$active_messenger,
4145
+			$message_type_to_deactivate
4146
+		);
4147
+	}
4148
+
4149
+
4150
+	/**
4151
+	 * This just initializes the defaults for activating messenger and message type responses.
4152
+	 */
4153
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
4154
+	{
4155
+		$this->_template_args['data']['active_mts'] = array();
4156
+		$this->_template_args['data']['mt_reload'] = array();
4157
+	}
4158
+
4159
+
4160
+	/**
4161
+	 * Setup appropriate response for activating a messenger and/or message types
4162
+	 *
4163
+	 * @param EE_messenger         $messenger
4164
+	 * @param EE_message_type|null $message_type
4165
+	 * @return bool
4166
+	 * @throws DomainException
4167
+	 * @throws EE_Error
4168
+	 * @throws InvalidArgumentException
4169
+	 * @throws ReflectionException
4170
+	 * @throws InvalidDataTypeException
4171
+	 * @throws InvalidInterfaceException
4172
+	 */
4173
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
4174
+		$messenger,
4175
+		EE_Message_Type $message_type = null
4176
+	) {
4177
+		// if $messenger isn't a valid messenger object then get out.
4178
+		if (! $messenger instanceof EE_Messenger) {
4179
+			EE_Error::add_error(
4180
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4181
+				__FILE__,
4182
+				__FUNCTION__,
4183
+				__LINE__
4184
+			);
4185
+
4186
+			return false;
4187
+		}
4188
+		// activated
4189
+		if ($this->_template_args['data']['active_mts']) {
4190
+			EE_Error::overwrite_success();
4191
+			// activated a message type with the messenger
4192
+			if ($message_type instanceof EE_message_type) {
4193
+				EE_Error::add_success(
4194
+					sprintf(
4195
+						esc_html__(
4196
+							'%s message type has been successfully activated with the %s messenger',
4197
+							'event_espresso'
4198
+						),
4199
+						ucwords($message_type->label['singular']),
4200
+						ucwords($messenger->label['singular'])
4201
+					)
4202
+				);
4203
+
4204
+				// if message type was invoice then let's make sure we activate the invoice payment method.
4205
+				if ($message_type->name === 'invoice') {
4206
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
4207
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4208
+					if ($pm instanceof EE_Payment_Method) {
4209
+						EE_Error::add_attention(
4210
+							esc_html__(
4211
+								'Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
4212
+								'event_espresso'
4213
+							)
4214
+						);
4215
+					}
4216
+				}
4217
+				// just toggles the entire messenger
4218
+			} else {
4219
+				EE_Error::add_success(
4220
+					sprintf(
4221
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4222
+						ucwords($messenger->label['singular'])
4223
+					)
4224
+				);
4225
+			}
4226
+
4227
+			return true;
4228
+
4229
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4230
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4231
+			// in which case we just give a success message for the messenger being successfully activated.
4232
+		} else {
4233
+			if (! $messenger->get_default_message_types()) {
4234
+				// messenger doesn't have any default message types so still a success.
4235
+				EE_Error::add_success(
4236
+					sprintf(
4237
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4238
+						ucwords($messenger->label['singular'])
4239
+					)
4240
+				);
4241
+
4242
+				return true;
4243
+			} else {
4244
+				EE_Error::add_error(
4245
+					$message_type instanceof EE_message_type
4246
+						? sprintf(
4247
+							esc_html__(
4248
+								'%s message type was not successfully activated with the %s messenger',
4249
+								'event_espresso'
4250
+							),
4251
+							ucwords($message_type->label['singular']),
4252
+							ucwords($messenger->label['singular'])
4253
+						)
4254
+						: sprintf(
4255
+							esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4256
+							ucwords($messenger->label['singular'])
4257
+						),
4258
+					__FILE__,
4259
+					__FUNCTION__,
4260
+					__LINE__
4261
+				);
4262
+
4263
+				return false;
4264
+			}
4265
+		}
4266
+	}
4267
+
4268
+
4269
+	/**
4270
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
4271
+	 *
4272
+	 * @param EE_messenger         $messenger
4273
+	 * @param EE_message_type|null $message_type
4274
+	 * @return bool
4275
+	 * @throws DomainException
4276
+	 * @throws EE_Error
4277
+	 * @throws InvalidArgumentException
4278
+	 * @throws ReflectionException
4279
+	 * @throws InvalidDataTypeException
4280
+	 * @throws InvalidInterfaceException
4281
+	 */
4282
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4283
+		$messenger,
4284
+		EE_message_type $message_type = null
4285
+	) {
4286
+		EE_Error::overwrite_success();
4287
+
4288
+		// if $messenger isn't a valid messenger object then get out.
4289
+		if (! $messenger instanceof EE_Messenger) {
4290
+			EE_Error::add_error(
4291
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4292
+				__FILE__,
4293
+				__FUNCTION__,
4294
+				__LINE__
4295
+			);
4296
+
4297
+			return false;
4298
+		}
4299
+
4300
+		if ($message_type instanceof EE_message_type) {
4301
+			$message_type_name = $message_type->name;
4302
+			EE_Error::add_success(
4303
+				sprintf(
4304
+					esc_html__(
4305
+						'%s message type has been successfully deactivated for the %s messenger.',
4306
+						'event_espresso'
4307
+					),
4308
+					ucwords($message_type->label['singular']),
4309
+					ucwords($messenger->label['singular'])
4310
+				)
4311
+			);
4312
+		} else {
4313
+			$message_type_name = '';
4314
+			EE_Error::add_success(
4315
+				sprintf(
4316
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4317
+					ucwords($messenger->label['singular'])
4318
+				)
4319
+			);
4320
+		}
4321
+
4322
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4323
+		if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4324
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
4325
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4326
+			if ($count_updated > 0) {
4327
+				$msg = $message_type_name === 'invoice'
4328
+					? esc_html__(
4329
+						'Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
4330
+						'event_espresso'
4331
+					)
4332
+					: esc_html__(
4333
+						'Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
4334
+						'event_espresso'
4335
+					);
4336
+				EE_Error::add_attention($msg);
4337
+			}
4338
+		}
4339
+
4340
+		return true;
4341
+	}
4342
+
4343
+
4344
+	/**
4345
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4346
+	 *
4347
+	 * @throws DomainException
4348
+	 */
4349
+	public function update_mt_form()
4350
+	{
4351
+		if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4352
+			EE_Error::add_error(
4353
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4354
+				__FILE__,
4355
+				__FUNCTION__,
4356
+				__LINE__
4357
+			);
4358
+			$this->_return_json();
4359
+		}
4360
+
4361
+		$message_types = $this->get_installed_message_types();
4362
+
4363
+		$message_type = $message_types[ $this->_req_data['message_type'] ];
4364
+		$messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4365
+
4366
+		$content = $this->_message_type_settings_content(
4367
+			$message_type,
4368
+			$messenger,
4369
+			true
4370
+		);
4371
+		$this->_template_args['success'] = true;
4372
+		$this->_template_args['content'] = $content;
4373
+		$this->_return_json();
4374
+	}
4375
+
4376
+
4377
+	/**
4378
+	 * this handles saving the settings for a messenger or message type
4379
+	 *
4380
+	 */
4381
+	public function save_settings()
4382
+	{
4383
+		if (! isset($this->_req_data['type'])) {
4384
+			EE_Error::add_error(
4385
+				esc_html__(
4386
+					'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4387
+					'event_espresso'
4388
+				),
4389
+				__FILE__,
4390
+				__FUNCTION__,
4391
+				__LINE__
4392
+			);
4393
+			$this->_template_args['error'] = true;
4394
+			$this->_return_json();
4395
+		}
4396
+
4397
+
4398
+		if ($this->_req_data['type'] === 'messenger') {
4399
+			// this should be an array.
4400
+			$settings = $this->_req_data['messenger_settings'];
4401
+			$messenger = $settings['messenger'];
4402
+			// let's setup the settings data
4403
+			foreach ($settings as $key => $value) {
4404
+				switch ($key) {
4405
+					case 'messenger':
4406
+						unset($settings['messenger']);
4407
+						break;
4408
+					case 'message_types':
4409
+						unset($settings['message_types']);
4410
+						break;
4411
+					default:
4412
+						$settings[ $key ] = $value;
4413
+						break;
4414
+				}
4415
+			}
4416
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4417
+		} elseif ($this->_req_data['type'] === 'message_type') {
4418
+			$settings = $this->_req_data['message_type_settings'];
4419
+			$messenger = $settings['messenger'];
4420
+			$message_type = $settings['message_type'];
4421
+
4422
+			foreach ($settings as $key => $value) {
4423
+				switch ($key) {
4424
+					case 'messenger':
4425
+						unset($settings['messenger']);
4426
+						break;
4427
+					case 'message_type':
4428
+						unset($settings['message_type']);
4429
+						break;
4430
+					default:
4431
+						$settings[ $key ] = $value;
4432
+						break;
4433
+				}
4434
+			}
4435
+
4436
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4437
+		}
4438
+
4439
+		// okay we should have the data all setup.  Now we just update!
4440
+		$success = $this->_message_resource_manager->update_active_messengers_option();
4441
+
4442
+		if ($success) {
4443
+			EE_Error::add_success(__('Settings updated', 'event_espresso'));
4444
+		} else {
4445
+			EE_Error::add_error(
4446
+				esc_html__(
4447
+					'Settings did not get updated',
4448
+					'event_espresso'
4449
+				),
4450
+				__FILE__,
4451
+				__FUNCTION__,
4452
+				__LINE__
4453
+			);
4454
+		}
4455
+
4456
+		$this->_template_args['success'] = $success;
4457
+		$this->_return_json();
4458
+	}
4459
+
4460
+
4461
+
4462
+
4463
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4464
+
4465
+
4466
+	/**
4467
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4468
+	 * However, this does not send immediately, it just queues for sending.
4469
+	 *
4470
+	 * @since 4.9.0
4471
+	 * @throws EE_Error
4472
+	 * @throws InvalidDataTypeException
4473
+	 * @throws InvalidInterfaceException
4474
+	 * @throws InvalidArgumentException
4475
+	 * @throws ReflectionException
4476
+	 */
4477
+	protected function _generate_now()
4478
+	{
4479
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4480
+		$this->_redirect_after_action(false, '', '', array(), true);
4481
+	}
4482
+
4483
+
4484
+	/**
4485
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4486
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4487
+	 *
4488
+	 * @since 4.9.0
4489
+	 * @throws EE_Error
4490
+	 * @throws InvalidDataTypeException
4491
+	 * @throws InvalidInterfaceException
4492
+	 * @throws InvalidArgumentException
4493
+	 * @throws ReflectionException
4494
+	 */
4495
+	protected function _generate_and_send_now()
4496
+	{
4497
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4498
+		$this->_redirect_after_action(false, '', '', array(), true);
4499
+	}
4500
+
4501
+
4502
+	/**
4503
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4504
+	 *
4505
+	 * @since 4.9.0
4506
+	 * @throws EE_Error
4507
+	 * @throws InvalidDataTypeException
4508
+	 * @throws InvalidInterfaceException
4509
+	 * @throws InvalidArgumentException
4510
+	 * @throws ReflectionException
4511
+	 */
4512
+	protected function _queue_for_resending()
4513
+	{
4514
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4515
+		$this->_redirect_after_action(false, '', '', array(), true);
4516
+	}
4517
+
4518
+
4519
+	/**
4520
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4521
+	 *
4522
+	 * @since 4.9.0
4523
+	 * @throws EE_Error
4524
+	 * @throws InvalidDataTypeException
4525
+	 * @throws InvalidInterfaceException
4526
+	 * @throws InvalidArgumentException
4527
+	 * @throws ReflectionException
4528
+	 */
4529
+	protected function _send_now()
4530
+	{
4531
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4532
+		$this->_redirect_after_action(false, '', '', array(), true);
4533
+	}
4534
+
4535
+
4536
+	/**
4537
+	 * Deletes EE_messages for IDs in the request.
4538
+	 *
4539
+	 * @since 4.9.0
4540
+	 * @throws EE_Error
4541
+	 * @throws InvalidDataTypeException
4542
+	 * @throws InvalidInterfaceException
4543
+	 * @throws InvalidArgumentException
4544
+	 */
4545
+	protected function _delete_ee_messages()
4546
+	{
4547
+		$msg_ids = $this->_get_msg_ids_from_request();
4548
+		$deleted_count = 0;
4549
+		foreach ($msg_ids as $msg_id) {
4550
+			if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4551
+				$deleted_count++;
4552
+			}
4553
+		}
4554
+		if ($deleted_count) {
4555
+			EE_Error::add_success(
4556
+				esc_html(
4557
+					_n(
4558
+						'Message successfully deleted',
4559
+						'Messages successfully deleted',
4560
+						$deleted_count,
4561
+						'event_espresso'
4562
+					)
4563
+				)
4564
+			);
4565
+			$this->_redirect_after_action(
4566
+				false,
4567
+				'',
4568
+				'',
4569
+				array(),
4570
+				true
4571
+			);
4572
+		} else {
4573
+			EE_Error::add_error(
4574
+				_n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4575
+				__FILE__,
4576
+				__FUNCTION__,
4577
+				__LINE__
4578
+			);
4579
+			$this->_redirect_after_action(false, '', '', array(), true);
4580
+		}
4581
+	}
4582
+
4583
+
4584
+	/**
4585
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4586
+	 *
4587
+	 * @since 4.9.0
4588
+	 * @return array
4589
+	 */
4590
+	protected function _get_msg_ids_from_request()
4591
+	{
4592
+		if (! isset($this->_req_data['MSG_ID'])) {
4593
+			return array();
4594
+		}
4595
+
4596
+		return is_array($this->_req_data['MSG_ID'])
4597
+			? array_keys($this->_req_data['MSG_ID'])
4598
+			: array($this->_req_data['MSG_ID']);
4599
+	}
4600 4600
 }
Please login to merge, or discard this patch.
languages/event_espresso-translations-js.php 1 patch
Spacing   +599 added lines, -599 removed lines patch added patch discarded remove patch
@@ -2,226 +2,226 @@  discard block
 block discarded – undo
2 2
 /* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */
3 3
 $generated_i18n_strings = array(
4 4
 	// Reference: packages/ui-components/src/Pagination/constants.ts:6
5
-	__( '2', 'event_espresso' ),
5
+	__('2', 'event_espresso'),
6 6
 
7 7
 	// Reference: packages/ui-components/src/Pagination/constants.ts:7
8
-	__( '6', 'event_espresso' ),
8
+	__('6', 'event_espresso'),
9 9
 
10 10
 	// Reference: packages/ui-components/src/Pagination/constants.ts:8
11
-	__( '12', 'event_espresso' ),
11
+	__('12', 'event_espresso'),
12 12
 
13 13
 	// Reference: packages/ui-components/src/Pagination/constants.ts:9
14
-	__( '24', 'event_espresso' ),
14
+	__('24', 'event_espresso'),
15 15
 
16 16
 	// Reference: packages/ui-components/src/Pagination/constants.ts:10
17
-	__( '48', 'event_espresso' ),
17
+	__('48', 'event_espresso'),
18 18
 
19 19
 	// Reference: domains/core/admin/blocks/src/components/AvatarImage.tsx:27
20
-	__( 'contact avatar', 'event_espresso' ),
20
+	__('contact avatar', 'event_espresso'),
21 21
 
22 22
 	// Reference: domains/core/admin/blocks/src/components/OrderByControl.tsx:12
23
-	__( 'Order by', 'event_espresso' ),
23
+	__('Order by', 'event_espresso'),
24 24
 
25 25
 	// Reference: domains/core/admin/blocks/src/components/RegStatusControl.tsx:17
26 26
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectStatus.tsx:13
27
-	__( 'Select Registration Status', 'event_espresso' ),
27
+	__('Select Registration Status', 'event_espresso'),
28 28
 
29 29
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:14
30
-	__( 'Ascending', 'event_espresso' ),
30
+	__('Ascending', 'event_espresso'),
31 31
 
32 32
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:18
33
-	__( 'Descending', 'event_espresso' ),
33
+	__('Descending', 'event_espresso'),
34 34
 
35 35
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:24
36
-	__( 'Sort order:', 'event_espresso' ),
36
+	__('Sort order:', 'event_espresso'),
37 37
 
38 38
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:41
39
-	__( 'There was some error fetching attendees list', 'event_espresso' ),
39
+	__('There was some error fetching attendees list', 'event_espresso'),
40 40
 
41 41
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:47
42
-	__( 'To get started, select what event you want to show attendees from in the block settings.', 'event_espresso' ),
42
+	__('To get started, select what event you want to show attendees from in the block settings.', 'event_espresso'),
43 43
 
44 44
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:53
45
-	__( 'There are no attendees for selected options.', 'event_espresso' ),
45
+	__('There are no attendees for selected options.', 'event_espresso'),
46 46
 
47 47
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:12
48
-	__( 'Display on Archives', 'event_espresso' ),
48
+	__('Display on Archives', 'event_espresso'),
49 49
 
50 50
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:17
51
-	__( 'Attendees are shown whenever this post is listed in an archive view.', 'event_espresso' ),
51
+	__('Attendees are shown whenever this post is listed in an archive view.', 'event_espresso'),
52 52
 
53 53
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:18
54
-	__( 'Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso' ),
54
+	__('Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso'),
55 55
 
56 56
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:29
57
-	__( 'Number of Attendees to Display:', 'event_espresso' ),
57
+	__('Number of Attendees to Display:', 'event_espresso'),
58 58
 
59 59
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:34
60 60
 	/* translators: %d attendees count */
61
-	_n_noop( 'Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso' ),
61
+	_n_noop('Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso'),
62 62
 
63 63
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:27
64
-	__( 'Display Gravatar', 'event_espresso' ),
64
+	__('Display Gravatar', 'event_espresso'),
65 65
 
66 66
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:32
67
-	__( 'Gravatar images are shown for each attendee.', 'event_espresso' ),
67
+	__('Gravatar images are shown for each attendee.', 'event_espresso'),
68 68
 
69 69
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:33
70
-	__( 'No gravatar images are shown for each attendee.', 'event_espresso' ),
70
+	__('No gravatar images are shown for each attendee.', 'event_espresso'),
71 71
 
72 72
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:38
73
-	__( 'Size of Gravatar', 'event_espresso' ),
73
+	__('Size of Gravatar', 'event_espresso'),
74 74
 
75 75
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectDatetime.tsx:22
76
-	__( 'Select Datetime', 'event_espresso' ),
76
+	__('Select Datetime', 'event_espresso'),
77 77
 
78 78
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectEvent.tsx:22
79
-	__( 'Select Event', 'event_espresso' ),
79
+	__('Select Event', 'event_espresso'),
80 80
 
81 81
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:11
82
-	__( 'Attendee id', 'event_espresso' ),
82
+	__('Attendee id', 'event_espresso'),
83 83
 
84 84
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:15
85
-	__( 'Last name only', 'event_espresso' ),
85
+	__('Last name only', 'event_espresso'),
86 86
 
87 87
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:19
88
-	__( 'First name only', 'event_espresso' ),
88
+	__('First name only', 'event_espresso'),
89 89
 
90 90
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:23
91
-	__( 'First, then Last name', 'event_espresso' ),
91
+	__('First, then Last name', 'event_espresso'),
92 92
 
93 93
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:27
94
-	__( 'Last, then First name', 'event_espresso' ),
94
+	__('Last, then First name', 'event_espresso'),
95 95
 
96 96
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:41
97
-	__( 'Order Attendees by:', 'event_espresso' ),
97
+	__('Order Attendees by:', 'event_espresso'),
98 98
 
99 99
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectTicket.tsx:22
100
-	__( 'Select Ticket', 'event_espresso' ),
100
+	__('Select Ticket', 'event_espresso'),
101 101
 
102 102
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:21
103
-	__( 'Filter By Settings', 'event_espresso' ),
103
+	__('Filter By Settings', 'event_espresso'),
104 104
 
105 105
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:36
106
-	__( 'Gravatar Setttings', 'event_espresso' ),
106
+	__('Gravatar Setttings', 'event_espresso'),
107 107
 
108 108
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:39
109
-	__( 'Archive Settings', 'event_espresso' ),
109
+	__('Archive Settings', 'event_espresso'),
110 110
 
111 111
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:10
112
-	__( 'Event Attendees', 'event_espresso' ),
112
+	__('Event Attendees', 'event_espresso'),
113 113
 
114 114
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:11
115
-	__( 'Displays a list of people that have registered for the specified event', 'event_espresso' ),
115
+	__('Displays a list of people that have registered for the specified event', 'event_espresso'),
116 116
 
117 117
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
118
-	__( 'event', 'event_espresso' ),
118
+	__('event', 'event_espresso'),
119 119
 
120 120
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
121
-	__( 'attendees', 'event_espresso' ),
121
+	__('attendees', 'event_espresso'),
122 122
 
123 123
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
124
-	__( 'list', 'event_espresso' ),
124
+	__('list', 'event_espresso'),
125 125
 
126 126
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:17
127
-	__( 'Error', 'event_espresso' ),
127
+	__('Error', 'event_espresso'),
128 128
 
129 129
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:24
130 130
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityTemplate.tsx:16
131
-	__( 'Select…', 'event_espresso' ),
131
+	__('Select…', 'event_espresso'),
132 132
 
133 133
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:9
134
-	__( 'Loading…', 'event_espresso' ),
134
+	__('Loading…', 'event_espresso'),
135 135
 
136 136
 	// Reference: domains/core/admin/eventEditor/src/ui/EventDescription.tsx:33
137
-	__( 'Event Description', 'event_espresso' ),
137
+	__('Event Description', 'event_espresso'),
138 138
 
139 139
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/ActiveStatus.tsx:22
140
-	__( 'Active status', 'event_espresso' ),
140
+	__('Active status', 'event_espresso'),
141 141
 
142 142
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/AltRegPage.tsx:14
143
-	__( 'Alternative Registration Page', 'event_espresso' ),
143
+	__('Alternative Registration Page', 'event_espresso'),
144 144
 
145 145
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/DefaultRegistrationStatus.tsx:15
146
-	__( 'Default Registration Status', 'event_espresso' ),
146
+	__('Default Registration Status', 'event_espresso'),
147 147
 
148 148
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:9
149
-	__( 'Donations Enabled', 'event_espresso' ),
149
+	__('Donations Enabled', 'event_espresso'),
150 150
 
151 151
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:9
152
-	__( 'Donations Disabled', 'event_espresso' ),
152
+	__('Donations Disabled', 'event_espresso'),
153 153
 
154 154
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventManager.tsx:16
155
-	__( 'Event Manager', 'event_espresso' ),
155
+	__('Event Manager', 'event_espresso'),
156 156
 
157 157
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventPhoneNumber.tsx:11
158
-	__( 'Event Phone Number', 'event_espresso' ),
158
+	__('Event Phone Number', 'event_espresso'),
159 159
 
160 160
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/MaxRegistrations.tsx:12
161
-	__( 'Max Registrations per Transaction', 'event_espresso' ),
161
+	__('Max Registrations per Transaction', 'event_espresso'),
162 162
 
163 163
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:9
164
-	__( 'Ticket Selector Enabled', 'event_espresso' ),
164
+	__('Ticket Selector Enabled', 'event_espresso'),
165 165
 
166 166
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:9
167
-	__( 'Ticket Selector Disabled', 'event_espresso' ),
167
+	__('Ticket Selector Disabled', 'event_espresso'),
168 168
 
169 169
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/index.tsx:43
170
-	__( 'Registration Options', 'event_espresso' ),
170
+	__('Registration Options', 'event_espresso'),
171 171
 
172 172
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/DateRegistrationsLink.tsx:13
173
-	__( 'view ALL registrations for this date.', 'event_espresso' ),
173
+	__('view ALL registrations for this date.', 'event_espresso'),
174 174
 
175 175
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
176
-	__( 'primary information about the date', 'event_espresso' ),
176
+	__('primary information about the date', 'event_espresso'),
177 177
 
178 178
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
179
-	__( 'Date Details', 'event_espresso' ),
179
+	__('Date Details', 'event_espresso'),
180 180
 
181 181
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
182 182
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
183 183
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
184
-	__( 'relations between tickets and dates', 'event_espresso' ),
184
+	__('relations between tickets and dates', 'event_espresso'),
185 185
 
186 186
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
187
-	__( 'Assign Tickets', 'event_espresso' ),
187
+	__('Assign Tickets', 'event_espresso'),
188 188
 
189 189
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/FooterButtons.tsx:22
190
-	__( 'Save and assign tickets', 'event_espresso' ),
190
+	__('Save and assign tickets', 'event_espresso'),
191 191
 
192 192
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:27
193 193
 	/* translators: %s datetime id */
194
-	__( 'Edit datetime %s', 'event_espresso' ),
194
+	__('Edit datetime %s', 'event_espresso'),
195 195
 
196 196
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:30
197
-	__( 'New Datetime', 'event_espresso' ),
197
+	__('New Datetime', 'event_espresso'),
198 198
 
199 199
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:110
200 200
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:108
201 201
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:126
202 202
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:108
203
-	__( 'Details', 'event_espresso' ),
203
+	__('Details', 'event_espresso'),
204 204
 
205 205
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:114
206 206
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:112
207 207
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:81
208
-	__( 'Capacity', 'event_espresso' ),
208
+	__('Capacity', 'event_espresso'),
209 209
 
210 210
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:119
211
-	__( 'The maximum number of registrants that can attend the event at this particular date.', 'event_espresso' ),
211
+	__('The maximum number of registrants that can attend the event at this particular date.', 'event_espresso'),
212 212
 
213 213
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:123
214
-	__( 'Set to 0 to close registration or leave blank for no limit.', 'event_espresso' ),
214
+	__('Set to 0 to close registration or leave blank for no limit.', 'event_espresso'),
215 215
 
216 216
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:129
217 217
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:203
218
-	__( 'Trash', 'event_espresso' ),
218
+	__('Trash', 'event_espresso'),
219 219
 
220 220
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:71
221 221
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:45
222 222
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:87
223 223
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:45
224
-	__( 'Basics', 'event_espresso' ),
224
+	__('Basics', 'event_espresso'),
225 225
 
226 226
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:75
227 227
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:49
@@ -229,249 +229,249 @@  discard block
 block discarded – undo
229 229
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:91
230 230
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:49
231 231
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:40
232
-	__( 'Name', 'event_espresso' ),
232
+	__('Name', 'event_espresso'),
233 233
 
234 234
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:80
235 235
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:55
236 236
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:96
237 237
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:55
238 238
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:47
239
-	__( 'Description', 'event_espresso' ),
239
+	__('Description', 'event_espresso'),
240 240
 
241 241
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:88
242 242
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:63
243 243
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:63
244
-	__( 'Dates', 'event_espresso' ),
244
+	__('Dates', 'event_espresso'),
245 245
 
246 246
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:92
247 247
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:51
248 248
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:108
249
-	__( 'Start Date', 'event_espresso' ),
249
+	__('Start Date', 'event_espresso'),
250 250
 
251 251
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:99
252 252
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:65
253 253
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:115
254
-	__( 'End Date', 'event_espresso' ),
254
+	__('End Date', 'event_espresso'),
255 255
 
256 256
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:35
257 257
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/TableView.tsx:33
258
-	__( 'Event Dates', 'event_espresso' ),
258
+	__('Event Dates', 'event_espresso'),
259 259
 
260 260
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:38
261
-	__( 'loading event dates…', 'event_espresso' ),
261
+	__('loading event dates…', 'event_espresso'),
262 262
 
263 263
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:20
264
-	__( 'Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso' ),
264
+	__('Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso'),
265 265
 
266 266
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:30
267
-	__( 'Ticket Assignments', 'event_espresso' ),
267
+	__('Ticket Assignments', 'event_espresso'),
268 268
 
269 269
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:25
270
-	__( 'Number of related tickets', 'event_espresso' ),
270
+	__('Number of related tickets', 'event_espresso'),
271 271
 
272 272
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:26
273
-	__( 'There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso' ),
273
+	__('There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso'),
274 274
 
275 275
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:34
276
-	__( 'assign tickets', 'event_espresso' ),
276
+	__('assign tickets', 'event_espresso'),
277 277
 
278 278
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:25
279
-	__( 'Permanently delete Datetime?', 'event_espresso' ),
279
+	__('Permanently delete Datetime?', 'event_espresso'),
280 280
 
281 281
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:25
282
-	__( 'Move Datetime to Trash?', 'event_espresso' ),
282
+	__('Move Datetime to Trash?', 'event_espresso'),
283 283
 
284 284
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:27
285
-	__( 'Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso' ),
285
+	__('Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso'),
286 286
 
287 287
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:30
288
-	__( 'Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso' ),
288
+	__('Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso'),
289 289
 
290 290
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:39
291 291
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:44
292
-	__( 'delete permanently', 'event_espresso' ),
292
+	__('delete permanently', 'event_espresso'),
293 293
 
294 294
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:39
295
-	__( 'trash datetime', 'event_espresso' ),
295
+	__('trash datetime', 'event_espresso'),
296 296
 
297 297
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:45
298
-	__( 'event date main menu', 'event_espresso' ),
298
+	__('event date main menu', 'event_espresso'),
299 299
 
300 300
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:59
301
-	__( 'edit datetime', 'event_espresso' ),
301
+	__('edit datetime', 'event_espresso'),
302 302
 
303 303
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:60
304
-	__( 'copy datetime', 'event_espresso' ),
304
+	__('copy datetime', 'event_espresso'),
305 305
 
306 306
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:36
307 307
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:39
308 308
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:43
309
-	__( 'bulk actions', 'event_espresso' ),
309
+	__('bulk actions', 'event_espresso'),
310 310
 
311 311
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:40
312
-	__( 'edit datetime details', 'event_espresso' ),
312
+	__('edit datetime details', 'event_espresso'),
313 313
 
314 314
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
315
-	__( 'delete datetimes', 'event_espresso' ),
315
+	__('delete datetimes', 'event_espresso'),
316 316
 
317 317
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
318
-	__( 'trash datetimes', 'event_espresso' ),
318
+	__('trash datetimes', 'event_espresso'),
319 319
 
320 320
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:14
321
-	__( 'Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso' ),
321
+	__('Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso'),
322 322
 
323 323
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
324
-	__( 'Are you sure you want to trash these datetimes?', 'event_espresso' ),
324
+	__('Are you sure you want to trash these datetimes?', 'event_espresso'),
325 325
 
326 326
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
327
-	__( 'Delete datetimes permanently', 'event_espresso' ),
327
+	__('Delete datetimes permanently', 'event_espresso'),
328 328
 
329 329
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
330
-	__( 'Trash datetimes', 'event_espresso' ),
330
+	__('Trash datetimes', 'event_espresso'),
331 331
 
332 332
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:21
333
-	__( 'Bulk edit date details', 'event_espresso' ),
333
+	__('Bulk edit date details', 'event_espresso'),
334 334
 
335 335
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:22
336
-	__( 'any changes will be applied to ALL of the selected dates.', 'event_espresso' ),
336
+	__('any changes will be applied to ALL of the selected dates.', 'event_espresso'),
337 337
 
338 338
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/formValidation.ts:12
339 339
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/formValidation.ts:12
340
-	__( 'Name must be at least three characters', 'event_espresso' ),
340
+	__('Name must be at least three characters', 'event_espresso'),
341 341
 
342 342
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:67
343 343
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:67
344
-	__( 'Shift dates', 'event_espresso' ),
344
+	__('Shift dates', 'event_espresso'),
345 345
 
346 346
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:92
347 347
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:92
348
-	__( 'earlier', 'event_espresso' ),
348
+	__('earlier', 'event_espresso'),
349 349
 
350 350
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:96
351 351
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:96
352
-	__( 'later', 'event_espresso' ),
352
+	__('later', 'event_espresso'),
353 353
 
354 354
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCapacity.tsx:37
355
-	__( 'edit capacity (registration limit)…', 'event_espresso' ),
355
+	__('edit capacity (registration limit)…', 'event_espresso'),
356 356
 
357 357
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:38
358
-	__( 'Edit Event Date', 'event_espresso' ),
358
+	__('Edit Event Date', 'event_espresso'),
359 359
 
360 360
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:42
361
-	__( 'edit start and end dates', 'event_espresso' ),
361
+	__('edit start and end dates', 'event_espresso'),
362 362
 
363 363
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:15
364 364
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:15
365
-	__( 'sold', 'event_espresso' ),
365
+	__('sold', 'event_espresso'),
366 366
 
367 367
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:28
368
-	__( 'capacity', 'event_espresso' ),
368
+	__('capacity', 'event_espresso'),
369 369
 
370 370
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:34
371 371
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:33
372
-	__( 'reg list', 'event_espresso' ),
372
+	__('reg list', 'event_espresso'),
373 373
 
374 374
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:46
375 375
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:45
376
-	__( 'Edit description', 'event_espresso' ),
376
+	__('Edit description', 'event_espresso'),
377 377
 
378 378
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:47
379 379
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:46
380
-	__( 'edit description…', 'event_espresso' ),
380
+	__('edit description…', 'event_espresso'),
381 381
 
382 382
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:10
383
-	__( 'Move Date to Trash', 'event_espresso' ),
383
+	__('Move Date to Trash', 'event_espresso'),
384 384
 
385 385
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:13
386 386
 	// Reference: packages/constants/src/datetime.ts:6
387
-	__( 'Active', 'event_espresso' ),
387
+	__('Active', 'event_espresso'),
388 388
 
389 389
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:14
390 390
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:13
391
-	__( 'Trashed', 'event_espresso' ),
391
+	__('Trashed', 'event_espresso'),
392 392
 
393 393
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:15
394 394
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:14
395 395
 	// Reference: packages/constants/src/datetime.ts:8
396
-	__( 'Expired', 'event_espresso' ),
396
+	__('Expired', 'event_espresso'),
397 397
 
398 398
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:16
399 399
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:16
400
-	__( 'Sold Out', 'event_espresso' ),
400
+	__('Sold Out', 'event_espresso'),
401 401
 
402 402
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:17
403 403
 	// Reference: packages/constants/src/datetime.ts:12
404
-	__( 'Upcoming', 'event_espresso' ),
404
+	__('Upcoming', 'event_espresso'),
405 405
 
406 406
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:7
407
-	__( 'Edit Event Date Details', 'event_espresso' ),
407
+	__('Edit Event Date Details', 'event_espresso'),
408 408
 
409 409
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:8
410
-	__( 'View Registrations for this Date', 'event_espresso' ),
410
+	__('View Registrations for this Date', 'event_espresso'),
411 411
 
412 412
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:9
413
-	__( 'Manage Ticket Assignments', 'event_espresso' ),
413
+	__('Manage Ticket Assignments', 'event_espresso'),
414 414
 
415 415
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:23
416 416
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:34
417
-	__( 'edit title…', 'event_espresso' ),
417
+	__('edit title…', 'event_espresso'),
418 418
 
419 419
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/ActiveDatesFilters.tsx:17
420 420
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/ActiveTicketsFilters.tsx:17
421
-	__( 'ON', 'event_espresso' ),
421
+	__('ON', 'event_espresso'),
422 422
 
423 423
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:10
424
-	__( 'end dates only', 'event_espresso' ),
424
+	__('end dates only', 'event_espresso'),
425 425
 
426 426
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:11
427
-	__( 'start and end dates', 'event_espresso' ),
427
+	__('start and end dates', 'event_espresso'),
428 428
 
429 429
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:16
430
-	__( 'dates above 90% capacity', 'event_espresso' ),
430
+	__('dates above 90% capacity', 'event_espresso'),
431 431
 
432 432
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:17
433
-	__( 'dates above 75% capacity', 'event_espresso' ),
433
+	__('dates above 75% capacity', 'event_espresso'),
434 434
 
435 435
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:18
436
-	__( 'dates above 50% capacity', 'event_espresso' ),
436
+	__('dates above 50% capacity', 'event_espresso'),
437 437
 
438 438
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:19
439
-	__( 'dates below 50% capacity', 'event_espresso' ),
439
+	__('dates below 50% capacity', 'event_espresso'),
440 440
 
441 441
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:23
442
-	__( 'all dates', 'event_espresso' ),
442
+	__('all dates', 'event_espresso'),
443 443
 
444 444
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:24
445
-	__( 'all active and upcoming', 'event_espresso' ),
445
+	__('all active and upcoming', 'event_espresso'),
446 446
 
447 447
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:25
448
-	__( 'active dates only', 'event_espresso' ),
448
+	__('active dates only', 'event_espresso'),
449 449
 
450 450
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:26
451
-	__( 'upcoming dates only', 'event_espresso' ),
451
+	__('upcoming dates only', 'event_espresso'),
452 452
 
453 453
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:27
454
-	__( 'next active or upcoming only', 'event_espresso' ),
454
+	__('next active or upcoming only', 'event_espresso'),
455 455
 
456 456
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:28
457
-	__( 'sold out dates only', 'event_espresso' ),
457
+	__('sold out dates only', 'event_espresso'),
458 458
 
459 459
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:29
460
-	__( 'recently expired dates', 'event_espresso' ),
460
+	__('recently expired dates', 'event_espresso'),
461 461
 
462 462
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:30
463
-	__( 'all expired dates', 'event_espresso' ),
463
+	__('all expired dates', 'event_espresso'),
464 464
 
465 465
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:31
466
-	__( 'trashed dates only', 'event_espresso' ),
466
+	__('trashed dates only', 'event_espresso'),
467 467
 
468 468
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:35
469 469
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:9
470 470
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:61
471
-	__( 'start date', 'event_espresso' ),
471
+	__('start date', 'event_espresso'),
472 472
 
473 473
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:36
474
-	__( 'name', 'event_espresso' ),
474
+	__('name', 'event_espresso'),
475 475
 
476 476
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:37
477 477
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:31
@@ -479,141 +479,141 @@  discard block
 block discarded – undo
479 479
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/HeaderCell.tsx:27
480 480
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:31
481 481
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:23
482
-	__( 'ID', 'event_espresso' ),
482
+	__('ID', 'event_espresso'),
483 483
 
484 484
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:38
485 485
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:47
486
-	__( 'custom order', 'event_espresso' ),
486
+	__('custom order', 'event_espresso'),
487 487
 
488 488
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:42
489 489
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:51
490
-	__( 'display', 'event_espresso' ),
490
+	__('display', 'event_espresso'),
491 491
 
492 492
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:43
493
-	__( 'recurrence', 'event_espresso' ),
493
+	__('recurrence', 'event_espresso'),
494 494
 
495 495
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:44
496 496
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:53
497
-	__( 'sales', 'event_espresso' ),
497
+	__('sales', 'event_espresso'),
498 498
 
499 499
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:45
500 500
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:55
501
-	__( 'sort by', 'event_espresso' ),
501
+	__('sort by', 'event_espresso'),
502 502
 
503 503
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:46
504 504
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:54
505 505
 	// Reference: packages/ee-components/src/EntityList/EntityListFilterBar.tsx:46
506
-	__( 'search', 'event_espresso' ),
506
+	__('search', 'event_espresso'),
507 507
 
508 508
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:47
509 509
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:56
510
-	__( 'status', 'event_espresso' ),
510
+	__('status', 'event_espresso'),
511 511
 
512 512
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:9
513
-	__( 'start dates only', 'event_espresso' ),
513
+	__('start dates only', 'event_espresso'),
514 514
 
515 515
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
516 516
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/NewDateModal.tsx:12
517 517
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/OptionsModalButton.tsx:16
518
-	__( 'Add New Date', 'event_espresso' ),
518
+	__('Add New Date', 'event_espresso'),
519 519
 
520 520
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
521
-	__( 'Add Single Date', 'event_espresso' ),
521
+	__('Add Single Date', 'event_espresso'),
522 522
 
523 523
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:43
524
-	__( 'Add a single date that only occurs once', 'event_espresso' ),
524
+	__('Add a single date that only occurs once', 'event_espresso'),
525 525
 
526 526
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:45
527
-	__( 'Single Date', 'event_espresso' ),
527
+	__('Single Date', 'event_espresso'),
528 528
 
529 529
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:106
530
-	__( 'Reg list', 'event_espresso' ),
530
+	__('Reg list', 'event_espresso'),
531 531
 
532 532
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:107
533 533
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:111
534
-	__( 'Regs', 'event_espresso' ),
534
+	__('Regs', 'event_espresso'),
535 535
 
536 536
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:122
537 537
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:126
538 538
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:59
539
-	__( 'Actions', 'event_espresso' ),
539
+	__('Actions', 'event_espresso'),
540 540
 
541 541
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:52
542
-	__( 'Start', 'event_espresso' ),
542
+	__('Start', 'event_espresso'),
543 543
 
544 544
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:66
545
-	__( 'End', 'event_espresso' ),
545
+	__('End', 'event_espresso'),
546 546
 
547 547
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:82
548
-	__( 'Cap', 'event_espresso' ),
548
+	__('Cap', 'event_espresso'),
549 549
 
550 550
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:94
551 551
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:98
552
-	__( 'Sold', 'event_espresso' ),
552
+	__('Sold', 'event_espresso'),
553 553
 
554 554
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/RegistrationForm.tsx:9
555
-	__( 'Registration Form', 'event_espresso' ),
555
+	__('Registration Form', 'event_espresso'),
556 556
 
557 557
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:18
558
-	__( 'Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
559
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
558
+	__('Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
559
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
560 560
 
561 561
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:22
562
-	__( 'Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
563
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
562
+	__('Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
563
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
564 564
 
565 565
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:32
566
-	__( 'Please Update Assignments', 'event_espresso' ),
566
+	__('Please Update Assignments', 'event_espresso'),
567 567
 
568 568
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:26
569
-	__( 'There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso' ),
569
+	__('There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso'),
570 570
 
571 571
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:29
572 572
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:74
573 573
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:21
574
-	__( 'Alert!', 'event_espresso' ),
574
+	__('Alert!', 'event_espresso'),
575 575
 
576 576
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:42
577 577
 	/* translators: 1 entity id, 2 entity name */
578
-	__( 'Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso' ),
578
+	__('Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso'),
579 579
 
580 580
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:49
581 581
 	/* translators: 1 entity id, 2 entity name */
582
-	__( 'Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso' ),
582
+	__('Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso'),
583 583
 
584 584
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal.tsx:28
585 585
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/Table.tsx:13
586
-	__( 'Ticket Assignment Manager', 'event_espresso' ),
586
+	__('Ticket Assignment Manager', 'event_espresso'),
587 587
 
588 588
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:10
589
-	__( 'existing relation', 'event_espresso' ),
589
+	__('existing relation', 'event_espresso'),
590 590
 
591 591
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:15
592
-	__( 'remove existing relation', 'event_espresso' ),
592
+	__('remove existing relation', 'event_espresso'),
593 593
 
594 594
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:20
595
-	__( 'add new relation', 'event_espresso' ),
595
+	__('add new relation', 'event_espresso'),
596 596
 
597 597
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:25
598
-	__( 'invalid relation', 'event_espresso' ),
598
+	__('invalid relation', 'event_espresso'),
599 599
 
600 600
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:29
601
-	__( 'no relation', 'event_espresso' ),
601
+	__('no relation', 'event_espresso'),
602 602
 
603 603
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/BodyCell.tsx:23
604
-	__( 'assign ticket', 'event_espresso' ),
604
+	__('assign ticket', 'event_espresso'),
605 605
 
606 606
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:15
607
-	__( 'Assignments', 'event_espresso' ),
607
+	__('Assignments', 'event_espresso'),
608 608
 
609 609
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:16
610
-	__( 'Event Dates are listed below', 'event_espresso' ),
610
+	__('Event Dates are listed below', 'event_espresso'),
611 611
 
612 612
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:17
613
-	__( 'Tickets are listed along the top', 'event_espresso' ),
613
+	__('Tickets are listed along the top', 'event_espresso'),
614 614
 
615 615
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:18
616
-	__( 'Click the cell buttons to toggle assigments', 'event_espresso' ),
616
+	__('Click the cell buttons to toggle assigments', 'event_espresso'),
617 617
 
618 618
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/useSubmitButtonProps.ts:29
619 619
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:16
@@ -622,1316 +622,1316 @@  discard block
 block discarded – undo
622 622
 	// Reference: packages/tpc/src/buttons/useSubmitButtonProps.tsx:29
623 623
 	// Reference: packages/ui-components/src/Modal/useSubmitButtonProps.tsx:13
624 624
 	// Reference: packages/ui-components/src/Stepper/buttons/Submit.tsx:7
625
-	__( 'Submit', 'event_espresso' ),
625
+	__('Submit', 'event_espresso'),
626 626
 
627 627
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:20
628
-	__( 'All Dates', 'event_espresso' ),
628
+	__('All Dates', 'event_espresso'),
629 629
 
630 630
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:27
631
-	__( 'dates by month', 'event_espresso' ),
631
+	__('dates by month', 'event_espresso'),
632 632
 
633 633
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowExpiredTicketsControl.tsx:16
634
-	__( 'show expired tickets', 'event_espresso' ),
634
+	__('show expired tickets', 'event_espresso'),
635 635
 
636 636
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedDatesControl.tsx:13
637
-	__( 'show trashed dates', 'event_espresso' ),
637
+	__('show trashed dates', 'event_espresso'),
638 638
 
639 639
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedTicketsControl.tsx:16
640
-	__( 'show trashed tickets', 'event_espresso' ),
640
+	__('show trashed tickets', 'event_espresso'),
641 641
 
642 642
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/TicketRegistrationsLink.tsx:13
643
-	__( 'total registrations.', 'event_espresso' ),
643
+	__('total registrations.', 'event_espresso'),
644 644
 
645 645
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/TicketRegistrationsLink.tsx:14
646
-	__( 'view ALL registrations for this ticket.', 'event_espresso' ),
646
+	__('view ALL registrations for this ticket.', 'event_espresso'),
647 647
 
648 648
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/Container.tsx:38
649 649
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actions/Actions.tsx:21
650
-	__( 'Default tickets', 'event_espresso' ),
650
+	__('Default tickets', 'event_espresso'),
651 651
 
652 652
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:26
653 653
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:33
654
-	__( 'Set ticket prices', 'event_espresso' ),
654
+	__('Set ticket prices', 'event_espresso'),
655 655
 
656 656
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:31
657
-	__( 'Skip prices - Save', 'event_espresso' ),
657
+	__('Skip prices - Save', 'event_espresso'),
658 658
 
659 659
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:37
660 660
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:57
661
-	__( 'Ticket details', 'event_espresso' ),
661
+	__('Ticket details', 'event_espresso'),
662 662
 
663 663
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:38
664
-	__( 'Save', 'event_espresso' ),
664
+	__('Save', 'event_espresso'),
665 665
 
666 666
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:22
667 667
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:26
668 668
 	/* translators: %s ticket id */
669
-	__( 'Edit ticket %s', 'event_espresso' ),
669
+	__('Edit ticket %s', 'event_espresso'),
670 670
 
671 671
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:25
672 672
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:29
673
-	__( 'New Ticket Details', 'event_espresso' ),
673
+	__('New Ticket Details', 'event_espresso'),
674 674
 
675 675
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
676 676
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
677
-	__( 'primary information about the ticket', 'event_espresso' ),
677
+	__('primary information about the ticket', 'event_espresso'),
678 678
 
679 679
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
680 680
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
681
-	__( 'Ticket Details', 'event_espresso' ),
681
+	__('Ticket Details', 'event_espresso'),
682 682
 
683 683
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:12
684 684
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:12
685
-	__( 'apply ticket price modifiers and taxes', 'event_espresso' ),
685
+	__('apply ticket price modifiers and taxes', 'event_espresso'),
686 686
 
687 687
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:14
688 688
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:14
689
-	__( 'Price Calculator', 'event_espresso' ),
689
+	__('Price Calculator', 'event_espresso'),
690 690
 
691 691
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
692 692
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
693
-	__( 'Assign Dates', 'event_espresso' ),
693
+	__('Assign Dates', 'event_espresso'),
694 694
 
695 695
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:39
696
-	__( 'Skip prices - assign dates', 'event_espresso' ),
696
+	__('Skip prices - assign dates', 'event_espresso'),
697 697
 
698 698
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:50
699
-	__( 'Save and assign dates', 'event_espresso' ),
699
+	__('Save and assign dates', 'event_espresso'),
700 700
 
701 701
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:104
702
-	__( 'Ticket Sales', 'event_espresso' ),
702
+	__('Ticket Sales', 'event_espresso'),
703 703
 
704 704
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:130
705 705
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:112
706
-	__( 'Quantity For Sale', 'event_espresso' ),
706
+	__('Quantity For Sale', 'event_espresso'),
707 707
 
708 708
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:136
709
-	__( 'The maximum number of this ticket available for sale.', 'event_espresso' ),
709
+	__('The maximum number of this ticket available for sale.', 'event_espresso'),
710 710
 
711 711
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:138
712
-	__( 'Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso' ),
712
+	__('Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso'),
713 713
 
714 714
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:144
715 715
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:121
716
-	__( 'Number of Uses', 'event_espresso' ),
716
+	__('Number of Uses', 'event_espresso'),
717 717
 
718 718
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:150
719
-	__( 'Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso' ),
719
+	__('Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso'),
720 720
 
721 721
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:154
722
-	__( 'Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso' ),
722
+	__('Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso'),
723 723
 
724 724
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:162
725 725
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:129
726
-	__( 'Minimum Quantity', 'event_espresso' ),
726
+	__('Minimum Quantity', 'event_espresso'),
727 727
 
728 728
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:167
729
-	__( 'The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
729
+	__('The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
730 730
 
731 731
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:171
732
-	__( 'Leave blank for no minimum.', 'event_espresso' ),
732
+	__('Leave blank for no minimum.', 'event_espresso'),
733 733
 
734 734
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:177
735 735
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:137
736
-	__( 'Maximum Quantity', 'event_espresso' ),
736
+	__('Maximum Quantity', 'event_espresso'),
737 737
 
738 738
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:183
739
-	__( 'The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
739
+	__('The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
740 740
 
741 741
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:187
742
-	__( 'Leave blank for no maximum.', 'event_espresso' ),
742
+	__('Leave blank for no maximum.', 'event_espresso'),
743 743
 
744 744
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:193
745 745
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:146
746
-	__( 'Required Ticket', 'event_espresso' ),
746
+	__('Required Ticket', 'event_espresso'),
747 747
 
748 748
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:195
749
-	__( 'If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso' ),
749
+	__('If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso'),
750 750
 
751 751
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:209
752
-	__( 'Visibility', 'event_espresso' ),
752
+	__('Visibility', 'event_espresso'),
753 753
 
754 754
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:211
755
-	__( 'Where the ticket can be viewed throughout the UI.', 'event_espresso' ),
755
+	__('Where the ticket can be viewed throughout the UI.', 'event_espresso'),
756 756
 
757 757
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:36
758
-	__( 'Available Tickets', 'event_espresso' ),
758
+	__('Available Tickets', 'event_espresso'),
759 759
 
760 760
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:39
761
-	__( 'loading tickets…', 'event_espresso' ),
761
+	__('loading tickets…', 'event_espresso'),
762 762
 
763 763
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:26
764
-	__( 'Number of related dates', 'event_espresso' ),
764
+	__('Number of related dates', 'event_espresso'),
765 765
 
766 766
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:27
767
-	__( 'There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso' ),
767
+	__('There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso'),
768 768
 
769 769
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:37
770
-	__( 'assign dates', 'event_espresso' ),
770
+	__('assign dates', 'event_espresso'),
771 771
 
772 772
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:18
773
-	__( 'Permanently delete Ticket?', 'event_espresso' ),
773
+	__('Permanently delete Ticket?', 'event_espresso'),
774 774
 
775 775
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:18
776
-	__( 'Move Ticket to Trash?', 'event_espresso' ),
776
+	__('Move Ticket to Trash?', 'event_espresso'),
777 777
 
778 778
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:21
779
-	__( 'Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso' ),
779
+	__('Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso'),
780 780
 
781 781
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:22
782
-	__( 'Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso' ),
782
+	__('Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso'),
783 783
 
784 784
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:44
785 785
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Trash.tsx:6
786
-	__( 'trash ticket', 'event_espresso' ),
786
+	__('trash ticket', 'event_espresso'),
787 787
 
788 788
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:25
789
-	__( 'ticket main menu', 'event_espresso' ),
789
+	__('ticket main menu', 'event_espresso'),
790 790
 
791 791
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:38
792 792
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Edit.tsx:15
793
-	__( 'edit ticket', 'event_espresso' ),
793
+	__('edit ticket', 'event_espresso'),
794 794
 
795 795
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:39
796
-	__( 'copy ticket', 'event_espresso' ),
796
+	__('copy ticket', 'event_espresso'),
797 797
 
798 798
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:43
799
-	__( 'edit ticket details', 'event_espresso' ),
799
+	__('edit ticket details', 'event_espresso'),
800 800
 
801 801
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
802
-	__( 'delete tickets', 'event_espresso' ),
802
+	__('delete tickets', 'event_espresso'),
803 803
 
804 804
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
805
-	__( 'trash tickets', 'event_espresso' ),
805
+	__('trash tickets', 'event_espresso'),
806 806
 
807 807
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:51
808
-	__( 'edit ticket prices', 'event_espresso' ),
808
+	__('edit ticket prices', 'event_espresso'),
809 809
 
810 810
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:14
811
-	__( 'Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso' ),
811
+	__('Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso'),
812 812
 
813 813
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
814
-	__( 'Are you sure you want to trash these tickets?', 'event_espresso' ),
814
+	__('Are you sure you want to trash these tickets?', 'event_espresso'),
815 815
 
816 816
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
817
-	__( 'Delete tickets permanently', 'event_espresso' ),
817
+	__('Delete tickets permanently', 'event_espresso'),
818 818
 
819 819
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
820
-	__( 'Trash tickets', 'event_espresso' ),
820
+	__('Trash tickets', 'event_espresso'),
821 821
 
822 822
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:21
823
-	__( 'Bulk edit ticket details', 'event_espresso' ),
823
+	__('Bulk edit ticket details', 'event_espresso'),
824 824
 
825 825
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:22
826
-	__( 'any changes will be applied to ALL of the selected tickets.', 'event_espresso' ),
826
+	__('any changes will be applied to ALL of the selected tickets.', 'event_espresso'),
827 827
 
828 828
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/EditPrices.tsx:19
829
-	__( 'Bulk edit ticket prices', 'event_espresso' ),
829
+	__('Bulk edit ticket prices', 'event_espresso'),
830 830
 
831 831
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:20
832
-	__( 'Edit all prices together', 'event_espresso' ),
832
+	__('Edit all prices together', 'event_espresso'),
833 833
 
834 834
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:21
835
-	__( 'Edit all the selected ticket prices dynamically', 'event_espresso' ),
835
+	__('Edit all the selected ticket prices dynamically', 'event_espresso'),
836 836
 
837 837
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:25
838
-	__( 'Edit prices individually', 'event_espresso' ),
838
+	__('Edit prices individually', 'event_espresso'),
839 839
 
840 840
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:26
841
-	__( 'Edit prices for each ticket individually', 'event_espresso' ),
841
+	__('Edit prices for each ticket individually', 'event_espresso'),
842 842
 
843 843
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:14
844 844
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:34
845 845
 	// Reference: packages/form/src/ResetButton.tsx:18
846 846
 	// Reference: packages/tpc/src/buttons/useResetButtonProps.tsx:12
847
-	__( 'Reset', 'event_espresso' ),
847
+	__('Reset', 'event_espresso'),
848 848
 
849 849
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:15
850 850
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:76
851 851
 	// Reference: packages/ui-components/src/Modal/useCancelButtonProps.tsx:10
852
-	__( 'Cancel', 'event_espresso' ),
852
+	__('Cancel', 'event_espresso'),
853 853
 
854 854
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/editSeparately/TPCInstance.tsx:26
855 855
 	/* translators: %s ticket name */
856
-	__( 'Edit prices for Ticket: %s', 'event_espresso' ),
856
+	__('Edit prices for Ticket: %s', 'event_espresso'),
857 857
 
858 858
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:37
859
-	__( 'Edit Ticket Sale Dates', 'event_espresso' ),
859
+	__('Edit Ticket Sale Dates', 'event_espresso'),
860 860
 
861 861
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:41
862
-	__( 'edit ticket sales start and end dates', 'event_espresso' ),
862
+	__('edit ticket sales start and end dates', 'event_espresso'),
863 863
 
864 864
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:28
865
-	__( 'quantity', 'event_espresso' ),
865
+	__('quantity', 'event_espresso'),
866 866
 
867 867
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:27
868
-	__( 'edit quantity of tickets available…', 'event_espresso' ),
868
+	__('edit quantity of tickets available…', 'event_espresso'),
869 869
 
870 870
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:10
871
-	__( 'Move Ticket to Trash', 'event_espresso' ),
871
+	__('Move Ticket to Trash', 'event_espresso'),
872 872
 
873 873
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:15
874 874
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:52
875
-	__( 'On Sale', 'event_espresso' ),
875
+	__('On Sale', 'event_espresso'),
876 876
 
877 877
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:17
878
-	__( 'Pending', 'event_espresso' ),
878
+	__('Pending', 'event_espresso'),
879 879
 
880 880
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:7
881
-	__( 'Edit Ticket Details', 'event_espresso' ),
881
+	__('Edit Ticket Details', 'event_espresso'),
882 882
 
883 883
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:8
884
-	__( 'Manage Date Assignments', 'event_espresso' ),
884
+	__('Manage Date Assignments', 'event_espresso'),
885 885
 
886 886
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:9
887 887
 	// Reference: packages/tpc/src/components/table/Table.tsx:43
888
-	__( 'Ticket Price Calculator', 'event_espresso' ),
888
+	__('Ticket Price Calculator', 'event_espresso'),
889 889
 
890 890
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:39
891
-	__( 'edit ticket total…', 'event_espresso' ),
891
+	__('edit ticket total…', 'event_espresso'),
892 892
 
893 893
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:53
894
-	__( 'set price…', 'event_espresso' ),
894
+	__('set price…', 'event_espresso'),
895 895
 
896 896
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:23
897
-	__( 'tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso' ),
897
+	__('tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso'),
898 898
 
899 899
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:24
900
-	__( 'tickets list is unlinked and is showing tickets for all event dates', 'event_espresso' ),
900
+	__('tickets list is unlinked and is showing tickets for all event dates', 'event_espresso'),
901 901
 
902 902
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:10
903
-	__( 'ticket sales start and end dates', 'event_espresso' ),
903
+	__('ticket sales start and end dates', 'event_espresso'),
904 904
 
905 905
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:15
906
-	__( 'tickets with 90% or more sold', 'event_espresso' ),
906
+	__('tickets with 90% or more sold', 'event_espresso'),
907 907
 
908 908
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:16
909
-	__( 'tickets with 75% or more sold', 'event_espresso' ),
909
+	__('tickets with 75% or more sold', 'event_espresso'),
910 910
 
911 911
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:17
912
-	__( 'tickets with 50% or more sold', 'event_espresso' ),
912
+	__('tickets with 50% or more sold', 'event_espresso'),
913 913
 
914 914
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:19
915
-	__( 'tickets with less than 50% sold', 'event_espresso' ),
915
+	__('tickets with less than 50% sold', 'event_espresso'),
916 916
 
917 917
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:28
918
-	__( 'all tickets for all dates', 'event_espresso' ),
918
+	__('all tickets for all dates', 'event_espresso'),
919 919
 
920 920
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:29
921
-	__( 'all on sale and sale pending', 'event_espresso' ),
921
+	__('all on sale and sale pending', 'event_espresso'),
922 922
 
923 923
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:30
924
-	__( 'on sale tickets only', 'event_espresso' ),
924
+	__('on sale tickets only', 'event_espresso'),
925 925
 
926 926
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:31
927
-	__( 'sale pending tickets only', 'event_espresso' ),
927
+	__('sale pending tickets only', 'event_espresso'),
928 928
 
929 929
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:32
930
-	__( 'next on sale or sale pending only', 'event_espresso' ),
930
+	__('next on sale or sale pending only', 'event_espresso'),
931 931
 
932 932
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:33
933
-	__( 'sold out tickets only', 'event_espresso' ),
933
+	__('sold out tickets only', 'event_espresso'),
934 934
 
935 935
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:34
936
-	__( 'expired tickets only', 'event_espresso' ),
936
+	__('expired tickets only', 'event_espresso'),
937 937
 
938 938
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:35
939
-	__( 'trashed tickets only', 'event_espresso' ),
939
+	__('trashed tickets only', 'event_espresso'),
940 940
 
941 941
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:40
942
-	__( 'all tickets for above dates', 'event_espresso' ),
942
+	__('all tickets for above dates', 'event_espresso'),
943 943
 
944 944
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:44
945
-	__( 'ticket sale date', 'event_espresso' ),
945
+	__('ticket sale date', 'event_espresso'),
946 946
 
947 947
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:45
948
-	__( 'ticket name', 'event_espresso' ),
948
+	__('ticket name', 'event_espresso'),
949 949
 
950 950
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:46
951
-	__( 'ticket ID', 'event_espresso' ),
951
+	__('ticket ID', 'event_espresso'),
952 952
 
953 953
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:52
954
-	__( 'link', 'event_espresso' ),
954
+	__('link', 'event_espresso'),
955 955
 
956 956
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:8
957
-	__( 'ticket sales start date only', 'event_espresso' ),
957
+	__('ticket sales start date only', 'event_espresso'),
958 958
 
959 959
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:9
960
-	__( 'ticket sales end date only', 'event_espresso' ),
960
+	__('ticket sales end date only', 'event_espresso'),
961 961
 
962 962
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:18
963
-	__( 'Add New Ticket', 'event_espresso' ),
963
+	__('Add New Ticket', 'event_espresso'),
964 964
 
965 965
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:32
966
-	__( 'Add a single ticket and assign the dates to it', 'event_espresso' ),
966
+	__('Add a single ticket and assign the dates to it', 'event_espresso'),
967 967
 
968 968
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:34
969
-	__( 'Single Ticket', 'event_espresso' ),
969
+	__('Single Ticket', 'event_espresso'),
970 970
 
971 971
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/TableView.tsx:39
972
-	__( 'Tickets', 'event_espresso' ),
972
+	__('Tickets', 'event_espresso'),
973 973
 
974 974
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:110
975
-	__( 'Registrations', 'event_espresso' ),
975
+	__('Registrations', 'event_espresso'),
976 976
 
977 977
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:51
978
-	__( 'Goes on Sale', 'event_espresso' ),
978
+	__('Goes on Sale', 'event_espresso'),
979 979
 
980 980
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:65
981
-	__( 'Sale Ends', 'event_espresso' ),
981
+	__('Sale Ends', 'event_espresso'),
982 982
 
983 983
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:66
984
-	__( 'Ends', 'event_espresso' ),
984
+	__('Ends', 'event_espresso'),
985 985
 
986 986
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:78
987
-	__( 'Price', 'event_espresso' ),
987
+	__('Price', 'event_espresso'),
988 988
 
989 989
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:88
990
-	__( 'Quantity', 'event_espresso' ),
990
+	__('Quantity', 'event_espresso'),
991 991
 
992 992
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:29
993
-	__( 'Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso' ),
993
+	__('Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso'),
994 994
 
995 995
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:40
996
-	__( 'Skip', 'event_espresso' ),
996
+	__('Skip', 'event_espresso'),
997 997
 
998 998
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:42
999
-	__( 'Sure I\'ll help', 'event_espresso' ),
999
+	__('Sure I\'ll help', 'event_espresso'),
1000 1000
 
1001 1001
 	// Reference: packages/adapters/src/Pagination/Pagination.tsx:23
1002
-	__( 'pagination', 'event_espresso' ),
1002
+	__('pagination', 'event_espresso'),
1003 1003
 
1004 1004
 	// Reference: packages/adapters/src/TagSelector/TagSelector.tsx:112
1005
-	__( 'toggle menu', 'event_espresso' ),
1005
+	__('toggle menu', 'event_espresso'),
1006 1006
 
1007 1007
 	// Reference: packages/constants/src/datetime.ts:10
1008
-	__( 'Postponed', 'event_espresso' ),
1008
+	__('Postponed', 'event_espresso'),
1009 1009
 
1010 1010
 	// Reference: packages/constants/src/datetime.ts:11
1011
-	__( 'SoldOut', 'event_espresso' ),
1011
+	__('SoldOut', 'event_espresso'),
1012 1012
 
1013 1013
 	// Reference: packages/constants/src/datetime.ts:7
1014 1014
 	// Reference: packages/predicates/src/registration/statusOptions.ts:10
1015
-	__( 'Cancelled', 'event_espresso' ),
1015
+	__('Cancelled', 'event_espresso'),
1016 1016
 
1017 1017
 	// Reference: packages/constants/src/datetime.ts:9
1018
-	__( 'Inactive', 'event_espresso' ),
1018
+	__('Inactive', 'event_espresso'),
1019 1019
 
1020 1020
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:13
1021
-	__( 'day in range', 'event_espresso' ),
1021
+	__('day in range', 'event_espresso'),
1022 1022
 
1023 1023
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:17
1024 1024
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:79
1025
-	__( 'end date', 'event_espresso' ),
1025
+	__('end date', 'event_espresso'),
1026 1026
 
1027 1027
 	// Reference: packages/dates/src/components/DateTimePicker.tsx:13
1028 1028
 	// Reference: packages/dates/src/components/TimePicker.tsx:14
1029
-	__( 'time', 'event_espresso' ),
1029
+	__('time', 'event_espresso'),
1030 1030
 
1031 1031
 	// Reference: packages/dates/src/constants.ts:5
1032
-	__( 'End Date & Time must be set later than the Start Date & Time', 'event_espresso' ),
1032
+	__('End Date & Time must be set later than the Start Date & Time', 'event_espresso'),
1033 1033
 
1034 1034
 	// Reference: packages/dates/src/constants.ts:7
1035
-	__( 'Start Date & Time must be set before the End Date & Time', 'event_espresso' ),
1035
+	__('Start Date & Time must be set before the End Date & Time', 'event_espresso'),
1036 1036
 
1037 1037
 	// Reference: packages/dates/src/utils/misc.ts:15
1038
-	__( 'month(s)', 'event_espresso' ),
1038
+	__('month(s)', 'event_espresso'),
1039 1039
 
1040 1040
 	// Reference: packages/dates/src/utils/misc.ts:16
1041
-	__( 'week(s)', 'event_espresso' ),
1041
+	__('week(s)', 'event_espresso'),
1042 1042
 
1043 1043
 	// Reference: packages/dates/src/utils/misc.ts:17
1044
-	__( 'day(s)', 'event_espresso' ),
1044
+	__('day(s)', 'event_espresso'),
1045 1045
 
1046 1046
 	// Reference: packages/dates/src/utils/misc.ts:18
1047
-	__( 'hour(s)', 'event_espresso' ),
1047
+	__('hour(s)', 'event_espresso'),
1048 1048
 
1049 1049
 	// Reference: packages/dates/src/utils/misc.ts:19
1050
-	__( 'minute(s)', 'event_espresso' ),
1050
+	__('minute(s)', 'event_espresso'),
1051 1051
 
1052 1052
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:105
1053
-	__( 'datetimes initialized', 'event_espresso' ),
1053
+	__('datetimes initialized', 'event_espresso'),
1054 1054
 
1055 1055
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:115
1056
-	__( 'tickets initialized', 'event_espresso' ),
1056
+	__('tickets initialized', 'event_espresso'),
1057 1057
 
1058 1058
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:125
1059
-	__( 'prices initialized', 'event_espresso' ),
1059
+	__('prices initialized', 'event_espresso'),
1060 1060
 
1061 1061
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:95
1062
-	__( 'price types initialized', 'event_espresso' ),
1062
+	__('price types initialized', 'event_espresso'),
1063 1063
 
1064 1064
 	// Reference: packages/edtr-services/src/apollo/mutations/useReorderEntities.ts:72
1065
-	__( 'reordering has been applied', 'event_espresso' ),
1065
+	__('reordering has been applied', 'event_espresso'),
1066 1066
 
1067 1067
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:38
1068 1068
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:39
1069
-	__( 'End date has been adjusted', 'event_espresso' ),
1069
+	__('End date has been adjusted', 'event_espresso'),
1070 1070
 
1071 1071
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:59
1072
-	__( 'Required', 'event_espresso' ),
1072
+	__('Required', 'event_espresso'),
1073 1073
 
1074 1074
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:64
1075
-	__( 'Start Date is required', 'event_espresso' ),
1075
+	__('Start Date is required', 'event_espresso'),
1076 1076
 
1077 1077
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:68
1078
-	__( 'End Date is required', 'event_espresso' ),
1078
+	__('End Date is required', 'event_espresso'),
1079 1079
 
1080 1080
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:31
1081
-	__( 'no results found', 'event_espresso' ),
1081
+	__('no results found', 'event_espresso'),
1082 1082
 
1083 1083
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:32
1084
-	__( 'try changing filter settings', 'event_espresso' ),
1084
+	__('try changing filter settings', 'event_espresso'),
1085 1085
 
1086 1086
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:27
1087 1087
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:34
1088
-	__( 'starts', 'event_espresso' ),
1088
+	__('starts', 'event_espresso'),
1089 1089
 
1090 1090
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:34
1091 1091
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:47
1092
-	__( 'ends', 'event_espresso' ),
1092
+	__('ends', 'event_espresso'),
1093 1093
 
1094 1094
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:38
1095 1095
 	/* translators: %d entity id */
1096
-	__( 'select entity with id %d', 'event_espresso' ),
1096
+	__('select entity with id %d', 'event_espresso'),
1097 1097
 
1098 1098
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:41
1099
-	__( 'select all entities', 'event_espresso' ),
1099
+	__('select all entities', 'event_espresso'),
1100 1100
 
1101 1101
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1102
-	__( 'Note: ', 'event_espresso' ),
1102
+	__('Note: ', 'event_espresso'),
1103 1103
 
1104 1104
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1105
-	__( 'any changes will be applied to ALL of the selected entities.', 'event_espresso' ),
1105
+	__('any changes will be applied to ALL of the selected entities.', 'event_espresso'),
1106 1106
 
1107 1107
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:26
1108
-	__( 'Bulk edit details', 'event_espresso' ),
1108
+	__('Bulk edit details', 'event_espresso'),
1109 1109
 
1110 1110
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:17
1111
-	__( 'Are you sure you want to bulk update the details?', 'event_espresso' ),
1111
+	__('Are you sure you want to bulk update the details?', 'event_espresso'),
1112 1112
 
1113 1113
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:18
1114
-	__( 'Bulk update details', 'event_espresso' ),
1114
+	__('Bulk update details', 'event_espresso'),
1115 1115
 
1116 1116
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:26
1117
-	__( 'reorder dates', 'event_espresso' ),
1117
+	__('reorder dates', 'event_espresso'),
1118 1118
 
1119 1119
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:26
1120
-	__( 'reorder tickets', 'event_espresso' ),
1120
+	__('reorder tickets', 'event_espresso'),
1121 1121
 
1122 1122
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:32
1123
-	__( 'delete form element', 'event_espresso' ),
1123
+	__('delete form element', 'event_espresso'),
1124 1124
 
1125 1125
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:49
1126
-	__( 'form element settings', 'event_espresso' ),
1126
+	__('form element settings', 'event_espresso'),
1127 1127
 
1128 1128
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:59
1129
-	__( 'copy form element', 'event_espresso' ),
1129
+	__('copy form element', 'event_espresso'),
1130 1130
 
1131 1131
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:69
1132
-	__( 'click, hold, and drag to reorder form element', 'event_espresso' ),
1132
+	__('click, hold, and drag to reorder form element', 'event_espresso'),
1133 1133
 
1134 1134
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:20
1135
-	__( 'remove option', 'event_espresso' ),
1135
+	__('remove option', 'event_espresso'),
1136 1136
 
1137 1137
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:42
1138
-	__( 'value', 'event_espresso' ),
1138
+	__('value', 'event_espresso'),
1139 1139
 
1140 1140
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:52
1141
-	__( 'label', 'event_espresso' ),
1141
+	__('label', 'event_espresso'),
1142 1142
 
1143 1143
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:63
1144
-	__( 'click, hold, and drag to reorder field option', 'event_espresso' ),
1144
+	__('click, hold, and drag to reorder field option', 'event_espresso'),
1145 1145
 
1146 1146
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:61
1147
-	__( 'Options are the choices you give people to select from.', 'event_espresso' ),
1147
+	__('Options are the choices you give people to select from.', 'event_espresso'),
1148 1148
 
1149 1149
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:63
1150
-	__( 'The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso' ),
1150
+	__('The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso'),
1151 1151
 
1152 1152
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:96
1153
-	__( 'add new option', 'event_espresso' ),
1153
+	__('add new option', 'event_espresso'),
1154 1154
 
1155 1155
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:22
1156 1156
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:21
1157
-	__( 'Settings', 'event_espresso' ),
1157
+	__('Settings', 'event_espresso'),
1158 1158
 
1159 1159
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:26
1160 1160
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:25
1161
-	__( 'Styles', 'event_espresso' ),
1161
+	__('Styles', 'event_espresso'),
1162 1162
 
1163 1163
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:30
1164
-	__( 'Validation', 'event_espresso' ),
1164
+	__('Validation', 'event_espresso'),
1165 1165
 
1166 1166
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:34
1167 1167
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:29
1168
-	__( 'Rules', 'event_espresso' ),
1168
+	__('Rules', 'event_espresso'),
1169 1169
 
1170 1170
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:18
1171 1171
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:19
1172
-	__( 'admin label', 'event_espresso' ),
1172
+	__('admin label', 'event_espresso'),
1173 1173
 
1174 1174
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:23
1175
-	__( 'admin only', 'event_espresso' ),
1175
+	__('admin only', 'event_espresso'),
1176 1176
 
1177 1177
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:30
1178
-	__( 'content', 'event_espresso' ),
1178
+	__('content', 'event_espresso'),
1179 1179
 
1180 1180
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:39
1181 1181
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:14
1182
-	__( 'public label', 'event_espresso' ),
1182
+	__('public label', 'event_espresso'),
1183 1183
 
1184 1184
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:44
1185
-	__( 'options', 'event_espresso' ),
1185
+	__('options', 'event_espresso'),
1186 1186
 
1187 1187
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:47
1188
-	__( 'placeholder', 'event_espresso' ),
1188
+	__('placeholder', 'event_espresso'),
1189 1189
 
1190 1190
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:52
1191
-	__( 'help text', 'event_espresso' ),
1191
+	__('help text', 'event_espresso'),
1192 1192
 
1193 1193
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:14
1194 1194
 	// Reference: packages/form-builder/src/FormSection/Tabs/Styles.tsx:13
1195
-	__( 'css class', 'event_espresso' ),
1195
+	__('css class', 'event_espresso'),
1196 1196
 
1197 1197
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:19
1198
-	__( 'help text css class', 'event_espresso' ),
1198
+	__('help text css class', 'event_espresso'),
1199 1199
 
1200 1200
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:16
1201
-	__( 'required', 'event_espresso' ),
1201
+	__('required', 'event_espresso'),
1202 1202
 
1203 1203
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:21
1204
-	__( 'required text', 'event_espresso' ),
1204
+	__('required text', 'event_espresso'),
1205 1205
 
1206 1206
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:28
1207
-	__( 'min', 'event_espresso' ),
1207
+	__('min', 'event_espresso'),
1208 1208
 
1209 1209
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:33
1210
-	__( 'max', 'event_espresso' ),
1210
+	__('max', 'event_espresso'),
1211 1211
 
1212 1212
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:110
1213
-	__( 'add new form element', 'event_espresso' ),
1213
+	__('add new form element', 'event_espresso'),
1214 1214
 
1215 1215
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:117
1216 1216
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:52
1217 1217
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityTemplate.tsx:27
1218
-	__( 'Add', 'event_espresso' ),
1218
+	__('Add', 'event_espresso'),
1219 1219
 
1220 1220
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:76
1221
-	__( 'Add Form Element', 'event_espresso' ),
1221
+	__('Add Form Element', 'event_espresso'),
1222 1222
 
1223 1223
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:85
1224
-	__( 'form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso' ),
1224
+	__('form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso'),
1225 1225
 
1226 1226
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:92
1227
-	__( 'load existing form section', 'event_espresso' ),
1227
+	__('load existing form section', 'event_espresso'),
1228 1228
 
1229 1229
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:32
1230
-	__( 'delete form section', 'event_espresso' ),
1230
+	__('delete form section', 'event_espresso'),
1231 1231
 
1232 1232
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:47
1233
-	__( 'form section settings', 'event_espresso' ),
1233
+	__('form section settings', 'event_espresso'),
1234 1234
 
1235 1235
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:57
1236
-	__( 'copy form section', 'event_espresso' ),
1236
+	__('copy form section', 'event_espresso'),
1237 1237
 
1238 1238
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:74
1239
-	__( 'click, hold, and drag to reorder form section', 'event_espresso' ),
1239
+	__('click, hold, and drag to reorder form section', 'event_espresso'),
1240 1240
 
1241 1241
 	// Reference: packages/form-builder/src/FormSection/FormSections.tsx:26
1242
-	__( 'Add Form Section', 'event_espresso' ),
1242
+	__('Add Form Section', 'event_espresso'),
1243 1243
 
1244 1244
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:43
1245
-	__( 'save form section for use in other forms', 'event_espresso' ),
1245
+	__('save form section for use in other forms', 'event_espresso'),
1246 1246
 
1247 1247
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:47
1248
-	__( 'save as', 'event_espresso' ),
1248
+	__('save as', 'event_espresso'),
1249 1249
 
1250 1250
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:51
1251
-	__( 'default', 'event_espresso' ),
1251
+	__('default', 'event_espresso'),
1252 1252
 
1253 1253
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:54
1254
-	__( ' a copy of this form section will be automatically added to ALL new events', 'event_espresso' ),
1254
+	__(' a copy of this form section will be automatically added to ALL new events', 'event_espresso'),
1255 1255
 
1256 1256
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:57
1257
-	__( 'shared', 'event_espresso' ),
1257
+	__('shared', 'event_espresso'),
1258 1258
 
1259 1259
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:60
1260
-	__( 'a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso' ),
1260
+	__('a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso'),
1261 1261
 
1262 1262
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:24
1263
-	__( 'show label', 'event_espresso' ),
1263
+	__('show label', 'event_espresso'),
1264 1264
 
1265 1265
 	// Reference: packages/form-builder/src/constants.ts:100
1266
-	__( 'Time', 'event_espresso' ),
1266
+	__('Time', 'event_espresso'),
1267 1267
 
1268 1268
 	// Reference: packages/form-builder/src/constants.ts:102
1269
-	__( 'adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso' ),
1269
+	__('adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso'),
1270 1270
 
1271 1271
 	// Reference: packages/form-builder/src/constants.ts:105
1272
-	__( 'Week', 'event_espresso' ),
1272
+	__('Week', 'event_espresso'),
1273 1273
 
1274 1274
 	// Reference: packages/form-builder/src/constants.ts:107
1275
-	__( 'adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso' ),
1275
+	__('adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso'),
1276 1276
 
1277 1277
 	// Reference: packages/form-builder/src/constants.ts:110
1278
-	__( 'Day Selector', 'event_espresso' ),
1278
+	__('Day Selector', 'event_espresso'),
1279 1279
 
1280 1280
 	// Reference: packages/form-builder/src/constants.ts:112
1281
-	__( 'adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso' ),
1281
+	__('adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso'),
1282 1282
 
1283 1283
 	// Reference: packages/form-builder/src/constants.ts:115
1284
-	__( 'Month Selector', 'event_espresso' ),
1284
+	__('Month Selector', 'event_espresso'),
1285 1285
 
1286 1286
 	// Reference: packages/form-builder/src/constants.ts:117
1287
-	__( 'adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso' ),
1287
+	__('adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso'),
1288 1288
 
1289 1289
 	// Reference: packages/form-builder/src/constants.ts:120
1290
-	__( 'Year Selector', 'event_espresso' ),
1290
+	__('Year Selector', 'event_espresso'),
1291 1291
 
1292 1292
 	// Reference: packages/form-builder/src/constants.ts:122
1293
-	__( 'adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso' ),
1293
+	__('adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso'),
1294 1294
 
1295 1295
 	// Reference: packages/form-builder/src/constants.ts:125
1296
-	__( 'Radio Buttons', 'event_espresso' ),
1296
+	__('Radio Buttons', 'event_espresso'),
1297 1297
 
1298 1298
 	// Reference: packages/form-builder/src/constants.ts:127
1299
-	__( 'adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso' ),
1299
+	__('adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso'),
1300 1300
 
1301 1301
 	// Reference: packages/form-builder/src/constants.ts:130
1302
-	__( 'Decimal Number', 'event_espresso' ),
1302
+	__('Decimal Number', 'event_espresso'),
1303 1303
 
1304 1304
 	// Reference: packages/form-builder/src/constants.ts:132
1305
-	__( 'adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso' ),
1305
+	__('adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso'),
1306 1306
 
1307 1307
 	// Reference: packages/form-builder/src/constants.ts:135
1308
-	__( 'Whole Number', 'event_espresso' ),
1308
+	__('Whole Number', 'event_espresso'),
1309 1309
 
1310 1310
 	// Reference: packages/form-builder/src/constants.ts:137
1311
-	__( 'adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso' ),
1311
+	__('adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso'),
1312 1312
 
1313 1313
 	// Reference: packages/form-builder/src/constants.ts:140
1314
-	__( 'Number Range', 'event_espresso' ),
1314
+	__('Number Range', 'event_espresso'),
1315 1315
 
1316 1316
 	// Reference: packages/form-builder/src/constants.ts:145
1317
-	__( 'Phone Number', 'event_espresso' ),
1317
+	__('Phone Number', 'event_espresso'),
1318 1318
 
1319 1319
 	// Reference: packages/form-builder/src/constants.ts:150
1320
-	__( 'Dropdown', 'event_espresso' ),
1320
+	__('Dropdown', 'event_espresso'),
1321 1321
 
1322 1322
 	// Reference: packages/form-builder/src/constants.ts:152
1323
-	__( 'adds a dropdown selector that accepts a single value', 'event_espresso' ),
1323
+	__('adds a dropdown selector that accepts a single value', 'event_espresso'),
1324 1324
 
1325 1325
 	// Reference: packages/form-builder/src/constants.ts:155
1326
-	__( 'Multi Select', 'event_espresso' ),
1326
+	__('Multi Select', 'event_espresso'),
1327 1327
 
1328 1328
 	// Reference: packages/form-builder/src/constants.ts:157
1329
-	__( 'adds a dropdown selector that accepts multiple values', 'event_espresso' ),
1329
+	__('adds a dropdown selector that accepts multiple values', 'event_espresso'),
1330 1330
 
1331 1331
 	// Reference: packages/form-builder/src/constants.ts:160
1332
-	__( 'Toggle/Switch', 'event_espresso' ),
1332
+	__('Toggle/Switch', 'event_espresso'),
1333 1333
 
1334 1334
 	// Reference: packages/form-builder/src/constants.ts:162
1335
-	__( 'adds a toggle or a switch to accept true or false value', 'event_espresso' ),
1335
+	__('adds a toggle or a switch to accept true or false value', 'event_espresso'),
1336 1336
 
1337 1337
 	// Reference: packages/form-builder/src/constants.ts:165
1338
-	__( 'Multi Checkbox', 'event_espresso' ),
1338
+	__('Multi Checkbox', 'event_espresso'),
1339 1339
 
1340 1340
 	// Reference: packages/form-builder/src/constants.ts:167
1341
-	__( 'adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso' ),
1341
+	__('adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso'),
1342 1342
 
1343 1343
 	// Reference: packages/form-builder/src/constants.ts:170
1344
-	__( 'Country Selector', 'event_espresso' ),
1344
+	__('Country Selector', 'event_espresso'),
1345 1345
 
1346 1346
 	// Reference: packages/form-builder/src/constants.ts:172
1347
-	__( 'adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso' ),
1347
+	__('adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso'),
1348 1348
 
1349 1349
 	// Reference: packages/form-builder/src/constants.ts:175
1350
-	__( 'State Selector', 'event_espresso' ),
1350
+	__('State Selector', 'event_espresso'),
1351 1351
 
1352 1352
 	// Reference: packages/form-builder/src/constants.ts:180
1353
-	__( 'Button', 'event_espresso' ),
1353
+	__('Button', 'event_espresso'),
1354 1354
 
1355 1355
 	// Reference: packages/form-builder/src/constants.ts:182
1356
-	__( 'adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso' ),
1356
+	__('adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso'),
1357 1357
 
1358 1358
 	// Reference: packages/form-builder/src/constants.ts:185
1359
-	__( 'Reset Button', 'event_espresso' ),
1359
+	__('Reset Button', 'event_espresso'),
1360 1360
 
1361 1361
 	// Reference: packages/form-builder/src/constants.ts:187
1362
-	__( 'adds a button that will reset the form back to its orginial state.', 'event_espresso' ),
1362
+	__('adds a button that will reset the form back to its orginial state.', 'event_espresso'),
1363 1363
 
1364 1364
 	// Reference: packages/form-builder/src/constants.ts:38
1365
-	__( 'Form Section', 'event_espresso' ),
1365
+	__('Form Section', 'event_espresso'),
1366 1366
 
1367 1367
 	// Reference: packages/form-builder/src/constants.ts:40
1368
-	__( 'Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso' ),
1368
+	__('Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso'),
1369 1369
 
1370 1370
 	// Reference: packages/form-builder/src/constants.ts:45
1371
-	__( 'HTML Block', 'event_espresso' ),
1371
+	__('HTML Block', 'event_espresso'),
1372 1372
 
1373 1373
 	// Reference: packages/form-builder/src/constants.ts:47
1374
-	__( 'allows you to add HTML like headings or text paragraphs to your form', 'event_espresso' ),
1374
+	__('allows you to add HTML like headings or text paragraphs to your form', 'event_espresso'),
1375 1375
 
1376 1376
 	// Reference: packages/form-builder/src/constants.ts:50
1377
-	__( 'Text Input', 'event_espresso' ),
1377
+	__('Text Input', 'event_espresso'),
1378 1378
 
1379 1379
 	// Reference: packages/form-builder/src/constants.ts:52
1380
-	__( 'adds a text input that only accepts plain text', 'event_espresso' ),
1380
+	__('adds a text input that only accepts plain text', 'event_espresso'),
1381 1381
 
1382 1382
 	// Reference: packages/form-builder/src/constants.ts:55
1383
-	__( 'Plain Text Area', 'event_espresso' ),
1383
+	__('Plain Text Area', 'event_espresso'),
1384 1384
 
1385 1385
 	// Reference: packages/form-builder/src/constants.ts:57
1386
-	__( 'adds a textarea block that only accepts plain text', 'event_espresso' ),
1386
+	__('adds a textarea block that only accepts plain text', 'event_espresso'),
1387 1387
 
1388 1388
 	// Reference: packages/form-builder/src/constants.ts:60
1389
-	__( 'HTML Text Area', 'event_espresso' ),
1389
+	__('HTML Text Area', 'event_espresso'),
1390 1390
 
1391 1391
 	// Reference: packages/form-builder/src/constants.ts:62
1392
-	__( 'adds a textarea block that accepts text including simple HTML markup', 'event_espresso' ),
1392
+	__('adds a textarea block that accepts text including simple HTML markup', 'event_espresso'),
1393 1393
 
1394 1394
 	// Reference: packages/form-builder/src/constants.ts:65
1395
-	__( 'Email Address', 'event_espresso' ),
1395
+	__('Email Address', 'event_espresso'),
1396 1396
 
1397 1397
 	// Reference: packages/form-builder/src/constants.ts:67
1398
-	__( 'adds a text input that only accets a valid email address', 'event_espresso' ),
1398
+	__('adds a text input that only accets a valid email address', 'event_espresso'),
1399 1399
 
1400 1400
 	// Reference: packages/form-builder/src/constants.ts:70
1401
-	__( 'Email Confirmation', 'event_espresso' ),
1401
+	__('Email Confirmation', 'event_espresso'),
1402 1402
 
1403 1403
 	// Reference: packages/form-builder/src/constants.ts:75
1404
-	__( 'Password', 'event_espresso' ),
1404
+	__('Password', 'event_espresso'),
1405 1405
 
1406 1406
 	// Reference: packages/form-builder/src/constants.ts:77
1407
-	__( 'adds a text input that accepts text but masks what the user enters', 'event_espresso' ),
1407
+	__('adds a text input that accepts text but masks what the user enters', 'event_espresso'),
1408 1408
 
1409 1409
 	// Reference: packages/form-builder/src/constants.ts:80
1410
-	__( 'URL', 'event_espresso' ),
1410
+	__('URL', 'event_espresso'),
1411 1411
 
1412 1412
 	// Reference: packages/form-builder/src/constants.ts:82
1413
-	__( 'adds a text input for entering a URL address', 'event_espresso' ),
1413
+	__('adds a text input for entering a URL address', 'event_espresso'),
1414 1414
 
1415 1415
 	// Reference: packages/form-builder/src/constants.ts:85
1416
-	__( 'Date', 'event_espresso' ),
1416
+	__('Date', 'event_espresso'),
1417 1417
 
1418 1418
 	// Reference: packages/form-builder/src/constants.ts:87
1419
-	__( 'adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso' ),
1419
+	__('adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso'),
1420 1420
 
1421 1421
 	// Reference: packages/form-builder/src/constants.ts:90
1422
-	__( 'Local Date', 'event_espresso' ),
1422
+	__('Local Date', 'event_espresso'),
1423 1423
 
1424 1424
 	// Reference: packages/form-builder/src/constants.ts:95
1425
-	__( 'Month', 'event_espresso' ),
1425
+	__('Month', 'event_espresso'),
1426 1426
 
1427 1427
 	// Reference: packages/form-builder/src/constants.ts:97
1428
-	__( 'adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso' ),
1428
+	__('adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso'),
1429 1429
 
1430 1430
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:12
1431
-	__( 'Select Image', 'event_espresso' ),
1431
+	__('Select Image', 'event_espresso'),
1432 1432
 
1433 1433
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:44
1434 1434
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:11
1435 1435
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:12
1436
-	__( 'Select', 'event_espresso' ),
1436
+	__('Select', 'event_espresso'),
1437 1437
 
1438 1438
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:36
1439 1439
 	/* translators: %d the entry number */
1440
-	__( 'Entry %d', 'event_espresso' ),
1440
+	__('Entry %d', 'event_espresso'),
1441 1441
 
1442 1442
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:11
1443 1443
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:17
1444
-	__( 'sold out', 'event_espresso' ),
1444
+	__('sold out', 'event_espresso'),
1445 1445
 
1446 1446
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:14
1447 1447
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:14
1448
-	__( 'expired', 'event_espresso' ),
1448
+	__('expired', 'event_espresso'),
1449 1449
 
1450 1450
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:17
1451
-	__( 'upcoming', 'event_espresso' ),
1451
+	__('upcoming', 'event_espresso'),
1452 1452
 
1453 1453
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:20
1454
-	__( 'active', 'event_espresso' ),
1454
+	__('active', 'event_espresso'),
1455 1455
 
1456 1456
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:23
1457 1457
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:11
1458
-	__( 'trashed', 'event_espresso' ),
1458
+	__('trashed', 'event_espresso'),
1459 1459
 
1460 1460
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:26
1461
-	__( 'cancelled', 'event_espresso' ),
1461
+	__('cancelled', 'event_espresso'),
1462 1462
 
1463 1463
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:29
1464
-	__( 'postponed', 'event_espresso' ),
1464
+	__('postponed', 'event_espresso'),
1465 1465
 
1466 1466
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:33
1467
-	__( 'inactive', 'event_espresso' ),
1467
+	__('inactive', 'event_espresso'),
1468 1468
 
1469 1469
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:20
1470
-	__( 'pending', 'event_espresso' ),
1470
+	__('pending', 'event_espresso'),
1471 1471
 
1472 1472
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:23
1473
-	__( 'on sale', 'event_espresso' ),
1473
+	__('on sale', 'event_espresso'),
1474 1474
 
1475 1475
 	// Reference: packages/predicates/src/registration/statusOptions.ts:14
1476
-	__( 'Declined', 'event_espresso' ),
1476
+	__('Declined', 'event_espresso'),
1477 1477
 
1478 1478
 	// Reference: packages/predicates/src/registration/statusOptions.ts:18
1479
-	__( 'Incomplete', 'event_espresso' ),
1479
+	__('Incomplete', 'event_espresso'),
1480 1480
 
1481 1481
 	// Reference: packages/predicates/src/registration/statusOptions.ts:22
1482
-	__( 'Not Approved', 'event_espresso' ),
1482
+	__('Not Approved', 'event_espresso'),
1483 1483
 
1484 1484
 	// Reference: packages/predicates/src/registration/statusOptions.ts:26
1485
-	__( 'Pending Payment', 'event_espresso' ),
1485
+	__('Pending Payment', 'event_espresso'),
1486 1486
 
1487 1487
 	// Reference: packages/predicates/src/registration/statusOptions.ts:30
1488
-	__( 'Wait List', 'event_espresso' ),
1488
+	__('Wait List', 'event_espresso'),
1489 1489
 
1490 1490
 	// Reference: packages/predicates/src/registration/statusOptions.ts:6
1491
-	__( 'Approved', 'event_espresso' ),
1491
+	__('Approved', 'event_espresso'),
1492 1492
 
1493 1493
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:9
1494 1494
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:10
1495
-	__( 'Select media', 'event_espresso' ),
1495
+	__('Select media', 'event_espresso'),
1496 1496
 
1497 1497
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/RichTextEditor.tsx:84
1498
-	__( 'Write something…', 'event_espresso' ),
1498
+	__('Write something…', 'event_espresso'),
1499 1499
 
1500 1500
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/Toolbar.tsx:20
1501
-	__( 'RTE Toolbar', 'event_espresso' ),
1501
+	__('RTE Toolbar', 'event_espresso'),
1502 1502
 
1503 1503
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:11
1504
-	__( 'Normal', 'event_espresso' ),
1504
+	__('Normal', 'event_espresso'),
1505 1505
 
1506 1506
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:12
1507
-	__( 'H1', 'event_espresso' ),
1507
+	__('H1', 'event_espresso'),
1508 1508
 
1509 1509
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:13
1510
-	__( 'H2', 'event_espresso' ),
1510
+	__('H2', 'event_espresso'),
1511 1511
 
1512 1512
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:14
1513
-	__( 'H3', 'event_espresso' ),
1513
+	__('H3', 'event_espresso'),
1514 1514
 
1515 1515
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:15
1516
-	__( 'H4', 'event_espresso' ),
1516
+	__('H4', 'event_espresso'),
1517 1517
 
1518 1518
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:16
1519
-	__( 'H5', 'event_espresso' ),
1519
+	__('H5', 'event_espresso'),
1520 1520
 
1521 1521
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:17
1522
-	__( 'H6', 'event_espresso' ),
1522
+	__('H6', 'event_espresso'),
1523 1523
 
1524 1524
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:18
1525
-	__( 'Block quote', 'event_espresso' ),
1525
+	__('Block quote', 'event_espresso'),
1526 1526
 
1527 1527
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:19
1528
-	__( 'Code', 'event_espresso' ),
1528
+	__('Code', 'event_espresso'),
1529 1529
 
1530 1530
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:36
1531
-	__( 'Set color', 'event_espresso' ),
1531
+	__('Set color', 'event_espresso'),
1532 1532
 
1533 1533
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:45
1534
-	__( 'Text color', 'event_espresso' ),
1534
+	__('Text color', 'event_espresso'),
1535 1535
 
1536 1536
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:47
1537
-	__( 'Background color', 'event_espresso' ),
1537
+	__('Background color', 'event_espresso'),
1538 1538
 
1539 1539
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:39
1540
-	__( 'Add image', 'event_espresso' ),
1540
+	__('Add image', 'event_espresso'),
1541 1541
 
1542 1542
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:51
1543
-	__( 'Image URL', 'event_espresso' ),
1543
+	__('Image URL', 'event_espresso'),
1544 1544
 
1545 1545
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:55
1546
-	__( 'Alt text', 'event_espresso' ),
1546
+	__('Alt text', 'event_espresso'),
1547 1547
 
1548 1548
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:56
1549
-	__( 'Width', 'event_espresso' ),
1549
+	__('Width', 'event_espresso'),
1550 1550
 
1551 1551
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:60
1552
-	__( 'Height', 'event_espresso' ),
1552
+	__('Height', 'event_espresso'),
1553 1553
 
1554 1554
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:54
1555
-	__( 'Edit link', 'event_espresso' ),
1555
+	__('Edit link', 'event_espresso'),
1556 1556
 
1557 1557
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:64
1558
-	__( 'URL title', 'event_espresso' ),
1558
+	__('URL title', 'event_espresso'),
1559 1559
 
1560 1560
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:11
1561
-	__( 'Unordered list', 'event_espresso' ),
1561
+	__('Unordered list', 'event_espresso'),
1562 1562
 
1563 1563
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:12
1564
-	__( 'Ordered list', 'event_espresso' ),
1564
+	__('Ordered list', 'event_espresso'),
1565 1565
 
1566 1566
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:13
1567 1567
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:13
1568
-	__( 'Indent', 'event_espresso' ),
1568
+	__('Indent', 'event_espresso'),
1569 1569
 
1570 1570
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:14
1571 1571
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:14
1572
-	__( 'Outdent', 'event_espresso' ),
1572
+	__('Outdent', 'event_espresso'),
1573 1573
 
1574 1574
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:11
1575
-	__( 'Unordered textalign', 'event_espresso' ),
1575
+	__('Unordered textalign', 'event_espresso'),
1576 1576
 
1577 1577
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:12
1578
-	__( 'Ordered textalign', 'event_espresso' ),
1578
+	__('Ordered textalign', 'event_espresso'),
1579 1579
 
1580 1580
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/render/Image/Toolbar.tsx:32
1581
-	__( 'Image toolbar', 'event_espresso' ),
1581
+	__('Image toolbar', 'event_espresso'),
1582 1582
 
1583 1583
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:62
1584 1584
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:35
1585
-	__( 'Visual editor', 'event_espresso' ),
1585
+	__('Visual editor', 'event_espresso'),
1586 1586
 
1587 1587
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:66
1588 1588
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:39
1589
-	__( 'HTML editor', 'event_espresso' ),
1589
+	__('HTML editor', 'event_espresso'),
1590 1590
 
1591 1591
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:68
1592
-	__( 'Add Media', 'event_espresso' ),
1592
+	__('Add Media', 'event_espresso'),
1593 1593
 
1594 1594
 	// Reference: packages/tpc/src/buttons/AddPriceModifierButton.tsx:14
1595
-	__( 'add new price modifier after this row', 'event_espresso' ),
1595
+	__('add new price modifier after this row', 'event_espresso'),
1596 1596
 
1597 1597
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:14
1598
-	__( 'Delete all prices', 'event_espresso' ),
1598
+	__('Delete all prices', 'event_espresso'),
1599 1599
 
1600 1600
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:27
1601
-	__( 'Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso' ),
1601
+	__('Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso'),
1602 1602
 
1603 1603
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:31
1604
-	__( 'Delete all prices?', 'event_espresso' ),
1604
+	__('Delete all prices?', 'event_espresso'),
1605 1605
 
1606 1606
 	// Reference: packages/tpc/src/buttons/DeletePriceModifierButton.tsx:12
1607
-	__( 'delete price modifier', 'event_espresso' ),
1607
+	__('delete price modifier', 'event_espresso'),
1608 1608
 
1609 1609
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:14
1610
-	__( 'Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso' ),
1610
+	__('Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso'),
1611 1611
 
1612 1612
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:17
1613
-	__( 'Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso' ),
1613
+	__('Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso'),
1614 1614
 
1615 1615
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1616
-	__( 'Disable reverse calculate', 'event_espresso' ),
1616
+	__('Disable reverse calculate', 'event_espresso'),
1617 1617
 
1618 1618
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1619
-	__( 'Enable reverse calculate', 'event_espresso' ),
1619
+	__('Enable reverse calculate', 'event_espresso'),
1620 1620
 
1621 1621
 	// Reference: packages/tpc/src/buttons/TicketPriceCalculatorButton.tsx:28
1622
-	__( 'ticket price calculator', 'event_espresso' ),
1622
+	__('ticket price calculator', 'event_espresso'),
1623 1623
 
1624 1624
 	// Reference: packages/tpc/src/buttons/taxes/AddDefaultTaxesButton.tsx:9
1625
-	__( 'Add default taxes', 'event_espresso' ),
1625
+	__('Add default taxes', 'event_espresso'),
1626 1626
 
1627 1627
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:10
1628
-	__( 'Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso' ),
1628
+	__('Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso'),
1629 1629
 
1630 1630
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:14
1631
-	__( 'Remove all taxes?', 'event_espresso' ),
1631
+	__('Remove all taxes?', 'event_espresso'),
1632 1632
 
1633 1633
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:7
1634
-	__( 'Remove taxes', 'event_espresso' ),
1634
+	__('Remove taxes', 'event_espresso'),
1635 1635
 
1636 1636
 	// Reference: packages/tpc/src/components/DefaultPricesInfo.tsx:29
1637
-	__( 'Modify default prices.', 'event_espresso' ),
1637
+	__('Modify default prices.', 'event_espresso'),
1638 1638
 
1639 1639
 	// Reference: packages/tpc/src/components/DefaultTaxesInfo.tsx:29
1640
-	__( 'New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso' ),
1640
+	__('New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso'),
1641 1641
 
1642 1642
 	// Reference: packages/tpc/src/components/LockedTicketsBanner.tsx:12
1643
-	__( 'Editing of prices is disabled', 'event_espresso' ),
1643
+	__('Editing of prices is disabled', 'event_espresso'),
1644 1644
 
1645 1645
 	// Reference: packages/tpc/src/components/NoPricesBanner/AddDefaultPricesButton.tsx:9
1646
-	__( 'Add default prices', 'event_espresso' ),
1646
+	__('Add default prices', 'event_espresso'),
1647 1647
 
1648 1648
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:13
1649
-	__( 'This Ticket is Currently Free', 'event_espresso' ),
1649
+	__('This Ticket is Currently Free', 'event_espresso'),
1650 1650
 
1651 1651
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:21
1652 1652
 	/* translators: %s default prices */
1653
-	__( 'Click the button below to load your %s into the calculator.', 'event_espresso' ),
1653
+	__('Click the button below to load your %s into the calculator.', 'event_espresso'),
1654 1654
 
1655 1655
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:22
1656
-	__( 'default prices', 'event_espresso' ),
1656
+	__('default prices', 'event_espresso'),
1657 1657
 
1658 1658
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:29
1659
-	__( 'Additional ticket price modifiers can be added or removed.', 'event_espresso' ),
1659
+	__('Additional ticket price modifiers can be added or removed.', 'event_espresso'),
1660 1660
 
1661 1661
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:32
1662
-	__( 'Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso' ),
1662
+	__('Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso'),
1663 1663
 
1664 1664
 	// Reference: packages/tpc/src/components/TicketPriceCalculatorModal.tsx:32
1665 1665
 	/* translators: %s ticket name */
1666
-	__( 'Price Calculator for Ticket: %s', 'event_espresso' ),
1666
+	__('Price Calculator for Ticket: %s', 'event_espresso'),
1667 1667
 
1668 1668
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:48
1669
-	__( 'Total', 'event_espresso' ),
1669
+	__('Total', 'event_espresso'),
1670 1670
 
1671 1671
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:57
1672
-	__( 'ticket total', 'event_espresso' ),
1672
+	__('ticket total', 'event_espresso'),
1673 1673
 
1674 1674
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:29
1675
-	__( 'Order', 'event_espresso' ),
1675
+	__('Order', 'event_espresso'),
1676 1676
 
1677 1677
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:35
1678
-	__( 'Price Type', 'event_espresso' ),
1678
+	__('Price Type', 'event_espresso'),
1679 1679
 
1680 1680
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:41
1681
-	__( 'Label', 'event_espresso' ),
1681
+	__('Label', 'event_espresso'),
1682 1682
 
1683 1683
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:53
1684
-	__( 'Amount', 'event_espresso' ),
1684
+	__('Amount', 'event_espresso'),
1685 1685
 
1686 1686
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:22
1687
-	__( 'Copy ticket', 'event_espresso' ),
1687
+	__('Copy ticket', 'event_espresso'),
1688 1688
 
1689 1689
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:26
1690
-	__( 'Copy and archive this ticket', 'event_espresso' ),
1690
+	__('Copy and archive this ticket', 'event_espresso'),
1691 1691
 
1692 1692
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:29
1693
-	__( 'OK', 'event_espresso' ),
1693
+	__('OK', 'event_espresso'),
1694 1694
 
1695 1695
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:32
1696
-	__( 'amount', 'event_espresso' ),
1696
+	__('amount', 'event_espresso'),
1697 1697
 
1698 1698
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:44
1699
-	__( 'amount…', 'event_espresso' ),
1699
+	__('amount…', 'event_espresso'),
1700 1700
 
1701 1701
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:14
1702
-	__( 'description…', 'event_espresso' ),
1702
+	__('description…', 'event_espresso'),
1703 1703
 
1704 1704
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:9
1705
-	__( 'price description', 'event_espresso' ),
1705
+	__('price description', 'event_espresso'),
1706 1706
 
1707 1707
 	// Reference: packages/tpc/src/inputs/PriceIdInput.tsx:5
1708
-	__( 'price id', 'event_espresso' ),
1708
+	__('price id', 'event_espresso'),
1709 1709
 
1710 1710
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:13
1711
-	__( 'label…', 'event_espresso' ),
1711
+	__('label…', 'event_espresso'),
1712 1712
 
1713 1713
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:8
1714
-	__( 'price name', 'event_espresso' ),
1714
+	__('price name', 'event_espresso'),
1715 1715
 
1716 1716
 	// Reference: packages/tpc/src/inputs/PriceOrderInput.tsx:14
1717
-	__( 'price order', 'event_espresso' ),
1717
+	__('price order', 'event_espresso'),
1718 1718
 
1719 1719
 	// Reference: packages/tpc/src/inputs/PriceTypeInput.tsx:19
1720
-	__( 'price type', 'event_espresso' ),
1720
+	__('price type', 'event_espresso'),
1721 1721
 
1722 1722
 	// Reference: packages/tpc/src/utils/constants.ts:8
1723
-	__( 'Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso' ),
1723
+	__('Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso'),
1724 1724
 
1725 1725
 	// Reference: packages/ui-components/src/ActiveFilters/ActiveFilters.tsx:8
1726
-	__( 'active filters:', 'event_espresso' ),
1726
+	__('active filters:', 'event_espresso'),
1727 1727
 
1728 1728
 	// Reference: packages/ui-components/src/ActiveFilters/FilterTag/index.tsx:15
1729 1729
 	/* translators: %s filter name */
1730
-	__( 'remove filter - %s', 'event_espresso' ),
1730
+	__('remove filter - %s', 'event_espresso'),
1731 1731
 
1732 1732
 	// Reference: packages/ui-components/src/CalendarDateRange/CalendarDateRange.tsx:37
1733
-	__( 'to', 'event_espresso' ),
1733
+	__('to', 'event_espresso'),
1734 1734
 
1735 1735
 	// Reference: packages/ui-components/src/CalendarPageDate/CalendarPageDate.tsx:54
1736
-	__( 'TO', 'event_espresso' ),
1736
+	__('TO', 'event_espresso'),
1737 1737
 
1738 1738
 	// Reference: packages/ui-components/src/ColorPicker/ColorPicker.tsx:60
1739
-	__( 'Custom color', 'event_espresso' ),
1739
+	__('Custom color', 'event_espresso'),
1740 1740
 
1741 1741
 	// Reference: packages/ui-components/src/ColorPicker/Swatch.tsx:23
1742 1742
 	/* translators: color name */
1743
-	__( 'Color: %s', 'event_espresso' ),
1743
+	__('Color: %s', 'event_espresso'),
1744 1744
 
1745 1745
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:13
1746
-	__( 'Cyan bluish gray', 'event_espresso' ),
1746
+	__('Cyan bluish gray', 'event_espresso'),
1747 1747
 
1748 1748
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:17
1749
-	__( 'White', 'event_espresso' ),
1749
+	__('White', 'event_espresso'),
1750 1750
 
1751 1751
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:21
1752
-	__( 'Pale pink', 'event_espresso' ),
1752
+	__('Pale pink', 'event_espresso'),
1753 1753
 
1754 1754
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:25
1755
-	__( 'Vivid red', 'event_espresso' ),
1755
+	__('Vivid red', 'event_espresso'),
1756 1756
 
1757 1757
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:29
1758
-	__( 'Luminous vivid orange', 'event_espresso' ),
1758
+	__('Luminous vivid orange', 'event_espresso'),
1759 1759
 
1760 1760
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:33
1761
-	__( 'Luminous vivid amber', 'event_espresso' ),
1761
+	__('Luminous vivid amber', 'event_espresso'),
1762 1762
 
1763 1763
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:37
1764
-	__( 'Light green cyan', 'event_espresso' ),
1764
+	__('Light green cyan', 'event_espresso'),
1765 1765
 
1766 1766
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:41
1767
-	__( 'Vivid green cyan', 'event_espresso' ),
1767
+	__('Vivid green cyan', 'event_espresso'),
1768 1768
 
1769 1769
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:45
1770
-	__( 'Pale cyan blue', 'event_espresso' ),
1770
+	__('Pale cyan blue', 'event_espresso'),
1771 1771
 
1772 1772
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:49
1773
-	__( 'Vivid cyan blue', 'event_espresso' ),
1773
+	__('Vivid cyan blue', 'event_espresso'),
1774 1774
 
1775 1775
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:53
1776
-	__( 'Vivid purple', 'event_espresso' ),
1776
+	__('Vivid purple', 'event_espresso'),
1777 1777
 
1778 1778
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:9
1779
-	__( 'Black', 'event_espresso' ),
1779
+	__('Black', 'event_espresso'),
1780 1780
 
1781 1781
 	// Reference: packages/ui-components/src/Confirm/ConfirmClose.tsx:7
1782 1782
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:22
1783
-	__( 'Are you sure you want to close this?', 'event_espresso' ),
1783
+	__('Are you sure you want to close this?', 'event_espresso'),
1784 1784
 
1785 1785
 	// Reference: packages/ui-components/src/Confirm/ConfirmDelete.tsx:7
1786
-	__( 'Are you sure you want to delete this?', 'event_espresso' ),
1786
+	__('Are you sure you want to delete this?', 'event_espresso'),
1787 1787
 
1788 1788
 	// Reference: packages/ui-components/src/Confirm/useConfirmWithButton.tsx:10
1789
-	__( 'Please confirm this action.', 'event_espresso' ),
1789
+	__('Please confirm this action.', 'event_espresso'),
1790 1790
 
1791 1791
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:32
1792
-	__( 'No', 'event_espresso' ),
1792
+	__('No', 'event_espresso'),
1793 1793
 
1794 1794
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:33
1795
-	__( 'Yes', 'event_espresso' ),
1795
+	__('Yes', 'event_espresso'),
1796 1796
 
1797 1797
 	// Reference: packages/ui-components/src/CurrencyDisplay/CurrencyDisplay.tsx:34
1798
-	__( 'free', 'event_espresso' ),
1798
+	__('free', 'event_espresso'),
1799 1799
 
1800 1800
 	// Reference: packages/ui-components/src/DateTimeRangePicker/DateTimeRangePicker.tsx:117
1801 1801
 	// Reference: packages/ui-components/src/Popover/PopoverForm/PopoverForm.tsx:44
1802
-	__( 'save', 'event_espresso' ),
1802
+	__('save', 'event_espresso'),
1803 1803
 
1804 1804
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
1805
-	__( 'Hide Debug Info', 'event_espresso' ),
1805
+	__('Hide Debug Info', 'event_espresso'),
1806 1806
 
1807 1807
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
1808
-	__( 'Show Debug Info', 'event_espresso' ),
1808
+	__('Show Debug Info', 'event_espresso'),
1809 1809
 
1810 1810
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:49
1811
-	__( 'Edit Start and End Dates and Times', 'event_espresso' ),
1811
+	__('Edit Start and End Dates and Times', 'event_espresso'),
1812 1812
 
1813 1813
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Copy.tsx:8
1814
-	__( 'copy', 'event_espresso' ),
1814
+	__('copy', 'event_espresso'),
1815 1815
 
1816 1816
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Edit.tsx:8
1817
-	__( 'edit', 'event_espresso' ),
1817
+	__('edit', 'event_espresso'),
1818 1818
 
1819 1819
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Trash.tsx:8
1820
-	__( 'trash', 'event_espresso' ),
1820
+	__('trash', 'event_espresso'),
1821 1821
 
1822 1822
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Untrash.tsx:8
1823
-	__( 'untrash', 'event_espresso' ),
1823
+	__('untrash', 'event_espresso'),
1824 1824
 
1825 1825
 	// Reference: packages/ui-components/src/EntityDetailsPanel/EntityDetailsPanelSold.tsx:37
1826
-	__( 'view approved registrations for this date.', 'event_espresso' ),
1826
+	__('view approved registrations for this date.', 'event_espresso'),
1827 1827
 
1828 1828
 	// Reference: packages/ui-components/src/EntityDetailsPanel/EntityDetailsPanelSold.tsx:38
1829
-	__( 'view approved registrations for this ticket.', 'event_espresso' ),
1829
+	__('view approved registrations for this ticket.', 'event_espresso'),
1830 1830
 
1831 1831
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/CardViewFilterButton.tsx:21
1832
-	__( 'card view', 'event_espresso' ),
1832
+	__('card view', 'event_espresso'),
1833 1833
 
1834 1834
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/TableViewFilterButton.tsx:20
1835
-	__( 'table view', 'event_espresso' ),
1835
+	__('table view', 'event_espresso'),
1836 1836
 
1837 1837
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
1838
-	__( 'hide bulk actions', 'event_espresso' ),
1838
+	__('hide bulk actions', 'event_espresso'),
1839 1839
 
1840 1840
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
1841
-	__( 'show bulk actions', 'event_espresso' ),
1841
+	__('show bulk actions', 'event_espresso'),
1842 1842
 
1843 1843
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:9
1844
-	__( 'hide filters', 'event_espresso' ),
1844
+	__('hide filters', 'event_espresso'),
1845 1845
 
1846 1846
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:9
1847
-	__( 'show filters', 'event_espresso' ),
1847
+	__('show filters', 'event_espresso'),
1848 1848
 
1849 1849
 	// Reference: packages/ui-components/src/Legend/ToggleLegendButton.tsx:26
1850
-	__( 'hide legend', 'event_espresso' ),
1850
+	__('hide legend', 'event_espresso'),
1851 1851
 
1852 1852
 	// Reference: packages/ui-components/src/Legend/ToggleLegendButton.tsx:26
1853
-	__( 'show legend', 'event_espresso' ),
1853
+	__('show legend', 'event_espresso'),
1854 1854
 
1855 1855
 	// Reference: packages/ui-components/src/LoadingNotice/LoadingNotice.tsx:11
1856
-	__( 'loading…', 'event_espresso' ),
1856
+	__('loading…', 'event_espresso'),
1857 1857
 
1858 1858
 	// Reference: packages/ui-components/src/Modal/Modal.tsx:58
1859
-	__( 'close modal', 'event_espresso' ),
1859
+	__('close modal', 'event_espresso'),
1860 1860
 
1861 1861
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:10
1862
-	__( 'jump to previous', 'event_espresso' ),
1862
+	__('jump to previous', 'event_espresso'),
1863 1863
 
1864 1864
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:11
1865
-	__( 'jump to next', 'event_espresso' ),
1865
+	__('jump to next', 'event_espresso'),
1866 1866
 
1867 1867
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:12
1868
-	__( 'page', 'event_espresso' ),
1868
+	__('page', 'event_espresso'),
1869 1869
 
1870 1870
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:8
1871
-	__( 'previous', 'event_espresso' ),
1871
+	__('previous', 'event_espresso'),
1872 1872
 
1873 1873
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:9
1874
-	__( 'next', 'event_espresso' ),
1874
+	__('next', 'event_espresso'),
1875 1875
 
1876 1876
 	// Reference: packages/ui-components/src/Pagination/PerPage.tsx:37
1877
-	__( 'items per page', 'event_espresso' ),
1877
+	__('items per page', 'event_espresso'),
1878 1878
 
1879 1879
 	// Reference: packages/ui-components/src/Pagination/constants.ts:10
1880 1880
 	/* translators: %s is per page value */
1881
-	__( '%s / page', 'event_espresso' ),
1881
+	__('%s / page', 'event_espresso'),
1882 1882
 
1883 1883
 	// Reference: packages/ui-components/src/Pagination/constants.ts:13
1884
-	__( 'Next Page', 'event_espresso' ),
1884
+	__('Next Page', 'event_espresso'),
1885 1885
 
1886 1886
 	// Reference: packages/ui-components/src/Pagination/constants.ts:14
1887
-	__( 'Previous Page', 'event_espresso' ),
1887
+	__('Previous Page', 'event_espresso'),
1888 1888
 
1889 1889
 	// Reference: packages/ui-components/src/PercentSign/index.tsx:10
1890
-	__( '%', 'event_espresso' ),
1890
+	__('%', 'event_espresso'),
1891 1891
 
1892 1892
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:23
1893
-	__( 'Select an existing one to use as a template.', 'event_espresso' ),
1893
+	__('Select an existing one to use as a template.', 'event_espresso'),
1894 1894
 
1895 1895
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:27
1896
-	__( 'or', 'event_espresso' ),
1896
+	__('or', 'event_espresso'),
1897 1897
 
1898 1898
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:30
1899
-	__( 'Add new and insert details manually', 'event_espresso' ),
1899
+	__('Add new and insert details manually', 'event_espresso'),
1900 1900
 
1901 1901
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:34
1902
-	__( 'Add New', 'event_espresso' ),
1902
+	__('Add New', 'event_espresso'),
1903 1903
 
1904 1904
 	// Reference: packages/ui-components/src/Stepper/buttons/Next.tsx:8
1905
-	__( 'Next', 'event_espresso' ),
1905
+	__('Next', 'event_espresso'),
1906 1906
 
1907 1907
 	// Reference: packages/ui-components/src/Stepper/buttons/Previous.tsx:8
1908
-	__( 'Previous', 'event_espresso' ),
1908
+	__('Previous', 'event_espresso'),
1909 1909
 
1910 1910
 	// Reference: packages/ui-components/src/Steps/Steps.tsx:31
1911
-	__( 'Steps', 'event_espresso' ),
1911
+	__('Steps', 'event_espresso'),
1912 1912
 
1913 1913
 	// Reference: packages/ui-components/src/TabbableText/index.tsx:19
1914
-	__( 'Click to edit…', 'event_espresso' ),
1914
+	__('Click to edit…', 'event_espresso'),
1915 1915
 
1916 1916
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:14
1917
-	__( 'The Website\'s Time Zone', 'event_espresso' ),
1917
+	__('The Website\'s Time Zone', 'event_espresso'),
1918 1918
 
1919 1919
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:19
1920
-	__( 'UTC (Greenwich Mean Time)', 'event_espresso' ),
1920
+	__('UTC (Greenwich Mean Time)', 'event_espresso'),
1921 1921
 
1922 1922
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:9
1923
-	__( 'Your Local Time Zone', 'event_espresso' ),
1923
+	__('Your Local Time Zone', 'event_espresso'),
1924 1924
 
1925 1925
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:27
1926
-	__( 'click for timezone information', 'event_espresso' ),
1926
+	__('click for timezone information', 'event_espresso'),
1927 1927
 
1928 1928
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:32
1929
-	__( 'This Date Converted To:', 'event_espresso' ),
1929
+	__('This Date Converted To:', 'event_espresso'),
1930 1930
 
1931 1931
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:51
1932
-	__( 'select all', 'event_espresso' ),
1932
+	__('select all', 'event_espresso'),
1933 1933
 
1934 1934
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:54
1935
-	__( 'apply', 'event_espresso' )
1935
+	__('apply', 'event_espresso')
1936 1936
 );
1937 1937
 /* THIS IS THE END OF THE GENERATED FILE */
Please login to merge, or discard this patch.