Completed
Branch FET/update-messages-admin-requ... (ee19e8)
by
unknown
02:16 queued 15s
created
core/helpers/EEH_Form_Fields.helper.php 2 patches
Indentation   +1971 added lines, -1971 removed lines patch added patch discarded remove patch
@@ -29,1997 +29,1997 @@
 block discarded – undo
29 29
 {
30 30
 
31 31
 
32
-    /**
33
-     *  Generates HTML for the forms used on admin pages
34
-     *
35
-     *
36
-     * @static
37
-     * @access public
38
-     * @param array $input_vars - array of input field details
39
-     *                          format:
40
-     *                          $template_form_fields['field-id'] = array(
41
-     *                          'name' => 'name_attribute',
42
-     *                          'label' => esc_html__('Field Label', 'event_espresso'), //or false
43
-     *                          'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden',
44
-     *                          'checkbox', 'wp_editor'
45
-     *                          'type' => 'int', //what "type" the value is (i.e. string, int etc)
46
-     *                          'required' => false, //boolean for whether the field is required
47
-     *                          'validation' => true, //boolean, whether to validate the field (todo)
48
-     *                          'value' => 'some_value_for_field', //what value is used for field
49
-     *                          'format' => '%d', //what format the value is (%d, %f, or %s)
50
-     *                          'db-col' => 'column_in_db' //used to indicate which column the field corresponds with
51
-     *                          in the db
52
-     *                          'options' => optiona, optionb || array('value' => 'label', '') //if the input type is
53
-     *                          "select", this allows you to set the args for the different <option> tags.
54
-     *                          'tabindex' => 1 //this allows you to set the tabindex for the field.
55
-     *                          'append_content' => '' //this allows you to send in html content to append to the
56
-     *                          field.
57
-     *                          )
58
-     * @param array $form_id    - used for defining unique identifiers for the form.
59
-     * @return string
60
-     * @todo   : at some point we can break this down into other static methods to abstract it a bit better.
61
-     */
62
-    public static function get_form_fields($input_vars = [], $form_id = false)
63
-    {
64
-
65
-        if (empty($input_vars)) {
66
-            EE_Error::add_error(
67
-                esc_html__('missing required variables for the form field generator', 'event_espresso'),
68
-                __FILE__,
69
-                __FUNCTION__,
70
-                __LINE__
71
-            );
72
-            return false;
73
-        }
74
-
75
-        $output        = "";
76
-        $inputs        = [];
77
-        $hidden_inputs = [];
78
-
79
-        // cycle thru inputs
80
-        foreach ($input_vars as $input_key => $input_value) {
81
-            $defaults = [
82
-                'append_content' => '',
83
-                'css_class'      => '',
84
-                'cols'           => 80,
85
-                'db-col'         => 'column_in_db',
86
-                'format'         => '%d',
87
-                'input'          => 'hidden',
88
-                'label'          => esc_html__('No label', 'event_espresso'),
89
-                'name'           => $input_key,
90
-                'options'        => [],
91
-                'required'       => false,
92
-                'tabindex'       => 0,
93
-                'rows'           => 10,
94
-                'type'           => 'int',
95
-                'validation'     => true,
96
-                'value'          => 'some_value_for_field',
97
-            ];
98
-
99
-            $input_value = wp_parse_args($input_value, $defaults);
100
-
101
-            $append_content = $input_value['append_content'];
102
-            $css_class      = $input_value['css_class'];
103
-            $cols           = $input_value['cols'];
104
-            $label          = $input_value['label'];
105
-            $name           = $input_value['name'];
106
-            $options        = $input_value['options'];
107
-            $required       = $input_value['required'];
108
-            $tab_index      = $input_value['tabindex'];
109
-            $rows           = $input_value['rows'];
110
-            $type           = $input_value['input'];
111
-            $value          = $input_value['value'];
112
-
113
-            $id    = $form_id ? $form_id . '-' . $input_key : $input_key;
114
-            $class = $required ? 'required ' . $css_class : $css_class;
115
-
116
-            // what type of input are we dealing with ?
117
-            switch ($type) {
118
-                case 'checkbox':
119
-                case 'radio':
120
-                    $field = self::adminMulti($value, $class, $id, $name, $required, $tab_index, $type, 1, $label);
121
-                    $field .= $append_content ?: '';
122
-                    break;
123
-
124
-                case 'hidden':
125
-                    $field           = null;
126
-                    $hidden_inputs[] = self::adminHidden($css_class, $id, $name, $value);
127
-                    break;
128
-
129
-                case 'select':
130
-                    $options = is_array($options) ? $options : explode(',', $options);
131
-                    $field   = self::adminLabel($id, $label, $required);
132
-                    $field   .= self::adminSelect($value, $class, $id, $name, $required, $tab_index, $options);
133
-                    $field   .= $append_content ?: '';
134
-                    break;
135
-
136
-                case 'textarea':
137
-                    $field = self::adminLabel($id, $label, $required);
138
-                    $field .= self::adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value);
139
-                    $field .= $append_content ?: '';
140
-                    break;
141
-
142
-                case 'wp_editor':
143
-                    $label = esc_html($label);
144
-                    $field = "<h4>{$label}</h4>";
145
-                    $field .= $append_content ?: '';
146
-                    $field .= self::adminWpEditor(
147
-                        $class,
148
-                        $id,
149
-                        $name,
150
-                        $rows,
151
-                        $tab_index,
152
-                        $value
153
-                    );
154
-                    break;
155
-
156
-                default:
157
-                    $field = self::adminLabel($id, $label, $required);
158
-                    $field .= self::adminText($class, $id, $name, $required, $tab_index, $value);
159
-                    $field .= $append_content ?: '';
160
-            }
161
-            if ($field) {
162
-                $inputs[] = $field;
163
-            }
164
-        } // end foreach( $input_vars as $input_key => $input_value )
165
-
166
-        if (! empty($inputs)) {
167
-            $glue   = "
32
+	/**
33
+	 *  Generates HTML for the forms used on admin pages
34
+	 *
35
+	 *
36
+	 * @static
37
+	 * @access public
38
+	 * @param array $input_vars - array of input field details
39
+	 *                          format:
40
+	 *                          $template_form_fields['field-id'] = array(
41
+	 *                          'name' => 'name_attribute',
42
+	 *                          'label' => esc_html__('Field Label', 'event_espresso'), //or false
43
+	 *                          'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden',
44
+	 *                          'checkbox', 'wp_editor'
45
+	 *                          'type' => 'int', //what "type" the value is (i.e. string, int etc)
46
+	 *                          'required' => false, //boolean for whether the field is required
47
+	 *                          'validation' => true, //boolean, whether to validate the field (todo)
48
+	 *                          'value' => 'some_value_for_field', //what value is used for field
49
+	 *                          'format' => '%d', //what format the value is (%d, %f, or %s)
50
+	 *                          'db-col' => 'column_in_db' //used to indicate which column the field corresponds with
51
+	 *                          in the db
52
+	 *                          'options' => optiona, optionb || array('value' => 'label', '') //if the input type is
53
+	 *                          "select", this allows you to set the args for the different <option> tags.
54
+	 *                          'tabindex' => 1 //this allows you to set the tabindex for the field.
55
+	 *                          'append_content' => '' //this allows you to send in html content to append to the
56
+	 *                          field.
57
+	 *                          )
58
+	 * @param array $form_id    - used for defining unique identifiers for the form.
59
+	 * @return string
60
+	 * @todo   : at some point we can break this down into other static methods to abstract it a bit better.
61
+	 */
62
+	public static function get_form_fields($input_vars = [], $form_id = false)
63
+	{
64
+
65
+		if (empty($input_vars)) {
66
+			EE_Error::add_error(
67
+				esc_html__('missing required variables for the form field generator', 'event_espresso'),
68
+				__FILE__,
69
+				__FUNCTION__,
70
+				__LINE__
71
+			);
72
+			return false;
73
+		}
74
+
75
+		$output        = "";
76
+		$inputs        = [];
77
+		$hidden_inputs = [];
78
+
79
+		// cycle thru inputs
80
+		foreach ($input_vars as $input_key => $input_value) {
81
+			$defaults = [
82
+				'append_content' => '',
83
+				'css_class'      => '',
84
+				'cols'           => 80,
85
+				'db-col'         => 'column_in_db',
86
+				'format'         => '%d',
87
+				'input'          => 'hidden',
88
+				'label'          => esc_html__('No label', 'event_espresso'),
89
+				'name'           => $input_key,
90
+				'options'        => [],
91
+				'required'       => false,
92
+				'tabindex'       => 0,
93
+				'rows'           => 10,
94
+				'type'           => 'int',
95
+				'validation'     => true,
96
+				'value'          => 'some_value_for_field',
97
+			];
98
+
99
+			$input_value = wp_parse_args($input_value, $defaults);
100
+
101
+			$append_content = $input_value['append_content'];
102
+			$css_class      = $input_value['css_class'];
103
+			$cols           = $input_value['cols'];
104
+			$label          = $input_value['label'];
105
+			$name           = $input_value['name'];
106
+			$options        = $input_value['options'];
107
+			$required       = $input_value['required'];
108
+			$tab_index      = $input_value['tabindex'];
109
+			$rows           = $input_value['rows'];
110
+			$type           = $input_value['input'];
111
+			$value          = $input_value['value'];
112
+
113
+			$id    = $form_id ? $form_id . '-' . $input_key : $input_key;
114
+			$class = $required ? 'required ' . $css_class : $css_class;
115
+
116
+			// what type of input are we dealing with ?
117
+			switch ($type) {
118
+				case 'checkbox':
119
+				case 'radio':
120
+					$field = self::adminMulti($value, $class, $id, $name, $required, $tab_index, $type, 1, $label);
121
+					$field .= $append_content ?: '';
122
+					break;
123
+
124
+				case 'hidden':
125
+					$field           = null;
126
+					$hidden_inputs[] = self::adminHidden($css_class, $id, $name, $value);
127
+					break;
128
+
129
+				case 'select':
130
+					$options = is_array($options) ? $options : explode(',', $options);
131
+					$field   = self::adminLabel($id, $label, $required);
132
+					$field   .= self::adminSelect($value, $class, $id, $name, $required, $tab_index, $options);
133
+					$field   .= $append_content ?: '';
134
+					break;
135
+
136
+				case 'textarea':
137
+					$field = self::adminLabel($id, $label, $required);
138
+					$field .= self::adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value);
139
+					$field .= $append_content ?: '';
140
+					break;
141
+
142
+				case 'wp_editor':
143
+					$label = esc_html($label);
144
+					$field = "<h4>{$label}</h4>";
145
+					$field .= $append_content ?: '';
146
+					$field .= self::adminWpEditor(
147
+						$class,
148
+						$id,
149
+						$name,
150
+						$rows,
151
+						$tab_index,
152
+						$value
153
+					);
154
+					break;
155
+
156
+				default:
157
+					$field = self::adminLabel($id, $label, $required);
158
+					$field .= self::adminText($class, $id, $name, $required, $tab_index, $value);
159
+					$field .= $append_content ?: '';
160
+			}
161
+			if ($field) {
162
+				$inputs[] = $field;
163
+			}
164
+		} // end foreach( $input_vars as $input_key => $input_value )
165
+
166
+		if (! empty($inputs)) {
167
+			$glue   = "
168 168
                 </li>
169 169
                 <li>
170 170
                     ";
171
-            $inputs = implode($glue, $inputs);
172
-            $output = "
171
+			$inputs = implode($glue, $inputs);
172
+			$output = "
173 173
             <ul>
174 174
                 <li>
175 175
                 {$inputs} 
176 176
                 </li>
177 177
             </ul>
178 178
             ";
179
-        }
180
-        return $output . implode("\n", $hidden_inputs);
181
-    }
182
-
183
-
184
-    /**
185
-     * form_fields_array
186
-     * This utility function assembles form fields from a given structured array with field information.
187
-     * //TODO: This is an alternate generator that we may want to use instead.
188
-     *
189
-     * @param array $fields structured array of fields to assemble in the following format:
190
-     *                      [field_name] => array(
191
-     *                      ['label'] => 'label for field',
192
-     *                      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select
193
-     *                      type of field you can indicated the labels for each option via this index
194
-     *                      ['extra_desc'] => 'extra description for the field', //optional
195
-     *                      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults
196
-     *                      to text
197
-     *                      ['value'] => 'value that goes in the field', //(if multi then this is an array of values
198
-     *                      and the 'default' paramater will be used for what is selected)
199
-     *                      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
200
-     *                      ['class'] => 'name-of-class(es)-for-input',
201
-     *                      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi
202
-     *                      select type of field you can indicate the css class for each option via this index.
203
-     *                      ['id'] => 'css-id-for-input') //defaults to 'field_name'
204
-     *                      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields
205
-     *                      generated are going to be used in a loop and you want to make sure that the field
206
-     *                      identifiers are unique from each other.
207
-     *                      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types
208
-     *                      such as textarea to indicate cols/rows.
209
-     *                      ['tabindex'] => '' //this allows you to set the tabindex for the field.
210
-     *                      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally
211
-     *                      contain an array of arguments for the editor setup.
212
-     *
213
-     * @return array         an array of inputs for form indexed by field name, and in the following structure:
214
-     *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
215
-     */
216
-    public static function get_form_fields_array($fields)
217
-    {
218
-
219
-        $form_fields = [];
220
-        $fields      = (array) $fields;
221
-
222
-        foreach ($fields as $field_name => $field_atts) {
223
-            // defaults:
224
-            $defaults = [
225
-                'class'         => '',
226
-                'classes'       => '',
227
-                'default'       => '',
228
-                'dimensions'    => ['10', '5'],
229
-                'extra_desc'    => '',
230
-                'id'            => $field_name,
231
-                'label'         => '',
232
-                'labels'        => '',
233
-                'required'      => false,
234
-                'tabindex'      => 0,
235
-                'type'          => 'text',
236
-                'unique_id'     => '',
237
-                'value'         => '',
238
-                'wpeditor_args' => [],
239
-            ];
240
-            // merge defaults with passed arguments
241
-            $_fields = wp_parse_args($field_atts, $defaults);
242
-
243
-            $class          = $_fields['class'];
244
-            $classes        = $_fields['classes'];
245
-            $default        = $_fields['default'];
246
-            $dims           = $_fields['dimensions'];
247
-            $extra_desc     = $_fields['extra_desc'];
248
-            $id             = $_fields['id'];
249
-            $label          = $_fields['label'];
250
-            $labels         = $_fields['labels'];
251
-            $required       = $_fields['required'];
252
-            $tab_index      = $_fields['tabindex'];
253
-            $type           = $_fields['type'];
254
-            $unique_id      = $_fields['unique_id'];
255
-            $value          = $_fields['value'];
256
-            $wp_editor_args = $_fields['wpeditor_args'];
257
-
258
-            // generate label
259
-            $label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
260
-            // generate field name
261
-            $name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
262
-
263
-            // we determine what we're building based on the type
264
-            switch ($type) {
265
-                case 'checkbox':
266
-                case 'radio':
267
-                    if (is_array($value)) {
268
-                        $c_input = '';
269
-                        foreach ($value as $key => $val) {
270
-                            $c_input .= self::adminMulti(
271
-                                $default,
272
-                                isset($classes[ $key ]) ? $classes[ $key ] : '',
273
-                                $field_name . '_' . $value,
274
-                                $name,
275
-                                $required,
276
-                                $tab_index,
277
-                                $type,
278
-                                $val,
279
-                                isset($labels[ $key ]) ? $labels[ $key ] : ''
280
-                            );
281
-                        }
282
-                        $field = $c_input;
283
-                    } else {
284
-                        $field = self::adminMulti(
285
-                            $default,
286
-                            $class,
287
-                            $id,
288
-                            $name,
289
-                            $required,
290
-                            $tab_index,
291
-                            $type,
292
-                            $value,
293
-                            $_fields['label']
294
-                        );
295
-                    }
296
-                    break;
297
-
298
-                case 'hidden':
299
-                    $field = self::adminHidden($class, $id, $name, $value);
300
-                    break;
301
-
302
-                case 'select':
303
-                    $options = [];
304
-                    foreach ($value as $key => $val) {
305
-                        $options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
306
-                    }
307
-                    $field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
308
-                    break;
309
-
310
-                case 'textarea':
311
-                    $field =
312
-                        self::adminTextarea($class, $dims[0], $id, $name, $required, $dims[1], $tab_index, $value);
313
-                    break;
314
-
315
-                case 'wp_editor':
316
-                    $field = self::adminWpEditor(
317
-                        $class,
318
-                        $_fields['id'],
319
-                        $name,
320
-                        $dims[1],
321
-                        $tab_index,
322
-                        $value,
323
-                        $wp_editor_args
324
-                    );
325
-                    break;
326
-
327
-                default:
328
-                    $field = self::adminText($class, $id, $name, $required, $tab_index, $value);
329
-            }
330
-
331
-            $form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
332
-        }
333
-
334
-        return $form_fields;
335
-    }
336
-
337
-
338
-    /**
339
-     * @param string $class
340
-     * @param string $id
341
-     * @param string $name
342
-     * @param string $value
343
-     * @return string
344
-     * @since   4.10.14.p
345
-     */
346
-    private static function adminHidden($class, $id, $name, $value)
347
-    {
348
-        $id    = esc_attr($id);
349
-        $name  = esc_attr($name);
350
-        $class = esc_attr($class);
351
-        return "
179
+		}
180
+		return $output . implode("\n", $hidden_inputs);
181
+	}
182
+
183
+
184
+	/**
185
+	 * form_fields_array
186
+	 * This utility function assembles form fields from a given structured array with field information.
187
+	 * //TODO: This is an alternate generator that we may want to use instead.
188
+	 *
189
+	 * @param array $fields structured array of fields to assemble in the following format:
190
+	 *                      [field_name] => array(
191
+	 *                      ['label'] => 'label for field',
192
+	 *                      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select
193
+	 *                      type of field you can indicated the labels for each option via this index
194
+	 *                      ['extra_desc'] => 'extra description for the field', //optional
195
+	 *                      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults
196
+	 *                      to text
197
+	 *                      ['value'] => 'value that goes in the field', //(if multi then this is an array of values
198
+	 *                      and the 'default' paramater will be used for what is selected)
199
+	 *                      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
200
+	 *                      ['class'] => 'name-of-class(es)-for-input',
201
+	 *                      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi
202
+	 *                      select type of field you can indicate the css class for each option via this index.
203
+	 *                      ['id'] => 'css-id-for-input') //defaults to 'field_name'
204
+	 *                      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields
205
+	 *                      generated are going to be used in a loop and you want to make sure that the field
206
+	 *                      identifiers are unique from each other.
207
+	 *                      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types
208
+	 *                      such as textarea to indicate cols/rows.
209
+	 *                      ['tabindex'] => '' //this allows you to set the tabindex for the field.
210
+	 *                      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally
211
+	 *                      contain an array of arguments for the editor setup.
212
+	 *
213
+	 * @return array         an array of inputs for form indexed by field name, and in the following structure:
214
+	 *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
215
+	 */
216
+	public static function get_form_fields_array($fields)
217
+	{
218
+
219
+		$form_fields = [];
220
+		$fields      = (array) $fields;
221
+
222
+		foreach ($fields as $field_name => $field_atts) {
223
+			// defaults:
224
+			$defaults = [
225
+				'class'         => '',
226
+				'classes'       => '',
227
+				'default'       => '',
228
+				'dimensions'    => ['10', '5'],
229
+				'extra_desc'    => '',
230
+				'id'            => $field_name,
231
+				'label'         => '',
232
+				'labels'        => '',
233
+				'required'      => false,
234
+				'tabindex'      => 0,
235
+				'type'          => 'text',
236
+				'unique_id'     => '',
237
+				'value'         => '',
238
+				'wpeditor_args' => [],
239
+			];
240
+			// merge defaults with passed arguments
241
+			$_fields = wp_parse_args($field_atts, $defaults);
242
+
243
+			$class          = $_fields['class'];
244
+			$classes        = $_fields['classes'];
245
+			$default        = $_fields['default'];
246
+			$dims           = $_fields['dimensions'];
247
+			$extra_desc     = $_fields['extra_desc'];
248
+			$id             = $_fields['id'];
249
+			$label          = $_fields['label'];
250
+			$labels         = $_fields['labels'];
251
+			$required       = $_fields['required'];
252
+			$tab_index      = $_fields['tabindex'];
253
+			$type           = $_fields['type'];
254
+			$unique_id      = $_fields['unique_id'];
255
+			$value          = $_fields['value'];
256
+			$wp_editor_args = $_fields['wpeditor_args'];
257
+
258
+			// generate label
259
+			$label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
260
+			// generate field name
261
+			$name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
262
+
263
+			// we determine what we're building based on the type
264
+			switch ($type) {
265
+				case 'checkbox':
266
+				case 'radio':
267
+					if (is_array($value)) {
268
+						$c_input = '';
269
+						foreach ($value as $key => $val) {
270
+							$c_input .= self::adminMulti(
271
+								$default,
272
+								isset($classes[ $key ]) ? $classes[ $key ] : '',
273
+								$field_name . '_' . $value,
274
+								$name,
275
+								$required,
276
+								$tab_index,
277
+								$type,
278
+								$val,
279
+								isset($labels[ $key ]) ? $labels[ $key ] : ''
280
+							);
281
+						}
282
+						$field = $c_input;
283
+					} else {
284
+						$field = self::adminMulti(
285
+							$default,
286
+							$class,
287
+							$id,
288
+							$name,
289
+							$required,
290
+							$tab_index,
291
+							$type,
292
+							$value,
293
+							$_fields['label']
294
+						);
295
+					}
296
+					break;
297
+
298
+				case 'hidden':
299
+					$field = self::adminHidden($class, $id, $name, $value);
300
+					break;
301
+
302
+				case 'select':
303
+					$options = [];
304
+					foreach ($value as $key => $val) {
305
+						$options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
306
+					}
307
+					$field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
308
+					break;
309
+
310
+				case 'textarea':
311
+					$field =
312
+						self::adminTextarea($class, $dims[0], $id, $name, $required, $dims[1], $tab_index, $value);
313
+					break;
314
+
315
+				case 'wp_editor':
316
+					$field = self::adminWpEditor(
317
+						$class,
318
+						$_fields['id'],
319
+						$name,
320
+						$dims[1],
321
+						$tab_index,
322
+						$value,
323
+						$wp_editor_args
324
+					);
325
+					break;
326
+
327
+				default:
328
+					$field = self::adminText($class, $id, $name, $required, $tab_index, $value);
329
+			}
330
+
331
+			$form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
332
+		}
333
+
334
+		return $form_fields;
335
+	}
336
+
337
+
338
+	/**
339
+	 * @param string $class
340
+	 * @param string $id
341
+	 * @param string $name
342
+	 * @param string $value
343
+	 * @return string
344
+	 * @since   4.10.14.p
345
+	 */
346
+	private static function adminHidden($class, $id, $name, $value)
347
+	{
348
+		$id    = esc_attr($id);
349
+		$name  = esc_attr($name);
350
+		$class = esc_attr($class);
351
+		return "
352 352
         <input name='{$name}' type='hidden' id='{$id}' class='{$class}' value='{$value}' />";
353
-    }
354
-
355
-
356
-    /**
357
-     * @param string $id
358
-     * @param string $label
359
-     * @param string $required
360
-     * @return string
361
-     * @since   4.10.14.p
362
-     */
363
-    private static function adminLabel($id, $label, $required)
364
-    {
365
-        $id       = esc_attr($id);
366
-        $label    = esc_html($label);
367
-        $required = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? " <span>*</span>" : '';
368
-        return "<label for='{$id}'>{$label}{$required}</label>";
369
-    }
370
-
371
-
372
-    /**
373
-     * @param string $default
374
-     * @param string $class
375
-     * @param string $id
376
-     * @param string $name
377
-     * @param string $required
378
-     * @param int    $tab_index
379
-     * @param string $type
380
-     * @param string $value
381
-     * @param string $label
382
-     * @return string
383
-     * @since   4.10.14.p
384
-     */
385
-    private static function adminMulti($default, $class, $id, $name, $required, $tab_index, $type, $value, $label = '')
386
-    {
387
-        $id        = esc_attr($id);
388
-        $name      = esc_attr($name);
389
-        $class     = esc_attr($class);
390
-        $tab_index = absint($tab_index);
391
-        $checked   = ! empty($default) && $default == $value ? 'checked="checked" ' : '';
392
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
393
-        $input     = "
353
+	}
354
+
355
+
356
+	/**
357
+	 * @param string $id
358
+	 * @param string $label
359
+	 * @param string $required
360
+	 * @return string
361
+	 * @since   4.10.14.p
362
+	 */
363
+	private static function adminLabel($id, $label, $required)
364
+	{
365
+		$id       = esc_attr($id);
366
+		$label    = esc_html($label);
367
+		$required = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? " <span>*</span>" : '';
368
+		return "<label for='{$id}'>{$label}{$required}</label>";
369
+	}
370
+
371
+
372
+	/**
373
+	 * @param string $default
374
+	 * @param string $class
375
+	 * @param string $id
376
+	 * @param string $name
377
+	 * @param string $required
378
+	 * @param int    $tab_index
379
+	 * @param string $type
380
+	 * @param string $value
381
+	 * @param string $label
382
+	 * @return string
383
+	 * @since   4.10.14.p
384
+	 */
385
+	private static function adminMulti($default, $class, $id, $name, $required, $tab_index, $type, $value, $label = '')
386
+	{
387
+		$id        = esc_attr($id);
388
+		$name      = esc_attr($name);
389
+		$class     = esc_attr($class);
390
+		$tab_index = absint($tab_index);
391
+		$checked   = ! empty($default) && $default == $value ? 'checked="checked" ' : '';
392
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
393
+		$input     = "
394 394
         <input name='{$name}[]' type='{$type}' id='{$id}' class='{$class}' value='{$value}' {$checked} {$required} tabindex='{$tab_index}'/>";
395
-        if ($label === '') {
396
-            return $input;
397
-        }
398
-        $label = esc_html($label);
399
-        return "
395
+		if ($label === '') {
396
+			return $input;
397
+		}
398
+		$label = esc_html($label);
399
+		return "
400 400
         <label for='$id'>
401 401
             {$input}
402 402
             {$label}
403 403
         </label>";
404
-    }
405
-
406
-
407
-    /**
408
-     * @param string $default
409
-     * @param string $class
410
-     * @param string $id
411
-     * @param string $name
412
-     * @param string $required
413
-     * @param int    $tab_index
414
-     * @param array  $options
415
-     * @return string
416
-     * @since   4.10.14.p
417
-     */
418
-    private static function adminSelect($default, $class, $id, $name, $required, $tab_index, $options = [])
419
-    {
420
-        $options_array = [];
421
-        foreach ($options as $value => $label) {
422
-            $selected        = ! empty($default) && $default == $value ? 'selected="selected"' : '';
423
-            $value           = esc_attr($value);
424
-            $label           = wp_strip_all_tags($label);
425
-            $options_array[] = "<option value='{$value}' {$selected}>{$label}</option>";
426
-        }
427
-        $options_html = implode($options_array, "\n");
428
-        $id           = esc_attr($id);
429
-        $name         = esc_attr($name);
430
-        $class        = esc_attr($class);
431
-        $tab_index    = absint($tab_index);
432
-        $required     = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
433
-        return "
404
+	}
405
+
406
+
407
+	/**
408
+	 * @param string $default
409
+	 * @param string $class
410
+	 * @param string $id
411
+	 * @param string $name
412
+	 * @param string $required
413
+	 * @param int    $tab_index
414
+	 * @param array  $options
415
+	 * @return string
416
+	 * @since   4.10.14.p
417
+	 */
418
+	private static function adminSelect($default, $class, $id, $name, $required, $tab_index, $options = [])
419
+	{
420
+		$options_array = [];
421
+		foreach ($options as $value => $label) {
422
+			$selected        = ! empty($default) && $default == $value ? 'selected="selected"' : '';
423
+			$value           = esc_attr($value);
424
+			$label           = wp_strip_all_tags($label);
425
+			$options_array[] = "<option value='{$value}' {$selected}>{$label}</option>";
426
+		}
427
+		$options_html = implode($options_array, "\n");
428
+		$id           = esc_attr($id);
429
+		$name         = esc_attr($name);
430
+		$class        = esc_attr($class);
431
+		$tab_index    = absint($tab_index);
432
+		$required     = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
433
+		return "
434 434
         <select name='{$name}' id='{$id}' class='{$class}' {$required} tabindex='{$tab_index}'>
435 435
             {$options_html}
436 436
         </select>";
437
-    }
438
-
439
-
440
-    /**
441
-     * @param string $class
442
-     * @param string $id
443
-     * @param string $name
444
-     * @param string $required
445
-     * @param int    $tab_index
446
-     * @param string $value
447
-     * @return string
448
-     * @since   4.10.14.p
449
-     */
450
-    private static function adminText($class, $id, $name, $required, $tab_index, $value)
451
-    {
452
-        $id        = esc_attr($id);
453
-        $name      = esc_attr($name);
454
-        $class     = esc_attr($class);
455
-        $tab_index = absint($tab_index);
456
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
457
-        return "
437
+	}
438
+
439
+
440
+	/**
441
+	 * @param string $class
442
+	 * @param string $id
443
+	 * @param string $name
444
+	 * @param string $required
445
+	 * @param int    $tab_index
446
+	 * @param string $value
447
+	 * @return string
448
+	 * @since   4.10.14.p
449
+	 */
450
+	private static function adminText($class, $id, $name, $required, $tab_index, $value)
451
+	{
452
+		$id        = esc_attr($id);
453
+		$name      = esc_attr($name);
454
+		$class     = esc_attr($class);
455
+		$tab_index = absint($tab_index);
456
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
457
+		return "
458 458
         <input name='{$name}' type='text' id='{$id}' class='{$class}' value='{$value}' {$required} tabindex='{$tab_index}'/>";
459
-    }
460
-
461
-
462
-    /**
463
-     * @param string $class
464
-     * @param int    $cols
465
-     * @param string $id
466
-     * @param string $name
467
-     * @param string $required
468
-     * @param int    $rows
469
-     * @param int    $tab_index
470
-     * @param string $value
471
-     * @return string
472
-     * @since   4.10.14.p
473
-     */
474
-    private static function adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value)
475
-    {
476
-        $id        = esc_attr($id);
477
-        $name      = esc_attr($name);
478
-        $class     = esc_attr($class);
479
-        $cols      = absint($cols);
480
-        $rows      = absint($rows);
481
-        $value     = esc_textarea($value);
482
-        $tab_index = absint($tab_index);
483
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
484
-        return "
459
+	}
460
+
461
+
462
+	/**
463
+	 * @param string $class
464
+	 * @param int    $cols
465
+	 * @param string $id
466
+	 * @param string $name
467
+	 * @param string $required
468
+	 * @param int    $rows
469
+	 * @param int    $tab_index
470
+	 * @param string $value
471
+	 * @return string
472
+	 * @since   4.10.14.p
473
+	 */
474
+	private static function adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value)
475
+	{
476
+		$id        = esc_attr($id);
477
+		$name      = esc_attr($name);
478
+		$class     = esc_attr($class);
479
+		$cols      = absint($cols);
480
+		$rows      = absint($rows);
481
+		$value     = esc_textarea($value);
482
+		$tab_index = absint($tab_index);
483
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
484
+		return "
485 485
         <textarea name='{$name}' id='{$id}' class='{$class}' rows='{$rows}' cols='{$cols}' {$required} tabindex='{$tab_index}'>
486 486
             {$value}
487 487
         </textarea>";
488
-    }
489
-
490
-
491
-    /**
492
-     * @param string $class
493
-     * @param string $id
494
-     * @param string $name
495
-     * @param int    $rows
496
-     * @param int    $tab_index
497
-     * @param string $value
498
-     * @param array  $wp_editor_args
499
-     * @return false|string
500
-     * @since   4.10.14.p
501
-     */
502
-    private static function adminWpEditor($class, $id, $name, $rows, $tab_index, $value, $wp_editor_args = [])
503
-    {
504
-        $editor_settings = $wp_editor_args + [
505
-                'textarea_name' => esc_attr($name),
506
-                'textarea_rows' => absint($rows),
507
-                'editor_class'  => esc_attr($class),
508
-                'tabindex'      => absint($tab_index),
509
-            ];
510
-        ob_start();
511
-        wp_editor($value, esc_attr($id), $editor_settings);
512
-        return ob_get_clean();
513
-    }
514
-
515
-
516
-    /**
517
-     * espresso admin page select_input
518
-     * Turns an array into a select fields
519
-     *
520
-     * @static
521
-     * @access public
522
-     * @param string  $name       field name
523
-     * @param array   $values     option values, numbered array starting at 0, where each value is an array with a key
524
-     *                            'text' (meaning text to display' and 'id' (meaning the internal value) eg:
525
-     *                            array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or
526
-     *                            as an array of key-value pairs, where the key is to be used for the select input's
527
-     *                            name, and the value will be the text shown to the user.  Optionally you can also
528
-     *                            include an additional key of "class" which will add a specific class to the option
529
-     *                            for that value.
530
-     * @param string  $default    default value
531
-     * @param string  $parameters extra parameters
532
-     * @param string  $class      css class
533
-     * @param boolean $autosize   whether to autosize the select or not
534
-     * @return string              html string for the select input
535
-     */
536
-    public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
537
-    {
538
-        // if $values was submitted in the wrong format, convert it over
539
-        if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
540
-            $converted_values = [];
541
-            foreach ($values as $id => $text) {
542
-                $converted_values[] = ['id' => $id, 'text' => $text];
543
-            }
544
-            $values = $converted_values;
545
-        }
546
-
547
-        $field =
548
-            '<select id="' . EEH_Formatter::ee_tep_output_string($name)
549
-            . '" name="' . EEH_Formatter::ee_tep_output_string($name)
550
-            . '"';
551
-
552
-        if (EEH_Formatter::ee_tep_not_null($parameters)) {
553
-            $field .= ' ' . $parameters;
554
-        }
555
-        if ($autosize) {
556
-            $size = 'med';
557
-            for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
558
-                if ($values[ $ii ]['text']) {
559
-                    if (strlen($values[ $ii ]['text']) > 5) {
560
-                        $size = 'wide';
561
-                    }
562
-                }
563
-            }
564
-        } else {
565
-            $size = '';
566
-        }
567
-
568
-        $field .= ' class="' . $class . ' ' . $size . '">';
569
-
570
-        if (empty($default) && isset($GLOBALS[ $name ])) {
571
-            $default = stripslashes($GLOBALS[ $name ]);
572
-        }
573
-
574
-
575
-        for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
576
-            $field .= '<option value="' . $values[ $i ]['id'] . '"';
577
-            if ($default == $values[ $i ]['id']) {
578
-                $field .= ' selected = "selected"';
579
-            }
580
-            if (isset($values[ $i ]['class'])) {
581
-                $field .= ' class="' . $values[ $i ]['class'] . '"';
582
-            }
583
-            $field .= '>' . $values[ $i ]['text'] . '</option>';
584
-        }
585
-        $field .= '</select>';
586
-
587
-        return $field;
588
-    }
589
-
590
-
591
-    /**
592
-     * generate_question_groups_html
593
-     *
594
-     * @param array  $question_groups
595
-     * @param string $group_wrapper
596
-     * @return string HTML
597
-     * @throws EE_Error
598
-     * @throws ReflectionException
599
-     */
600
-    public static function generate_question_groups_html($question_groups = [], $group_wrapper = 'fieldset')
601
-    {
602
-
603
-        $html                            = '';
604
-        $before_question_group_questions =
605
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
606
-        $after_question_group_questions  =
607
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
608
-
609
-        if (! empty($question_groups)) {
610
-            // loop thru question groups
611
-            foreach ($question_groups as $QSG) {
612
-                // check that questions exist
613
-                if (! empty($QSG['QSG_questions'])) {
614
-                    // use fieldsets
615
-                    $html .= "\n\t"
616
-                             . '<'
617
-                             . $group_wrapper
618
-                             . ' class="espresso-question-group-wrap" id="'
619
-                             . $QSG['QSG_identifier']
620
-                             . '">';
621
-                    // group_name
622
-                    $html .= $QSG['QSG_show_group_name']
623
-                        ? "\n\t\t"
624
-                          . '<h5 class="espresso-question-group-title-h5 section-title">'
625
-                          . self::prep_answer($QSG['QSG_name'])
626
-                          . '</h5>'
627
-                        : '';
628
-                    // group_desc
629
-                    $html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc'])
630
-                        ? '<div class="espresso-question-group-desc-pg">'
631
-                          . self::prep_answer($QSG['QSG_desc'])
632
-                          . '</div>'
633
-                        : '';
634
-
635
-                    $html .= $before_question_group_questions;
636
-                    // loop thru questions
637
-                    foreach ($QSG['QSG_questions'] as $question) {
638
-                        $QFI  = new EE_Question_Form_Input(
639
-                            $question['qst_obj'],
640
-                            $question['ans_obj'],
641
-                            $question
642
-                        );
643
-                        $html .= self::generate_form_input($QFI);
644
-                    }
645
-                    $html .= $after_question_group_questions;
646
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
647
-                }
648
-            }
649
-        }
650
-
651
-        return $html;
652
-    }
653
-
654
-
655
-    /**
656
-     * generate_question_groups_html
657
-     *
658
-     * @param array  $question_groups
659
-     * @param array  $q_meta
660
-     * @param bool   $from_admin
661
-     * @param string $group_wrapper
662
-     * @return string HTML
663
-     * @throws EE_Error
664
-     * @throws ReflectionException
665
-     */
666
-    public static function generate_question_groups_html2(
667
-        $question_groups = [],
668
-        $q_meta = [],
669
-        $from_admin = false,
670
-        $group_wrapper = 'fieldset'
671
-    ) {
672
-
673
-        $html                            = '';
674
-        $before_question_group_questions =
675
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
676
-        $after_question_group_questions  =
677
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
678
-
679
-        $default_q_meta = [
680
-            'att_nmbr'    => 1,
681
-            'ticket_id'   => '',
682
-            'input_name'  => '',
683
-            'input_id'    => '',
684
-            'input_class' => '',
685
-        ];
686
-        $q_meta         = array_merge($default_q_meta, $q_meta);
687
-
688
-        if (! empty($question_groups)) {
689
-            // loop thru question groups
690
-            foreach ($question_groups as $QSG) {
691
-                if ($QSG instanceof EE_Question_Group) {
692
-                    // check that questions exist
693
-
694
-                    $where = ['QST_deleted' => 0];
695
-                    if (! $from_admin) {
696
-                        $where['QST_admin_only'] = 0;
697
-                    }
698
-                    $questions =
699
-                        $QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
700
-                    if (! empty($questions)) {
701
-                        // use fieldsets
702
-                        $html .= "\n\t"
703
-                                 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
704
-                                 . 'id="' . $QSG->get('QSG_identifier') . '">';
705
-                        // group_name
706
-                        if ($QSG->show_group_name()) {
707
-                            $html .= "\n\t\t"
708
-                                     . '<h5 class="espresso-question-group-title-h5 section-title">'
709
-                                     . $QSG->get_pretty('QSG_name')
710
-                                     . '</h5>';
711
-                        }
712
-                        // group_desc
713
-                        if ($QSG->show_group_desc()) {
714
-                            $html .= '<div class="espresso-question-group-desc-pg">'
715
-                                     . $QSG->get_pretty('QSG_desc')
716
-                                     . '</div>';
717
-                        }
718
-
719
-                        $html .= $before_question_group_questions;
720
-                        // loop thru questions
721
-                        foreach ($questions as $QST) {
722
-                            $qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
723
-
724
-                            $answer = null;
725
-
726
-                            /** @var RequestInterface $request */
727
-                            $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
728
-                            $request_qstn = $request->getRequestParam('qstn', [], 'string', true);
729
-                            if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
730
-                                // check for answer in $request_qstn in case we are reprocessing a form after an error
731
-                                if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
732
-                                    $answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
733
-                                        ? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
734
-                                        : sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
735
-                                }
736
-                            } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
737
-                                // attendee data from the session
738
-                                $answer =
739
-                                    isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
740
-                            }
741
-
742
-
743
-                            $QFI  = new EE_Question_Form_Input(
744
-                                $QST,
745
-                                EE_Answer::new_instance(
746
-                                    [
747
-                                        'ANS_ID'    => 0,
748
-                                        'QST_ID'    => 0,
749
-                                        'REG_ID'    => 0,
750
-                                        'ANS_value' => $answer,
751
-                                    ]
752
-                                ),
753
-                                $q_meta
754
-                            );
755
-                            $html .= self::generate_form_input($QFI);
756
-                        }
757
-                        $html .= $after_question_group_questions;
758
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
759
-                    }
760
-                }
761
-            }
762
-        }
763
-        return $html;
764
-    }
765
-
766
-
767
-    /**
768
-     * generate_form_input
769
-     *
770
-     * @param EE_Question_Form_Input $QFI
771
-     * @return string HTML
772
-     * @throws EE_Error
773
-     * @throws ReflectionException
774
-     */
775
-    public static function generate_form_input(EE_Question_Form_Input $QFI)
776
-    {
777
-        if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
778
-            return '';
779
-        }
780
-        /** @var RequestInterface $request */
781
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
782
-
783
-        $QFI = self::_load_system_dropdowns($QFI);
784
-        $QFI = self::_load_specialized_dropdowns($QFI);
785
-
786
-        // we also need to verify
787
-
788
-        $display_text = $QFI->get('QST_display_text');
789
-        $input_name   = $QFI->get('QST_input_name');
790
-        $answer       = $request->getRequestParam($input_name, $QFI->get('ANS_value'));
791
-        $input_id     = $QFI->get('QST_input_id');
792
-        $input_class  = $QFI->get('QST_input_class');
793
-        //      $disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
794
-        $disabled          = $QFI->get('QST_disabled');
795
-        $required_label    = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
796
-        $QST_required      = $QFI->get('QST_required');
797
-        $required          =
798
-            $QST_required
799
-                ? ['label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required]
800
-                : [];
801
-        $use_html_entities = $QFI->get_meta('htmlentities');
802
-        $required_text     =
803
-            $QFI->get('QST_required_text') != ''
804
-                ? $QFI->get('QST_required_text')
805
-                : esc_html__('This field is required', 'event_espresso');
806
-        $required_text     = $QST_required
807
-            ? "\n\t\t\t"
808
-              . '<div class="required-text hidden">'
809
-              . self::prep_answer($required_text, $use_html_entities)
810
-              . '</div>'
811
-            : '';
812
-        $label_class       = 'espresso-form-input-lbl';
813
-        $QST_options       = $QFI->options(true, $answer);
814
-        $options           = is_array($QST_options) ? self::prep_answer_options($QST_options) : [];
815
-        $system_ID         = $QFI->get('QST_system');
816
-        $label_b4          = $QFI->get_meta('label_b4');
817
-        $use_desc_4_label  = $QFI->get_meta('use_desc_4_label');
818
-
819
-
820
-        switch ($QFI->get('QST_type')) {
821
-            case 'TEXTAREA':
822
-                return EEH_Form_Fields::textarea(
823
-                    $display_text,
824
-                    $answer,
825
-                    $input_name,
826
-                    $input_id,
827
-                    $input_class,
828
-                    [],
829
-                    $required,
830
-                    $required_text,
831
-                    $label_class,
832
-                    $disabled,
833
-                    $system_ID,
834
-                    $use_html_entities
835
-                );
836
-
837
-            case 'DROPDOWN':
838
-                return EEH_Form_Fields::select(
839
-                    $display_text,
840
-                    $answer,
841
-                    $options,
842
-                    $input_name,
843
-                    $input_id,
844
-                    $input_class,
845
-                    $required,
846
-                    $required_text,
847
-                    $label_class,
848
-                    $disabled,
849
-                    $system_ID,
850
-                    $use_html_entities,
851
-                    true
852
-                );
853
-
854
-
855
-            case 'RADIO_BTN':
856
-                return EEH_Form_Fields::radio(
857
-                    $display_text,
858
-                    $answer,
859
-                    $options,
860
-                    $input_name,
861
-                    $input_id,
862
-                    $input_class,
863
-                    $required,
864
-                    $required_text,
865
-                    $label_class,
866
-                    $disabled,
867
-                    $system_ID,
868
-                    $use_html_entities,
869
-                    $label_b4,
870
-                    $use_desc_4_label
871
-                );
872
-
873
-            case 'CHECKBOX':
874
-                return EEH_Form_Fields::checkbox(
875
-                    $display_text,
876
-                    $answer,
877
-                    $options,
878
-                    $input_name,
879
-                    $input_id,
880
-                    $input_class,
881
-                    $required,
882
-                    $required_text,
883
-                    $label_class,
884
-                    $disabled,
885
-                    $label_b4,
886
-                    $system_ID,
887
-                    $use_html_entities
888
-                );
889
-
890
-            case 'DATE':
891
-                return EEH_Form_Fields::datepicker(
892
-                    $display_text,
893
-                    $answer,
894
-                    $input_name,
895
-                    $input_id,
896
-                    $input_class,
897
-                    $required,
898
-                    $required_text,
899
-                    $label_class,
900
-                    $disabled,
901
-                    $system_ID,
902
-                    $use_html_entities
903
-                );
904
-
905
-            case 'TEXT':
906
-            default:
907
-                return EEH_Form_Fields::text(
908
-                    $display_text,
909
-                    $answer,
910
-                    $input_name,
911
-                    $input_id,
912
-                    $input_class,
913
-                    $required,
914
-                    $required_text,
915
-                    $label_class,
916
-                    $disabled,
917
-                    $system_ID,
918
-                    $use_html_entities
919
-                );
920
-        }
921
-    }
922
-
923
-
924
-    /**
925
-     * generates HTML for a form text input
926
-     *
927
-     * @param string $question    label content
928
-     * @param string $answer      form input value attribute
929
-     * @param string $name        form input name attribute
930
-     * @param string $id          form input css id attribute
931
-     * @param string $class       form input css class attribute
932
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
933
-     *                            required 'class', and required 'msg' attribute
934
-     * @param string $label_class css class attribute for the label
935
-     * @param string $disabled    disabled="disabled" or null
936
-     * @return string HTML
937
-     */
938
-    public static function text(
939
-        $question = false,
940
-        $answer = null,
941
-        $name = false,
942
-        $id = '',
943
-        $class = '',
944
-        $required = false,
945
-        $required_text = '',
946
-        $label_class = '',
947
-        $disabled = false,
948
-        $system_ID = false,
949
-        $use_html_entities = true
950
-    ) {
951
-        // need these
952
-        if (! $question || ! $name) {
953
-            return null;
954
-        }
955
-        // prep the answer
956
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
957
-        // prep the required array
958
-        $required = self::prep_required($required);
959
-        // set disabled tag
960
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
961
-        // ya gots ta have style man!!!
962
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
963
-        $class     = empty($class) ? $txt_class : $class;
964
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
965
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
966
-
967
-        $label_html =
968
-            $required_text
969
-            . "\n\t\t\t"
970
-            . '<label for="' . $name . '" class="' . $label_class . '">'
971
-            . self::prep_question($question)
972
-            . $required['label']
973
-            . '</label><br/>';
974
-        // filter label but ensure required text comes before it
975
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
976
-
977
-        $input_html =
978
-            "\n\t\t\t"
979
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
980
-            . 'class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  '
981
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
982
-
983
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
984
-        return $label_html . $input_html;
985
-    }
986
-
987
-
988
-    /**
989
-     * generates HTML for a form textarea
990
-     *
991
-     * @param string $question    label content
992
-     * @param string $answer      form input value attribute
993
-     * @param string $name        form input name attribute
994
-     * @param string $id          form input css id attribute
995
-     * @param string $class       form input css class attribute
996
-     * @param array  $dimensions  array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
997
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
998
-     *                            required 'class', and required 'msg' attribute
999
-     * @param string $label_class css class attribute for the label
1000
-     * @param string $disabled    disabled="disabled" or null
1001
-     * @return string HTML
1002
-     */
1003
-    public static function textarea(
1004
-        $question = false,
1005
-        $answer = null,
1006
-        $name = false,
1007
-        $id = '',
1008
-        $class = '',
1009
-        $dimensions = false,
1010
-        $required = false,
1011
-        $required_text = '',
1012
-        $label_class = '',
1013
-        $disabled = false,
1014
-        $system_ID = false,
1015
-        $use_html_entities = true
1016
-    ) {
1017
-        // need these
1018
-        if (! $question || ! $name) {
1019
-            return null;
1020
-        }
1021
-        // prep the answer
1022
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1023
-        // prep the required array
1024
-        $required = self::prep_required($required);
1025
-        // make sure $dimensions is an array
1026
-        $dimensions = is_array($dimensions) ? $dimensions : [];
1027
-        // and set some defaults
1028
-        $dimensions = array_merge(['rows' => 3, 'cols' => 40], $dimensions);
1029
-        // set disabled tag
1030
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1031
-        // ya gots ta have style man!!!
1032
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
1033
-        $class     = empty($class) ? $txt_class : $class;
1034
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1035
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1036
-
1037
-        $label_html =
1038
-            $required_text
1039
-            . "\n\t\t\t"
1040
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1041
-            . self::prep_question($question)
1042
-            . $required['label']
1043
-            . '</label><br/>';
1044
-        // filter label but ensure required text comes before it
1045
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1046
-
1047
-        $input_html =
1048
-            "\n\t\t\t"
1049
-            . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1050
-            . 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1051
-            . 'title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1052
-            . $answer
1053
-            . '</textarea>';
1054
-
1055
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1056
-        return $label_html . $input_html;
1057
-    }
1058
-
1059
-
1060
-    /**
1061
-     * generates HTML for a form select input
1062
-     *
1063
-     * @param string $question    label content
1064
-     * @param string $answer      form input value attribute
1065
-     * @param array  $options     array of answer options where array key = option value and array value = option
1066
-     *                            display text
1067
-     * @param string $name        form input name attribute
1068
-     * @param string $id          form input css id attribute
1069
-     * @param string $class       form input css class attribute
1070
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1071
-     *                            required 'class', and required 'msg' attribute
1072
-     * @param string $label_class css class attribute for the label
1073
-     * @param string $disabled    disabled="disabled" or null
1074
-     * @return string HTML
1075
-     */
1076
-    public static function select(
1077
-        $question = false,
1078
-        $answer = null,
1079
-        $options = false,
1080
-        $name = false,
1081
-        $id = '',
1082
-        $class = '',
1083
-        $required = false,
1084
-        $required_text = '',
1085
-        $label_class = '',
1086
-        $disabled = false,
1087
-        $system_ID = false,
1088
-        $use_html_entities = true,
1089
-        $add_please_select_option = false
1090
-    ) {
1091
-
1092
-        // need these
1093
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1094
-            return null;
1095
-        }
1096
-        // prep the answer
1097
-        $answer =
1098
-            is_array($answer)
1099
-                ? self::prep_answer(array_shift($answer), $use_html_entities)
1100
-                : self::prep_answer(
1101
-                    $answer,
1102
-                    $use_html_entities
1103
-                );
1104
-        // prep the required array
1105
-        $required = self::prep_required($required);
1106
-        // set disabled tag
1107
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1108
-        // ya gots ta have style man!!!
1109
-        $txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
1110
-        $class     = empty($class) ? $txt_class : $class;
1111
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1112
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1113
-
1114
-        $label_html =
1115
-            $required_text
1116
-            . "\n\t\t\t"
1117
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1118
-            . self::prep_question($question)
1119
-            . $required['label']
1120
-            . '</label><br/>';
1121
-        // filter label but ensure required text comes before it
1122
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1123
-
1124
-        $input_html =
1125
-            "\n\t\t\t"
1126
-            . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1127
-            . 'title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1128
-        // recursively count array elements, to determine total number of options
1129
-        $only_option = count($options, 1) == 1;
1130
-        if (! $only_option) {
1131
-            // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1132
-            $selected   = $answer === null ? ' selected="selected"' : '';
1133
-            $input_html .= $add_please_select_option
1134
-                ? "\n\t\t\t\t"
1135
-                  . '<option value=""' . $selected . '>'
1136
-                  . esc_html__(' - please select - ', 'event_espresso')
1137
-                  . '</option>'
1138
-                : '';
1139
-        }
1140
-        foreach ($options as $key => $value) {
1141
-            // if value is an array, then create option groups, else create regular ol' options
1142
-            $input_html .= is_array($value)
1143
-                ? self::_generate_select_option_group(
1144
-                    $key,
1145
-                    $value,
1146
-                    $answer,
1147
-                    $use_html_entities
1148
-                )
1149
-                : self::_generate_select_option(
1150
-                    $value->value(),
1151
-                    $value->desc(),
1152
-                    $answer,
1153
-                    $only_option,
1154
-                    $use_html_entities
1155
-                );
1156
-        }
1157
-
1158
-        $input_html .= "\n\t\t\t" . '</select>';
1159
-
1160
-        $input_html =
1161
-            apply_filters(
1162
-                'FHEE__EEH_Form_Fields__select__before_end_wrapper',
1163
-                $input_html,
1164
-                $question,
1165
-                $answer,
1166
-                $name,
1167
-                $id,
1168
-                $class,
1169
-                $system_ID
1170
-            );
1171
-
1172
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1173
-        return $label_html . $input_html;
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     *  _generate_select_option_group
1179
-     *
1180
-     *  if  $value for a select box is an array, then the key will be used as the optgroup label
1181
-     *  and the value array will be looped thru and the elements sent to _generate_select_option
1182
-     *
1183
-     * @param mixed   $opt_group
1184
-     * @param mixed   $QSOs
1185
-     * @param mixed   $answer
1186
-     * @param boolean $use_html_entities
1187
-     * @return string
1188
-     */
1189
-    private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1190
-    {
1191
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1192
-        foreach ($QSOs as $QSO) {
1193
-            $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1194
-        }
1195
-        $html .= "\n\t\t\t\t" . '</optgroup>';
1196
-        return $html;
1197
-    }
1198
-
1199
-
1200
-    /**
1201
-     *  _generate_select_option
1202
-     *
1203
-     * @param mixed   $key
1204
-     * @param mixed   $value
1205
-     * @param mixed   $answer
1206
-     * @param int     $only_option
1207
-     * @param boolean $use_html_entities
1208
-     * @return string
1209
-     */
1210
-    private static function _generate_select_option(
1211
-        $key,
1212
-        $value,
1213
-        $answer,
1214
-        $only_option = false,
1215
-        $use_html_entities = true
1216
-    ) {
1217
-        $key      = self::prep_answer($key, $use_html_entities);
1218
-        $value    = self::prep_answer($value, $use_html_entities);
1219
-        $value    = ! empty($value) ? $value : $key;
1220
-        $selected = ($answer == $key || $only_option) ? 'selected="selected"' : '';
1221
-        return "\n\t\t\t\t"
1222
-               . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1223
-               . $value
1224
-               . '&nbsp;&nbsp;&nbsp;</option>';
1225
-    }
1226
-
1227
-
1228
-    /**
1229
-     * generates HTML for form radio button inputs
1230
-     *
1231
-     * @param bool|string $question    label content
1232
-     * @param string      $answer      form input value attribute
1233
-     * @param array|bool  $options     array of answer options where array key = option value and array value = option
1234
-     *                                 display text
1235
-     * @param bool|string $name        form input name attribute
1236
-     * @param string      $id          form input css id attribute
1237
-     * @param string      $class       form input css class attribute
1238
-     * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1239
-     *                                 required 'class', and required 'msg' attribute
1240
-     * @param string      $required_text
1241
-     * @param string      $label_class css class attribute for the label
1242
-     * @param bool|string $disabled    disabled="disabled" or null
1243
-     * @param bool        $system_ID
1244
-     * @param bool        $use_html_entities
1245
-     * @param bool        $label_b4
1246
-     * @param bool        $use_desc_4_label
1247
-     * @return string HTML
1248
-     */
1249
-    public static function radio(
1250
-        $question = false,
1251
-        $answer = null,
1252
-        $options = false,
1253
-        $name = false,
1254
-        $id = '',
1255
-        $class = '',
1256
-        $required = false,
1257
-        $required_text = '',
1258
-        $label_class = '',
1259
-        $disabled = false,
1260
-        $system_ID = false,
1261
-        $use_html_entities = true,
1262
-        $label_b4 = false,
1263
-        $use_desc_4_label = false
1264
-    ) {
1265
-        // need these
1266
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1267
-            return null;
1268
-        }
1269
-        // prep the answer
1270
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1271
-        // prep the required array
1272
-        $required = self::prep_required($required);
1273
-        // set disabled tag
1274
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1275
-        // ya gots ta have style man!!!
1276
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1277
-        $class       = ! empty($class) ? $class : 'espresso-radio-btn-inp';
1278
-        $extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1279
-
1280
-        $label_html =
1281
-            $required_text
1282
-            . "\n\t\t\t"
1283
-            . '<label class="' . $label_class . '">'
1284
-            . self::prep_question($question)
1285
-            . $required['label']
1286
-            . '</label> ';
1287
-        // filter label but ensure required text comes before it
1288
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1289
-
1290
-        $input_html =
1291
-            "\n\t\t\t"
1292
-            . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
1293
-
1294
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1295
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1296
-
1297
-        foreach ($options as $OPT) {
1298
-            if ($OPT instanceof EE_Question_Option) {
1299
-                $value   = self::prep_option_value($OPT->value());
1300
-                $label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1301
-                $size    = $use_desc_4_label
1302
-                    ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1303
-                    : self::get_label_size_class($OPT->value());
1304
-                $desc    = $OPT->desc();// no self::prep_answer
1305
-                $answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1306
-                $checked = (string) $value == (string) $answer ? ' checked="checked"' : '';
1307
-                $opt     = '-' . sanitize_key($value);
1308
-
1309
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1310
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1311
-                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
1312
-                $input_html .= "\n\t\t\t\t\t\t"
1313
-                               . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1314
-                               . 'class="' . $class . '" value="' . $value . '" '
1315
-                               . 'title="' . esc_attr($required['msg']) . '" ' . $disabled
1316
-                               . $checked . ' ' . $extra . '/>';
1317
-                $input_html .= ! $label_b4
1318
-                    ? "\n\t\t\t\t\t\t"
1319
-                      . '<span class="espresso-radio-btn-desc">'
1320
-                      . $label
1321
-                      . '</span>'
1322
-                    : '';
1323
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
1324
-                $input_html .= $use_desc_4_label
1325
-                    ? ''
1326
-                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1327
-                $input_html .= "\n\t\t\t\t" . '</li>';
1328
-            }
1329
-        }
1330
-
1331
-        $input_html .= "\n\t\t\t" . '</ul>';
1332
-
1333
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1334
-        return $label_html . $input_html;
1335
-    }
1336
-
1337
-
1338
-    /**
1339
-     * generates HTML for form checkbox inputs
1340
-     *
1341
-     * @param string $question    label content
1342
-     * @param string $answer      form input value attribute
1343
-     * @param array  $options     array of options where array key = option value and array value = option display text
1344
-     * @param string $name        form input name attribute
1345
-     * @param string $id          form input css id attribute
1346
-     * @param string $class       form input css class attribute
1347
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1348
-     *                            required 'class', and required 'msg' attribute
1349
-     * @param string $label_class css class attribute for the label
1350
-     * @param string $disabled    disabled="disabled" or null
1351
-     * @return string HTML
1352
-     */
1353
-    public static function checkbox(
1354
-        $question = false,
1355
-        $answer = null,
1356
-        $options = false,
1357
-        $name = false,
1358
-        $id = '',
1359
-        $class = '',
1360
-        $required = false,
1361
-        $required_text = '',
1362
-        $label_class = '',
1363
-        $disabled = false,
1364
-        $label_b4 = false,
1365
-        $system_ID = false,
1366
-        $use_html_entities = true
1367
-    ) {
1368
-        // need these
1369
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1370
-            return null;
1371
-        }
1372
-        $answer = maybe_unserialize($answer);
1373
-
1374
-        // prep the answer(s)
1375
-        $answer = is_array($answer) ? $answer : [sanitize_key($answer) => $answer];
1376
-
1377
-        foreach ($answer as $key => $value) {
1378
-            $key            = self::prep_option_value($key);
1379
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
1380
-        }
1381
-
1382
-        // prep the required array
1383
-        $required = self::prep_required($required);
1384
-        // set disabled tag
1385
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1386
-        // ya gots ta have style man!!!
1387
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1388
-        $class       = empty($class) ? 'espresso-radio-btn-inp' : $class;
1389
-        $extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1390
-
1391
-        $label_html =
1392
-            $required_text
1393
-            . "\n\t\t\t"
1394
-            . '<label class="' . $label_class . '">'
1395
-            . self::prep_question($question)
1396
-            . $required['label']
1397
-            . '</label> ';
1398
-        // filter label but ensure required text comes before it
1399
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1400
-
1401
-        $input_html =
1402
-            "\n\t\t\t"
1403
-            . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
1404
-
1405
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1406
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1407
-
1408
-        foreach ($options as $OPT) {
1409
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
1410
-            $size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1411
-            $text  = self::prep_answer($OPT->value());
1412
-            $desc  = $OPT->desc();
1413
-            $opt   = '-' . sanitize_key($value);
1414
-
1415
-            $checked = is_array($answer) && in_array($text, $answer) ? ' checked="checked"' : '';
1416
-
1417
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1418
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1419
-            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1420
-            $input_html .= "\n\t\t\t\t\t\t"
1421
-                           . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1422
-                           . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1423
-                           . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1424
-            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1425
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
1426
-            if (! empty($desc) && $desc != $text) {
1427
-                $input_html .= "\n\t\t\t\t\t"
1428
-                               . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1429
-                               . $desc
1430
-                               . '</div>';
1431
-            }
1432
-            $input_html .= "\n\t\t\t\t" . '</li>';
1433
-        }
1434
-
1435
-        $input_html .= "\n\t\t\t" . '</ul>';
1436
-
1437
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1438
-        return $label_html . $input_html;
1439
-    }
1440
-
1441
-
1442
-    /**
1443
-     * generates HTML for a form datepicker input
1444
-     *
1445
-     * @param string $question    label content
1446
-     * @param string $answer      form input value attribute
1447
-     * @param string $name        form input name attribute
1448
-     * @param string $id          form input css id attribute
1449
-     * @param string $class       form input css class attribute
1450
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1451
-     *                            required 'class', and required 'msg' attribute
1452
-     * @param string $label_class css class attribute for the label
1453
-     * @param string $disabled    disabled="disabled" or null
1454
-     * @return string HTML
1455
-     */
1456
-    public static function datepicker(
1457
-        $question = false,
1458
-        $answer = null,
1459
-        $name = false,
1460
-        $id = '',
1461
-        $class = '',
1462
-        $required = false,
1463
-        $required_text = '',
1464
-        $label_class = '',
1465
-        $disabled = false,
1466
-        $system_ID = false,
1467
-        $use_html_entities = true
1468
-    ) {
1469
-        // need these
1470
-        if (! $question || ! $name) {
1471
-            return null;
1472
-        }
1473
-        // prep the answer
1474
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1475
-        // prep the required array
1476
-        $required = self::prep_required($required);
1477
-        // set disabled tag
1478
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1479
-        // ya gots ta have style man!!!
1480
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1481
-        $class     = empty($class) ? $txt_class : $class;
1482
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1483
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1484
-
1485
-        $label_html =
1486
-            $required_text
1487
-            . "\n\t\t\t"
1488
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1489
-            . self::prep_question($question)
1490
-            . $required['label']
1491
-            . '</label><br/>';
1492
-        // filter label but ensure required text comes before it
1493
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1494
-
1495
-        $input_html =
1496
-            "\n\t\t\t"
1497
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
1498
-            . 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1499
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1500
-
1501
-        // enqueue scripts
1502
-        wp_register_style(
1503
-            'espresso-ui-theme',
1504
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1505
-            [],
1506
-            EVENT_ESPRESSO_VERSION
1507
-        );
1508
-        wp_enqueue_style('espresso-ui-theme');
1509
-        wp_enqueue_script('jquery-ui-datepicker');
1510
-
1511
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1512
-        return $label_html . $input_html;
1513
-    }
1514
-
1515
-
1516
-    /**
1517
-     *  remove_label_keep_required_msg
1518
-     *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1519
-     *
1520
-     * @access public
1521
-     * @return     string
1522
-     */
1523
-    public static function remove_label_keep_required_msg($label_html, $required_text)
1524
-    {
1525
-        return $required_text;
1526
-    }
1527
-
1528
-
1529
-    /**
1530
-     * Simply returns the HTML for a hidden input of the given name and value.
1531
-     *
1532
-     * @param string $name
1533
-     * @param string $value
1534
-     * @return string HTML
1535
-     */
1536
-    public static function hidden_input($name, $value, $id = '')
1537
-    {
1538
-        $id = ! empty($id) ? $id : $name;
1539
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1540
-    }
1541
-
1542
-
1543
-    /**
1544
-     * prep_question
1545
-     *
1546
-     * @param string $question
1547
-     * @return string
1548
-     */
1549
-    public static function prep_question($question)
1550
-    {
1551
-        return $question;
1552
-    }
1553
-
1554
-
1555
-    /**
1556
-     *  prep_answer
1557
-     *
1558
-     * @param mixed $answer
1559
-     * @return string
1560
-     */
1561
-    public static function prep_answer($answer, $use_html_entities = true)
1562
-    {
1563
-        // make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired,
1564
-        // we want "0".
1565
-        if (is_bool($answer)) {
1566
-            $answer = $answer ? 1 : 0;
1567
-        }
1568
-        $answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1569
-        return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1570
-    }
1571
-
1572
-
1573
-    /**
1574
-     *  prep_answer_options
1575
-     *
1576
-     * @param array $QSOs array of EE_Question_Option objects
1577
-     * @return array
1578
-     */
1579
-    public static function prep_answer_options($QSOs = [])
1580
-    {
1581
-        $prepped_answer_options = [];
1582
-        if (is_array($QSOs) && ! empty($QSOs)) {
1583
-            foreach ($QSOs as $key => $QSO) {
1584
-                if (! $QSO instanceof EE_Question_Option) {
1585
-                    $QSO = EE_Question_Option::new_instance(
1586
-                        [
1587
-                            'QSO_value' => is_array($QSO) && isset($QSO['id'])
1588
-                                ? (string) $QSO['id']
1589
-                                : (string) $key,
1590
-                            'QSO_desc'  => is_array($QSO) && isset($QSO['text'])
1591
-                                ? (string) $QSO['text']
1592
-                                : (string) $QSO,
1593
-                        ]
1594
-                    );
1595
-                }
1596
-                if ($QSO->opt_group()) {
1597
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1598
-                } else {
1599
-                    $prepped_answer_options[] = $QSO;
1600
-                }
1601
-            }
1602
-        }
1603
-        //      d( $prepped_answer_options );
1604
-        return $prepped_answer_options;
1605
-    }
1606
-
1607
-
1608
-    /**
1609
-     *  prep_option_value
1610
-     *
1611
-     * @param string $option_value
1612
-     * @return string
1613
-     */
1614
-    public static function prep_option_value($option_value)
1615
-    {
1616
-        return esc_attr(trim(stripslashes($option_value)));
1617
-    }
1618
-
1619
-
1620
-    /**
1621
-     *  prep_required
1622
-     *
1623
-     * @param string|array $required
1624
-     * @return array
1625
-     */
1626
-    public static function prep_required($required = [])
1627
-    {
1628
-        // make sure required is an array
1629
-        $required = is_array($required) ? $required : [];
1630
-        // and set some defaults
1631
-        return array_merge(['label' => '', 'class' => '', 'msg' => ''], $required);
1632
-    }
1633
-
1634
-
1635
-    /**
1636
-     *  get_label_size_class
1637
-     *
1638
-     * @param string $value
1639
-     * @return string
1640
-     */
1641
-    public static function get_label_size_class($value = false)
1642
-    {
1643
-        if ($value === false || $value === '') {
1644
-            return ' class="medium-lbl"';
1645
-        }
1646
-        // determine length of option value
1647
-        $val_size = strlen($value);
1648
-        switch ($val_size) {
1649
-            case $val_size < 3:
1650
-                $size = ' class="nano-lbl"';
1651
-                break;
1652
-            case $val_size < 6:
1653
-                $size = ' class="micro-lbl"';
1654
-                break;
1655
-            case $val_size < 12:
1656
-                $size = ' class="tiny-lbl"';
1657
-                break;
1658
-            case $val_size < 25:
1659
-                $size = ' class="small-lbl"';
1660
-                break;
1661
-            case $val_size > 100:
1662
-                $size = ' class="big-lbl"';
1663
-                break;
1664
-            default:
1665
-                $size = ' class="medium-lbl"';
1666
-                break;
1667
-        }
1668
-        return $size;
1669
-    }
1670
-
1671
-
1672
-    /**
1673
-     *  _load_system_dropdowns
1674
-     *
1675
-     * @param EE_Question_Form_Input $QFI
1676
-     * @return array
1677
-     * @throws EE_Error
1678
-     * @throws ReflectionException
1679
-     */
1680
-    private static function _load_system_dropdowns($QFI)
1681
-    {
1682
-        $QST_system = $QFI->get('QST_system');
1683
-        switch ($QST_system) {
1684
-            case 'state':
1685
-                $QFI = self::generate_state_dropdown($QFI);
1686
-                break;
1687
-            case 'country':
1688
-                $QFI = self::generate_country_dropdown($QFI);
1689
-                break;
1690
-            case 'admin-state':
1691
-                $QFI = self::generate_state_dropdown($QFI, true);
1692
-                break;
1693
-            case 'admin-country':
1694
-                $QFI = self::generate_country_dropdown($QFI, true);
1695
-                break;
1696
-        }
1697
-        return $QFI;
1698
-    }
1699
-
1700
-
1701
-    /**
1702
-     * This preps dropdowns that are specialized.
1703
-     *
1704
-     * @param EE_Question_Form_Input $QFI
1705
-     *
1706
-     * @return EE_Question_Form_Input
1707
-     * @throws EE_Error
1708
-     * @throws ReflectionException
1709
-     * @since  4.6.0
1710
-     */
1711
-    protected static function _load_specialized_dropdowns($QFI)
1712
-    {
1713
-        switch ($QFI->get('QST_type')) {
1714
-            case 'STATE':
1715
-                $QFI = self::generate_state_dropdown($QFI);
1716
-                break;
1717
-            case 'COUNTRY':
1718
-                $QFI = self::generate_country_dropdown($QFI);
1719
-                break;
1720
-        }
1721
-        return $QFI;
1722
-    }
1723
-
1724
-
1725
-    /**
1726
-     *    generate_state_dropdown
1727
-     *
1728
-     * @param EE_Question_Form_Input $QST
1729
-     * @param bool                   $get_all
1730
-     * @return EE_Question_Form_Input
1731
-     * @throws EE_Error
1732
-     * @throws ReflectionException
1733
-     */
1734
-    public static function generate_state_dropdown($QST, $get_all = false)
1735
-    {
1736
-        $states = $get_all
1737
-            ? EEM_State::instance()->get_all_states()
1738
-            : EEM_State::instance()->get_all_states_of_active_countries();
1739
-        if ($states && count($states) != count($QST->options())) {
1740
-            $QST->set('QST_type', 'DROPDOWN');
1741
-            // if multiple countries, we'll create option groups within the dropdown
1742
-            foreach ($states as $state) {
1743
-                if ($state instanceof EE_State) {
1744
-                    $QSO = EE_Question_Option::new_instance(
1745
-                        [
1746
-                            'QSO_value'   => $state->ID(),
1747
-                            'QSO_desc'    => $state->name(),
1748
-                            'QST_ID'      => $QST->get('QST_ID'),
1749
-                            'QSO_deleted' => false,
1750
-                        ]
1751
-                    );
1752
-                    // set option group
1753
-                    $QSO->set_opt_group($state->country()->name());
1754
-                    // add option to question
1755
-                    $QST->add_temp_option($QSO);
1756
-                }
1757
-            }
1758
-        }
1759
-        return $QST;
1760
-    }
1761
-
1762
-
1763
-    /**
1764
-     *    generate_country_dropdown
1765
-     *
1766
-     * @param      $QST
1767
-     * @param bool $get_all
1768
-     * @return array
1769
-     * @throws EE_Error
1770
-     * @throws ReflectionException
1771
-     * @internal param array $question
1772
-     */
1773
-    public static function generate_country_dropdown($QST, $get_all = false)
1774
-    {
1775
-        $countries = $get_all
1776
-            ? EEM_Country::instance()->get_all_countries()
1777
-            : EEM_Country::instance()->get_all_active_countries();
1778
-        if ($countries && count($countries) != count($QST->options())) {
1779
-            $QST->set('QST_type', 'DROPDOWN');
1780
-            // now add countries
1781
-            foreach ($countries as $country) {
1782
-                if ($country instanceof EE_Country) {
1783
-                    $QSO = EE_Question_Option::new_instance(
1784
-                        [
1785
-                            'QSO_value'   => $country->ID(),
1786
-                            'QSO_desc'    => $country->name(),
1787
-                            'QST_ID'      => $QST->get('QST_ID'),
1788
-                            'QSO_deleted' => false,
1789
-                        ]
1790
-                    );
1791
-                    $QST->add_temp_option($QSO);
1792
-                }
1793
-            }
1794
-        }
1795
-        return $QST;
1796
-    }
1797
-
1798
-
1799
-    /**
1800
-     *  generates options for a month dropdown selector with numbers from 01 to 12
1801
-     *
1802
-     * @return array()
1803
-     */
1804
-    public static function two_digit_months_dropdown_options()
1805
-    {
1806
-        $options = [];
1807
-        for ($x = 1; $x <= 12; $x++) {
1808
-            $mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1809
-            $options[ $mm ] = $mm;
1810
-        }
1811
-        return EEH_Form_Fields::prep_answer_options($options);
1812
-    }
1813
-
1814
-
1815
-    /**
1816
-     *  generates a year dropdown selector with numbers for the next ten years
1817
-     *
1818
-     * @return array
1819
-     */
1820
-    public static function next_decade_two_digit_year_dropdown_options()
1821
-    {
1822
-        $options      = [];
1823
-        $current_year = date('y');
1824
-        $next_decade  = $current_year + 10;
1825
-        for ($x = $current_year; $x <= $next_decade; $x++) {
1826
-            $yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1827
-            $options[ $yy ] = $yy;
1828
-        }
1829
-        return EEH_Form_Fields::prep_answer_options($options);
1830
-    }
1831
-
1832
-
1833
-    /**
1834
-     * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for
1835
-     * list table filter.
1836
-     *
1837
-     * @param string  $cur_date     any currently selected date can be entered here.
1838
-     * @param string  $status       Registration status
1839
-     * @param integer $evt_category Event Category ID if the Event Category filter is selected
1840
-     * @return string                html
1841
-     * @throws EE_Error
1842
-     */
1843
-    public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1844
-    {
1845
-        $_where = [];
1846
-        if (! empty($status)) {
1847
-            $_where['STS_ID'] = $status;
1848
-        }
1849
-
1850
-        if ($evt_category > 0) {
1851
-            $_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1852
-        }
1853
-
1854
-        $regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1855
-
1856
-        // setup vals for select input helper
1857
-        $options = [
1858
-            0 => [
1859
-                'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1860
-                'id'   => '',
1861
-            ],
1862
-        ];
1863
-
1864
-        foreach ($regdtts as $regdtt) {
1865
-            $date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1866
-            $options[] = [
1867
-                'text' => $date,
1868
-                'id'   => $date,
1869
-            ];
1870
-        }
1871
-
1872
-        return self::select_input('month_range', $options, $cur_date, '', 'wide');
1873
-    }
1874
-
1875
-
1876
-    /**
1877
-     * generates a month/year dropdown selector for all events matching the given criteria
1878
-     * Typically used for list table filter
1879
-     *
1880
-     * @param string $cur_date          any currently selected date can be entered here.
1881
-     * @param string $status            "view" (i.e. all, today, month, draft)
1882
-     * @param int    $evt_category      category event belongs to
1883
-     * @param string $evt_active_status "upcoming", "expired", "active", or "inactive"
1884
-     * @return string                    html
1885
-     * @throws EE_Error
1886
-     */
1887
-    public static function generate_event_months_dropdown(
1888
-        $cur_date = '',
1889
-        $status = null,
1890
-        $evt_category = null,
1891
-        $evt_active_status = null
1892
-    ) {
1893
-        // determine what post_status our condition will have for the query.
1894
-        // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1895
-        switch ($status) {
1896
-            case 'month':
1897
-            case 'today':
1898
-            case null:
1899
-            case 'all':
1900
-                $where['Event.status'] = ['NOT IN', ['trash']];
1901
-                break;
1902
-            case 'draft':
1903
-                $where['Event.status'] = ['IN', ['draft', 'auto-draft']];
1904
-                break;
1905
-            default:
1906
-                $where['Event.status'] = $status;
1907
-        }
1908
-
1909
-        // phpcs:enable
1910
-
1911
-        // categories?
1912
-
1913
-
1914
-        if (! empty($evt_category)) {
1915
-            $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1916
-            $where['Event.Term_Taxonomy.term_id']  = $evt_category;
1917
-        }
1918
-
1919
-
1920
-        //      $where['DTT_is_primary'] = 1;
1921
-
1922
-        $DTTS = EEM_Datetime::instance()->get_dtt_months_and_years($where, $evt_active_status);
1923
-
1924
-        // let's setup vals for select input helper
1925
-        $options = [
1926
-            0 => [
1927
-                'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1928
-                'id'   => "",
1929
-            ],
1930
-        ];
1931
-
1932
-
1933
-        // translate month and date
1934
-        global $wp_locale;
1935
-
1936
-        foreach ($DTTS as $DTT) {
1937
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1938
-            $id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1939
-            $options[]      = [
1940
-                'text' => $localized_date,
1941
-                'id'   => $id,
1942
-            ];
1943
-        }
1944
-
1945
-
1946
-        return self::select_input('month_range', $options, $cur_date, '', 'wide');
1947
-    }
1948
-
1949
-
1950
-    /**
1951
-     * generates the dropdown selector for event categories
1952
-     * typically used as a filter on list tables.
1953
-     *
1954
-     * @param integer $current_cat currently selected category
1955
-     * @return string               html for dropdown
1956
-     * @throws EE_Error
1957
-     * @throws ReflectionException
1958
-     */
1959
-    public static function generate_event_category_dropdown($current_cat = -1)
1960
-    {
1961
-        $categories = EEM_Term::instance()->get_all_ee_categories(true);
1962
-        $options    = [
1963
-            '0' => [
1964
-                'text' => esc_html__('All Categories', 'event_espresso'),
1965
-                'id'   => -1,
1966
-            ],
1967
-        ];
1968
-
1969
-        // setup categories for dropdown
1970
-        foreach ($categories as $category) {
1971
-            $options[] = [
1972
-                'text' => $category->get('name'),
1973
-                'id'   => $category->ID(),
1974
-            ];
1975
-        }
1976
-
1977
-        return self::select_input('EVT_CAT', $options, $current_cat);
1978
-    }
1979
-
1980
-
1981
-    /**
1982
-     *    generate a submit button with or without it's own microform
1983
-     *    this is the only way to create buttons that are compatible across all themes
1984
-     *
1985
-     * @access    public
1986
-     * @param string      $url              - the form action
1987
-     * @param string      $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm"
1988
-     *                                      for the form
1989
-     * @param string      $class            - css classes (separated by spaces if more than one)
1990
-     * @param string      $text             - what appears on the button
1991
-     * @param string      $nonce_action     - if using nonces
1992
-     * @param bool|string $input_only       - whether to print form header and footer. TRUE returns the input without
1993
-     *                                      the form
1994
-     * @param string      $extra_attributes - any extra attributes that need to be attached to the form input
1995
-     * @return    string
1996
-     */
1997
-    public static function submit_button(
1998
-        $url = '',
1999
-        $ID = '',
2000
-        $class = '',
2001
-        $text = '',
2002
-        $nonce_action = '',
2003
-        $input_only = false,
2004
-        $extra_attributes = ''
2005
-    ) {
2006
-        $btn = '';
2007
-        if (empty($url) || empty($ID)) {
2008
-            return $btn;
2009
-        }
2010
-        $text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2011
-        $btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2012
-                 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2013
-        if (! $input_only) {
2014
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2015
-            $btn_frm .= ! empty($nonce_action)
2016
-                ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2017
-                : '';
2018
-            $btn_frm .= $btn;
2019
-            $btn_frm .= '</form>';
2020
-            $btn     = $btn_frm;
2021
-            unset($btn_frm);
2022
-        }
2023
-        return $btn;
2024
-    }
488
+	}
489
+
490
+
491
+	/**
492
+	 * @param string $class
493
+	 * @param string $id
494
+	 * @param string $name
495
+	 * @param int    $rows
496
+	 * @param int    $tab_index
497
+	 * @param string $value
498
+	 * @param array  $wp_editor_args
499
+	 * @return false|string
500
+	 * @since   4.10.14.p
501
+	 */
502
+	private static function adminWpEditor($class, $id, $name, $rows, $tab_index, $value, $wp_editor_args = [])
503
+	{
504
+		$editor_settings = $wp_editor_args + [
505
+				'textarea_name' => esc_attr($name),
506
+				'textarea_rows' => absint($rows),
507
+				'editor_class'  => esc_attr($class),
508
+				'tabindex'      => absint($tab_index),
509
+			];
510
+		ob_start();
511
+		wp_editor($value, esc_attr($id), $editor_settings);
512
+		return ob_get_clean();
513
+	}
514
+
515
+
516
+	/**
517
+	 * espresso admin page select_input
518
+	 * Turns an array into a select fields
519
+	 *
520
+	 * @static
521
+	 * @access public
522
+	 * @param string  $name       field name
523
+	 * @param array   $values     option values, numbered array starting at 0, where each value is an array with a key
524
+	 *                            'text' (meaning text to display' and 'id' (meaning the internal value) eg:
525
+	 *                            array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or
526
+	 *                            as an array of key-value pairs, where the key is to be used for the select input's
527
+	 *                            name, and the value will be the text shown to the user.  Optionally you can also
528
+	 *                            include an additional key of "class" which will add a specific class to the option
529
+	 *                            for that value.
530
+	 * @param string  $default    default value
531
+	 * @param string  $parameters extra parameters
532
+	 * @param string  $class      css class
533
+	 * @param boolean $autosize   whether to autosize the select or not
534
+	 * @return string              html string for the select input
535
+	 */
536
+	public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
537
+	{
538
+		// if $values was submitted in the wrong format, convert it over
539
+		if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
540
+			$converted_values = [];
541
+			foreach ($values as $id => $text) {
542
+				$converted_values[] = ['id' => $id, 'text' => $text];
543
+			}
544
+			$values = $converted_values;
545
+		}
546
+
547
+		$field =
548
+			'<select id="' . EEH_Formatter::ee_tep_output_string($name)
549
+			. '" name="' . EEH_Formatter::ee_tep_output_string($name)
550
+			. '"';
551
+
552
+		if (EEH_Formatter::ee_tep_not_null($parameters)) {
553
+			$field .= ' ' . $parameters;
554
+		}
555
+		if ($autosize) {
556
+			$size = 'med';
557
+			for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
558
+				if ($values[ $ii ]['text']) {
559
+					if (strlen($values[ $ii ]['text']) > 5) {
560
+						$size = 'wide';
561
+					}
562
+				}
563
+			}
564
+		} else {
565
+			$size = '';
566
+		}
567
+
568
+		$field .= ' class="' . $class . ' ' . $size . '">';
569
+
570
+		if (empty($default) && isset($GLOBALS[ $name ])) {
571
+			$default = stripslashes($GLOBALS[ $name ]);
572
+		}
573
+
574
+
575
+		for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
576
+			$field .= '<option value="' . $values[ $i ]['id'] . '"';
577
+			if ($default == $values[ $i ]['id']) {
578
+				$field .= ' selected = "selected"';
579
+			}
580
+			if (isset($values[ $i ]['class'])) {
581
+				$field .= ' class="' . $values[ $i ]['class'] . '"';
582
+			}
583
+			$field .= '>' . $values[ $i ]['text'] . '</option>';
584
+		}
585
+		$field .= '</select>';
586
+
587
+		return $field;
588
+	}
589
+
590
+
591
+	/**
592
+	 * generate_question_groups_html
593
+	 *
594
+	 * @param array  $question_groups
595
+	 * @param string $group_wrapper
596
+	 * @return string HTML
597
+	 * @throws EE_Error
598
+	 * @throws ReflectionException
599
+	 */
600
+	public static function generate_question_groups_html($question_groups = [], $group_wrapper = 'fieldset')
601
+	{
602
+
603
+		$html                            = '';
604
+		$before_question_group_questions =
605
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
606
+		$after_question_group_questions  =
607
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
608
+
609
+		if (! empty($question_groups)) {
610
+			// loop thru question groups
611
+			foreach ($question_groups as $QSG) {
612
+				// check that questions exist
613
+				if (! empty($QSG['QSG_questions'])) {
614
+					// use fieldsets
615
+					$html .= "\n\t"
616
+							 . '<'
617
+							 . $group_wrapper
618
+							 . ' class="espresso-question-group-wrap" id="'
619
+							 . $QSG['QSG_identifier']
620
+							 . '">';
621
+					// group_name
622
+					$html .= $QSG['QSG_show_group_name']
623
+						? "\n\t\t"
624
+						  . '<h5 class="espresso-question-group-title-h5 section-title">'
625
+						  . self::prep_answer($QSG['QSG_name'])
626
+						  . '</h5>'
627
+						: '';
628
+					// group_desc
629
+					$html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc'])
630
+						? '<div class="espresso-question-group-desc-pg">'
631
+						  . self::prep_answer($QSG['QSG_desc'])
632
+						  . '</div>'
633
+						: '';
634
+
635
+					$html .= $before_question_group_questions;
636
+					// loop thru questions
637
+					foreach ($QSG['QSG_questions'] as $question) {
638
+						$QFI  = new EE_Question_Form_Input(
639
+							$question['qst_obj'],
640
+							$question['ans_obj'],
641
+							$question
642
+						);
643
+						$html .= self::generate_form_input($QFI);
644
+					}
645
+					$html .= $after_question_group_questions;
646
+					$html .= "\n\t" . '</' . $group_wrapper . '>';
647
+				}
648
+			}
649
+		}
650
+
651
+		return $html;
652
+	}
653
+
654
+
655
+	/**
656
+	 * generate_question_groups_html
657
+	 *
658
+	 * @param array  $question_groups
659
+	 * @param array  $q_meta
660
+	 * @param bool   $from_admin
661
+	 * @param string $group_wrapper
662
+	 * @return string HTML
663
+	 * @throws EE_Error
664
+	 * @throws ReflectionException
665
+	 */
666
+	public static function generate_question_groups_html2(
667
+		$question_groups = [],
668
+		$q_meta = [],
669
+		$from_admin = false,
670
+		$group_wrapper = 'fieldset'
671
+	) {
672
+
673
+		$html                            = '';
674
+		$before_question_group_questions =
675
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
676
+		$after_question_group_questions  =
677
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
678
+
679
+		$default_q_meta = [
680
+			'att_nmbr'    => 1,
681
+			'ticket_id'   => '',
682
+			'input_name'  => '',
683
+			'input_id'    => '',
684
+			'input_class' => '',
685
+		];
686
+		$q_meta         = array_merge($default_q_meta, $q_meta);
687
+
688
+		if (! empty($question_groups)) {
689
+			// loop thru question groups
690
+			foreach ($question_groups as $QSG) {
691
+				if ($QSG instanceof EE_Question_Group) {
692
+					// check that questions exist
693
+
694
+					$where = ['QST_deleted' => 0];
695
+					if (! $from_admin) {
696
+						$where['QST_admin_only'] = 0;
697
+					}
698
+					$questions =
699
+						$QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
700
+					if (! empty($questions)) {
701
+						// use fieldsets
702
+						$html .= "\n\t"
703
+								 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
704
+								 . 'id="' . $QSG->get('QSG_identifier') . '">';
705
+						// group_name
706
+						if ($QSG->show_group_name()) {
707
+							$html .= "\n\t\t"
708
+									 . '<h5 class="espresso-question-group-title-h5 section-title">'
709
+									 . $QSG->get_pretty('QSG_name')
710
+									 . '</h5>';
711
+						}
712
+						// group_desc
713
+						if ($QSG->show_group_desc()) {
714
+							$html .= '<div class="espresso-question-group-desc-pg">'
715
+									 . $QSG->get_pretty('QSG_desc')
716
+									 . '</div>';
717
+						}
718
+
719
+						$html .= $before_question_group_questions;
720
+						// loop thru questions
721
+						foreach ($questions as $QST) {
722
+							$qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
723
+
724
+							$answer = null;
725
+
726
+							/** @var RequestInterface $request */
727
+							$request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
728
+							$request_qstn = $request->getRequestParam('qstn', [], 'string', true);
729
+							if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
730
+								// check for answer in $request_qstn in case we are reprocessing a form after an error
731
+								if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
732
+									$answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
733
+										? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
734
+										: sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
735
+								}
736
+							} elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
737
+								// attendee data from the session
738
+								$answer =
739
+									isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
740
+							}
741
+
742
+
743
+							$QFI  = new EE_Question_Form_Input(
744
+								$QST,
745
+								EE_Answer::new_instance(
746
+									[
747
+										'ANS_ID'    => 0,
748
+										'QST_ID'    => 0,
749
+										'REG_ID'    => 0,
750
+										'ANS_value' => $answer,
751
+									]
752
+								),
753
+								$q_meta
754
+							);
755
+							$html .= self::generate_form_input($QFI);
756
+						}
757
+						$html .= $after_question_group_questions;
758
+						$html .= "\n\t" . '</' . $group_wrapper . '>';
759
+					}
760
+				}
761
+			}
762
+		}
763
+		return $html;
764
+	}
765
+
766
+
767
+	/**
768
+	 * generate_form_input
769
+	 *
770
+	 * @param EE_Question_Form_Input $QFI
771
+	 * @return string HTML
772
+	 * @throws EE_Error
773
+	 * @throws ReflectionException
774
+	 */
775
+	public static function generate_form_input(EE_Question_Form_Input $QFI)
776
+	{
777
+		if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
778
+			return '';
779
+		}
780
+		/** @var RequestInterface $request */
781
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
782
+
783
+		$QFI = self::_load_system_dropdowns($QFI);
784
+		$QFI = self::_load_specialized_dropdowns($QFI);
785
+
786
+		// we also need to verify
787
+
788
+		$display_text = $QFI->get('QST_display_text');
789
+		$input_name   = $QFI->get('QST_input_name');
790
+		$answer       = $request->getRequestParam($input_name, $QFI->get('ANS_value'));
791
+		$input_id     = $QFI->get('QST_input_id');
792
+		$input_class  = $QFI->get('QST_input_class');
793
+		//      $disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
794
+		$disabled          = $QFI->get('QST_disabled');
795
+		$required_label    = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
796
+		$QST_required      = $QFI->get('QST_required');
797
+		$required          =
798
+			$QST_required
799
+				? ['label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required]
800
+				: [];
801
+		$use_html_entities = $QFI->get_meta('htmlentities');
802
+		$required_text     =
803
+			$QFI->get('QST_required_text') != ''
804
+				? $QFI->get('QST_required_text')
805
+				: esc_html__('This field is required', 'event_espresso');
806
+		$required_text     = $QST_required
807
+			? "\n\t\t\t"
808
+			  . '<div class="required-text hidden">'
809
+			  . self::prep_answer($required_text, $use_html_entities)
810
+			  . '</div>'
811
+			: '';
812
+		$label_class       = 'espresso-form-input-lbl';
813
+		$QST_options       = $QFI->options(true, $answer);
814
+		$options           = is_array($QST_options) ? self::prep_answer_options($QST_options) : [];
815
+		$system_ID         = $QFI->get('QST_system');
816
+		$label_b4          = $QFI->get_meta('label_b4');
817
+		$use_desc_4_label  = $QFI->get_meta('use_desc_4_label');
818
+
819
+
820
+		switch ($QFI->get('QST_type')) {
821
+			case 'TEXTAREA':
822
+				return EEH_Form_Fields::textarea(
823
+					$display_text,
824
+					$answer,
825
+					$input_name,
826
+					$input_id,
827
+					$input_class,
828
+					[],
829
+					$required,
830
+					$required_text,
831
+					$label_class,
832
+					$disabled,
833
+					$system_ID,
834
+					$use_html_entities
835
+				);
836
+
837
+			case 'DROPDOWN':
838
+				return EEH_Form_Fields::select(
839
+					$display_text,
840
+					$answer,
841
+					$options,
842
+					$input_name,
843
+					$input_id,
844
+					$input_class,
845
+					$required,
846
+					$required_text,
847
+					$label_class,
848
+					$disabled,
849
+					$system_ID,
850
+					$use_html_entities,
851
+					true
852
+				);
853
+
854
+
855
+			case 'RADIO_BTN':
856
+				return EEH_Form_Fields::radio(
857
+					$display_text,
858
+					$answer,
859
+					$options,
860
+					$input_name,
861
+					$input_id,
862
+					$input_class,
863
+					$required,
864
+					$required_text,
865
+					$label_class,
866
+					$disabled,
867
+					$system_ID,
868
+					$use_html_entities,
869
+					$label_b4,
870
+					$use_desc_4_label
871
+				);
872
+
873
+			case 'CHECKBOX':
874
+				return EEH_Form_Fields::checkbox(
875
+					$display_text,
876
+					$answer,
877
+					$options,
878
+					$input_name,
879
+					$input_id,
880
+					$input_class,
881
+					$required,
882
+					$required_text,
883
+					$label_class,
884
+					$disabled,
885
+					$label_b4,
886
+					$system_ID,
887
+					$use_html_entities
888
+				);
889
+
890
+			case 'DATE':
891
+				return EEH_Form_Fields::datepicker(
892
+					$display_text,
893
+					$answer,
894
+					$input_name,
895
+					$input_id,
896
+					$input_class,
897
+					$required,
898
+					$required_text,
899
+					$label_class,
900
+					$disabled,
901
+					$system_ID,
902
+					$use_html_entities
903
+				);
904
+
905
+			case 'TEXT':
906
+			default:
907
+				return EEH_Form_Fields::text(
908
+					$display_text,
909
+					$answer,
910
+					$input_name,
911
+					$input_id,
912
+					$input_class,
913
+					$required,
914
+					$required_text,
915
+					$label_class,
916
+					$disabled,
917
+					$system_ID,
918
+					$use_html_entities
919
+				);
920
+		}
921
+	}
922
+
923
+
924
+	/**
925
+	 * generates HTML for a form text input
926
+	 *
927
+	 * @param string $question    label content
928
+	 * @param string $answer      form input value attribute
929
+	 * @param string $name        form input name attribute
930
+	 * @param string $id          form input css id attribute
931
+	 * @param string $class       form input css class attribute
932
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
933
+	 *                            required 'class', and required 'msg' attribute
934
+	 * @param string $label_class css class attribute for the label
935
+	 * @param string $disabled    disabled="disabled" or null
936
+	 * @return string HTML
937
+	 */
938
+	public static function text(
939
+		$question = false,
940
+		$answer = null,
941
+		$name = false,
942
+		$id = '',
943
+		$class = '',
944
+		$required = false,
945
+		$required_text = '',
946
+		$label_class = '',
947
+		$disabled = false,
948
+		$system_ID = false,
949
+		$use_html_entities = true
950
+	) {
951
+		// need these
952
+		if (! $question || ! $name) {
953
+			return null;
954
+		}
955
+		// prep the answer
956
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
957
+		// prep the required array
958
+		$required = self::prep_required($required);
959
+		// set disabled tag
960
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
961
+		// ya gots ta have style man!!!
962
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
963
+		$class     = empty($class) ? $txt_class : $class;
964
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
965
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
966
+
967
+		$label_html =
968
+			$required_text
969
+			. "\n\t\t\t"
970
+			. '<label for="' . $name . '" class="' . $label_class . '">'
971
+			. self::prep_question($question)
972
+			. $required['label']
973
+			. '</label><br/>';
974
+		// filter label but ensure required text comes before it
975
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
976
+
977
+		$input_html =
978
+			"\n\t\t\t"
979
+			. '<input type="text" name="' . $name . '" id="' . $id . '" '
980
+			. 'class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  '
981
+			. 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
982
+
983
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
984
+		return $label_html . $input_html;
985
+	}
986
+
987
+
988
+	/**
989
+	 * generates HTML for a form textarea
990
+	 *
991
+	 * @param string $question    label content
992
+	 * @param string $answer      form input value attribute
993
+	 * @param string $name        form input name attribute
994
+	 * @param string $id          form input css id attribute
995
+	 * @param string $class       form input css class attribute
996
+	 * @param array  $dimensions  array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
997
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
998
+	 *                            required 'class', and required 'msg' attribute
999
+	 * @param string $label_class css class attribute for the label
1000
+	 * @param string $disabled    disabled="disabled" or null
1001
+	 * @return string HTML
1002
+	 */
1003
+	public static function textarea(
1004
+		$question = false,
1005
+		$answer = null,
1006
+		$name = false,
1007
+		$id = '',
1008
+		$class = '',
1009
+		$dimensions = false,
1010
+		$required = false,
1011
+		$required_text = '',
1012
+		$label_class = '',
1013
+		$disabled = false,
1014
+		$system_ID = false,
1015
+		$use_html_entities = true
1016
+	) {
1017
+		// need these
1018
+		if (! $question || ! $name) {
1019
+			return null;
1020
+		}
1021
+		// prep the answer
1022
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1023
+		// prep the required array
1024
+		$required = self::prep_required($required);
1025
+		// make sure $dimensions is an array
1026
+		$dimensions = is_array($dimensions) ? $dimensions : [];
1027
+		// and set some defaults
1028
+		$dimensions = array_merge(['rows' => 3, 'cols' => 40], $dimensions);
1029
+		// set disabled tag
1030
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1031
+		// ya gots ta have style man!!!
1032
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
1033
+		$class     = empty($class) ? $txt_class : $class;
1034
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1035
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1036
+
1037
+		$label_html =
1038
+			$required_text
1039
+			. "\n\t\t\t"
1040
+			. '<label for="' . $name . '" class="' . $label_class . '">'
1041
+			. self::prep_question($question)
1042
+			. $required['label']
1043
+			. '</label><br/>';
1044
+		// filter label but ensure required text comes before it
1045
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1046
+
1047
+		$input_html =
1048
+			"\n\t\t\t"
1049
+			. '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1050
+			. 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1051
+			. 'title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1052
+			. $answer
1053
+			. '</textarea>';
1054
+
1055
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1056
+		return $label_html . $input_html;
1057
+	}
1058
+
1059
+
1060
+	/**
1061
+	 * generates HTML for a form select input
1062
+	 *
1063
+	 * @param string $question    label content
1064
+	 * @param string $answer      form input value attribute
1065
+	 * @param array  $options     array of answer options where array key = option value and array value = option
1066
+	 *                            display text
1067
+	 * @param string $name        form input name attribute
1068
+	 * @param string $id          form input css id attribute
1069
+	 * @param string $class       form input css class attribute
1070
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1071
+	 *                            required 'class', and required 'msg' attribute
1072
+	 * @param string $label_class css class attribute for the label
1073
+	 * @param string $disabled    disabled="disabled" or null
1074
+	 * @return string HTML
1075
+	 */
1076
+	public static function select(
1077
+		$question = false,
1078
+		$answer = null,
1079
+		$options = false,
1080
+		$name = false,
1081
+		$id = '',
1082
+		$class = '',
1083
+		$required = false,
1084
+		$required_text = '',
1085
+		$label_class = '',
1086
+		$disabled = false,
1087
+		$system_ID = false,
1088
+		$use_html_entities = true,
1089
+		$add_please_select_option = false
1090
+	) {
1091
+
1092
+		// need these
1093
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1094
+			return null;
1095
+		}
1096
+		// prep the answer
1097
+		$answer =
1098
+			is_array($answer)
1099
+				? self::prep_answer(array_shift($answer), $use_html_entities)
1100
+				: self::prep_answer(
1101
+					$answer,
1102
+					$use_html_entities
1103
+				);
1104
+		// prep the required array
1105
+		$required = self::prep_required($required);
1106
+		// set disabled tag
1107
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1108
+		// ya gots ta have style man!!!
1109
+		$txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
1110
+		$class     = empty($class) ? $txt_class : $class;
1111
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1112
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1113
+
1114
+		$label_html =
1115
+			$required_text
1116
+			. "\n\t\t\t"
1117
+			. '<label for="' . $name . '" class="' . $label_class . '">'
1118
+			. self::prep_question($question)
1119
+			. $required['label']
1120
+			. '</label><br/>';
1121
+		// filter label but ensure required text comes before it
1122
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1123
+
1124
+		$input_html =
1125
+			"\n\t\t\t"
1126
+			. '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1127
+			. 'title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1128
+		// recursively count array elements, to determine total number of options
1129
+		$only_option = count($options, 1) == 1;
1130
+		if (! $only_option) {
1131
+			// if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1132
+			$selected   = $answer === null ? ' selected="selected"' : '';
1133
+			$input_html .= $add_please_select_option
1134
+				? "\n\t\t\t\t"
1135
+				  . '<option value=""' . $selected . '>'
1136
+				  . esc_html__(' - please select - ', 'event_espresso')
1137
+				  . '</option>'
1138
+				: '';
1139
+		}
1140
+		foreach ($options as $key => $value) {
1141
+			// if value is an array, then create option groups, else create regular ol' options
1142
+			$input_html .= is_array($value)
1143
+				? self::_generate_select_option_group(
1144
+					$key,
1145
+					$value,
1146
+					$answer,
1147
+					$use_html_entities
1148
+				)
1149
+				: self::_generate_select_option(
1150
+					$value->value(),
1151
+					$value->desc(),
1152
+					$answer,
1153
+					$only_option,
1154
+					$use_html_entities
1155
+				);
1156
+		}
1157
+
1158
+		$input_html .= "\n\t\t\t" . '</select>';
1159
+
1160
+		$input_html =
1161
+			apply_filters(
1162
+				'FHEE__EEH_Form_Fields__select__before_end_wrapper',
1163
+				$input_html,
1164
+				$question,
1165
+				$answer,
1166
+				$name,
1167
+				$id,
1168
+				$class,
1169
+				$system_ID
1170
+			);
1171
+
1172
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1173
+		return $label_html . $input_html;
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 *  _generate_select_option_group
1179
+	 *
1180
+	 *  if  $value for a select box is an array, then the key will be used as the optgroup label
1181
+	 *  and the value array will be looped thru and the elements sent to _generate_select_option
1182
+	 *
1183
+	 * @param mixed   $opt_group
1184
+	 * @param mixed   $QSOs
1185
+	 * @param mixed   $answer
1186
+	 * @param boolean $use_html_entities
1187
+	 * @return string
1188
+	 */
1189
+	private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1190
+	{
1191
+		$html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1192
+		foreach ($QSOs as $QSO) {
1193
+			$html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1194
+		}
1195
+		$html .= "\n\t\t\t\t" . '</optgroup>';
1196
+		return $html;
1197
+	}
1198
+
1199
+
1200
+	/**
1201
+	 *  _generate_select_option
1202
+	 *
1203
+	 * @param mixed   $key
1204
+	 * @param mixed   $value
1205
+	 * @param mixed   $answer
1206
+	 * @param int     $only_option
1207
+	 * @param boolean $use_html_entities
1208
+	 * @return string
1209
+	 */
1210
+	private static function _generate_select_option(
1211
+		$key,
1212
+		$value,
1213
+		$answer,
1214
+		$only_option = false,
1215
+		$use_html_entities = true
1216
+	) {
1217
+		$key      = self::prep_answer($key, $use_html_entities);
1218
+		$value    = self::prep_answer($value, $use_html_entities);
1219
+		$value    = ! empty($value) ? $value : $key;
1220
+		$selected = ($answer == $key || $only_option) ? 'selected="selected"' : '';
1221
+		return "\n\t\t\t\t"
1222
+			   . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1223
+			   . $value
1224
+			   . '&nbsp;&nbsp;&nbsp;</option>';
1225
+	}
1226
+
1227
+
1228
+	/**
1229
+	 * generates HTML for form radio button inputs
1230
+	 *
1231
+	 * @param bool|string $question    label content
1232
+	 * @param string      $answer      form input value attribute
1233
+	 * @param array|bool  $options     array of answer options where array key = option value and array value = option
1234
+	 *                                 display text
1235
+	 * @param bool|string $name        form input name attribute
1236
+	 * @param string      $id          form input css id attribute
1237
+	 * @param string      $class       form input css class attribute
1238
+	 * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1239
+	 *                                 required 'class', and required 'msg' attribute
1240
+	 * @param string      $required_text
1241
+	 * @param string      $label_class css class attribute for the label
1242
+	 * @param bool|string $disabled    disabled="disabled" or null
1243
+	 * @param bool        $system_ID
1244
+	 * @param bool        $use_html_entities
1245
+	 * @param bool        $label_b4
1246
+	 * @param bool        $use_desc_4_label
1247
+	 * @return string HTML
1248
+	 */
1249
+	public static function radio(
1250
+		$question = false,
1251
+		$answer = null,
1252
+		$options = false,
1253
+		$name = false,
1254
+		$id = '',
1255
+		$class = '',
1256
+		$required = false,
1257
+		$required_text = '',
1258
+		$label_class = '',
1259
+		$disabled = false,
1260
+		$system_ID = false,
1261
+		$use_html_entities = true,
1262
+		$label_b4 = false,
1263
+		$use_desc_4_label = false
1264
+	) {
1265
+		// need these
1266
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1267
+			return null;
1268
+		}
1269
+		// prep the answer
1270
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1271
+		// prep the required array
1272
+		$required = self::prep_required($required);
1273
+		// set disabled tag
1274
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1275
+		// ya gots ta have style man!!!
1276
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1277
+		$class       = ! empty($class) ? $class : 'espresso-radio-btn-inp';
1278
+		$extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1279
+
1280
+		$label_html =
1281
+			$required_text
1282
+			. "\n\t\t\t"
1283
+			. '<label class="' . $label_class . '">'
1284
+			. self::prep_question($question)
1285
+			. $required['label']
1286
+			. '</label> ';
1287
+		// filter label but ensure required text comes before it
1288
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1289
+
1290
+		$input_html =
1291
+			"\n\t\t\t"
1292
+			. '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
1293
+
1294
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1295
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1296
+
1297
+		foreach ($options as $OPT) {
1298
+			if ($OPT instanceof EE_Question_Option) {
1299
+				$value   = self::prep_option_value($OPT->value());
1300
+				$label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1301
+				$size    = $use_desc_4_label
1302
+					? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1303
+					: self::get_label_size_class($OPT->value());
1304
+				$desc    = $OPT->desc();// no self::prep_answer
1305
+				$answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1306
+				$checked = (string) $value == (string) $answer ? ' checked="checked"' : '';
1307
+				$opt     = '-' . sanitize_key($value);
1308
+
1309
+				$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1310
+				$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1311
+				$input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
1312
+				$input_html .= "\n\t\t\t\t\t\t"
1313
+							   . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1314
+							   . 'class="' . $class . '" value="' . $value . '" '
1315
+							   . 'title="' . esc_attr($required['msg']) . '" ' . $disabled
1316
+							   . $checked . ' ' . $extra . '/>';
1317
+				$input_html .= ! $label_b4
1318
+					? "\n\t\t\t\t\t\t"
1319
+					  . '<span class="espresso-radio-btn-desc">'
1320
+					  . $label
1321
+					  . '</span>'
1322
+					: '';
1323
+				$input_html .= "\n\t\t\t\t\t" . '</label>';
1324
+				$input_html .= $use_desc_4_label
1325
+					? ''
1326
+					: '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1327
+				$input_html .= "\n\t\t\t\t" . '</li>';
1328
+			}
1329
+		}
1330
+
1331
+		$input_html .= "\n\t\t\t" . '</ul>';
1332
+
1333
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1334
+		return $label_html . $input_html;
1335
+	}
1336
+
1337
+
1338
+	/**
1339
+	 * generates HTML for form checkbox inputs
1340
+	 *
1341
+	 * @param string $question    label content
1342
+	 * @param string $answer      form input value attribute
1343
+	 * @param array  $options     array of options where array key = option value and array value = option display text
1344
+	 * @param string $name        form input name attribute
1345
+	 * @param string $id          form input css id attribute
1346
+	 * @param string $class       form input css class attribute
1347
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1348
+	 *                            required 'class', and required 'msg' attribute
1349
+	 * @param string $label_class css class attribute for the label
1350
+	 * @param string $disabled    disabled="disabled" or null
1351
+	 * @return string HTML
1352
+	 */
1353
+	public static function checkbox(
1354
+		$question = false,
1355
+		$answer = null,
1356
+		$options = false,
1357
+		$name = false,
1358
+		$id = '',
1359
+		$class = '',
1360
+		$required = false,
1361
+		$required_text = '',
1362
+		$label_class = '',
1363
+		$disabled = false,
1364
+		$label_b4 = false,
1365
+		$system_ID = false,
1366
+		$use_html_entities = true
1367
+	) {
1368
+		// need these
1369
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1370
+			return null;
1371
+		}
1372
+		$answer = maybe_unserialize($answer);
1373
+
1374
+		// prep the answer(s)
1375
+		$answer = is_array($answer) ? $answer : [sanitize_key($answer) => $answer];
1376
+
1377
+		foreach ($answer as $key => $value) {
1378
+			$key            = self::prep_option_value($key);
1379
+			$answer[ $key ] = self::prep_answer($value, $use_html_entities);
1380
+		}
1381
+
1382
+		// prep the required array
1383
+		$required = self::prep_required($required);
1384
+		// set disabled tag
1385
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1386
+		// ya gots ta have style man!!!
1387
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1388
+		$class       = empty($class) ? 'espresso-radio-btn-inp' : $class;
1389
+		$extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1390
+
1391
+		$label_html =
1392
+			$required_text
1393
+			. "\n\t\t\t"
1394
+			. '<label class="' . $label_class . '">'
1395
+			. self::prep_question($question)
1396
+			. $required['label']
1397
+			. '</label> ';
1398
+		// filter label but ensure required text comes before it
1399
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1400
+
1401
+		$input_html =
1402
+			"\n\t\t\t"
1403
+			. '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
1404
+
1405
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1406
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1407
+
1408
+		foreach ($options as $OPT) {
1409
+			$value = $OPT->value();// self::prep_option_value( $OPT->value() );
1410
+			$size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1411
+			$text  = self::prep_answer($OPT->value());
1412
+			$desc  = $OPT->desc();
1413
+			$opt   = '-' . sanitize_key($value);
1414
+
1415
+			$checked = is_array($answer) && in_array($text, $answer) ? ' checked="checked"' : '';
1416
+
1417
+			$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1418
+			$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1419
+			$input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1420
+			$input_html .= "\n\t\t\t\t\t\t"
1421
+						   . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1422
+						   . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1423
+						   . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1424
+			$input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1425
+			$input_html .= "\n\t\t\t\t\t" . '</label>';
1426
+			if (! empty($desc) && $desc != $text) {
1427
+				$input_html .= "\n\t\t\t\t\t"
1428
+							   . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1429
+							   . $desc
1430
+							   . '</div>';
1431
+			}
1432
+			$input_html .= "\n\t\t\t\t" . '</li>';
1433
+		}
1434
+
1435
+		$input_html .= "\n\t\t\t" . '</ul>';
1436
+
1437
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1438
+		return $label_html . $input_html;
1439
+	}
1440
+
1441
+
1442
+	/**
1443
+	 * generates HTML for a form datepicker input
1444
+	 *
1445
+	 * @param string $question    label content
1446
+	 * @param string $answer      form input value attribute
1447
+	 * @param string $name        form input name attribute
1448
+	 * @param string $id          form input css id attribute
1449
+	 * @param string $class       form input css class attribute
1450
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1451
+	 *                            required 'class', and required 'msg' attribute
1452
+	 * @param string $label_class css class attribute for the label
1453
+	 * @param string $disabled    disabled="disabled" or null
1454
+	 * @return string HTML
1455
+	 */
1456
+	public static function datepicker(
1457
+		$question = false,
1458
+		$answer = null,
1459
+		$name = false,
1460
+		$id = '',
1461
+		$class = '',
1462
+		$required = false,
1463
+		$required_text = '',
1464
+		$label_class = '',
1465
+		$disabled = false,
1466
+		$system_ID = false,
1467
+		$use_html_entities = true
1468
+	) {
1469
+		// need these
1470
+		if (! $question || ! $name) {
1471
+			return null;
1472
+		}
1473
+		// prep the answer
1474
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1475
+		// prep the required array
1476
+		$required = self::prep_required($required);
1477
+		// set disabled tag
1478
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1479
+		// ya gots ta have style man!!!
1480
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1481
+		$class     = empty($class) ? $txt_class : $class;
1482
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1483
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1484
+
1485
+		$label_html =
1486
+			$required_text
1487
+			. "\n\t\t\t"
1488
+			. '<label for="' . $name . '" class="' . $label_class . '">'
1489
+			. self::prep_question($question)
1490
+			. $required['label']
1491
+			. '</label><br/>';
1492
+		// filter label but ensure required text comes before it
1493
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1494
+
1495
+		$input_html =
1496
+			"\n\t\t\t"
1497
+			. '<input type="text" name="' . $name . '" id="' . $id . '" '
1498
+			. 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1499
+			. 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1500
+
1501
+		// enqueue scripts
1502
+		wp_register_style(
1503
+			'espresso-ui-theme',
1504
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1505
+			[],
1506
+			EVENT_ESPRESSO_VERSION
1507
+		);
1508
+		wp_enqueue_style('espresso-ui-theme');
1509
+		wp_enqueue_script('jquery-ui-datepicker');
1510
+
1511
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1512
+		return $label_html . $input_html;
1513
+	}
1514
+
1515
+
1516
+	/**
1517
+	 *  remove_label_keep_required_msg
1518
+	 *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1519
+	 *
1520
+	 * @access public
1521
+	 * @return     string
1522
+	 */
1523
+	public static function remove_label_keep_required_msg($label_html, $required_text)
1524
+	{
1525
+		return $required_text;
1526
+	}
1527
+
1528
+
1529
+	/**
1530
+	 * Simply returns the HTML for a hidden input of the given name and value.
1531
+	 *
1532
+	 * @param string $name
1533
+	 * @param string $value
1534
+	 * @return string HTML
1535
+	 */
1536
+	public static function hidden_input($name, $value, $id = '')
1537
+	{
1538
+		$id = ! empty($id) ? $id : $name;
1539
+		return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1540
+	}
1541
+
1542
+
1543
+	/**
1544
+	 * prep_question
1545
+	 *
1546
+	 * @param string $question
1547
+	 * @return string
1548
+	 */
1549
+	public static function prep_question($question)
1550
+	{
1551
+		return $question;
1552
+	}
1553
+
1554
+
1555
+	/**
1556
+	 *  prep_answer
1557
+	 *
1558
+	 * @param mixed $answer
1559
+	 * @return string
1560
+	 */
1561
+	public static function prep_answer($answer, $use_html_entities = true)
1562
+	{
1563
+		// make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired,
1564
+		// we want "0".
1565
+		if (is_bool($answer)) {
1566
+			$answer = $answer ? 1 : 0;
1567
+		}
1568
+		$answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1569
+		return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1570
+	}
1571
+
1572
+
1573
+	/**
1574
+	 *  prep_answer_options
1575
+	 *
1576
+	 * @param array $QSOs array of EE_Question_Option objects
1577
+	 * @return array
1578
+	 */
1579
+	public static function prep_answer_options($QSOs = [])
1580
+	{
1581
+		$prepped_answer_options = [];
1582
+		if (is_array($QSOs) && ! empty($QSOs)) {
1583
+			foreach ($QSOs as $key => $QSO) {
1584
+				if (! $QSO instanceof EE_Question_Option) {
1585
+					$QSO = EE_Question_Option::new_instance(
1586
+						[
1587
+							'QSO_value' => is_array($QSO) && isset($QSO['id'])
1588
+								? (string) $QSO['id']
1589
+								: (string) $key,
1590
+							'QSO_desc'  => is_array($QSO) && isset($QSO['text'])
1591
+								? (string) $QSO['text']
1592
+								: (string) $QSO,
1593
+						]
1594
+					);
1595
+				}
1596
+				if ($QSO->opt_group()) {
1597
+					$prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1598
+				} else {
1599
+					$prepped_answer_options[] = $QSO;
1600
+				}
1601
+			}
1602
+		}
1603
+		//      d( $prepped_answer_options );
1604
+		return $prepped_answer_options;
1605
+	}
1606
+
1607
+
1608
+	/**
1609
+	 *  prep_option_value
1610
+	 *
1611
+	 * @param string $option_value
1612
+	 * @return string
1613
+	 */
1614
+	public static function prep_option_value($option_value)
1615
+	{
1616
+		return esc_attr(trim(stripslashes($option_value)));
1617
+	}
1618
+
1619
+
1620
+	/**
1621
+	 *  prep_required
1622
+	 *
1623
+	 * @param string|array $required
1624
+	 * @return array
1625
+	 */
1626
+	public static function prep_required($required = [])
1627
+	{
1628
+		// make sure required is an array
1629
+		$required = is_array($required) ? $required : [];
1630
+		// and set some defaults
1631
+		return array_merge(['label' => '', 'class' => '', 'msg' => ''], $required);
1632
+	}
1633
+
1634
+
1635
+	/**
1636
+	 *  get_label_size_class
1637
+	 *
1638
+	 * @param string $value
1639
+	 * @return string
1640
+	 */
1641
+	public static function get_label_size_class($value = false)
1642
+	{
1643
+		if ($value === false || $value === '') {
1644
+			return ' class="medium-lbl"';
1645
+		}
1646
+		// determine length of option value
1647
+		$val_size = strlen($value);
1648
+		switch ($val_size) {
1649
+			case $val_size < 3:
1650
+				$size = ' class="nano-lbl"';
1651
+				break;
1652
+			case $val_size < 6:
1653
+				$size = ' class="micro-lbl"';
1654
+				break;
1655
+			case $val_size < 12:
1656
+				$size = ' class="tiny-lbl"';
1657
+				break;
1658
+			case $val_size < 25:
1659
+				$size = ' class="small-lbl"';
1660
+				break;
1661
+			case $val_size > 100:
1662
+				$size = ' class="big-lbl"';
1663
+				break;
1664
+			default:
1665
+				$size = ' class="medium-lbl"';
1666
+				break;
1667
+		}
1668
+		return $size;
1669
+	}
1670
+
1671
+
1672
+	/**
1673
+	 *  _load_system_dropdowns
1674
+	 *
1675
+	 * @param EE_Question_Form_Input $QFI
1676
+	 * @return array
1677
+	 * @throws EE_Error
1678
+	 * @throws ReflectionException
1679
+	 */
1680
+	private static function _load_system_dropdowns($QFI)
1681
+	{
1682
+		$QST_system = $QFI->get('QST_system');
1683
+		switch ($QST_system) {
1684
+			case 'state':
1685
+				$QFI = self::generate_state_dropdown($QFI);
1686
+				break;
1687
+			case 'country':
1688
+				$QFI = self::generate_country_dropdown($QFI);
1689
+				break;
1690
+			case 'admin-state':
1691
+				$QFI = self::generate_state_dropdown($QFI, true);
1692
+				break;
1693
+			case 'admin-country':
1694
+				$QFI = self::generate_country_dropdown($QFI, true);
1695
+				break;
1696
+		}
1697
+		return $QFI;
1698
+	}
1699
+
1700
+
1701
+	/**
1702
+	 * This preps dropdowns that are specialized.
1703
+	 *
1704
+	 * @param EE_Question_Form_Input $QFI
1705
+	 *
1706
+	 * @return EE_Question_Form_Input
1707
+	 * @throws EE_Error
1708
+	 * @throws ReflectionException
1709
+	 * @since  4.6.0
1710
+	 */
1711
+	protected static function _load_specialized_dropdowns($QFI)
1712
+	{
1713
+		switch ($QFI->get('QST_type')) {
1714
+			case 'STATE':
1715
+				$QFI = self::generate_state_dropdown($QFI);
1716
+				break;
1717
+			case 'COUNTRY':
1718
+				$QFI = self::generate_country_dropdown($QFI);
1719
+				break;
1720
+		}
1721
+		return $QFI;
1722
+	}
1723
+
1724
+
1725
+	/**
1726
+	 *    generate_state_dropdown
1727
+	 *
1728
+	 * @param EE_Question_Form_Input $QST
1729
+	 * @param bool                   $get_all
1730
+	 * @return EE_Question_Form_Input
1731
+	 * @throws EE_Error
1732
+	 * @throws ReflectionException
1733
+	 */
1734
+	public static function generate_state_dropdown($QST, $get_all = false)
1735
+	{
1736
+		$states = $get_all
1737
+			? EEM_State::instance()->get_all_states()
1738
+			: EEM_State::instance()->get_all_states_of_active_countries();
1739
+		if ($states && count($states) != count($QST->options())) {
1740
+			$QST->set('QST_type', 'DROPDOWN');
1741
+			// if multiple countries, we'll create option groups within the dropdown
1742
+			foreach ($states as $state) {
1743
+				if ($state instanceof EE_State) {
1744
+					$QSO = EE_Question_Option::new_instance(
1745
+						[
1746
+							'QSO_value'   => $state->ID(),
1747
+							'QSO_desc'    => $state->name(),
1748
+							'QST_ID'      => $QST->get('QST_ID'),
1749
+							'QSO_deleted' => false,
1750
+						]
1751
+					);
1752
+					// set option group
1753
+					$QSO->set_opt_group($state->country()->name());
1754
+					// add option to question
1755
+					$QST->add_temp_option($QSO);
1756
+				}
1757
+			}
1758
+		}
1759
+		return $QST;
1760
+	}
1761
+
1762
+
1763
+	/**
1764
+	 *    generate_country_dropdown
1765
+	 *
1766
+	 * @param      $QST
1767
+	 * @param bool $get_all
1768
+	 * @return array
1769
+	 * @throws EE_Error
1770
+	 * @throws ReflectionException
1771
+	 * @internal param array $question
1772
+	 */
1773
+	public static function generate_country_dropdown($QST, $get_all = false)
1774
+	{
1775
+		$countries = $get_all
1776
+			? EEM_Country::instance()->get_all_countries()
1777
+			: EEM_Country::instance()->get_all_active_countries();
1778
+		if ($countries && count($countries) != count($QST->options())) {
1779
+			$QST->set('QST_type', 'DROPDOWN');
1780
+			// now add countries
1781
+			foreach ($countries as $country) {
1782
+				if ($country instanceof EE_Country) {
1783
+					$QSO = EE_Question_Option::new_instance(
1784
+						[
1785
+							'QSO_value'   => $country->ID(),
1786
+							'QSO_desc'    => $country->name(),
1787
+							'QST_ID'      => $QST->get('QST_ID'),
1788
+							'QSO_deleted' => false,
1789
+						]
1790
+					);
1791
+					$QST->add_temp_option($QSO);
1792
+				}
1793
+			}
1794
+		}
1795
+		return $QST;
1796
+	}
1797
+
1798
+
1799
+	/**
1800
+	 *  generates options for a month dropdown selector with numbers from 01 to 12
1801
+	 *
1802
+	 * @return array()
1803
+	 */
1804
+	public static function two_digit_months_dropdown_options()
1805
+	{
1806
+		$options = [];
1807
+		for ($x = 1; $x <= 12; $x++) {
1808
+			$mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1809
+			$options[ $mm ] = $mm;
1810
+		}
1811
+		return EEH_Form_Fields::prep_answer_options($options);
1812
+	}
1813
+
1814
+
1815
+	/**
1816
+	 *  generates a year dropdown selector with numbers for the next ten years
1817
+	 *
1818
+	 * @return array
1819
+	 */
1820
+	public static function next_decade_two_digit_year_dropdown_options()
1821
+	{
1822
+		$options      = [];
1823
+		$current_year = date('y');
1824
+		$next_decade  = $current_year + 10;
1825
+		for ($x = $current_year; $x <= $next_decade; $x++) {
1826
+			$yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1827
+			$options[ $yy ] = $yy;
1828
+		}
1829
+		return EEH_Form_Fields::prep_answer_options($options);
1830
+	}
1831
+
1832
+
1833
+	/**
1834
+	 * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for
1835
+	 * list table filter.
1836
+	 *
1837
+	 * @param string  $cur_date     any currently selected date can be entered here.
1838
+	 * @param string  $status       Registration status
1839
+	 * @param integer $evt_category Event Category ID if the Event Category filter is selected
1840
+	 * @return string                html
1841
+	 * @throws EE_Error
1842
+	 */
1843
+	public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1844
+	{
1845
+		$_where = [];
1846
+		if (! empty($status)) {
1847
+			$_where['STS_ID'] = $status;
1848
+		}
1849
+
1850
+		if ($evt_category > 0) {
1851
+			$_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1852
+		}
1853
+
1854
+		$regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1855
+
1856
+		// setup vals for select input helper
1857
+		$options = [
1858
+			0 => [
1859
+				'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1860
+				'id'   => '',
1861
+			],
1862
+		];
1863
+
1864
+		foreach ($regdtts as $regdtt) {
1865
+			$date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1866
+			$options[] = [
1867
+				'text' => $date,
1868
+				'id'   => $date,
1869
+			];
1870
+		}
1871
+
1872
+		return self::select_input('month_range', $options, $cur_date, '', 'wide');
1873
+	}
1874
+
1875
+
1876
+	/**
1877
+	 * generates a month/year dropdown selector for all events matching the given criteria
1878
+	 * Typically used for list table filter
1879
+	 *
1880
+	 * @param string $cur_date          any currently selected date can be entered here.
1881
+	 * @param string $status            "view" (i.e. all, today, month, draft)
1882
+	 * @param int    $evt_category      category event belongs to
1883
+	 * @param string $evt_active_status "upcoming", "expired", "active", or "inactive"
1884
+	 * @return string                    html
1885
+	 * @throws EE_Error
1886
+	 */
1887
+	public static function generate_event_months_dropdown(
1888
+		$cur_date = '',
1889
+		$status = null,
1890
+		$evt_category = null,
1891
+		$evt_active_status = null
1892
+	) {
1893
+		// determine what post_status our condition will have for the query.
1894
+		// phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1895
+		switch ($status) {
1896
+			case 'month':
1897
+			case 'today':
1898
+			case null:
1899
+			case 'all':
1900
+				$where['Event.status'] = ['NOT IN', ['trash']];
1901
+				break;
1902
+			case 'draft':
1903
+				$where['Event.status'] = ['IN', ['draft', 'auto-draft']];
1904
+				break;
1905
+			default:
1906
+				$where['Event.status'] = $status;
1907
+		}
1908
+
1909
+		// phpcs:enable
1910
+
1911
+		// categories?
1912
+
1913
+
1914
+		if (! empty($evt_category)) {
1915
+			$where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1916
+			$where['Event.Term_Taxonomy.term_id']  = $evt_category;
1917
+		}
1918
+
1919
+
1920
+		//      $where['DTT_is_primary'] = 1;
1921
+
1922
+		$DTTS = EEM_Datetime::instance()->get_dtt_months_and_years($where, $evt_active_status);
1923
+
1924
+		// let's setup vals for select input helper
1925
+		$options = [
1926
+			0 => [
1927
+				'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1928
+				'id'   => "",
1929
+			],
1930
+		];
1931
+
1932
+
1933
+		// translate month and date
1934
+		global $wp_locale;
1935
+
1936
+		foreach ($DTTS as $DTT) {
1937
+			$localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1938
+			$id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1939
+			$options[]      = [
1940
+				'text' => $localized_date,
1941
+				'id'   => $id,
1942
+			];
1943
+		}
1944
+
1945
+
1946
+		return self::select_input('month_range', $options, $cur_date, '', 'wide');
1947
+	}
1948
+
1949
+
1950
+	/**
1951
+	 * generates the dropdown selector for event categories
1952
+	 * typically used as a filter on list tables.
1953
+	 *
1954
+	 * @param integer $current_cat currently selected category
1955
+	 * @return string               html for dropdown
1956
+	 * @throws EE_Error
1957
+	 * @throws ReflectionException
1958
+	 */
1959
+	public static function generate_event_category_dropdown($current_cat = -1)
1960
+	{
1961
+		$categories = EEM_Term::instance()->get_all_ee_categories(true);
1962
+		$options    = [
1963
+			'0' => [
1964
+				'text' => esc_html__('All Categories', 'event_espresso'),
1965
+				'id'   => -1,
1966
+			],
1967
+		];
1968
+
1969
+		// setup categories for dropdown
1970
+		foreach ($categories as $category) {
1971
+			$options[] = [
1972
+				'text' => $category->get('name'),
1973
+				'id'   => $category->ID(),
1974
+			];
1975
+		}
1976
+
1977
+		return self::select_input('EVT_CAT', $options, $current_cat);
1978
+	}
1979
+
1980
+
1981
+	/**
1982
+	 *    generate a submit button with or without it's own microform
1983
+	 *    this is the only way to create buttons that are compatible across all themes
1984
+	 *
1985
+	 * @access    public
1986
+	 * @param string      $url              - the form action
1987
+	 * @param string      $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm"
1988
+	 *                                      for the form
1989
+	 * @param string      $class            - css classes (separated by spaces if more than one)
1990
+	 * @param string      $text             - what appears on the button
1991
+	 * @param string      $nonce_action     - if using nonces
1992
+	 * @param bool|string $input_only       - whether to print form header and footer. TRUE returns the input without
1993
+	 *                                      the form
1994
+	 * @param string      $extra_attributes - any extra attributes that need to be attached to the form input
1995
+	 * @return    string
1996
+	 */
1997
+	public static function submit_button(
1998
+		$url = '',
1999
+		$ID = '',
2000
+		$class = '',
2001
+		$text = '',
2002
+		$nonce_action = '',
2003
+		$input_only = false,
2004
+		$extra_attributes = ''
2005
+	) {
2006
+		$btn = '';
2007
+		if (empty($url) || empty($ID)) {
2008
+			return $btn;
2009
+		}
2010
+		$text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2011
+		$btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2012
+				 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2013
+		if (! $input_only) {
2014
+			$btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2015
+			$btn_frm .= ! empty($nonce_action)
2016
+				? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2017
+				: '';
2018
+			$btn_frm .= $btn;
2019
+			$btn_frm .= '</form>';
2020
+			$btn     = $btn_frm;
2021
+			unset($btn_frm);
2022
+		}
2023
+		return $btn;
2024
+	}
2025 2025
 }
Please login to merge, or discard this patch.
Spacing   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -110,8 +110,8 @@  discard block
 block discarded – undo
110 110
             $type           = $input_value['input'];
111 111
             $value          = $input_value['value'];
112 112
 
113
-            $id    = $form_id ? $form_id . '-' . $input_key : $input_key;
114
-            $class = $required ? 'required ' . $css_class : $css_class;
113
+            $id    = $form_id ? $form_id.'-'.$input_key : $input_key;
114
+            $class = $required ? 'required '.$css_class : $css_class;
115 115
 
116 116
             // what type of input are we dealing with ?
117 117
             switch ($type) {
@@ -163,8 +163,8 @@  discard block
 block discarded – undo
163 163
             }
164 164
         } // end foreach( $input_vars as $input_key => $input_value )
165 165
 
166
-        if (! empty($inputs)) {
167
-            $glue   = "
166
+        if ( ! empty($inputs)) {
167
+            $glue = "
168 168
                 </li>
169 169
                 <li>
170 170
                     ";
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
             </ul>
178 178
             ";
179 179
         }
180
-        return $output . implode("\n", $hidden_inputs);
180
+        return $output.implode("\n", $hidden_inputs);
181 181
     }
182 182
 
183 183
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
             // generate label
259 259
             $label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
260 260
             // generate field name
261
-            $name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
261
+            $name = ! empty($unique_id) ? $field_name.'['.$unique_id.']' : $field_name;
262 262
 
263 263
             // we determine what we're building based on the type
264 264
             switch ($type) {
@@ -269,14 +269,14 @@  discard block
 block discarded – undo
269 269
                         foreach ($value as $key => $val) {
270 270
                             $c_input .= self::adminMulti(
271 271
                                 $default,
272
-                                isset($classes[ $key ]) ? $classes[ $key ] : '',
273
-                                $field_name . '_' . $value,
272
+                                isset($classes[$key]) ? $classes[$key] : '',
273
+                                $field_name.'_'.$value,
274 274
                                 $name,
275 275
                                 $required,
276 276
                                 $tab_index,
277 277
                                 $type,
278 278
                                 $val,
279
-                                isset($labels[ $key ]) ? $labels[ $key ] : ''
279
+                                isset($labels[$key]) ? $labels[$key] : ''
280 280
                             );
281 281
                         }
282 282
                         $field = $c_input;
@@ -302,7 +302,7 @@  discard block
 block discarded – undo
302 302
                 case 'select':
303 303
                     $options = [];
304 304
                     foreach ($value as $key => $val) {
305
-                        $options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
305
+                        $options[$val] = isset($labels[$key]) ? $labels[$key] : '';
306 306
                     }
307 307
                     $field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
308 308
                     break;
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
                     $field = self::adminText($class, $id, $name, $required, $tab_index, $value);
329 329
             }
330 330
 
331
-            $form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
331
+            $form_fields[$field_name] = ['label' => $label, 'field' => $field.$extra_desc];
332 332
         }
333 333
 
334 334
         return $form_fields;
@@ -536,7 +536,7 @@  discard block
 block discarded – undo
536 536
     public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
537 537
     {
538 538
         // if $values was submitted in the wrong format, convert it over
539
-        if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
539
+        if ( ! empty($values) && ( ! array_key_exists(0, $values) || ! is_array($values[0]))) {
540 540
             $converted_values = [];
541 541
             foreach ($values as $id => $text) {
542 542
                 $converted_values[] = ['id' => $id, 'text' => $text];
@@ -545,18 +545,18 @@  discard block
 block discarded – undo
545 545
         }
546 546
 
547 547
         $field =
548
-            '<select id="' . EEH_Formatter::ee_tep_output_string($name)
549
-            . '" name="' . EEH_Formatter::ee_tep_output_string($name)
548
+            '<select id="'.EEH_Formatter::ee_tep_output_string($name)
549
+            . '" name="'.EEH_Formatter::ee_tep_output_string($name)
550 550
             . '"';
551 551
 
552 552
         if (EEH_Formatter::ee_tep_not_null($parameters)) {
553
-            $field .= ' ' . $parameters;
553
+            $field .= ' '.$parameters;
554 554
         }
555 555
         if ($autosize) {
556 556
             $size = 'med';
557 557
             for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
558
-                if ($values[ $ii ]['text']) {
559
-                    if (strlen($values[ $ii ]['text']) > 5) {
558
+                if ($values[$ii]['text']) {
559
+                    if (strlen($values[$ii]['text']) > 5) {
560 560
                         $size = 'wide';
561 561
                     }
562 562
                 }
@@ -565,22 +565,22 @@  discard block
 block discarded – undo
565 565
             $size = '';
566 566
         }
567 567
 
568
-        $field .= ' class="' . $class . ' ' . $size . '">';
568
+        $field .= ' class="'.$class.' '.$size.'">';
569 569
 
570
-        if (empty($default) && isset($GLOBALS[ $name ])) {
571
-            $default = stripslashes($GLOBALS[ $name ]);
570
+        if (empty($default) && isset($GLOBALS[$name])) {
571
+            $default = stripslashes($GLOBALS[$name]);
572 572
         }
573 573
 
574 574
 
575 575
         for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
576
-            $field .= '<option value="' . $values[ $i ]['id'] . '"';
577
-            if ($default == $values[ $i ]['id']) {
576
+            $field .= '<option value="'.$values[$i]['id'].'"';
577
+            if ($default == $values[$i]['id']) {
578 578
                 $field .= ' selected = "selected"';
579 579
             }
580
-            if (isset($values[ $i ]['class'])) {
581
-                $field .= ' class="' . $values[ $i ]['class'] . '"';
580
+            if (isset($values[$i]['class'])) {
581
+                $field .= ' class="'.$values[$i]['class'].'"';
582 582
             }
583
-            $field .= '>' . $values[ $i ]['text'] . '</option>';
583
+            $field .= '>'.$values[$i]['text'].'</option>';
584 584
         }
585 585
         $field .= '</select>';
586 586
 
@@ -606,11 +606,11 @@  discard block
 block discarded – undo
606 606
         $after_question_group_questions  =
607 607
             apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
608 608
 
609
-        if (! empty($question_groups)) {
609
+        if ( ! empty($question_groups)) {
610 610
             // loop thru question groups
611 611
             foreach ($question_groups as $QSG) {
612 612
                 // check that questions exist
613
-                if (! empty($QSG['QSG_questions'])) {
613
+                if ( ! empty($QSG['QSG_questions'])) {
614 614
                     // use fieldsets
615 615
                     $html .= "\n\t"
616 616
                              . '<'
@@ -635,7 +635,7 @@  discard block
 block discarded – undo
635 635
                     $html .= $before_question_group_questions;
636 636
                     // loop thru questions
637 637
                     foreach ($QSG['QSG_questions'] as $question) {
638
-                        $QFI  = new EE_Question_Form_Input(
638
+                        $QFI = new EE_Question_Form_Input(
639 639
                             $question['qst_obj'],
640 640
                             $question['ans_obj'],
641 641
                             $question
@@ -643,7 +643,7 @@  discard block
 block discarded – undo
643 643
                         $html .= self::generate_form_input($QFI);
644 644
                     }
645 645
                     $html .= $after_question_group_questions;
646
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
646
+                    $html .= "\n\t".'</'.$group_wrapper.'>';
647 647
                 }
648 648
             }
649 649
         }
@@ -683,25 +683,25 @@  discard block
 block discarded – undo
683 683
             'input_id'    => '',
684 684
             'input_class' => '',
685 685
         ];
686
-        $q_meta         = array_merge($default_q_meta, $q_meta);
686
+        $q_meta = array_merge($default_q_meta, $q_meta);
687 687
 
688
-        if (! empty($question_groups)) {
688
+        if ( ! empty($question_groups)) {
689 689
             // loop thru question groups
690 690
             foreach ($question_groups as $QSG) {
691 691
                 if ($QSG instanceof EE_Question_Group) {
692 692
                     // check that questions exist
693 693
 
694 694
                     $where = ['QST_deleted' => 0];
695
-                    if (! $from_admin) {
695
+                    if ( ! $from_admin) {
696 696
                         $where['QST_admin_only'] = 0;
697 697
                     }
698 698
                     $questions =
699 699
                         $QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
700
-                    if (! empty($questions)) {
700
+                    if ( ! empty($questions)) {
701 701
                         // use fieldsets
702 702
                         $html .= "\n\t"
703
-                                 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
704
-                                 . 'id="' . $QSG->get('QSG_identifier') . '">';
703
+                                 . '<'.$group_wrapper.' class="espresso-question-group-wrap" '
704
+                                 . 'id="'.$QSG->get('QSG_identifier').'">';
705 705
                         // group_name
706 706
                         if ($QSG->show_group_name()) {
707 707
                             $html .= "\n\t\t"
@@ -726,21 +726,21 @@  discard block
 block discarded – undo
726 726
                             /** @var RequestInterface $request */
727 727
                             $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
728 728
                             $request_qstn = $request->getRequestParam('qstn', [], 'string', true);
729
-                            if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
729
+                            if ( ! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
730 730
                                 // check for answer in $request_qstn in case we are reprocessing a form after an error
731
-                                if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
732
-                                    $answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
733
-                                        ? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
734
-                                        : sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
731
+                                if (isset($request_qstn[$q_meta['input_id']][$qstn_id])) {
732
+                                    $answer = is_array($request_qstn[$q_meta['input_id']][$qstn_id])
733
+                                        ? $request_qstn[$q_meta['input_id']][$qstn_id]
734
+                                        : sanitize_text_field($request_qstn[$q_meta['input_id']][$qstn_id]);
735 735
                                 }
736 736
                             } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
737 737
                                 // attendee data from the session
738 738
                                 $answer =
739
-                                    isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
739
+                                    isset($q_meta['attendee'][$qstn_id]) ? $q_meta['attendee'][$qstn_id] : null;
740 740
                             }
741 741
 
742 742
 
743
-                            $QFI  = new EE_Question_Form_Input(
743
+                            $QFI = new EE_Question_Form_Input(
744 744
                                 $QST,
745 745
                                 EE_Answer::new_instance(
746 746
                                     [
@@ -755,7 +755,7 @@  discard block
 block discarded – undo
755 755
                             $html .= self::generate_form_input($QFI);
756 756
                         }
757 757
                         $html .= $after_question_group_questions;
758
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
758
+                        $html .= "\n\t".'</'.$group_wrapper.'>';
759 759
                     }
760 760
                 }
761 761
             }
@@ -803,7 +803,7 @@  discard block
 block discarded – undo
803 803
             $QFI->get('QST_required_text') != ''
804 804
                 ? $QFI->get('QST_required_text')
805 805
                 : esc_html__('This field is required', 'event_espresso');
806
-        $required_text     = $QST_required
806
+        $required_text = $QST_required
807 807
             ? "\n\t\t\t"
808 808
               . '<div class="required-text hidden">'
809 809
               . self::prep_answer($required_text, $use_html_entities)
@@ -949,7 +949,7 @@  discard block
 block discarded – undo
949 949
         $use_html_entities = true
950 950
     ) {
951 951
         // need these
952
-        if (! $question || ! $name) {
952
+        if ( ! $question || ! $name) {
953 953
             return null;
954 954
         }
955 955
         // prep the answer
@@ -961,13 +961,13 @@  discard block
 block discarded – undo
961 961
         // ya gots ta have style man!!!
962 962
         $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
963 963
         $class     = empty($class) ? $txt_class : $class;
964
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
964
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
965 965
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
966 966
 
967 967
         $label_html =
968 968
             $required_text
969 969
             . "\n\t\t\t"
970
-            . '<label for="' . $name . '" class="' . $label_class . '">'
970
+            . '<label for="'.$name.'" class="'.$label_class.'">'
971 971
             . self::prep_question($question)
972 972
             . $required['label']
973 973
             . '</label><br/>';
@@ -976,12 +976,12 @@  discard block
 block discarded – undo
976 976
 
977 977
         $input_html =
978 978
             "\n\t\t\t"
979
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
980
-            . 'class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  '
981
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
979
+            . '<input type="text" name="'.$name.'" id="'.$id.'" '
980
+            . 'class="'.$class.' '.$required['class'].'" value="'.esc_attr($answer).'"  '
981
+            . 'title="'.esc_attr($required['msg']).'" '.$disabled.' '.$extra.'/>';
982 982
 
983 983
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
984
-        return $label_html . $input_html;
984
+        return $label_html.$input_html;
985 985
     }
986 986
 
987 987
 
@@ -1015,7 +1015,7 @@  discard block
 block discarded – undo
1015 1015
         $use_html_entities = true
1016 1016
     ) {
1017 1017
         // need these
1018
-        if (! $question || ! $name) {
1018
+        if ( ! $question || ! $name) {
1019 1019
             return null;
1020 1020
         }
1021 1021
         // prep the answer
@@ -1031,13 +1031,13 @@  discard block
 block discarded – undo
1031 1031
         // ya gots ta have style man!!!
1032 1032
         $txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
1033 1033
         $class     = empty($class) ? $txt_class : $class;
1034
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1034
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
1035 1035
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1036 1036
 
1037 1037
         $label_html =
1038 1038
             $required_text
1039 1039
             . "\n\t\t\t"
1040
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1040
+            . '<label for="'.$name.'" class="'.$label_class.'">'
1041 1041
             . self::prep_question($question)
1042 1042
             . $required['label']
1043 1043
             . '</label><br/>';
@@ -1046,14 +1046,14 @@  discard block
 block discarded – undo
1046 1046
 
1047 1047
         $input_html =
1048 1048
             "\n\t\t\t"
1049
-            . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1050
-            . 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1051
-            . 'title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1049
+            . '<textarea name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].'" '
1050
+            . 'rows="'.$dimensions['rows'].'" cols="'.$dimensions['cols'].'"  '
1051
+            . 'title="'.$required['msg'].'" '.$disabled.' '.$extra.'>'
1052 1052
             . $answer
1053 1053
             . '</textarea>';
1054 1054
 
1055 1055
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1056
-        return $label_html . $input_html;
1056
+        return $label_html.$input_html;
1057 1057
     }
1058 1058
 
1059 1059
 
@@ -1090,7 +1090,7 @@  discard block
 block discarded – undo
1090 1090
     ) {
1091 1091
 
1092 1092
         // need these
1093
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1093
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1094 1094
             return null;
1095 1095
         }
1096 1096
         // prep the answer
@@ -1108,13 +1108,13 @@  discard block
 block discarded – undo
1108 1108
         // ya gots ta have style man!!!
1109 1109
         $txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
1110 1110
         $class     = empty($class) ? $txt_class : $class;
1111
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1111
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
1112 1112
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1113 1113
 
1114 1114
         $label_html =
1115 1115
             $required_text
1116 1116
             . "\n\t\t\t"
1117
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1117
+            . '<label for="'.$name.'" class="'.$label_class.'">'
1118 1118
             . self::prep_question($question)
1119 1119
             . $required['label']
1120 1120
             . '</label><br/>';
@@ -1123,16 +1123,16 @@  discard block
 block discarded – undo
1123 1123
 
1124 1124
         $input_html =
1125 1125
             "\n\t\t\t"
1126
-            . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1127
-            . 'title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1126
+            . '<select name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].'" '
1127
+            . 'title="'.esc_attr($required['msg']).'"'.$disabled.' '.$extra.'>';
1128 1128
         // recursively count array elements, to determine total number of options
1129 1129
         $only_option = count($options, 1) == 1;
1130
-        if (! $only_option) {
1130
+        if ( ! $only_option) {
1131 1131
             // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1132
-            $selected   = $answer === null ? ' selected="selected"' : '';
1132
+            $selected = $answer === null ? ' selected="selected"' : '';
1133 1133
             $input_html .= $add_please_select_option
1134 1134
                 ? "\n\t\t\t\t"
1135
-                  . '<option value=""' . $selected . '>'
1135
+                  . '<option value=""'.$selected.'>'
1136 1136
                   . esc_html__(' - please select - ', 'event_espresso')
1137 1137
                   . '</option>'
1138 1138
                 : '';
@@ -1155,7 +1155,7 @@  discard block
 block discarded – undo
1155 1155
                 );
1156 1156
         }
1157 1157
 
1158
-        $input_html .= "\n\t\t\t" . '</select>';
1158
+        $input_html .= "\n\t\t\t".'</select>';
1159 1159
 
1160 1160
         $input_html =
1161 1161
             apply_filters(
@@ -1170,7 +1170,7 @@  discard block
 block discarded – undo
1170 1170
             );
1171 1171
 
1172 1172
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1173
-        return $label_html . $input_html;
1173
+        return $label_html.$input_html;
1174 1174
     }
1175 1175
 
1176 1176
 
@@ -1188,11 +1188,11 @@  discard block
 block discarded – undo
1188 1188
      */
1189 1189
     private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1190 1190
     {
1191
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1191
+        $html = "\n\t\t\t\t".'<optgroup label="'.self::prep_option_value($opt_group).'">';
1192 1192
         foreach ($QSOs as $QSO) {
1193 1193
             $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1194 1194
         }
1195
-        $html .= "\n\t\t\t\t" . '</optgroup>';
1195
+        $html .= "\n\t\t\t\t".'</optgroup>';
1196 1196
         return $html;
1197 1197
     }
1198 1198
 
@@ -1219,7 +1219,7 @@  discard block
 block discarded – undo
1219 1219
         $value    = ! empty($value) ? $value : $key;
1220 1220
         $selected = ($answer == $key || $only_option) ? 'selected="selected"' : '';
1221 1221
         return "\n\t\t\t\t"
1222
-               . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1222
+               . '<option value="'.self::prep_option_value($key).'" '.$selected.'> '
1223 1223
                . $value
1224 1224
                . '&nbsp;&nbsp;&nbsp;</option>';
1225 1225
     }
@@ -1263,7 +1263,7 @@  discard block
 block discarded – undo
1263 1263
         $use_desc_4_label = false
1264 1264
     ) {
1265 1265
         // need these
1266
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1266
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1267 1267
             return null;
1268 1268
         }
1269 1269
         // prep the answer
@@ -1280,7 +1280,7 @@  discard block
 block discarded – undo
1280 1280
         $label_html =
1281 1281
             $required_text
1282 1282
             . "\n\t\t\t"
1283
-            . '<label class="' . $label_class . '">'
1283
+            . '<label class="'.$label_class.'">'
1284 1284
             . self::prep_question($question)
1285 1285
             . $required['label']
1286 1286
             . '</label> ';
@@ -1289,49 +1289,49 @@  discard block
 block discarded – undo
1289 1289
 
1290 1290
         $input_html =
1291 1291
             "\n\t\t\t"
1292
-            . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
1292
+            . '<ul id="'.$id.'-ul" class="espresso-radio-btn-options-ul '.$label_class.' '.$class.'-ul">';
1293 1293
 
1294
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1295
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1294
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1295
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
1296 1296
 
1297 1297
         foreach ($options as $OPT) {
1298 1298
             if ($OPT instanceof EE_Question_Option) {
1299 1299
                 $value   = self::prep_option_value($OPT->value());
1300 1300
                 $label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1301 1301
                 $size    = $use_desc_4_label
1302
-                    ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1302
+                    ? self::get_label_size_class($OPT->value().' '.$OPT->desc())
1303 1303
                     : self::get_label_size_class($OPT->value());
1304
-                $desc    = $OPT->desc();// no self::prep_answer
1304
+                $desc    = $OPT->desc(); // no self::prep_answer
1305 1305
                 $answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1306 1306
                 $checked = (string) $value == (string) $answer ? ' checked="checked"' : '';
1307
-                $opt     = '-' . sanitize_key($value);
1307
+                $opt     = '-'.sanitize_key($value);
1308 1308
 
1309
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1310
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1311
-                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
1309
+                $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
1310
+                $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-radio-btn-lbl">';
1311
+                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$label.'</span>' : '';
1312 1312
                 $input_html .= "\n\t\t\t\t\t\t"
1313
-                               . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1314
-                               . 'class="' . $class . '" value="' . $value . '" '
1315
-                               . 'title="' . esc_attr($required['msg']) . '" ' . $disabled
1316
-                               . $checked . ' ' . $extra . '/>';
1313
+                               . '<input type="radio" name="'.$name.'" id="'.$id.$opt.'" '
1314
+                               . 'class="'.$class.'" value="'.$value.'" '
1315
+                               . 'title="'.esc_attr($required['msg']).'" '.$disabled
1316
+                               . $checked.' '.$extra.'/>';
1317 1317
                 $input_html .= ! $label_b4
1318 1318
                     ? "\n\t\t\t\t\t\t"
1319 1319
                       . '<span class="espresso-radio-btn-desc">'
1320 1320
                       . $label
1321 1321
                       . '</span>'
1322 1322
                     : '';
1323
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
1323
+                $input_html .= "\n\t\t\t\t\t".'</label>';
1324 1324
                 $input_html .= $use_desc_4_label
1325 1325
                     ? ''
1326
-                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1327
-                $input_html .= "\n\t\t\t\t" . '</li>';
1326
+                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">'.$desc.'</span>';
1327
+                $input_html .= "\n\t\t\t\t".'</li>';
1328 1328
             }
1329 1329
         }
1330 1330
 
1331
-        $input_html .= "\n\t\t\t" . '</ul>';
1331
+        $input_html .= "\n\t\t\t".'</ul>';
1332 1332
 
1333 1333
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1334
-        return $label_html . $input_html;
1334
+        return $label_html.$input_html;
1335 1335
     }
1336 1336
 
1337 1337
 
@@ -1366,7 +1366,7 @@  discard block
 block discarded – undo
1366 1366
         $use_html_entities = true
1367 1367
     ) {
1368 1368
         // need these
1369
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1369
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1370 1370
             return null;
1371 1371
         }
1372 1372
         $answer = maybe_unserialize($answer);
@@ -1376,7 +1376,7 @@  discard block
 block discarded – undo
1376 1376
 
1377 1377
         foreach ($answer as $key => $value) {
1378 1378
             $key            = self::prep_option_value($key);
1379
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
1379
+            $answer[$key] = self::prep_answer($value, $use_html_entities);
1380 1380
         }
1381 1381
 
1382 1382
         // prep the required array
@@ -1391,7 +1391,7 @@  discard block
 block discarded – undo
1391 1391
         $label_html =
1392 1392
             $required_text
1393 1393
             . "\n\t\t\t"
1394
-            . '<label class="' . $label_class . '">'
1394
+            . '<label class="'.$label_class.'">'
1395 1395
             . self::prep_question($question)
1396 1396
             . $required['label']
1397 1397
             . '</label> ';
@@ -1400,42 +1400,42 @@  discard block
 block discarded – undo
1400 1400
 
1401 1401
         $input_html =
1402 1402
             "\n\t\t\t"
1403
-            . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
1403
+            . '<ul id="'.$id.'-ul" class="espresso-checkbox-options-ul '.$label_class.' '.$class.'-ul">';
1404 1404
 
1405
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1406
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1405
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1406
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
1407 1407
 
1408 1408
         foreach ($options as $OPT) {
1409
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
1410
-            $size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1409
+            $value = $OPT->value(); // self::prep_option_value( $OPT->value() );
1410
+            $size  = self::get_label_size_class($OPT->value().' '.$OPT->desc());
1411 1411
             $text  = self::prep_answer($OPT->value());
1412 1412
             $desc  = $OPT->desc();
1413
-            $opt   = '-' . sanitize_key($value);
1413
+            $opt   = '-'.sanitize_key($value);
1414 1414
 
1415 1415
             $checked = is_array($answer) && in_array($text, $answer) ? ' checked="checked"' : '';
1416 1416
 
1417
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1418
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1419
-            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1417
+            $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
1418
+            $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-checkbox-lbl">';
1419
+            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$text.'</span>' : '';
1420 1420
             $input_html .= "\n\t\t\t\t\t\t"
1421
-                           . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1422
-                           . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1423
-                           . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1424
-            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1425
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
1426
-            if (! empty($desc) && $desc != $text) {
1421
+                           . '<input type="checkbox" name="'.$name.'['.$OPT->ID().']" '
1422
+                           . 'id="'.$id.$opt.'" class="'.$class.'" value="'.$value.'" '
1423
+                           . 'title="'.esc_attr($required['msg']).'" '.$disabled.$checked.' '.$extra.'/>';
1424
+            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$text.'</span>' : '';
1425
+            $input_html .= "\n\t\t\t\t\t".'</label>';
1426
+            if ( ! empty($desc) && $desc != $text) {
1427 1427
                 $input_html .= "\n\t\t\t\t\t"
1428 1428
                                . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1429 1429
                                . $desc
1430 1430
                                . '</div>';
1431 1431
             }
1432
-            $input_html .= "\n\t\t\t\t" . '</li>';
1432
+            $input_html .= "\n\t\t\t\t".'</li>';
1433 1433
         }
1434 1434
 
1435
-        $input_html .= "\n\t\t\t" . '</ul>';
1435
+        $input_html .= "\n\t\t\t".'</ul>';
1436 1436
 
1437 1437
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1438
-        return $label_html . $input_html;
1438
+        return $label_html.$input_html;
1439 1439
     }
1440 1440
 
1441 1441
 
@@ -1467,7 +1467,7 @@  discard block
 block discarded – undo
1467 1467
         $use_html_entities = true
1468 1468
     ) {
1469 1469
         // need these
1470
-        if (! $question || ! $name) {
1470
+        if ( ! $question || ! $name) {
1471 1471
             return null;
1472 1472
         }
1473 1473
         // prep the answer
@@ -1479,13 +1479,13 @@  discard block
 block discarded – undo
1479 1479
         // ya gots ta have style man!!!
1480 1480
         $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1481 1481
         $class     = empty($class) ? $txt_class : $class;
1482
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1482
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
1483 1483
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1484 1484
 
1485 1485
         $label_html =
1486 1486
             $required_text
1487 1487
             . "\n\t\t\t"
1488
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1488
+            . '<label for="'.$name.'" class="'.$label_class.'">'
1489 1489
             . self::prep_question($question)
1490 1490
             . $required['label']
1491 1491
             . '</label><br/>';
@@ -1494,14 +1494,14 @@  discard block
 block discarded – undo
1494 1494
 
1495 1495
         $input_html =
1496 1496
             "\n\t\t\t"
1497
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
1498
-            . 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1499
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1497
+            . '<input type="text" name="'.$name.'" id="'.$id.'" '
1498
+            . 'class="'.$class.' '.$required['class'].' datepicker" value="'.$answer.'"  '
1499
+            . 'title="'.esc_attr($required['msg']).'" '.$disabled.' '.$extra.'/>';
1500 1500
 
1501 1501
         // enqueue scripts
1502 1502
         wp_register_style(
1503 1503
             'espresso-ui-theme',
1504
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1504
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1505 1505
             [],
1506 1506
             EVENT_ESPRESSO_VERSION
1507 1507
         );
@@ -1509,7 +1509,7 @@  discard block
 block discarded – undo
1509 1509
         wp_enqueue_script('jquery-ui-datepicker');
1510 1510
 
1511 1511
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1512
-        return $label_html . $input_html;
1512
+        return $label_html.$input_html;
1513 1513
     }
1514 1514
 
1515 1515
 
@@ -1536,7 +1536,7 @@  discard block
 block discarded – undo
1536 1536
     public static function hidden_input($name, $value, $id = '')
1537 1537
     {
1538 1538
         $id = ! empty($id) ? $id : $name;
1539
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1539
+        return '<input id="'.$id.'" type="hidden" name="'.$name.'" value="'.$value.'"/>';
1540 1540
     }
1541 1541
 
1542 1542
 
@@ -1581,7 +1581,7 @@  discard block
 block discarded – undo
1581 1581
         $prepped_answer_options = [];
1582 1582
         if (is_array($QSOs) && ! empty($QSOs)) {
1583 1583
             foreach ($QSOs as $key => $QSO) {
1584
-                if (! $QSO instanceof EE_Question_Option) {
1584
+                if ( ! $QSO instanceof EE_Question_Option) {
1585 1585
                     $QSO = EE_Question_Option::new_instance(
1586 1586
                         [
1587 1587
                             'QSO_value' => is_array($QSO) && isset($QSO['id'])
@@ -1594,7 +1594,7 @@  discard block
 block discarded – undo
1594 1594
                     );
1595 1595
                 }
1596 1596
                 if ($QSO->opt_group()) {
1597
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1597
+                    $prepped_answer_options[$QSO->opt_group()][] = $QSO;
1598 1598
                 } else {
1599 1599
                     $prepped_answer_options[] = $QSO;
1600 1600
                 }
@@ -1806,7 +1806,7 @@  discard block
 block discarded – undo
1806 1806
         $options = [];
1807 1807
         for ($x = 1; $x <= 12; $x++) {
1808 1808
             $mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1809
-            $options[ $mm ] = $mm;
1809
+            $options[$mm] = $mm;
1810 1810
         }
1811 1811
         return EEH_Form_Fields::prep_answer_options($options);
1812 1812
     }
@@ -1824,7 +1824,7 @@  discard block
 block discarded – undo
1824 1824
         $next_decade  = $current_year + 10;
1825 1825
         for ($x = $current_year; $x <= $next_decade; $x++) {
1826 1826
             $yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1827
-            $options[ $yy ] = $yy;
1827
+            $options[$yy] = $yy;
1828 1828
         }
1829 1829
         return EEH_Form_Fields::prep_answer_options($options);
1830 1830
     }
@@ -1843,7 +1843,7 @@  discard block
 block discarded – undo
1843 1843
     public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1844 1844
     {
1845 1845
         $_where = [];
1846
-        if (! empty($status)) {
1846
+        if ( ! empty($status)) {
1847 1847
             $_where['STS_ID'] = $status;
1848 1848
         }
1849 1849
 
@@ -1862,7 +1862,7 @@  discard block
 block discarded – undo
1862 1862
         ];
1863 1863
 
1864 1864
         foreach ($regdtts as $regdtt) {
1865
-            $date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1865
+            $date      = $regdtt->reg_month.' '.$regdtt->reg_year;
1866 1866
             $options[] = [
1867 1867
                 'text' => $date,
1868 1868
                 'id'   => $date,
@@ -1911,7 +1911,7 @@  discard block
 block discarded – undo
1911 1911
         // categories?
1912 1912
 
1913 1913
 
1914
-        if (! empty($evt_category)) {
1914
+        if ( ! empty($evt_category)) {
1915 1915
             $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1916 1916
             $where['Event.Term_Taxonomy.term_id']  = $evt_category;
1917 1917
         }
@@ -1934,8 +1934,8 @@  discard block
 block discarded – undo
1934 1934
         global $wp_locale;
1935 1935
 
1936 1936
         foreach ($DTTS as $DTT) {
1937
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1938
-            $id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1937
+            $localized_date = $wp_locale->get_month($DTT->dtt_month_num).' '.$DTT->dtt_year;
1938
+            $id             = $DTT->dtt_month.' '.$DTT->dtt_year;
1939 1939
             $options[]      = [
1940 1940
                 'text' => $localized_date,
1941 1941
                 'id'   => $id,
@@ -2008,16 +2008,16 @@  discard block
 block discarded – undo
2008 2008
             return $btn;
2009 2009
         }
2010 2010
         $text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2011
-        $btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2012
-                 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2013
-        if (! $input_only) {
2014
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2011
+        $btn .= '<input id="'.$ID.'-btn" class="'.$class.'" '
2012
+                 . 'type="submit" value="'.$text.'" '.$extra_attributes.'/>';
2013
+        if ( ! $input_only) {
2014
+            $btn_frm = '<form id="'.$ID.'-frm" method="POST" action="'.$url.'">';
2015 2015
             $btn_frm .= ! empty($nonce_action)
2016
-                ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2016
+                ? wp_nonce_field($nonce_action, $nonce_action.'_nonce', true, false)
2017 2017
                 : '';
2018 2018
             $btn_frm .= $btn;
2019 2019
             $btn_frm .= '</form>';
2020
-            $btn     = $btn_frm;
2020
+            $btn = $btn_frm;
2021 2021
             unset($btn_frm);
2022 2022
         }
2023 2023
         return $btn;
Please login to merge, or discard this patch.
core/helpers/EEH_MSG_Template.helper.php 1 patch
Indentation   +1249 added lines, -1249 removed lines patch added patch discarded remove patch
@@ -15,1253 +15,1253 @@
 block discarded – undo
15 15
 {
16 16
 
17 17
 
18
-    /**
19
-     * Holds a collection of EE_Message_Template_Pack objects.
20
-     * @type EE_Messages_Template_Pack_Collection
21
-     */
22
-    protected static $_template_pack_collection;
23
-
24
-
25
-    /**
26
-     * @throws EE_Error
27
-     */
28
-    private static function _set_autoloader()
29
-    {
30
-        EED_Messages::set_autoloaders();
31
-    }
32
-
33
-
34
-    /**
35
-     * generate_new_templates
36
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
37
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
38
-     * for the event.
39
-     *
40
-     * @access protected
41
-     * @param string $messenger     the messenger we are generating templates for
42
-     * @param array  $message_types array of message types that the templates are generated for.
43
-     * @param int    $GRP_ID        If a non global template is being generated then it is expected we'll have a GRP_ID
44
-     *                              to use as the base for the new generated template.
45
-     * @param bool   $global        true indicates generating templates on messenger activation. false requires GRP_ID
46
-     *                              for event specific template generation.
47
-     * @return array  @see EEH_MSG_Template::_create_new_templates for the return value of each element in the array
48
-     *                for templates that are generated.  If this is an empty array then it means no templates were
49
-     *                generated which usually means there was an error.  Anything in the array with an empty value for
50
-     *                `MTP_context` means that it was not a new generated template but just reactivated (which only
51
-     *                happens for global templates that already exist in the database.
52
-     * @throws EE_Error
53
-     * @throws ReflectionException
54
-     */
55
-    public static function generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
56
-    {
57
-        // make sure message_type is an array.
58
-        $message_types = (array) $message_types;
59
-        $templates = array();
60
-
61
-        if (empty($messenger)) {
62
-            throw new EE_Error(esc_html__('We need a messenger to generate templates!', 'event_espresso'));
63
-        }
64
-
65
-        // if we STILL have empty $message_types then we need to generate an error message b/c we NEED message types to do the template files.
66
-        if (empty($message_types)) {
67
-            throw new EE_Error(esc_html__('We need at least one message type to generate templates!', 'event_espresso'));
68
-        }
69
-
70
-        EEH_MSG_Template::_set_autoloader();
71
-        foreach ($message_types as $message_type) {
72
-            // if this is global template generation.
73
-            if ($global) {
74
-                // let's attempt to get the GRP_ID for this combo IF GRP_ID is empty.
75
-                if (empty($GRP_ID)) {
76
-                    $GRP_ID = EEM_Message_Template_Group::instance()->get_one(
77
-                        array(
78
-                            array(
79
-                                'MTP_messenger'    => $messenger,
80
-                                'MTP_message_type' => $message_type,
81
-                                'MTP_is_global'    => true,
82
-                            ),
83
-                        )
84
-                    );
85
-                    $GRP_ID = $GRP_ID instanceof EE_Message_Template_Group ? $GRP_ID->ID() : 0;
86
-                }
87
-                // First let's determine if we already HAVE global templates for this messenger and message_type combination.
88
-                //  If we do then NO generation!!
89
-                if (EEH_MSG_Template::already_generated($messenger, $message_type, $GRP_ID)) {
90
-                    $templates[] = array(
91
-                        'GRP_ID' => $GRP_ID,
92
-                        'MTP_context' => '',
93
-                    );
94
-                    // we already have generated templates for this so let's go to the next message type.
95
-                    continue;
96
-                }
97
-            }
98
-            $new_message_template_group = EEH_MSG_Template::create_new_templates($messenger, $message_type, $GRP_ID, $global);
99
-
100
-            if (! $new_message_template_group) {
101
-                continue;
102
-            }
103
-            $templates[] = $new_message_template_group;
104
-        }
105
-
106
-        return $templates;
107
-    }
108
-
109
-
110
-    /**
111
-     * The purpose of this method is to determine if there are already generated templates in the database for the
112
-     * given variables.
113
-     *
114
-     * @param string $messenger    messenger
115
-     * @param string $message_type message type
116
-     * @param int    $GRP_ID       GRP ID ( if a custom template) (if not provided then we're just doing global
117
-     *                             template check)
118
-     * @return bool                true = generated, false = hasn't been generated.
119
-     * @throws EE_Error
120
-     */
121
-    public static function already_generated($messenger, $message_type, $GRP_ID = 0)
122
-    {
123
-        EEH_MSG_Template::_set_autoloader();
124
-        // what method we use depends on whether we have an GRP_ID or not
125
-        $count = empty($GRP_ID)
126
-            ? EEM_Message_Template::instance()->count(
127
-                array(
128
-                    array(
129
-                        'Message_Template_Group.MTP_messenger'    => $messenger,
130
-                        'Message_Template_Group.MTP_message_type' => $message_type,
131
-                        'Message_Template_Group.MTP_is_global'    => true
132
-                    )
133
-                )
134
-            )
135
-            : EEM_Message_Template::instance()->count(array( array( 'GRP_ID' => $GRP_ID ) ));
136
-
137
-        return $count > 0;
138
-    }
139
-
140
-
141
-    /**
142
-     * Updates all message templates matching the incoming messengers and message types to active status.
143
-     *
144
-     * @static
145
-     * @param array $messenger_names    Messenger slug
146
-     * @param array $message_type_names Message type slug
147
-     * @return  int                         count of updated records.
148
-     * @throws EE_Error
149
-     */
150
-    public static function update_to_active($messenger_names, $message_type_names)
151
-    {
152
-        $messenger_names = is_array($messenger_names) ? $messenger_names : array( $messenger_names );
153
-        $message_type_names = is_array($message_type_names) ? $message_type_names : array( $message_type_names );
154
-        return EEM_Message_Template_Group::instance()->update(
155
-            array( 'MTP_is_active' => 1 ),
156
-            array(
157
-                array(
158
-                    'MTP_messenger'     => array( 'IN', $messenger_names ),
159
-                    'MTP_message_type'  => array( 'IN', $message_type_names )
160
-                )
161
-            )
162
-        );
163
-    }
164
-
165
-
166
-    /**
167
-     * Updates all message template groups matching the incoming arguments to inactive status.
168
-     *
169
-     * @static
170
-     * @param array $messenger_names    The messenger slugs.
171
-     *                                  If empty then all templates matching the message types are marked inactive.
172
-     *                                  Otherwise only templates matching the messengers and message types.
173
-     * @param array $message_type_names The message type slugs.
174
-     *                                  If empty then all templates matching the messengers are marked inactive.
175
-     *                                  Otherwise only templates matching the messengers and message types.
176
-     *
177
-     * @return int  count of updated records.
178
-     * @throws EE_Error
179
-     */
180
-    public static function update_to_inactive($messenger_names = array(), $message_type_names = array())
181
-    {
182
-        return EEM_Message_Template_Group::instance()->deactivate_message_template_groups_for(
183
-            $messenger_names,
184
-            $message_type_names
185
-        );
186
-    }
187
-
188
-
189
-    /**
190
-     * The purpose of this function is to return all installed message objects
191
-     * (messengers and message type regardless of whether they are ACTIVE or not)
192
-     *
193
-     * @param string $type
194
-     * @return array array consisting of installed messenger objects and installed message type objects.
195
-     * @throws EE_Error
196
-     * @throws ReflectionException
197
-     * @deprecated 4.9.0
198
-     * @static
199
-     */
200
-    public static function get_installed_message_objects($type = 'all')
201
-    {
202
-        self::_set_autoloader();
203
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
204
-        return array(
205
-            'messenger' => $message_resource_manager->installed_messengers(),
206
-            'message_type' => $message_resource_manager->installed_message_types()
207
-        );
208
-    }
209
-
210
-
211
-    /**
212
-     * This will return an array of shortcodes => labels from the
213
-     * messenger and message_type objects associated with this
214
-     * template.
215
-     *
216
-     * @param string $message_type
217
-     * @param string $messenger
218
-     * @param array  $fields                        What fields we're returning valid shortcodes for.
219
-     *                                              If empty then we assume all fields are to be returned. Optional.
220
-     * @param string $context                       What context we're going to return shortcodes for. Optional.
221
-     * @param bool   $merged                        If TRUE then we don't return shortcodes indexed by field,
222
-     *                                              but instead an array of the unique shortcodes for all the given (
223
-     *                                              or all) fields. Optional.
224
-     * @return array                                an array of shortcodes in the format
225
-     *                                              array( '[shortcode] => 'label')
226
-     *                                              OR
227
-     *                                              FALSE if no shortcodes found.
228
-     * @throws ReflectionException
229
-     * @throws EE_Error*@since 4.3.0
230
-     *
231
-     */
232
-    public static function get_shortcodes(
233
-        $message_type,
234
-        $messenger,
235
-        $fields = array(),
236
-        $context = 'admin',
237
-        $merged = false
238
-    ) {
239
-        $messenger_name = str_replace(' ', '_', ucwords(str_replace('_', ' ', $messenger)));
240
-        $mt_name = str_replace(' ', '_', ucwords(str_replace('_', ' ', $message_type)));
241
-        /** @var EE_Message_Resource_Manager $message_resource_manager */
242
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
243
-        // convert slug to object
244
-        $messenger = $message_resource_manager->get_messenger($messenger);
245
-
246
-        // if messenger isn't a EE_messenger resource then bail.
247
-        if (! $messenger instanceof EE_messenger) {
248
-            return array();
249
-        }
250
-
251
-        // validate class for getting our list of shortcodes
252
-        $classname = 'EE_Messages_' . $messenger_name . '_' . $mt_name . '_Validator';
253
-        if (! class_exists($classname)) {
254
-            $msg[] = esc_html__('The Validator class was unable to load', 'event_espresso');
255
-            $msg[] = sprintf(
256
-                esc_html__('The class name compiled was %s. Please check and make sure the spelling and case is correct for the class name and that there is an autoloader in place for this class', 'event_espresso'),
257
-                $classname
258
-            );
259
-            throw new EE_Error(implode('||', $msg));
260
-        }
261
-
262
-        /** @type EE_Messages_Validator $_VLD */
263
-        $_VLD = new $classname(array(), $context);
264
-        $valid_shortcodes = $_VLD->get_validators();
265
-
266
-        // let's make sure we're only getting the shortcode part of the validators
267
-        $shortcodes = array();
268
-        foreach ($valid_shortcodes as $field => $validators) {
269
-            $shortcodes[ $field ] = $validators['shortcodes'];
270
-        }
271
-        $valid_shortcodes = $shortcodes;
272
-
273
-        // if not all fields let's make sure we ONLY include the shortcodes for the specified fields.
274
-        if (! empty($fields)) {
275
-            $specified_shortcodes = array();
276
-            foreach ($fields as $field) {
277
-                if (isset($valid_shortcodes[ $field ])) {
278
-                    $specified_shortcodes[ $field ] = $valid_shortcodes[ $field ];
279
-                }
280
-            }
281
-            $valid_shortcodes = $specified_shortcodes;
282
-        }
283
-
284
-        // if not merged then let's replace the fields with the localized fields
285
-        if (! $merged) {
286
-            // let's get all the fields for the set messenger so that we can get the localized label and use that in the returned array.
287
-            $field_settings = $messenger->get_template_fields();
288
-            $localized = array();
289
-            foreach ($valid_shortcodes as $field => $shortcodes) {
290
-                // get localized field label
291
-                if (isset($field_settings[ $field ])) {
292
-                    // possible that this is used as a main field.
293
-                    if (empty($field_settings[ $field ])) {
294
-                        if (isset($field_settings['extra'][ $field ])) {
295
-                            $_field = $field_settings['extra'][ $field ]['main']['label'];
296
-                        } else {
297
-                            $_field = $field;
298
-                        }
299
-                    } else {
300
-                        $_field = $field_settings[ $field ]['label'];
301
-                    }
302
-                } elseif (isset($field_settings['extra'])) {
303
-                    // loop through extra "main fields" and see if any of their children have our field
304
-                    foreach ($field_settings['extra'] as $fields) {
305
-                        if (isset($fields[ $field ])) {
306
-                            $_field = $fields[ $field ]['label'];
307
-                        } else {
308
-                            $_field = $field;
309
-                        }
310
-                    }
311
-                } else {
312
-                    $_field = $field;
313
-                }
314
-                if (isset($_field)) {
315
-                    $localized[ (string) $_field ] = $shortcodes;
316
-                }
317
-            }
318
-            $valid_shortcodes = $localized;
319
-        }
320
-
321
-        // if $merged then let's merge all the shortcodes into one list NOT indexed by field.
322
-        if ($merged) {
323
-            $merged_codes = array();
324
-            foreach ($valid_shortcodes as $shortcode) {
325
-                foreach ($shortcode as $code => $label) {
326
-                    if (isset($merged_codes[ $code ])) {
327
-                        continue;
328
-                    } else {
329
-                        $merged_codes[ $code ] = $label;
330
-                    }
331
-                }
332
-            }
333
-            $valid_shortcodes = $merged_codes;
334
-        }
335
-
336
-        return $valid_shortcodes;
337
-    }
338
-
339
-
340
-    /**
341
-     * Get Messenger object.
342
-     *
343
-     * @param string $messenger messenger slug for the messenger object we want to retrieve.
344
-     * @return EE_messenger
345
-     * @throws ReflectionException
346
-     * @throws EE_Error*@since 4.3.0
347
-     * @deprecated 4.9.0
348
-     */
349
-    public static function messenger_obj($messenger)
350
-    {
351
-        /** @type EE_Message_Resource_Manager $Message_Resource_Manager */
352
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
353
-        return $Message_Resource_Manager->get_messenger($messenger);
354
-    }
355
-
356
-
357
-    /**
358
-     * get Message type object
359
-     *
360
-     * @param string $message_type the slug for the message type object to retrieve
361
-     * @return EE_message_type
362
-     * @throws ReflectionException
363
-     * @throws EE_Error*@since 4.3.0
364
-     * @deprecated 4.9.0
365
-     */
366
-    public static function message_type_obj($message_type)
367
-    {
368
-        /** @type EE_Message_Resource_Manager $Message_Resource_Manager */
369
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
370
-        return $Message_Resource_Manager->get_message_type($message_type);
371
-    }
372
-
373
-
374
-    /**
375
-     * Given a message_type slug, will return whether that message type is active in the system or not.
376
-     *
377
-     * @since    4.3.0
378
-     * @param string $message_type message type to check for.
379
-     * @return boolean
380
-     * @throws EE_Error
381
-     * @throws ReflectionException
382
-     */
383
-    public static function is_mt_active($message_type)
384
-    {
385
-        /** @type EE_Message_Resource_Manager $Message_Resource_Manager */
386
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
387
-        $active_mts = $Message_Resource_Manager->list_of_active_message_types();
388
-        return in_array($message_type, $active_mts);
389
-    }
390
-
391
-
392
-    /**
393
-     * Given a messenger slug, will return whether that messenger is active in the system or not.
394
-     *
395
-     * @since    4.3.0
396
-     *
397
-     * @param string $messenger slug for messenger to check.
398
-     * @return boolean
399
-     * @throws EE_Error
400
-     * @throws ReflectionException
401
-     */
402
-    public static function is_messenger_active($messenger)
403
-    {
404
-        /** @type EE_Message_Resource_Manager $Message_Resource_Manager */
405
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
406
-        $active_messenger = $Message_Resource_Manager->get_active_messenger($messenger);
407
-        return $active_messenger instanceof EE_messenger;
408
-    }
409
-
410
-
411
-    /**
412
-     * Used to return active messengers array stored in the wp options table.
413
-     * If no value is present in the option then an empty array is returned.
414
-     *
415
-     * @deprecated 4.9
416
-     * @since      4.3.1
417
-     *
418
-     * @return array
419
-     * @throws EE_Error
420
-     * @throws ReflectionException
421
-     */
422
-    public static function get_active_messengers_in_db()
423
-    {
424
-        EE_Error::doing_it_wrong(
425
-            __METHOD__,
426
-            esc_html__('Please use EE_Message_Resource_Manager::get_active_messengers_option() instead.', 'event_espresso'),
427
-            '4.9.0'
428
-        );
429
-        /** @var EE_Message_Resource_Manager $Message_Resource_Manager */
430
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
431
-        return $Message_Resource_Manager->get_active_messengers_option();
432
-    }
433
-
434
-
435
-    /**
436
-     * Used to update the active messengers array stored in the wp options table.
437
-     *
438
-     * @since      4.3.1
439
-     * @deprecated 4.9.0
440
-     *
441
-     * @param array $data_to_save Incoming data to save.
442
-     *
443
-     * @return bool FALSE if not updated, TRUE if updated.
444
-     * @throws EE_Error
445
-     * @throws ReflectionException
446
-     */
447
-    public static function update_active_messengers_in_db($data_to_save)
448
-    {
449
-        EE_Error::doing_it_wrong(
450
-            __METHOD__,
451
-            esc_html__('Please use EE_Message_Resource_Manager::update_active_messengers_option() instead.', 'event_espresso'),
452
-            '4.9.0'
453
-        );
454
-        /** @var EE_Message_Resource_Manager $Message_Resource_Manager */
455
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
456
-        return $Message_Resource_Manager->update_active_messengers_option($data_to_save);
457
-    }
458
-
459
-
460
-    /**
461
-     * This does some validation of incoming params, determines what type of url is being prepped and returns the
462
-     * appropriate url trigger
463
-     *
464
-     * @param EE_message_type $message_type
465
-     * @param EE_Message $message
466
-     * @param EE_Registration | null $registration  The registration object must be included if this
467
-     *                                              is going to be a registration trigger url.
468
-     * @param string $sending_messenger             The (optional) sending messenger for the url.
469
-     *
470
-     * @return string
471
-     * @throws EE_Error
472
-     */
473
-    public static function get_url_trigger(
474
-        EE_message_type $message_type,
475
-        EE_Message $message,
476
-        $registration = null,
477
-        $sending_messenger = ''
478
-    ) {
479
-        // first determine if the url can be to the EE_Message object.
480
-        if (! $message_type->always_generate()) {
481
-            return EEH_MSG_Template::generate_browser_trigger($message);
482
-        }
483
-
484
-        // if $registration object is not valid then exit early because there's nothing that can be generated.
485
-        if (! $registration instanceof EE_Registration) {
486
-            throw new EE_Error(
487
-                esc_html__('Incoming value for registration is not a valid EE_Registration object.', 'event_espresso')
488
-            );
489
-        }
490
-
491
-        // validate given context
492
-        $contexts = $message_type->get_contexts();
493
-        if ($message->context() !== '' && ! isset($contexts[ $message->context() ])) {
494
-            throw new EE_Error(
495
-                sprintf(
496
-                    esc_html__('The context %s is not a valid context for %s.', 'event_espresso'),
497
-                    $message->context(),
498
-                    get_class($message_type)
499
-                )
500
-            );
501
-        }
502
-
503
-        // valid sending messenger but only if sending messenger set.  Otherwise generating messenger is used.
504
-        if (! empty($sending_messenger)) {
505
-            $with_messengers = $message_type->with_messengers();
506
-            if (
507
-                ! isset($with_messengers[ $message->messenger() ])
508
-                 || ! in_array($sending_messenger, $with_messengers[ $message->messenger() ])
509
-            ) {
510
-                throw new EE_Error(
511
-                    sprintf(
512
-                        esc_html__(
513
-                            'The given sending messenger string (%1$s) does not match a valid sending messenger with the %2$s.  If this is incorrect, make sure that the message type has defined this messenger as a sending messenger in its $_with_messengers array.',
514
-                            'event_espresso'
515
-                        ),
516
-                        $sending_messenger,
517
-                        get_class($message_type)
518
-                    )
519
-                );
520
-            }
521
-        } else {
522
-            $sending_messenger = $message->messenger();
523
-        }
524
-        return EEH_MSG_Template::generate_url_trigger(
525
-            $sending_messenger,
526
-            $message->messenger(),
527
-            $message->context(),
528
-            $message->message_type(),
529
-            $registration,
530
-            $message->GRP_ID()
531
-        );
532
-    }
533
-
534
-
535
-    /**
536
-     * This returns the url for triggering a in browser view of a specific EE_Message object.
537
-     * @param EE_Message $message
538
-     * @return string.
539
-     */
540
-    public static function generate_browser_trigger(EE_Message $message)
541
-    {
542
-        $query_args = array(
543
-            'ee' => 'msg_browser_trigger',
544
-            'token' => $message->MSG_token()
545
-        );
546
-        return apply_filters(
547
-            'FHEE__EEH_MSG_Template__generate_browser_trigger',
548
-            add_query_arg($query_args, site_url()),
549
-            $message
550
-        );
551
-    }
552
-
553
-
554
-
555
-
556
-
557
-
558
-    /**
559
-     * This returns the url for triggering an in browser view of the error saved on the incoming message object.
560
-     * @param EE_Message $message
561
-     * @return string
562
-     */
563
-    public static function generate_error_display_trigger(EE_Message $message)
564
-    {
565
-        return apply_filters(
566
-            'FHEE__EEH_MSG_Template__generate_error_display_trigger',
567
-            add_query_arg(
568
-                array(
569
-                    'ee' => 'msg_browser_error_trigger',
570
-                    'token' => $message->MSG_token()
571
-                ),
572
-                site_url()
573
-            ),
574
-            $message
575
-        );
576
-    }
577
-
578
-
579
-    /**
580
-     * This generates a url trigger for the msg_url_trigger route using the given arguments
581
-     *
582
-     * @param string          $sending_messenger      The sending messenger slug.
583
-     * @param string          $generating_messenger   The generating messenger slug.
584
-     * @param string          $context                The context for the template.
585
-     * @param string          $message_type           The message type slug
586
-     * @param EE_Registration $registration
587
-     * @param integer         $message_template_group id   The EE_Message_Template_Group ID for the template.
588
-     * @param integer         $data_id                The id to the EE_Base_Class for getting the data used by the
589
-     *                                                trigger.
590
-     * @return string          The generated url.
591
-     * @throws EE_Error
592
-     */
593
-    public static function generate_url_trigger(
594
-        $sending_messenger,
595
-        $generating_messenger,
596
-        $context,
597
-        $message_type,
598
-        EE_Registration $registration,
599
-        $message_template_group,
600
-        $data_id = 0
601
-    ) {
602
-        $query_args = array(
603
-            'ee' => 'msg_url_trigger',
604
-            'snd_msgr' => $sending_messenger,
605
-            'gen_msgr' => $generating_messenger,
606
-            'message_type' => $message_type,
607
-            'context' => $context,
608
-            'token' => $registration->reg_url_link(),
609
-            'GRP_ID' => $message_template_group,
610
-            'id' => $data_id
611
-            );
612
-        $url = add_query_arg($query_args, get_home_url());
613
-
614
-        // made it here so now we can just get the url and filter it.  Filtered globally and by message type.
615
-        return apply_filters(
616
-            'FHEE__EEH_MSG_Template__generate_url_trigger',
617
-            $url,
618
-            $sending_messenger,
619
-            $generating_messenger,
620
-            $context,
621
-            $message_type,
622
-            $registration,
623
-            $message_template_group,
624
-            $data_id
625
-        );
626
-    }
627
-
628
-
629
-
630
-
631
-    /**
632
-     * Return the specific css for the action icon given.
633
-     *
634
-     * @param string $type  What action to return.
635
-     * @return string[]
636
-     * @since 4.9.0
637
-     */
638
-    public static function get_message_action_icon($type)
639
-    {
640
-        $action_icons = self::get_message_action_icons();
641
-        return isset($action_icons[ $type ]) ? $action_icons[ $type ] : [];
642
-    }
643
-
644
-
645
-    /**
646
-     * This is used for retrieving the css classes used for the icons representing message actions.
647
-     *
648
-     * @since 4.9.0
649
-     *
650
-     * @return array
651
-     */
652
-    public static function get_message_action_icons()
653
-    {
654
-        return apply_filters(
655
-            'FHEE__EEH_MSG_Template__message_action_icons',
656
-            array(
657
-                'view' => array(
658
-                    'label' => esc_html__('View Message', 'event_espresso'),
659
-                    'css_class' => 'dashicons dashicons-welcome-view-site',
660
-                ),
661
-                'error' => array(
662
-                    'label' => esc_html__('View Error Message', 'event_espresso'),
663
-                    'css_class' => 'dashicons dashicons-info',
664
-                ),
665
-                'see_notifications_for' => array(
666
-                    'label' => esc_html__('View Related Messages', 'event_espresso'),
667
-                    'css_class' => 'dashicons dashicons-megaphone',
668
-                ),
669
-                'generate_now' => array(
670
-                    'label' => esc_html__('Generate the message now.', 'event_espresso'),
671
-                    'css_class' => 'dashicons dashicons-admin-tools',
672
-                ),
673
-                'send_now' => array(
674
-                    'label' => esc_html__('Send Immediately', 'event_espresso'),
675
-                    'css_class' => 'dashicons dashicons-controls-forward',
676
-                ),
677
-                'queue_for_resending' => array(
678
-                    'label' => esc_html__('Queue for Resending', 'event_espresso'),
679
-                    'css_class' => 'dashicons dashicons-controls-repeat',
680
-                ),
681
-                'view_transaction' => array(
682
-                    'label' => esc_html__('View related Transaction', 'event_espresso'),
683
-                    'css_class' => 'dashicons dashicons-cart',
684
-                )
685
-            )
686
-        );
687
-    }
688
-
689
-
690
-    /**
691
-     * This returns the url for a given action related to EE_Message.
692
-     *
693
-     * @param string     $type         What type of action to return the url for.
694
-     * @param EE_Message $message      Required for generating the correct url for some types.
695
-     * @param array      $query_params Any additional query params to be included with the generated url.
696
-     *
697
-     * @return string
698
-     * @throws EE_Error
699
-     * @throws ReflectionException
700
-     * @since 4.9.0
701
-     *
702
-     */
703
-    public static function get_message_action_url($type, EE_Message $message = null, $query_params = array())
704
-    {
705
-        $action_urls = self::get_message_action_urls($message, $query_params);
706
-        return isset($action_urls[ $type ])  ? $action_urls[ $type ] : '';
707
-    }
708
-
709
-
710
-    /**
711
-     * This returns all the current urls for EE_Message actions.
712
-     *
713
-     * @since 4.9.0
714
-     *
715
-     * @param EE_Message $message      The EE_Message object required to generate correct urls for some types.
716
-     * @param array      $query_params Any additional query_params to be included with the generated url.
717
-     *
718
-     * @return array
719
-     * @throws EE_Error
720
-     * @throws ReflectionException
721
-     */
722
-    public static function get_message_action_urls(EE_Message $message = null, $query_params = array())
723
-    {
724
-        EE_Registry::instance()->load_helper('URL');
725
-        // if $message is not an instance of EE_Message then let's just do a dummy.
726
-        $message = empty($message) ? EE_Message_Factory::create() : $message;
727
-        $action_urls =  apply_filters(
728
-            'FHEE__EEH_MSG_Template__get_message_action_url',
729
-            array(
730
-                'view' => EEH_MSG_Template::generate_browser_trigger($message),
731
-                'error' => EEH_MSG_Template::generate_error_display_trigger($message),
732
-                'see_notifications_for' => EEH_URL::add_query_args_and_nonce(
733
-                    array_merge(
734
-                        array(
735
-                            'page' => 'espresso_messages',
736
-                            'action' => 'default',
737
-                            'filterby' => 1,
738
-                        ),
739
-                        $query_params
740
-                    ),
741
-                    admin_url('admin.php')
742
-                ),
743
-                'generate_now' => EEH_URL::add_query_args_and_nonce(
744
-                    array(
745
-                        'page' => 'espresso_messages',
746
-                        'action' => 'generate_now',
747
-                        'MSG_ID' => $message->ID()
748
-                    ),
749
-                    admin_url('admin.php')
750
-                ),
751
-                'send_now' => EEH_URL::add_query_args_and_nonce(
752
-                    array(
753
-                        'page' => 'espresso_messages',
754
-                        'action' => 'send_now',
755
-                        'MSG_ID' => $message->ID()
756
-                    ),
757
-                    admin_url('admin.php')
758
-                ),
759
-                'queue_for_resending' => EEH_URL::add_query_args_and_nonce(
760
-                    array(
761
-                        'page' => 'espresso_messages',
762
-                        'action' => 'queue_for_resending',
763
-                        'MSG_ID' => $message->ID()
764
-                    ),
765
-                    admin_url('admin.php')
766
-                ),
767
-            )
768
-        );
769
-        if (
770
-            $message->TXN_ID() > 0
771
-            && EE_Registry::instance()->CAP->current_user_can(
772
-                'ee_read_transaction',
773
-                'espresso_transactions_default',
774
-                $message->TXN_ID()
775
-            )
776
-        ) {
777
-            $action_urls['view_transaction'] = EEH_URL::add_query_args_and_nonce(
778
-                array(
779
-                    'page' => 'espresso_transactions',
780
-                    'action' => 'view_transaction',
781
-                    'TXN_ID' => $message->TXN_ID()
782
-                ),
783
-                admin_url('admin.php')
784
-            );
785
-        } else {
786
-            $action_urls['view_transaction'] = '';
787
-        }
788
-        return $action_urls;
789
-    }
790
-
791
-
792
-    /**
793
-     * This returns a generated link html including the icon used for the action link for EE_Message actions.
794
-     *
795
-     * @param string          $type         What type of action the link is for (if invalid type is passed in then an
796
-     *                                      empty string is returned)
797
-     * @param EE_Message|null $message      The EE_Message object (required for some actions to generate correctly)
798
-     * @param array           $query_params Any extra query params to include in the generated link.
799
-     *
800
-     * @return string
801
-     * @throws EE_Error
802
-     * @throws ReflectionException
803
-     * @since 4.9.0
804
-     *
805
-     */
806
-    public static function get_message_action_link($type, EE_Message $message = null, $query_params = array())
807
-    {
808
-        $url = EEH_MSG_Template::get_message_action_url($type, $message, $query_params);
809
-        $icon_css = EEH_MSG_Template::get_message_action_icon($type);
810
-        $title = isset($icon_css['label']) ? 'title="' . $icon_css['label'] . '"' : '';
811
-
812
-        if (empty($url) || empty($icon_css) || ! isset($icon_css['css_class'])) {
813
-            return '';
814
-        }
815
-
816
-        $icon_css['css_class'] .= esc_attr(
817
-            apply_filters(
818
-                'FHEE__EEH_MSG_Template__get_message_action_link__icon_css_class',
819
-                ' js-ee-message-action-link ee-message-action-link-' . $type,
820
-                $type,
821
-                $message,
822
-                $query_params
823
-            )
824
-        );
825
-
826
-        return '<a href="' . $url . '" ' . $title . '><span class="' . esc_attr($icon_css['css_class']) . '"></span></a>';
827
-    }
828
-
829
-
830
-
831
-
832
-
833
-    /**
834
-     * This returns an array with keys as reg statuses and values as the corresponding message type slug (filtered).
835
-     *
836
-     * @since 4.9.0
837
-     * @return array
838
-     */
839
-    public static function reg_status_to_message_type_array()
840
-    {
841
-        return (array) apply_filters(
842
-            'FHEE__EEH_MSG_Template__reg_status_to_message_type_array',
843
-            array(
844
-                EEM_Registration::status_id_approved => 'registration',
845
-                EEM_Registration::status_id_pending_payment => 'pending_approval',
846
-                EEM_Registration::status_id_not_approved => 'not_approved_registration',
847
-                EEM_Registration::status_id_cancelled => 'cancelled_registration',
848
-                EEM_Registration::status_id_declined => 'declined_registration'
849
-            )
850
-        );
851
-    }
852
-
853
-
854
-
855
-
856
-    /**
857
-     * This returns the corresponding registration message type slug to the given reg status. If there isn't a
858
-     * match, then returns an empty string.
859
-     *
860
-     * @since 4.9.0
861
-     * @param $reg_status
862
-     * @return string
863
-     */
864
-    public static function convert_reg_status_to_message_type($reg_status)
865
-    {
866
-        $reg_status_array = self::reg_status_to_message_type_array();
867
-        return isset($reg_status_array[ $reg_status ]) ? $reg_status_array[ $reg_status ] : '';
868
-    }
869
-
870
-
871
-    /**
872
-     * This returns an array with keys as payment stati and values as the corresponding message type slug (filtered).
873
-     *
874
-     * @since 4.9.0
875
-     * @return array
876
-     */
877
-    public static function payment_status_to_message_type_array()
878
-    {
879
-        return (array) apply_filters(
880
-            'FHEE__EEH_MSG_Template__payment_status_to_message_type_array',
881
-            array(
882
-                EEM_Payment::status_id_approved => 'payment',
883
-                EEM_Payment::status_id_pending => 'payment_pending',
884
-                EEM_Payment::status_id_cancelled => 'payment_cancelled',
885
-                EEM_Payment::status_id_declined => 'payment_declined',
886
-                EEM_Payment::status_id_failed => 'payment_failed'
887
-            )
888
-        );
889
-    }
890
-
891
-
892
-
893
-
894
-    /**
895
-     * This returns the corresponding payment message type slug to the given payment status. If there isn't a match then
896
-     * an empty string is returned
897
-     *
898
-     * @since 4.9.0
899
-     * @param $payment_status
900
-     * @return string
901
-     */
902
-    public static function convert_payment_status_to_message_type($payment_status)
903
-    {
904
-        $payment_status_array = self::payment_status_to_message_type_array();
905
-        return isset($payment_status_array[ $payment_status ]) ? $payment_status_array[ $payment_status ] : '';
906
-    }
907
-
908
-
909
-    /**
910
-     * This is used to retrieve the template pack for the given name.
911
-     *
912
-     * @param string $template_pack_name  should match the set `dbref` property value on the EE_Messages_Template_Pack.
913
-     *
914
-     * @return EE_Messages_Template_Pack
915
-     */
916
-    public static function get_template_pack($template_pack_name)
917
-    {
918
-        if (! self::$_template_pack_collection instanceof EE_Object_Collection) {
919
-            self::$_template_pack_collection = new EE_Messages_Template_Pack_Collection();
920
-        }
921
-
922
-        // first see if in collection already
923
-        $template_pack = self::$_template_pack_collection->get_by_name($template_pack_name);
924
-
925
-        if ($template_pack instanceof EE_Messages_Template_Pack) {
926
-            return $template_pack;
927
-        }
928
-
929
-        // nope...let's get it.
930
-        // not set yet so let's attempt to get it.
931
-        $pack_class_name = 'EE_Messages_Template_Pack_' . str_replace(
932
-            ' ',
933
-            '_',
934
-            ucwords(
935
-                str_replace('_', ' ', $template_pack_name)
936
-            )
937
-        );
938
-        if (! class_exists($pack_class_name) && $template_pack_name !== 'default') {
939
-            return self::get_template_pack('default');
940
-        } else {
941
-            $template_pack = new $pack_class_name();
942
-            self::$_template_pack_collection->add($template_pack);
943
-            return $template_pack;
944
-        }
945
-    }
946
-
947
-
948
-
949
-
950
-    /**
951
-     * Globs template packs installed in core and returns the template pack collection with all installed template packs
952
-     * in it.
953
-     *
954
-     * @since 4.9.0
955
-     *
956
-     * @return EE_Messages_Template_Pack_Collection
957
-     */
958
-    public static function get_template_pack_collection()
959
-    {
960
-        $new_collection = false;
961
-        if (! self::$_template_pack_collection instanceof EE_Messages_Template_Pack_Collection) {
962
-            self::$_template_pack_collection = new EE_Messages_Template_Pack_Collection();
963
-            $new_collection = true;
964
-        }
965
-
966
-        // glob the defaults directory for messages
967
-        $templates = glob(EE_LIBRARIES . 'messages/defaults/*', GLOB_ONLYDIR);
968
-        foreach ($templates as $template_path) {
969
-            // grab folder name
970
-            $template = basename($template_path);
971
-
972
-            if (! $new_collection) {
973
-                // already have it?
974
-                if (self::$_template_pack_collection->get_by_name($template) instanceof EE_Messages_Template_Pack) {
975
-                    continue;
976
-                }
977
-            }
978
-
979
-            // setup classname.
980
-            $template_pack_class_name = 'EE_Messages_Template_Pack_' . str_replace(
981
-                ' ',
982
-                '_',
983
-                ucwords(
984
-                    str_replace(
985
-                        '_',
986
-                        ' ',
987
-                        $template
988
-                    )
989
-                )
990
-            );
991
-            if (! class_exists($template_pack_class_name)) {
992
-                continue;
993
-            }
994
-            self::$_template_pack_collection->add(new $template_pack_class_name());
995
-        }
996
-
997
-        /**
998
-         * Filter for plugins to add in any additional template packs
999
-         * Note the filter name here is for backward compat, this used to be found in EED_Messages.
1000
-         */
1001
-        $additional_template_packs = apply_filters('FHEE__EED_Messages__get_template_packs__template_packs', array());
1002
-        foreach ((array) $additional_template_packs as $template_pack) {
1003
-            if (
1004
-                self::$_template_pack_collection->get_by_name(
1005
-                    $template_pack->dbref
1006
-                ) instanceof EE_Messages_Template_Pack
1007
-            ) {
1008
-                continue;
1009
-            }
1010
-            self::$_template_pack_collection->add($template_pack);
1011
-        }
1012
-        return self::$_template_pack_collection;
1013
-    }
1014
-
1015
-
1016
-    /**
1017
-     * This is a wrapper for the protected _create_new_templates function
1018
-     *
1019
-     * @param string $messenger_name
1020
-     * @param string $message_type_name message type that the templates are being created for
1021
-     * @param int    $GRP_ID
1022
-     * @param bool   $global
1023
-     * @return array
1024
-     * @throws EE_Error
1025
-     * @throws ReflectionException
1026
-     */
1027
-    public static function create_new_templates($messenger_name, $message_type_name, $GRP_ID = 0, $global = false)
1028
-    {
1029
-        /** @type EE_Message_Resource_Manager $Message_Resource_Manager */
1030
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1031
-        $messenger = $Message_Resource_Manager->valid_messenger($messenger_name);
1032
-        $message_type = $Message_Resource_Manager->valid_message_type($message_type_name);
1033
-        if (! EEH_MSG_Template::message_type_has_active_templates_for_messenger($messenger, $message_type, $global)) {
1034
-            return array();
1035
-        }
1036
-        // whew made it this far!  Okay, let's go ahead and create the templates then
1037
-        return EEH_MSG_Template::_create_new_templates($messenger, $message_type, $GRP_ID, $global);
1038
-    }
1039
-
1040
-
1041
-    /**
1042
-     * @param EE_messenger     $messenger
1043
-     * @param EE_message_type  $message_type
1044
-     * @param                  $GRP_ID
1045
-     * @param                  $global
1046
-     * @return array|mixed
1047
-     * @throws EE_Error
1048
-     * @throws ReflectionException
1049
-     */
1050
-    protected static function _create_new_templates(EE_messenger $messenger, EE_message_type $message_type, $GRP_ID, $global)
1051
-    {
1052
-        // if we're creating a custom template then we don't need to use the defaults class
1053
-        if (! $global) {
1054
-            return EEH_MSG_Template::_create_custom_template_group($messenger, $message_type, $GRP_ID);
1055
-        }
1056
-        /** @type EE_Messages_Template_Defaults $Message_Template_Defaults */
1057
-        $Message_Template_Defaults = EE_Registry::factory(
1058
-            'EE_Messages_Template_Defaults',
1059
-            array( $messenger, $message_type, $GRP_ID )
1060
-        );
1061
-        // generate templates
1062
-        $success = $Message_Template_Defaults->create_new_templates();
1063
-
1064
-        // if creating the template failed.  Then we should deactivate the related message_type for the messenger because
1065
-        // its not active if it doesn't have a template.  Note this is only happening for GLOBAL template creation
1066
-        // attempts.
1067
-        if (! $success) {
1068
-            /** @var EE_Message_Resource_Manager $message_resource_manager */
1069
-            $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1070
-            $message_resource_manager->deactivate_message_type_for_messenger($message_type->name, $messenger->name);
1071
-        }
1072
-
1073
-        /**
1074
-         * $success is in an array in the following format
1075
-         * array(
1076
-         *    'GRP_ID' => $new_grp_id,
1077
-         *    'MTP_context' => $first_context_in_new_templates,
1078
-         * )
1079
-         */
1080
-        return $success;
1081
-    }
1082
-
1083
-
1084
-    /**
1085
-     * This creates a custom template using the incoming GRP_ID
1086
-     *
1087
-     * @param EE_messenger    $messenger
1088
-     * @param EE_message_type $message_type
1089
-     * @param int             $GRP_ID           GRP_ID for the template_group being used as the base
1090
-     * @return  array $success              This will be an array in the format:
1091
-     *                                          array(
1092
-     *                                          'GRP_ID' => $new_grp_id,
1093
-     *                                          'MTP_context' => $first_context_in_created_template
1094
-     *                                          )
1095
-     * @throws EE_Error
1096
-     * @throws ReflectionException
1097
-     * @access private
1098
-     */
1099
-    private static function _create_custom_template_group(EE_messenger $messenger, EE_message_type $message_type, $GRP_ID)
1100
-    {
1101
-        // defaults
1102
-        $success = array( 'GRP_ID' => null, 'MTP_context' => '' );
1103
-        // get the template group to use as a template from the db.  If $GRP_ID is empty then we'll assume the base will be the global template matching the messenger and message type.
1104
-        $Message_Template_Group = empty($GRP_ID)
1105
-            ? EEM_Message_Template_Group::instance()->get_one(
1106
-                array(
1107
-                    array(
1108
-                        'MTP_messenger'    => $messenger->name,
1109
-                        'MTP_message_type' => $message_type->name,
1110
-                        'MTP_is_global'    => true
1111
-                    )
1112
-                )
1113
-            )
1114
-            : EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1115
-        // if we don't have a mtg at this point then we need to bail.
1116
-        if (! $Message_Template_Group instanceof EE_Message_Template_Group) {
1117
-            EE_Error::add_error(
1118
-                sprintf(
1119
-                    esc_html__(
1120
-                        'Something went wrong with generating the custom template from this group id: %s.  This usually happens when there is no matching message template group in the db.',
1121
-                        'event_espresso'
1122
-                    ),
1123
-                    $GRP_ID
1124
-                ),
1125
-                __FILE__,
1126
-                __FUNCTION__,
1127
-                __LINE__
1128
-            );
1129
-            return $success;
1130
-        }
1131
-        // let's get all the related message_template objects for this group.
1132
-        $message_templates = $Message_Template_Group->message_templates();
1133
-        // now we have what we need to setup the new template
1134
-        $new_mtg = clone $Message_Template_Group;
1135
-        $new_mtg->set('GRP_ID', 0);
1136
-        $new_mtg->set('MTP_is_global', false);
1137
-
1138
-        /** @var RequestInterface $request */
1139
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
1140
-        $template_name = $request->isAjax() && $request->requestParamIsSet('templateName')
1141
-            ? $request->getRequestParam('templateName')
1142
-            : esc_html__('New Custom Template', 'event_espresso');
1143
-        $template_description = $request->isAjax() && $request->requestParamIsSet('templateDescription')
1144
-            ? $request->getRequestParam('templateDescription')
1145
-            : sprintf(
1146
-                esc_html__(
1147
-                    'This is a custom template that was created for the %s messenger and %s message type.',
1148
-                    'event_espresso'
1149
-                ),
1150
-                $new_mtg->messenger_obj()->label['singular'],
1151
-                $new_mtg->message_type_obj()->label['singular']
1152
-            );
1153
-        $new_mtg->set('MTP_name', $template_name);
1154
-        $new_mtg->set('MTP_description', $template_description);
1155
-        // remove ALL relations on this template group so they don't get saved!
1156
-        $new_mtg->_remove_relations('Message_Template');
1157
-        $new_mtg->save();
1158
-        $success['GRP_ID'] = $new_mtg->ID();
1159
-        $success['template_name'] = $template_name;
1160
-        // add new message templates and add relation to.
1161
-        foreach ($message_templates as $message_template) {
1162
-            if (! $message_template instanceof EE_Message_Template) {
1163
-                continue;
1164
-            }
1165
-            $new_message_template = clone $message_template;
1166
-            $new_message_template->set('MTP_ID', 0);
1167
-            $new_message_template->set('GRP_ID', $new_mtg->ID()); // relation
1168
-            $new_message_template->save();
1169
-            if (empty($success['MTP_context'])) {
1170
-                $success['MTP_context'] = $new_message_template->get('MTP_context');
1171
-            }
1172
-        }
1173
-        return $success;
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * message_type_has_active_templates_for_messenger
1179
-     *
1180
-     * @param EE_messenger    $messenger
1181
-     * @param EE_message_type $message_type
1182
-     * @param bool            $global
1183
-     * @return bool
1184
-     * @throws EE_Error
1185
-     */
1186
-    public static function message_type_has_active_templates_for_messenger(
1187
-        EE_messenger $messenger,
1188
-        EE_message_type $message_type,
1189
-        $global = false
1190
-    ) {
1191
-        // is given message_type valid for given messenger (if this is not a global save)
1192
-        if ($global) {
1193
-            return true;
1194
-        }
1195
-        $active_templates = EEM_Message_Template_Group::instance()->count(
1196
-            array(
1197
-                array(
1198
-                    'MTP_is_active'    => true,
1199
-                    'MTP_messenger'    => $messenger->name,
1200
-                    'MTP_message_type' => $message_type->name
1201
-                )
1202
-            )
1203
-        );
1204
-        if ($active_templates > 0) {
1205
-            return true;
1206
-        }
1207
-        EE_Error::add_error(
1208
-            sprintf(
1209
-                esc_html__(
1210
-                    'The %1$s message type is not registered with the %2$s messenger. Please visit the Messenger activation page to assign this message type first if you want to use it.',
1211
-                    'event_espresso'
1212
-                ),
1213
-                $message_type->name,
1214
-                $messenger->name
1215
-            ),
1216
-            __FILE__,
1217
-            __FUNCTION__,
1218
-            __LINE__
1219
-        );
1220
-        return false;
1221
-    }
1222
-
1223
-
1224
-    /**
1225
-     * get_fields
1226
-     * This takes a given messenger and message type and returns all the template fields indexed by context (and with field type).
1227
-     *
1228
-     * @param string $messenger_name    name of EE_messenger
1229
-     * @param string $message_type_name name of EE_message_type
1230
-     * @return array
1231
-     * @throws EE_Error
1232
-     * @throws ReflectionException
1233
-     */
1234
-    public static function get_fields($messenger_name, $message_type_name)
1235
-    {
1236
-        $template_fields = array();
1237
-        /** @type EE_Message_Resource_Manager $Message_Resource_Manager */
1238
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1239
-        $messenger = $Message_Resource_Manager->valid_messenger($messenger_name);
1240
-        $message_type = $Message_Resource_Manager->valid_message_type($message_type_name);
1241
-        if (! EEH_MSG_Template::message_type_has_active_templates_for_messenger($messenger, $message_type)) {
1242
-            return array();
1243
-        }
1244
-
1245
-        $excluded_fields_for_messenger = $message_type->excludedFieldsForMessenger($messenger_name);
1246
-
1247
-        // okay now let's assemble an array with the messenger template fields added to the message_type contexts.
1248
-        foreach ($message_type->get_contexts() as $context => $details) {
1249
-            foreach ($messenger->get_template_fields() as $field => $value) {
1250
-                if (in_array($field, $excluded_fields_for_messenger, true)) {
1251
-                    continue;
1252
-                }
1253
-                $template_fields[ $context ][ $field ] = $value;
1254
-            }
1255
-        }
1256
-        if (empty($template_fields)) {
1257
-            EE_Error::add_error(
1258
-                esc_html__('Something went wrong and we couldn\'t get any templates assembled', 'event_espresso'),
1259
-                __FILE__,
1260
-                __FUNCTION__,
1261
-                __LINE__
1262
-            );
1263
-            return array();
1264
-        }
1265
-        return $template_fields;
1266
-    }
18
+	/**
19
+	 * Holds a collection of EE_Message_Template_Pack objects.
20
+	 * @type EE_Messages_Template_Pack_Collection
21
+	 */
22
+	protected static $_template_pack_collection;
23
+
24
+
25
+	/**
26
+	 * @throws EE_Error
27
+	 */
28
+	private static function _set_autoloader()
29
+	{
30
+		EED_Messages::set_autoloaders();
31
+	}
32
+
33
+
34
+	/**
35
+	 * generate_new_templates
36
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
37
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
38
+	 * for the event.
39
+	 *
40
+	 * @access protected
41
+	 * @param string $messenger     the messenger we are generating templates for
42
+	 * @param array  $message_types array of message types that the templates are generated for.
43
+	 * @param int    $GRP_ID        If a non global template is being generated then it is expected we'll have a GRP_ID
44
+	 *                              to use as the base for the new generated template.
45
+	 * @param bool   $global        true indicates generating templates on messenger activation. false requires GRP_ID
46
+	 *                              for event specific template generation.
47
+	 * @return array  @see EEH_MSG_Template::_create_new_templates for the return value of each element in the array
48
+	 *                for templates that are generated.  If this is an empty array then it means no templates were
49
+	 *                generated which usually means there was an error.  Anything in the array with an empty value for
50
+	 *                `MTP_context` means that it was not a new generated template but just reactivated (which only
51
+	 *                happens for global templates that already exist in the database.
52
+	 * @throws EE_Error
53
+	 * @throws ReflectionException
54
+	 */
55
+	public static function generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
56
+	{
57
+		// make sure message_type is an array.
58
+		$message_types = (array) $message_types;
59
+		$templates = array();
60
+
61
+		if (empty($messenger)) {
62
+			throw new EE_Error(esc_html__('We need a messenger to generate templates!', 'event_espresso'));
63
+		}
64
+
65
+		// if we STILL have empty $message_types then we need to generate an error message b/c we NEED message types to do the template files.
66
+		if (empty($message_types)) {
67
+			throw new EE_Error(esc_html__('We need at least one message type to generate templates!', 'event_espresso'));
68
+		}
69
+
70
+		EEH_MSG_Template::_set_autoloader();
71
+		foreach ($message_types as $message_type) {
72
+			// if this is global template generation.
73
+			if ($global) {
74
+				// let's attempt to get the GRP_ID for this combo IF GRP_ID is empty.
75
+				if (empty($GRP_ID)) {
76
+					$GRP_ID = EEM_Message_Template_Group::instance()->get_one(
77
+						array(
78
+							array(
79
+								'MTP_messenger'    => $messenger,
80
+								'MTP_message_type' => $message_type,
81
+								'MTP_is_global'    => true,
82
+							),
83
+						)
84
+					);
85
+					$GRP_ID = $GRP_ID instanceof EE_Message_Template_Group ? $GRP_ID->ID() : 0;
86
+				}
87
+				// First let's determine if we already HAVE global templates for this messenger and message_type combination.
88
+				//  If we do then NO generation!!
89
+				if (EEH_MSG_Template::already_generated($messenger, $message_type, $GRP_ID)) {
90
+					$templates[] = array(
91
+						'GRP_ID' => $GRP_ID,
92
+						'MTP_context' => '',
93
+					);
94
+					// we already have generated templates for this so let's go to the next message type.
95
+					continue;
96
+				}
97
+			}
98
+			$new_message_template_group = EEH_MSG_Template::create_new_templates($messenger, $message_type, $GRP_ID, $global);
99
+
100
+			if (! $new_message_template_group) {
101
+				continue;
102
+			}
103
+			$templates[] = $new_message_template_group;
104
+		}
105
+
106
+		return $templates;
107
+	}
108
+
109
+
110
+	/**
111
+	 * The purpose of this method is to determine if there are already generated templates in the database for the
112
+	 * given variables.
113
+	 *
114
+	 * @param string $messenger    messenger
115
+	 * @param string $message_type message type
116
+	 * @param int    $GRP_ID       GRP ID ( if a custom template) (if not provided then we're just doing global
117
+	 *                             template check)
118
+	 * @return bool                true = generated, false = hasn't been generated.
119
+	 * @throws EE_Error
120
+	 */
121
+	public static function already_generated($messenger, $message_type, $GRP_ID = 0)
122
+	{
123
+		EEH_MSG_Template::_set_autoloader();
124
+		// what method we use depends on whether we have an GRP_ID or not
125
+		$count = empty($GRP_ID)
126
+			? EEM_Message_Template::instance()->count(
127
+				array(
128
+					array(
129
+						'Message_Template_Group.MTP_messenger'    => $messenger,
130
+						'Message_Template_Group.MTP_message_type' => $message_type,
131
+						'Message_Template_Group.MTP_is_global'    => true
132
+					)
133
+				)
134
+			)
135
+			: EEM_Message_Template::instance()->count(array( array( 'GRP_ID' => $GRP_ID ) ));
136
+
137
+		return $count > 0;
138
+	}
139
+
140
+
141
+	/**
142
+	 * Updates all message templates matching the incoming messengers and message types to active status.
143
+	 *
144
+	 * @static
145
+	 * @param array $messenger_names    Messenger slug
146
+	 * @param array $message_type_names Message type slug
147
+	 * @return  int                         count of updated records.
148
+	 * @throws EE_Error
149
+	 */
150
+	public static function update_to_active($messenger_names, $message_type_names)
151
+	{
152
+		$messenger_names = is_array($messenger_names) ? $messenger_names : array( $messenger_names );
153
+		$message_type_names = is_array($message_type_names) ? $message_type_names : array( $message_type_names );
154
+		return EEM_Message_Template_Group::instance()->update(
155
+			array( 'MTP_is_active' => 1 ),
156
+			array(
157
+				array(
158
+					'MTP_messenger'     => array( 'IN', $messenger_names ),
159
+					'MTP_message_type'  => array( 'IN', $message_type_names )
160
+				)
161
+			)
162
+		);
163
+	}
164
+
165
+
166
+	/**
167
+	 * Updates all message template groups matching the incoming arguments to inactive status.
168
+	 *
169
+	 * @static
170
+	 * @param array $messenger_names    The messenger slugs.
171
+	 *                                  If empty then all templates matching the message types are marked inactive.
172
+	 *                                  Otherwise only templates matching the messengers and message types.
173
+	 * @param array $message_type_names The message type slugs.
174
+	 *                                  If empty then all templates matching the messengers are marked inactive.
175
+	 *                                  Otherwise only templates matching the messengers and message types.
176
+	 *
177
+	 * @return int  count of updated records.
178
+	 * @throws EE_Error
179
+	 */
180
+	public static function update_to_inactive($messenger_names = array(), $message_type_names = array())
181
+	{
182
+		return EEM_Message_Template_Group::instance()->deactivate_message_template_groups_for(
183
+			$messenger_names,
184
+			$message_type_names
185
+		);
186
+	}
187
+
188
+
189
+	/**
190
+	 * The purpose of this function is to return all installed message objects
191
+	 * (messengers and message type regardless of whether they are ACTIVE or not)
192
+	 *
193
+	 * @param string $type
194
+	 * @return array array consisting of installed messenger objects and installed message type objects.
195
+	 * @throws EE_Error
196
+	 * @throws ReflectionException
197
+	 * @deprecated 4.9.0
198
+	 * @static
199
+	 */
200
+	public static function get_installed_message_objects($type = 'all')
201
+	{
202
+		self::_set_autoloader();
203
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
204
+		return array(
205
+			'messenger' => $message_resource_manager->installed_messengers(),
206
+			'message_type' => $message_resource_manager->installed_message_types()
207
+		);
208
+	}
209
+
210
+
211
+	/**
212
+	 * This will return an array of shortcodes => labels from the
213
+	 * messenger and message_type objects associated with this
214
+	 * template.
215
+	 *
216
+	 * @param string $message_type
217
+	 * @param string $messenger
218
+	 * @param array  $fields                        What fields we're returning valid shortcodes for.
219
+	 *                                              If empty then we assume all fields are to be returned. Optional.
220
+	 * @param string $context                       What context we're going to return shortcodes for. Optional.
221
+	 * @param bool   $merged                        If TRUE then we don't return shortcodes indexed by field,
222
+	 *                                              but instead an array of the unique shortcodes for all the given (
223
+	 *                                              or all) fields. Optional.
224
+	 * @return array                                an array of shortcodes in the format
225
+	 *                                              array( '[shortcode] => 'label')
226
+	 *                                              OR
227
+	 *                                              FALSE if no shortcodes found.
228
+	 * @throws ReflectionException
229
+	 * @throws EE_Error*@since 4.3.0
230
+	 *
231
+	 */
232
+	public static function get_shortcodes(
233
+		$message_type,
234
+		$messenger,
235
+		$fields = array(),
236
+		$context = 'admin',
237
+		$merged = false
238
+	) {
239
+		$messenger_name = str_replace(' ', '_', ucwords(str_replace('_', ' ', $messenger)));
240
+		$mt_name = str_replace(' ', '_', ucwords(str_replace('_', ' ', $message_type)));
241
+		/** @var EE_Message_Resource_Manager $message_resource_manager */
242
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
243
+		// convert slug to object
244
+		$messenger = $message_resource_manager->get_messenger($messenger);
245
+
246
+		// if messenger isn't a EE_messenger resource then bail.
247
+		if (! $messenger instanceof EE_messenger) {
248
+			return array();
249
+		}
250
+
251
+		// validate class for getting our list of shortcodes
252
+		$classname = 'EE_Messages_' . $messenger_name . '_' . $mt_name . '_Validator';
253
+		if (! class_exists($classname)) {
254
+			$msg[] = esc_html__('The Validator class was unable to load', 'event_espresso');
255
+			$msg[] = sprintf(
256
+				esc_html__('The class name compiled was %s. Please check and make sure the spelling and case is correct for the class name and that there is an autoloader in place for this class', 'event_espresso'),
257
+				$classname
258
+			);
259
+			throw new EE_Error(implode('||', $msg));
260
+		}
261
+
262
+		/** @type EE_Messages_Validator $_VLD */
263
+		$_VLD = new $classname(array(), $context);
264
+		$valid_shortcodes = $_VLD->get_validators();
265
+
266
+		// let's make sure we're only getting the shortcode part of the validators
267
+		$shortcodes = array();
268
+		foreach ($valid_shortcodes as $field => $validators) {
269
+			$shortcodes[ $field ] = $validators['shortcodes'];
270
+		}
271
+		$valid_shortcodes = $shortcodes;
272
+
273
+		// if not all fields let's make sure we ONLY include the shortcodes for the specified fields.
274
+		if (! empty($fields)) {
275
+			$specified_shortcodes = array();
276
+			foreach ($fields as $field) {
277
+				if (isset($valid_shortcodes[ $field ])) {
278
+					$specified_shortcodes[ $field ] = $valid_shortcodes[ $field ];
279
+				}
280
+			}
281
+			$valid_shortcodes = $specified_shortcodes;
282
+		}
283
+
284
+		// if not merged then let's replace the fields with the localized fields
285
+		if (! $merged) {
286
+			// let's get all the fields for the set messenger so that we can get the localized label and use that in the returned array.
287
+			$field_settings = $messenger->get_template_fields();
288
+			$localized = array();
289
+			foreach ($valid_shortcodes as $field => $shortcodes) {
290
+				// get localized field label
291
+				if (isset($field_settings[ $field ])) {
292
+					// possible that this is used as a main field.
293
+					if (empty($field_settings[ $field ])) {
294
+						if (isset($field_settings['extra'][ $field ])) {
295
+							$_field = $field_settings['extra'][ $field ]['main']['label'];
296
+						} else {
297
+							$_field = $field;
298
+						}
299
+					} else {
300
+						$_field = $field_settings[ $field ]['label'];
301
+					}
302
+				} elseif (isset($field_settings['extra'])) {
303
+					// loop through extra "main fields" and see if any of their children have our field
304
+					foreach ($field_settings['extra'] as $fields) {
305
+						if (isset($fields[ $field ])) {
306
+							$_field = $fields[ $field ]['label'];
307
+						} else {
308
+							$_field = $field;
309
+						}
310
+					}
311
+				} else {
312
+					$_field = $field;
313
+				}
314
+				if (isset($_field)) {
315
+					$localized[ (string) $_field ] = $shortcodes;
316
+				}
317
+			}
318
+			$valid_shortcodes = $localized;
319
+		}
320
+
321
+		// if $merged then let's merge all the shortcodes into one list NOT indexed by field.
322
+		if ($merged) {
323
+			$merged_codes = array();
324
+			foreach ($valid_shortcodes as $shortcode) {
325
+				foreach ($shortcode as $code => $label) {
326
+					if (isset($merged_codes[ $code ])) {
327
+						continue;
328
+					} else {
329
+						$merged_codes[ $code ] = $label;
330
+					}
331
+				}
332
+			}
333
+			$valid_shortcodes = $merged_codes;
334
+		}
335
+
336
+		return $valid_shortcodes;
337
+	}
338
+
339
+
340
+	/**
341
+	 * Get Messenger object.
342
+	 *
343
+	 * @param string $messenger messenger slug for the messenger object we want to retrieve.
344
+	 * @return EE_messenger
345
+	 * @throws ReflectionException
346
+	 * @throws EE_Error*@since 4.3.0
347
+	 * @deprecated 4.9.0
348
+	 */
349
+	public static function messenger_obj($messenger)
350
+	{
351
+		/** @type EE_Message_Resource_Manager $Message_Resource_Manager */
352
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
353
+		return $Message_Resource_Manager->get_messenger($messenger);
354
+	}
355
+
356
+
357
+	/**
358
+	 * get Message type object
359
+	 *
360
+	 * @param string $message_type the slug for the message type object to retrieve
361
+	 * @return EE_message_type
362
+	 * @throws ReflectionException
363
+	 * @throws EE_Error*@since 4.3.0
364
+	 * @deprecated 4.9.0
365
+	 */
366
+	public static function message_type_obj($message_type)
367
+	{
368
+		/** @type EE_Message_Resource_Manager $Message_Resource_Manager */
369
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
370
+		return $Message_Resource_Manager->get_message_type($message_type);
371
+	}
372
+
373
+
374
+	/**
375
+	 * Given a message_type slug, will return whether that message type is active in the system or not.
376
+	 *
377
+	 * @since    4.3.0
378
+	 * @param string $message_type message type to check for.
379
+	 * @return boolean
380
+	 * @throws EE_Error
381
+	 * @throws ReflectionException
382
+	 */
383
+	public static function is_mt_active($message_type)
384
+	{
385
+		/** @type EE_Message_Resource_Manager $Message_Resource_Manager */
386
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
387
+		$active_mts = $Message_Resource_Manager->list_of_active_message_types();
388
+		return in_array($message_type, $active_mts);
389
+	}
390
+
391
+
392
+	/**
393
+	 * Given a messenger slug, will return whether that messenger is active in the system or not.
394
+	 *
395
+	 * @since    4.3.0
396
+	 *
397
+	 * @param string $messenger slug for messenger to check.
398
+	 * @return boolean
399
+	 * @throws EE_Error
400
+	 * @throws ReflectionException
401
+	 */
402
+	public static function is_messenger_active($messenger)
403
+	{
404
+		/** @type EE_Message_Resource_Manager $Message_Resource_Manager */
405
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
406
+		$active_messenger = $Message_Resource_Manager->get_active_messenger($messenger);
407
+		return $active_messenger instanceof EE_messenger;
408
+	}
409
+
410
+
411
+	/**
412
+	 * Used to return active messengers array stored in the wp options table.
413
+	 * If no value is present in the option then an empty array is returned.
414
+	 *
415
+	 * @deprecated 4.9
416
+	 * @since      4.3.1
417
+	 *
418
+	 * @return array
419
+	 * @throws EE_Error
420
+	 * @throws ReflectionException
421
+	 */
422
+	public static function get_active_messengers_in_db()
423
+	{
424
+		EE_Error::doing_it_wrong(
425
+			__METHOD__,
426
+			esc_html__('Please use EE_Message_Resource_Manager::get_active_messengers_option() instead.', 'event_espresso'),
427
+			'4.9.0'
428
+		);
429
+		/** @var EE_Message_Resource_Manager $Message_Resource_Manager */
430
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
431
+		return $Message_Resource_Manager->get_active_messengers_option();
432
+	}
433
+
434
+
435
+	/**
436
+	 * Used to update the active messengers array stored in the wp options table.
437
+	 *
438
+	 * @since      4.3.1
439
+	 * @deprecated 4.9.0
440
+	 *
441
+	 * @param array $data_to_save Incoming data to save.
442
+	 *
443
+	 * @return bool FALSE if not updated, TRUE if updated.
444
+	 * @throws EE_Error
445
+	 * @throws ReflectionException
446
+	 */
447
+	public static function update_active_messengers_in_db($data_to_save)
448
+	{
449
+		EE_Error::doing_it_wrong(
450
+			__METHOD__,
451
+			esc_html__('Please use EE_Message_Resource_Manager::update_active_messengers_option() instead.', 'event_espresso'),
452
+			'4.9.0'
453
+		);
454
+		/** @var EE_Message_Resource_Manager $Message_Resource_Manager */
455
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
456
+		return $Message_Resource_Manager->update_active_messengers_option($data_to_save);
457
+	}
458
+
459
+
460
+	/**
461
+	 * This does some validation of incoming params, determines what type of url is being prepped and returns the
462
+	 * appropriate url trigger
463
+	 *
464
+	 * @param EE_message_type $message_type
465
+	 * @param EE_Message $message
466
+	 * @param EE_Registration | null $registration  The registration object must be included if this
467
+	 *                                              is going to be a registration trigger url.
468
+	 * @param string $sending_messenger             The (optional) sending messenger for the url.
469
+	 *
470
+	 * @return string
471
+	 * @throws EE_Error
472
+	 */
473
+	public static function get_url_trigger(
474
+		EE_message_type $message_type,
475
+		EE_Message $message,
476
+		$registration = null,
477
+		$sending_messenger = ''
478
+	) {
479
+		// first determine if the url can be to the EE_Message object.
480
+		if (! $message_type->always_generate()) {
481
+			return EEH_MSG_Template::generate_browser_trigger($message);
482
+		}
483
+
484
+		// if $registration object is not valid then exit early because there's nothing that can be generated.
485
+		if (! $registration instanceof EE_Registration) {
486
+			throw new EE_Error(
487
+				esc_html__('Incoming value for registration is not a valid EE_Registration object.', 'event_espresso')
488
+			);
489
+		}
490
+
491
+		// validate given context
492
+		$contexts = $message_type->get_contexts();
493
+		if ($message->context() !== '' && ! isset($contexts[ $message->context() ])) {
494
+			throw new EE_Error(
495
+				sprintf(
496
+					esc_html__('The context %s is not a valid context for %s.', 'event_espresso'),
497
+					$message->context(),
498
+					get_class($message_type)
499
+				)
500
+			);
501
+		}
502
+
503
+		// valid sending messenger but only if sending messenger set.  Otherwise generating messenger is used.
504
+		if (! empty($sending_messenger)) {
505
+			$with_messengers = $message_type->with_messengers();
506
+			if (
507
+				! isset($with_messengers[ $message->messenger() ])
508
+				 || ! in_array($sending_messenger, $with_messengers[ $message->messenger() ])
509
+			) {
510
+				throw new EE_Error(
511
+					sprintf(
512
+						esc_html__(
513
+							'The given sending messenger string (%1$s) does not match a valid sending messenger with the %2$s.  If this is incorrect, make sure that the message type has defined this messenger as a sending messenger in its $_with_messengers array.',
514
+							'event_espresso'
515
+						),
516
+						$sending_messenger,
517
+						get_class($message_type)
518
+					)
519
+				);
520
+			}
521
+		} else {
522
+			$sending_messenger = $message->messenger();
523
+		}
524
+		return EEH_MSG_Template::generate_url_trigger(
525
+			$sending_messenger,
526
+			$message->messenger(),
527
+			$message->context(),
528
+			$message->message_type(),
529
+			$registration,
530
+			$message->GRP_ID()
531
+		);
532
+	}
533
+
534
+
535
+	/**
536
+	 * This returns the url for triggering a in browser view of a specific EE_Message object.
537
+	 * @param EE_Message $message
538
+	 * @return string.
539
+	 */
540
+	public static function generate_browser_trigger(EE_Message $message)
541
+	{
542
+		$query_args = array(
543
+			'ee' => 'msg_browser_trigger',
544
+			'token' => $message->MSG_token()
545
+		);
546
+		return apply_filters(
547
+			'FHEE__EEH_MSG_Template__generate_browser_trigger',
548
+			add_query_arg($query_args, site_url()),
549
+			$message
550
+		);
551
+	}
552
+
553
+
554
+
555
+
556
+
557
+
558
+	/**
559
+	 * This returns the url for triggering an in browser view of the error saved on the incoming message object.
560
+	 * @param EE_Message $message
561
+	 * @return string
562
+	 */
563
+	public static function generate_error_display_trigger(EE_Message $message)
564
+	{
565
+		return apply_filters(
566
+			'FHEE__EEH_MSG_Template__generate_error_display_trigger',
567
+			add_query_arg(
568
+				array(
569
+					'ee' => 'msg_browser_error_trigger',
570
+					'token' => $message->MSG_token()
571
+				),
572
+				site_url()
573
+			),
574
+			$message
575
+		);
576
+	}
577
+
578
+
579
+	/**
580
+	 * This generates a url trigger for the msg_url_trigger route using the given arguments
581
+	 *
582
+	 * @param string          $sending_messenger      The sending messenger slug.
583
+	 * @param string          $generating_messenger   The generating messenger slug.
584
+	 * @param string          $context                The context for the template.
585
+	 * @param string          $message_type           The message type slug
586
+	 * @param EE_Registration $registration
587
+	 * @param integer         $message_template_group id   The EE_Message_Template_Group ID for the template.
588
+	 * @param integer         $data_id                The id to the EE_Base_Class for getting the data used by the
589
+	 *                                                trigger.
590
+	 * @return string          The generated url.
591
+	 * @throws EE_Error
592
+	 */
593
+	public static function generate_url_trigger(
594
+		$sending_messenger,
595
+		$generating_messenger,
596
+		$context,
597
+		$message_type,
598
+		EE_Registration $registration,
599
+		$message_template_group,
600
+		$data_id = 0
601
+	) {
602
+		$query_args = array(
603
+			'ee' => 'msg_url_trigger',
604
+			'snd_msgr' => $sending_messenger,
605
+			'gen_msgr' => $generating_messenger,
606
+			'message_type' => $message_type,
607
+			'context' => $context,
608
+			'token' => $registration->reg_url_link(),
609
+			'GRP_ID' => $message_template_group,
610
+			'id' => $data_id
611
+			);
612
+		$url = add_query_arg($query_args, get_home_url());
613
+
614
+		// made it here so now we can just get the url and filter it.  Filtered globally and by message type.
615
+		return apply_filters(
616
+			'FHEE__EEH_MSG_Template__generate_url_trigger',
617
+			$url,
618
+			$sending_messenger,
619
+			$generating_messenger,
620
+			$context,
621
+			$message_type,
622
+			$registration,
623
+			$message_template_group,
624
+			$data_id
625
+		);
626
+	}
627
+
628
+
629
+
630
+
631
+	/**
632
+	 * Return the specific css for the action icon given.
633
+	 *
634
+	 * @param string $type  What action to return.
635
+	 * @return string[]
636
+	 * @since 4.9.0
637
+	 */
638
+	public static function get_message_action_icon($type)
639
+	{
640
+		$action_icons = self::get_message_action_icons();
641
+		return isset($action_icons[ $type ]) ? $action_icons[ $type ] : [];
642
+	}
643
+
644
+
645
+	/**
646
+	 * This is used for retrieving the css classes used for the icons representing message actions.
647
+	 *
648
+	 * @since 4.9.0
649
+	 *
650
+	 * @return array
651
+	 */
652
+	public static function get_message_action_icons()
653
+	{
654
+		return apply_filters(
655
+			'FHEE__EEH_MSG_Template__message_action_icons',
656
+			array(
657
+				'view' => array(
658
+					'label' => esc_html__('View Message', 'event_espresso'),
659
+					'css_class' => 'dashicons dashicons-welcome-view-site',
660
+				),
661
+				'error' => array(
662
+					'label' => esc_html__('View Error Message', 'event_espresso'),
663
+					'css_class' => 'dashicons dashicons-info',
664
+				),
665
+				'see_notifications_for' => array(
666
+					'label' => esc_html__('View Related Messages', 'event_espresso'),
667
+					'css_class' => 'dashicons dashicons-megaphone',
668
+				),
669
+				'generate_now' => array(
670
+					'label' => esc_html__('Generate the message now.', 'event_espresso'),
671
+					'css_class' => 'dashicons dashicons-admin-tools',
672
+				),
673
+				'send_now' => array(
674
+					'label' => esc_html__('Send Immediately', 'event_espresso'),
675
+					'css_class' => 'dashicons dashicons-controls-forward',
676
+				),
677
+				'queue_for_resending' => array(
678
+					'label' => esc_html__('Queue for Resending', 'event_espresso'),
679
+					'css_class' => 'dashicons dashicons-controls-repeat',
680
+				),
681
+				'view_transaction' => array(
682
+					'label' => esc_html__('View related Transaction', 'event_espresso'),
683
+					'css_class' => 'dashicons dashicons-cart',
684
+				)
685
+			)
686
+		);
687
+	}
688
+
689
+
690
+	/**
691
+	 * This returns the url for a given action related to EE_Message.
692
+	 *
693
+	 * @param string     $type         What type of action to return the url for.
694
+	 * @param EE_Message $message      Required for generating the correct url for some types.
695
+	 * @param array      $query_params Any additional query params to be included with the generated url.
696
+	 *
697
+	 * @return string
698
+	 * @throws EE_Error
699
+	 * @throws ReflectionException
700
+	 * @since 4.9.0
701
+	 *
702
+	 */
703
+	public static function get_message_action_url($type, EE_Message $message = null, $query_params = array())
704
+	{
705
+		$action_urls = self::get_message_action_urls($message, $query_params);
706
+		return isset($action_urls[ $type ])  ? $action_urls[ $type ] : '';
707
+	}
708
+
709
+
710
+	/**
711
+	 * This returns all the current urls for EE_Message actions.
712
+	 *
713
+	 * @since 4.9.0
714
+	 *
715
+	 * @param EE_Message $message      The EE_Message object required to generate correct urls for some types.
716
+	 * @param array      $query_params Any additional query_params to be included with the generated url.
717
+	 *
718
+	 * @return array
719
+	 * @throws EE_Error
720
+	 * @throws ReflectionException
721
+	 */
722
+	public static function get_message_action_urls(EE_Message $message = null, $query_params = array())
723
+	{
724
+		EE_Registry::instance()->load_helper('URL');
725
+		// if $message is not an instance of EE_Message then let's just do a dummy.
726
+		$message = empty($message) ? EE_Message_Factory::create() : $message;
727
+		$action_urls =  apply_filters(
728
+			'FHEE__EEH_MSG_Template__get_message_action_url',
729
+			array(
730
+				'view' => EEH_MSG_Template::generate_browser_trigger($message),
731
+				'error' => EEH_MSG_Template::generate_error_display_trigger($message),
732
+				'see_notifications_for' => EEH_URL::add_query_args_and_nonce(
733
+					array_merge(
734
+						array(
735
+							'page' => 'espresso_messages',
736
+							'action' => 'default',
737
+							'filterby' => 1,
738
+						),
739
+						$query_params
740
+					),
741
+					admin_url('admin.php')
742
+				),
743
+				'generate_now' => EEH_URL::add_query_args_and_nonce(
744
+					array(
745
+						'page' => 'espresso_messages',
746
+						'action' => 'generate_now',
747
+						'MSG_ID' => $message->ID()
748
+					),
749
+					admin_url('admin.php')
750
+				),
751
+				'send_now' => EEH_URL::add_query_args_and_nonce(
752
+					array(
753
+						'page' => 'espresso_messages',
754
+						'action' => 'send_now',
755
+						'MSG_ID' => $message->ID()
756
+					),
757
+					admin_url('admin.php')
758
+				),
759
+				'queue_for_resending' => EEH_URL::add_query_args_and_nonce(
760
+					array(
761
+						'page' => 'espresso_messages',
762
+						'action' => 'queue_for_resending',
763
+						'MSG_ID' => $message->ID()
764
+					),
765
+					admin_url('admin.php')
766
+				),
767
+			)
768
+		);
769
+		if (
770
+			$message->TXN_ID() > 0
771
+			&& EE_Registry::instance()->CAP->current_user_can(
772
+				'ee_read_transaction',
773
+				'espresso_transactions_default',
774
+				$message->TXN_ID()
775
+			)
776
+		) {
777
+			$action_urls['view_transaction'] = EEH_URL::add_query_args_and_nonce(
778
+				array(
779
+					'page' => 'espresso_transactions',
780
+					'action' => 'view_transaction',
781
+					'TXN_ID' => $message->TXN_ID()
782
+				),
783
+				admin_url('admin.php')
784
+			);
785
+		} else {
786
+			$action_urls['view_transaction'] = '';
787
+		}
788
+		return $action_urls;
789
+	}
790
+
791
+
792
+	/**
793
+	 * This returns a generated link html including the icon used for the action link for EE_Message actions.
794
+	 *
795
+	 * @param string          $type         What type of action the link is for (if invalid type is passed in then an
796
+	 *                                      empty string is returned)
797
+	 * @param EE_Message|null $message      The EE_Message object (required for some actions to generate correctly)
798
+	 * @param array           $query_params Any extra query params to include in the generated link.
799
+	 *
800
+	 * @return string
801
+	 * @throws EE_Error
802
+	 * @throws ReflectionException
803
+	 * @since 4.9.0
804
+	 *
805
+	 */
806
+	public static function get_message_action_link($type, EE_Message $message = null, $query_params = array())
807
+	{
808
+		$url = EEH_MSG_Template::get_message_action_url($type, $message, $query_params);
809
+		$icon_css = EEH_MSG_Template::get_message_action_icon($type);
810
+		$title = isset($icon_css['label']) ? 'title="' . $icon_css['label'] . '"' : '';
811
+
812
+		if (empty($url) || empty($icon_css) || ! isset($icon_css['css_class'])) {
813
+			return '';
814
+		}
815
+
816
+		$icon_css['css_class'] .= esc_attr(
817
+			apply_filters(
818
+				'FHEE__EEH_MSG_Template__get_message_action_link__icon_css_class',
819
+				' js-ee-message-action-link ee-message-action-link-' . $type,
820
+				$type,
821
+				$message,
822
+				$query_params
823
+			)
824
+		);
825
+
826
+		return '<a href="' . $url . '" ' . $title . '><span class="' . esc_attr($icon_css['css_class']) . '"></span></a>';
827
+	}
828
+
829
+
830
+
831
+
832
+
833
+	/**
834
+	 * This returns an array with keys as reg statuses and values as the corresponding message type slug (filtered).
835
+	 *
836
+	 * @since 4.9.0
837
+	 * @return array
838
+	 */
839
+	public static function reg_status_to_message_type_array()
840
+	{
841
+		return (array) apply_filters(
842
+			'FHEE__EEH_MSG_Template__reg_status_to_message_type_array',
843
+			array(
844
+				EEM_Registration::status_id_approved => 'registration',
845
+				EEM_Registration::status_id_pending_payment => 'pending_approval',
846
+				EEM_Registration::status_id_not_approved => 'not_approved_registration',
847
+				EEM_Registration::status_id_cancelled => 'cancelled_registration',
848
+				EEM_Registration::status_id_declined => 'declined_registration'
849
+			)
850
+		);
851
+	}
852
+
853
+
854
+
855
+
856
+	/**
857
+	 * This returns the corresponding registration message type slug to the given reg status. If there isn't a
858
+	 * match, then returns an empty string.
859
+	 *
860
+	 * @since 4.9.0
861
+	 * @param $reg_status
862
+	 * @return string
863
+	 */
864
+	public static function convert_reg_status_to_message_type($reg_status)
865
+	{
866
+		$reg_status_array = self::reg_status_to_message_type_array();
867
+		return isset($reg_status_array[ $reg_status ]) ? $reg_status_array[ $reg_status ] : '';
868
+	}
869
+
870
+
871
+	/**
872
+	 * This returns an array with keys as payment stati and values as the corresponding message type slug (filtered).
873
+	 *
874
+	 * @since 4.9.0
875
+	 * @return array
876
+	 */
877
+	public static function payment_status_to_message_type_array()
878
+	{
879
+		return (array) apply_filters(
880
+			'FHEE__EEH_MSG_Template__payment_status_to_message_type_array',
881
+			array(
882
+				EEM_Payment::status_id_approved => 'payment',
883
+				EEM_Payment::status_id_pending => 'payment_pending',
884
+				EEM_Payment::status_id_cancelled => 'payment_cancelled',
885
+				EEM_Payment::status_id_declined => 'payment_declined',
886
+				EEM_Payment::status_id_failed => 'payment_failed'
887
+			)
888
+		);
889
+	}
890
+
891
+
892
+
893
+
894
+	/**
895
+	 * This returns the corresponding payment message type slug to the given payment status. If there isn't a match then
896
+	 * an empty string is returned
897
+	 *
898
+	 * @since 4.9.0
899
+	 * @param $payment_status
900
+	 * @return string
901
+	 */
902
+	public static function convert_payment_status_to_message_type($payment_status)
903
+	{
904
+		$payment_status_array = self::payment_status_to_message_type_array();
905
+		return isset($payment_status_array[ $payment_status ]) ? $payment_status_array[ $payment_status ] : '';
906
+	}
907
+
908
+
909
+	/**
910
+	 * This is used to retrieve the template pack for the given name.
911
+	 *
912
+	 * @param string $template_pack_name  should match the set `dbref` property value on the EE_Messages_Template_Pack.
913
+	 *
914
+	 * @return EE_Messages_Template_Pack
915
+	 */
916
+	public static function get_template_pack($template_pack_name)
917
+	{
918
+		if (! self::$_template_pack_collection instanceof EE_Object_Collection) {
919
+			self::$_template_pack_collection = new EE_Messages_Template_Pack_Collection();
920
+		}
921
+
922
+		// first see if in collection already
923
+		$template_pack = self::$_template_pack_collection->get_by_name($template_pack_name);
924
+
925
+		if ($template_pack instanceof EE_Messages_Template_Pack) {
926
+			return $template_pack;
927
+		}
928
+
929
+		// nope...let's get it.
930
+		// not set yet so let's attempt to get it.
931
+		$pack_class_name = 'EE_Messages_Template_Pack_' . str_replace(
932
+			' ',
933
+			'_',
934
+			ucwords(
935
+				str_replace('_', ' ', $template_pack_name)
936
+			)
937
+		);
938
+		if (! class_exists($pack_class_name) && $template_pack_name !== 'default') {
939
+			return self::get_template_pack('default');
940
+		} else {
941
+			$template_pack = new $pack_class_name();
942
+			self::$_template_pack_collection->add($template_pack);
943
+			return $template_pack;
944
+		}
945
+	}
946
+
947
+
948
+
949
+
950
+	/**
951
+	 * Globs template packs installed in core and returns the template pack collection with all installed template packs
952
+	 * in it.
953
+	 *
954
+	 * @since 4.9.0
955
+	 *
956
+	 * @return EE_Messages_Template_Pack_Collection
957
+	 */
958
+	public static function get_template_pack_collection()
959
+	{
960
+		$new_collection = false;
961
+		if (! self::$_template_pack_collection instanceof EE_Messages_Template_Pack_Collection) {
962
+			self::$_template_pack_collection = new EE_Messages_Template_Pack_Collection();
963
+			$new_collection = true;
964
+		}
965
+
966
+		// glob the defaults directory for messages
967
+		$templates = glob(EE_LIBRARIES . 'messages/defaults/*', GLOB_ONLYDIR);
968
+		foreach ($templates as $template_path) {
969
+			// grab folder name
970
+			$template = basename($template_path);
971
+
972
+			if (! $new_collection) {
973
+				// already have it?
974
+				if (self::$_template_pack_collection->get_by_name($template) instanceof EE_Messages_Template_Pack) {
975
+					continue;
976
+				}
977
+			}
978
+
979
+			// setup classname.
980
+			$template_pack_class_name = 'EE_Messages_Template_Pack_' . str_replace(
981
+				' ',
982
+				'_',
983
+				ucwords(
984
+					str_replace(
985
+						'_',
986
+						' ',
987
+						$template
988
+					)
989
+				)
990
+			);
991
+			if (! class_exists($template_pack_class_name)) {
992
+				continue;
993
+			}
994
+			self::$_template_pack_collection->add(new $template_pack_class_name());
995
+		}
996
+
997
+		/**
998
+		 * Filter for plugins to add in any additional template packs
999
+		 * Note the filter name here is for backward compat, this used to be found in EED_Messages.
1000
+		 */
1001
+		$additional_template_packs = apply_filters('FHEE__EED_Messages__get_template_packs__template_packs', array());
1002
+		foreach ((array) $additional_template_packs as $template_pack) {
1003
+			if (
1004
+				self::$_template_pack_collection->get_by_name(
1005
+					$template_pack->dbref
1006
+				) instanceof EE_Messages_Template_Pack
1007
+			) {
1008
+				continue;
1009
+			}
1010
+			self::$_template_pack_collection->add($template_pack);
1011
+		}
1012
+		return self::$_template_pack_collection;
1013
+	}
1014
+
1015
+
1016
+	/**
1017
+	 * This is a wrapper for the protected _create_new_templates function
1018
+	 *
1019
+	 * @param string $messenger_name
1020
+	 * @param string $message_type_name message type that the templates are being created for
1021
+	 * @param int    $GRP_ID
1022
+	 * @param bool   $global
1023
+	 * @return array
1024
+	 * @throws EE_Error
1025
+	 * @throws ReflectionException
1026
+	 */
1027
+	public static function create_new_templates($messenger_name, $message_type_name, $GRP_ID = 0, $global = false)
1028
+	{
1029
+		/** @type EE_Message_Resource_Manager $Message_Resource_Manager */
1030
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1031
+		$messenger = $Message_Resource_Manager->valid_messenger($messenger_name);
1032
+		$message_type = $Message_Resource_Manager->valid_message_type($message_type_name);
1033
+		if (! EEH_MSG_Template::message_type_has_active_templates_for_messenger($messenger, $message_type, $global)) {
1034
+			return array();
1035
+		}
1036
+		// whew made it this far!  Okay, let's go ahead and create the templates then
1037
+		return EEH_MSG_Template::_create_new_templates($messenger, $message_type, $GRP_ID, $global);
1038
+	}
1039
+
1040
+
1041
+	/**
1042
+	 * @param EE_messenger     $messenger
1043
+	 * @param EE_message_type  $message_type
1044
+	 * @param                  $GRP_ID
1045
+	 * @param                  $global
1046
+	 * @return array|mixed
1047
+	 * @throws EE_Error
1048
+	 * @throws ReflectionException
1049
+	 */
1050
+	protected static function _create_new_templates(EE_messenger $messenger, EE_message_type $message_type, $GRP_ID, $global)
1051
+	{
1052
+		// if we're creating a custom template then we don't need to use the defaults class
1053
+		if (! $global) {
1054
+			return EEH_MSG_Template::_create_custom_template_group($messenger, $message_type, $GRP_ID);
1055
+		}
1056
+		/** @type EE_Messages_Template_Defaults $Message_Template_Defaults */
1057
+		$Message_Template_Defaults = EE_Registry::factory(
1058
+			'EE_Messages_Template_Defaults',
1059
+			array( $messenger, $message_type, $GRP_ID )
1060
+		);
1061
+		// generate templates
1062
+		$success = $Message_Template_Defaults->create_new_templates();
1063
+
1064
+		// if creating the template failed.  Then we should deactivate the related message_type for the messenger because
1065
+		// its not active if it doesn't have a template.  Note this is only happening for GLOBAL template creation
1066
+		// attempts.
1067
+		if (! $success) {
1068
+			/** @var EE_Message_Resource_Manager $message_resource_manager */
1069
+			$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1070
+			$message_resource_manager->deactivate_message_type_for_messenger($message_type->name, $messenger->name);
1071
+		}
1072
+
1073
+		/**
1074
+		 * $success is in an array in the following format
1075
+		 * array(
1076
+		 *    'GRP_ID' => $new_grp_id,
1077
+		 *    'MTP_context' => $first_context_in_new_templates,
1078
+		 * )
1079
+		 */
1080
+		return $success;
1081
+	}
1082
+
1083
+
1084
+	/**
1085
+	 * This creates a custom template using the incoming GRP_ID
1086
+	 *
1087
+	 * @param EE_messenger    $messenger
1088
+	 * @param EE_message_type $message_type
1089
+	 * @param int             $GRP_ID           GRP_ID for the template_group being used as the base
1090
+	 * @return  array $success              This will be an array in the format:
1091
+	 *                                          array(
1092
+	 *                                          'GRP_ID' => $new_grp_id,
1093
+	 *                                          'MTP_context' => $first_context_in_created_template
1094
+	 *                                          )
1095
+	 * @throws EE_Error
1096
+	 * @throws ReflectionException
1097
+	 * @access private
1098
+	 */
1099
+	private static function _create_custom_template_group(EE_messenger $messenger, EE_message_type $message_type, $GRP_ID)
1100
+	{
1101
+		// defaults
1102
+		$success = array( 'GRP_ID' => null, 'MTP_context' => '' );
1103
+		// get the template group to use as a template from the db.  If $GRP_ID is empty then we'll assume the base will be the global template matching the messenger and message type.
1104
+		$Message_Template_Group = empty($GRP_ID)
1105
+			? EEM_Message_Template_Group::instance()->get_one(
1106
+				array(
1107
+					array(
1108
+						'MTP_messenger'    => $messenger->name,
1109
+						'MTP_message_type' => $message_type->name,
1110
+						'MTP_is_global'    => true
1111
+					)
1112
+				)
1113
+			)
1114
+			: EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1115
+		// if we don't have a mtg at this point then we need to bail.
1116
+		if (! $Message_Template_Group instanceof EE_Message_Template_Group) {
1117
+			EE_Error::add_error(
1118
+				sprintf(
1119
+					esc_html__(
1120
+						'Something went wrong with generating the custom template from this group id: %s.  This usually happens when there is no matching message template group in the db.',
1121
+						'event_espresso'
1122
+					),
1123
+					$GRP_ID
1124
+				),
1125
+				__FILE__,
1126
+				__FUNCTION__,
1127
+				__LINE__
1128
+			);
1129
+			return $success;
1130
+		}
1131
+		// let's get all the related message_template objects for this group.
1132
+		$message_templates = $Message_Template_Group->message_templates();
1133
+		// now we have what we need to setup the new template
1134
+		$new_mtg = clone $Message_Template_Group;
1135
+		$new_mtg->set('GRP_ID', 0);
1136
+		$new_mtg->set('MTP_is_global', false);
1137
+
1138
+		/** @var RequestInterface $request */
1139
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
1140
+		$template_name = $request->isAjax() && $request->requestParamIsSet('templateName')
1141
+			? $request->getRequestParam('templateName')
1142
+			: esc_html__('New Custom Template', 'event_espresso');
1143
+		$template_description = $request->isAjax() && $request->requestParamIsSet('templateDescription')
1144
+			? $request->getRequestParam('templateDescription')
1145
+			: sprintf(
1146
+				esc_html__(
1147
+					'This is a custom template that was created for the %s messenger and %s message type.',
1148
+					'event_espresso'
1149
+				),
1150
+				$new_mtg->messenger_obj()->label['singular'],
1151
+				$new_mtg->message_type_obj()->label['singular']
1152
+			);
1153
+		$new_mtg->set('MTP_name', $template_name);
1154
+		$new_mtg->set('MTP_description', $template_description);
1155
+		// remove ALL relations on this template group so they don't get saved!
1156
+		$new_mtg->_remove_relations('Message_Template');
1157
+		$new_mtg->save();
1158
+		$success['GRP_ID'] = $new_mtg->ID();
1159
+		$success['template_name'] = $template_name;
1160
+		// add new message templates and add relation to.
1161
+		foreach ($message_templates as $message_template) {
1162
+			if (! $message_template instanceof EE_Message_Template) {
1163
+				continue;
1164
+			}
1165
+			$new_message_template = clone $message_template;
1166
+			$new_message_template->set('MTP_ID', 0);
1167
+			$new_message_template->set('GRP_ID', $new_mtg->ID()); // relation
1168
+			$new_message_template->save();
1169
+			if (empty($success['MTP_context'])) {
1170
+				$success['MTP_context'] = $new_message_template->get('MTP_context');
1171
+			}
1172
+		}
1173
+		return $success;
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * message_type_has_active_templates_for_messenger
1179
+	 *
1180
+	 * @param EE_messenger    $messenger
1181
+	 * @param EE_message_type $message_type
1182
+	 * @param bool            $global
1183
+	 * @return bool
1184
+	 * @throws EE_Error
1185
+	 */
1186
+	public static function message_type_has_active_templates_for_messenger(
1187
+		EE_messenger $messenger,
1188
+		EE_message_type $message_type,
1189
+		$global = false
1190
+	) {
1191
+		// is given message_type valid for given messenger (if this is not a global save)
1192
+		if ($global) {
1193
+			return true;
1194
+		}
1195
+		$active_templates = EEM_Message_Template_Group::instance()->count(
1196
+			array(
1197
+				array(
1198
+					'MTP_is_active'    => true,
1199
+					'MTP_messenger'    => $messenger->name,
1200
+					'MTP_message_type' => $message_type->name
1201
+				)
1202
+			)
1203
+		);
1204
+		if ($active_templates > 0) {
1205
+			return true;
1206
+		}
1207
+		EE_Error::add_error(
1208
+			sprintf(
1209
+				esc_html__(
1210
+					'The %1$s message type is not registered with the %2$s messenger. Please visit the Messenger activation page to assign this message type first if you want to use it.',
1211
+					'event_espresso'
1212
+				),
1213
+				$message_type->name,
1214
+				$messenger->name
1215
+			),
1216
+			__FILE__,
1217
+			__FUNCTION__,
1218
+			__LINE__
1219
+		);
1220
+		return false;
1221
+	}
1222
+
1223
+
1224
+	/**
1225
+	 * get_fields
1226
+	 * This takes a given messenger and message type and returns all the template fields indexed by context (and with field type).
1227
+	 *
1228
+	 * @param string $messenger_name    name of EE_messenger
1229
+	 * @param string $message_type_name name of EE_message_type
1230
+	 * @return array
1231
+	 * @throws EE_Error
1232
+	 * @throws ReflectionException
1233
+	 */
1234
+	public static function get_fields($messenger_name, $message_type_name)
1235
+	{
1236
+		$template_fields = array();
1237
+		/** @type EE_Message_Resource_Manager $Message_Resource_Manager */
1238
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1239
+		$messenger = $Message_Resource_Manager->valid_messenger($messenger_name);
1240
+		$message_type = $Message_Resource_Manager->valid_message_type($message_type_name);
1241
+		if (! EEH_MSG_Template::message_type_has_active_templates_for_messenger($messenger, $message_type)) {
1242
+			return array();
1243
+		}
1244
+
1245
+		$excluded_fields_for_messenger = $message_type->excludedFieldsForMessenger($messenger_name);
1246
+
1247
+		// okay now let's assemble an array with the messenger template fields added to the message_type contexts.
1248
+		foreach ($message_type->get_contexts() as $context => $details) {
1249
+			foreach ($messenger->get_template_fields() as $field => $value) {
1250
+				if (in_array($field, $excluded_fields_for_messenger, true)) {
1251
+					continue;
1252
+				}
1253
+				$template_fields[ $context ][ $field ] = $value;
1254
+			}
1255
+		}
1256
+		if (empty($template_fields)) {
1257
+			EE_Error::add_error(
1258
+				esc_html__('Something went wrong and we couldn\'t get any templates assembled', 'event_espresso'),
1259
+				__FILE__,
1260
+				__FUNCTION__,
1261
+				__LINE__
1262
+			);
1263
+			return array();
1264
+		}
1265
+		return $template_fields;
1266
+	}
1267 1267
 }
Please login to merge, or discard this patch.
admin_pages/messages/templates/shortcode_selector_skeleton.template.php 2 patches
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -28,14 +28,14 @@
 block discarded – undo
28 28
         </h6>
29 29
         <h4>
30 30
             <?php
31
-            printf(
32
-                esc_html__('"%1$s" field', 'event_espresso'),
33
-                esc_attr($fieldname)
34
-            ); ?>
31
+			printf(
32
+				esc_html__('"%1$s" field', 'event_espresso'),
33
+				esc_attr($fieldname)
34
+			); ?>
35 35
         </h4>
36 36
         <ul>
37 37
         <?php
38
-        foreach (array_keys($shortcodes) as $shortcode) : ?>
38
+		foreach (array_keys($shortcodes) as $shortcode) : ?>
39 39
             <li>
40 40
                 <span class="js-shortcode-selection"
41 41
                       data-linked-input-id="<?php echo esc_attr($linked_input_id); ?>"
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@
 block discarded – undo
10 10
  * @type    string $linked_input_id The name of the input that the shortcode gets inserted to.
11 11
  */
12 12
 
13
-if (! empty($shortcodes)) : ?>
13
+if ( ! empty($shortcodes)) : ?>
14 14
 <div class="ee-messages-shortcodes-chooser-wrap">
15 15
     <button class="ee-messages-shortcodes-chooser js-open-list-trigger button button-secondary"
16 16
             aria-label="<?php echo esc_html__('open shortcode selector', 'event_espresso'); ?>"
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 2 patches
Indentation   +4638 added lines, -4638 removed lines patch added patch discarded remove patch
@@ -16,2687 +16,2687 @@  discard block
 block discarded – undo
16 16
  */
17 17
 class Messages_Admin_Page extends EE_Admin_Page
18 18
 {
19
-    /**
20
-     * @var EEM_Message
21
-     */
22
-    private $MSG_MODEL;
23
-
24
-    /**
25
-     * @var EEM_Message_Template
26
-     */
27
-    private $MTP_MODEL;
28
-
29
-    /**
30
-     * @var EEM_Message_Template_Group
31
-     */
32
-    private $MTG_MODEL;
33
-
34
-    /**
35
-     * @var EE_Message_Resource_Manager $_message_resource_manager
36
-     */
37
-    protected $_message_resource_manager;
38
-
39
-    /**
40
-     * @var string
41
-     */
42
-    protected $_active_message_type_name = '';
43
-
44
-    /**
45
-     * @var string
46
-     */
47
-    protected $_active_messenger_name = '';
48
-
49
-    /**
50
-     * @var EE_messenger $_active_messenger
51
-     */
52
-    protected $_active_messenger;
53
-
54
-    protected $_activate_meta_box_type;
55
-
56
-    protected $_current_message_meta_box;
57
-
58
-    protected $_current_message_meta_box_object;
59
-
60
-    protected $_context_switcher;
61
-
62
-    protected $_shortcodes           = [];
63
-
64
-    protected $_active_messengers    = [];
65
-
66
-    protected $_active_message_types = [];
67
-
68
-    /**
69
-     * @var EE_Message_Template_Group $_message_template_group
70
-     */
71
-    protected $_message_template_group;
72
-
73
-    protected $_m_mt_settings = [];
74
-
75
-
76
-    /**
77
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
78
-     * IF there is no group then it gets automatically set to the Default template pack.
79
-     *
80
-     * @since 4.5.0
81
-     *
82
-     * @var EE_Messages_Template_Pack
83
-     */
84
-    protected $_template_pack;
85
-
86
-
87
-    /**
88
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
89
-     * group is.  If there is no group then it automatically gets set to default.
90
-     *
91
-     * @since 4.5.0
92
-     *
93
-     * @var string
94
-     */
95
-    protected $_variation;
96
-
97
-
98
-    /**
99
-     * @param bool $routing
100
-     * @throws EE_Error
101
-     * @throws ReflectionException
102
-     */
103
-    public function __construct($routing = true)
104
-    {
105
-        // make sure messages autoloader is running
106
-        EED_Messages::set_autoloaders();
107
-        parent::__construct($routing);
108
-    }
109
-
110
-
111
-    /**
112
-     * @return EEM_Message
113
-     * @throws EE_Error
114
-     */
115
-    public function getMsgModel()
116
-    {
117
-        if (! $this->MSG_MODEL instanceof EEM_Message) {
118
-            $this->MSG_MODEL = EEM_Message::instance();
119
-        }
120
-        return $this->MSG_MODEL;
121
-    }
122
-
123
-
124
-    /**
125
-     * @return EEM_Message_Template
126
-     * @throws EE_Error
127
-     */
128
-    public function getMtpModel()
129
-    {
130
-        if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
131
-            $this->MTP_MODEL = EEM_Message_Template::instance();
132
-        }
133
-        return $this->MTP_MODEL;
134
-    }
135
-
136
-
137
-    /**
138
-     * @return EEM_Message_Template_Group
139
-     * @throws EE_Error
140
-     */
141
-    public function getMtgModel()
142
-    {
143
-        if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
144
-            $this->MTG_MODEL = EEM_Message_Template_Group::instance();
145
-        }
146
-        return $this->MTG_MODEL;
147
-    }
148
-
149
-
150
-    /**
151
-     * @throws EE_Error
152
-     * @throws ReflectionException
153
-     */
154
-    protected function _init_page_props()
155
-    {
156
-        $this->page_slug        = EE_MSG_PG_SLUG;
157
-        $this->page_label       = esc_html__('Messages Settings', 'event_espresso');
158
-        $this->_admin_base_url  = EE_MSG_ADMIN_URL;
159
-        $this->_admin_base_path = EE_MSG_ADMIN;
160
-
161
-        $this->_active_messenger_name    = $this->request->getRequestParam('messenger', '');
162
-        $this->_active_message_type_name = $this->request->getRequestParam('message_type', '');
163
-
164
-        $this->_load_message_resource_manager();
165
-    }
166
-
167
-
168
-    /**
169
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
170
-     *
171
-     * @throws EE_Error
172
-     * @throws InvalidDataTypeException
173
-     * @throws InvalidInterfaceException
174
-     * @throws InvalidArgumentException
175
-     * @throws ReflectionException
176
-     */
177
-    protected function _load_message_resource_manager()
178
-    {
179
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
180
-    }
181
-
182
-
183
-    /**
184
-     * @return array
185
-     * @throws EE_Error
186
-     * @throws InvalidArgumentException
187
-     * @throws InvalidDataTypeException
188
-     * @throws InvalidInterfaceException
189
-     * @deprecated 4.9.9.rc.014
190
-     */
191
-    public function get_messengers_for_list_table()
192
-    {
193
-        EE_Error::doing_it_wrong(
194
-            __METHOD__,
195
-            sprintf(
196
-                esc_html__(
197
-                    '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',
198
-                    'event_espresso'
199
-                ),
200
-                'Messages_Admin_Page::get_messengers_select_input()'
201
-            ),
202
-            '4.9.9.rc.014'
203
-        );
204
-
205
-        $m_values          = [];
206
-        $active_messengers = $this->getMsgModel()->get_all(['group_by' => 'MSG_messenger']);
207
-        // setup messengers for selects
208
-        $i = 1;
209
-        foreach ($active_messengers as $active_messenger) {
210
-            if ($active_messenger instanceof EE_Message) {
211
-                $m_values[ $i ]['id']   = $active_messenger->messenger();
212
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
213
-                $i++;
214
-            }
215
-        }
216
-
217
-        return $m_values;
218
-    }
219
-
220
-
221
-    /**
222
-     * @return array
223
-     * @throws EE_Error
224
-     * @throws InvalidArgumentException
225
-     * @throws InvalidDataTypeException
226
-     * @throws InvalidInterfaceException
227
-     * @deprecated 4.9.9.rc.014
228
-     */
229
-    public function get_message_types_for_list_table()
230
-    {
231
-        EE_Error::doing_it_wrong(
232
-            __METHOD__,
233
-            sprintf(
234
-                esc_html__(
235
-                    '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',
236
-                    'event_espresso'
237
-                ),
238
-                'Messages_Admin_Page::get_message_types_select_input()'
239
-            ),
240
-            '4.9.9.rc.014'
241
-        );
242
-
243
-        $mt_values       = [];
244
-        $active_messages = $this->getMsgModel()->get_all(['group_by' => 'MSG_message_type']);
245
-        $i               = 1;
246
-        foreach ($active_messages as $active_message) {
247
-            if ($active_message instanceof EE_Message) {
248
-                $mt_values[ $i ]['id']   = $active_message->message_type();
249
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
250
-                $i++;
251
-            }
252
-        }
253
-
254
-        return $mt_values;
255
-    }
256
-
257
-
258
-    /**
259
-     * @return array
260
-     * @throws EE_Error
261
-     * @throws InvalidArgumentException
262
-     * @throws InvalidDataTypeException
263
-     * @throws InvalidInterfaceException
264
-     * @deprecated 4.9.9.rc.014
265
-     */
266
-    public function get_contexts_for_message_types_for_list_table()
267
-    {
268
-        EE_Error::doing_it_wrong(
269
-            __METHOD__,
270
-            sprintf(
271
-                esc_html__(
272
-                    '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',
273
-                    'event_espresso'
274
-                ),
275
-                'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
276
-            ),
277
-            '4.9.9.rc.014'
278
-        );
279
-
280
-        $contexts                = [];
281
-        $active_message_contexts = $this->getMsgModel()->get_all(['group_by' => 'MSG_context']);
282
-        foreach ($active_message_contexts as $active_message) {
283
-            if ($active_message instanceof EE_Message) {
284
-                $message_type = $active_message->message_type_object();
285
-                if ($message_type instanceof EE_message_type) {
286
-                    $message_type_contexts = $message_type->get_contexts();
287
-                    foreach ($message_type_contexts as $context => $context_details) {
288
-                        $contexts[ $context ] = $context_details['label'];
289
-                    }
290
-                }
291
-            }
292
-        }
293
-
294
-        return $contexts;
295
-    }
296
-
297
-
298
-    /**
299
-     * Generate select input with provided messenger options array.
300
-     *
301
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
302
-     *                                 labels.
303
-     * @return string
304
-     * @throws EE_Error
305
-     */
306
-    public function get_messengers_select_input($messenger_options)
307
-    {
308
-        // if empty or just one value then just return an empty string
309
-        if (
310
-            empty($messenger_options)
311
-            || ! is_array($messenger_options)
312
-            || count($messenger_options) === 1
313
-        ) {
314
-            return '';
315
-        }
316
-        // merge in default
317
-        $messenger_options = array_merge(
318
-            ['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
319
-            $messenger_options
320
-        );
321
-        $input             = new EE_Select_Input(
322
-            $messenger_options,
323
-            [
324
-                'html_name'  => 'ee_messenger_filter_by',
325
-                'html_id'    => 'ee_messenger_filter_by',
326
-                'html_class' => 'wide',
327
-                'default'    => $this->request->getRequestParam('ee_messenger_filter_by', 'none_selected', 'title'),
328
-            ]
329
-        );
330
-
331
-        return $input->get_html_for_input();
332
-    }
333
-
334
-
335
-    /**
336
-     * Generate select input with provided message type options array.
337
-     *
338
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
339
-     *                                    message type labels
340
-     * @return string
341
-     * @throws EE_Error
342
-     */
343
-    public function get_message_types_select_input($message_type_options)
344
-    {
345
-        // if empty or count of options is 1 then just return an empty string
346
-        if (
347
-            empty($message_type_options)
348
-            || ! is_array($message_type_options)
349
-            || count($message_type_options) === 1
350
-        ) {
351
-            return '';
352
-        }
353
-        // merge in default
354
-        $message_type_options = array_merge(
355
-            ['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
356
-            $message_type_options
357
-        );
358
-        $input                = new EE_Select_Input(
359
-            $message_type_options,
360
-            [
361
-                'html_name'  => 'ee_message_type_filter_by',
362
-                'html_id'    => 'ee_message_type_filter_by',
363
-                'html_class' => 'wide',
364
-                'default'    => $this->request->getRequestParam('ee_message_type_filter_by', 'none_selected', 'title'),
365
-            ]
366
-        );
367
-
368
-        return $input->get_html_for_input();
369
-    }
370
-
371
-
372
-    /**
373
-     * Generate select input with provide message type contexts array.
374
-     *
375
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
376
-     *                               context label.
377
-     * @return string
378
-     * @throws EE_Error
379
-     */
380
-    public function get_contexts_for_message_types_select_input($context_options)
381
-    {
382
-        // if empty or count of options is one then just return empty string
383
-        if (
384
-            empty($context_options)
385
-            || ! is_array($context_options)
386
-            || count($context_options) === 1
387
-        ) {
388
-            return '';
389
-        }
390
-        // merge in default
391
-        $context_options = array_merge(
392
-            ['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
393
-            $context_options
394
-        );
395
-        $input           = new EE_Select_Input(
396
-            $context_options,
397
-            [
398
-                'html_name'  => 'ee_context_filter_by',
399
-                'html_id'    => 'ee_context_filter_by',
400
-                'html_class' => 'wide',
401
-                'default'    => $this->request->getRequestParam('ee_context_filter_by', 'none_selected', 'title'),
402
-            ]
403
-        );
404
-
405
-        return $input->get_html_for_input();
406
-    }
407
-
408
-
409
-    protected function _ajax_hooks()
410
-    {
411
-        add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
412
-        add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
413
-        add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
414
-        add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
415
-        add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
416
-        add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
417
-    }
418
-
419
-
420
-    protected function _define_page_props()
421
-    {
422
-        $this->_admin_page_title = $this->page_label;
423
-        $this->_labels           = [
424
-            'buttons'    => [
425
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
426
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
427
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
428
-            ],
429
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
430
-        ];
431
-    }
432
-
433
-
434
-    /**
435
-     *        an array for storing key => value pairs of request actions and their corresponding methods
436
-     *
437
-     * @access protected
438
-     * @return void
439
-     */
440
-    protected function _set_page_routes()
441
-    {
442
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
443
-        $GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
444
-        $MSG_ID = $this->request->getRequestParam('MSG_ID', 0, 'int');
445
-
446
-        $this->_page_routes = [
447
-            'default'                          => [
448
-                'func'       => '_message_queue_list_table',
449
-                'capability' => 'ee_read_global_messages',
450
-            ],
451
-            'global_mtps'                      => [
452
-                'func'       => '_ee_default_messages_overview_list_table',
453
-                'capability' => 'ee_read_global_messages',
454
-            ],
455
-            'custom_mtps'                      => [
456
-                'func'       => '_custom_mtps_preview',
457
-                'capability' => 'ee_read_messages',
458
-            ],
459
-            'add_new_message_template'         => [
460
-                'func'       => '_add_message_template',
461
-                'capability' => 'ee_edit_messages',
462
-                'noheader'   => true,
463
-            ],
464
-            'edit_message_template'            => [
465
-                'func'       => '_edit_message_template',
466
-                'capability' => 'ee_edit_message',
467
-                'obj_id'     => $GRP_ID,
468
-            ],
469
-            'preview_message'                  => [
470
-                'func'               => '_preview_message',
471
-                'capability'         => 'ee_read_message',
472
-                'obj_id'             => $GRP_ID,
473
-                'noheader'           => true,
474
-                'headers_sent_route' => 'display_preview_message',
475
-            ],
476
-            'display_preview_message'          => [
477
-                'func'       => '_display_preview_message',
478
-                'capability' => 'ee_read_message',
479
-                'obj_id'     => $GRP_ID,
480
-            ],
481
-            'insert_message_template'          => [
482
-                'func'       => '_insert_or_update_message_template',
483
-                'capability' => 'ee_edit_messages',
484
-                'args'       => ['new' => true],
485
-                'noheader'   => true,
486
-            ],
487
-            'update_message_template'          => [
488
-                'func'       => '_insert_or_update_message_template',
489
-                'capability' => 'ee_edit_message',
490
-                'obj_id'     => $GRP_ID,
491
-                'args'       => ['new' => false],
492
-                'noheader'   => true,
493
-            ],
494
-            'trash_message_template'           => [
495
-                'func'       => '_trash_or_restore_message_template',
496
-                'capability' => 'ee_delete_message',
497
-                'obj_id'     => $GRP_ID,
498
-                'args'       => ['trash' => true, 'all' => true],
499
-                'noheader'   => true,
500
-            ],
501
-            'trash_message_template_context'   => [
502
-                'func'       => '_trash_or_restore_message_template',
503
-                'capability' => 'ee_delete_message',
504
-                'obj_id'     => $GRP_ID,
505
-                'args'       => ['trash' => true],
506
-                'noheader'   => true,
507
-            ],
508
-            'restore_message_template'         => [
509
-                'func'       => '_trash_or_restore_message_template',
510
-                'capability' => 'ee_delete_message',
511
-                'obj_id'     => $GRP_ID,
512
-                'args'       => ['trash' => false, 'all' => true],
513
-                'noheader'   => true,
514
-            ],
515
-            'restore_message_template_context' => [
516
-                'func'       => '_trash_or_restore_message_template',
517
-                'capability' => 'ee_delete_message',
518
-                'obj_id'     => $GRP_ID,
519
-                'args'       => ['trash' => false],
520
-                'noheader'   => true,
521
-            ],
522
-            'delete_message_template'          => [
523
-                'func'       => '_delete_message_template',
524
-                'capability' => 'ee_delete_message',
525
-                'obj_id'     => $GRP_ID,
526
-                'noheader'   => true,
527
-            ],
528
-            'reset_to_default'                 => [
529
-                'func'       => '_reset_to_default_template',
530
-                'capability' => 'ee_edit_message',
531
-                'obj_id'     => $GRP_ID,
532
-                'noheader'   => true,
533
-            ],
534
-            'settings'                         => [
535
-                'func'       => '_settings',
536
-                'capability' => 'manage_options',
537
-            ],
538
-            'update_global_settings'           => [
539
-                'func'       => '_update_global_settings',
540
-                'capability' => 'manage_options',
541
-                'noheader'   => true,
542
-            ],
543
-            'generate_now'                     => [
544
-                'func'       => '_generate_now',
545
-                'capability' => 'ee_send_message',
546
-                'noheader'   => true,
547
-            ],
548
-            'generate_and_send_now'            => [
549
-                'func'       => '_generate_and_send_now',
550
-                'capability' => 'ee_send_message',
551
-                'noheader'   => true,
552
-            ],
553
-            'queue_for_resending'              => [
554
-                'func'       => '_queue_for_resending',
555
-                'capability' => 'ee_send_message',
556
-                'noheader'   => true,
557
-            ],
558
-            'send_now'                         => [
559
-                'func'       => '_send_now',
560
-                'capability' => 'ee_send_message',
561
-                'noheader'   => true,
562
-            ],
563
-            'delete_ee_message'                => [
564
-                'func'       => '_delete_ee_messages',
565
-                'capability' => 'ee_delete_messages',
566
-                'noheader'   => true,
567
-            ],
568
-            'delete_ee_messages'               => [
569
-                'func'       => '_delete_ee_messages',
570
-                'capability' => 'ee_delete_messages',
571
-                'noheader'   => true,
572
-                'obj_id'     => $MSG_ID,
573
-            ],
574
-        ];
575
-    }
576
-
577
-
578
-    protected function _set_page_config()
579
-    {
580
-        $this->_page_config = [
581
-            'default'                  => [
582
-                'nav'           => [
583
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
584
-                    'order' => 10,
585
-                ],
586
-                'list_table'    => 'EE_Message_List_Table',
587
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
588
-                'require_nonce' => false,
589
-            ],
590
-            'global_mtps'              => [
591
-                'nav'           => [
592
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
593
-                    'order' => 20,
594
-                ],
595
-                'list_table'    => 'Messages_Template_List_Table',
596
-                'help_tabs'     => [
597
-                    'messages_overview_help_tab'                                => [
598
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
599
-                        'filename' => 'messages_overview',
600
-                    ],
601
-                    'messages_overview_messages_table_column_headings_help_tab' => [
602
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
603
-                        'filename' => 'messages_overview_table_column_headings',
604
-                    ],
605
-                    'messages_overview_messages_filters_help_tab'               => [
606
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
607
-                        'filename' => 'messages_overview_filters',
608
-                    ],
609
-                    'messages_overview_messages_views_help_tab'                 => [
610
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
611
-                        'filename' => 'messages_overview_views',
612
-                    ],
613
-                    'message_overview_message_types_help_tab'                   => [
614
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
615
-                        'filename' => 'messages_overview_types',
616
-                    ],
617
-                    'messages_overview_messengers_help_tab'                     => [
618
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
619
-                        'filename' => 'messages_overview_messengers',
620
-                    ],
621
-                ],
622
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
623
-                // 'help_tour'     => array('Messages_Overview_Help_Tour'),
624
-                'require_nonce' => false,
625
-            ],
626
-            'custom_mtps'              => [
627
-                'nav'           => [
628
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
629
-                    'order' => 30,
630
-                ],
631
-                'help_tabs'     => [],
632
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
633
-                // 'help_tour'     => array(),
634
-                'require_nonce' => false,
635
-            ],
636
-            'add_new_message_template' => [
637
-                'nav'           => [
638
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
639
-                    'order'      => 5,
640
-                    'persistent' => false,
641
-                ],
642
-                'require_nonce' => false,
643
-            ],
644
-            'edit_message_template'    => [
645
-                'labels'        => [
646
-                    'buttons'    => [
647
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
648
-                    ],
649
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
650
-                ],
651
-                'nav'           => [
652
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
653
-                    'order'      => 5,
654
-                    'persistent' => false,
655
-                    'url'        => '',
656
-                ],
657
-                'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
658
-                'has_metaboxes' => true,
659
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
660
-                // 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
661
-                'help_tabs'     => [
662
-                    'edit_message_template'            => [
663
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
664
-                        'callback' => 'edit_message_template_help_tab',
665
-                    ],
666
-                    'message_templates_help_tab'       => [
667
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
668
-                        'filename' => 'messages_templates',
669
-                    ],
670
-                    'message_template_shortcodes'      => [
671
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
672
-                        'callback' => 'message_template_shortcodes_help_tab',
673
-                    ],
674
-                    'message_preview_help_tab'         => [
675
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
676
-                        'filename' => 'messages_preview',
677
-                    ],
678
-                    'messages_overview_other_help_tab' => [
679
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
680
-                        'filename' => 'messages_overview_other',
681
-                    ],
682
-                ],
683
-                'require_nonce' => false,
684
-            ],
685
-            'display_preview_message'  => [
686
-                'nav'           => [
687
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
688
-                    'order'      => 5,
689
-                    'url'        => '',
690
-                    'persistent' => false,
691
-                ],
692
-                'help_tabs'     => [
693
-                    'preview_message' => [
694
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
695
-                        'callback' => 'preview_message_help_tab',
696
-                    ],
697
-                ],
698
-                'require_nonce' => false,
699
-            ],
700
-            'settings'                 => [
701
-                'nav'           => [
702
-                    'label' => esc_html__('Settings', 'event_espresso'),
703
-                    'order' => 40,
704
-                ],
705
-                'metaboxes'     => ['_messages_settings_metaboxes'],
706
-                'help_tabs'     => [
707
-                    'messages_settings_help_tab'               => [
708
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
709
-                        'filename' => 'messages_settings',
710
-                    ],
711
-                    'messages_settings_message_types_help_tab' => [
712
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
713
-                        'filename' => 'messages_settings_message_types',
714
-                    ],
715
-                    'messages_settings_messengers_help_tab'    => [
716
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
717
-                        'filename' => 'messages_settings_messengers',
718
-                    ],
719
-                ],
720
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
721
-                // 'help_tour'     => array('Messages_Settings_Help_Tour'),
722
-                'require_nonce' => false,
723
-            ],
724
-        ];
725
-    }
726
-
727
-
728
-    protected function _add_screen_options()
729
-    {
730
-        // todo
731
-    }
732
-
733
-
734
-    protected function _add_screen_options_global_mtps()
735
-    {
736
-        /**
737
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
738
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
739
-         */
740
-        $page_title              = $this->_admin_page_title;
741
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
742
-        $this->_per_page_screen_option();
743
-        $this->_admin_page_title = $page_title;
744
-    }
745
-
746
-
747
-    protected function _add_screen_options_default()
748
-    {
749
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
750
-        $this->_per_page_screen_option();
751
-    }
752
-
753
-
754
-    // none of the below group are currently used for Messages
755
-    protected function _add_feature_pointers()
756
-    {
757
-    }
758
-
759
-
760
-    public function admin_init()
761
-    {
762
-    }
763
-
764
-
765
-    public function admin_notices()
766
-    {
767
-    }
768
-
769
-
770
-    public function admin_footer_scripts()
771
-    {
772
-    }
773
-
774
-
775
-    public function messages_help_tab()
776
-    {
777
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
778
-    }
779
-
780
-
781
-    public function messengers_help_tab()
782
-    {
783
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
784
-    }
785
-
786
-
787
-    public function message_types_help_tab()
788
-    {
789
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
790
-    }
791
-
792
-
793
-    public function messages_overview_help_tab()
794
-    {
795
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
796
-    }
797
-
798
-
799
-    public function message_templates_help_tab()
800
-    {
801
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
802
-    }
803
-
804
-
805
-    public function edit_message_template_help_tab()
806
-    {
807
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
808
-                        . esc_attr__('Editor Title', 'event_espresso')
809
-                        . '" />';
810
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
811
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
812
-                        . '" />';
813
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
814
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
815
-                        . '" />';
816
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
817
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
818
-                        . '" />';
819
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
820
-                        . esc_attr__('Publish Metabox', 'event_espresso')
821
-                        . '" />';
822
-        EEH_Template::display_template(
823
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
824
-            $args
825
-        );
826
-    }
827
-
828
-
829
-    /**
830
-     * @throws ReflectionException
831
-     * @throws EE_Error
832
-     */
833
-    public function message_template_shortcodes_help_tab()
834
-    {
835
-        $this->_set_shortcodes();
836
-        $args['shortcodes'] = $this->_shortcodes;
837
-        EEH_Template::display_template(
838
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
839
-            $args
840
-        );
841
-    }
842
-
843
-
844
-    public function preview_message_help_tab()
845
-    {
846
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
847
-    }
848
-
849
-
850
-    public function settings_help_tab()
851
-    {
852
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
853
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
854
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
855
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
856
-        $args['img3'] = '<div class="switch">'
857
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
858
-                        . ' type="checkbox" checked="checked">'
859
-                        . '<label for="ee-on-off-toggle-on"></label>'
860
-                        . '</div>';
861
-        $args['img4'] = '<div class="switch">'
862
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
863
-                        . ' type="checkbox">'
864
-                        . '<label for="ee-on-off-toggle-on"></label>'
865
-                        . '</div>';
866
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
867
-    }
868
-
869
-
870
-    public function load_scripts_styles()
871
-    {
872
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
873
-        wp_enqueue_style('espresso_ee_msg');
874
-
875
-        wp_register_script(
876
-            'ee-messages-settings',
877
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
878
-            ['jquery-ui-droppable', 'ee-serialize-full-array'],
879
-            EVENT_ESPRESSO_VERSION,
880
-            true
881
-        );
882
-        wp_register_script(
883
-            'ee-msg-list-table-js',
884
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
885
-            ['ee-dialog'],
886
-            EVENT_ESPRESSO_VERSION
887
-        );
888
-    }
889
-
890
-
891
-    public function load_scripts_styles_default()
892
-    {
893
-        wp_enqueue_script('ee-msg-list-table-js');
894
-    }
895
-
896
-
897
-    public function wp_editor_css($mce_css)
898
-    {
899
-        // if we're on the edit_message_template route
900
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
901
-            $message_type_name = $this->_active_message_type_name;
902
-
903
-            // we're going to REPLACE the existing mce css
904
-            // we need to get the css file location from the active messenger
905
-            $mce_css = $this->_active_messenger->get_variation(
906
-                $this->_template_pack,
907
-                $message_type_name,
908
-                true,
909
-                'wpeditor',
910
-                $this->_variation
911
-            );
912
-        }
913
-
914
-        return $mce_css;
915
-    }
916
-
917
-
918
-    /**
919
-     * @throws EE_Error
920
-     * @throws ReflectionException
921
-     */
922
-    public function load_scripts_styles_edit_message_template()
923
-    {
924
-
925
-        $this->_set_shortcodes();
926
-
927
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
928
-            esc_html__(
929
-                '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.',
930
-                'event_espresso'
931
-            ),
932
-            $this->_message_template_group->messenger_obj()->label['singular'],
933
-            $this->_message_template_group->message_type_obj()->label['singular']
934
-        );
935
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
936
-            '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?',
937
-            'event_espresso'
938
-        );
939
-        EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
940
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
941
-            'event_espresso'
942
-        );
943
-
944
-        wp_register_script(
945
-            'ee_msgs_edit_js',
946
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
947
-            ['jquery'],
948
-            EVENT_ESPRESSO_VERSION
949
-        );
950
-
951
-        wp_enqueue_script('ee_admin_js');
952
-        wp_enqueue_script('ee_msgs_edit_js');
953
-
954
-        // add in special css for tiny_mce
955
-        add_filter('mce_css', [$this, 'wp_editor_css']);
956
-    }
957
-
958
-
959
-    /**
960
-     * @throws EE_Error
961
-     * @throws ReflectionException
962
-     */
963
-    public function load_scripts_styles_display_preview_message()
964
-    {
965
-        $this->_set_message_template_group();
966
-        if ($this->_active_messenger_name) {
967
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
968
-                $this->_active_messenger_name
969
-            );
970
-        }
971
-
972
-        wp_enqueue_style(
973
-            'espresso_preview_css',
974
-            $this->_active_messenger->get_variation(
975
-                $this->_template_pack,
976
-                $this->_active_message_type_name,
977
-                true,
978
-                'preview',
979
-                $this->_variation
980
-            )
981
-        );
982
-    }
983
-
984
-
985
-    public function load_scripts_styles_settings()
986
-    {
987
-        wp_register_style(
988
-            'ee-message-settings',
989
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
990
-            [],
991
-            EVENT_ESPRESSO_VERSION
992
-        );
993
-        wp_enqueue_style('ee-text-links');
994
-        wp_enqueue_style('ee-message-settings');
995
-        wp_enqueue_script('ee-messages-settings');
996
-    }
997
-
998
-
999
-    /**
1000
-     * set views array for List Table
1001
-     */
1002
-    public function _set_list_table_views_global_mtps()
1003
-    {
1004
-        $this->_views = [
1005
-            'in_use' => [
1006
-                'slug'  => 'in_use',
1007
-                'label' => esc_html__('In Use', 'event_espresso'),
1008
-                'count' => 0,
1009
-            ],
1010
-        ];
1011
-    }
1012
-
1013
-
1014
-    /**
1015
-     * Set views array for the Custom Template List Table
1016
-     */
1017
-    public function _set_list_table_views_custom_mtps()
1018
-    {
1019
-        $this->_set_list_table_views_global_mtps();
1020
-        $this->_views['in_use']['bulk_action'] = [
1021
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
1022
-        ];
1023
-    }
1024
-
1025
-
1026
-    /**
1027
-     * set views array for message queue list table
1028
-     *
1029
-     * @throws InvalidDataTypeException
1030
-     * @throws InvalidInterfaceException
1031
-     * @throws InvalidArgumentException
1032
-     * @throws EE_Error
1033
-     * @throws ReflectionException
1034
-     */
1035
-    public function _set_list_table_views_default()
1036
-    {
1037
-        EE_Registry::instance()->load_helper('Template');
1038
-
1039
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
1040
-            'ee_send_message',
1041
-            'message_list_table_bulk_actions'
1042
-        )
1043
-            ? [
1044
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
1045
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
1046
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
1047
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
1048
-            ]
1049
-            : [];
1050
-
1051
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
1052
-            'ee_delete_messages',
1053
-            'message_list_table_bulk_actions'
1054
-        )
1055
-            ? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
1056
-            : [];
1057
-
1058
-
1059
-        $this->_views = [
1060
-            'all' => [
1061
-                'slug'        => 'all',
1062
-                'label'       => esc_html__('All', 'event_espresso'),
1063
-                'count'       => 0,
1064
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1065
-            ],
1066
-        ];
1067
-
1068
-
1069
-        foreach ($this->getMsgModel()->all_statuses() as $status) {
1070
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1071
-                continue;
1072
-            }
1073
-            $status_bulk_actions = $common_bulk_actions;
1074
-            // unset bulk actions not applying to status
1075
-            if (! empty($status_bulk_actions)) {
1076
-                switch ($status) {
1077
-                    case EEM_Message::status_idle:
1078
-                    case EEM_Message::status_resend:
1079
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1080
-                        break;
1081
-
1082
-                    case EEM_Message::status_failed:
1083
-                    case EEM_Message::status_debug_only:
1084
-                    case EEM_Message::status_messenger_executing:
1085
-                        $status_bulk_actions = [];
1086
-                        break;
1087
-
1088
-                    case EEM_Message::status_incomplete:
1089
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1090
-                        break;
1091
-
1092
-                    case EEM_Message::status_retry:
1093
-                    case EEM_Message::status_sent:
1094
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1095
-                        break;
1096
-                }
1097
-            }
1098
-
1099
-            // skip adding messenger executing status to views because it will be included with the Failed view.
1100
-            if ($status === EEM_Message::status_messenger_executing) {
1101
-                continue;
1102
-            }
1103
-
1104
-            $this->_views[ strtolower($status) ] = [
1105
-                'slug'        => strtolower($status),
1106
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1107
-                'count'       => 0,
1108
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1109
-            ];
1110
-        }
1111
-    }
1112
-
1113
-
1114
-    /**
1115
-     * @throws EE_Error
1116
-     */
1117
-    protected function _ee_default_messages_overview_list_table()
1118
-    {
1119
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1120
-        $this->display_admin_list_table_page_with_no_sidebar();
1121
-    }
1122
-
1123
-
1124
-    /**
1125
-     * @throws EE_Error
1126
-     * @throws ReflectionException
1127
-     */
1128
-    protected function _message_queue_list_table()
1129
-    {
1130
-        $this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
1131
-        $this->_template_args['per_column']        = 6;
1132
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
1133
-        $this->_template_args['before_list_table'] = '<h3>'
1134
-                                                     . $this->getMsgModel()->get_pretty_label_for_results()
1135
-                                                     . '</h3>';
1136
-        $this->display_admin_list_table_page_with_no_sidebar();
1137
-    }
1138
-
1139
-
1140
-    /**
1141
-     * @throws EE_Error
1142
-     */
1143
-    protected function _message_legend_items()
1144
-    {
1145
-
1146
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1147
-        $action_items       = [];
1148
-
1149
-        foreach ($action_css_classes as $action_item => $action_details) {
1150
-            if ($action_item === 'see_notifications_for') {
1151
-                continue;
1152
-            }
1153
-            $action_items[ $action_item ] = [
1154
-                'class' => $action_details['css_class'],
1155
-                'desc'  => $action_details['label'],
1156
-            ];
1157
-        }
1158
-
1159
-        /** @var array $status_items status legend setup */
1160
-        $status_items = [
1161
-            'sent_status'                => [
1162
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1163
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1164
-            ],
1165
-            'idle_status'                => [
1166
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1167
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1168
-            ],
1169
-            'failed_status'              => [
1170
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1171
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1172
-            ],
1173
-            'messenger_executing_status' => [
1174
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1175
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1176
-            ],
1177
-            'resend_status'              => [
1178
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1179
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1180
-            ],
1181
-            'incomplete_status'          => [
1182
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1183
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1184
-            ],
1185
-            'retry_status'               => [
1186
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1187
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1188
-            ],
1189
-        ];
1190
-        if (EEM_Message::debug()) {
1191
-            $status_items['debug_only_status'] = [
1192
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1193
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1194
-            ];
1195
-        }
1196
-
1197
-        return array_merge($action_items, $status_items);
1198
-    }
1199
-
1200
-
1201
-    /**
1202
-     * @throws EE_Error
1203
-     */
1204
-    protected function _custom_mtps_preview()
1205
-    {
1206
-        $this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1207
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1208
-                                                . ' alt="' . esc_attr__(
1209
-                                                    'Preview Custom Message Templates screenshot',
1210
-                                                    'event_espresso'
1211
-                                                ) . '" />';
1212
-        $this->_template_args['preview_text'] = '<strong>'
1213
-                                                . esc_html__(
1214
-                                                    '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.',
1215
-                                                    'event_espresso'
1216
-                                                )
1217
-                                                . '</strong>';
1218
-
1219
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1220
-    }
1221
-
1222
-
1223
-    /**
1224
-     * get_message_templates
1225
-     * This gets all the message templates for listing on the overview list.
1226
-     *
1227
-     * @access public
1228
-     * @param int    $per_page the amount of templates groups to show per page
1229
-     * @param string $type     the current _view we're getting templates for
1230
-     * @param bool   $count    return count?
1231
-     * @param bool   $all      disregard any paging info (get all data);
1232
-     * @param bool   $global   whether to return just global (true) or custom templates (false)
1233
-     * @return array
1234
-     * @throws EE_Error
1235
-     * @throws InvalidArgumentException
1236
-     * @throws InvalidDataTypeException
1237
-     * @throws InvalidInterfaceException
1238
-     */
1239
-    public function get_message_templates(
1240
-        $per_page = 10,
1241
-        $type = 'in_use',
1242
-        $count = false,
1243
-        $all = false,
1244
-        $global = true
1245
-    ) {
1246
-        $orderby = $this->request->getRequestParam('orderby', 'GRP_ID');
1247
-        $this->request->setRequestParam('orderby', $orderby);
1248
-
1249
-        $order        = $this->request->getRequestParam('order', 'ASC');
1250
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
1251
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1252
-
1253
-        $offset = ($current_page - 1) * $per_page;
1254
-        $limit  = $all ? null : [$offset, $per_page];
1255
-
1256
-        // options will match what is in the _views array property
1257
-        return $type === 'in_use'
1258
-            ? $this->getMtgModel()->get_all_active_message_templates(
1259
-                $orderby,
1260
-                $order,
1261
-                $limit,
1262
-                $count,
1263
-                $global,
1264
-                true
1265
-            )
1266
-            : $this->getMtgModel()->get_all_trashed_grouped_message_templates(
1267
-                $orderby,
1268
-                $order,
1269
-                $limit,
1270
-                $count,
1271
-                $global
1272
-            );
1273
-    }
1274
-
1275
-
1276
-    /**
1277
-     * filters etc might need a list of installed message_types
1278
-     *
1279
-     * @return array an array of message type objects
1280
-     */
1281
-    public function get_installed_message_types()
1282
-    {
1283
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1284
-        $installed               = [];
1285
-
1286
-        foreach ($installed_message_types as $message_type) {
1287
-            $installed[ $message_type->name ] = $message_type;
1288
-        }
1289
-
1290
-        return $installed;
1291
-    }
1292
-
1293
-
1294
-    /**
1295
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1296
-     *
1297
-     * @param string $message_type
1298
-     * @param string $messenger
1299
-     * @param string $GRP_ID
1300
-     *
1301
-     * @throws EE_error
1302
-     * @throws ReflectionException
1303
-     */
1304
-    public function add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1305
-    {
1306
-        // set values override any request data
1307
-        $message_type = ! empty($message_type) ? $message_type : $this->_active_message_type_name;
1308
-        $messenger    = ! empty($messenger) ? $messenger : $this->_active_messenger_name;
1309
-        $GRP_ID       = ! empty($GRP_ID) ? $GRP_ID : $this->request->getRequestParam('GRP_ID', 0, 'int');
1310
-
1311
-        // we need messenger and message type.  They should be coming from the event editor. If not here then return error
1312
-        if (empty($message_type) || empty($messenger)) {
1313
-            throw new EE_Error(
1314
-                esc_html__(
1315
-                    'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1316
-                    'event_espresso'
1317
-                )
1318
-            );
1319
-        }
1320
-
1321
-        // we need the GRP_ID for the template being used as the base for the new template
1322
-        if (empty($GRP_ID)) {
1323
-            throw new EE_Error(
1324
-                esc_html__(
1325
-                    'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1326
-                    'event_espresso'
1327
-                )
1328
-            );
1329
-        }
1330
-
1331
-        // let's just make sure the template gets generated!
1332
-
1333
-        // we need to reassign some variables for what the insert is expecting
1334
-        $this->request->setRequestParam('MTP_messenger', $messenger);
1335
-        $this->request->setRequestParam('MTP_message_type', $message_type);
1336
-        $this->request->setRequestParam('GRP_ID', $GRP_ID);
1337
-
1338
-        $this->_insert_or_update_message_template(true);
1339
-    }
1340
-
1341
-
1342
-    /**
1343
-     * @param string $message_type     message type slug
1344
-     * @param string $messenger        messenger slug
1345
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1346
-     *                                 off of.
1347
-     * @throws EE_error
1348
-     * @throws ReflectionException
1349
-     * @deprecated $VID:$
1350
-     */
1351
-    protected function _add_message_template($message_type, $messenger, $GRP_ID)
1352
-    {
1353
-        $this->add_message_template($message_type, $messenger, $GRP_ID);
1354
-    }
1355
-
1356
-
1357
-    /**
1358
-     * _edit_message_template
1359
-     *
1360
-     * @access protected
1361
-     * @return void
1362
-     * @throws InvalidIdentifierException
1363
-     * @throws DomainException
1364
-     * @throws EE_Error
1365
-     * @throws InvalidArgumentException
1366
-     * @throws ReflectionException
1367
-     * @throws InvalidDataTypeException
1368
-     * @throws InvalidInterfaceException
1369
-     */
1370
-    protected function _edit_message_template()
1371
-    {
1372
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1373
-        $template_fields = '';
1374
-        $sidebar_fields  = '';
1375
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1376
-        // valid html in the templates.
1377
-        add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1378
-
1379
-        $GRP_ID = $this->request->getRequestParam('id', 0, 'int');
1380
-        $EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
1381
-
1382
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1383
-        $message_template_group = $this->_message_template_group;
1384
-        $c_label                = $message_template_group->context_label();
1385
-        $c_config               = $message_template_group->contexts_config();
1386
-
1387
-        reset($c_config);
1388
-        $context = $this->request->getRequestParam('context', key($c_config));
1389
-        $context = strtolower($context);
1390
-
1391
-        $action = empty($GRP_ID) ? 'insert_message_template' : 'update_message_template';
1392
-
1393
-        $edit_message_template_form_url = add_query_arg(
1394
-            ['action' => $action, 'noheader' => true],
1395
-            EE_MSG_ADMIN_URL
1396
-        );
1397
-
1398
-        // set active messenger for this view
1399
-        $this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1400
-            $message_template_group->messenger()
1401
-        );
1402
-        $this->_active_message_type_name = $message_template_group->message_type();
1403
-
1404
-
1405
-        // Do we have any validation errors?
1406
-        $validators = $this->_get_transient();
1407
-        $v_fields   = ! empty($validators) ? array_keys($validators) : [];
1408
-
1409
-
1410
-        // we need to assemble the title from Various details
1411
-        $context_label = sprintf(
1412
-            esc_html__('(%s %s)', 'event_espresso'),
1413
-            $c_config[ $context ]['label'],
1414
-            ucwords($c_label['label'])
1415
-        );
1416
-
1417
-        $title = sprintf(
1418
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1419
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1420
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1421
-            $context_label
1422
-        );
1423
-
1424
-        $this->_template_args['GRP_ID']           = $GRP_ID;
1425
-        $this->_template_args['message_template'] = $message_template_group;
1426
-        $this->_template_args['is_extra_fields']  = false;
1427
-
1428
-
1429
-        // let's get EEH_MSG_Template so we can get template form fields
1430
-        $template_field_structure = EEH_MSG_Template::get_fields(
1431
-            $message_template_group->messenger(),
1432
-            $message_template_group->message_type()
1433
-        );
1434
-
1435
-        if (! $template_field_structure) {
1436
-            $template_field_structure = false;
1437
-            $template_fields          = esc_html__(
1438
-                'There was an error in assembling the fields for this display (you should see an error message)',
1439
-                'event_espresso'
1440
-            );
1441
-        }
1442
-
1443
-
1444
-        $message_templates = $message_template_group->context_templates();
1445
-
1446
-
1447
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1448
-        // will get handled in the "extra" array.
1449
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1450
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1451
-                unset($template_field_structure[ $context ][ $reference_field ]);
1452
-            }
1453
-        }
1454
-
1455
-        // let's loop through the template_field_structure and actually assemble the input fields!
1456
-        if (! empty($template_field_structure)) {
1457
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1458
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1459
-                // the extra array and reset them.
1460
-                if ($template_field === 'extra') {
1461
-                    $this->_template_args['is_extra_fields'] = true;
1462
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1463
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1464
-                        $content          = $message_template instanceof EE_Message_Template
1465
-                            ? $message_template->get('MTP_content')
1466
-                            : '';
1467
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1468
-                            // let's verify if we need this extra field via the shortcodes parameter.
1469
-                            $continue = false;
1470
-                            if (isset($extra_array['shortcodes_required'])) {
1471
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1472
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1473
-                                        $continue = true;
1474
-                                    }
1475
-                                }
1476
-                                if ($continue) {
1477
-                                    continue;
1478
-                                }
1479
-                            }
1480
-
1481
-                            $field_id = $reference_field . '-' . $extra_field . '-content';
1482
-
1483
-                            $template_form_fields[ $field_id ]         = $extra_array;
1484
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1485
-                                                                         . $reference_field
1486
-                                                                         . '][content]['
1487
-                                                                         . $extra_field . ']';
1488
-                            $css_class                                 = isset($extra_array['css_class'])
1489
-                                ? $extra_array['css_class']
1490
-                                : '';
1491
-
1492
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1493
-                                                                              && in_array($extra_field, $v_fields, true)
1494
-                                                                              && (
1495
-                                                                                  is_array($validators[ $extra_field ])
1496
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1497
-                                                                              )
1498
-                                ? 'validate-error ' . $css_class
1499
-                                : $css_class;
1500
-
1501
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1502
-                                                                          && isset($content[ $extra_field ])
1503
-                                ? $content[ $extra_field ]
1504
-                                : '';
1505
-
1506
-                            // do we have a validation error?  if we do then let's use that value instead
1507
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1508
-                                ? $validators[ $extra_field ]['value']
1509
-                                : $template_form_fields[ $field_id ]['value'];
1510
-
1511
-
1512
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1513
-
1514
-                            // shortcode selector
1515
-                            $field_name_to_use                                   = $extra_field === 'main'
1516
-                                ? 'content'
1517
-                                : $extra_field;
1518
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1519
-                                $field_name_to_use,
1520
-                                $field_id
1521
-                            );
1522
-                        }
1523
-                        $template_field_MTP_id           = $reference_field . '-MTP_ID';
1524
-                        $template_field_template_name_id = $reference_field . '-name';
1525
-
1526
-                        $template_form_fields[ $template_field_MTP_id ] = [
1527
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1528
-                            'label'      => null,
1529
-                            'input'      => 'hidden',
1530
-                            'type'       => 'int',
1531
-                            'required'   => false,
1532
-                            'validation' => false,
1533
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1534
-                            'css_class'  => '',
1535
-                            'format'     => '%d',
1536
-                            'db-col'     => 'MTP_ID',
1537
-                        ];
1538
-
1539
-                        $template_form_fields[ $template_field_template_name_id ] = [
1540
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1541
-                            'label'      => null,
1542
-                            'input'      => 'hidden',
1543
-                            'type'       => 'string',
1544
-                            'required'   => false,
1545
-                            'validation' => true,
1546
-                            'value'      => $reference_field,
1547
-                            'css_class'  => '',
1548
-                            'format'     => '%s',
1549
-                            'db-col'     => 'MTP_template_field',
1550
-                        ];
1551
-                    }
1552
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1553
-                } else {
1554
-                    $field_id                                   = $template_field . '-content';
1555
-                    $template_form_fields[ $field_id ]          = $field_setup_array;
1556
-                    $template_form_fields[ $field_id ]['name']  =
1557
-                        'MTP_template_fields[' . $template_field . '][content]';
1558
-                    $message_template                           =
1559
-                        isset($message_templates[ $context ][ $template_field ])
1560
-                            ? $message_templates[ $context ][ $template_field ]
1561
-                            : null;
1562
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1563
-                                                                  && is_array($message_templates[ $context ])
1564
-                                                                  && $message_template instanceof EE_Message_Template
1565
-                        ? $message_template->get('MTP_content')
1566
-                        : '';
1567
-
1568
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1569
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1570
-                        ? $validators[ $template_field ]['value']
1571
-                        : $template_form_fields[ $field_id ]['value'];
1572
-
1573
-
1574
-                    $template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1575
-                    $css_class                                      = isset($field_setup_array['css_class'])
1576
-                        ? $field_setup_array['css_class']
1577
-                        : '';
1578
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1579
-                                                                      && in_array($template_field, $v_fields, true)
1580
-                                                                      && isset($validators[ $template_field ]['msg'])
1581
-                        ? 'validate-error ' . $css_class
1582
-                        : $css_class;
1583
-
1584
-                    // shortcode selector
1585
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1586
-                        $template_field,
1587
-                        $field_id
1588
-                    );
1589
-                }
1590
-
1591
-                // k took care of content field(s) now let's take care of others.
1592
-
1593
-                $template_field_MTP_id                 = $template_field . '-MTP_ID';
1594
-                $template_field_field_template_name_id = $template_field . '-name';
1595
-
1596
-                // foreach template field there are actually two form fields created
1597
-                $template_form_fields[ $template_field_MTP_id ] = [
1598
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1599
-                    'label'      => null,
1600
-                    'input'      => 'hidden',
1601
-                    'type'       => 'int',
1602
-                    'required'   => false,
1603
-                    'validation' => true,
1604
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1605
-                    'css_class'  => '',
1606
-                    'format'     => '%d',
1607
-                    'db-col'     => 'MTP_ID',
1608
-                ];
1609
-
1610
-                $template_form_fields[ $template_field_field_template_name_id ] = [
1611
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1612
-                    'label'      => null,
1613
-                    'input'      => 'hidden',
1614
-                    'type'       => 'string',
1615
-                    'required'   => false,
1616
-                    'validation' => true,
1617
-                    'value'      => $template_field,
1618
-                    'css_class'  => '',
1619
-                    'format'     => '%s',
1620
-                    'db-col'     => 'MTP_template_field',
1621
-                ];
1622
-            }
1623
-
1624
-            // add other fields
1625
-            $template_form_fields['ee-msg-current-context'] = [
1626
-                'name'       => 'MTP_context',
1627
-                'label'      => null,
1628
-                'input'      => 'hidden',
1629
-                'type'       => 'string',
1630
-                'required'   => false,
1631
-                'validation' => true,
1632
-                'value'      => $context,
1633
-                'css_class'  => '',
1634
-                'format'     => '%s',
1635
-                'db-col'     => 'MTP_context',
1636
-            ];
1637
-
1638
-            $template_form_fields['ee-msg-grp-id'] = [
1639
-                'name'       => 'GRP_ID',
1640
-                'label'      => null,
1641
-                'input'      => 'hidden',
1642
-                'type'       => 'int',
1643
-                'required'   => false,
1644
-                'validation' => true,
1645
-                'value'      => $GRP_ID,
1646
-                'css_class'  => '',
1647
-                'format'     => '%d',
1648
-                'db-col'     => 'GRP_ID',
1649
-            ];
1650
-
1651
-            $template_form_fields['ee-msg-messenger'] = [
1652
-                'name'       => 'MTP_messenger',
1653
-                'label'      => null,
1654
-                'input'      => 'hidden',
1655
-                'type'       => 'string',
1656
-                'required'   => false,
1657
-                'validation' => true,
1658
-                'value'      => $message_template_group->messenger(),
1659
-                'css_class'  => '',
1660
-                'format'     => '%s',
1661
-                'db-col'     => 'MTP_messenger',
1662
-            ];
1663
-
1664
-            $template_form_fields['ee-msg-message-type'] = [
1665
-                'name'       => 'MTP_message_type',
1666
-                'label'      => null,
1667
-                'input'      => 'hidden',
1668
-                'type'       => 'string',
1669
-                'required'   => false,
1670
-                'validation' => true,
1671
-                'value'      => $message_template_group->message_type(),
1672
-                'css_class'  => '',
1673
-                'format'     => '%s',
1674
-                'db-col'     => 'MTP_message_type',
1675
-            ];
1676
-
1677
-            $sidebar_form_fields['ee-msg-is-global'] = [
1678
-                'name'       => 'MTP_is_global',
1679
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1680
-                'input'      => 'hidden',
1681
-                'type'       => 'int',
1682
-                'required'   => false,
1683
-                'validation' => true,
1684
-                'value'      => $message_template_group->get('MTP_is_global'),
1685
-                'css_class'  => '',
1686
-                'format'     => '%d',
1687
-                'db-col'     => 'MTP_is_global',
1688
-            ];
1689
-
1690
-            $sidebar_form_fields['ee-msg-is-override'] = [
1691
-                'name'       => 'MTP_is_override',
1692
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1693
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1694
-                'type'       => 'int',
1695
-                'required'   => false,
1696
-                'validation' => true,
1697
-                'value'      => $message_template_group->get('MTP_is_override'),
1698
-                'css_class'  => '',
1699
-                'format'     => '%d',
1700
-                'db-col'     => 'MTP_is_override',
1701
-            ];
1702
-
1703
-            $sidebar_form_fields['ee-msg-is-active'] = [
1704
-                'name'       => 'MTP_is_active',
1705
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1706
-                'input'      => 'hidden',
1707
-                'type'       => 'int',
1708
-                'required'   => false,
1709
-                'validation' => true,
1710
-                'value'      => $message_template_group->is_active(),
1711
-                'css_class'  => '',
1712
-                'format'     => '%d',
1713
-                'db-col'     => 'MTP_is_active',
1714
-            ];
1715
-
1716
-            $sidebar_form_fields['ee-msg-deleted'] = [
1717
-                'name'       => 'MTP_deleted',
1718
-                'label'      => null,
1719
-                'input'      => 'hidden',
1720
-                'type'       => 'int',
1721
-                'required'   => false,
1722
-                'validation' => true,
1723
-                'value'      => $message_template_group->get('MTP_deleted'),
1724
-                'css_class'  => '',
1725
-                'format'     => '%d',
1726
-                'db-col'     => 'MTP_deleted',
1727
-            ];
1728
-            $sidebar_form_fields['ee-msg-author']  = [
1729
-                'name'       => 'MTP_user_id',
1730
-                'label'      => esc_html__('Author', 'event_espresso'),
1731
-                'input'      => 'hidden',
1732
-                'type'       => 'int',
1733
-                'required'   => false,
1734
-                'validation' => false,
1735
-                'value'      => $message_template_group->user(),
1736
-                'format'     => '%d',
1737
-                'db-col'     => 'MTP_user_id',
1738
-            ];
1739
-
1740
-            $sidebar_form_fields['ee-msg-route'] = [
1741
-                'name'  => 'action',
1742
-                'input' => 'hidden',
1743
-                'type'  => 'string',
1744
-                'value' => $action,
1745
-            ];
1746
-
1747
-            $sidebar_form_fields['ee-msg-id']        = [
1748
-                'name'  => 'id',
1749
-                'input' => 'hidden',
1750
-                'type'  => 'int',
1751
-                'value' => $GRP_ID,
1752
-            ];
1753
-            $sidebar_form_fields['ee-msg-evt-nonce'] = [
1754
-                'name'  => $action . '_nonce',
1755
-                'input' => 'hidden',
1756
-                'type'  => 'string',
1757
-                'value' => wp_create_nonce($action . '_nonce'),
1758
-            ];
1759
-
1760
-            $template_switch = $this->request->getRequestParam('template_switch');
1761
-            if ($template_switch) {
1762
-                $sidebar_form_fields['ee-msg-template-switch'] = [
1763
-                    'name'  => 'template_switch',
1764
-                    'input' => 'hidden',
1765
-                    'type'  => 'int',
1766
-                    'value' => 1,
1767
-                ];
1768
-            }
1769
-
1770
-
1771
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1772
-            $sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1773
-        } //end if ( !empty($template_field_structure) )
1774
-
1775
-        // set extra content for publish box
1776
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1777
-        $this->_set_publish_post_box_vars(
1778
-            'id',
1779
-            $GRP_ID,
1780
-            false,
1781
-            add_query_arg(
1782
-                ['action' => 'global_mtps'],
1783
-                $this->_admin_base_url
1784
-            )
1785
-        );
1786
-
1787
-        // add preview button
1788
-        $preview_url    = parent::add_query_args_and_nonce(
1789
-            [
1790
-                'message_type' => $message_template_group->message_type(),
1791
-                'messenger'    => $message_template_group->messenger(),
1792
-                'context'      => $context,
1793
-                'GRP_ID'       => $GRP_ID,
1794
-                'evt_id'       => $EVT_ID,
1795
-                'action'       => 'preview_message',
1796
-            ],
1797
-            $this->_admin_base_url
1798
-        );
1799
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1800
-                          . esc_html__('Preview', 'event_espresso')
1801
-                          . '</a>';
1802
-
1803
-
1804
-        // setup context switcher
1805
-        $context_switcher_args = [
1806
-            'page'    => 'espresso_messages',
1807
-            'action'  => 'edit_message_template',
1808
-            'id'      => $GRP_ID,
1809
-            'evt_id'  => $EVT_ID,
1810
-            'context' => $context,
1811
-            'extra'   => $preview_button,
1812
-        ];
1813
-        $this->_set_context_switcher($message_template_group, $context_switcher_args);
1814
-
1815
-
1816
-        // main box
1817
-        $this->_template_args['template_fields']                         = $template_fields;
1818
-        $this->_template_args['sidebar_box_id']                          = 'details';
1819
-        $this->_template_args['action']                                  = $action;
1820
-        $this->_template_args['context']                                 = $context;
1821
-        $this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1822
-        $this->_template_args['learn_more_about_message_templates_link'] =
1823
-            $this->_learn_more_about_message_templates_link();
1824
-
1825
-
1826
-        $this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1827
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1828
-            $message_template_group,
1829
-            $context,
1830
-            $context_label
1831
-        );
1832
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1833
-        $this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1834
-
1835
-        $this->_template_path = $this->_template_args['GRP_ID']
1836
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1837
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1838
-
1839
-        // send along EE_Message_Template_Group object for further template use.
1840
-        $this->_template_args['MTP'] = $message_template_group;
1841
-
1842
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1843
-            $this->_template_path,
1844
-            $this->_template_args,
1845
-            true
1846
-        );
1847
-
1848
-
1849
-        // finally, let's set the admin_page title
1850
-        $this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1851
-
1852
-
1853
-        // we need to take care of setting the shortcodes property for use elsewhere.
1854
-        $this->_set_shortcodes();
1855
-
1856
-
1857
-        // final template wrapper
1858
-        $this->display_admin_page_with_sidebar();
1859
-    }
1860
-
1861
-
1862
-    public function filter_tinymce_init($mceInit, $editor_id)
1863
-    {
1864
-        return $mceInit;
1865
-    }
1866
-
1867
-
1868
-    public function add_context_switcher()
1869
-    {
1870
-        return $this->_context_switcher;
1871
-    }
1872
-
1873
-
1874
-    /**
1875
-     * Adds the activation/deactivation toggle for the message template context.
1876
-     *
1877
-     * @param EE_Message_Template_Group $message_template_group
1878
-     * @param string                    $context
1879
-     * @param string                    $context_label
1880
-     * @return string
1881
-     * @throws DomainException
1882
-     * @throws EE_Error
1883
-     * @throws InvalidIdentifierException
1884
-     * @throws ReflectionException
1885
-     */
1886
-    protected function add_active_context_element(
1887
-        EE_Message_Template_Group $message_template_group,
1888
-        $context,
1889
-        $context_label
1890
-    ) {
1891
-        $template_args = [
1892
-            'context'                   => $context,
1893
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1894
-            'is_active'                 => $message_template_group->is_context_active($context),
1895
-            'on_off_action'             => $message_template_group->is_context_active($context)
1896
-                ? 'context-off'
1897
-                : 'context-on',
1898
-            'context_label'             => str_replace(['(', ')'], '', $context_label),
1899
-            'message_template_group_id' => $message_template_group->ID(),
1900
-        ];
1901
-        return EEH_Template::display_template(
1902
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1903
-            $template_args,
1904
-            true
1905
-        );
1906
-    }
1907
-
1908
-
1909
-    /**
1910
-     * Ajax callback for `toggle_context_template` ajax action.
1911
-     * Handles toggling the message context on or off.
1912
-     *
1913
-     * @throws EE_Error
1914
-     * @throws InvalidArgumentException
1915
-     * @throws InvalidDataTypeException
1916
-     * @throws InvalidIdentifierException
1917
-     * @throws InvalidInterfaceException
1918
-     */
1919
-    public function toggle_context_template()
1920
-    {
1921
-        $success = true;
1922
-        // check for required data
1923
-        if (
1924
-            ! (
1925
-                $this->request->requestParamIsSet('message_template_group_id')
1926
-                && $this->request->requestParamIsSet('context')
1927
-                && $this->request->requestParamIsSet('status')
1928
-            )
1929
-        ) {
1930
-            EE_Error::add_error(
1931
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1932
-                __FILE__,
1933
-                __FUNCTION__,
1934
-                __LINE__
1935
-            );
1936
-            $success = false;
1937
-        }
1938
-
1939
-        $nonce   = $this->request->getRequestParam('toggle_context_nonce', '');
1940
-        $context = $this->request->getRequestParam('context', '');
1941
-        $status  = $this->request->getRequestParam('status', '');
1942
-
1943
-        $this->_verify_nonce($nonce, "activate_{$context}_toggle_nonce");
1944
-
1945
-        if ($status !== 'off' && $status !== 'on') {
1946
-            EE_Error::add_error(
1947
-                sprintf(
1948
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1949
-                    $status
1950
-                ),
1951
-                __FILE__,
1952
-                __FUNCTION__,
1953
-                __LINE__
1954
-            );
1955
-            $success = false;
1956
-        }
1957
-        $message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, 'int');
1958
-        $message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1959
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1960
-            EE_Error::add_error(
1961
-                sprintf(
1962
-                    esc_html__(
1963
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1964
-                        'event_espresso'
1965
-                    ),
1966
-                    $message_template_group_id,
1967
-                    'EE_Message_Template_Group'
1968
-                ),
1969
-                __FILE__,
1970
-                __FUNCTION__,
1971
-                __LINE__
1972
-            );
1973
-            $success = false;
1974
-        }
1975
-        if ($success) {
1976
-            $success = $status === 'off'
1977
-                ? $message_template_group->deactivate_context($context)
1978
-                : $message_template_group->activate_context($context);
1979
-        }
1980
-        $this->_template_args['success'] = $success;
1981
-        $this->_return_json();
1982
-    }
1983
-
1984
-
1985
-    public function _add_form_element_before()
1986
-    {
1987
-        return '<form method="post" action="'
1988
-               . $this->_template_args['edit_message_template_form_url']
1989
-               . '" id="ee-msg-edit-frm">';
1990
-    }
1991
-
1992
-
1993
-    public function _add_form_element_after()
1994
-    {
1995
-        return '</form>';
1996
-    }
1997
-
1998
-
1999
-    /**
2000
-     * This executes switching the template pack for a message template.
2001
-     *
2002
-     * @throws EE_Error
2003
-     * @throws InvalidDataTypeException
2004
-     * @throws InvalidInterfaceException
2005
-     * @throws InvalidArgumentException
2006
-     * @throws ReflectionException
2007
-     * @since 4.5.0
2008
-     */
2009
-    public function switch_template_pack()
2010
-    {
2011
-
2012
-        $GRP_ID        = $this->request->getRequestParam('GRP_ID', 0, 'int');
2013
-        $template_pack = $this->request->getRequestParam('template_pack', '');
2014
-
2015
-        // verify we have needed values.
2016
-        if (empty($GRP_ID) || empty($template_pack)) {
2017
-            $this->_template_args['error'] = true;
2018
-            EE_Error::add_error(
2019
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
2020
-                __FILE__,
2021
-                __FUNCTION__,
2022
-                __LINE__
2023
-            );
2024
-        } else {
2025
-            // get template, set the new template_pack and then reset to default
2026
-            /** @var EE_Message_Template_Group $message_template_group */
2027
-            $message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
2028
-
2029
-            $message_template_group->set_template_pack_name($template_pack);
2030
-            $this->request->setRequestParam('msgr', $message_template_group->messenger());
2031
-            $this->request->setRequestParam('mt', $message_template_group->message_type());
2032
-
2033
-            $query_args = $this->_reset_to_default_template();
2034
-
2035
-            if (empty($query_args['id'])) {
2036
-                EE_Error::add_error(
2037
-                    esc_html__(
2038
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
2039
-                        'event_espresso'
2040
-                    ),
2041
-                    __FILE__,
2042
-                    __FUNCTION__,
2043
-                    __LINE__
2044
-                );
2045
-                $this->_template_args['error'] = true;
2046
-            } else {
2047
-                $template_label       = $message_template_group->get_template_pack()->label;
2048
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2049
-                EE_Error::add_success(
2050
-                    sprintf(
2051
-                        esc_html__(
2052
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2053
-                            'event_espresso'
2054
-                        ),
2055
-                        $template_label,
2056
-                        $template_pack_labels->template_pack
2057
-                    )
2058
-                );
2059
-                // generate the redirect url for js.
2060
-                $url = self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2061
-
2062
-                $this->_template_args['data']['redirect_url'] = $url;
2063
-                $this->_template_args['success']              = true;
2064
-            }
2065
-
2066
-            $this->_return_json();
2067
-        }
2068
-    }
2069
-
2070
-
2071
-    /**
2072
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2073
-     * they want.
2074
-     *
2075
-     * @access protected
2076
-     * @return array|void
2077
-     * @throws EE_Error
2078
-     * @throws InvalidArgumentException
2079
-     * @throws InvalidDataTypeException
2080
-     * @throws InvalidInterfaceException
2081
-     * @throws ReflectionException
2082
-     */
2083
-    protected function _reset_to_default_template()
2084
-    {
2085
-        $templates    = [];
2086
-        $GRP_ID       = $this->request->getRequestParam('GRP_ID', 0, 'int');
2087
-        $messenger    = $this->request->getRequestParam('msgr');
2088
-        $message_type = $this->request->getRequestParam('mt');
2089
-        // we need to make sure we've got the info we need.
2090
-        if (! ($GRP_ID && $messenger && $message_type)) {
2091
-            EE_Error::add_error(
2092
-                esc_html__(
2093
-                    '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.',
2094
-                    'event_espresso'
2095
-                ),
2096
-                __FILE__,
2097
-                __FUNCTION__,
2098
-                __LINE__
2099
-            );
2100
-        }
2101
-
2102
-        // all templates will be reset to whatever the defaults are
2103
-        // for the global template matching the messenger and message type.
2104
-        $success = ! empty($GRP_ID);
2105
-
2106
-        if ($success) {
2107
-            // let's first determine if the incoming template is a global template,
2108
-            // if it isn't then we need to get the global template matching messenger and message type.
2109
-            // $MTPG = $this->getMtgModel()->get_one_by_ID( $GRP_ID );
2110
-
2111
-
2112
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2113
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
2114
-
2115
-            if ($success) {
2116
-                // if successfully deleted, lets generate the new ones.
2117
-                // Note. We set GLOBAL to true, because resets on ANY template
2118
-                // will use the related global template defaults for regeneration.
2119
-                // This means that if a custom template is reset it resets to whatever the related global template is.
2120
-                // HOWEVER, we DO keep the template pack and template variation set
2121
-                // for the current custom template when resetting.
2122
-                $templates = $this->_generate_new_templates($messenger, $message_type, $GRP_ID, true);
2123
-            }
2124
-        }
2125
-
2126
-        // any error messages?
2127
-        if (! $success) {
2128
-            EE_Error::add_error(
2129
-                esc_html__(
2130
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
2131
-                    'event_espresso'
2132
-                ),
2133
-                __FILE__,
2134
-                __FUNCTION__,
2135
-                __LINE__
2136
-            );
2137
-        }
2138
-
2139
-        // all good, let's add a success message!
2140
-        if ($success && ! empty($templates)) {
2141
-            // the info for the template we generated is the first element in the returned array
2142
-            EE_Error::overwrite_success();
2143
-            EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
2144
-        }
2145
-
2146
-
2147
-        $query_args = [
2148
-            'id'      => isset($templates['GRP_ID']) ? $templates['GRP_ID'] : null,
2149
-            'context' => isset($templates['MTP_context']) ? $templates['MTP_context'] : null,
2150
-            'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2151
-        ];
2152
-
2153
-        // if called via ajax then we return query args otherwise redirect
2154
-        if ($this->request->isAjax()) {
2155
-            return $query_args;
2156
-        }
2157
-        $this->_redirect_after_action(false, '', '', $query_args, true);
2158
-    }
2159
-
2160
-
2161
-    /**
2162
-     * Retrieve and set the message preview for display.
2163
-     *
2164
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2165
-     * @return string
2166
-     * @throws ReflectionException
2167
-     * @throws EE_Error
2168
-     * @throws InvalidArgumentException
2169
-     * @throws InvalidDataTypeException
2170
-     * @throws InvalidInterfaceException
2171
-     */
2172
-    public function _preview_message($send = false)
2173
-    {
2174
-        // first make sure we've got the necessary parameters
2175
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2176
-        if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
2177
-            EE_Error::add_error(
2178
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2179
-                __FILE__,
2180
-                __FUNCTION__,
2181
-                __LINE__
2182
-            );
2183
-        }
2184
-
2185
-        $context = $this->request->getRequestParam('context');
2186
-        // get the preview!
2187
-        $preview = EED_Messages::preview_message(
2188
-            $this->_active_message_type_name,
2189
-            $context,
2190
-            $this->_active_messenger_name,
2191
-            $send
2192
-        );
2193
-
2194
-        if ($send) {
2195
-            return $preview;
2196
-        }
2197
-
2198
-        // if we have an evt_id set on the request, use it.
2199
-        $EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
2200
-
2201
-        // let's add a button to go back to the edit view
2202
-        $query_args             = [
2203
-            'id'      => $GRP_ID,
2204
-            'evt_id'  => $EVT_ID,
2205
-            'context' => $context,
2206
-            'action'  => 'edit_message_template',
2207
-        ];
2208
-        $go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2209
-        $preview_button         = '<a href="'
2210
-                                  . $go_back_url
2211
-                                  . '" class="button-secondary messages-preview-go-back-button">'
2212
-                                  . esc_html__('Go Back to Edit', 'event_espresso')
2213
-                                  . '</a>';
2214
-        $message_types          = $this->get_installed_message_types();
2215
-        $active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
2216
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2217
-            ? ucwords($active_messenger->label['singular'])
2218
-            : esc_html__('Unknown Messenger', 'event_espresso');
2219
-        // let's provide a helpful title for context
2220
-        $preview_title = sprintf(
2221
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2222
-            $active_messenger_label,
2223
-            ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2224
-        );
2225
-        if (empty($preview)) {
2226
-            $this->noEventsErrorMessage();
2227
-        }
2228
-        // setup display of preview.
2229
-        $this->_admin_page_title                    = $preview_title;
2230
-        $this->_template_args['admin_page_title']   = $preview_title;
2231
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2232
-        $this->_template_args['data']['force_json'] = true;
2233
-
2234
-        return '';
2235
-    }
2236
-
2237
-
2238
-    /**
2239
-     * Used to set an error if there are no events available for generating a preview/test send.
2240
-     *
2241
-     * @param bool $test_send Whether the error should be generated for the context of a test send.
2242
-     */
2243
-    protected function noEventsErrorMessage($test_send = false)
2244
-    {
2245
-        $events_url = parent::add_query_args_and_nonce(
2246
-            [
2247
-                'action' => 'default',
2248
-                'page'   => 'espresso_events',
2249
-            ],
2250
-            admin_url('admin.php')
2251
-        );
2252
-        $message    = $test_send
2253
-            ? esc_html__(
2254
-                '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!',
2255
-                'event_espresso'
2256
-            )
2257
-            : esc_html__(
2258
-                '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!',
2259
-                'event_espresso'
2260
-            );
2261
-
2262
-        EE_Error::add_attention(
2263
-            sprintf(
2264
-                $message,
2265
-                "<a href='{$events_url}'>",
2266
-                '</a>'
2267
-            )
2268
-        );
2269
-    }
2270
-
2271
-
2272
-    /**
2273
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2274
-     * gets called automatically.
2275
-     *
2276
-     * @return void
2277
-     * @throws EE_Error
2278
-     * @since 4.5.0
2279
-     *
2280
-     */
2281
-    protected function _display_preview_message()
2282
-    {
2283
-        $this->display_admin_page_with_no_sidebar();
2284
-    }
2285
-
2286
-
2287
-    /**
2288
-     * registers metaboxes that should show up on the "edit_message_template" page
2289
-     *
2290
-     * @access protected
2291
-     * @return void
2292
-     */
2293
-    protected function _register_edit_meta_boxes()
2294
-    {
2295
-        add_meta_box(
2296
-            'mtp_valid_shortcodes',
2297
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2298
-            [$this, 'shortcode_meta_box'],
2299
-            $this->_current_screen->id,
2300
-            'side'
2301
-        );
2302
-        add_meta_box(
2303
-            'mtp_extra_actions',
2304
-            esc_html__('Extra Actions', 'event_espresso'),
2305
-            [$this, 'extra_actions_meta_box'],
2306
-            $this->_current_screen->id,
2307
-            'side',
2308
-            'high'
2309
-        );
2310
-        add_meta_box(
2311
-            'mtp_templates',
2312
-            esc_html__('Template Styles', 'event_espresso'),
2313
-            [$this, 'template_pack_meta_box'],
2314
-            $this->_current_screen->id,
2315
-            'side',
2316
-            'high'
2317
-        );
2318
-    }
2319
-
2320
-
2321
-    /**
2322
-     * metabox content for all template pack and variation selection.
2323
-     *
2324
-     * @return void
2325
-     * @throws DomainException
2326
-     * @throws EE_Error
2327
-     * @throws InvalidArgumentException
2328
-     * @throws ReflectionException
2329
-     * @throws InvalidDataTypeException
2330
-     * @throws InvalidInterfaceException
2331
-     * @since 4.5.0
2332
-     */
2333
-    public function template_pack_meta_box()
2334
-    {
2335
-        $this->_set_message_template_group();
2336
-
2337
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2338
-
2339
-        $tp_select_values = [];
2340
-
2341
-        foreach ($tp_collection as $tp) {
2342
-            // only include template packs that support this messenger and message type!
2343
-            $supports = $tp->get_supports();
2344
-            if (
2345
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2346
-                || ! in_array(
2347
-                    $this->_message_template_group->message_type(),
2348
-                    $supports[ $this->_message_template_group->messenger() ],
2349
-                    true
2350
-                )
2351
-            ) {
2352
-                // not supported
2353
-                continue;
2354
-            }
2355
-
2356
-            $tp_select_values[] = [
2357
-                'text' => $tp->label,
2358
-                'id'   => $tp->dbref,
2359
-            ];
2360
-        }
2361
-
2362
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2363
-        // the default template pack.  This still allows for the odd template pack to override.
2364
-        if (empty($tp_select_values)) {
2365
-            $tp_select_values[] = [
2366
-                'text' => esc_html__('Default', 'event_espresso'),
2367
-                'id'   => 'default',
2368
-            ];
2369
-        }
2370
-
2371
-        // setup variation select values for the currently selected template.
2372
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
2373
-            $this->_message_template_group->messenger(),
2374
-            $this->_message_template_group->message_type()
2375
-        );
2376
-        $variations_select_values = [];
2377
-        foreach ($variations as $variation => $label) {
2378
-            $variations_select_values[] = [
2379
-                'text' => $label,
2380
-                'id'   => $variation,
2381
-            ];
2382
-        }
2383
-
2384
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2385
-
2386
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2387
-            'MTP_template_pack',
2388
-            $tp_select_values,
2389
-            $this->_message_template_group->get_template_pack_name()
2390
-        );
2391
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
2392
-            'MTP_template_variation',
2393
-            $variations_select_values,
2394
-            $this->_message_template_group->get_template_pack_variation()
2395
-        );
2396
-        $template_args['template_pack_label']            = $template_pack_labels->template_pack;
2397
-        $template_args['template_variation_label']       = $template_pack_labels->template_variation;
2398
-        $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2399
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2400
-
2401
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2402
-
2403
-        EEH_Template::display_template($template, $template_args);
2404
-    }
2405
-
2406
-
2407
-    /**
2408
-     * This meta box holds any extra actions related to Message Templates
2409
-     * For now, this includes Resetting templates to defaults and sending a test email.
2410
-     *
2411
-     * @access  public
2412
-     * @return void
2413
-     * @throws EE_Error
2414
-     */
2415
-    public function extra_actions_meta_box()
2416
-    {
2417
-        $template_form_fields = [];
2418
-
2419
-        $extra_args = [
2420
-            'msgr'   => $this->_message_template_group->messenger(),
2421
-            'mt'     => $this->_message_template_group->message_type(),
2422
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2423
-        ];
2424
-        // first we need to see if there are any fields
2425
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2426
-
2427
-        if (! empty($fields)) {
2428
-            // yup there be fields
2429
-            foreach ($fields as $field => $config) {
2430
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2431
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2432
-                $default  = isset($config['default']) ? $config['default'] : '';
2433
-                $default  = isset($config['value']) ? $config['value'] : $default;
2434
-
2435
-                // if type is hidden and the value is empty
2436
-                // something may have gone wrong so let's correct with the defaults
2437
-                $fix                = $config['input'] === 'hidden'
2438
-                                      && isset($existing[ $field ])
2439
-                                      && empty($existing[ $field ])
2440
-                    ? $default
2441
-                    : '';
2442
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2443
-                    ? $existing[ $field ]
2444
-                    : $fix;
2445
-
2446
-                $template_form_fields[ $field_id ] = [
2447
-                    'name'       => 'test_settings_fld[' . $field . ']',
2448
-                    'label'      => $config['label'],
2449
-                    'input'      => $config['input'],
2450
-                    'type'       => $config['type'],
2451
-                    'required'   => $config['required'],
2452
-                    'validation' => $config['validation'],
2453
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2454
-                    'css_class'  => $config['css_class'],
2455
-                    'options'    => isset($config['options']) ? $config['options'] : [],
2456
-                    'default'    => $default,
2457
-                    'format'     => $config['format'],
2458
-                ];
2459
-            }
2460
-        }
2461
-
2462
-        $test_settings_html = ! empty($template_form_fields)
2463
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2464
-            : '';
2465
-
2466
-        // print out $test_settings_fields
2467
-        if (! empty($test_settings_html)) {
2468
-            $test_settings_html .= '<input type="submit" class="button-primary mtp-test-button alignright" ';
2469
-            $test_settings_html .= 'name="test_button" value="';
2470
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2471
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2472
-        }
2473
-
2474
-        // and button
2475
-        $test_settings_html .= '<p>';
2476
-        $test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2477
-        $test_settings_html .= '</p>';
2478
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2479
-        $test_settings_html .= $this->get_action_link_or_button(
2480
-            'reset_to_default',
2481
-            'reset',
2482
-            $extra_args,
2483
-            'button-primary reset-default-button'
2484
-        );
2485
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2486
-        echo $test_settings_html; // already escaped
2487
-    }
2488
-
2489
-
2490
-    /**
2491
-     * This returns the shortcode selector skeleton for a given context and field.
2492
-     *
2493
-     * @param string $field           The name of the field retrieving shortcodes for.
2494
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2495
-     * @return string
2496
-     * @throws DomainException
2497
-     * @throws EE_Error
2498
-     * @throws InvalidArgumentException
2499
-     * @throws ReflectionException
2500
-     * @throws InvalidDataTypeException
2501
-     * @throws InvalidInterfaceException
2502
-     * @since 4.9.rc.000
2503
-     */
2504
-    protected function _get_shortcode_selector($field, $linked_input_id)
2505
-    {
2506
-        $template_args = [
2507
-            'shortcodes'      => $this->_get_shortcodes([$field]),
2508
-            'fieldname'       => $field,
2509
-            'linked_input_id' => $linked_input_id,
2510
-        ];
2511
-
2512
-        return EEH_Template::display_template(
2513
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2514
-            $template_args,
2515
-            true
2516
-        );
2517
-    }
2518
-
2519
-
2520
-    /**
2521
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2522
-     * page)
2523
-     *
2524
-     * @access public
2525
-     * @return void
2526
-     * @throws EE_Error
2527
-     * @throws InvalidArgumentException
2528
-     * @throws ReflectionException
2529
-     * @throws InvalidDataTypeException
2530
-     * @throws InvalidInterfaceException
2531
-     */
2532
-    public function shortcode_meta_box()
2533
-    {
2534
-        $shortcodes = $this->_get_shortcodes([], false);
2535
-        // just make sure the shortcodes property is set
2536
-        // $messenger = $this->_message_template_group->messenger_obj();
2537
-        // now let's set the content depending on the status of the shortcodes array
2538
-        if (empty($shortcodes)) {
2539
-            echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2540
-            return;
2541
-        }
2542
-        ?>
19
+	/**
20
+	 * @var EEM_Message
21
+	 */
22
+	private $MSG_MODEL;
23
+
24
+	/**
25
+	 * @var EEM_Message_Template
26
+	 */
27
+	private $MTP_MODEL;
28
+
29
+	/**
30
+	 * @var EEM_Message_Template_Group
31
+	 */
32
+	private $MTG_MODEL;
33
+
34
+	/**
35
+	 * @var EE_Message_Resource_Manager $_message_resource_manager
36
+	 */
37
+	protected $_message_resource_manager;
38
+
39
+	/**
40
+	 * @var string
41
+	 */
42
+	protected $_active_message_type_name = '';
43
+
44
+	/**
45
+	 * @var string
46
+	 */
47
+	protected $_active_messenger_name = '';
48
+
49
+	/**
50
+	 * @var EE_messenger $_active_messenger
51
+	 */
52
+	protected $_active_messenger;
53
+
54
+	protected $_activate_meta_box_type;
55
+
56
+	protected $_current_message_meta_box;
57
+
58
+	protected $_current_message_meta_box_object;
59
+
60
+	protected $_context_switcher;
61
+
62
+	protected $_shortcodes           = [];
63
+
64
+	protected $_active_messengers    = [];
65
+
66
+	protected $_active_message_types = [];
67
+
68
+	/**
69
+	 * @var EE_Message_Template_Group $_message_template_group
70
+	 */
71
+	protected $_message_template_group;
72
+
73
+	protected $_m_mt_settings = [];
74
+
75
+
76
+	/**
77
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
78
+	 * IF there is no group then it gets automatically set to the Default template pack.
79
+	 *
80
+	 * @since 4.5.0
81
+	 *
82
+	 * @var EE_Messages_Template_Pack
83
+	 */
84
+	protected $_template_pack;
85
+
86
+
87
+	/**
88
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
89
+	 * group is.  If there is no group then it automatically gets set to default.
90
+	 *
91
+	 * @since 4.5.0
92
+	 *
93
+	 * @var string
94
+	 */
95
+	protected $_variation;
96
+
97
+
98
+	/**
99
+	 * @param bool $routing
100
+	 * @throws EE_Error
101
+	 * @throws ReflectionException
102
+	 */
103
+	public function __construct($routing = true)
104
+	{
105
+		// make sure messages autoloader is running
106
+		EED_Messages::set_autoloaders();
107
+		parent::__construct($routing);
108
+	}
109
+
110
+
111
+	/**
112
+	 * @return EEM_Message
113
+	 * @throws EE_Error
114
+	 */
115
+	public function getMsgModel()
116
+	{
117
+		if (! $this->MSG_MODEL instanceof EEM_Message) {
118
+			$this->MSG_MODEL = EEM_Message::instance();
119
+		}
120
+		return $this->MSG_MODEL;
121
+	}
122
+
123
+
124
+	/**
125
+	 * @return EEM_Message_Template
126
+	 * @throws EE_Error
127
+	 */
128
+	public function getMtpModel()
129
+	{
130
+		if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
131
+			$this->MTP_MODEL = EEM_Message_Template::instance();
132
+		}
133
+		return $this->MTP_MODEL;
134
+	}
135
+
136
+
137
+	/**
138
+	 * @return EEM_Message_Template_Group
139
+	 * @throws EE_Error
140
+	 */
141
+	public function getMtgModel()
142
+	{
143
+		if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
144
+			$this->MTG_MODEL = EEM_Message_Template_Group::instance();
145
+		}
146
+		return $this->MTG_MODEL;
147
+	}
148
+
149
+
150
+	/**
151
+	 * @throws EE_Error
152
+	 * @throws ReflectionException
153
+	 */
154
+	protected function _init_page_props()
155
+	{
156
+		$this->page_slug        = EE_MSG_PG_SLUG;
157
+		$this->page_label       = esc_html__('Messages Settings', 'event_espresso');
158
+		$this->_admin_base_url  = EE_MSG_ADMIN_URL;
159
+		$this->_admin_base_path = EE_MSG_ADMIN;
160
+
161
+		$this->_active_messenger_name    = $this->request->getRequestParam('messenger', '');
162
+		$this->_active_message_type_name = $this->request->getRequestParam('message_type', '');
163
+
164
+		$this->_load_message_resource_manager();
165
+	}
166
+
167
+
168
+	/**
169
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
170
+	 *
171
+	 * @throws EE_Error
172
+	 * @throws InvalidDataTypeException
173
+	 * @throws InvalidInterfaceException
174
+	 * @throws InvalidArgumentException
175
+	 * @throws ReflectionException
176
+	 */
177
+	protected function _load_message_resource_manager()
178
+	{
179
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
180
+	}
181
+
182
+
183
+	/**
184
+	 * @return array
185
+	 * @throws EE_Error
186
+	 * @throws InvalidArgumentException
187
+	 * @throws InvalidDataTypeException
188
+	 * @throws InvalidInterfaceException
189
+	 * @deprecated 4.9.9.rc.014
190
+	 */
191
+	public function get_messengers_for_list_table()
192
+	{
193
+		EE_Error::doing_it_wrong(
194
+			__METHOD__,
195
+			sprintf(
196
+				esc_html__(
197
+					'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',
198
+					'event_espresso'
199
+				),
200
+				'Messages_Admin_Page::get_messengers_select_input()'
201
+			),
202
+			'4.9.9.rc.014'
203
+		);
204
+
205
+		$m_values          = [];
206
+		$active_messengers = $this->getMsgModel()->get_all(['group_by' => 'MSG_messenger']);
207
+		// setup messengers for selects
208
+		$i = 1;
209
+		foreach ($active_messengers as $active_messenger) {
210
+			if ($active_messenger instanceof EE_Message) {
211
+				$m_values[ $i ]['id']   = $active_messenger->messenger();
212
+				$m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
213
+				$i++;
214
+			}
215
+		}
216
+
217
+		return $m_values;
218
+	}
219
+
220
+
221
+	/**
222
+	 * @return array
223
+	 * @throws EE_Error
224
+	 * @throws InvalidArgumentException
225
+	 * @throws InvalidDataTypeException
226
+	 * @throws InvalidInterfaceException
227
+	 * @deprecated 4.9.9.rc.014
228
+	 */
229
+	public function get_message_types_for_list_table()
230
+	{
231
+		EE_Error::doing_it_wrong(
232
+			__METHOD__,
233
+			sprintf(
234
+				esc_html__(
235
+					'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',
236
+					'event_espresso'
237
+				),
238
+				'Messages_Admin_Page::get_message_types_select_input()'
239
+			),
240
+			'4.9.9.rc.014'
241
+		);
242
+
243
+		$mt_values       = [];
244
+		$active_messages = $this->getMsgModel()->get_all(['group_by' => 'MSG_message_type']);
245
+		$i               = 1;
246
+		foreach ($active_messages as $active_message) {
247
+			if ($active_message instanceof EE_Message) {
248
+				$mt_values[ $i ]['id']   = $active_message->message_type();
249
+				$mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
250
+				$i++;
251
+			}
252
+		}
253
+
254
+		return $mt_values;
255
+	}
256
+
257
+
258
+	/**
259
+	 * @return array
260
+	 * @throws EE_Error
261
+	 * @throws InvalidArgumentException
262
+	 * @throws InvalidDataTypeException
263
+	 * @throws InvalidInterfaceException
264
+	 * @deprecated 4.9.9.rc.014
265
+	 */
266
+	public function get_contexts_for_message_types_for_list_table()
267
+	{
268
+		EE_Error::doing_it_wrong(
269
+			__METHOD__,
270
+			sprintf(
271
+				esc_html__(
272
+					'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',
273
+					'event_espresso'
274
+				),
275
+				'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
276
+			),
277
+			'4.9.9.rc.014'
278
+		);
279
+
280
+		$contexts                = [];
281
+		$active_message_contexts = $this->getMsgModel()->get_all(['group_by' => 'MSG_context']);
282
+		foreach ($active_message_contexts as $active_message) {
283
+			if ($active_message instanceof EE_Message) {
284
+				$message_type = $active_message->message_type_object();
285
+				if ($message_type instanceof EE_message_type) {
286
+					$message_type_contexts = $message_type->get_contexts();
287
+					foreach ($message_type_contexts as $context => $context_details) {
288
+						$contexts[ $context ] = $context_details['label'];
289
+					}
290
+				}
291
+			}
292
+		}
293
+
294
+		return $contexts;
295
+	}
296
+
297
+
298
+	/**
299
+	 * Generate select input with provided messenger options array.
300
+	 *
301
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
302
+	 *                                 labels.
303
+	 * @return string
304
+	 * @throws EE_Error
305
+	 */
306
+	public function get_messengers_select_input($messenger_options)
307
+	{
308
+		// if empty or just one value then just return an empty string
309
+		if (
310
+			empty($messenger_options)
311
+			|| ! is_array($messenger_options)
312
+			|| count($messenger_options) === 1
313
+		) {
314
+			return '';
315
+		}
316
+		// merge in default
317
+		$messenger_options = array_merge(
318
+			['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
319
+			$messenger_options
320
+		);
321
+		$input             = new EE_Select_Input(
322
+			$messenger_options,
323
+			[
324
+				'html_name'  => 'ee_messenger_filter_by',
325
+				'html_id'    => 'ee_messenger_filter_by',
326
+				'html_class' => 'wide',
327
+				'default'    => $this->request->getRequestParam('ee_messenger_filter_by', 'none_selected', 'title'),
328
+			]
329
+		);
330
+
331
+		return $input->get_html_for_input();
332
+	}
333
+
334
+
335
+	/**
336
+	 * Generate select input with provided message type options array.
337
+	 *
338
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
339
+	 *                                    message type labels
340
+	 * @return string
341
+	 * @throws EE_Error
342
+	 */
343
+	public function get_message_types_select_input($message_type_options)
344
+	{
345
+		// if empty or count of options is 1 then just return an empty string
346
+		if (
347
+			empty($message_type_options)
348
+			|| ! is_array($message_type_options)
349
+			|| count($message_type_options) === 1
350
+		) {
351
+			return '';
352
+		}
353
+		// merge in default
354
+		$message_type_options = array_merge(
355
+			['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
356
+			$message_type_options
357
+		);
358
+		$input                = new EE_Select_Input(
359
+			$message_type_options,
360
+			[
361
+				'html_name'  => 'ee_message_type_filter_by',
362
+				'html_id'    => 'ee_message_type_filter_by',
363
+				'html_class' => 'wide',
364
+				'default'    => $this->request->getRequestParam('ee_message_type_filter_by', 'none_selected', 'title'),
365
+			]
366
+		);
367
+
368
+		return $input->get_html_for_input();
369
+	}
370
+
371
+
372
+	/**
373
+	 * Generate select input with provide message type contexts array.
374
+	 *
375
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
376
+	 *                               context label.
377
+	 * @return string
378
+	 * @throws EE_Error
379
+	 */
380
+	public function get_contexts_for_message_types_select_input($context_options)
381
+	{
382
+		// if empty or count of options is one then just return empty string
383
+		if (
384
+			empty($context_options)
385
+			|| ! is_array($context_options)
386
+			|| count($context_options) === 1
387
+		) {
388
+			return '';
389
+		}
390
+		// merge in default
391
+		$context_options = array_merge(
392
+			['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
393
+			$context_options
394
+		);
395
+		$input           = new EE_Select_Input(
396
+			$context_options,
397
+			[
398
+				'html_name'  => 'ee_context_filter_by',
399
+				'html_id'    => 'ee_context_filter_by',
400
+				'html_class' => 'wide',
401
+				'default'    => $this->request->getRequestParam('ee_context_filter_by', 'none_selected', 'title'),
402
+			]
403
+		);
404
+
405
+		return $input->get_html_for_input();
406
+	}
407
+
408
+
409
+	protected function _ajax_hooks()
410
+	{
411
+		add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
412
+		add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
413
+		add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
414
+		add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
415
+		add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
416
+		add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
417
+	}
418
+
419
+
420
+	protected function _define_page_props()
421
+	{
422
+		$this->_admin_page_title = $this->page_label;
423
+		$this->_labels           = [
424
+			'buttons'    => [
425
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
426
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
427
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
428
+			],
429
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
430
+		];
431
+	}
432
+
433
+
434
+	/**
435
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
436
+	 *
437
+	 * @access protected
438
+	 * @return void
439
+	 */
440
+	protected function _set_page_routes()
441
+	{
442
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
443
+		$GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
444
+		$MSG_ID = $this->request->getRequestParam('MSG_ID', 0, 'int');
445
+
446
+		$this->_page_routes = [
447
+			'default'                          => [
448
+				'func'       => '_message_queue_list_table',
449
+				'capability' => 'ee_read_global_messages',
450
+			],
451
+			'global_mtps'                      => [
452
+				'func'       => '_ee_default_messages_overview_list_table',
453
+				'capability' => 'ee_read_global_messages',
454
+			],
455
+			'custom_mtps'                      => [
456
+				'func'       => '_custom_mtps_preview',
457
+				'capability' => 'ee_read_messages',
458
+			],
459
+			'add_new_message_template'         => [
460
+				'func'       => '_add_message_template',
461
+				'capability' => 'ee_edit_messages',
462
+				'noheader'   => true,
463
+			],
464
+			'edit_message_template'            => [
465
+				'func'       => '_edit_message_template',
466
+				'capability' => 'ee_edit_message',
467
+				'obj_id'     => $GRP_ID,
468
+			],
469
+			'preview_message'                  => [
470
+				'func'               => '_preview_message',
471
+				'capability'         => 'ee_read_message',
472
+				'obj_id'             => $GRP_ID,
473
+				'noheader'           => true,
474
+				'headers_sent_route' => 'display_preview_message',
475
+			],
476
+			'display_preview_message'          => [
477
+				'func'       => '_display_preview_message',
478
+				'capability' => 'ee_read_message',
479
+				'obj_id'     => $GRP_ID,
480
+			],
481
+			'insert_message_template'          => [
482
+				'func'       => '_insert_or_update_message_template',
483
+				'capability' => 'ee_edit_messages',
484
+				'args'       => ['new' => true],
485
+				'noheader'   => true,
486
+			],
487
+			'update_message_template'          => [
488
+				'func'       => '_insert_or_update_message_template',
489
+				'capability' => 'ee_edit_message',
490
+				'obj_id'     => $GRP_ID,
491
+				'args'       => ['new' => false],
492
+				'noheader'   => true,
493
+			],
494
+			'trash_message_template'           => [
495
+				'func'       => '_trash_or_restore_message_template',
496
+				'capability' => 'ee_delete_message',
497
+				'obj_id'     => $GRP_ID,
498
+				'args'       => ['trash' => true, 'all' => true],
499
+				'noheader'   => true,
500
+			],
501
+			'trash_message_template_context'   => [
502
+				'func'       => '_trash_or_restore_message_template',
503
+				'capability' => 'ee_delete_message',
504
+				'obj_id'     => $GRP_ID,
505
+				'args'       => ['trash' => true],
506
+				'noheader'   => true,
507
+			],
508
+			'restore_message_template'         => [
509
+				'func'       => '_trash_or_restore_message_template',
510
+				'capability' => 'ee_delete_message',
511
+				'obj_id'     => $GRP_ID,
512
+				'args'       => ['trash' => false, 'all' => true],
513
+				'noheader'   => true,
514
+			],
515
+			'restore_message_template_context' => [
516
+				'func'       => '_trash_or_restore_message_template',
517
+				'capability' => 'ee_delete_message',
518
+				'obj_id'     => $GRP_ID,
519
+				'args'       => ['trash' => false],
520
+				'noheader'   => true,
521
+			],
522
+			'delete_message_template'          => [
523
+				'func'       => '_delete_message_template',
524
+				'capability' => 'ee_delete_message',
525
+				'obj_id'     => $GRP_ID,
526
+				'noheader'   => true,
527
+			],
528
+			'reset_to_default'                 => [
529
+				'func'       => '_reset_to_default_template',
530
+				'capability' => 'ee_edit_message',
531
+				'obj_id'     => $GRP_ID,
532
+				'noheader'   => true,
533
+			],
534
+			'settings'                         => [
535
+				'func'       => '_settings',
536
+				'capability' => 'manage_options',
537
+			],
538
+			'update_global_settings'           => [
539
+				'func'       => '_update_global_settings',
540
+				'capability' => 'manage_options',
541
+				'noheader'   => true,
542
+			],
543
+			'generate_now'                     => [
544
+				'func'       => '_generate_now',
545
+				'capability' => 'ee_send_message',
546
+				'noheader'   => true,
547
+			],
548
+			'generate_and_send_now'            => [
549
+				'func'       => '_generate_and_send_now',
550
+				'capability' => 'ee_send_message',
551
+				'noheader'   => true,
552
+			],
553
+			'queue_for_resending'              => [
554
+				'func'       => '_queue_for_resending',
555
+				'capability' => 'ee_send_message',
556
+				'noheader'   => true,
557
+			],
558
+			'send_now'                         => [
559
+				'func'       => '_send_now',
560
+				'capability' => 'ee_send_message',
561
+				'noheader'   => true,
562
+			],
563
+			'delete_ee_message'                => [
564
+				'func'       => '_delete_ee_messages',
565
+				'capability' => 'ee_delete_messages',
566
+				'noheader'   => true,
567
+			],
568
+			'delete_ee_messages'               => [
569
+				'func'       => '_delete_ee_messages',
570
+				'capability' => 'ee_delete_messages',
571
+				'noheader'   => true,
572
+				'obj_id'     => $MSG_ID,
573
+			],
574
+		];
575
+	}
576
+
577
+
578
+	protected function _set_page_config()
579
+	{
580
+		$this->_page_config = [
581
+			'default'                  => [
582
+				'nav'           => [
583
+					'label' => esc_html__('Message Activity', 'event_espresso'),
584
+					'order' => 10,
585
+				],
586
+				'list_table'    => 'EE_Message_List_Table',
587
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
588
+				'require_nonce' => false,
589
+			],
590
+			'global_mtps'              => [
591
+				'nav'           => [
592
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
593
+					'order' => 20,
594
+				],
595
+				'list_table'    => 'Messages_Template_List_Table',
596
+				'help_tabs'     => [
597
+					'messages_overview_help_tab'                                => [
598
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
599
+						'filename' => 'messages_overview',
600
+					],
601
+					'messages_overview_messages_table_column_headings_help_tab' => [
602
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
603
+						'filename' => 'messages_overview_table_column_headings',
604
+					],
605
+					'messages_overview_messages_filters_help_tab'               => [
606
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
607
+						'filename' => 'messages_overview_filters',
608
+					],
609
+					'messages_overview_messages_views_help_tab'                 => [
610
+						'title'    => esc_html__('Message Views', 'event_espresso'),
611
+						'filename' => 'messages_overview_views',
612
+					],
613
+					'message_overview_message_types_help_tab'                   => [
614
+						'title'    => esc_html__('Message Types', 'event_espresso'),
615
+						'filename' => 'messages_overview_types',
616
+					],
617
+					'messages_overview_messengers_help_tab'                     => [
618
+						'title'    => esc_html__('Messengers', 'event_espresso'),
619
+						'filename' => 'messages_overview_messengers',
620
+					],
621
+				],
622
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
623
+				// 'help_tour'     => array('Messages_Overview_Help_Tour'),
624
+				'require_nonce' => false,
625
+			],
626
+			'custom_mtps'              => [
627
+				'nav'           => [
628
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
629
+					'order' => 30,
630
+				],
631
+				'help_tabs'     => [],
632
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
633
+				// 'help_tour'     => array(),
634
+				'require_nonce' => false,
635
+			],
636
+			'add_new_message_template' => [
637
+				'nav'           => [
638
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
639
+					'order'      => 5,
640
+					'persistent' => false,
641
+				],
642
+				'require_nonce' => false,
643
+			],
644
+			'edit_message_template'    => [
645
+				'labels'        => [
646
+					'buttons'    => [
647
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
648
+					],
649
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
650
+				],
651
+				'nav'           => [
652
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
653
+					'order'      => 5,
654
+					'persistent' => false,
655
+					'url'        => '',
656
+				],
657
+				'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
658
+				'has_metaboxes' => true,
659
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
660
+				// 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
661
+				'help_tabs'     => [
662
+					'edit_message_template'            => [
663
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
664
+						'callback' => 'edit_message_template_help_tab',
665
+					],
666
+					'message_templates_help_tab'       => [
667
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
668
+						'filename' => 'messages_templates',
669
+					],
670
+					'message_template_shortcodes'      => [
671
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
672
+						'callback' => 'message_template_shortcodes_help_tab',
673
+					],
674
+					'message_preview_help_tab'         => [
675
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
676
+						'filename' => 'messages_preview',
677
+					],
678
+					'messages_overview_other_help_tab' => [
679
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
680
+						'filename' => 'messages_overview_other',
681
+					],
682
+				],
683
+				'require_nonce' => false,
684
+			],
685
+			'display_preview_message'  => [
686
+				'nav'           => [
687
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
688
+					'order'      => 5,
689
+					'url'        => '',
690
+					'persistent' => false,
691
+				],
692
+				'help_tabs'     => [
693
+					'preview_message' => [
694
+						'title'    => esc_html__('About Previews', 'event_espresso'),
695
+						'callback' => 'preview_message_help_tab',
696
+					],
697
+				],
698
+				'require_nonce' => false,
699
+			],
700
+			'settings'                 => [
701
+				'nav'           => [
702
+					'label' => esc_html__('Settings', 'event_espresso'),
703
+					'order' => 40,
704
+				],
705
+				'metaboxes'     => ['_messages_settings_metaboxes'],
706
+				'help_tabs'     => [
707
+					'messages_settings_help_tab'               => [
708
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
709
+						'filename' => 'messages_settings',
710
+					],
711
+					'messages_settings_message_types_help_tab' => [
712
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
713
+						'filename' => 'messages_settings_message_types',
714
+					],
715
+					'messages_settings_messengers_help_tab'    => [
716
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
717
+						'filename' => 'messages_settings_messengers',
718
+					],
719
+				],
720
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
721
+				// 'help_tour'     => array('Messages_Settings_Help_Tour'),
722
+				'require_nonce' => false,
723
+			],
724
+		];
725
+	}
726
+
727
+
728
+	protected function _add_screen_options()
729
+	{
730
+		// todo
731
+	}
732
+
733
+
734
+	protected function _add_screen_options_global_mtps()
735
+	{
736
+		/**
737
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
738
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
739
+		 */
740
+		$page_title              = $this->_admin_page_title;
741
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
742
+		$this->_per_page_screen_option();
743
+		$this->_admin_page_title = $page_title;
744
+	}
745
+
746
+
747
+	protected function _add_screen_options_default()
748
+	{
749
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
750
+		$this->_per_page_screen_option();
751
+	}
752
+
753
+
754
+	// none of the below group are currently used for Messages
755
+	protected function _add_feature_pointers()
756
+	{
757
+	}
758
+
759
+
760
+	public function admin_init()
761
+	{
762
+	}
763
+
764
+
765
+	public function admin_notices()
766
+	{
767
+	}
768
+
769
+
770
+	public function admin_footer_scripts()
771
+	{
772
+	}
773
+
774
+
775
+	public function messages_help_tab()
776
+	{
777
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
778
+	}
779
+
780
+
781
+	public function messengers_help_tab()
782
+	{
783
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
784
+	}
785
+
786
+
787
+	public function message_types_help_tab()
788
+	{
789
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
790
+	}
791
+
792
+
793
+	public function messages_overview_help_tab()
794
+	{
795
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
796
+	}
797
+
798
+
799
+	public function message_templates_help_tab()
800
+	{
801
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
802
+	}
803
+
804
+
805
+	public function edit_message_template_help_tab()
806
+	{
807
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
808
+						. esc_attr__('Editor Title', 'event_espresso')
809
+						. '" />';
810
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
811
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
812
+						. '" />';
813
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
814
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
815
+						. '" />';
816
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
817
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
818
+						. '" />';
819
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
820
+						. esc_attr__('Publish Metabox', 'event_espresso')
821
+						. '" />';
822
+		EEH_Template::display_template(
823
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
824
+			$args
825
+		);
826
+	}
827
+
828
+
829
+	/**
830
+	 * @throws ReflectionException
831
+	 * @throws EE_Error
832
+	 */
833
+	public function message_template_shortcodes_help_tab()
834
+	{
835
+		$this->_set_shortcodes();
836
+		$args['shortcodes'] = $this->_shortcodes;
837
+		EEH_Template::display_template(
838
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
839
+			$args
840
+		);
841
+	}
842
+
843
+
844
+	public function preview_message_help_tab()
845
+	{
846
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
847
+	}
848
+
849
+
850
+	public function settings_help_tab()
851
+	{
852
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
853
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
854
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
855
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
856
+		$args['img3'] = '<div class="switch">'
857
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
858
+						. ' type="checkbox" checked="checked">'
859
+						. '<label for="ee-on-off-toggle-on"></label>'
860
+						. '</div>';
861
+		$args['img4'] = '<div class="switch">'
862
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
863
+						. ' type="checkbox">'
864
+						. '<label for="ee-on-off-toggle-on"></label>'
865
+						. '</div>';
866
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
867
+	}
868
+
869
+
870
+	public function load_scripts_styles()
871
+	{
872
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
873
+		wp_enqueue_style('espresso_ee_msg');
874
+
875
+		wp_register_script(
876
+			'ee-messages-settings',
877
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
878
+			['jquery-ui-droppable', 'ee-serialize-full-array'],
879
+			EVENT_ESPRESSO_VERSION,
880
+			true
881
+		);
882
+		wp_register_script(
883
+			'ee-msg-list-table-js',
884
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
885
+			['ee-dialog'],
886
+			EVENT_ESPRESSO_VERSION
887
+		);
888
+	}
889
+
890
+
891
+	public function load_scripts_styles_default()
892
+	{
893
+		wp_enqueue_script('ee-msg-list-table-js');
894
+	}
895
+
896
+
897
+	public function wp_editor_css($mce_css)
898
+	{
899
+		// if we're on the edit_message_template route
900
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
901
+			$message_type_name = $this->_active_message_type_name;
902
+
903
+			// we're going to REPLACE the existing mce css
904
+			// we need to get the css file location from the active messenger
905
+			$mce_css = $this->_active_messenger->get_variation(
906
+				$this->_template_pack,
907
+				$message_type_name,
908
+				true,
909
+				'wpeditor',
910
+				$this->_variation
911
+			);
912
+		}
913
+
914
+		return $mce_css;
915
+	}
916
+
917
+
918
+	/**
919
+	 * @throws EE_Error
920
+	 * @throws ReflectionException
921
+	 */
922
+	public function load_scripts_styles_edit_message_template()
923
+	{
924
+
925
+		$this->_set_shortcodes();
926
+
927
+		EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
928
+			esc_html__(
929
+				'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.',
930
+				'event_espresso'
931
+			),
932
+			$this->_message_template_group->messenger_obj()->label['singular'],
933
+			$this->_message_template_group->message_type_obj()->label['singular']
934
+		);
935
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
936
+			'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?',
937
+			'event_espresso'
938
+		);
939
+		EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
940
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
941
+			'event_espresso'
942
+		);
943
+
944
+		wp_register_script(
945
+			'ee_msgs_edit_js',
946
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
947
+			['jquery'],
948
+			EVENT_ESPRESSO_VERSION
949
+		);
950
+
951
+		wp_enqueue_script('ee_admin_js');
952
+		wp_enqueue_script('ee_msgs_edit_js');
953
+
954
+		// add in special css for tiny_mce
955
+		add_filter('mce_css', [$this, 'wp_editor_css']);
956
+	}
957
+
958
+
959
+	/**
960
+	 * @throws EE_Error
961
+	 * @throws ReflectionException
962
+	 */
963
+	public function load_scripts_styles_display_preview_message()
964
+	{
965
+		$this->_set_message_template_group();
966
+		if ($this->_active_messenger_name) {
967
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
968
+				$this->_active_messenger_name
969
+			);
970
+		}
971
+
972
+		wp_enqueue_style(
973
+			'espresso_preview_css',
974
+			$this->_active_messenger->get_variation(
975
+				$this->_template_pack,
976
+				$this->_active_message_type_name,
977
+				true,
978
+				'preview',
979
+				$this->_variation
980
+			)
981
+		);
982
+	}
983
+
984
+
985
+	public function load_scripts_styles_settings()
986
+	{
987
+		wp_register_style(
988
+			'ee-message-settings',
989
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
990
+			[],
991
+			EVENT_ESPRESSO_VERSION
992
+		);
993
+		wp_enqueue_style('ee-text-links');
994
+		wp_enqueue_style('ee-message-settings');
995
+		wp_enqueue_script('ee-messages-settings');
996
+	}
997
+
998
+
999
+	/**
1000
+	 * set views array for List Table
1001
+	 */
1002
+	public function _set_list_table_views_global_mtps()
1003
+	{
1004
+		$this->_views = [
1005
+			'in_use' => [
1006
+				'slug'  => 'in_use',
1007
+				'label' => esc_html__('In Use', 'event_espresso'),
1008
+				'count' => 0,
1009
+			],
1010
+		];
1011
+	}
1012
+
1013
+
1014
+	/**
1015
+	 * Set views array for the Custom Template List Table
1016
+	 */
1017
+	public function _set_list_table_views_custom_mtps()
1018
+	{
1019
+		$this->_set_list_table_views_global_mtps();
1020
+		$this->_views['in_use']['bulk_action'] = [
1021
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
1022
+		];
1023
+	}
1024
+
1025
+
1026
+	/**
1027
+	 * set views array for message queue list table
1028
+	 *
1029
+	 * @throws InvalidDataTypeException
1030
+	 * @throws InvalidInterfaceException
1031
+	 * @throws InvalidArgumentException
1032
+	 * @throws EE_Error
1033
+	 * @throws ReflectionException
1034
+	 */
1035
+	public function _set_list_table_views_default()
1036
+	{
1037
+		EE_Registry::instance()->load_helper('Template');
1038
+
1039
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
1040
+			'ee_send_message',
1041
+			'message_list_table_bulk_actions'
1042
+		)
1043
+			? [
1044
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
1045
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
1046
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
1047
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
1048
+			]
1049
+			: [];
1050
+
1051
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
1052
+			'ee_delete_messages',
1053
+			'message_list_table_bulk_actions'
1054
+		)
1055
+			? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
1056
+			: [];
1057
+
1058
+
1059
+		$this->_views = [
1060
+			'all' => [
1061
+				'slug'        => 'all',
1062
+				'label'       => esc_html__('All', 'event_espresso'),
1063
+				'count'       => 0,
1064
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1065
+			],
1066
+		];
1067
+
1068
+
1069
+		foreach ($this->getMsgModel()->all_statuses() as $status) {
1070
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1071
+				continue;
1072
+			}
1073
+			$status_bulk_actions = $common_bulk_actions;
1074
+			// unset bulk actions not applying to status
1075
+			if (! empty($status_bulk_actions)) {
1076
+				switch ($status) {
1077
+					case EEM_Message::status_idle:
1078
+					case EEM_Message::status_resend:
1079
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1080
+						break;
1081
+
1082
+					case EEM_Message::status_failed:
1083
+					case EEM_Message::status_debug_only:
1084
+					case EEM_Message::status_messenger_executing:
1085
+						$status_bulk_actions = [];
1086
+						break;
1087
+
1088
+					case EEM_Message::status_incomplete:
1089
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1090
+						break;
1091
+
1092
+					case EEM_Message::status_retry:
1093
+					case EEM_Message::status_sent:
1094
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1095
+						break;
1096
+				}
1097
+			}
1098
+
1099
+			// skip adding messenger executing status to views because it will be included with the Failed view.
1100
+			if ($status === EEM_Message::status_messenger_executing) {
1101
+				continue;
1102
+			}
1103
+
1104
+			$this->_views[ strtolower($status) ] = [
1105
+				'slug'        => strtolower($status),
1106
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1107
+				'count'       => 0,
1108
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1109
+			];
1110
+		}
1111
+	}
1112
+
1113
+
1114
+	/**
1115
+	 * @throws EE_Error
1116
+	 */
1117
+	protected function _ee_default_messages_overview_list_table()
1118
+	{
1119
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1120
+		$this->display_admin_list_table_page_with_no_sidebar();
1121
+	}
1122
+
1123
+
1124
+	/**
1125
+	 * @throws EE_Error
1126
+	 * @throws ReflectionException
1127
+	 */
1128
+	protected function _message_queue_list_table()
1129
+	{
1130
+		$this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
1131
+		$this->_template_args['per_column']        = 6;
1132
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
1133
+		$this->_template_args['before_list_table'] = '<h3>'
1134
+													 . $this->getMsgModel()->get_pretty_label_for_results()
1135
+													 . '</h3>';
1136
+		$this->display_admin_list_table_page_with_no_sidebar();
1137
+	}
1138
+
1139
+
1140
+	/**
1141
+	 * @throws EE_Error
1142
+	 */
1143
+	protected function _message_legend_items()
1144
+	{
1145
+
1146
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1147
+		$action_items       = [];
1148
+
1149
+		foreach ($action_css_classes as $action_item => $action_details) {
1150
+			if ($action_item === 'see_notifications_for') {
1151
+				continue;
1152
+			}
1153
+			$action_items[ $action_item ] = [
1154
+				'class' => $action_details['css_class'],
1155
+				'desc'  => $action_details['label'],
1156
+			];
1157
+		}
1158
+
1159
+		/** @var array $status_items status legend setup */
1160
+		$status_items = [
1161
+			'sent_status'                => [
1162
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1163
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1164
+			],
1165
+			'idle_status'                => [
1166
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1167
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1168
+			],
1169
+			'failed_status'              => [
1170
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1171
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1172
+			],
1173
+			'messenger_executing_status' => [
1174
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1175
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1176
+			],
1177
+			'resend_status'              => [
1178
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1179
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1180
+			],
1181
+			'incomplete_status'          => [
1182
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1183
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1184
+			],
1185
+			'retry_status'               => [
1186
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1187
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1188
+			],
1189
+		];
1190
+		if (EEM_Message::debug()) {
1191
+			$status_items['debug_only_status'] = [
1192
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1193
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1194
+			];
1195
+		}
1196
+
1197
+		return array_merge($action_items, $status_items);
1198
+	}
1199
+
1200
+
1201
+	/**
1202
+	 * @throws EE_Error
1203
+	 */
1204
+	protected function _custom_mtps_preview()
1205
+	{
1206
+		$this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1207
+		$this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1208
+												. ' alt="' . esc_attr__(
1209
+													'Preview Custom Message Templates screenshot',
1210
+													'event_espresso'
1211
+												) . '" />';
1212
+		$this->_template_args['preview_text'] = '<strong>'
1213
+												. esc_html__(
1214
+													'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.',
1215
+													'event_espresso'
1216
+												)
1217
+												. '</strong>';
1218
+
1219
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1220
+	}
1221
+
1222
+
1223
+	/**
1224
+	 * get_message_templates
1225
+	 * This gets all the message templates for listing on the overview list.
1226
+	 *
1227
+	 * @access public
1228
+	 * @param int    $per_page the amount of templates groups to show per page
1229
+	 * @param string $type     the current _view we're getting templates for
1230
+	 * @param bool   $count    return count?
1231
+	 * @param bool   $all      disregard any paging info (get all data);
1232
+	 * @param bool   $global   whether to return just global (true) or custom templates (false)
1233
+	 * @return array
1234
+	 * @throws EE_Error
1235
+	 * @throws InvalidArgumentException
1236
+	 * @throws InvalidDataTypeException
1237
+	 * @throws InvalidInterfaceException
1238
+	 */
1239
+	public function get_message_templates(
1240
+		$per_page = 10,
1241
+		$type = 'in_use',
1242
+		$count = false,
1243
+		$all = false,
1244
+		$global = true
1245
+	) {
1246
+		$orderby = $this->request->getRequestParam('orderby', 'GRP_ID');
1247
+		$this->request->setRequestParam('orderby', $orderby);
1248
+
1249
+		$order        = $this->request->getRequestParam('order', 'ASC');
1250
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
1251
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1252
+
1253
+		$offset = ($current_page - 1) * $per_page;
1254
+		$limit  = $all ? null : [$offset, $per_page];
1255
+
1256
+		// options will match what is in the _views array property
1257
+		return $type === 'in_use'
1258
+			? $this->getMtgModel()->get_all_active_message_templates(
1259
+				$orderby,
1260
+				$order,
1261
+				$limit,
1262
+				$count,
1263
+				$global,
1264
+				true
1265
+			)
1266
+			: $this->getMtgModel()->get_all_trashed_grouped_message_templates(
1267
+				$orderby,
1268
+				$order,
1269
+				$limit,
1270
+				$count,
1271
+				$global
1272
+			);
1273
+	}
1274
+
1275
+
1276
+	/**
1277
+	 * filters etc might need a list of installed message_types
1278
+	 *
1279
+	 * @return array an array of message type objects
1280
+	 */
1281
+	public function get_installed_message_types()
1282
+	{
1283
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1284
+		$installed               = [];
1285
+
1286
+		foreach ($installed_message_types as $message_type) {
1287
+			$installed[ $message_type->name ] = $message_type;
1288
+		}
1289
+
1290
+		return $installed;
1291
+	}
1292
+
1293
+
1294
+	/**
1295
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1296
+	 *
1297
+	 * @param string $message_type
1298
+	 * @param string $messenger
1299
+	 * @param string $GRP_ID
1300
+	 *
1301
+	 * @throws EE_error
1302
+	 * @throws ReflectionException
1303
+	 */
1304
+	public function add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1305
+	{
1306
+		// set values override any request data
1307
+		$message_type = ! empty($message_type) ? $message_type : $this->_active_message_type_name;
1308
+		$messenger    = ! empty($messenger) ? $messenger : $this->_active_messenger_name;
1309
+		$GRP_ID       = ! empty($GRP_ID) ? $GRP_ID : $this->request->getRequestParam('GRP_ID', 0, 'int');
1310
+
1311
+		// we need messenger and message type.  They should be coming from the event editor. If not here then return error
1312
+		if (empty($message_type) || empty($messenger)) {
1313
+			throw new EE_Error(
1314
+				esc_html__(
1315
+					'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1316
+					'event_espresso'
1317
+				)
1318
+			);
1319
+		}
1320
+
1321
+		// we need the GRP_ID for the template being used as the base for the new template
1322
+		if (empty($GRP_ID)) {
1323
+			throw new EE_Error(
1324
+				esc_html__(
1325
+					'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1326
+					'event_espresso'
1327
+				)
1328
+			);
1329
+		}
1330
+
1331
+		// let's just make sure the template gets generated!
1332
+
1333
+		// we need to reassign some variables for what the insert is expecting
1334
+		$this->request->setRequestParam('MTP_messenger', $messenger);
1335
+		$this->request->setRequestParam('MTP_message_type', $message_type);
1336
+		$this->request->setRequestParam('GRP_ID', $GRP_ID);
1337
+
1338
+		$this->_insert_or_update_message_template(true);
1339
+	}
1340
+
1341
+
1342
+	/**
1343
+	 * @param string $message_type     message type slug
1344
+	 * @param string $messenger        messenger slug
1345
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1346
+	 *                                 off of.
1347
+	 * @throws EE_error
1348
+	 * @throws ReflectionException
1349
+	 * @deprecated $VID:$
1350
+	 */
1351
+	protected function _add_message_template($message_type, $messenger, $GRP_ID)
1352
+	{
1353
+		$this->add_message_template($message_type, $messenger, $GRP_ID);
1354
+	}
1355
+
1356
+
1357
+	/**
1358
+	 * _edit_message_template
1359
+	 *
1360
+	 * @access protected
1361
+	 * @return void
1362
+	 * @throws InvalidIdentifierException
1363
+	 * @throws DomainException
1364
+	 * @throws EE_Error
1365
+	 * @throws InvalidArgumentException
1366
+	 * @throws ReflectionException
1367
+	 * @throws InvalidDataTypeException
1368
+	 * @throws InvalidInterfaceException
1369
+	 */
1370
+	protected function _edit_message_template()
1371
+	{
1372
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1373
+		$template_fields = '';
1374
+		$sidebar_fields  = '';
1375
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1376
+		// valid html in the templates.
1377
+		add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1378
+
1379
+		$GRP_ID = $this->request->getRequestParam('id', 0, 'int');
1380
+		$EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
1381
+
1382
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1383
+		$message_template_group = $this->_message_template_group;
1384
+		$c_label                = $message_template_group->context_label();
1385
+		$c_config               = $message_template_group->contexts_config();
1386
+
1387
+		reset($c_config);
1388
+		$context = $this->request->getRequestParam('context', key($c_config));
1389
+		$context = strtolower($context);
1390
+
1391
+		$action = empty($GRP_ID) ? 'insert_message_template' : 'update_message_template';
1392
+
1393
+		$edit_message_template_form_url = add_query_arg(
1394
+			['action' => $action, 'noheader' => true],
1395
+			EE_MSG_ADMIN_URL
1396
+		);
1397
+
1398
+		// set active messenger for this view
1399
+		$this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1400
+			$message_template_group->messenger()
1401
+		);
1402
+		$this->_active_message_type_name = $message_template_group->message_type();
1403
+
1404
+
1405
+		// Do we have any validation errors?
1406
+		$validators = $this->_get_transient();
1407
+		$v_fields   = ! empty($validators) ? array_keys($validators) : [];
1408
+
1409
+
1410
+		// we need to assemble the title from Various details
1411
+		$context_label = sprintf(
1412
+			esc_html__('(%s %s)', 'event_espresso'),
1413
+			$c_config[ $context ]['label'],
1414
+			ucwords($c_label['label'])
1415
+		);
1416
+
1417
+		$title = sprintf(
1418
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1419
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1420
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1421
+			$context_label
1422
+		);
1423
+
1424
+		$this->_template_args['GRP_ID']           = $GRP_ID;
1425
+		$this->_template_args['message_template'] = $message_template_group;
1426
+		$this->_template_args['is_extra_fields']  = false;
1427
+
1428
+
1429
+		// let's get EEH_MSG_Template so we can get template form fields
1430
+		$template_field_structure = EEH_MSG_Template::get_fields(
1431
+			$message_template_group->messenger(),
1432
+			$message_template_group->message_type()
1433
+		);
1434
+
1435
+		if (! $template_field_structure) {
1436
+			$template_field_structure = false;
1437
+			$template_fields          = esc_html__(
1438
+				'There was an error in assembling the fields for this display (you should see an error message)',
1439
+				'event_espresso'
1440
+			);
1441
+		}
1442
+
1443
+
1444
+		$message_templates = $message_template_group->context_templates();
1445
+
1446
+
1447
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1448
+		// will get handled in the "extra" array.
1449
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1450
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1451
+				unset($template_field_structure[ $context ][ $reference_field ]);
1452
+			}
1453
+		}
1454
+
1455
+		// let's loop through the template_field_structure and actually assemble the input fields!
1456
+		if (! empty($template_field_structure)) {
1457
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1458
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1459
+				// the extra array and reset them.
1460
+				if ($template_field === 'extra') {
1461
+					$this->_template_args['is_extra_fields'] = true;
1462
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1463
+						$message_template = $message_templates[ $context ][ $reference_field ];
1464
+						$content          = $message_template instanceof EE_Message_Template
1465
+							? $message_template->get('MTP_content')
1466
+							: '';
1467
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1468
+							// let's verify if we need this extra field via the shortcodes parameter.
1469
+							$continue = false;
1470
+							if (isset($extra_array['shortcodes_required'])) {
1471
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1472
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1473
+										$continue = true;
1474
+									}
1475
+								}
1476
+								if ($continue) {
1477
+									continue;
1478
+								}
1479
+							}
1480
+
1481
+							$field_id = $reference_field . '-' . $extra_field . '-content';
1482
+
1483
+							$template_form_fields[ $field_id ]         = $extra_array;
1484
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1485
+																		 . $reference_field
1486
+																		 . '][content]['
1487
+																		 . $extra_field . ']';
1488
+							$css_class                                 = isset($extra_array['css_class'])
1489
+								? $extra_array['css_class']
1490
+								: '';
1491
+
1492
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1493
+																			  && in_array($extra_field, $v_fields, true)
1494
+																			  && (
1495
+																				  is_array($validators[ $extra_field ])
1496
+																				  && isset($validators[ $extra_field ]['msg'])
1497
+																			  )
1498
+								? 'validate-error ' . $css_class
1499
+								: $css_class;
1500
+
1501
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1502
+																		  && isset($content[ $extra_field ])
1503
+								? $content[ $extra_field ]
1504
+								: '';
1505
+
1506
+							// do we have a validation error?  if we do then let's use that value instead
1507
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1508
+								? $validators[ $extra_field ]['value']
1509
+								: $template_form_fields[ $field_id ]['value'];
1510
+
1511
+
1512
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1513
+
1514
+							// shortcode selector
1515
+							$field_name_to_use                                   = $extra_field === 'main'
1516
+								? 'content'
1517
+								: $extra_field;
1518
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1519
+								$field_name_to_use,
1520
+								$field_id
1521
+							);
1522
+						}
1523
+						$template_field_MTP_id           = $reference_field . '-MTP_ID';
1524
+						$template_field_template_name_id = $reference_field . '-name';
1525
+
1526
+						$template_form_fields[ $template_field_MTP_id ] = [
1527
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1528
+							'label'      => null,
1529
+							'input'      => 'hidden',
1530
+							'type'       => 'int',
1531
+							'required'   => false,
1532
+							'validation' => false,
1533
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1534
+							'css_class'  => '',
1535
+							'format'     => '%d',
1536
+							'db-col'     => 'MTP_ID',
1537
+						];
1538
+
1539
+						$template_form_fields[ $template_field_template_name_id ] = [
1540
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1541
+							'label'      => null,
1542
+							'input'      => 'hidden',
1543
+							'type'       => 'string',
1544
+							'required'   => false,
1545
+							'validation' => true,
1546
+							'value'      => $reference_field,
1547
+							'css_class'  => '',
1548
+							'format'     => '%s',
1549
+							'db-col'     => 'MTP_template_field',
1550
+						];
1551
+					}
1552
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1553
+				} else {
1554
+					$field_id                                   = $template_field . '-content';
1555
+					$template_form_fields[ $field_id ]          = $field_setup_array;
1556
+					$template_form_fields[ $field_id ]['name']  =
1557
+						'MTP_template_fields[' . $template_field . '][content]';
1558
+					$message_template                           =
1559
+						isset($message_templates[ $context ][ $template_field ])
1560
+							? $message_templates[ $context ][ $template_field ]
1561
+							: null;
1562
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1563
+																  && is_array($message_templates[ $context ])
1564
+																  && $message_template instanceof EE_Message_Template
1565
+						? $message_template->get('MTP_content')
1566
+						: '';
1567
+
1568
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1569
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1570
+						? $validators[ $template_field ]['value']
1571
+						: $template_form_fields[ $field_id ]['value'];
1572
+
1573
+
1574
+					$template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1575
+					$css_class                                      = isset($field_setup_array['css_class'])
1576
+						? $field_setup_array['css_class']
1577
+						: '';
1578
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1579
+																	  && in_array($template_field, $v_fields, true)
1580
+																	  && isset($validators[ $template_field ]['msg'])
1581
+						? 'validate-error ' . $css_class
1582
+						: $css_class;
1583
+
1584
+					// shortcode selector
1585
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1586
+						$template_field,
1587
+						$field_id
1588
+					);
1589
+				}
1590
+
1591
+				// k took care of content field(s) now let's take care of others.
1592
+
1593
+				$template_field_MTP_id                 = $template_field . '-MTP_ID';
1594
+				$template_field_field_template_name_id = $template_field . '-name';
1595
+
1596
+				// foreach template field there are actually two form fields created
1597
+				$template_form_fields[ $template_field_MTP_id ] = [
1598
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1599
+					'label'      => null,
1600
+					'input'      => 'hidden',
1601
+					'type'       => 'int',
1602
+					'required'   => false,
1603
+					'validation' => true,
1604
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1605
+					'css_class'  => '',
1606
+					'format'     => '%d',
1607
+					'db-col'     => 'MTP_ID',
1608
+				];
1609
+
1610
+				$template_form_fields[ $template_field_field_template_name_id ] = [
1611
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1612
+					'label'      => null,
1613
+					'input'      => 'hidden',
1614
+					'type'       => 'string',
1615
+					'required'   => false,
1616
+					'validation' => true,
1617
+					'value'      => $template_field,
1618
+					'css_class'  => '',
1619
+					'format'     => '%s',
1620
+					'db-col'     => 'MTP_template_field',
1621
+				];
1622
+			}
1623
+
1624
+			// add other fields
1625
+			$template_form_fields['ee-msg-current-context'] = [
1626
+				'name'       => 'MTP_context',
1627
+				'label'      => null,
1628
+				'input'      => 'hidden',
1629
+				'type'       => 'string',
1630
+				'required'   => false,
1631
+				'validation' => true,
1632
+				'value'      => $context,
1633
+				'css_class'  => '',
1634
+				'format'     => '%s',
1635
+				'db-col'     => 'MTP_context',
1636
+			];
1637
+
1638
+			$template_form_fields['ee-msg-grp-id'] = [
1639
+				'name'       => 'GRP_ID',
1640
+				'label'      => null,
1641
+				'input'      => 'hidden',
1642
+				'type'       => 'int',
1643
+				'required'   => false,
1644
+				'validation' => true,
1645
+				'value'      => $GRP_ID,
1646
+				'css_class'  => '',
1647
+				'format'     => '%d',
1648
+				'db-col'     => 'GRP_ID',
1649
+			];
1650
+
1651
+			$template_form_fields['ee-msg-messenger'] = [
1652
+				'name'       => 'MTP_messenger',
1653
+				'label'      => null,
1654
+				'input'      => 'hidden',
1655
+				'type'       => 'string',
1656
+				'required'   => false,
1657
+				'validation' => true,
1658
+				'value'      => $message_template_group->messenger(),
1659
+				'css_class'  => '',
1660
+				'format'     => '%s',
1661
+				'db-col'     => 'MTP_messenger',
1662
+			];
1663
+
1664
+			$template_form_fields['ee-msg-message-type'] = [
1665
+				'name'       => 'MTP_message_type',
1666
+				'label'      => null,
1667
+				'input'      => 'hidden',
1668
+				'type'       => 'string',
1669
+				'required'   => false,
1670
+				'validation' => true,
1671
+				'value'      => $message_template_group->message_type(),
1672
+				'css_class'  => '',
1673
+				'format'     => '%s',
1674
+				'db-col'     => 'MTP_message_type',
1675
+			];
1676
+
1677
+			$sidebar_form_fields['ee-msg-is-global'] = [
1678
+				'name'       => 'MTP_is_global',
1679
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1680
+				'input'      => 'hidden',
1681
+				'type'       => 'int',
1682
+				'required'   => false,
1683
+				'validation' => true,
1684
+				'value'      => $message_template_group->get('MTP_is_global'),
1685
+				'css_class'  => '',
1686
+				'format'     => '%d',
1687
+				'db-col'     => 'MTP_is_global',
1688
+			];
1689
+
1690
+			$sidebar_form_fields['ee-msg-is-override'] = [
1691
+				'name'       => 'MTP_is_override',
1692
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1693
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1694
+				'type'       => 'int',
1695
+				'required'   => false,
1696
+				'validation' => true,
1697
+				'value'      => $message_template_group->get('MTP_is_override'),
1698
+				'css_class'  => '',
1699
+				'format'     => '%d',
1700
+				'db-col'     => 'MTP_is_override',
1701
+			];
1702
+
1703
+			$sidebar_form_fields['ee-msg-is-active'] = [
1704
+				'name'       => 'MTP_is_active',
1705
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1706
+				'input'      => 'hidden',
1707
+				'type'       => 'int',
1708
+				'required'   => false,
1709
+				'validation' => true,
1710
+				'value'      => $message_template_group->is_active(),
1711
+				'css_class'  => '',
1712
+				'format'     => '%d',
1713
+				'db-col'     => 'MTP_is_active',
1714
+			];
1715
+
1716
+			$sidebar_form_fields['ee-msg-deleted'] = [
1717
+				'name'       => 'MTP_deleted',
1718
+				'label'      => null,
1719
+				'input'      => 'hidden',
1720
+				'type'       => 'int',
1721
+				'required'   => false,
1722
+				'validation' => true,
1723
+				'value'      => $message_template_group->get('MTP_deleted'),
1724
+				'css_class'  => '',
1725
+				'format'     => '%d',
1726
+				'db-col'     => 'MTP_deleted',
1727
+			];
1728
+			$sidebar_form_fields['ee-msg-author']  = [
1729
+				'name'       => 'MTP_user_id',
1730
+				'label'      => esc_html__('Author', 'event_espresso'),
1731
+				'input'      => 'hidden',
1732
+				'type'       => 'int',
1733
+				'required'   => false,
1734
+				'validation' => false,
1735
+				'value'      => $message_template_group->user(),
1736
+				'format'     => '%d',
1737
+				'db-col'     => 'MTP_user_id',
1738
+			];
1739
+
1740
+			$sidebar_form_fields['ee-msg-route'] = [
1741
+				'name'  => 'action',
1742
+				'input' => 'hidden',
1743
+				'type'  => 'string',
1744
+				'value' => $action,
1745
+			];
1746
+
1747
+			$sidebar_form_fields['ee-msg-id']        = [
1748
+				'name'  => 'id',
1749
+				'input' => 'hidden',
1750
+				'type'  => 'int',
1751
+				'value' => $GRP_ID,
1752
+			];
1753
+			$sidebar_form_fields['ee-msg-evt-nonce'] = [
1754
+				'name'  => $action . '_nonce',
1755
+				'input' => 'hidden',
1756
+				'type'  => 'string',
1757
+				'value' => wp_create_nonce($action . '_nonce'),
1758
+			];
1759
+
1760
+			$template_switch = $this->request->getRequestParam('template_switch');
1761
+			if ($template_switch) {
1762
+				$sidebar_form_fields['ee-msg-template-switch'] = [
1763
+					'name'  => 'template_switch',
1764
+					'input' => 'hidden',
1765
+					'type'  => 'int',
1766
+					'value' => 1,
1767
+				];
1768
+			}
1769
+
1770
+
1771
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1772
+			$sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1773
+		} //end if ( !empty($template_field_structure) )
1774
+
1775
+		// set extra content for publish box
1776
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1777
+		$this->_set_publish_post_box_vars(
1778
+			'id',
1779
+			$GRP_ID,
1780
+			false,
1781
+			add_query_arg(
1782
+				['action' => 'global_mtps'],
1783
+				$this->_admin_base_url
1784
+			)
1785
+		);
1786
+
1787
+		// add preview button
1788
+		$preview_url    = parent::add_query_args_and_nonce(
1789
+			[
1790
+				'message_type' => $message_template_group->message_type(),
1791
+				'messenger'    => $message_template_group->messenger(),
1792
+				'context'      => $context,
1793
+				'GRP_ID'       => $GRP_ID,
1794
+				'evt_id'       => $EVT_ID,
1795
+				'action'       => 'preview_message',
1796
+			],
1797
+			$this->_admin_base_url
1798
+		);
1799
+		$preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1800
+						  . esc_html__('Preview', 'event_espresso')
1801
+						  . '</a>';
1802
+
1803
+
1804
+		// setup context switcher
1805
+		$context_switcher_args = [
1806
+			'page'    => 'espresso_messages',
1807
+			'action'  => 'edit_message_template',
1808
+			'id'      => $GRP_ID,
1809
+			'evt_id'  => $EVT_ID,
1810
+			'context' => $context,
1811
+			'extra'   => $preview_button,
1812
+		];
1813
+		$this->_set_context_switcher($message_template_group, $context_switcher_args);
1814
+
1815
+
1816
+		// main box
1817
+		$this->_template_args['template_fields']                         = $template_fields;
1818
+		$this->_template_args['sidebar_box_id']                          = 'details';
1819
+		$this->_template_args['action']                                  = $action;
1820
+		$this->_template_args['context']                                 = $context;
1821
+		$this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1822
+		$this->_template_args['learn_more_about_message_templates_link'] =
1823
+			$this->_learn_more_about_message_templates_link();
1824
+
1825
+
1826
+		$this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1827
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1828
+			$message_template_group,
1829
+			$context,
1830
+			$context_label
1831
+		);
1832
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1833
+		$this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1834
+
1835
+		$this->_template_path = $this->_template_args['GRP_ID']
1836
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1837
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1838
+
1839
+		// send along EE_Message_Template_Group object for further template use.
1840
+		$this->_template_args['MTP'] = $message_template_group;
1841
+
1842
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1843
+			$this->_template_path,
1844
+			$this->_template_args,
1845
+			true
1846
+		);
1847
+
1848
+
1849
+		// finally, let's set the admin_page title
1850
+		$this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1851
+
1852
+
1853
+		// we need to take care of setting the shortcodes property for use elsewhere.
1854
+		$this->_set_shortcodes();
1855
+
1856
+
1857
+		// final template wrapper
1858
+		$this->display_admin_page_with_sidebar();
1859
+	}
1860
+
1861
+
1862
+	public function filter_tinymce_init($mceInit, $editor_id)
1863
+	{
1864
+		return $mceInit;
1865
+	}
1866
+
1867
+
1868
+	public function add_context_switcher()
1869
+	{
1870
+		return $this->_context_switcher;
1871
+	}
1872
+
1873
+
1874
+	/**
1875
+	 * Adds the activation/deactivation toggle for the message template context.
1876
+	 *
1877
+	 * @param EE_Message_Template_Group $message_template_group
1878
+	 * @param string                    $context
1879
+	 * @param string                    $context_label
1880
+	 * @return string
1881
+	 * @throws DomainException
1882
+	 * @throws EE_Error
1883
+	 * @throws InvalidIdentifierException
1884
+	 * @throws ReflectionException
1885
+	 */
1886
+	protected function add_active_context_element(
1887
+		EE_Message_Template_Group $message_template_group,
1888
+		$context,
1889
+		$context_label
1890
+	) {
1891
+		$template_args = [
1892
+			'context'                   => $context,
1893
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1894
+			'is_active'                 => $message_template_group->is_context_active($context),
1895
+			'on_off_action'             => $message_template_group->is_context_active($context)
1896
+				? 'context-off'
1897
+				: 'context-on',
1898
+			'context_label'             => str_replace(['(', ')'], '', $context_label),
1899
+			'message_template_group_id' => $message_template_group->ID(),
1900
+		];
1901
+		return EEH_Template::display_template(
1902
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1903
+			$template_args,
1904
+			true
1905
+		);
1906
+	}
1907
+
1908
+
1909
+	/**
1910
+	 * Ajax callback for `toggle_context_template` ajax action.
1911
+	 * Handles toggling the message context on or off.
1912
+	 *
1913
+	 * @throws EE_Error
1914
+	 * @throws InvalidArgumentException
1915
+	 * @throws InvalidDataTypeException
1916
+	 * @throws InvalidIdentifierException
1917
+	 * @throws InvalidInterfaceException
1918
+	 */
1919
+	public function toggle_context_template()
1920
+	{
1921
+		$success = true;
1922
+		// check for required data
1923
+		if (
1924
+			! (
1925
+				$this->request->requestParamIsSet('message_template_group_id')
1926
+				&& $this->request->requestParamIsSet('context')
1927
+				&& $this->request->requestParamIsSet('status')
1928
+			)
1929
+		) {
1930
+			EE_Error::add_error(
1931
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1932
+				__FILE__,
1933
+				__FUNCTION__,
1934
+				__LINE__
1935
+			);
1936
+			$success = false;
1937
+		}
1938
+
1939
+		$nonce   = $this->request->getRequestParam('toggle_context_nonce', '');
1940
+		$context = $this->request->getRequestParam('context', '');
1941
+		$status  = $this->request->getRequestParam('status', '');
1942
+
1943
+		$this->_verify_nonce($nonce, "activate_{$context}_toggle_nonce");
1944
+
1945
+		if ($status !== 'off' && $status !== 'on') {
1946
+			EE_Error::add_error(
1947
+				sprintf(
1948
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1949
+					$status
1950
+				),
1951
+				__FILE__,
1952
+				__FUNCTION__,
1953
+				__LINE__
1954
+			);
1955
+			$success = false;
1956
+		}
1957
+		$message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, 'int');
1958
+		$message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1959
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1960
+			EE_Error::add_error(
1961
+				sprintf(
1962
+					esc_html__(
1963
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1964
+						'event_espresso'
1965
+					),
1966
+					$message_template_group_id,
1967
+					'EE_Message_Template_Group'
1968
+				),
1969
+				__FILE__,
1970
+				__FUNCTION__,
1971
+				__LINE__
1972
+			);
1973
+			$success = false;
1974
+		}
1975
+		if ($success) {
1976
+			$success = $status === 'off'
1977
+				? $message_template_group->deactivate_context($context)
1978
+				: $message_template_group->activate_context($context);
1979
+		}
1980
+		$this->_template_args['success'] = $success;
1981
+		$this->_return_json();
1982
+	}
1983
+
1984
+
1985
+	public function _add_form_element_before()
1986
+	{
1987
+		return '<form method="post" action="'
1988
+			   . $this->_template_args['edit_message_template_form_url']
1989
+			   . '" id="ee-msg-edit-frm">';
1990
+	}
1991
+
1992
+
1993
+	public function _add_form_element_after()
1994
+	{
1995
+		return '</form>';
1996
+	}
1997
+
1998
+
1999
+	/**
2000
+	 * This executes switching the template pack for a message template.
2001
+	 *
2002
+	 * @throws EE_Error
2003
+	 * @throws InvalidDataTypeException
2004
+	 * @throws InvalidInterfaceException
2005
+	 * @throws InvalidArgumentException
2006
+	 * @throws ReflectionException
2007
+	 * @since 4.5.0
2008
+	 */
2009
+	public function switch_template_pack()
2010
+	{
2011
+
2012
+		$GRP_ID        = $this->request->getRequestParam('GRP_ID', 0, 'int');
2013
+		$template_pack = $this->request->getRequestParam('template_pack', '');
2014
+
2015
+		// verify we have needed values.
2016
+		if (empty($GRP_ID) || empty($template_pack)) {
2017
+			$this->_template_args['error'] = true;
2018
+			EE_Error::add_error(
2019
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
2020
+				__FILE__,
2021
+				__FUNCTION__,
2022
+				__LINE__
2023
+			);
2024
+		} else {
2025
+			// get template, set the new template_pack and then reset to default
2026
+			/** @var EE_Message_Template_Group $message_template_group */
2027
+			$message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
2028
+
2029
+			$message_template_group->set_template_pack_name($template_pack);
2030
+			$this->request->setRequestParam('msgr', $message_template_group->messenger());
2031
+			$this->request->setRequestParam('mt', $message_template_group->message_type());
2032
+
2033
+			$query_args = $this->_reset_to_default_template();
2034
+
2035
+			if (empty($query_args['id'])) {
2036
+				EE_Error::add_error(
2037
+					esc_html__(
2038
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
2039
+						'event_espresso'
2040
+					),
2041
+					__FILE__,
2042
+					__FUNCTION__,
2043
+					__LINE__
2044
+				);
2045
+				$this->_template_args['error'] = true;
2046
+			} else {
2047
+				$template_label       = $message_template_group->get_template_pack()->label;
2048
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2049
+				EE_Error::add_success(
2050
+					sprintf(
2051
+						esc_html__(
2052
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2053
+							'event_espresso'
2054
+						),
2055
+						$template_label,
2056
+						$template_pack_labels->template_pack
2057
+					)
2058
+				);
2059
+				// generate the redirect url for js.
2060
+				$url = self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2061
+
2062
+				$this->_template_args['data']['redirect_url'] = $url;
2063
+				$this->_template_args['success']              = true;
2064
+			}
2065
+
2066
+			$this->_return_json();
2067
+		}
2068
+	}
2069
+
2070
+
2071
+	/**
2072
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2073
+	 * they want.
2074
+	 *
2075
+	 * @access protected
2076
+	 * @return array|void
2077
+	 * @throws EE_Error
2078
+	 * @throws InvalidArgumentException
2079
+	 * @throws InvalidDataTypeException
2080
+	 * @throws InvalidInterfaceException
2081
+	 * @throws ReflectionException
2082
+	 */
2083
+	protected function _reset_to_default_template()
2084
+	{
2085
+		$templates    = [];
2086
+		$GRP_ID       = $this->request->getRequestParam('GRP_ID', 0, 'int');
2087
+		$messenger    = $this->request->getRequestParam('msgr');
2088
+		$message_type = $this->request->getRequestParam('mt');
2089
+		// we need to make sure we've got the info we need.
2090
+		if (! ($GRP_ID && $messenger && $message_type)) {
2091
+			EE_Error::add_error(
2092
+				esc_html__(
2093
+					'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.',
2094
+					'event_espresso'
2095
+				),
2096
+				__FILE__,
2097
+				__FUNCTION__,
2098
+				__LINE__
2099
+			);
2100
+		}
2101
+
2102
+		// all templates will be reset to whatever the defaults are
2103
+		// for the global template matching the messenger and message type.
2104
+		$success = ! empty($GRP_ID);
2105
+
2106
+		if ($success) {
2107
+			// let's first determine if the incoming template is a global template,
2108
+			// if it isn't then we need to get the global template matching messenger and message type.
2109
+			// $MTPG = $this->getMtgModel()->get_one_by_ID( $GRP_ID );
2110
+
2111
+
2112
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2113
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
2114
+
2115
+			if ($success) {
2116
+				// if successfully deleted, lets generate the new ones.
2117
+				// Note. We set GLOBAL to true, because resets on ANY template
2118
+				// will use the related global template defaults for regeneration.
2119
+				// This means that if a custom template is reset it resets to whatever the related global template is.
2120
+				// HOWEVER, we DO keep the template pack and template variation set
2121
+				// for the current custom template when resetting.
2122
+				$templates = $this->_generate_new_templates($messenger, $message_type, $GRP_ID, true);
2123
+			}
2124
+		}
2125
+
2126
+		// any error messages?
2127
+		if (! $success) {
2128
+			EE_Error::add_error(
2129
+				esc_html__(
2130
+					'Something went wrong with deleting existing templates. Unable to reset to default',
2131
+					'event_espresso'
2132
+				),
2133
+				__FILE__,
2134
+				__FUNCTION__,
2135
+				__LINE__
2136
+			);
2137
+		}
2138
+
2139
+		// all good, let's add a success message!
2140
+		if ($success && ! empty($templates)) {
2141
+			// the info for the template we generated is the first element in the returned array
2142
+			EE_Error::overwrite_success();
2143
+			EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
2144
+		}
2145
+
2146
+
2147
+		$query_args = [
2148
+			'id'      => isset($templates['GRP_ID']) ? $templates['GRP_ID'] : null,
2149
+			'context' => isset($templates['MTP_context']) ? $templates['MTP_context'] : null,
2150
+			'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2151
+		];
2152
+
2153
+		// if called via ajax then we return query args otherwise redirect
2154
+		if ($this->request->isAjax()) {
2155
+			return $query_args;
2156
+		}
2157
+		$this->_redirect_after_action(false, '', '', $query_args, true);
2158
+	}
2159
+
2160
+
2161
+	/**
2162
+	 * Retrieve and set the message preview for display.
2163
+	 *
2164
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2165
+	 * @return string
2166
+	 * @throws ReflectionException
2167
+	 * @throws EE_Error
2168
+	 * @throws InvalidArgumentException
2169
+	 * @throws InvalidDataTypeException
2170
+	 * @throws InvalidInterfaceException
2171
+	 */
2172
+	public function _preview_message($send = false)
2173
+	{
2174
+		// first make sure we've got the necessary parameters
2175
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2176
+		if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
2177
+			EE_Error::add_error(
2178
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2179
+				__FILE__,
2180
+				__FUNCTION__,
2181
+				__LINE__
2182
+			);
2183
+		}
2184
+
2185
+		$context = $this->request->getRequestParam('context');
2186
+		// get the preview!
2187
+		$preview = EED_Messages::preview_message(
2188
+			$this->_active_message_type_name,
2189
+			$context,
2190
+			$this->_active_messenger_name,
2191
+			$send
2192
+		);
2193
+
2194
+		if ($send) {
2195
+			return $preview;
2196
+		}
2197
+
2198
+		// if we have an evt_id set on the request, use it.
2199
+		$EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
2200
+
2201
+		// let's add a button to go back to the edit view
2202
+		$query_args             = [
2203
+			'id'      => $GRP_ID,
2204
+			'evt_id'  => $EVT_ID,
2205
+			'context' => $context,
2206
+			'action'  => 'edit_message_template',
2207
+		];
2208
+		$go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2209
+		$preview_button         = '<a href="'
2210
+								  . $go_back_url
2211
+								  . '" class="button-secondary messages-preview-go-back-button">'
2212
+								  . esc_html__('Go Back to Edit', 'event_espresso')
2213
+								  . '</a>';
2214
+		$message_types          = $this->get_installed_message_types();
2215
+		$active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
2216
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2217
+			? ucwords($active_messenger->label['singular'])
2218
+			: esc_html__('Unknown Messenger', 'event_espresso');
2219
+		// let's provide a helpful title for context
2220
+		$preview_title = sprintf(
2221
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2222
+			$active_messenger_label,
2223
+			ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2224
+		);
2225
+		if (empty($preview)) {
2226
+			$this->noEventsErrorMessage();
2227
+		}
2228
+		// setup display of preview.
2229
+		$this->_admin_page_title                    = $preview_title;
2230
+		$this->_template_args['admin_page_title']   = $preview_title;
2231
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2232
+		$this->_template_args['data']['force_json'] = true;
2233
+
2234
+		return '';
2235
+	}
2236
+
2237
+
2238
+	/**
2239
+	 * Used to set an error if there are no events available for generating a preview/test send.
2240
+	 *
2241
+	 * @param bool $test_send Whether the error should be generated for the context of a test send.
2242
+	 */
2243
+	protected function noEventsErrorMessage($test_send = false)
2244
+	{
2245
+		$events_url = parent::add_query_args_and_nonce(
2246
+			[
2247
+				'action' => 'default',
2248
+				'page'   => 'espresso_events',
2249
+			],
2250
+			admin_url('admin.php')
2251
+		);
2252
+		$message    = $test_send
2253
+			? esc_html__(
2254
+				'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!',
2255
+				'event_espresso'
2256
+			)
2257
+			: esc_html__(
2258
+				'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!',
2259
+				'event_espresso'
2260
+			);
2261
+
2262
+		EE_Error::add_attention(
2263
+			sprintf(
2264
+				$message,
2265
+				"<a href='{$events_url}'>",
2266
+				'</a>'
2267
+			)
2268
+		);
2269
+	}
2270
+
2271
+
2272
+	/**
2273
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2274
+	 * gets called automatically.
2275
+	 *
2276
+	 * @return void
2277
+	 * @throws EE_Error
2278
+	 * @since 4.5.0
2279
+	 *
2280
+	 */
2281
+	protected function _display_preview_message()
2282
+	{
2283
+		$this->display_admin_page_with_no_sidebar();
2284
+	}
2285
+
2286
+
2287
+	/**
2288
+	 * registers metaboxes that should show up on the "edit_message_template" page
2289
+	 *
2290
+	 * @access protected
2291
+	 * @return void
2292
+	 */
2293
+	protected function _register_edit_meta_boxes()
2294
+	{
2295
+		add_meta_box(
2296
+			'mtp_valid_shortcodes',
2297
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2298
+			[$this, 'shortcode_meta_box'],
2299
+			$this->_current_screen->id,
2300
+			'side'
2301
+		);
2302
+		add_meta_box(
2303
+			'mtp_extra_actions',
2304
+			esc_html__('Extra Actions', 'event_espresso'),
2305
+			[$this, 'extra_actions_meta_box'],
2306
+			$this->_current_screen->id,
2307
+			'side',
2308
+			'high'
2309
+		);
2310
+		add_meta_box(
2311
+			'mtp_templates',
2312
+			esc_html__('Template Styles', 'event_espresso'),
2313
+			[$this, 'template_pack_meta_box'],
2314
+			$this->_current_screen->id,
2315
+			'side',
2316
+			'high'
2317
+		);
2318
+	}
2319
+
2320
+
2321
+	/**
2322
+	 * metabox content for all template pack and variation selection.
2323
+	 *
2324
+	 * @return void
2325
+	 * @throws DomainException
2326
+	 * @throws EE_Error
2327
+	 * @throws InvalidArgumentException
2328
+	 * @throws ReflectionException
2329
+	 * @throws InvalidDataTypeException
2330
+	 * @throws InvalidInterfaceException
2331
+	 * @since 4.5.0
2332
+	 */
2333
+	public function template_pack_meta_box()
2334
+	{
2335
+		$this->_set_message_template_group();
2336
+
2337
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2338
+
2339
+		$tp_select_values = [];
2340
+
2341
+		foreach ($tp_collection as $tp) {
2342
+			// only include template packs that support this messenger and message type!
2343
+			$supports = $tp->get_supports();
2344
+			if (
2345
+				! isset($supports[ $this->_message_template_group->messenger() ])
2346
+				|| ! in_array(
2347
+					$this->_message_template_group->message_type(),
2348
+					$supports[ $this->_message_template_group->messenger() ],
2349
+					true
2350
+				)
2351
+			) {
2352
+				// not supported
2353
+				continue;
2354
+			}
2355
+
2356
+			$tp_select_values[] = [
2357
+				'text' => $tp->label,
2358
+				'id'   => $tp->dbref,
2359
+			];
2360
+		}
2361
+
2362
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2363
+		// the default template pack.  This still allows for the odd template pack to override.
2364
+		if (empty($tp_select_values)) {
2365
+			$tp_select_values[] = [
2366
+				'text' => esc_html__('Default', 'event_espresso'),
2367
+				'id'   => 'default',
2368
+			];
2369
+		}
2370
+
2371
+		// setup variation select values for the currently selected template.
2372
+		$variations               = $this->_message_template_group->get_template_pack()->get_variations(
2373
+			$this->_message_template_group->messenger(),
2374
+			$this->_message_template_group->message_type()
2375
+		);
2376
+		$variations_select_values = [];
2377
+		foreach ($variations as $variation => $label) {
2378
+			$variations_select_values[] = [
2379
+				'text' => $label,
2380
+				'id'   => $variation,
2381
+			];
2382
+		}
2383
+
2384
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2385
+
2386
+		$template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2387
+			'MTP_template_pack',
2388
+			$tp_select_values,
2389
+			$this->_message_template_group->get_template_pack_name()
2390
+		);
2391
+		$template_args['variations_selector']            = EEH_Form_Fields::select_input(
2392
+			'MTP_template_variation',
2393
+			$variations_select_values,
2394
+			$this->_message_template_group->get_template_pack_variation()
2395
+		);
2396
+		$template_args['template_pack_label']            = $template_pack_labels->template_pack;
2397
+		$template_args['template_variation_label']       = $template_pack_labels->template_variation;
2398
+		$template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2399
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2400
+
2401
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2402
+
2403
+		EEH_Template::display_template($template, $template_args);
2404
+	}
2405
+
2406
+
2407
+	/**
2408
+	 * This meta box holds any extra actions related to Message Templates
2409
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2410
+	 *
2411
+	 * @access  public
2412
+	 * @return void
2413
+	 * @throws EE_Error
2414
+	 */
2415
+	public function extra_actions_meta_box()
2416
+	{
2417
+		$template_form_fields = [];
2418
+
2419
+		$extra_args = [
2420
+			'msgr'   => $this->_message_template_group->messenger(),
2421
+			'mt'     => $this->_message_template_group->message_type(),
2422
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2423
+		];
2424
+		// first we need to see if there are any fields
2425
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2426
+
2427
+		if (! empty($fields)) {
2428
+			// yup there be fields
2429
+			foreach ($fields as $field => $config) {
2430
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2431
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2432
+				$default  = isset($config['default']) ? $config['default'] : '';
2433
+				$default  = isset($config['value']) ? $config['value'] : $default;
2434
+
2435
+				// if type is hidden and the value is empty
2436
+				// something may have gone wrong so let's correct with the defaults
2437
+				$fix                = $config['input'] === 'hidden'
2438
+									  && isset($existing[ $field ])
2439
+									  && empty($existing[ $field ])
2440
+					? $default
2441
+					: '';
2442
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2443
+					? $existing[ $field ]
2444
+					: $fix;
2445
+
2446
+				$template_form_fields[ $field_id ] = [
2447
+					'name'       => 'test_settings_fld[' . $field . ']',
2448
+					'label'      => $config['label'],
2449
+					'input'      => $config['input'],
2450
+					'type'       => $config['type'],
2451
+					'required'   => $config['required'],
2452
+					'validation' => $config['validation'],
2453
+					'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2454
+					'css_class'  => $config['css_class'],
2455
+					'options'    => isset($config['options']) ? $config['options'] : [],
2456
+					'default'    => $default,
2457
+					'format'     => $config['format'],
2458
+				];
2459
+			}
2460
+		}
2461
+
2462
+		$test_settings_html = ! empty($template_form_fields)
2463
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2464
+			: '';
2465
+
2466
+		// print out $test_settings_fields
2467
+		if (! empty($test_settings_html)) {
2468
+			$test_settings_html .= '<input type="submit" class="button-primary mtp-test-button alignright" ';
2469
+			$test_settings_html .= 'name="test_button" value="';
2470
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2471
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2472
+		}
2473
+
2474
+		// and button
2475
+		$test_settings_html .= '<p>';
2476
+		$test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2477
+		$test_settings_html .= '</p>';
2478
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2479
+		$test_settings_html .= $this->get_action_link_or_button(
2480
+			'reset_to_default',
2481
+			'reset',
2482
+			$extra_args,
2483
+			'button-primary reset-default-button'
2484
+		);
2485
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2486
+		echo $test_settings_html; // already escaped
2487
+	}
2488
+
2489
+
2490
+	/**
2491
+	 * This returns the shortcode selector skeleton for a given context and field.
2492
+	 *
2493
+	 * @param string $field           The name of the field retrieving shortcodes for.
2494
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2495
+	 * @return string
2496
+	 * @throws DomainException
2497
+	 * @throws EE_Error
2498
+	 * @throws InvalidArgumentException
2499
+	 * @throws ReflectionException
2500
+	 * @throws InvalidDataTypeException
2501
+	 * @throws InvalidInterfaceException
2502
+	 * @since 4.9.rc.000
2503
+	 */
2504
+	protected function _get_shortcode_selector($field, $linked_input_id)
2505
+	{
2506
+		$template_args = [
2507
+			'shortcodes'      => $this->_get_shortcodes([$field]),
2508
+			'fieldname'       => $field,
2509
+			'linked_input_id' => $linked_input_id,
2510
+		];
2511
+
2512
+		return EEH_Template::display_template(
2513
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2514
+			$template_args,
2515
+			true
2516
+		);
2517
+	}
2518
+
2519
+
2520
+	/**
2521
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2522
+	 * page)
2523
+	 *
2524
+	 * @access public
2525
+	 * @return void
2526
+	 * @throws EE_Error
2527
+	 * @throws InvalidArgumentException
2528
+	 * @throws ReflectionException
2529
+	 * @throws InvalidDataTypeException
2530
+	 * @throws InvalidInterfaceException
2531
+	 */
2532
+	public function shortcode_meta_box()
2533
+	{
2534
+		$shortcodes = $this->_get_shortcodes([], false);
2535
+		// just make sure the shortcodes property is set
2536
+		// $messenger = $this->_message_template_group->messenger_obj();
2537
+		// now let's set the content depending on the status of the shortcodes array
2538
+		if (empty($shortcodes)) {
2539
+			echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2540
+			return;
2541
+		}
2542
+		?>
2543 2543
         <div style="float:right; margin-top:10px">
2544 2544
             <?php echo $this->_get_help_tab_link('message_template_shortcodes'); // already escaped
2545
-            ?>
2545
+			?>
2546 2546
         </div>
2547 2547
         <p class="small-text">
2548 2548
             <?php printf(
2549
-                esc_html__(
2550
-                    'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2551
-                    'event_espresso'
2552
-                ),
2553
-                '<span class="dashicons dashicons-menu"></span>'
2554
-            ); ?>
2549
+				esc_html__(
2550
+					'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2551
+					'event_espresso'
2552
+				),
2553
+				'<span class="dashicons dashicons-menu"></span>'
2554
+			); ?>
2555 2555
         </p>
2556 2556
         <?php
2557
-    }
2558
-
2559
-
2560
-    /**
2561
-     * used to set the $_shortcodes property for when its needed elsewhere.
2562
-     *
2563
-     * @access protected
2564
-     * @return void
2565
-     * @throws EE_Error
2566
-     * @throws InvalidArgumentException
2567
-     * @throws ReflectionException
2568
-     * @throws InvalidDataTypeException
2569
-     * @throws InvalidInterfaceException
2570
-     */
2571
-    protected function _set_shortcodes()
2572
-    {
2573
-
2574
-        // no need to run this if the property is already set
2575
-        if (! empty($this->_shortcodes)) {
2576
-            return;
2577
-        }
2578
-
2579
-        $this->_shortcodes = $this->_get_shortcodes();
2580
-    }
2581
-
2582
-
2583
-    /**
2584
-     * gets all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2585
-     * property)
2586
-     *
2587
-     * @access  protected
2588
-     * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2589
-     *                         for. Defaults to all (for the given context)
2590
-     * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2591
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2592
-     *                         true just an array of shortcode/label pairs.
2593
-     * @throws EE_Error
2594
-     * @throws InvalidArgumentException
2595
-     * @throws ReflectionException
2596
-     * @throws InvalidDataTypeException
2597
-     * @throws InvalidInterfaceException
2598
-     */
2599
-    protected function _get_shortcodes($fields = [], $merged = true)
2600
-    {
2601
-        $this->_set_message_template_group();
2602
-
2603
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2604
-        $GRP_ID = $this->request->getRequestParam('id', 0, 'int');
2605
-        if (empty($GRP_ID)) {
2606
-            return [];
2607
-        }
2608
-        $context = $this->request->getRequestParam(
2609
-            'messenger',
2610
-            key($this->_message_template_group->contexts_config())
2611
-        );
2612
-        return $this->_message_template_group->get_shortcodes($context, $fields, $merged);
2613
-    }
2614
-
2615
-
2616
-    /**
2617
-     * This sets the _message_template property (containing the called message_template object)
2618
-     *
2619
-     * @access protected
2620
-     * @return void
2621
-     * @throws EE_Error
2622
-     * @throws InvalidArgumentException
2623
-     * @throws ReflectionException
2624
-     * @throws InvalidDataTypeException
2625
-     * @throws InvalidInterfaceException
2626
-     */
2627
-    protected function _set_message_template_group()
2628
-    {
2629
-        // get out if this is already set.
2630
-        if (! empty($this->_message_template_group)) {
2631
-            return;
2632
-        }
2633
-
2634
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2635
-        $GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
2636
-
2637
-        // let's get the message templates
2638
-        $this->_message_template_group = ! empty($GRP_ID)
2639
-            ? $this->getMtgModel()->get_one_by_ID($GRP_ID)
2640
-            : $this->getMtgModel()->create_default_object();
2641
-
2642
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2643
-        $this->_variation     = $this->_message_template_group->get_template_pack_variation();
2644
-    }
2645
-
2646
-
2647
-    /**
2648
-     * sets up a context switcher for edit forms
2649
-     *
2650
-     * @access  protected
2651
-     * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2652
-     * @param array                     $args                  various things the context switcher needs.
2653
-     * @throws EE_Error
2654
-     */
2655
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2656
-    {
2657
-        $context_details = $template_group_object->contexts_config();
2658
-        $context_label   = $template_group_object->context_label();
2659
-        ob_start();
2660
-        ?>
2557
+	}
2558
+
2559
+
2560
+	/**
2561
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2562
+	 *
2563
+	 * @access protected
2564
+	 * @return void
2565
+	 * @throws EE_Error
2566
+	 * @throws InvalidArgumentException
2567
+	 * @throws ReflectionException
2568
+	 * @throws InvalidDataTypeException
2569
+	 * @throws InvalidInterfaceException
2570
+	 */
2571
+	protected function _set_shortcodes()
2572
+	{
2573
+
2574
+		// no need to run this if the property is already set
2575
+		if (! empty($this->_shortcodes)) {
2576
+			return;
2577
+		}
2578
+
2579
+		$this->_shortcodes = $this->_get_shortcodes();
2580
+	}
2581
+
2582
+
2583
+	/**
2584
+	 * gets all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2585
+	 * property)
2586
+	 *
2587
+	 * @access  protected
2588
+	 * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2589
+	 *                         for. Defaults to all (for the given context)
2590
+	 * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2591
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2592
+	 *                         true just an array of shortcode/label pairs.
2593
+	 * @throws EE_Error
2594
+	 * @throws InvalidArgumentException
2595
+	 * @throws ReflectionException
2596
+	 * @throws InvalidDataTypeException
2597
+	 * @throws InvalidInterfaceException
2598
+	 */
2599
+	protected function _get_shortcodes($fields = [], $merged = true)
2600
+	{
2601
+		$this->_set_message_template_group();
2602
+
2603
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2604
+		$GRP_ID = $this->request->getRequestParam('id', 0, 'int');
2605
+		if (empty($GRP_ID)) {
2606
+			return [];
2607
+		}
2608
+		$context = $this->request->getRequestParam(
2609
+			'messenger',
2610
+			key($this->_message_template_group->contexts_config())
2611
+		);
2612
+		return $this->_message_template_group->get_shortcodes($context, $fields, $merged);
2613
+	}
2614
+
2615
+
2616
+	/**
2617
+	 * This sets the _message_template property (containing the called message_template object)
2618
+	 *
2619
+	 * @access protected
2620
+	 * @return void
2621
+	 * @throws EE_Error
2622
+	 * @throws InvalidArgumentException
2623
+	 * @throws ReflectionException
2624
+	 * @throws InvalidDataTypeException
2625
+	 * @throws InvalidInterfaceException
2626
+	 */
2627
+	protected function _set_message_template_group()
2628
+	{
2629
+		// get out if this is already set.
2630
+		if (! empty($this->_message_template_group)) {
2631
+			return;
2632
+		}
2633
+
2634
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2635
+		$GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
2636
+
2637
+		// let's get the message templates
2638
+		$this->_message_template_group = ! empty($GRP_ID)
2639
+			? $this->getMtgModel()->get_one_by_ID($GRP_ID)
2640
+			: $this->getMtgModel()->create_default_object();
2641
+
2642
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2643
+		$this->_variation     = $this->_message_template_group->get_template_pack_variation();
2644
+	}
2645
+
2646
+
2647
+	/**
2648
+	 * sets up a context switcher for edit forms
2649
+	 *
2650
+	 * @access  protected
2651
+	 * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2652
+	 * @param array                     $args                  various things the context switcher needs.
2653
+	 * @throws EE_Error
2654
+	 */
2655
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2656
+	{
2657
+		$context_details = $template_group_object->contexts_config();
2658
+		$context_label   = $template_group_object->context_label();
2659
+		ob_start();
2660
+		?>
2661 2661
         <div class="ee-msg-switcher-container">
2662 2662
             <form method="get" action="<?php echo esc_url_raw(EE_MSG_ADMIN_URL); ?>" id="ee-msg-context-switcher-frm">
2663 2663
                 <?php
2664
-                foreach ($args as $name => $value) {
2665
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2666
-                        continue;
2667
-                    }
2668
-                    ?>
2664
+				foreach ($args as $name => $value) {
2665
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2666
+						continue;
2667
+					}
2668
+					?>
2669 2669
                     <input type="hidden"
2670 2670
                            name="<?php echo esc_attr($name); ?>"
2671 2671
                            value="<?php echo esc_attr($value); ?>"
2672 2672
                     />
2673 2673
                     <?php
2674
-                }
2675
-                // setup nonce_url
2676
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2677
-                $id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2678
-                ?>
2674
+				}
2675
+				// setup nonce_url
2676
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2677
+				$id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2678
+				?>
2679 2679
                 <label for='<?php echo esc_attr($id); ?>' class='screen-reader-text'>
2680 2680
                     <?php esc_html_e('message context options', 'event_espresso'); ?>
2681 2681
                 </label>
2682 2682
                 <select id="<?php echo esc_attr($id); ?>" name="context">
2683 2683
                     <?php
2684
-                    $context_templates = $template_group_object->context_templates();
2685
-                    if (is_array($context_templates)) :
2686
-                        foreach ($context_templates as $context => $template_fields) :
2687
-                            $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2688
-                            ?>
2684
+					$context_templates = $template_group_object->context_templates();
2685
+					if (is_array($context_templates)) :
2686
+						foreach ($context_templates as $context => $template_fields) :
2687
+							$checked = ($context === $args['context']) ? 'selected="selected"' : '';
2688
+							?>
2689 2689
                             <option value="<?php echo esc_attr($context); ?>" <?php echo esc_attr($checked); ?>>
2690 2690
                                 <?php echo $context_details[ $context ]['label']; // already escaped
2691
-                                ?>
2691
+								?>
2692 2692
                             </option>
2693 2693
                         <?php endforeach;
2694
-                    endif; ?>
2694
+					endif; ?>
2695 2695
                 </select>
2696 2696
                 <?php $button_text = sprintf(
2697
-                    esc_html__('Switch %s', 'event_espresso'),
2698
-                    ucwords($context_label['label'])
2699
-                ); ?>
2697
+					esc_html__('Switch %s', 'event_espresso'),
2698
+					ucwords($context_label['label'])
2699
+				); ?>
2700 2700
                 <input class='button-secondary'
2701 2701
                        id="submit-msg-context-switcher-sbmt"
2702 2702
                        type="submit"
@@ -2704,1989 +2704,1989 @@  discard block
 block discarded – undo
2704 2704
                 />
2705 2705
             </form>
2706 2706
             <?php echo $args['extra']; // already escaped
2707
-            ?>
2707
+			?>
2708 2708
         </div> <!-- end .ee-msg-switcher-container -->
2709 2709
         <?php
2710
-        $this->_context_switcher = ob_get_clean();
2711
-    }
2712
-
2713
-
2714
-    /**
2715
-     * @param bool $new
2716
-     * @throws EE_Error
2717
-     * @throws ReflectionException
2718
-     */
2719
-    protected function _insert_or_update_message_template($new = false)
2720
-    {
2721
-        $form_data    = $this->getMessageTemplateFormData();
2722
-        $GRP_ID       = $form_data['GRP_ID'];
2723
-        $messenger    = $form_data['MTP_messenger'];
2724
-        $message_type = $form_data['MTP_message_type'];
2725
-        $context      = $form_data['MTP_context'];
2726
-
2727
-        // if this is "new" then we need to generate the default contexts
2728
-        // for the selected messenger/message_type for user to edit.
2729
-        list($success, $query_args) = $new
2730
-            ? $this->generateNewTemplates($GRP_ID, $messenger, $message_type)
2731
-            : $this->updateExistingTemplates($GRP_ID, $messenger, $message_type, $context, $form_data);
2732
-
2733
-        $success     = $success ? 1 : 0;
2734
-        $action_desc = $new ? 'created' : 'updated';
2735
-        $item_desc   = $this->generateUpdateDescription($messenger, $message_type, $context);
2736
-        $override    = $this->performTestSendAfterUpdate($messenger, $message_type, $context);
2737
-
2738
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
2739
-    }
2740
-
2741
-
2742
-    /**
2743
-     * retrieve and sanitize form data
2744
-     *
2745
-     * @return array
2746
-     * @since $VID:$
2747
-     */
2748
-    protected function getMessageTemplateFormData()
2749
-    {
2750
-        return [
2751
-            'GRP_ID'           => $this->request->getRequestParam('GRP_ID', 0, 'int'),
2752
-            'MTP_context'      => strtolower($this->request->getRequestParam('MTP_context', '')),
2753
-            'MTP_messenger'    => strtolower($this->request->getRequestParam('MTP_messenger', '')),
2754
-            'MTP_message_type' => strtolower($this->request->getRequestParam('MTP_message_type', '')),
2755
-            'MTP_user_id'      => $this->request->getRequestParam('MTP_user_id', 0, 'int'),
2756
-            'MTP_is_global'    => $this->request->getRequestParam('MTP_is_global', 0, 'int'),
2757
-            'MTP_is_override'  => $this->request->getRequestParam('MTP_is_override', 0, 'int'),
2758
-            'MTP_deleted'      => $this->request->getRequestParam('MTP_deleted', 0, 'int'),
2759
-            'MTP_is_active'    => $this->request->getRequestParam('MTP_is_active', 0, 'int'),
2760
-        ];
2761
-    }
2762
-
2763
-
2764
-    /**
2765
-     * @param int    $GRP_ID
2766
-     * @param string $messenger
2767
-     * @param string $message_type
2768
-     * @return array no return on AJAX requests
2769
-     * @throws EE_Error
2770
-     * @throws ReflectionException
2771
-     * @since $VID:$
2772
-     */
2773
-    private function generateNewTemplates($GRP_ID, $messenger, $message_type)
2774
-    {
2775
-        $new_templates = $this->_generate_new_templates($messenger, [$message_type], $GRP_ID);
2776
-        $success       = ! empty($new_templates);
2777
-
2778
-        // we return things differently if doing ajax
2779
-        if ($this->request->isAjax()) {
2780
-            $this->_template_args['success'] = $success;
2781
-            $this->_template_args['error']   = ! $success;
2782
-            $this->_template_args['content'] = '';
2783
-            $this->_template_args['data']    = [
2784
-                'grpID'        => $new_templates['GRP_ID'],
2785
-                'templateName' => $new_templates['template_name'],
2786
-            ];
2787
-            if ($success) {
2788
-                EE_Error::overwrite_success();
2789
-                EE_Error::add_success(
2790
-                    esc_html__(
2791
-                        '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.',
2792
-                        'event_espresso'
2793
-                    )
2794
-                );
2795
-            }
2796
-            $this->_return_json();
2797
-        }
2798
-        return [
2799
-            $success,
2800
-            // 'query_args'
2801
-            [
2802
-                'id'      => $new_templates['GRP_ID'],
2803
-                'context' => $new_templates['MTP_context'],
2804
-                'action'  => 'edit_message_template',
2805
-            ],
2806
-        ];
2807
-    }
2808
-
2809
-
2810
-    /**
2811
-     * @param int    $GRP_ID
2812
-     * @param string $messenger
2813
-     * @param string $message_type
2814
-     * @param string $context
2815
-     * @param array  $form_data
2816
-     * @return array
2817
-     * @throws EE_Error
2818
-     * @since $VID:$
2819
-     */
2820
-    private function updateExistingTemplates(
2821
-        $GRP_ID,
2822
-        $messenger,
2823
-        $message_type,
2824
-        $context,
2825
-        array $form_data
2826
-    ) {
2827
-        $success         = false;
2828
-        $template_fields = $this->getTemplateFields();
2829
-        if ($template_fields) {
2830
-            // if field data is valid, then success will be true
2831
-            $success = $this->validateTemplateFields(
2832
-                $messenger,
2833
-                $message_type,
2834
-                $context,
2835
-                $template_fields
2836
-            );
2837
-            if ($success) {
2838
-                $field_data = [];
2839
-                foreach ($template_fields as $template_field => $content) {
2840
-                    // combine top-level form data with content for this field
2841
-                    $field_data = $this->getTemplateFieldFormData($content, $form_data);
2842
-                    $success    = $this->updateMessageTemplates($template_field, $field_data) ? $success : false;
2843
-                }
2844
-                // we can use the last set_column_values for the MTPG update
2845
-                // (because its the same for all of these specific MTPs)
2846
-                $success = $this->updateMessageTemplateGroup($field_data) ? $success : false;
2847
-            }
2848
-        }
2849
-
2850
-        return [
2851
-            $success,
2852
-            // 'query_args'
2853
-            [
2854
-                'id'      => $GRP_ID,
2855
-                'context' => $context,
2856
-                'action'  => 'edit_message_template',
2857
-            ],
2858
-        ];
2859
-    }
2860
-
2861
-
2862
-    /**
2863
-     * @return array
2864
-     * @since $VID:$
2865
-     */
2866
-    private function getTemplateFields()
2867
-    {
2868
-        $template_fields = $this->request->getRequestParam('MTP_template_fields', null, 'html', true);
2869
-        if (empty($template_fields)) {
2870
-            EE_Error::add_error(
2871
-                esc_html__(
2872
-                    'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2873
-                    'event_espresso'
2874
-                ),
2875
-                __FILE__,
2876
-                __FUNCTION__,
2877
-                __LINE__
2878
-            );
2879
-            return null;
2880
-        }
2881
-        // messages content is expected to be escaped
2882
-        return EEH_Array::addSlashesRecursively($template_fields);
2883
-    }
2884
-
2885
-
2886
-    /**
2887
-     * @param string $messenger
2888
-     * @param string $message_type
2889
-     * @param string $context
2890
-     * @param array  $template_fields
2891
-     * @return bool
2892
-     * @throws EE_Error
2893
-     * @since   $VID:$
2894
-     */
2895
-    private function validateTemplateFields(
2896
-        $messenger,
2897
-        $message_type,
2898
-        $context,
2899
-        array $template_fields
2900
-    ) {
2901
-        // first validate all fields!
2902
-        // this filter allows client code to add its own validation to the template fields as well.
2903
-        // returning an empty array means everything passed validation.
2904
-        // errors in validation should be represented in an array with the following shape:
2905
-        // array(
2906
-        //   'fieldname' => array(
2907
-        //          'msg' => 'error message'
2908
-        //          'value' => 'value for field producing error'
2909
-        // )
2910
-        $custom_validation = (array) apply_filters(
2911
-            'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2912
-            [],
2913
-            $template_fields,
2914
-            $context,
2915
-            $messenger,
2916
-            $message_type
2917
-        );
2918
-
2919
-        $system_validation = $this->getMtgModel()->validate(
2920
-            $template_fields,
2921
-            $context,
2922
-            $messenger,
2923
-            $message_type
2924
-        );
2925
-
2926
-        $system_validation = ! is_array($system_validation) && $system_validation ? [] : $system_validation;
2927
-        $validates         = array_merge($custom_validation, $system_validation);
2928
-
2929
-        // if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2930
-        // appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2931
-        //  WE need to make sure there is no actual error messages in validates.
2932
-        if (empty($validates)) {
2933
-            return true;
2934
-        }
2935
-
2936
-        // add the transient so when the form loads we know which fields to highlight
2937
-        $this->_add_transient('edit_message_template', $validates);
2938
-        // setup notices
2939
-        foreach ($validates as $error) {
2940
-            if (isset($error['msg'])) {
2941
-                EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2942
-            }
2943
-        }
2944
-        return false;
2945
-    }
2946
-
2947
-
2948
-    /**
2949
-     * @param array $field_data
2950
-     * @param array $form_data
2951
-     * @return array
2952
-     * @since   $VID:$
2953
-     */
2954
-    private function getTemplateFieldFormData(array $field_data, array $form_data)
2955
-    {
2956
-        return $form_data + [
2957
-                'MTP_ID'             => $field_data['MTP_ID'],
2958
-                'MTP_template_field' => $field_data['name'],
2959
-                // if they aren't allowed to use all JS, restrict them to standard allowed post tags
2960
-                'MTP_content'        => ! current_user_can('unfiltered_html')
2961
-                    ? $this->sanitizeMessageTemplateContent($field_data['content'])
2962
-                    : $field_data['content'],
2963
-            ];
2964
-    }
2965
-
2966
-
2967
-    /**
2968
-     * @param string $template_field
2969
-     * @param array  $form_data
2970
-     * @return bool
2971
-     * @throws EE_Error
2972
-     * @since $VID:$
2973
-     */
2974
-    private function updateMessageTemplates($template_field, array $form_data)
2975
-    {
2976
-        $MTP_ID                  = $form_data['MTP_ID'];
2977
-        $message_template_fields = [
2978
-            'GRP_ID'             => $form_data['GRP_ID'],
2979
-            'MTP_template_field' => $form_data['MTP_template_field'],
2980
-            'MTP_context'        => $form_data['MTP_context'],
2981
-            'MTP_content'        => $form_data['MTP_content'],
2982
-        ];
2983
-
2984
-        $hasMtpID = ! empty($MTP_ID);
2985
-        // if we have a MTP_ID for this field then update it, otherwise insert.
2986
-        // this has already been through the template field validator and sanitized, so it will be
2987
-        // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2988
-        // message template field in a messenger/message type and existing users don't have the
2989
-        // default setup for it.
2990
-        // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2991
-        $updated = $hasMtpID
2992
-            ? $this->getMtpModel()->update($message_template_fields, [['MTP_ID' => $MTP_ID]])
2993
-            : $this->getMtpModel()->insert($message_template_fields);
2994
-
2995
-        $insert_failed = ! $hasMtpID && ! $updated;
2996
-        // updates will return 0 if the field was not changed (ie: no changes = nothing actually updated)
2997
-        // but we won't consider that a problem, but if it returns false, then something went BOOM!
2998
-        $update_failed = $hasMtpID && $updated === false;
2999
-
3000
-        if ($insert_failed || $update_failed) {
3001
-            EE_Error::add_error(
3002
-                sprintf(
3003
-                    esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
3004
-                    $template_field
3005
-                ),
3006
-                __FILE__,
3007
-                __FUNCTION__,
3008
-                __LINE__
3009
-            );
3010
-            return false;
3011
-        }
3012
-        return true;
3013
-    }
3014
-
3015
-
3016
-    /**
3017
-     * @param array $form_data
3018
-     * @return bool
3019
-     * @throws EE_Error
3020
-     * @since $VID:$
3021
-     */
3022
-    private function updateMessageTemplateGroup(array $form_data)
3023
-    {
3024
-        $GRP_ID  = $form_data['GRP_ID'];
3025
-        $updated = $this->getMtgModel()->update(
3026
-        // fields and values
3027
-            [
3028
-                'MTP_user_id'      => $form_data['MTP_user_id'],
3029
-                'MTP_messenger'    => $form_data['MTP_messenger'],
3030
-                'MTP_message_type' => $form_data['MTP_message_type'],
3031
-                'MTP_is_global'    => $form_data['MTP_is_global'],
3032
-                'MTP_is_override'  => $form_data['MTP_is_override'],
3033
-                'MTP_deleted'      => $form_data['MTP_deleted'],
3034
-                'MTP_is_active'    => $form_data['MTP_is_active'],
3035
-                'MTP_name'         => $this->request->getRequestParam('ee_msg_non_global_fields[MTP_name]', ''),
3036
-                'MTP_description'  => $this->request->getRequestParam(
3037
-                    'ee_msg_non_global_fields[MTP_description]',
3038
-                    ''
3039
-                ),
3040
-            ],
3041
-            // where
3042
-            [['GRP_ID' => $GRP_ID]]
3043
-        );
3044
-
3045
-        if ($updated === false) {
3046
-            EE_Error::add_error(
3047
-                sprintf(
3048
-                    esc_html__(
3049
-                        'The Message Template Group (%d) was NOT updated for some reason',
3050
-                        'event_espresso'
3051
-                    ),
3052
-                    $form_data['GRP_ID']
3053
-                ),
3054
-                __FILE__,
3055
-                __FUNCTION__,
3056
-                __LINE__
3057
-            );
3058
-            return false;
3059
-        }
3060
-        // k now we need to ensure the template_pack and template_variation fields are set.
3061
-        $template_pack      = $this->request->getRequestParam('MTP_template_pack', 'default');
3062
-        $template_variation = $this->request->getRequestParam('MTP_template_variation', 'default');
3063
-
3064
-        $message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3065
-        if ($message_template_group instanceof EE_Message_Template_Group) {
3066
-            $message_template_group->set_template_pack_name($template_pack);
3067
-            $message_template_group->set_template_pack_variation($template_variation);
3068
-        }
3069
-        return true;
3070
-    }
3071
-
3072
-
3073
-    /**
3074
-     * recursively runs wp_kses() on message template content in a model safe manner
3075
-     *
3076
-     * @param array|string $content
3077
-     * @return array|string
3078
-     * @since   $VID:$
3079
-     */
3080
-    private function sanitizeMessageTemplateContent($content)
3081
-    {
3082
-        if (is_array($content)) {
3083
-            foreach ($content as $key => $value) {
3084
-                $content[ $key ] = $this->sanitizeMessageTemplateContent($value);
3085
-            }
3086
-            return $content;
3087
-        }
3088
-        // remove slashes so wp_kses() works properly
3089
-        // wp_kses_stripslashes() only removes slashes from double-quotes,
3090
-        // so attributes using single quotes always appear invalid.
3091
-        $content = stripslashes($content);
3092
-        $content = wp_kses($content, wp_kses_allowed_html('post'));
3093
-        // But currently the models expect slashed data, so after wp_kses()
3094
-        // runs we need to re-slash the data. Sheesh.
3095
-        // See https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
3096
-        return addslashes($content);
3097
-    }
3098
-
3099
-
3100
-    /**
3101
-     * @param string $messenger
3102
-     * @param string $message_type
3103
-     * @param string $context
3104
-     * @return string
3105
-     * @since $VID:$
3106
-     */
3107
-    private function generateUpdateDescription($messenger, $message_type, $context)
3108
-    {
3109
-        // need the message type and messenger objects to be able to use the labels for the notices
3110
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger);
3111
-        $messenger_label  = $messenger_object instanceof EE_messenger
3112
-            ? ucwords($messenger_object->label['singular'])
3113
-            : '';
3114
-
3115
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type);
3116
-        $message_type_label  = $message_type_object instanceof EE_message_type
3117
-            ? ucwords($message_type_object->label['singular'])
3118
-            : '';
3119
-
3120
-        $context   = ucwords(str_replace('_', ' ', $context));
3121
-        $item_desc = $messenger_label && $message_type_label
3122
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
3123
-            : '';
3124
-        $item_desc .= 'Message Template';
3125
-        return $item_desc;
3126
-    }
3127
-
3128
-
3129
-    /**
3130
-     * @param string $messenger
3131
-     * @param string $message_type
3132
-     * @param string $context
3133
-     * @return bool
3134
-     * @throws EE_Error
3135
-     * @throws ReflectionException
3136
-     * @since $VID:$
3137
-     */
3138
-    private function performTestSendAfterUpdate($messenger, $message_type, $context)
3139
-    {
3140
-        // was a test send triggered?
3141
-        if ($this->request->getRequestParam('test_button', false, 'bool')) {
3142
-            EE_Error::overwrite_success();
3143
-            $this->_do_test_send($context, $messenger, $message_type);
3144
-            return true;
3145
-        }
3146
-        return false;
3147
-    }
3148
-
3149
-
3150
-    /**
3151
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
3152
-     *
3153
-     * @param string $context      what context being tested
3154
-     * @param string $messenger    messenger being tested
3155
-     * @param string $message_type message type being tested
3156
-     * @throws EE_Error
3157
-     * @throws InvalidArgumentException
3158
-     * @throws InvalidDataTypeException
3159
-     * @throws InvalidInterfaceException
3160
-     * @throws ReflectionException
3161
-     */
3162
-    protected function _do_test_send($context, $messenger, $message_type)
3163
-    {
3164
-        // set things up for preview
3165
-        $this->request->setRequestParam('messenger', $messenger);
3166
-        $this->request->setRequestParam('message_type', $message_type);
3167
-        $this->request->setRequestParam('context', $context);
3168
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
3169
-        $this->request->setRequestParam('GRP_ID', $GRP_ID);
3170
-
3171
-        $active_messenger  = $this->_message_resource_manager->get_active_messenger($messenger);
3172
-        $test_settings_fld = $this->request->getRequestParam('test_settings_fld', [], 'string', true);
3173
-
3174
-        // let's save any existing fields that might be required by the messenger
3175
-        if (
3176
-            ! empty($test_settings_fld)
3177
-            && $active_messenger instanceof EE_messenger
3178
-            && apply_filters(
3179
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3180
-                true,
3181
-                $test_settings_fld,
3182
-                $active_messenger
3183
-            )
3184
-        ) {
3185
-            $active_messenger->set_existing_test_settings($test_settings_fld);
3186
-        }
3187
-
3188
-        /**
3189
-         * Use filter to add additional controls on whether message can send or not
3190
-         */
3191
-        if (
3192
-            apply_filters(
3193
-                'FHEE__Messages_Admin_Page__do_test_send__can_send',
3194
-                true,
3195
-                $context,
3196
-                $this->request->requestParams(),
3197
-                $messenger,
3198
-                $message_type
3199
-            )
3200
-        ) {
3201
-            if (EEM_Event::instance()->count() > 0) {
3202
-                $success = $this->_preview_message(true);
3203
-                if ($success) {
3204
-                    EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
3205
-                } else {
3206
-                    EE_Error::add_error(
3207
-                        esc_html__('The test message was not sent', 'event_espresso'),
3208
-                        __FILE__,
3209
-                        __FUNCTION__,
3210
-                        __LINE__
3211
-                    );
3212
-                }
3213
-            } else {
3214
-                $this->noEventsErrorMessage(true);
3215
-            }
3216
-        }
3217
-    }
3218
-
3219
-
3220
-    /**
3221
-     * _generate_new_templates
3222
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3223
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3224
-     * for the event.
3225
-     *
3226
-     *
3227
-     * @param string $messenger      the messenger we are generating templates for
3228
-     * @param array  $message_types  array of message types that the templates are generated for.
3229
-     * @param int    $GRP_ID         If this is a custom template being generated then a GRP_ID needs to be included to
3230
-     *                               indicate the message_template_group being used as the base.
3231
-     *
3232
-     * @param bool   $global
3233
-     *
3234
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
3235
-     *                               encountering problems.
3236
-     * @throws EE_Error
3237
-     * @throws ReflectionException
3238
-     */
3239
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3240
-    {
3241
-        // if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3242
-        // just don't generate any templates.
3243
-        if (empty($message_types)) {
3244
-            return [];
3245
-        }
3246
-
3247
-        $templates = EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3248
-        return $templates[0];
3249
-    }
3250
-
3251
-
3252
-    /**
3253
-     * [_trash_or_restore_message_template]
3254
-     *
3255
-     * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3256
-     * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3257
-     *                        an individual context (FALSE).
3258
-     * @return void
3259
-     * @throws EE_Error
3260
-     * @throws InvalidArgumentException
3261
-     * @throws InvalidDataTypeException
3262
-     * @throws InvalidInterfaceException
3263
-     */
3264
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
3265
-    {
3266
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3267
-
3268
-        $success = 1;
3269
-
3270
-        // incoming GRP_IDs
3271
-        if ($all) {
3272
-            // Checkboxes
3273
-            $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3274
-            if (! empty($checkboxes)) {
3275
-                // if array has more than one element then success message should be plural.
3276
-                // todo: what about nonce?
3277
-                $success = count($checkboxes) > 1 ? 2 : 1;
3278
-
3279
-                // cycle through checkboxes
3280
-                while (list($GRP_ID, $value) = each($checkboxes)) {
3281
-                    $trashed_or_restored = $trash
3282
-                        ? $this->getMtgModel()->delete_by_ID($GRP_ID)
3283
-                        : $this->getMtgModel()->restore_by_ID($GRP_ID);
3284
-                    if (! $trashed_or_restored) {
3285
-                        $success = 0;
3286
-                    }
3287
-                }
3288
-            } else {
3289
-                // grab single GRP_ID and handle
3290
-                $GRP_ID = $this->request->getRequestParam('id', 0, 'int');
3291
-                if (! empty($GRP_ID)) {
3292
-                    $trashed_or_restored = $trash
3293
-                        ? $this->getMtgModel()->delete_by_ID($GRP_ID)
3294
-                        : $this->getMtgModel()->restore_by_ID($GRP_ID);
3295
-                    if (! $trashed_or_restored) {
3296
-                        $success = 0;
3297
-                    }
3298
-                } else {
3299
-                    $success = 0;
3300
-                }
3301
-            }
3302
-        }
3303
-
3304
-        $action_desc = $trash
3305
-            ? esc_html__('moved to the trash', 'event_espresso')
3306
-            : esc_html__('restored', 'event_espresso');
3307
-
3308
-        $template_switch = $this->request->getRequestParam('template_switch', false, 'bool');
3309
-        $action_desc     = $template_switch ? esc_html__('switched', 'event_espresso') : $action_desc;
3310
-
3311
-        $item_desc = $all ? _n(
3312
-            'Message Template Group',
3313
-            'Message Template Groups',
3314
-            $success,
3315
-            'event_espresso'
3316
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3317
-
3318
-        $item_desc = $template_switch
3319
-            ? _n('template', 'templates', $success, 'event_espresso')
3320
-            : $item_desc;
3321
-
3322
-        $this->_redirect_after_action($success, $item_desc, $action_desc, []);
3323
-    }
3324
-
3325
-
3326
-    /**
3327
-     * [_delete_message_template]
3328
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3329
-     *
3330
-     * @return void
3331
-     * @throws EE_Error
3332
-     * @throws InvalidArgumentException
3333
-     * @throws InvalidDataTypeException
3334
-     * @throws InvalidInterfaceException
3335
-     * @throws ReflectionException
3336
-     */
3337
-    protected function _delete_message_template()
3338
-    {
3339
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3340
-
3341
-        // checkboxes
3342
-        $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3343
-        if (! empty($checkboxes)) {
3344
-            // if array has more than one element then success message should be plural
3345
-            $success = count($checkboxes) > 1 ? 2 : 1;
3346
-
3347
-            // cycle through bulk action checkboxes
3348
-            while (list($GRP_ID, $value) = each($checkboxes)) {
3349
-                $success = $this->_delete_mtp_permanently($GRP_ID) ? $success : false;
3350
-            }
3351
-        } else {
3352
-            // grab single grp_id and delete
3353
-            $GRP_ID  = $this->request->getRequestParam('id', 0, 'int');
3354
-            $success = $this->_delete_mtp_permanently($GRP_ID);
3355
-        }
3356
-
3357
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', []);
3358
-    }
3359
-
3360
-
3361
-    /**
3362
-     * helper for permanently deleting a mtP group and all related message_templates
3363
-     *
3364
-     * @param int  $GRP_ID        The group being deleted
3365
-     * @param bool $include_group whether to delete the Message Template Group as well.
3366
-     * @return bool boolean to indicate the success of the deletes or not.
3367
-     * @throws EE_Error
3368
-     * @throws InvalidArgumentException
3369
-     * @throws InvalidDataTypeException
3370
-     * @throws InvalidInterfaceException
3371
-     * @throws ReflectionException
3372
-     * @throws ReflectionException
3373
-     */
3374
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3375
-    {
3376
-        $success = true;
3377
-        // first let's GET this group
3378
-        $MTG = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3379
-        // then delete permanently all the related Message Templates
3380
-        $deleted = $MTG->delete_related_permanently('Message_Template');
3381
-
3382
-        if ($deleted === 0) {
3383
-            $success = false;
3384
-        }
3385
-
3386
-        // now delete permanently this particular group
3387
-
3388
-        if ($include_group && ! $MTG->delete_permanently()) {
3389
-            $success = false;
3390
-        }
3391
-
3392
-        return $success;
3393
-    }
3394
-
3395
-
3396
-    /**
3397
-     *    _learn_more_about_message_templates_link
3398
-     *
3399
-     * @access protected
3400
-     * @return string
3401
-     */
3402
-    protected function _learn_more_about_message_templates_link()
3403
-    {
3404
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3405
-               . esc_html__('learn more about how message templates works', 'event_espresso')
3406
-               . '</a>';
3407
-    }
3408
-
3409
-
3410
-    /**
3411
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3412
-     * ajax and other routes.
3413
-     *
3414
-     * @return void
3415
-     * @throws DomainException
3416
-     * @throws EE_Error
3417
-     */
3418
-    protected function _settings()
3419
-    {
3420
-        $this->_set_m_mt_settings();
3421
-
3422
-        // let's setup the messenger tabs
3423
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3424
-            $this->_m_mt_settings['messenger_tabs'],
3425
-            'messenger_links',
3426
-            '|',
3427
-            $this->request->getRequestParam('selected_messenger', 'email')
3428
-        );
3429
-
3430
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3431
-        $this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
3432
-
3433
-        $this->display_admin_page_with_sidebar();
3434
-    }
3435
-
3436
-
3437
-    /**
3438
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3439
-     *
3440
-     * @access protected
3441
-     * @return void
3442
-     * @throws DomainException
3443
-     */
3444
-    protected function _set_m_mt_settings()
3445
-    {
3446
-        // first if this is already set then lets get out no need to regenerate data.
3447
-        if (! empty($this->_m_mt_settings)) {
3448
-            return;
3449
-        }
3450
-
3451
-        // get all installed messengers and message_types
3452
-        $messengers    = $this->_message_resource_manager->installed_messengers();
3453
-        $message_types = $this->_message_resource_manager->installed_message_types();
3454
-
3455
-
3456
-        // assemble the array for the _tab_text_links helper
3457
-
3458
-        foreach ($messengers as $messenger) {
3459
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3460
-                'label' => ucwords($messenger->label['singular']),
3461
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3462
-                    ? 'messenger-active'
3463
-                    : '',
3464
-                'href'  => $messenger->name,
3465
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3466
-                'slug'  => $messenger->name,
3467
-                'obj'   => $messenger,
3468
-            ];
3469
-
3470
-
3471
-            $message_types_for_messenger = $messenger->get_valid_message_types();
3472
-
3473
-            foreach ($message_types as $message_type) {
3474
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3475
-                // it shouldn't show in either the inactive OR active metabox.
3476
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3477
-                    continue;
3478
-                }
3479
-
3480
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3481
-                    $messenger->name,
3482
-                    $message_type->name
3483
-                )
3484
-                    ? 'active'
3485
-                    : 'inactive';
3486
-
3487
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3488
-                    'label'    => ucwords($message_type->label['singular']),
3489
-                    'class'    => 'message-type-' . $a_or_i,
3490
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3491
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3492
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3493
-                    'title'    => $a_or_i === 'active'
3494
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3495
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3496
-                    'content'  => $a_or_i === 'active'
3497
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
3498
-                        : $this->_message_type_settings_content($message_type, $messenger),
3499
-                    'slug'     => $message_type->name,
3500
-                    'active'   => $a_or_i === 'active',
3501
-                    'obj'      => $message_type,
3502
-                ];
3503
-            }
3504
-        }
3505
-    }
3506
-
3507
-
3508
-    /**
3509
-     * This just prepares the content for the message type settings
3510
-     *
3511
-     * @param EE_message_type $message_type The message type object
3512
-     * @param EE_messenger    $messenger    The messenger object
3513
-     * @param boolean         $active       Whether the message type is active or not
3514
-     * @return string html output for the content
3515
-     * @throws DomainException
3516
-     */
3517
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
3518
-    {
3519
-        // get message type fields
3520
-        $fields                                         = $message_type->get_admin_settings_fields();
3521
-        $settings_template_args['template_form_fields'] = '';
3522
-
3523
-        if (! empty($fields) && $active) {
3524
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3525
-            foreach ($fields as $fldname => $fldprops) {
3526
-                $field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3527
-                $template_form_field[ $field_id ] = [
3528
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3529
-                    'label'      => $fldprops['label'],
3530
-                    'input'      => $fldprops['field_type'],
3531
-                    'type'       => $fldprops['value_type'],
3532
-                    'required'   => $fldprops['required'],
3533
-                    'validation' => $fldprops['validation'],
3534
-                    'value'      => isset($existing_settings[ $fldname ])
3535
-                        ? $existing_settings[ $fldname ]
3536
-                        : $fldprops['default'],
3537
-                    'options'    => isset($fldprops['options'])
3538
-                        ? $fldprops['options']
3539
-                        : [],
3540
-                    'default'    => isset($existing_settings[ $fldname ])
3541
-                        ? $existing_settings[ $fldname ]
3542
-                        : $fldprops['default'],
3543
-                    'css_class'  => 'no-drag',
3544
-                    'format'     => $fldprops['format'],
3545
-                ];
3546
-            }
3547
-
3548
-
3549
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3550
-                ? $this->_generate_admin_form_fields(
3551
-                    $template_form_field,
3552
-                    'string',
3553
-                    'ee_mt_activate_form'
3554
-                )
3555
-                : '';
3556
-        }
3557
-
3558
-        $settings_template_args['description'] = $message_type->description;
3559
-        // we also need some hidden fields
3560
-        $hidden_fields = [
3561
-            'message_type_settings[messenger]' . $message_type->name    => [
3562
-                'type'  => 'hidden',
3563
-                'value' => $messenger->name,
3564
-            ],
3565
-            'message_type_settings[message_type]' . $message_type->name => [
3566
-                'type'  => 'hidden',
3567
-                'value' => $message_type->name,
3568
-            ],
3569
-            'type' . $message_type->name                                => [
3570
-                'type'  => 'hidden',
3571
-                'value' => 'message_type',
3572
-            ],
3573
-        ];
3574
-
3575
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3576
-            $hidden_fields,
3577
-            'array'
3578
-        );
3579
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3580
-            ? ' hidden'
3581
-            : '';
3582
-
3583
-
3584
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3585
-        return EEH_Template::display_template($template, $settings_template_args, true);
3586
-    }
3587
-
3588
-
3589
-    /**
3590
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3591
-     *
3592
-     * @access protected
3593
-     * @return void
3594
-     * @throws DomainException
3595
-     */
3596
-    protected function _messages_settings_metaboxes()
3597
-    {
3598
-        $this->_set_m_mt_settings();
3599
-        $m_boxes         = $mt_boxes = [];
3600
-        $m_template_args = $mt_template_args = [];
3601
-
3602
-        $selected_messenger = $this->request->getRequestParam('selected_messenger', 'email');
3603
-
3604
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3605
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3606
-                $is_messenger_active = $this->_message_resource_manager->is_messenger_active($messenger);
3607
-                $hide_on_message     = $is_messenger_active ? '' : 'hidden';
3608
-                $hide_off_message    = $is_messenger_active ? 'hidden' : '';
3609
-
3610
-                // messenger meta boxes
3611
-                $active         = $selected_messenger === $messenger;
3612
-                $active_mt_tabs = isset($this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'])
3613
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3614
-                    : '';
3615
-
3616
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3617
-                    esc_html__('%s Settings', 'event_espresso'),
3618
-                    $tab_array['label']
3619
-                );
3620
-
3621
-                $m_template_args[ $messenger . '_a_box' ] = [
3622
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3623
-                    'inactive_message_types' => isset(
3624
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3625
-                    )
3626
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3627
-                        : '',
3628
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3629
-                    'hidden'                 => $active ? '' : ' hidden',
3630
-                    'hide_on_message'        => $hide_on_message,
3631
-                    'messenger'              => $messenger,
3632
-                    'active'                 => $active,
3633
-                ];
3634
-
3635
-                // message type meta boxes
3636
-                // (which is really just the inactive container for each messenger
3637
-                // showing inactive message types for that messenger)
3638
-                $mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3639
-                $mt_template_args[ $messenger . '_i_box' ] = [
3640
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3641
-                    'inactive_message_types' => isset(
3642
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3643
-                    )
3644
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3645
-                        : '',
3646
-                    'hidden'                 => $active ? '' : ' hidden',
3647
-                    'hide_on_message'        => $hide_on_message,
3648
-                    'hide_off_message'       => $hide_off_message,
3649
-                    'messenger'              => $messenger,
3650
-                    'active'                 => $active,
3651
-                ];
3652
-            }
3653
-        }
3654
-
3655
-
3656
-        // register messenger metaboxes
3657
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3658
-        foreach ($m_boxes as $box => $label) {
3659
-            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3660
-            $msgr          = str_replace('_a_box', '', $box);
3661
-            add_meta_box(
3662
-                'espresso_' . $msgr . '_settings',
3663
-                $label,
3664
-                function ($post, $metabox) {
3665
-                    EEH_Template::display_template(
3666
-                        $metabox['args']['template_path'],
3667
-                        $metabox['args']['template_args']
3668
-                    );
3669
-                },
3670
-                $this->_current_screen->id,
3671
-                'normal',
3672
-                'high',
3673
-                $callback_args
3674
-            );
3675
-        }
3676
-
3677
-        // register message type metaboxes
3678
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3679
-        foreach ($mt_boxes as $box => $label) {
3680
-            $callback_args = [
3681
-                'template_path' => $mt_template_path,
3682
-                'template_args' => $mt_template_args[ $box ],
3683
-            ];
3684
-            $mt            = str_replace('_i_box', '', $box);
3685
-            add_meta_box(
3686
-                'espresso_' . $mt . '_inactive_mts',
3687
-                $label,
3688
-                function ($post, $metabox) {
3689
-                    EEH_Template::display_template(
3690
-                        $metabox['args']['template_path'],
3691
-                        $metabox['args']['template_args']
3692
-                    );
3693
-                },
3694
-                $this->_current_screen->id,
3695
-                'side',
3696
-                'high',
3697
-                $callback_args
3698
-            );
3699
-        }
3700
-
3701
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3702
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3703
-        if (is_main_site()) {
3704
-            add_meta_box(
3705
-                'espresso_global_message_settings',
3706
-                esc_html__('Global Message Settings', 'event_espresso'),
3707
-                [$this, 'global_messages_settings_metabox_content'],
3708
-                $this->_current_screen->id,
3709
-                'normal',
3710
-                'low',
3711
-                []
3712
-            );
3713
-        }
3714
-    }
3715
-
3716
-
3717
-    /**
3718
-     *  This generates the content for the global messages settings metabox.
3719
-     *
3720
-     * @return void
3721
-     * @throws EE_Error
3722
-     * @throws InvalidArgumentException
3723
-     * @throws ReflectionException
3724
-     * @throws InvalidDataTypeException
3725
-     * @throws InvalidInterfaceException
3726
-     */
3727
-    public function global_messages_settings_metabox_content()
3728
-    {
3729
-        $form = $this->_generate_global_settings_form();
3730
-        // already escaped
3731
-        echo $form->form_open(
3732
-            $this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3733
-            'POST'
3734
-        );
3735
-        echo $form->get_html();
3736
-        echo $form->form_close();
3737
-    }
3738
-
3739
-
3740
-    /**
3741
-     * This generates and returns the form object for the global messages settings.
3742
-     *
3743
-     * @return EE_Form_Section_Proper
3744
-     * @throws EE_Error
3745
-     * @throws InvalidArgumentException
3746
-     * @throws ReflectionException
3747
-     * @throws InvalidDataTypeException
3748
-     * @throws InvalidInterfaceException
3749
-     */
3750
-    protected function _generate_global_settings_form()
3751
-    {
3752
-        /** @var EE_Network_Core_Config $network_config */
3753
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3754
-
3755
-        return new EE_Form_Section_Proper(
3756
-            [
3757
-                'name'            => 'global_messages_settings',
3758
-                'html_id'         => 'global_messages_settings',
3759
-                'html_class'      => 'form-table',
3760
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3761
-                'subsections'     => apply_filters(
3762
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3763
-                    [
3764
-                        'do_messages_on_same_request' => new EE_Select_Input(
3765
-                            [
3766
-                                true  => esc_html__('On the same request', 'event_espresso'),
3767
-                                false => esc_html__('On a separate request', 'event_espresso'),
3768
-                            ],
3769
-                            [
3770
-                                'default'         => $network_config->do_messages_on_same_request,
3771
-                                'html_label_text' => esc_html__(
3772
-                                    'Generate and send all messages:',
3773
-                                    'event_espresso'
3774
-                                ),
3775
-                                'html_help_text'  => esc_html__(
3776
-                                    '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.',
3777
-                                    'event_espresso'
3778
-                                ),
3779
-                            ]
3780
-                        ),
3781
-                        'delete_threshold'            => new EE_Select_Input(
3782
-                            [
3783
-                                0  => esc_html__('Forever', 'event_espresso'),
3784
-                                3  => esc_html__('3 Months', 'event_espresso'),
3785
-                                6  => esc_html__('6 Months', 'event_espresso'),
3786
-                                9  => esc_html__('9 Months', 'event_espresso'),
3787
-                                12 => esc_html__('12 Months', 'event_espresso'),
3788
-                                24 => esc_html__('24 Months', 'event_espresso'),
3789
-                                36 => esc_html__('36 Months', 'event_espresso'),
3790
-                            ],
3791
-                            [
3792
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3793
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3794
-                                'html_help_text'  => esc_html__(
3795
-                                    'You can control how long a record of processed messages is kept via this option.',
3796
-                                    'event_espresso'
3797
-                                ),
3798
-                            ]
3799
-                        ),
3800
-                        'update_settings'             => new EE_Submit_Input(
3801
-                            [
3802
-                                'default'         => esc_html__('Update', 'event_espresso'),
3803
-                                'html_label_text' => '&nbsp',
3804
-                            ]
3805
-                        ),
3806
-                    ]
3807
-                ),
3808
-            ]
3809
-        );
3810
-    }
3811
-
3812
-
3813
-    /**
3814
-     * This handles updating the global settings set on the admin page.
3815
-     *
3816
-     * @throws EE_Error
3817
-     * @throws InvalidDataTypeException
3818
-     * @throws InvalidInterfaceException
3819
-     * @throws InvalidArgumentException
3820
-     * @throws ReflectionException
3821
-     */
3822
-    protected function _update_global_settings()
3823
-    {
3824
-        /** @var EE_Network_Core_Config $network_config */
3825
-        $network_config  = EE_Registry::instance()->NET_CFG->core;
3826
-        $messages_config = EE_Registry::instance()->CFG->messages;
3827
-        $form            = $this->_generate_global_settings_form();
3828
-        if ($form->was_submitted()) {
3829
-            $form->receive_form_submission();
3830
-            if ($form->is_valid()) {
3831
-                $valid_data = $form->valid_data();
3832
-                foreach ($valid_data as $property => $value) {
3833
-                    $setter = 'set_' . $property;
3834
-                    if (method_exists($network_config, $setter)) {
3835
-                        $network_config->{$setter}($value);
3836
-                    } elseif (
3837
-                        property_exists($network_config, $property)
3838
-                        && $network_config->{$property} !== $value
3839
-                    ) {
3840
-                        $network_config->{$property} = $value;
3841
-                    } elseif (
3842
-                        property_exists($messages_config, $property)
3843
-                        && $messages_config->{$property} !== $value
3844
-                    ) {
3845
-                        $messages_config->{$property} = $value;
3846
-                    }
3847
-                }
3848
-                // only update if the form submission was valid!
3849
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3850
-                EE_Registry::instance()->CFG->update_espresso_config();
3851
-                EE_Error::overwrite_success();
3852
-                EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3853
-            }
3854
-        }
3855
-        $this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3856
-    }
3857
-
3858
-
3859
-    /**
3860
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3861
-     *
3862
-     * @param array $tab_array This is an array of message type tab details used to generate the tabs
3863
-     * @return string html formatted tabs
3864
-     * @throws DomainException
3865
-     */
3866
-    protected function _get_mt_tabs($tab_array)
3867
-    {
3868
-        $tab_array = (array) $tab_array;
3869
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3870
-        $tabs      = '';
3871
-
3872
-        foreach ($tab_array as $tab) {
3873
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3874
-        }
3875
-
3876
-        return $tabs;
3877
-    }
3878
-
3879
-
3880
-    /**
3881
-     * This prepares the content of the messenger meta box admin settings
3882
-     *
3883
-     * @param EE_messenger $messenger The messenger we're setting up content for
3884
-     * @return string html formatted content
3885
-     * @throws DomainException
3886
-     */
3887
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3888
-    {
3889
-
3890
-        $fields                                         = $messenger->get_admin_settings_fields();
3891
-        $settings_template_args['template_form_fields'] = '';
3892
-
3893
-        // is $messenger active?
3894
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3895
-
3896
-
3897
-        if (! empty($fields)) {
3898
-            $existing_settings = $messenger->get_existing_admin_settings();
3899
-
3900
-            foreach ($fields as $fldname => $fldprops) {
3901
-                $field_id                         = $messenger->name . '-' . $fldname;
3902
-                $template_form_field[ $field_id ] = [
3903
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3904
-                    'label'      => $fldprops['label'],
3905
-                    'input'      => $fldprops['field_type'],
3906
-                    'type'       => $fldprops['value_type'],
3907
-                    'required'   => $fldprops['required'],
3908
-                    'validation' => $fldprops['validation'],
3909
-                    'value'      => isset($existing_settings[ $field_id ])
3910
-                        ? $existing_settings[ $field_id ]
3911
-                        : $fldprops['default'],
3912
-                    'css_class'  => '',
3913
-                    'format'     => $fldprops['format'],
3914
-                ];
3915
-            }
3916
-
3917
-
3918
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3919
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3920
-                : '';
3921
-        }
3922
-
3923
-        // we also need some hidden fields
3924
-        $settings_template_args['hidden_fields'] = [
3925
-            'messenger_settings[messenger]' . $messenger->name => [
3926
-                'type'  => 'hidden',
3927
-                'value' => $messenger->name,
3928
-            ],
3929
-            'type' . $messenger->name                          => [
3930
-                'type'  => 'hidden',
3931
-                'value' => 'messenger',
3932
-            ],
3933
-        ];
3934
-
3935
-        // make sure any active message types that are existing are included in the hidden fields
3936
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3937
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3938
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3939
-                    'type'  => 'hidden',
3940
-                    'value' => $mt,
3941
-                ];
3942
-            }
3943
-        }
3944
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3945
-            $settings_template_args['hidden_fields'],
3946
-            'array'
3947
-        );
3948
-        $active                                  =
3949
-            $this->_message_resource_manager->is_messenger_active($messenger->name);
3950
-
3951
-        $settings_template_args['messenger']           = $messenger->name;
3952
-        $settings_template_args['description']         = $messenger->description;
3953
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3954
-
3955
-
3956
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3957
-            $messenger->name
3958
-        )
3959
-            ? $settings_template_args['show_hide_edit_form']
3960
-            : ' hidden';
3961
-
3962
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3963
-            ? ' hidden'
3964
-            : $settings_template_args['show_hide_edit_form'];
3965
-
3966
-
3967
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3968
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3969
-        $settings_template_args['on_off_status'] = $active;
3970
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3971
-        return EEH_Template::display_template(
3972
-            $template,
3973
-            $settings_template_args,
3974
-            true
3975
-        );
3976
-    }
3977
-
3978
-
3979
-    /**
3980
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3981
-     *
3982
-     * @throws DomainException
3983
-     * @throws EE_Error
3984
-     * @throws InvalidDataTypeException
3985
-     * @throws InvalidInterfaceException
3986
-     * @throws InvalidArgumentException
3987
-     * @throws ReflectionException
3988
-     */
3989
-    public function activate_messenger_toggle()
3990
-    {
3991
-        $success = true;
3992
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3993
-        // let's check that we have required data
3994
-
3995
-        if (! $this->_active_messenger_name) {
3996
-            EE_Error::add_error(
3997
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3998
-                __FILE__,
3999
-                __FUNCTION__,
4000
-                __LINE__
4001
-            );
4002
-            $success = false;
4003
-        }
4004
-
4005
-        // do a nonce check here since we're not arriving via a normal route
4006
-        $nonce     = $this->request->getRequestParam('activate_nonce', '');
4007
-        $nonce_ref = "activate_{$this->_active_messenger_name}_toggle_nonce";
4008
-
4009
-        $this->_verify_nonce($nonce, $nonce_ref);
4010
-
4011
-
4012
-        $status = $this->request->getRequestParam('status');
4013
-        if (! $status) {
4014
-            EE_Error::add_error(
4015
-                esc_html__(
4016
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4017
-                    'event_espresso'
4018
-                ),
4019
-                __FILE__,
4020
-                __FUNCTION__,
4021
-                __LINE__
4022
-            );
4023
-            $success = false;
4024
-        }
4025
-
4026
-        // do check to verify we have a valid status.
4027
-        if ($status !== 'off' && $status !== 'on') {
4028
-            EE_Error::add_error(
4029
-                sprintf(
4030
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
4031
-                    $status
4032
-                ),
4033
-                __FILE__,
4034
-                __FUNCTION__,
4035
-                __LINE__
4036
-            );
4037
-            $success = false;
4038
-        }
4039
-
4040
-        if ($success) {
4041
-            // made it here?  Stop dawdling then!!
4042
-            $success = $status === 'off'
4043
-                ? $this->_deactivate_messenger($this->_active_messenger_name)
4044
-                : $this->_activate_messenger($this->_active_messenger_name);
4045
-        }
4046
-
4047
-        $this->_template_args['success'] = $success;
4048
-
4049
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
4050
-        $this->_return_json();
4051
-    }
4052
-
4053
-
4054
-    /**
4055
-     * used by ajax from the messages settings page to activate|deactivate a message type
4056
-     *
4057
-     * @throws DomainException
4058
-     * @throws EE_Error
4059
-     * @throws ReflectionException
4060
-     * @throws InvalidDataTypeException
4061
-     * @throws InvalidInterfaceException
4062
-     * @throws InvalidArgumentException
4063
-     */
4064
-    public function activate_mt_toggle()
4065
-    {
4066
-        $success = true;
4067
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
4068
-
4069
-        // let's make sure we have the necessary data
4070
-        if (! $this->_active_message_type_name) {
4071
-            EE_Error::add_error(
4072
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
4073
-                __FILE__,
4074
-                __FUNCTION__,
4075
-                __LINE__
4076
-            );
4077
-            $success = false;
4078
-        }
4079
-
4080
-        if (! $this->_active_messenger_name) {
4081
-            EE_Error::add_error(
4082
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
4083
-                __FILE__,
4084
-                __FUNCTION__,
4085
-                __LINE__
4086
-            );
4087
-            $success = false;
4088
-        }
4089
-
4090
-        $status = $this->request->getRequestParam('status');
4091
-        if (! $status) {
4092
-            EE_Error::add_error(
4093
-                esc_html__(
4094
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4095
-                    'event_espresso'
4096
-                ),
4097
-                __FILE__,
4098
-                __FUNCTION__,
4099
-                __LINE__
4100
-            );
4101
-            $success = false;
4102
-        }
4103
-
4104
-
4105
-        // do check to verify we have a valid status.
4106
-        if ($status !== 'activate' && $status !== 'deactivate') {
4107
-            EE_Error::add_error(
4108
-                sprintf(
4109
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
4110
-                    $status
4111
-                ),
4112
-                __FILE__,
4113
-                __FUNCTION__,
4114
-                __LINE__
4115
-            );
4116
-            $success = false;
4117
-        }
4118
-
4119
-
4120
-        // do a nonce check here since we're not arriving via a normal route
4121
-        $nonce = $this->request->getRequestParam('mt_nonce', '');
4122
-        $this->_verify_nonce($nonce, "{$this->_active_message_type_name}_nonce");
4123
-
4124
-        if ($success) {
4125
-            // made it here? um, what are you waiting for then?
4126
-            $success = $status === 'deactivate'
4127
-                ? $this->_deactivate_message_type_for_messenger(
4128
-                    $this->_active_messenger_name,
4129
-                    $this->_active_message_type_name
4130
-                )
4131
-                : $this->_activate_message_type_for_messenger(
4132
-                    $this->_active_messenger_name,
4133
-                    $this->_active_message_type_name
4134
-                );
4135
-        }
4136
-
4137
-        $this->_template_args['success'] = $success;
4138
-        $this->_return_json();
4139
-    }
4140
-
4141
-
4142
-    /**
4143
-     * Takes care of processing activating a messenger and preparing the appropriate response.
4144
-     *
4145
-     * @param string $messenger_name The name of the messenger being activated
4146
-     * @return bool
4147
-     * @throws DomainException
4148
-     * @throws EE_Error
4149
-     * @throws InvalidArgumentException
4150
-     * @throws ReflectionException
4151
-     * @throws InvalidDataTypeException
4152
-     * @throws InvalidInterfaceException
4153
-     */
4154
-    protected function _activate_messenger($messenger_name)
4155
-    {
4156
-        $active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
4157
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
4158
-            ? $active_messenger->get_default_message_types()
4159
-            : [];
4160
-
4161
-        // ensure is active
4162
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4163
-
4164
-        // set response_data for reload
4165
-        foreach ($message_types_to_activate as $message_type_name) {
4166
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4167
-            if (
4168
-                $this->_message_resource_manager->is_message_type_active_for_messenger(
4169
-                    $messenger_name,
4170
-                    $message_type_name
4171
-                )
4172
-                && $message_type instanceof EE_message_type
4173
-            ) {
4174
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
4175
-                if ($message_type->get_admin_settings_fields()) {
4176
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
4177
-                }
4178
-            }
4179
-        }
4180
-
4181
-        // add success message for activating messenger
4182
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4183
-    }
4184
-
4185
-
4186
-    /**
4187
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
4188
-     *
4189
-     * @param string $messenger_name The name of the messenger being activated
4190
-     * @return bool
4191
-     * @throws DomainException
4192
-     * @throws EE_Error
4193
-     * @throws InvalidArgumentException
4194
-     * @throws ReflectionException
4195
-     * @throws InvalidDataTypeException
4196
-     * @throws InvalidInterfaceException
4197
-     */
4198
-    protected function _deactivate_messenger($messenger_name)
4199
-    {
4200
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4201
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
4202
-
4203
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4204
-    }
4205
-
4206
-
4207
-    /**
4208
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4209
-     *
4210
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
4211
-     * @param string $message_type_name The name of the message type being activated for the messenger
4212
-     * @return bool
4213
-     * @throws DomainException
4214
-     * @throws EE_Error
4215
-     * @throws InvalidArgumentException
4216
-     * @throws ReflectionException
4217
-     * @throws InvalidDataTypeException
4218
-     * @throws InvalidInterfaceException
4219
-     */
4220
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4221
-    {
4222
-        $active_messenger         = $this->_message_resource_manager->get_messenger($messenger_name);
4223
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4224
-
4225
-        // ensure is active
4226
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4227
-
4228
-        // set response for load
4229
-        if (
4230
-            $this->_message_resource_manager->is_message_type_active_for_messenger(
4231
-                $messenger_name,
4232
-                $message_type_name
4233
-            )
4234
-        ) {
4235
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
4236
-            if ($message_type_to_activate->get_admin_settings_fields()) {
4237
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
4238
-            }
4239
-        }
4240
-
4241
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
4242
-            $active_messenger,
4243
-            $message_type_to_activate
4244
-        );
4245
-    }
4246
-
4247
-
4248
-    /**
4249
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4250
-     *
4251
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4252
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
4253
-     * @return bool
4254
-     * @throws DomainException
4255
-     * @throws EE_Error
4256
-     * @throws InvalidArgumentException
4257
-     * @throws ReflectionException
4258
-     * @throws InvalidDataTypeException
4259
-     * @throws InvalidInterfaceException
4260
-     */
4261
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4262
-    {
4263
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4264
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4265
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4266
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4267
-
4268
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4269
-            $active_messenger,
4270
-            $message_type_to_deactivate
4271
-        );
4272
-    }
4273
-
4274
-
4275
-    /**
4276
-     * This just initializes the defaults for activating messenger and message type responses.
4277
-     */
4278
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
4279
-    {
4280
-        $this->_template_args['data']['active_mts'] = [];
4281
-        $this->_template_args['data']['mt_reload']  = [];
4282
-    }
4283
-
4284
-
4285
-    /**
4286
-     * Setup appropriate response for activating a messenger and/or message types
4287
-     *
4288
-     * @param EE_messenger         $messenger
4289
-     * @param EE_message_type|null $message_type
4290
-     * @return bool
4291
-     * @throws DomainException
4292
-     * @throws EE_Error
4293
-     * @throws InvalidArgumentException
4294
-     * @throws ReflectionException
4295
-     * @throws InvalidDataTypeException
4296
-     * @throws InvalidInterfaceException
4297
-     */
4298
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
4299
-        $messenger,
4300
-        EE_Message_Type $message_type = null
4301
-    ) {
4302
-        // if $messenger isn't a valid messenger object then get out.
4303
-        if (! $messenger instanceof EE_Messenger) {
4304
-            EE_Error::add_error(
4305
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4306
-                __FILE__,
4307
-                __FUNCTION__,
4308
-                __LINE__
4309
-            );
4310
-            return false;
4311
-        }
4312
-        // activated
4313
-        if ($this->_template_args['data']['active_mts']) {
4314
-            EE_Error::overwrite_success();
4315
-            // activated a message type with the messenger
4316
-            if ($message_type instanceof EE_message_type) {
4317
-                EE_Error::add_success(
4318
-                    sprintf(
4319
-                        esc_html__(
4320
-                            '%s message type has been successfully activated with the %s messenger',
4321
-                            'event_espresso'
4322
-                        ),
4323
-                        ucwords($message_type->label['singular']),
4324
-                        ucwords($messenger->label['singular'])
4325
-                    )
4326
-                );
4327
-
4328
-                // if message type was invoice then let's make sure we activate the invoice payment method.
4329
-                if ($message_type->name === 'invoice') {
4330
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
4331
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4332
-                    if ($pm instanceof EE_Payment_Method) {
4333
-                        EE_Error::add_attention(
4334
-                            esc_html__(
4335
-                                '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.',
4336
-                                'event_espresso'
4337
-                            )
4338
-                        );
4339
-                    }
4340
-                }
4341
-                // just toggles the entire messenger
4342
-            } else {
4343
-                EE_Error::add_success(
4344
-                    sprintf(
4345
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4346
-                        ucwords($messenger->label['singular'])
4347
-                    )
4348
-                );
4349
-            }
4350
-
4351
-            return true;
4352
-
4353
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4354
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4355
-            // in which case we just give a success message for the messenger being successfully activated.
4356
-        } else {
4357
-            if (! $messenger->get_default_message_types()) {
4358
-                // messenger doesn't have any default message types so still a success.
4359
-                EE_Error::add_success(
4360
-                    sprintf(
4361
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4362
-                        ucwords($messenger->label['singular'])
4363
-                    )
4364
-                );
4365
-
4366
-                return true;
4367
-            } else {
4368
-                EE_Error::add_error(
4369
-                    $message_type instanceof EE_message_type
4370
-                    ? sprintf(
4371
-                        esc_html__(
4372
-                            '%s message type was not successfully activated with the %s messenger',
4373
-                            'event_espresso'
4374
-                        ),
4375
-                        ucwords($message_type->label['singular']),
4376
-                        ucwords($messenger->label['singular'])
4377
-                    )
4378
-                    : sprintf(
4379
-                        esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4380
-                        ucwords($messenger->label['singular'])
4381
-                    ),
4382
-                    __FILE__,
4383
-                    __FUNCTION__,
4384
-                    __LINE__
4385
-                );
4386
-
4387
-                return false;
4388
-            }
4389
-        }
4390
-    }
4391
-
4392
-
4393
-    /**
4394
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
4395
-     *
4396
-     * @param EE_messenger         $messenger
4397
-     * @param EE_message_type|null $message_type
4398
-     * @return bool
4399
-     * @throws DomainException
4400
-     * @throws EE_Error
4401
-     * @throws InvalidArgumentException
4402
-     * @throws ReflectionException
4403
-     * @throws InvalidDataTypeException
4404
-     * @throws InvalidInterfaceException
4405
-     */
4406
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4407
-        $messenger,
4408
-        EE_message_type $message_type = null
4409
-    ) {
4410
-        EE_Error::overwrite_success();
4411
-
4412
-        // if $messenger isn't a valid messenger object then get out.
4413
-        if (! $messenger instanceof EE_Messenger) {
4414
-            EE_Error::add_error(
4415
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4416
-                __FILE__,
4417
-                __FUNCTION__,
4418
-                __LINE__
4419
-            );
4420
-
4421
-            return false;
4422
-        }
4423
-
4424
-        if ($message_type instanceof EE_message_type) {
4425
-            $message_type_name = $message_type->name;
4426
-            EE_Error::add_success(
4427
-                sprintf(
4428
-                    esc_html__(
4429
-                        '%s message type has been successfully deactivated for the %s messenger.',
4430
-                        'event_espresso'
4431
-                    ),
4432
-                    ucwords($message_type->label['singular']),
4433
-                    ucwords($messenger->label['singular'])
4434
-                )
4435
-            );
4436
-        } else {
4437
-            $message_type_name = '';
4438
-            EE_Error::add_success(
4439
-                sprintf(
4440
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4441
-                    ucwords($messenger->label['singular'])
4442
-                )
4443
-            );
4444
-        }
4445
-
4446
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4447
-        if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4448
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
4449
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4450
-            if ($count_updated > 0) {
4451
-                $msg = $message_type_name === 'invoice'
4452
-                    ? esc_html__(
4453
-                        '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.',
4454
-                        'event_espresso'
4455
-                    )
4456
-                    : esc_html__(
4457
-                        '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.',
4458
-                        'event_espresso'
4459
-                    );
4460
-                EE_Error::add_attention($msg);
4461
-            }
4462
-        }
4463
-
4464
-        return true;
4465
-    }
4466
-
4467
-
4468
-    /**
4469
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4470
-     *
4471
-     * @throws DomainException
4472
-     * @throws EE_Error
4473
-     * @throws EE_Error
4474
-     */
4475
-    public function update_mt_form()
4476
-    {
4477
-        if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
4478
-            EE_Error::add_error(
4479
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4480
-                __FILE__,
4481
-                __FUNCTION__,
4482
-                __LINE__
4483
-            );
4484
-            $this->_return_json();
4485
-        }
4486
-
4487
-        $message_types = $this->get_installed_message_types();
4488
-        $message_type  = $message_types[ $this->_active_message_type_name ];
4489
-        $messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
4490
-        $content       = $this->_message_type_settings_content($message_type, $messenger, true);
4491
-
4492
-        $this->_template_args['success'] = true;
4493
-        $this->_template_args['content'] = $content;
4494
-        $this->_return_json();
4495
-    }
4496
-
4497
-
4498
-    /**
4499
-     * this handles saving the settings for a messenger or message type
4500
-     *
4501
-     * @throws EE_Error
4502
-     * @throws EE_Error
4503
-     */
4504
-    public function save_settings()
4505
-    {
4506
-        $type = $this->request->getRequestParam('type');
4507
-        if (! $type) {
4508
-            EE_Error::add_error(
4509
-                esc_html__(
4510
-                    'Cannot save settings because type is unknown (messenger settings or message type settings?)',
4511
-                    'event_espresso'
4512
-                ),
4513
-                __FILE__,
4514
-                __FUNCTION__,
4515
-                __LINE__
4516
-            );
4517
-            $this->_template_args['error'] = true;
4518
-            $this->_return_json();
4519
-        }
4520
-
4521
-
4522
-        if ($type === 'messenger') {
4523
-            // this should be an array.
4524
-            $settings  = $this->request->getRequestParam('messenger_settings', [], 'string', true);
4525
-            $messenger = $settings['messenger'];
4526
-            // remove messenger and message_types from settings array
4527
-            unset($settings['messenger'], $settings['message_types']);
4528
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4529
-        } elseif ($type === 'message_type') {
4530
-            $settings     = $this->request->getRequestParam('message_type_settings', [], 'string', true);
4531
-            $messenger    = $settings['messenger'];
4532
-            $message_type = $settings['message_type'];
4533
-            // remove messenger and message_types from settings array
4534
-            unset($settings['messenger'], $settings['message_types']);
4535
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4536
-        }
4537
-
4538
-        // okay we should have the data all setup.  Now we just update!
4539
-        $success = $this->_message_resource_manager->update_active_messengers_option();
4540
-
4541
-        if ($success) {
4542
-            EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
4543
-        } else {
4544
-            EE_Error::add_error(
4545
-                esc_html__('Settings did not get updated', 'event_espresso'),
4546
-                __FILE__,
4547
-                __FUNCTION__,
4548
-                __LINE__
4549
-            );
4550
-        }
4551
-
4552
-        $this->_template_args['success'] = $success;
4553
-        $this->_return_json();
4554
-    }
4555
-
4556
-
4557
-
4558
-
4559
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4560
-
4561
-
4562
-    /**
4563
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4564
-     * However, this does not send immediately, it just queues for sending.
4565
-     *
4566
-     * @throws EE_Error
4567
-     * @throws InvalidDataTypeException
4568
-     * @throws InvalidInterfaceException
4569
-     * @throws InvalidArgumentException
4570
-     * @throws ReflectionException
4571
-     * @since 4.9.0
4572
-     */
4573
-    protected function _generate_now()
4574
-    {
4575
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4576
-        $this->_redirect_after_action(false, '', '', [], true);
4577
-    }
4578
-
4579
-
4580
-    /**
4581
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4582
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4583
-     *
4584
-     * @throws EE_Error
4585
-     * @throws InvalidDataTypeException
4586
-     * @throws InvalidInterfaceException
4587
-     * @throws InvalidArgumentException
4588
-     * @throws ReflectionException
4589
-     * @since 4.9.0
4590
-     */
4591
-    protected function _generate_and_send_now()
4592
-    {
4593
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4594
-        $this->_redirect_after_action(false, '', '', [], true);
4595
-    }
4596
-
4597
-
4598
-    /**
4599
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4600
-     *
4601
-     * @throws EE_Error
4602
-     * @throws InvalidDataTypeException
4603
-     * @throws InvalidInterfaceException
4604
-     * @throws InvalidArgumentException
4605
-     * @throws ReflectionException
4606
-     * @since 4.9.0
4607
-     */
4608
-    protected function _queue_for_resending()
4609
-    {
4610
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4611
-        $this->_redirect_after_action(false, '', '', [], true);
4612
-    }
4613
-
4614
-
4615
-    /**
4616
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4617
-     *
4618
-     * @throws EE_Error
4619
-     * @throws InvalidDataTypeException
4620
-     * @throws InvalidInterfaceException
4621
-     * @throws InvalidArgumentException
4622
-     * @throws ReflectionException
4623
-     * @since 4.9.0
4624
-     */
4625
-    protected function _send_now()
4626
-    {
4627
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4628
-        $this->_redirect_after_action(false, '', '', [], true);
4629
-    }
4630
-
4631
-
4632
-    /**
4633
-     * Deletes EE_messages for IDs in the request.
4634
-     *
4635
-     * @throws EE_Error
4636
-     * @throws InvalidDataTypeException
4637
-     * @throws InvalidInterfaceException
4638
-     * @throws InvalidArgumentException
4639
-     * @since 4.9.0
4640
-     */
4641
-    protected function _delete_ee_messages()
4642
-    {
4643
-        $MSG_IDs       = $this->_get_msg_ids_from_request();
4644
-        $deleted_count = 0;
4645
-        foreach ($MSG_IDs as $MSG_ID) {
4646
-            if ($this->getMsgModel()->delete_by_ID($MSG_ID)) {
4647
-                $deleted_count++;
4648
-            }
4649
-        }
4650
-        if ($deleted_count) {
4651
-            EE_Error::add_success(
4652
-                esc_html(
4653
-                    _n(
4654
-                        'Message successfully deleted',
4655
-                        'Messages successfully deleted',
4656
-                        $deleted_count,
4657
-                        'event_espresso'
4658
-                    )
4659
-                )
4660
-            );
4661
-        } else {
4662
-            EE_Error::add_error(
4663
-                _n('The message was not deleted.', 'The messages were not deleted', count($MSG_IDs), 'event_espresso'),
4664
-                __FILE__,
4665
-                __FUNCTION__,
4666
-                __LINE__
4667
-            );
4668
-        }
4669
-        $this->_redirect_after_action(false, '', '', [], true);
4670
-    }
4671
-
4672
-
4673
-    /**
4674
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4675
-     *
4676
-     * @return array
4677
-     * @since 4.9.0
4678
-     */
4679
-    protected function _get_msg_ids_from_request()
4680
-    {
4681
-        $MSG_IDs = $this->request->getRequestParam('MSG_ID', [], 'string', true);
4682
-        if (empty($MSG_IDs)) {
4683
-            return [];
4684
-        }
4685
-        // if 'MSG_ID' was just a single ID (not an array)
4686
-        // then $MSG_IDs will be something like [123] so $MSG_IDs[0] should be 123
4687
-        // otherwise, $MSG_IDs was already an array where message IDs were used as the keys
4688
-        return count($MSG_IDs) === 1 && isset($MSG_IDs[0])
4689
-            ? $MSG_IDs
4690
-            : array_keys($MSG_IDs);
4691
-    }
2710
+		$this->_context_switcher = ob_get_clean();
2711
+	}
2712
+
2713
+
2714
+	/**
2715
+	 * @param bool $new
2716
+	 * @throws EE_Error
2717
+	 * @throws ReflectionException
2718
+	 */
2719
+	protected function _insert_or_update_message_template($new = false)
2720
+	{
2721
+		$form_data    = $this->getMessageTemplateFormData();
2722
+		$GRP_ID       = $form_data['GRP_ID'];
2723
+		$messenger    = $form_data['MTP_messenger'];
2724
+		$message_type = $form_data['MTP_message_type'];
2725
+		$context      = $form_data['MTP_context'];
2726
+
2727
+		// if this is "new" then we need to generate the default contexts
2728
+		// for the selected messenger/message_type for user to edit.
2729
+		list($success, $query_args) = $new
2730
+			? $this->generateNewTemplates($GRP_ID, $messenger, $message_type)
2731
+			: $this->updateExistingTemplates($GRP_ID, $messenger, $message_type, $context, $form_data);
2732
+
2733
+		$success     = $success ? 1 : 0;
2734
+		$action_desc = $new ? 'created' : 'updated';
2735
+		$item_desc   = $this->generateUpdateDescription($messenger, $message_type, $context);
2736
+		$override    = $this->performTestSendAfterUpdate($messenger, $message_type, $context);
2737
+
2738
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
2739
+	}
2740
+
2741
+
2742
+	/**
2743
+	 * retrieve and sanitize form data
2744
+	 *
2745
+	 * @return array
2746
+	 * @since $VID:$
2747
+	 */
2748
+	protected function getMessageTemplateFormData()
2749
+	{
2750
+		return [
2751
+			'GRP_ID'           => $this->request->getRequestParam('GRP_ID', 0, 'int'),
2752
+			'MTP_context'      => strtolower($this->request->getRequestParam('MTP_context', '')),
2753
+			'MTP_messenger'    => strtolower($this->request->getRequestParam('MTP_messenger', '')),
2754
+			'MTP_message_type' => strtolower($this->request->getRequestParam('MTP_message_type', '')),
2755
+			'MTP_user_id'      => $this->request->getRequestParam('MTP_user_id', 0, 'int'),
2756
+			'MTP_is_global'    => $this->request->getRequestParam('MTP_is_global', 0, 'int'),
2757
+			'MTP_is_override'  => $this->request->getRequestParam('MTP_is_override', 0, 'int'),
2758
+			'MTP_deleted'      => $this->request->getRequestParam('MTP_deleted', 0, 'int'),
2759
+			'MTP_is_active'    => $this->request->getRequestParam('MTP_is_active', 0, 'int'),
2760
+		];
2761
+	}
2762
+
2763
+
2764
+	/**
2765
+	 * @param int    $GRP_ID
2766
+	 * @param string $messenger
2767
+	 * @param string $message_type
2768
+	 * @return array no return on AJAX requests
2769
+	 * @throws EE_Error
2770
+	 * @throws ReflectionException
2771
+	 * @since $VID:$
2772
+	 */
2773
+	private function generateNewTemplates($GRP_ID, $messenger, $message_type)
2774
+	{
2775
+		$new_templates = $this->_generate_new_templates($messenger, [$message_type], $GRP_ID);
2776
+		$success       = ! empty($new_templates);
2777
+
2778
+		// we return things differently if doing ajax
2779
+		if ($this->request->isAjax()) {
2780
+			$this->_template_args['success'] = $success;
2781
+			$this->_template_args['error']   = ! $success;
2782
+			$this->_template_args['content'] = '';
2783
+			$this->_template_args['data']    = [
2784
+				'grpID'        => $new_templates['GRP_ID'],
2785
+				'templateName' => $new_templates['template_name'],
2786
+			];
2787
+			if ($success) {
2788
+				EE_Error::overwrite_success();
2789
+				EE_Error::add_success(
2790
+					esc_html__(
2791
+						'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.',
2792
+						'event_espresso'
2793
+					)
2794
+				);
2795
+			}
2796
+			$this->_return_json();
2797
+		}
2798
+		return [
2799
+			$success,
2800
+			// 'query_args'
2801
+			[
2802
+				'id'      => $new_templates['GRP_ID'],
2803
+				'context' => $new_templates['MTP_context'],
2804
+				'action'  => 'edit_message_template',
2805
+			],
2806
+		];
2807
+	}
2808
+
2809
+
2810
+	/**
2811
+	 * @param int    $GRP_ID
2812
+	 * @param string $messenger
2813
+	 * @param string $message_type
2814
+	 * @param string $context
2815
+	 * @param array  $form_data
2816
+	 * @return array
2817
+	 * @throws EE_Error
2818
+	 * @since $VID:$
2819
+	 */
2820
+	private function updateExistingTemplates(
2821
+		$GRP_ID,
2822
+		$messenger,
2823
+		$message_type,
2824
+		$context,
2825
+		array $form_data
2826
+	) {
2827
+		$success         = false;
2828
+		$template_fields = $this->getTemplateFields();
2829
+		if ($template_fields) {
2830
+			// if field data is valid, then success will be true
2831
+			$success = $this->validateTemplateFields(
2832
+				$messenger,
2833
+				$message_type,
2834
+				$context,
2835
+				$template_fields
2836
+			);
2837
+			if ($success) {
2838
+				$field_data = [];
2839
+				foreach ($template_fields as $template_field => $content) {
2840
+					// combine top-level form data with content for this field
2841
+					$field_data = $this->getTemplateFieldFormData($content, $form_data);
2842
+					$success    = $this->updateMessageTemplates($template_field, $field_data) ? $success : false;
2843
+				}
2844
+				// we can use the last set_column_values for the MTPG update
2845
+				// (because its the same for all of these specific MTPs)
2846
+				$success = $this->updateMessageTemplateGroup($field_data) ? $success : false;
2847
+			}
2848
+		}
2849
+
2850
+		return [
2851
+			$success,
2852
+			// 'query_args'
2853
+			[
2854
+				'id'      => $GRP_ID,
2855
+				'context' => $context,
2856
+				'action'  => 'edit_message_template',
2857
+			],
2858
+		];
2859
+	}
2860
+
2861
+
2862
+	/**
2863
+	 * @return array
2864
+	 * @since $VID:$
2865
+	 */
2866
+	private function getTemplateFields()
2867
+	{
2868
+		$template_fields = $this->request->getRequestParam('MTP_template_fields', null, 'html', true);
2869
+		if (empty($template_fields)) {
2870
+			EE_Error::add_error(
2871
+				esc_html__(
2872
+					'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2873
+					'event_espresso'
2874
+				),
2875
+				__FILE__,
2876
+				__FUNCTION__,
2877
+				__LINE__
2878
+			);
2879
+			return null;
2880
+		}
2881
+		// messages content is expected to be escaped
2882
+		return EEH_Array::addSlashesRecursively($template_fields);
2883
+	}
2884
+
2885
+
2886
+	/**
2887
+	 * @param string $messenger
2888
+	 * @param string $message_type
2889
+	 * @param string $context
2890
+	 * @param array  $template_fields
2891
+	 * @return bool
2892
+	 * @throws EE_Error
2893
+	 * @since   $VID:$
2894
+	 */
2895
+	private function validateTemplateFields(
2896
+		$messenger,
2897
+		$message_type,
2898
+		$context,
2899
+		array $template_fields
2900
+	) {
2901
+		// first validate all fields!
2902
+		// this filter allows client code to add its own validation to the template fields as well.
2903
+		// returning an empty array means everything passed validation.
2904
+		// errors in validation should be represented in an array with the following shape:
2905
+		// array(
2906
+		//   'fieldname' => array(
2907
+		//          'msg' => 'error message'
2908
+		//          'value' => 'value for field producing error'
2909
+		// )
2910
+		$custom_validation = (array) apply_filters(
2911
+			'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2912
+			[],
2913
+			$template_fields,
2914
+			$context,
2915
+			$messenger,
2916
+			$message_type
2917
+		);
2918
+
2919
+		$system_validation = $this->getMtgModel()->validate(
2920
+			$template_fields,
2921
+			$context,
2922
+			$messenger,
2923
+			$message_type
2924
+		);
2925
+
2926
+		$system_validation = ! is_array($system_validation) && $system_validation ? [] : $system_validation;
2927
+		$validates         = array_merge($custom_validation, $system_validation);
2928
+
2929
+		// if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2930
+		// appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2931
+		//  WE need to make sure there is no actual error messages in validates.
2932
+		if (empty($validates)) {
2933
+			return true;
2934
+		}
2935
+
2936
+		// add the transient so when the form loads we know which fields to highlight
2937
+		$this->_add_transient('edit_message_template', $validates);
2938
+		// setup notices
2939
+		foreach ($validates as $error) {
2940
+			if (isset($error['msg'])) {
2941
+				EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2942
+			}
2943
+		}
2944
+		return false;
2945
+	}
2946
+
2947
+
2948
+	/**
2949
+	 * @param array $field_data
2950
+	 * @param array $form_data
2951
+	 * @return array
2952
+	 * @since   $VID:$
2953
+	 */
2954
+	private function getTemplateFieldFormData(array $field_data, array $form_data)
2955
+	{
2956
+		return $form_data + [
2957
+				'MTP_ID'             => $field_data['MTP_ID'],
2958
+				'MTP_template_field' => $field_data['name'],
2959
+				// if they aren't allowed to use all JS, restrict them to standard allowed post tags
2960
+				'MTP_content'        => ! current_user_can('unfiltered_html')
2961
+					? $this->sanitizeMessageTemplateContent($field_data['content'])
2962
+					: $field_data['content'],
2963
+			];
2964
+	}
2965
+
2966
+
2967
+	/**
2968
+	 * @param string $template_field
2969
+	 * @param array  $form_data
2970
+	 * @return bool
2971
+	 * @throws EE_Error
2972
+	 * @since $VID:$
2973
+	 */
2974
+	private function updateMessageTemplates($template_field, array $form_data)
2975
+	{
2976
+		$MTP_ID                  = $form_data['MTP_ID'];
2977
+		$message_template_fields = [
2978
+			'GRP_ID'             => $form_data['GRP_ID'],
2979
+			'MTP_template_field' => $form_data['MTP_template_field'],
2980
+			'MTP_context'        => $form_data['MTP_context'],
2981
+			'MTP_content'        => $form_data['MTP_content'],
2982
+		];
2983
+
2984
+		$hasMtpID = ! empty($MTP_ID);
2985
+		// if we have a MTP_ID for this field then update it, otherwise insert.
2986
+		// this has already been through the template field validator and sanitized, so it will be
2987
+		// safe to insert this field.  Why insert?  This typically happens when we introduce a new
2988
+		// message template field in a messenger/message type and existing users don't have the
2989
+		// default setup for it.
2990
+		// @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2991
+		$updated = $hasMtpID
2992
+			? $this->getMtpModel()->update($message_template_fields, [['MTP_ID' => $MTP_ID]])
2993
+			: $this->getMtpModel()->insert($message_template_fields);
2994
+
2995
+		$insert_failed = ! $hasMtpID && ! $updated;
2996
+		// updates will return 0 if the field was not changed (ie: no changes = nothing actually updated)
2997
+		// but we won't consider that a problem, but if it returns false, then something went BOOM!
2998
+		$update_failed = $hasMtpID && $updated === false;
2999
+
3000
+		if ($insert_failed || $update_failed) {
3001
+			EE_Error::add_error(
3002
+				sprintf(
3003
+					esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
3004
+					$template_field
3005
+				),
3006
+				__FILE__,
3007
+				__FUNCTION__,
3008
+				__LINE__
3009
+			);
3010
+			return false;
3011
+		}
3012
+		return true;
3013
+	}
3014
+
3015
+
3016
+	/**
3017
+	 * @param array $form_data
3018
+	 * @return bool
3019
+	 * @throws EE_Error
3020
+	 * @since $VID:$
3021
+	 */
3022
+	private function updateMessageTemplateGroup(array $form_data)
3023
+	{
3024
+		$GRP_ID  = $form_data['GRP_ID'];
3025
+		$updated = $this->getMtgModel()->update(
3026
+		// fields and values
3027
+			[
3028
+				'MTP_user_id'      => $form_data['MTP_user_id'],
3029
+				'MTP_messenger'    => $form_data['MTP_messenger'],
3030
+				'MTP_message_type' => $form_data['MTP_message_type'],
3031
+				'MTP_is_global'    => $form_data['MTP_is_global'],
3032
+				'MTP_is_override'  => $form_data['MTP_is_override'],
3033
+				'MTP_deleted'      => $form_data['MTP_deleted'],
3034
+				'MTP_is_active'    => $form_data['MTP_is_active'],
3035
+				'MTP_name'         => $this->request->getRequestParam('ee_msg_non_global_fields[MTP_name]', ''),
3036
+				'MTP_description'  => $this->request->getRequestParam(
3037
+					'ee_msg_non_global_fields[MTP_description]',
3038
+					''
3039
+				),
3040
+			],
3041
+			// where
3042
+			[['GRP_ID' => $GRP_ID]]
3043
+		);
3044
+
3045
+		if ($updated === false) {
3046
+			EE_Error::add_error(
3047
+				sprintf(
3048
+					esc_html__(
3049
+						'The Message Template Group (%d) was NOT updated for some reason',
3050
+						'event_espresso'
3051
+					),
3052
+					$form_data['GRP_ID']
3053
+				),
3054
+				__FILE__,
3055
+				__FUNCTION__,
3056
+				__LINE__
3057
+			);
3058
+			return false;
3059
+		}
3060
+		// k now we need to ensure the template_pack and template_variation fields are set.
3061
+		$template_pack      = $this->request->getRequestParam('MTP_template_pack', 'default');
3062
+		$template_variation = $this->request->getRequestParam('MTP_template_variation', 'default');
3063
+
3064
+		$message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3065
+		if ($message_template_group instanceof EE_Message_Template_Group) {
3066
+			$message_template_group->set_template_pack_name($template_pack);
3067
+			$message_template_group->set_template_pack_variation($template_variation);
3068
+		}
3069
+		return true;
3070
+	}
3071
+
3072
+
3073
+	/**
3074
+	 * recursively runs wp_kses() on message template content in a model safe manner
3075
+	 *
3076
+	 * @param array|string $content
3077
+	 * @return array|string
3078
+	 * @since   $VID:$
3079
+	 */
3080
+	private function sanitizeMessageTemplateContent($content)
3081
+	{
3082
+		if (is_array($content)) {
3083
+			foreach ($content as $key => $value) {
3084
+				$content[ $key ] = $this->sanitizeMessageTemplateContent($value);
3085
+			}
3086
+			return $content;
3087
+		}
3088
+		// remove slashes so wp_kses() works properly
3089
+		// wp_kses_stripslashes() only removes slashes from double-quotes,
3090
+		// so attributes using single quotes always appear invalid.
3091
+		$content = stripslashes($content);
3092
+		$content = wp_kses($content, wp_kses_allowed_html('post'));
3093
+		// But currently the models expect slashed data, so after wp_kses()
3094
+		// runs we need to re-slash the data. Sheesh.
3095
+		// See https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
3096
+		return addslashes($content);
3097
+	}
3098
+
3099
+
3100
+	/**
3101
+	 * @param string $messenger
3102
+	 * @param string $message_type
3103
+	 * @param string $context
3104
+	 * @return string
3105
+	 * @since $VID:$
3106
+	 */
3107
+	private function generateUpdateDescription($messenger, $message_type, $context)
3108
+	{
3109
+		// need the message type and messenger objects to be able to use the labels for the notices
3110
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger);
3111
+		$messenger_label  = $messenger_object instanceof EE_messenger
3112
+			? ucwords($messenger_object->label['singular'])
3113
+			: '';
3114
+
3115
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type);
3116
+		$message_type_label  = $message_type_object instanceof EE_message_type
3117
+			? ucwords($message_type_object->label['singular'])
3118
+			: '';
3119
+
3120
+		$context   = ucwords(str_replace('_', ' ', $context));
3121
+		$item_desc = $messenger_label && $message_type_label
3122
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
3123
+			: '';
3124
+		$item_desc .= 'Message Template';
3125
+		return $item_desc;
3126
+	}
3127
+
3128
+
3129
+	/**
3130
+	 * @param string $messenger
3131
+	 * @param string $message_type
3132
+	 * @param string $context
3133
+	 * @return bool
3134
+	 * @throws EE_Error
3135
+	 * @throws ReflectionException
3136
+	 * @since $VID:$
3137
+	 */
3138
+	private function performTestSendAfterUpdate($messenger, $message_type, $context)
3139
+	{
3140
+		// was a test send triggered?
3141
+		if ($this->request->getRequestParam('test_button', false, 'bool')) {
3142
+			EE_Error::overwrite_success();
3143
+			$this->_do_test_send($context, $messenger, $message_type);
3144
+			return true;
3145
+		}
3146
+		return false;
3147
+	}
3148
+
3149
+
3150
+	/**
3151
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
3152
+	 *
3153
+	 * @param string $context      what context being tested
3154
+	 * @param string $messenger    messenger being tested
3155
+	 * @param string $message_type message type being tested
3156
+	 * @throws EE_Error
3157
+	 * @throws InvalidArgumentException
3158
+	 * @throws InvalidDataTypeException
3159
+	 * @throws InvalidInterfaceException
3160
+	 * @throws ReflectionException
3161
+	 */
3162
+	protected function _do_test_send($context, $messenger, $message_type)
3163
+	{
3164
+		// set things up for preview
3165
+		$this->request->setRequestParam('messenger', $messenger);
3166
+		$this->request->setRequestParam('message_type', $message_type);
3167
+		$this->request->setRequestParam('context', $context);
3168
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
3169
+		$this->request->setRequestParam('GRP_ID', $GRP_ID);
3170
+
3171
+		$active_messenger  = $this->_message_resource_manager->get_active_messenger($messenger);
3172
+		$test_settings_fld = $this->request->getRequestParam('test_settings_fld', [], 'string', true);
3173
+
3174
+		// let's save any existing fields that might be required by the messenger
3175
+		if (
3176
+			! empty($test_settings_fld)
3177
+			&& $active_messenger instanceof EE_messenger
3178
+			&& apply_filters(
3179
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3180
+				true,
3181
+				$test_settings_fld,
3182
+				$active_messenger
3183
+			)
3184
+		) {
3185
+			$active_messenger->set_existing_test_settings($test_settings_fld);
3186
+		}
3187
+
3188
+		/**
3189
+		 * Use filter to add additional controls on whether message can send or not
3190
+		 */
3191
+		if (
3192
+			apply_filters(
3193
+				'FHEE__Messages_Admin_Page__do_test_send__can_send',
3194
+				true,
3195
+				$context,
3196
+				$this->request->requestParams(),
3197
+				$messenger,
3198
+				$message_type
3199
+			)
3200
+		) {
3201
+			if (EEM_Event::instance()->count() > 0) {
3202
+				$success = $this->_preview_message(true);
3203
+				if ($success) {
3204
+					EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
3205
+				} else {
3206
+					EE_Error::add_error(
3207
+						esc_html__('The test message was not sent', 'event_espresso'),
3208
+						__FILE__,
3209
+						__FUNCTION__,
3210
+						__LINE__
3211
+					);
3212
+				}
3213
+			} else {
3214
+				$this->noEventsErrorMessage(true);
3215
+			}
3216
+		}
3217
+	}
3218
+
3219
+
3220
+	/**
3221
+	 * _generate_new_templates
3222
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3223
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3224
+	 * for the event.
3225
+	 *
3226
+	 *
3227
+	 * @param string $messenger      the messenger we are generating templates for
3228
+	 * @param array  $message_types  array of message types that the templates are generated for.
3229
+	 * @param int    $GRP_ID         If this is a custom template being generated then a GRP_ID needs to be included to
3230
+	 *                               indicate the message_template_group being used as the base.
3231
+	 *
3232
+	 * @param bool   $global
3233
+	 *
3234
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
3235
+	 *                               encountering problems.
3236
+	 * @throws EE_Error
3237
+	 * @throws ReflectionException
3238
+	 */
3239
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3240
+	{
3241
+		// if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3242
+		// just don't generate any templates.
3243
+		if (empty($message_types)) {
3244
+			return [];
3245
+		}
3246
+
3247
+		$templates = EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3248
+		return $templates[0];
3249
+	}
3250
+
3251
+
3252
+	/**
3253
+	 * [_trash_or_restore_message_template]
3254
+	 *
3255
+	 * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3256
+	 * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3257
+	 *                        an individual context (FALSE).
3258
+	 * @return void
3259
+	 * @throws EE_Error
3260
+	 * @throws InvalidArgumentException
3261
+	 * @throws InvalidDataTypeException
3262
+	 * @throws InvalidInterfaceException
3263
+	 */
3264
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
3265
+	{
3266
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3267
+
3268
+		$success = 1;
3269
+
3270
+		// incoming GRP_IDs
3271
+		if ($all) {
3272
+			// Checkboxes
3273
+			$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3274
+			if (! empty($checkboxes)) {
3275
+				// if array has more than one element then success message should be plural.
3276
+				// todo: what about nonce?
3277
+				$success = count($checkboxes) > 1 ? 2 : 1;
3278
+
3279
+				// cycle through checkboxes
3280
+				while (list($GRP_ID, $value) = each($checkboxes)) {
3281
+					$trashed_or_restored = $trash
3282
+						? $this->getMtgModel()->delete_by_ID($GRP_ID)
3283
+						: $this->getMtgModel()->restore_by_ID($GRP_ID);
3284
+					if (! $trashed_or_restored) {
3285
+						$success = 0;
3286
+					}
3287
+				}
3288
+			} else {
3289
+				// grab single GRP_ID and handle
3290
+				$GRP_ID = $this->request->getRequestParam('id', 0, 'int');
3291
+				if (! empty($GRP_ID)) {
3292
+					$trashed_or_restored = $trash
3293
+						? $this->getMtgModel()->delete_by_ID($GRP_ID)
3294
+						: $this->getMtgModel()->restore_by_ID($GRP_ID);
3295
+					if (! $trashed_or_restored) {
3296
+						$success = 0;
3297
+					}
3298
+				} else {
3299
+					$success = 0;
3300
+				}
3301
+			}
3302
+		}
3303
+
3304
+		$action_desc = $trash
3305
+			? esc_html__('moved to the trash', 'event_espresso')
3306
+			: esc_html__('restored', 'event_espresso');
3307
+
3308
+		$template_switch = $this->request->getRequestParam('template_switch', false, 'bool');
3309
+		$action_desc     = $template_switch ? esc_html__('switched', 'event_espresso') : $action_desc;
3310
+
3311
+		$item_desc = $all ? _n(
3312
+			'Message Template Group',
3313
+			'Message Template Groups',
3314
+			$success,
3315
+			'event_espresso'
3316
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3317
+
3318
+		$item_desc = $template_switch
3319
+			? _n('template', 'templates', $success, 'event_espresso')
3320
+			: $item_desc;
3321
+
3322
+		$this->_redirect_after_action($success, $item_desc, $action_desc, []);
3323
+	}
3324
+
3325
+
3326
+	/**
3327
+	 * [_delete_message_template]
3328
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3329
+	 *
3330
+	 * @return void
3331
+	 * @throws EE_Error
3332
+	 * @throws InvalidArgumentException
3333
+	 * @throws InvalidDataTypeException
3334
+	 * @throws InvalidInterfaceException
3335
+	 * @throws ReflectionException
3336
+	 */
3337
+	protected function _delete_message_template()
3338
+	{
3339
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3340
+
3341
+		// checkboxes
3342
+		$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3343
+		if (! empty($checkboxes)) {
3344
+			// if array has more than one element then success message should be plural
3345
+			$success = count($checkboxes) > 1 ? 2 : 1;
3346
+
3347
+			// cycle through bulk action checkboxes
3348
+			while (list($GRP_ID, $value) = each($checkboxes)) {
3349
+				$success = $this->_delete_mtp_permanently($GRP_ID) ? $success : false;
3350
+			}
3351
+		} else {
3352
+			// grab single grp_id and delete
3353
+			$GRP_ID  = $this->request->getRequestParam('id', 0, 'int');
3354
+			$success = $this->_delete_mtp_permanently($GRP_ID);
3355
+		}
3356
+
3357
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', []);
3358
+	}
3359
+
3360
+
3361
+	/**
3362
+	 * helper for permanently deleting a mtP group and all related message_templates
3363
+	 *
3364
+	 * @param int  $GRP_ID        The group being deleted
3365
+	 * @param bool $include_group whether to delete the Message Template Group as well.
3366
+	 * @return bool boolean to indicate the success of the deletes or not.
3367
+	 * @throws EE_Error
3368
+	 * @throws InvalidArgumentException
3369
+	 * @throws InvalidDataTypeException
3370
+	 * @throws InvalidInterfaceException
3371
+	 * @throws ReflectionException
3372
+	 * @throws ReflectionException
3373
+	 */
3374
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3375
+	{
3376
+		$success = true;
3377
+		// first let's GET this group
3378
+		$MTG = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3379
+		// then delete permanently all the related Message Templates
3380
+		$deleted = $MTG->delete_related_permanently('Message_Template');
3381
+
3382
+		if ($deleted === 0) {
3383
+			$success = false;
3384
+		}
3385
+
3386
+		// now delete permanently this particular group
3387
+
3388
+		if ($include_group && ! $MTG->delete_permanently()) {
3389
+			$success = false;
3390
+		}
3391
+
3392
+		return $success;
3393
+	}
3394
+
3395
+
3396
+	/**
3397
+	 *    _learn_more_about_message_templates_link
3398
+	 *
3399
+	 * @access protected
3400
+	 * @return string
3401
+	 */
3402
+	protected function _learn_more_about_message_templates_link()
3403
+	{
3404
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3405
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
3406
+			   . '</a>';
3407
+	}
3408
+
3409
+
3410
+	/**
3411
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3412
+	 * ajax and other routes.
3413
+	 *
3414
+	 * @return void
3415
+	 * @throws DomainException
3416
+	 * @throws EE_Error
3417
+	 */
3418
+	protected function _settings()
3419
+	{
3420
+		$this->_set_m_mt_settings();
3421
+
3422
+		// let's setup the messenger tabs
3423
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3424
+			$this->_m_mt_settings['messenger_tabs'],
3425
+			'messenger_links',
3426
+			'|',
3427
+			$this->request->getRequestParam('selected_messenger', 'email')
3428
+		);
3429
+
3430
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3431
+		$this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
3432
+
3433
+		$this->display_admin_page_with_sidebar();
3434
+	}
3435
+
3436
+
3437
+	/**
3438
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3439
+	 *
3440
+	 * @access protected
3441
+	 * @return void
3442
+	 * @throws DomainException
3443
+	 */
3444
+	protected function _set_m_mt_settings()
3445
+	{
3446
+		// first if this is already set then lets get out no need to regenerate data.
3447
+		if (! empty($this->_m_mt_settings)) {
3448
+			return;
3449
+		}
3450
+
3451
+		// get all installed messengers and message_types
3452
+		$messengers    = $this->_message_resource_manager->installed_messengers();
3453
+		$message_types = $this->_message_resource_manager->installed_message_types();
3454
+
3455
+
3456
+		// assemble the array for the _tab_text_links helper
3457
+
3458
+		foreach ($messengers as $messenger) {
3459
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3460
+				'label' => ucwords($messenger->label['singular']),
3461
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3462
+					? 'messenger-active'
3463
+					: '',
3464
+				'href'  => $messenger->name,
3465
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3466
+				'slug'  => $messenger->name,
3467
+				'obj'   => $messenger,
3468
+			];
3469
+
3470
+
3471
+			$message_types_for_messenger = $messenger->get_valid_message_types();
3472
+
3473
+			foreach ($message_types as $message_type) {
3474
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3475
+				// it shouldn't show in either the inactive OR active metabox.
3476
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3477
+					continue;
3478
+				}
3479
+
3480
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3481
+					$messenger->name,
3482
+					$message_type->name
3483
+				)
3484
+					? 'active'
3485
+					: 'inactive';
3486
+
3487
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3488
+					'label'    => ucwords($message_type->label['singular']),
3489
+					'class'    => 'message-type-' . $a_or_i,
3490
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3491
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3492
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3493
+					'title'    => $a_or_i === 'active'
3494
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3495
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3496
+					'content'  => $a_or_i === 'active'
3497
+						? $this->_message_type_settings_content($message_type, $messenger, true)
3498
+						: $this->_message_type_settings_content($message_type, $messenger),
3499
+					'slug'     => $message_type->name,
3500
+					'active'   => $a_or_i === 'active',
3501
+					'obj'      => $message_type,
3502
+				];
3503
+			}
3504
+		}
3505
+	}
3506
+
3507
+
3508
+	/**
3509
+	 * This just prepares the content for the message type settings
3510
+	 *
3511
+	 * @param EE_message_type $message_type The message type object
3512
+	 * @param EE_messenger    $messenger    The messenger object
3513
+	 * @param boolean         $active       Whether the message type is active or not
3514
+	 * @return string html output for the content
3515
+	 * @throws DomainException
3516
+	 */
3517
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
3518
+	{
3519
+		// get message type fields
3520
+		$fields                                         = $message_type->get_admin_settings_fields();
3521
+		$settings_template_args['template_form_fields'] = '';
3522
+
3523
+		if (! empty($fields) && $active) {
3524
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3525
+			foreach ($fields as $fldname => $fldprops) {
3526
+				$field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3527
+				$template_form_field[ $field_id ] = [
3528
+					'name'       => 'message_type_settings[' . $fldname . ']',
3529
+					'label'      => $fldprops['label'],
3530
+					'input'      => $fldprops['field_type'],
3531
+					'type'       => $fldprops['value_type'],
3532
+					'required'   => $fldprops['required'],
3533
+					'validation' => $fldprops['validation'],
3534
+					'value'      => isset($existing_settings[ $fldname ])
3535
+						? $existing_settings[ $fldname ]
3536
+						: $fldprops['default'],
3537
+					'options'    => isset($fldprops['options'])
3538
+						? $fldprops['options']
3539
+						: [],
3540
+					'default'    => isset($existing_settings[ $fldname ])
3541
+						? $existing_settings[ $fldname ]
3542
+						: $fldprops['default'],
3543
+					'css_class'  => 'no-drag',
3544
+					'format'     => $fldprops['format'],
3545
+				];
3546
+			}
3547
+
3548
+
3549
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3550
+				? $this->_generate_admin_form_fields(
3551
+					$template_form_field,
3552
+					'string',
3553
+					'ee_mt_activate_form'
3554
+				)
3555
+				: '';
3556
+		}
3557
+
3558
+		$settings_template_args['description'] = $message_type->description;
3559
+		// we also need some hidden fields
3560
+		$hidden_fields = [
3561
+			'message_type_settings[messenger]' . $message_type->name    => [
3562
+				'type'  => 'hidden',
3563
+				'value' => $messenger->name,
3564
+			],
3565
+			'message_type_settings[message_type]' . $message_type->name => [
3566
+				'type'  => 'hidden',
3567
+				'value' => $message_type->name,
3568
+			],
3569
+			'type' . $message_type->name                                => [
3570
+				'type'  => 'hidden',
3571
+				'value' => 'message_type',
3572
+			],
3573
+		];
3574
+
3575
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3576
+			$hidden_fields,
3577
+			'array'
3578
+		);
3579
+		$settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3580
+			? ' hidden'
3581
+			: '';
3582
+
3583
+
3584
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3585
+		return EEH_Template::display_template($template, $settings_template_args, true);
3586
+	}
3587
+
3588
+
3589
+	/**
3590
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3591
+	 *
3592
+	 * @access protected
3593
+	 * @return void
3594
+	 * @throws DomainException
3595
+	 */
3596
+	protected function _messages_settings_metaboxes()
3597
+	{
3598
+		$this->_set_m_mt_settings();
3599
+		$m_boxes         = $mt_boxes = [];
3600
+		$m_template_args = $mt_template_args = [];
3601
+
3602
+		$selected_messenger = $this->request->getRequestParam('selected_messenger', 'email');
3603
+
3604
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3605
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3606
+				$is_messenger_active = $this->_message_resource_manager->is_messenger_active($messenger);
3607
+				$hide_on_message     = $is_messenger_active ? '' : 'hidden';
3608
+				$hide_off_message    = $is_messenger_active ? 'hidden' : '';
3609
+
3610
+				// messenger meta boxes
3611
+				$active         = $selected_messenger === $messenger;
3612
+				$active_mt_tabs = isset($this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'])
3613
+					? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3614
+					: '';
3615
+
3616
+				$m_boxes[ $messenger . '_a_box' ] = sprintf(
3617
+					esc_html__('%s Settings', 'event_espresso'),
3618
+					$tab_array['label']
3619
+				);
3620
+
3621
+				$m_template_args[ $messenger . '_a_box' ] = [
3622
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3623
+					'inactive_message_types' => isset(
3624
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3625
+					)
3626
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3627
+						: '',
3628
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3629
+					'hidden'                 => $active ? '' : ' hidden',
3630
+					'hide_on_message'        => $hide_on_message,
3631
+					'messenger'              => $messenger,
3632
+					'active'                 => $active,
3633
+				];
3634
+
3635
+				// message type meta boxes
3636
+				// (which is really just the inactive container for each messenger
3637
+				// showing inactive message types for that messenger)
3638
+				$mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3639
+				$mt_template_args[ $messenger . '_i_box' ] = [
3640
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3641
+					'inactive_message_types' => isset(
3642
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3643
+					)
3644
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3645
+						: '',
3646
+					'hidden'                 => $active ? '' : ' hidden',
3647
+					'hide_on_message'        => $hide_on_message,
3648
+					'hide_off_message'       => $hide_off_message,
3649
+					'messenger'              => $messenger,
3650
+					'active'                 => $active,
3651
+				];
3652
+			}
3653
+		}
3654
+
3655
+
3656
+		// register messenger metaboxes
3657
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3658
+		foreach ($m_boxes as $box => $label) {
3659
+			$callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3660
+			$msgr          = str_replace('_a_box', '', $box);
3661
+			add_meta_box(
3662
+				'espresso_' . $msgr . '_settings',
3663
+				$label,
3664
+				function ($post, $metabox) {
3665
+					EEH_Template::display_template(
3666
+						$metabox['args']['template_path'],
3667
+						$metabox['args']['template_args']
3668
+					);
3669
+				},
3670
+				$this->_current_screen->id,
3671
+				'normal',
3672
+				'high',
3673
+				$callback_args
3674
+			);
3675
+		}
3676
+
3677
+		// register message type metaboxes
3678
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3679
+		foreach ($mt_boxes as $box => $label) {
3680
+			$callback_args = [
3681
+				'template_path' => $mt_template_path,
3682
+				'template_args' => $mt_template_args[ $box ],
3683
+			];
3684
+			$mt            = str_replace('_i_box', '', $box);
3685
+			add_meta_box(
3686
+				'espresso_' . $mt . '_inactive_mts',
3687
+				$label,
3688
+				function ($post, $metabox) {
3689
+					EEH_Template::display_template(
3690
+						$metabox['args']['template_path'],
3691
+						$metabox['args']['template_args']
3692
+					);
3693
+				},
3694
+				$this->_current_screen->id,
3695
+				'side',
3696
+				'high',
3697
+				$callback_args
3698
+			);
3699
+		}
3700
+
3701
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3702
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3703
+		if (is_main_site()) {
3704
+			add_meta_box(
3705
+				'espresso_global_message_settings',
3706
+				esc_html__('Global Message Settings', 'event_espresso'),
3707
+				[$this, 'global_messages_settings_metabox_content'],
3708
+				$this->_current_screen->id,
3709
+				'normal',
3710
+				'low',
3711
+				[]
3712
+			);
3713
+		}
3714
+	}
3715
+
3716
+
3717
+	/**
3718
+	 *  This generates the content for the global messages settings metabox.
3719
+	 *
3720
+	 * @return void
3721
+	 * @throws EE_Error
3722
+	 * @throws InvalidArgumentException
3723
+	 * @throws ReflectionException
3724
+	 * @throws InvalidDataTypeException
3725
+	 * @throws InvalidInterfaceException
3726
+	 */
3727
+	public function global_messages_settings_metabox_content()
3728
+	{
3729
+		$form = $this->_generate_global_settings_form();
3730
+		// already escaped
3731
+		echo $form->form_open(
3732
+			$this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3733
+			'POST'
3734
+		);
3735
+		echo $form->get_html();
3736
+		echo $form->form_close();
3737
+	}
3738
+
3739
+
3740
+	/**
3741
+	 * This generates and returns the form object for the global messages settings.
3742
+	 *
3743
+	 * @return EE_Form_Section_Proper
3744
+	 * @throws EE_Error
3745
+	 * @throws InvalidArgumentException
3746
+	 * @throws ReflectionException
3747
+	 * @throws InvalidDataTypeException
3748
+	 * @throws InvalidInterfaceException
3749
+	 */
3750
+	protected function _generate_global_settings_form()
3751
+	{
3752
+		/** @var EE_Network_Core_Config $network_config */
3753
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3754
+
3755
+		return new EE_Form_Section_Proper(
3756
+			[
3757
+				'name'            => 'global_messages_settings',
3758
+				'html_id'         => 'global_messages_settings',
3759
+				'html_class'      => 'form-table',
3760
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3761
+				'subsections'     => apply_filters(
3762
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3763
+					[
3764
+						'do_messages_on_same_request' => new EE_Select_Input(
3765
+							[
3766
+								true  => esc_html__('On the same request', 'event_espresso'),
3767
+								false => esc_html__('On a separate request', 'event_espresso'),
3768
+							],
3769
+							[
3770
+								'default'         => $network_config->do_messages_on_same_request,
3771
+								'html_label_text' => esc_html__(
3772
+									'Generate and send all messages:',
3773
+									'event_espresso'
3774
+								),
3775
+								'html_help_text'  => esc_html__(
3776
+									'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.',
3777
+									'event_espresso'
3778
+								),
3779
+							]
3780
+						),
3781
+						'delete_threshold'            => new EE_Select_Input(
3782
+							[
3783
+								0  => esc_html__('Forever', 'event_espresso'),
3784
+								3  => esc_html__('3 Months', 'event_espresso'),
3785
+								6  => esc_html__('6 Months', 'event_espresso'),
3786
+								9  => esc_html__('9 Months', 'event_espresso'),
3787
+								12 => esc_html__('12 Months', 'event_espresso'),
3788
+								24 => esc_html__('24 Months', 'event_espresso'),
3789
+								36 => esc_html__('36 Months', 'event_espresso'),
3790
+							],
3791
+							[
3792
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3793
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3794
+								'html_help_text'  => esc_html__(
3795
+									'You can control how long a record of processed messages is kept via this option.',
3796
+									'event_espresso'
3797
+								),
3798
+							]
3799
+						),
3800
+						'update_settings'             => new EE_Submit_Input(
3801
+							[
3802
+								'default'         => esc_html__('Update', 'event_espresso'),
3803
+								'html_label_text' => '&nbsp',
3804
+							]
3805
+						),
3806
+					]
3807
+				),
3808
+			]
3809
+		);
3810
+	}
3811
+
3812
+
3813
+	/**
3814
+	 * This handles updating the global settings set on the admin page.
3815
+	 *
3816
+	 * @throws EE_Error
3817
+	 * @throws InvalidDataTypeException
3818
+	 * @throws InvalidInterfaceException
3819
+	 * @throws InvalidArgumentException
3820
+	 * @throws ReflectionException
3821
+	 */
3822
+	protected function _update_global_settings()
3823
+	{
3824
+		/** @var EE_Network_Core_Config $network_config */
3825
+		$network_config  = EE_Registry::instance()->NET_CFG->core;
3826
+		$messages_config = EE_Registry::instance()->CFG->messages;
3827
+		$form            = $this->_generate_global_settings_form();
3828
+		if ($form->was_submitted()) {
3829
+			$form->receive_form_submission();
3830
+			if ($form->is_valid()) {
3831
+				$valid_data = $form->valid_data();
3832
+				foreach ($valid_data as $property => $value) {
3833
+					$setter = 'set_' . $property;
3834
+					if (method_exists($network_config, $setter)) {
3835
+						$network_config->{$setter}($value);
3836
+					} elseif (
3837
+						property_exists($network_config, $property)
3838
+						&& $network_config->{$property} !== $value
3839
+					) {
3840
+						$network_config->{$property} = $value;
3841
+					} elseif (
3842
+						property_exists($messages_config, $property)
3843
+						&& $messages_config->{$property} !== $value
3844
+					) {
3845
+						$messages_config->{$property} = $value;
3846
+					}
3847
+				}
3848
+				// only update if the form submission was valid!
3849
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3850
+				EE_Registry::instance()->CFG->update_espresso_config();
3851
+				EE_Error::overwrite_success();
3852
+				EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3853
+			}
3854
+		}
3855
+		$this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3856
+	}
3857
+
3858
+
3859
+	/**
3860
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3861
+	 *
3862
+	 * @param array $tab_array This is an array of message type tab details used to generate the tabs
3863
+	 * @return string html formatted tabs
3864
+	 * @throws DomainException
3865
+	 */
3866
+	protected function _get_mt_tabs($tab_array)
3867
+	{
3868
+		$tab_array = (array) $tab_array;
3869
+		$template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3870
+		$tabs      = '';
3871
+
3872
+		foreach ($tab_array as $tab) {
3873
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3874
+		}
3875
+
3876
+		return $tabs;
3877
+	}
3878
+
3879
+
3880
+	/**
3881
+	 * This prepares the content of the messenger meta box admin settings
3882
+	 *
3883
+	 * @param EE_messenger $messenger The messenger we're setting up content for
3884
+	 * @return string html formatted content
3885
+	 * @throws DomainException
3886
+	 */
3887
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3888
+	{
3889
+
3890
+		$fields                                         = $messenger->get_admin_settings_fields();
3891
+		$settings_template_args['template_form_fields'] = '';
3892
+
3893
+		// is $messenger active?
3894
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3895
+
3896
+
3897
+		if (! empty($fields)) {
3898
+			$existing_settings = $messenger->get_existing_admin_settings();
3899
+
3900
+			foreach ($fields as $fldname => $fldprops) {
3901
+				$field_id                         = $messenger->name . '-' . $fldname;
3902
+				$template_form_field[ $field_id ] = [
3903
+					'name'       => 'messenger_settings[' . $field_id . ']',
3904
+					'label'      => $fldprops['label'],
3905
+					'input'      => $fldprops['field_type'],
3906
+					'type'       => $fldprops['value_type'],
3907
+					'required'   => $fldprops['required'],
3908
+					'validation' => $fldprops['validation'],
3909
+					'value'      => isset($existing_settings[ $field_id ])
3910
+						? $existing_settings[ $field_id ]
3911
+						: $fldprops['default'],
3912
+					'css_class'  => '',
3913
+					'format'     => $fldprops['format'],
3914
+				];
3915
+			}
3916
+
3917
+
3918
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3919
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3920
+				: '';
3921
+		}
3922
+
3923
+		// we also need some hidden fields
3924
+		$settings_template_args['hidden_fields'] = [
3925
+			'messenger_settings[messenger]' . $messenger->name => [
3926
+				'type'  => 'hidden',
3927
+				'value' => $messenger->name,
3928
+			],
3929
+			'type' . $messenger->name                          => [
3930
+				'type'  => 'hidden',
3931
+				'value' => 'messenger',
3932
+			],
3933
+		];
3934
+
3935
+		// make sure any active message types that are existing are included in the hidden fields
3936
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3937
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3938
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3939
+					'type'  => 'hidden',
3940
+					'value' => $mt,
3941
+				];
3942
+			}
3943
+		}
3944
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3945
+			$settings_template_args['hidden_fields'],
3946
+			'array'
3947
+		);
3948
+		$active                                  =
3949
+			$this->_message_resource_manager->is_messenger_active($messenger->name);
3950
+
3951
+		$settings_template_args['messenger']           = $messenger->name;
3952
+		$settings_template_args['description']         = $messenger->description;
3953
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3954
+
3955
+
3956
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3957
+			$messenger->name
3958
+		)
3959
+			? $settings_template_args['show_hide_edit_form']
3960
+			: ' hidden';
3961
+
3962
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3963
+			? ' hidden'
3964
+			: $settings_template_args['show_hide_edit_form'];
3965
+
3966
+
3967
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3968
+		$settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3969
+		$settings_template_args['on_off_status'] = $active;
3970
+		$template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3971
+		return EEH_Template::display_template(
3972
+			$template,
3973
+			$settings_template_args,
3974
+			true
3975
+		);
3976
+	}
3977
+
3978
+
3979
+	/**
3980
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3981
+	 *
3982
+	 * @throws DomainException
3983
+	 * @throws EE_Error
3984
+	 * @throws InvalidDataTypeException
3985
+	 * @throws InvalidInterfaceException
3986
+	 * @throws InvalidArgumentException
3987
+	 * @throws ReflectionException
3988
+	 */
3989
+	public function activate_messenger_toggle()
3990
+	{
3991
+		$success = true;
3992
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3993
+		// let's check that we have required data
3994
+
3995
+		if (! $this->_active_messenger_name) {
3996
+			EE_Error::add_error(
3997
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3998
+				__FILE__,
3999
+				__FUNCTION__,
4000
+				__LINE__
4001
+			);
4002
+			$success = false;
4003
+		}
4004
+
4005
+		// do a nonce check here since we're not arriving via a normal route
4006
+		$nonce     = $this->request->getRequestParam('activate_nonce', '');
4007
+		$nonce_ref = "activate_{$this->_active_messenger_name}_toggle_nonce";
4008
+
4009
+		$this->_verify_nonce($nonce, $nonce_ref);
4010
+
4011
+
4012
+		$status = $this->request->getRequestParam('status');
4013
+		if (! $status) {
4014
+			EE_Error::add_error(
4015
+				esc_html__(
4016
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4017
+					'event_espresso'
4018
+				),
4019
+				__FILE__,
4020
+				__FUNCTION__,
4021
+				__LINE__
4022
+			);
4023
+			$success = false;
4024
+		}
4025
+
4026
+		// do check to verify we have a valid status.
4027
+		if ($status !== 'off' && $status !== 'on') {
4028
+			EE_Error::add_error(
4029
+				sprintf(
4030
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
4031
+					$status
4032
+				),
4033
+				__FILE__,
4034
+				__FUNCTION__,
4035
+				__LINE__
4036
+			);
4037
+			$success = false;
4038
+		}
4039
+
4040
+		if ($success) {
4041
+			// made it here?  Stop dawdling then!!
4042
+			$success = $status === 'off'
4043
+				? $this->_deactivate_messenger($this->_active_messenger_name)
4044
+				: $this->_activate_messenger($this->_active_messenger_name);
4045
+		}
4046
+
4047
+		$this->_template_args['success'] = $success;
4048
+
4049
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
4050
+		$this->_return_json();
4051
+	}
4052
+
4053
+
4054
+	/**
4055
+	 * used by ajax from the messages settings page to activate|deactivate a message type
4056
+	 *
4057
+	 * @throws DomainException
4058
+	 * @throws EE_Error
4059
+	 * @throws ReflectionException
4060
+	 * @throws InvalidDataTypeException
4061
+	 * @throws InvalidInterfaceException
4062
+	 * @throws InvalidArgumentException
4063
+	 */
4064
+	public function activate_mt_toggle()
4065
+	{
4066
+		$success = true;
4067
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
4068
+
4069
+		// let's make sure we have the necessary data
4070
+		if (! $this->_active_message_type_name) {
4071
+			EE_Error::add_error(
4072
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
4073
+				__FILE__,
4074
+				__FUNCTION__,
4075
+				__LINE__
4076
+			);
4077
+			$success = false;
4078
+		}
4079
+
4080
+		if (! $this->_active_messenger_name) {
4081
+			EE_Error::add_error(
4082
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
4083
+				__FILE__,
4084
+				__FUNCTION__,
4085
+				__LINE__
4086
+			);
4087
+			$success = false;
4088
+		}
4089
+
4090
+		$status = $this->request->getRequestParam('status');
4091
+		if (! $status) {
4092
+			EE_Error::add_error(
4093
+				esc_html__(
4094
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4095
+					'event_espresso'
4096
+				),
4097
+				__FILE__,
4098
+				__FUNCTION__,
4099
+				__LINE__
4100
+			);
4101
+			$success = false;
4102
+		}
4103
+
4104
+
4105
+		// do check to verify we have a valid status.
4106
+		if ($status !== 'activate' && $status !== 'deactivate') {
4107
+			EE_Error::add_error(
4108
+				sprintf(
4109
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
4110
+					$status
4111
+				),
4112
+				__FILE__,
4113
+				__FUNCTION__,
4114
+				__LINE__
4115
+			);
4116
+			$success = false;
4117
+		}
4118
+
4119
+
4120
+		// do a nonce check here since we're not arriving via a normal route
4121
+		$nonce = $this->request->getRequestParam('mt_nonce', '');
4122
+		$this->_verify_nonce($nonce, "{$this->_active_message_type_name}_nonce");
4123
+
4124
+		if ($success) {
4125
+			// made it here? um, what are you waiting for then?
4126
+			$success = $status === 'deactivate'
4127
+				? $this->_deactivate_message_type_for_messenger(
4128
+					$this->_active_messenger_name,
4129
+					$this->_active_message_type_name
4130
+				)
4131
+				: $this->_activate_message_type_for_messenger(
4132
+					$this->_active_messenger_name,
4133
+					$this->_active_message_type_name
4134
+				);
4135
+		}
4136
+
4137
+		$this->_template_args['success'] = $success;
4138
+		$this->_return_json();
4139
+	}
4140
+
4141
+
4142
+	/**
4143
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
4144
+	 *
4145
+	 * @param string $messenger_name The name of the messenger being activated
4146
+	 * @return bool
4147
+	 * @throws DomainException
4148
+	 * @throws EE_Error
4149
+	 * @throws InvalidArgumentException
4150
+	 * @throws ReflectionException
4151
+	 * @throws InvalidDataTypeException
4152
+	 * @throws InvalidInterfaceException
4153
+	 */
4154
+	protected function _activate_messenger($messenger_name)
4155
+	{
4156
+		$active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
4157
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
4158
+			? $active_messenger->get_default_message_types()
4159
+			: [];
4160
+
4161
+		// ensure is active
4162
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4163
+
4164
+		// set response_data for reload
4165
+		foreach ($message_types_to_activate as $message_type_name) {
4166
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4167
+			if (
4168
+				$this->_message_resource_manager->is_message_type_active_for_messenger(
4169
+					$messenger_name,
4170
+					$message_type_name
4171
+				)
4172
+				&& $message_type instanceof EE_message_type
4173
+			) {
4174
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
4175
+				if ($message_type->get_admin_settings_fields()) {
4176
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
4177
+				}
4178
+			}
4179
+		}
4180
+
4181
+		// add success message for activating messenger
4182
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4183
+	}
4184
+
4185
+
4186
+	/**
4187
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
4188
+	 *
4189
+	 * @param string $messenger_name The name of the messenger being activated
4190
+	 * @return bool
4191
+	 * @throws DomainException
4192
+	 * @throws EE_Error
4193
+	 * @throws InvalidArgumentException
4194
+	 * @throws ReflectionException
4195
+	 * @throws InvalidDataTypeException
4196
+	 * @throws InvalidInterfaceException
4197
+	 */
4198
+	protected function _deactivate_messenger($messenger_name)
4199
+	{
4200
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4201
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
4202
+
4203
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4204
+	}
4205
+
4206
+
4207
+	/**
4208
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4209
+	 *
4210
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
4211
+	 * @param string $message_type_name The name of the message type being activated for the messenger
4212
+	 * @return bool
4213
+	 * @throws DomainException
4214
+	 * @throws EE_Error
4215
+	 * @throws InvalidArgumentException
4216
+	 * @throws ReflectionException
4217
+	 * @throws InvalidDataTypeException
4218
+	 * @throws InvalidInterfaceException
4219
+	 */
4220
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4221
+	{
4222
+		$active_messenger         = $this->_message_resource_manager->get_messenger($messenger_name);
4223
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4224
+
4225
+		// ensure is active
4226
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4227
+
4228
+		// set response for load
4229
+		if (
4230
+			$this->_message_resource_manager->is_message_type_active_for_messenger(
4231
+				$messenger_name,
4232
+				$message_type_name
4233
+			)
4234
+		) {
4235
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
4236
+			if ($message_type_to_activate->get_admin_settings_fields()) {
4237
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
4238
+			}
4239
+		}
4240
+
4241
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
4242
+			$active_messenger,
4243
+			$message_type_to_activate
4244
+		);
4245
+	}
4246
+
4247
+
4248
+	/**
4249
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4250
+	 *
4251
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4252
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
4253
+	 * @return bool
4254
+	 * @throws DomainException
4255
+	 * @throws EE_Error
4256
+	 * @throws InvalidArgumentException
4257
+	 * @throws ReflectionException
4258
+	 * @throws InvalidDataTypeException
4259
+	 * @throws InvalidInterfaceException
4260
+	 */
4261
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4262
+	{
4263
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4264
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4265
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4266
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4267
+
4268
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4269
+			$active_messenger,
4270
+			$message_type_to_deactivate
4271
+		);
4272
+	}
4273
+
4274
+
4275
+	/**
4276
+	 * This just initializes the defaults for activating messenger and message type responses.
4277
+	 */
4278
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
4279
+	{
4280
+		$this->_template_args['data']['active_mts'] = [];
4281
+		$this->_template_args['data']['mt_reload']  = [];
4282
+	}
4283
+
4284
+
4285
+	/**
4286
+	 * Setup appropriate response for activating a messenger and/or message types
4287
+	 *
4288
+	 * @param EE_messenger         $messenger
4289
+	 * @param EE_message_type|null $message_type
4290
+	 * @return bool
4291
+	 * @throws DomainException
4292
+	 * @throws EE_Error
4293
+	 * @throws InvalidArgumentException
4294
+	 * @throws ReflectionException
4295
+	 * @throws InvalidDataTypeException
4296
+	 * @throws InvalidInterfaceException
4297
+	 */
4298
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
4299
+		$messenger,
4300
+		EE_Message_Type $message_type = null
4301
+	) {
4302
+		// if $messenger isn't a valid messenger object then get out.
4303
+		if (! $messenger instanceof EE_Messenger) {
4304
+			EE_Error::add_error(
4305
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4306
+				__FILE__,
4307
+				__FUNCTION__,
4308
+				__LINE__
4309
+			);
4310
+			return false;
4311
+		}
4312
+		// activated
4313
+		if ($this->_template_args['data']['active_mts']) {
4314
+			EE_Error::overwrite_success();
4315
+			// activated a message type with the messenger
4316
+			if ($message_type instanceof EE_message_type) {
4317
+				EE_Error::add_success(
4318
+					sprintf(
4319
+						esc_html__(
4320
+							'%s message type has been successfully activated with the %s messenger',
4321
+							'event_espresso'
4322
+						),
4323
+						ucwords($message_type->label['singular']),
4324
+						ucwords($messenger->label['singular'])
4325
+					)
4326
+				);
4327
+
4328
+				// if message type was invoice then let's make sure we activate the invoice payment method.
4329
+				if ($message_type->name === 'invoice') {
4330
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
4331
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4332
+					if ($pm instanceof EE_Payment_Method) {
4333
+						EE_Error::add_attention(
4334
+							esc_html__(
4335
+								'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.',
4336
+								'event_espresso'
4337
+							)
4338
+						);
4339
+					}
4340
+				}
4341
+				// just toggles the entire messenger
4342
+			} else {
4343
+				EE_Error::add_success(
4344
+					sprintf(
4345
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4346
+						ucwords($messenger->label['singular'])
4347
+					)
4348
+				);
4349
+			}
4350
+
4351
+			return true;
4352
+
4353
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4354
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4355
+			// in which case we just give a success message for the messenger being successfully activated.
4356
+		} else {
4357
+			if (! $messenger->get_default_message_types()) {
4358
+				// messenger doesn't have any default message types so still a success.
4359
+				EE_Error::add_success(
4360
+					sprintf(
4361
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4362
+						ucwords($messenger->label['singular'])
4363
+					)
4364
+				);
4365
+
4366
+				return true;
4367
+			} else {
4368
+				EE_Error::add_error(
4369
+					$message_type instanceof EE_message_type
4370
+					? sprintf(
4371
+						esc_html__(
4372
+							'%s message type was not successfully activated with the %s messenger',
4373
+							'event_espresso'
4374
+						),
4375
+						ucwords($message_type->label['singular']),
4376
+						ucwords($messenger->label['singular'])
4377
+					)
4378
+					: sprintf(
4379
+						esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4380
+						ucwords($messenger->label['singular'])
4381
+					),
4382
+					__FILE__,
4383
+					__FUNCTION__,
4384
+					__LINE__
4385
+				);
4386
+
4387
+				return false;
4388
+			}
4389
+		}
4390
+	}
4391
+
4392
+
4393
+	/**
4394
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
4395
+	 *
4396
+	 * @param EE_messenger         $messenger
4397
+	 * @param EE_message_type|null $message_type
4398
+	 * @return bool
4399
+	 * @throws DomainException
4400
+	 * @throws EE_Error
4401
+	 * @throws InvalidArgumentException
4402
+	 * @throws ReflectionException
4403
+	 * @throws InvalidDataTypeException
4404
+	 * @throws InvalidInterfaceException
4405
+	 */
4406
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4407
+		$messenger,
4408
+		EE_message_type $message_type = null
4409
+	) {
4410
+		EE_Error::overwrite_success();
4411
+
4412
+		// if $messenger isn't a valid messenger object then get out.
4413
+		if (! $messenger instanceof EE_Messenger) {
4414
+			EE_Error::add_error(
4415
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4416
+				__FILE__,
4417
+				__FUNCTION__,
4418
+				__LINE__
4419
+			);
4420
+
4421
+			return false;
4422
+		}
4423
+
4424
+		if ($message_type instanceof EE_message_type) {
4425
+			$message_type_name = $message_type->name;
4426
+			EE_Error::add_success(
4427
+				sprintf(
4428
+					esc_html__(
4429
+						'%s message type has been successfully deactivated for the %s messenger.',
4430
+						'event_espresso'
4431
+					),
4432
+					ucwords($message_type->label['singular']),
4433
+					ucwords($messenger->label['singular'])
4434
+				)
4435
+			);
4436
+		} else {
4437
+			$message_type_name = '';
4438
+			EE_Error::add_success(
4439
+				sprintf(
4440
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4441
+					ucwords($messenger->label['singular'])
4442
+				)
4443
+			);
4444
+		}
4445
+
4446
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4447
+		if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4448
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
4449
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4450
+			if ($count_updated > 0) {
4451
+				$msg = $message_type_name === 'invoice'
4452
+					? esc_html__(
4453
+						'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.',
4454
+						'event_espresso'
4455
+					)
4456
+					: esc_html__(
4457
+						'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.',
4458
+						'event_espresso'
4459
+					);
4460
+				EE_Error::add_attention($msg);
4461
+			}
4462
+		}
4463
+
4464
+		return true;
4465
+	}
4466
+
4467
+
4468
+	/**
4469
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4470
+	 *
4471
+	 * @throws DomainException
4472
+	 * @throws EE_Error
4473
+	 * @throws EE_Error
4474
+	 */
4475
+	public function update_mt_form()
4476
+	{
4477
+		if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
4478
+			EE_Error::add_error(
4479
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4480
+				__FILE__,
4481
+				__FUNCTION__,
4482
+				__LINE__
4483
+			);
4484
+			$this->_return_json();
4485
+		}
4486
+
4487
+		$message_types = $this->get_installed_message_types();
4488
+		$message_type  = $message_types[ $this->_active_message_type_name ];
4489
+		$messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
4490
+		$content       = $this->_message_type_settings_content($message_type, $messenger, true);
4491
+
4492
+		$this->_template_args['success'] = true;
4493
+		$this->_template_args['content'] = $content;
4494
+		$this->_return_json();
4495
+	}
4496
+
4497
+
4498
+	/**
4499
+	 * this handles saving the settings for a messenger or message type
4500
+	 *
4501
+	 * @throws EE_Error
4502
+	 * @throws EE_Error
4503
+	 */
4504
+	public function save_settings()
4505
+	{
4506
+		$type = $this->request->getRequestParam('type');
4507
+		if (! $type) {
4508
+			EE_Error::add_error(
4509
+				esc_html__(
4510
+					'Cannot save settings because type is unknown (messenger settings or message type settings?)',
4511
+					'event_espresso'
4512
+				),
4513
+				__FILE__,
4514
+				__FUNCTION__,
4515
+				__LINE__
4516
+			);
4517
+			$this->_template_args['error'] = true;
4518
+			$this->_return_json();
4519
+		}
4520
+
4521
+
4522
+		if ($type === 'messenger') {
4523
+			// this should be an array.
4524
+			$settings  = $this->request->getRequestParam('messenger_settings', [], 'string', true);
4525
+			$messenger = $settings['messenger'];
4526
+			// remove messenger and message_types from settings array
4527
+			unset($settings['messenger'], $settings['message_types']);
4528
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4529
+		} elseif ($type === 'message_type') {
4530
+			$settings     = $this->request->getRequestParam('message_type_settings', [], 'string', true);
4531
+			$messenger    = $settings['messenger'];
4532
+			$message_type = $settings['message_type'];
4533
+			// remove messenger and message_types from settings array
4534
+			unset($settings['messenger'], $settings['message_types']);
4535
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4536
+		}
4537
+
4538
+		// okay we should have the data all setup.  Now we just update!
4539
+		$success = $this->_message_resource_manager->update_active_messengers_option();
4540
+
4541
+		if ($success) {
4542
+			EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
4543
+		} else {
4544
+			EE_Error::add_error(
4545
+				esc_html__('Settings did not get updated', 'event_espresso'),
4546
+				__FILE__,
4547
+				__FUNCTION__,
4548
+				__LINE__
4549
+			);
4550
+		}
4551
+
4552
+		$this->_template_args['success'] = $success;
4553
+		$this->_return_json();
4554
+	}
4555
+
4556
+
4557
+
4558
+
4559
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4560
+
4561
+
4562
+	/**
4563
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4564
+	 * However, this does not send immediately, it just queues for sending.
4565
+	 *
4566
+	 * @throws EE_Error
4567
+	 * @throws InvalidDataTypeException
4568
+	 * @throws InvalidInterfaceException
4569
+	 * @throws InvalidArgumentException
4570
+	 * @throws ReflectionException
4571
+	 * @since 4.9.0
4572
+	 */
4573
+	protected function _generate_now()
4574
+	{
4575
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4576
+		$this->_redirect_after_action(false, '', '', [], true);
4577
+	}
4578
+
4579
+
4580
+	/**
4581
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4582
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4583
+	 *
4584
+	 * @throws EE_Error
4585
+	 * @throws InvalidDataTypeException
4586
+	 * @throws InvalidInterfaceException
4587
+	 * @throws InvalidArgumentException
4588
+	 * @throws ReflectionException
4589
+	 * @since 4.9.0
4590
+	 */
4591
+	protected function _generate_and_send_now()
4592
+	{
4593
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4594
+		$this->_redirect_after_action(false, '', '', [], true);
4595
+	}
4596
+
4597
+
4598
+	/**
4599
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4600
+	 *
4601
+	 * @throws EE_Error
4602
+	 * @throws InvalidDataTypeException
4603
+	 * @throws InvalidInterfaceException
4604
+	 * @throws InvalidArgumentException
4605
+	 * @throws ReflectionException
4606
+	 * @since 4.9.0
4607
+	 */
4608
+	protected function _queue_for_resending()
4609
+	{
4610
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4611
+		$this->_redirect_after_action(false, '', '', [], true);
4612
+	}
4613
+
4614
+
4615
+	/**
4616
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4617
+	 *
4618
+	 * @throws EE_Error
4619
+	 * @throws InvalidDataTypeException
4620
+	 * @throws InvalidInterfaceException
4621
+	 * @throws InvalidArgumentException
4622
+	 * @throws ReflectionException
4623
+	 * @since 4.9.0
4624
+	 */
4625
+	protected function _send_now()
4626
+	{
4627
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4628
+		$this->_redirect_after_action(false, '', '', [], true);
4629
+	}
4630
+
4631
+
4632
+	/**
4633
+	 * Deletes EE_messages for IDs in the request.
4634
+	 *
4635
+	 * @throws EE_Error
4636
+	 * @throws InvalidDataTypeException
4637
+	 * @throws InvalidInterfaceException
4638
+	 * @throws InvalidArgumentException
4639
+	 * @since 4.9.0
4640
+	 */
4641
+	protected function _delete_ee_messages()
4642
+	{
4643
+		$MSG_IDs       = $this->_get_msg_ids_from_request();
4644
+		$deleted_count = 0;
4645
+		foreach ($MSG_IDs as $MSG_ID) {
4646
+			if ($this->getMsgModel()->delete_by_ID($MSG_ID)) {
4647
+				$deleted_count++;
4648
+			}
4649
+		}
4650
+		if ($deleted_count) {
4651
+			EE_Error::add_success(
4652
+				esc_html(
4653
+					_n(
4654
+						'Message successfully deleted',
4655
+						'Messages successfully deleted',
4656
+						$deleted_count,
4657
+						'event_espresso'
4658
+					)
4659
+				)
4660
+			);
4661
+		} else {
4662
+			EE_Error::add_error(
4663
+				_n('The message was not deleted.', 'The messages were not deleted', count($MSG_IDs), 'event_espresso'),
4664
+				__FILE__,
4665
+				__FUNCTION__,
4666
+				__LINE__
4667
+			);
4668
+		}
4669
+		$this->_redirect_after_action(false, '', '', [], true);
4670
+	}
4671
+
4672
+
4673
+	/**
4674
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4675
+	 *
4676
+	 * @return array
4677
+	 * @since 4.9.0
4678
+	 */
4679
+	protected function _get_msg_ids_from_request()
4680
+	{
4681
+		$MSG_IDs = $this->request->getRequestParam('MSG_ID', [], 'string', true);
4682
+		if (empty($MSG_IDs)) {
4683
+			return [];
4684
+		}
4685
+		// if 'MSG_ID' was just a single ID (not an array)
4686
+		// then $MSG_IDs will be something like [123] so $MSG_IDs[0] should be 123
4687
+		// otherwise, $MSG_IDs was already an array where message IDs were used as the keys
4688
+		return count($MSG_IDs) === 1 && isset($MSG_IDs[0])
4689
+			? $MSG_IDs
4690
+			: array_keys($MSG_IDs);
4691
+	}
4692 4692
 }
Please login to merge, or discard this patch.
Spacing   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
      */
115 115
     public function getMsgModel()
116 116
     {
117
-        if (! $this->MSG_MODEL instanceof EEM_Message) {
117
+        if ( ! $this->MSG_MODEL instanceof EEM_Message) {
118 118
             $this->MSG_MODEL = EEM_Message::instance();
119 119
         }
120 120
         return $this->MSG_MODEL;
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
      */
128 128
     public function getMtpModel()
129 129
     {
130
-        if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
130
+        if ( ! $this->MTP_MODEL instanceof EEM_Message_Template) {
131 131
             $this->MTP_MODEL = EEM_Message_Template::instance();
132 132
         }
133 133
         return $this->MTP_MODEL;
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
      */
141 141
     public function getMtgModel()
142 142
     {
143
-        if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
143
+        if ( ! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
144 144
             $this->MTG_MODEL = EEM_Message_Template_Group::instance();
145 145
         }
146 146
         return $this->MTG_MODEL;
@@ -208,8 +208,8 @@  discard block
 block discarded – undo
208 208
         $i = 1;
209 209
         foreach ($active_messengers as $active_messenger) {
210 210
             if ($active_messenger instanceof EE_Message) {
211
-                $m_values[ $i ]['id']   = $active_messenger->messenger();
212
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
211
+                $m_values[$i]['id']   = $active_messenger->messenger();
212
+                $m_values[$i]['text'] = ucwords($active_messenger->messenger_label());
213 213
                 $i++;
214 214
             }
215 215
         }
@@ -245,8 +245,8 @@  discard block
 block discarded – undo
245 245
         $i               = 1;
246 246
         foreach ($active_messages as $active_message) {
247 247
             if ($active_message instanceof EE_Message) {
248
-                $mt_values[ $i ]['id']   = $active_message->message_type();
249
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
248
+                $mt_values[$i]['id']   = $active_message->message_type();
249
+                $mt_values[$i]['text'] = ucwords($active_message->message_type_label());
250 250
                 $i++;
251 251
             }
252 252
         }
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
                 if ($message_type instanceof EE_message_type) {
286 286
                     $message_type_contexts = $message_type->get_contexts();
287 287
                     foreach ($message_type_contexts as $context => $context_details) {
288
-                        $contexts[ $context ] = $context_details['label'];
288
+                        $contexts[$context] = $context_details['label'];
289 289
                     }
290 290
                 }
291 291
             }
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
             ['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
319 319
             $messenger_options
320 320
         );
321
-        $input             = new EE_Select_Input(
321
+        $input = new EE_Select_Input(
322 322
             $messenger_options,
323 323
             [
324 324
                 'html_name'  => 'ee_messenger_filter_by',
@@ -355,7 +355,7 @@  discard block
 block discarded – undo
355 355
             ['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
356 356
             $message_type_options
357 357
         );
358
-        $input                = new EE_Select_Input(
358
+        $input = new EE_Select_Input(
359 359
             $message_type_options,
360 360
             [
361 361
                 'html_name'  => 'ee_message_type_filter_by',
@@ -392,7 +392,7 @@  discard block
 block discarded – undo
392 392
             ['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
393 393
             $context_options
394 394
         );
395
-        $input           = new EE_Select_Input(
395
+        $input = new EE_Select_Input(
396 396
             $context_options,
397 397
             [
398 398
                 'html_name'  => 'ee_context_filter_by',
@@ -774,53 +774,53 @@  discard block
 block discarded – undo
774 774
 
775 775
     public function messages_help_tab()
776 776
     {
777
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
777
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_help_tab.template.php');
778 778
     }
779 779
 
780 780
 
781 781
     public function messengers_help_tab()
782 782
     {
783
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
783
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messenger_help_tab.template.php');
784 784
     }
785 785
 
786 786
 
787 787
     public function message_types_help_tab()
788 788
     {
789
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
789
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_type_help_tab.template.php');
790 790
     }
791 791
 
792 792
 
793 793
     public function messages_overview_help_tab()
794 794
     {
795
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
795
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_overview_help_tab.template.php');
796 796
     }
797 797
 
798 798
 
799 799
     public function message_templates_help_tab()
800 800
     {
801
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
801
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_templates_help_tab.template.php');
802 802
     }
803 803
 
804 804
 
805 805
     public function edit_message_template_help_tab()
806 806
     {
807
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
807
+        $args['img1'] = '<img src="'.EE_MSG_ASSETS_URL.'images/editor.png'.'" alt="'
808 808
                         . esc_attr__('Editor Title', 'event_espresso')
809 809
                         . '" />';
810
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
810
+        $args['img2'] = '<img src="'.EE_MSG_ASSETS_URL.'images/switch-context.png'.'" alt="'
811 811
                         . esc_attr__('Context Switcher and Preview', 'event_espresso')
812 812
                         . '" />';
813
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
813
+        $args['img3'] = '<img class="left" src="'.EE_MSG_ASSETS_URL.'images/form-fields.png'.'" alt="'
814 814
                         . esc_attr__('Message Template Form Fields', 'event_espresso')
815 815
                         . '" />';
816
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
816
+        $args['img4'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/shortcodes-metabox.png'.'" alt="'
817 817
                         . esc_attr__('Shortcodes Metabox', 'event_espresso')
818 818
                         . '" />';
819
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
819
+        $args['img5'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/publish-meta-box.png'.'" alt="'
820 820
                         . esc_attr__('Publish Metabox', 'event_espresso')
821 821
                         . '" />';
822 822
         EEH_Template::display_template(
823
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
823
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_templates_editor_help_tab.template.php',
824 824
             $args
825 825
         );
826 826
     }
@@ -835,7 +835,7 @@  discard block
 block discarded – undo
835 835
         $this->_set_shortcodes();
836 836
         $args['shortcodes'] = $this->_shortcodes;
837 837
         EEH_Template::display_template(
838
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
838
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_shortcodes_help_tab.template.php',
839 839
             $args
840 840
         );
841 841
     }
@@ -843,16 +843,16 @@  discard block
 block discarded – undo
843 843
 
844 844
     public function preview_message_help_tab()
845 845
     {
846
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
846
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_preview_help_tab.template.php');
847 847
     }
848 848
 
849 849
 
850 850
     public function settings_help_tab()
851 851
     {
852
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
853
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
854
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
855
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
852
+        $args['img1'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-active.png'
853
+                        . '" alt="'.esc_attr__('Active Email Tab', 'event_espresso').'" />';
854
+        $args['img2'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-inactive.png'
855
+                        . '" alt="'.esc_attr__('Inactive Email Tab', 'event_espresso').'" />';
856 856
         $args['img3'] = '<div class="switch">'
857 857
                         . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
858 858
                         . ' type="checkbox" checked="checked">'
@@ -863,25 +863,25 @@  discard block
 block discarded – undo
863 863
                         . ' type="checkbox">'
864 864
                         . '<label for="ee-on-off-toggle-on"></label>'
865 865
                         . '</div>';
866
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
866
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_settings_help_tab.template.php', $args);
867 867
     }
868 868
 
869 869
 
870 870
     public function load_scripts_styles()
871 871
     {
872
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
872
+        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL.'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
873 873
         wp_enqueue_style('espresso_ee_msg');
874 874
 
875 875
         wp_register_script(
876 876
             'ee-messages-settings',
877
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
877
+            EE_MSG_ASSETS_URL.'ee-messages-settings.js',
878 878
             ['jquery-ui-droppable', 'ee-serialize-full-array'],
879 879
             EVENT_ESPRESSO_VERSION,
880 880
             true
881 881
         );
882 882
         wp_register_script(
883 883
             'ee-msg-list-table-js',
884
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
884
+            EE_MSG_ASSETS_URL.'ee_message_admin_list_table.js',
885 885
             ['ee-dialog'],
886 886
             EVENT_ESPRESSO_VERSION
887 887
         );
@@ -924,7 +924,7 @@  discard block
 block discarded – undo
924 924
 
925 925
         $this->_set_shortcodes();
926 926
 
927
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
927
+        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
928 928
             esc_html__(
929 929
                 '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.',
930 930
                 'event_espresso'
@@ -936,14 +936,14 @@  discard block
 block discarded – undo
936 936
             '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?',
937 937
             'event_espresso'
938 938
         );
939
-        EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
939
+        EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
940 940
             'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
941 941
             'event_espresso'
942 942
         );
943 943
 
944 944
         wp_register_script(
945 945
             'ee_msgs_edit_js',
946
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
946
+            EE_MSG_ASSETS_URL.'ee_message_editor.js',
947 947
             ['jquery'],
948 948
             EVENT_ESPRESSO_VERSION
949 949
         );
@@ -986,7 +986,7 @@  discard block
 block discarded – undo
986 986
     {
987 987
         wp_register_style(
988 988
             'ee-message-settings',
989
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
989
+            EE_MSG_ASSETS_URL.'ee_message_settings.css',
990 990
             [],
991 991
             EVENT_ESPRESSO_VERSION
992 992
         );
@@ -1072,7 +1072,7 @@  discard block
 block discarded – undo
1072 1072
             }
1073 1073
             $status_bulk_actions = $common_bulk_actions;
1074 1074
             // unset bulk actions not applying to status
1075
-            if (! empty($status_bulk_actions)) {
1075
+            if ( ! empty($status_bulk_actions)) {
1076 1076
                 switch ($status) {
1077 1077
                     case EEM_Message::status_idle:
1078 1078
                     case EEM_Message::status_resend:
@@ -1101,7 +1101,7 @@  discard block
 block discarded – undo
1101 1101
                 continue;
1102 1102
             }
1103 1103
 
1104
-            $this->_views[ strtolower($status) ] = [
1104
+            $this->_views[strtolower($status)] = [
1105 1105
                 'slug'        => strtolower($status),
1106 1106
                 'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1107 1107
                 'count'       => 0,
@@ -1150,7 +1150,7 @@  discard block
 block discarded – undo
1150 1150
             if ($action_item === 'see_notifications_for') {
1151 1151
                 continue;
1152 1152
             }
1153
-            $action_items[ $action_item ] = [
1153
+            $action_items[$action_item] = [
1154 1154
                 'class' => $action_details['css_class'],
1155 1155
                 'desc'  => $action_details['label'],
1156 1156
             ];
@@ -1159,37 +1159,37 @@  discard block
 block discarded – undo
1159 1159
         /** @var array $status_items status legend setup */
1160 1160
         $status_items = [
1161 1161
             'sent_status'                => [
1162
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1162
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_sent,
1163 1163
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1164 1164
             ],
1165 1165
             'idle_status'                => [
1166
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1166
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_idle,
1167 1167
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1168 1168
             ],
1169 1169
             'failed_status'              => [
1170
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1170
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_failed,
1171 1171
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1172 1172
             ],
1173 1173
             'messenger_executing_status' => [
1174
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1174
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_messenger_executing,
1175 1175
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1176 1176
             ],
1177 1177
             'resend_status'              => [
1178
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1178
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_resend,
1179 1179
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1180 1180
             ],
1181 1181
             'incomplete_status'          => [
1182
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1182
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_incomplete,
1183 1183
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1184 1184
             ],
1185 1185
             'retry_status'               => [
1186
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1186
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_retry,
1187 1187
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1188 1188
             ],
1189 1189
         ];
1190 1190
         if (EEM_Message::debug()) {
1191 1191
             $status_items['debug_only_status'] = [
1192
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1192
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_debug_only,
1193 1193
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1194 1194
             ];
1195 1195
         }
@@ -1204,11 +1204,11 @@  discard block
 block discarded – undo
1204 1204
     protected function _custom_mtps_preview()
1205 1205
     {
1206 1206
         $this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1207
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1208
-                                                . ' alt="' . esc_attr__(
1207
+        $this->_template_args['preview_img']  = '<img src="'.EE_MSG_ASSETS_URL.'images/custom_mtps_preview.png"'
1208
+                                                . ' alt="'.esc_attr__(
1209 1209
                                                     'Preview Custom Message Templates screenshot',
1210 1210
                                                     'event_espresso'
1211
-                                                ) . '" />';
1211
+                                                ).'" />';
1212 1212
         $this->_template_args['preview_text'] = '<strong>'
1213 1213
                                                 . esc_html__(
1214 1214
                                                     '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.',
@@ -1284,7 +1284,7 @@  discard block
 block discarded – undo
1284 1284
         $installed               = [];
1285 1285
 
1286 1286
         foreach ($installed_message_types as $message_type) {
1287
-            $installed[ $message_type->name ] = $message_type;
1287
+            $installed[$message_type->name] = $message_type;
1288 1288
         }
1289 1289
 
1290 1290
         return $installed;
@@ -1410,7 +1410,7 @@  discard block
 block discarded – undo
1410 1410
         // we need to assemble the title from Various details
1411 1411
         $context_label = sprintf(
1412 1412
             esc_html__('(%s %s)', 'event_espresso'),
1413
-            $c_config[ $context ]['label'],
1413
+            $c_config[$context]['label'],
1414 1414
             ucwords($c_label['label'])
1415 1415
         );
1416 1416
 
@@ -1432,7 +1432,7 @@  discard block
 block discarded – undo
1432 1432
             $message_template_group->message_type()
1433 1433
         );
1434 1434
 
1435
-        if (! $template_field_structure) {
1435
+        if ( ! $template_field_structure) {
1436 1436
             $template_field_structure = false;
1437 1437
             $template_fields          = esc_html__(
1438 1438
                 'There was an error in assembling the fields for this display (you should see an error message)',
@@ -1446,21 +1446,21 @@  discard block
 block discarded – undo
1446 1446
 
1447 1447
         // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1448 1448
         // will get handled in the "extra" array.
1449
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1450
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1451
-                unset($template_field_structure[ $context ][ $reference_field ]);
1449
+        if (is_array($template_field_structure[$context]) && isset($template_field_structure[$context]['extra'])) {
1450
+            foreach ($template_field_structure[$context]['extra'] as $reference_field => $new_fields) {
1451
+                unset($template_field_structure[$context][$reference_field]);
1452 1452
             }
1453 1453
         }
1454 1454
 
1455 1455
         // let's loop through the template_field_structure and actually assemble the input fields!
1456
-        if (! empty($template_field_structure)) {
1457
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1456
+        if ( ! empty($template_field_structure)) {
1457
+            foreach ($template_field_structure[$context] as $template_field => $field_setup_array) {
1458 1458
                 // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1459 1459
                 // the extra array and reset them.
1460 1460
                 if ($template_field === 'extra') {
1461 1461
                     $this->_template_args['is_extra_fields'] = true;
1462 1462
                     foreach ($field_setup_array as $reference_field => $new_fields_array) {
1463
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1463
+                        $message_template = $message_templates[$context][$reference_field];
1464 1464
                         $content          = $message_template instanceof EE_Message_Template
1465 1465
                             ? $message_template->get('MTP_content')
1466 1466
                             : '';
@@ -1469,7 +1469,7 @@  discard block
 block discarded – undo
1469 1469
                             $continue = false;
1470 1470
                             if (isset($extra_array['shortcodes_required'])) {
1471 1471
                                 foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1472
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1472
+                                    if ( ! array_key_exists($shortcode, $this->_shortcodes)) {
1473 1473
                                         $continue = true;
1474 1474
                                     }
1475 1475
                                 }
@@ -1478,53 +1478,53 @@  discard block
 block discarded – undo
1478 1478
                                 }
1479 1479
                             }
1480 1480
 
1481
-                            $field_id = $reference_field . '-' . $extra_field . '-content';
1481
+                            $field_id = $reference_field.'-'.$extra_field.'-content';
1482 1482
 
1483
-                            $template_form_fields[ $field_id ]         = $extra_array;
1484
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1483
+                            $template_form_fields[$field_id]         = $extra_array;
1484
+                            $template_form_fields[$field_id]['name'] = 'MTP_template_fields['
1485 1485
                                                                          . $reference_field
1486 1486
                                                                          . '][content]['
1487
-                                                                         . $extra_field . ']';
1488
-                            $css_class                                 = isset($extra_array['css_class'])
1487
+                                                                         . $extra_field.']';
1488
+                            $css_class = isset($extra_array['css_class'])
1489 1489
                                 ? $extra_array['css_class']
1490 1490
                                 : '';
1491 1491
 
1492
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1492
+                            $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1493 1493
                                                                               && in_array($extra_field, $v_fields, true)
1494 1494
                                                                               && (
1495
-                                                                                  is_array($validators[ $extra_field ])
1496
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1495
+                                                                                  is_array($validators[$extra_field])
1496
+                                                                                  && isset($validators[$extra_field]['msg'])
1497 1497
                                                                               )
1498
-                                ? 'validate-error ' . $css_class
1498
+                                ? 'validate-error '.$css_class
1499 1499
                                 : $css_class;
1500 1500
 
1501
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1502
-                                                                          && isset($content[ $extra_field ])
1503
-                                ? $content[ $extra_field ]
1501
+                            $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1502
+                                                                          && isset($content[$extra_field])
1503
+                                ? $content[$extra_field]
1504 1504
                                 : '';
1505 1505
 
1506 1506
                             // do we have a validation error?  if we do then let's use that value instead
1507
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1508
-                                ? $validators[ $extra_field ]['value']
1509
-                                : $template_form_fields[ $field_id ]['value'];
1507
+                            $template_form_fields[$field_id]['value'] = isset($validators[$extra_field])
1508
+                                ? $validators[$extra_field]['value']
1509
+                                : $template_form_fields[$field_id]['value'];
1510 1510
 
1511 1511
 
1512
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1512
+                            $template_form_fields[$field_id]['db-col'] = 'MTP_content';
1513 1513
 
1514 1514
                             // shortcode selector
1515 1515
                             $field_name_to_use                                   = $extra_field === 'main'
1516 1516
                                 ? 'content'
1517 1517
                                 : $extra_field;
1518
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1518
+                            $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1519 1519
                                 $field_name_to_use,
1520 1520
                                 $field_id
1521 1521
                             );
1522 1522
                         }
1523
-                        $template_field_MTP_id           = $reference_field . '-MTP_ID';
1524
-                        $template_field_template_name_id = $reference_field . '-name';
1523
+                        $template_field_MTP_id           = $reference_field.'-MTP_ID';
1524
+                        $template_field_template_name_id = $reference_field.'-name';
1525 1525
 
1526
-                        $template_form_fields[ $template_field_MTP_id ] = [
1527
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1526
+                        $template_form_fields[$template_field_MTP_id] = [
1527
+                            'name'       => 'MTP_template_fields['.$reference_field.'][MTP_ID]',
1528 1528
                             'label'      => null,
1529 1529
                             'input'      => 'hidden',
1530 1530
                             'type'       => 'int',
@@ -1536,8 +1536,8 @@  discard block
 block discarded – undo
1536 1536
                             'db-col'     => 'MTP_ID',
1537 1537
                         ];
1538 1538
 
1539
-                        $template_form_fields[ $template_field_template_name_id ] = [
1540
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1539
+                        $template_form_fields[$template_field_template_name_id] = [
1540
+                            'name'       => 'MTP_template_fields['.$reference_field.'][name]',
1541 1541
                             'label'      => null,
1542 1542
                             'input'      => 'hidden',
1543 1543
                             'type'       => 'string',
@@ -1551,38 +1551,38 @@  discard block
 block discarded – undo
1551 1551
                     }
1552 1552
                     continue; // skip the next stuff, we got the necessary fields here for this dataset.
1553 1553
                 } else {
1554
-                    $field_id                                   = $template_field . '-content';
1555
-                    $template_form_fields[ $field_id ]          = $field_setup_array;
1556
-                    $template_form_fields[ $field_id ]['name']  =
1557
-                        'MTP_template_fields[' . $template_field . '][content]';
1554
+                    $field_id                                   = $template_field.'-content';
1555
+                    $template_form_fields[$field_id]          = $field_setup_array;
1556
+                    $template_form_fields[$field_id]['name']  =
1557
+                        'MTP_template_fields['.$template_field.'][content]';
1558 1558
                     $message_template                           =
1559
-                        isset($message_templates[ $context ][ $template_field ])
1560
-                            ? $message_templates[ $context ][ $template_field ]
1559
+                        isset($message_templates[$context][$template_field])
1560
+                            ? $message_templates[$context][$template_field]
1561 1561
                             : null;
1562
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1563
-                                                                  && is_array($message_templates[ $context ])
1562
+                    $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1563
+                                                                  && is_array($message_templates[$context])
1564 1564
                                                                   && $message_template instanceof EE_Message_Template
1565 1565
                         ? $message_template->get('MTP_content')
1566 1566
                         : '';
1567 1567
 
1568 1568
                     // do we have a validator error for this field?  if we do then we'll use that value instead
1569
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1570
-                        ? $validators[ $template_field ]['value']
1571
-                        : $template_form_fields[ $field_id ]['value'];
1569
+                    $template_form_fields[$field_id]['value'] = isset($validators[$template_field])
1570
+                        ? $validators[$template_field]['value']
1571
+                        : $template_form_fields[$field_id]['value'];
1572 1572
 
1573 1573
 
1574
-                    $template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1574
+                    $template_form_fields[$field_id]['db-col']    = 'MTP_content';
1575 1575
                     $css_class                                      = isset($field_setup_array['css_class'])
1576 1576
                         ? $field_setup_array['css_class']
1577 1577
                         : '';
1578
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1578
+                    $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1579 1579
                                                                       && in_array($template_field, $v_fields, true)
1580
-                                                                      && isset($validators[ $template_field ]['msg'])
1581
-                        ? 'validate-error ' . $css_class
1580
+                                                                      && isset($validators[$template_field]['msg'])
1581
+                        ? 'validate-error '.$css_class
1582 1582
                         : $css_class;
1583 1583
 
1584 1584
                     // shortcode selector
1585
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1585
+                    $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1586 1586
                         $template_field,
1587 1587
                         $field_id
1588 1588
                     );
@@ -1590,12 +1590,12 @@  discard block
 block discarded – undo
1590 1590
 
1591 1591
                 // k took care of content field(s) now let's take care of others.
1592 1592
 
1593
-                $template_field_MTP_id                 = $template_field . '-MTP_ID';
1594
-                $template_field_field_template_name_id = $template_field . '-name';
1593
+                $template_field_MTP_id                 = $template_field.'-MTP_ID';
1594
+                $template_field_field_template_name_id = $template_field.'-name';
1595 1595
 
1596 1596
                 // foreach template field there are actually two form fields created
1597
-                $template_form_fields[ $template_field_MTP_id ] = [
1598
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1597
+                $template_form_fields[$template_field_MTP_id] = [
1598
+                    'name'       => 'MTP_template_fields['.$template_field.'][MTP_ID]',
1599 1599
                     'label'      => null,
1600 1600
                     'input'      => 'hidden',
1601 1601
                     'type'       => 'int',
@@ -1607,8 +1607,8 @@  discard block
 block discarded – undo
1607 1607
                     'db-col'     => 'MTP_ID',
1608 1608
                 ];
1609 1609
 
1610
-                $template_form_fields[ $template_field_field_template_name_id ] = [
1611
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1610
+                $template_form_fields[$template_field_field_template_name_id] = [
1611
+                    'name'       => 'MTP_template_fields['.$template_field.'][name]',
1612 1612
                     'label'      => null,
1613 1613
                     'input'      => 'hidden',
1614 1614
                     'type'       => 'string',
@@ -1725,7 +1725,7 @@  discard block
 block discarded – undo
1725 1725
                 'format'     => '%d',
1726 1726
                 'db-col'     => 'MTP_deleted',
1727 1727
             ];
1728
-            $sidebar_form_fields['ee-msg-author']  = [
1728
+            $sidebar_form_fields['ee-msg-author'] = [
1729 1729
                 'name'       => 'MTP_user_id',
1730 1730
                 'label'      => esc_html__('Author', 'event_espresso'),
1731 1731
                 'input'      => 'hidden',
@@ -1744,17 +1744,17 @@  discard block
 block discarded – undo
1744 1744
                 'value' => $action,
1745 1745
             ];
1746 1746
 
1747
-            $sidebar_form_fields['ee-msg-id']        = [
1747
+            $sidebar_form_fields['ee-msg-id'] = [
1748 1748
                 'name'  => 'id',
1749 1749
                 'input' => 'hidden',
1750 1750
                 'type'  => 'int',
1751 1751
                 'value' => $GRP_ID,
1752 1752
             ];
1753 1753
             $sidebar_form_fields['ee-msg-evt-nonce'] = [
1754
-                'name'  => $action . '_nonce',
1754
+                'name'  => $action.'_nonce',
1755 1755
                 'input' => 'hidden',
1756 1756
                 'type'  => 'string',
1757
-                'value' => wp_create_nonce($action . '_nonce'),
1757
+                'value' => wp_create_nonce($action.'_nonce'),
1758 1758
             ];
1759 1759
 
1760 1760
             $template_switch = $this->request->getRequestParam('template_switch');
@@ -1785,7 +1785,7 @@  discard block
 block discarded – undo
1785 1785
         );
1786 1786
 
1787 1787
         // add preview button
1788
-        $preview_url    = parent::add_query_args_and_nonce(
1788
+        $preview_url = parent::add_query_args_and_nonce(
1789 1789
             [
1790 1790
                 'message_type' => $message_template_group->message_type(),
1791 1791
                 'messenger'    => $message_template_group->messenger(),
@@ -1796,7 +1796,7 @@  discard block
 block discarded – undo
1796 1796
             ],
1797 1797
             $this->_admin_base_url
1798 1798
         );
1799
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1799
+        $preview_button = '<a href="'.$preview_url.'" class="button-secondary messages-preview-button">'
1800 1800
                           . esc_html__('Preview', 'event_espresso')
1801 1801
                           . '</a>';
1802 1802
 
@@ -1830,11 +1830,11 @@  discard block
 block discarded – undo
1830 1830
             $context_label
1831 1831
         );
1832 1832
         $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1833
-        $this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1833
+        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1834 1834
 
1835 1835
         $this->_template_path = $this->_template_args['GRP_ID']
1836 1836
             ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1837
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1837
+            : EE_MSG_TEMPLATE_PATH.'ee_msg_details_main_add_meta_box.template.php';
1838 1838
 
1839 1839
         // send along EE_Message_Template_Group object for further template use.
1840 1840
         $this->_template_args['MTP'] = $message_template_group;
@@ -1890,7 +1890,7 @@  discard block
 block discarded – undo
1890 1890
     ) {
1891 1891
         $template_args = [
1892 1892
             'context'                   => $context,
1893
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1893
+            'nonce'                     => wp_create_nonce('activate_'.$context.'_toggle_nonce'),
1894 1894
             'is_active'                 => $message_template_group->is_context_active($context),
1895 1895
             'on_off_action'             => $message_template_group->is_context_active($context)
1896 1896
                 ? 'context-off'
@@ -1899,7 +1899,7 @@  discard block
 block discarded – undo
1899 1899
             'message_template_group_id' => $message_template_group->ID(),
1900 1900
         ];
1901 1901
         return EEH_Template::display_template(
1902
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1902
+            EE_MSG_TEMPLATE_PATH.'ee_msg_editor_active_context_element.template.php',
1903 1903
             $template_args,
1904 1904
             true
1905 1905
         );
@@ -1956,7 +1956,7 @@  discard block
 block discarded – undo
1956 1956
         }
1957 1957
         $message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, 'int');
1958 1958
         $message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1959
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1959
+        if ( ! $message_template_group instanceof EE_Message_Template_Group) {
1960 1960
             EE_Error::add_error(
1961 1961
                 sprintf(
1962 1962
                     esc_html__(
@@ -2087,7 +2087,7 @@  discard block
 block discarded – undo
2087 2087
         $messenger    = $this->request->getRequestParam('msgr');
2088 2088
         $message_type = $this->request->getRequestParam('mt');
2089 2089
         // we need to make sure we've got the info we need.
2090
-        if (! ($GRP_ID && $messenger && $message_type)) {
2090
+        if ( ! ($GRP_ID && $messenger && $message_type)) {
2091 2091
             EE_Error::add_error(
2092 2092
                 esc_html__(
2093 2093
                     '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.',
@@ -2124,7 +2124,7 @@  discard block
 block discarded – undo
2124 2124
         }
2125 2125
 
2126 2126
         // any error messages?
2127
-        if (! $success) {
2127
+        if ( ! $success) {
2128 2128
             EE_Error::add_error(
2129 2129
                 esc_html__(
2130 2130
                     'Something went wrong with deleting existing templates. Unable to reset to default',
@@ -2173,7 +2173,7 @@  discard block
 block discarded – undo
2173 2173
     {
2174 2174
         // first make sure we've got the necessary parameters
2175 2175
         $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2176
-        if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
2176
+        if ( ! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
2177 2177
             EE_Error::add_error(
2178 2178
                 esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2179 2179
                 __FILE__,
@@ -2199,7 +2199,7 @@  discard block
 block discarded – undo
2199 2199
         $EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
2200 2200
 
2201 2201
         // let's add a button to go back to the edit view
2202
-        $query_args             = [
2202
+        $query_args = [
2203 2203
             'id'      => $GRP_ID,
2204 2204
             'evt_id'  => $EVT_ID,
2205 2205
             'context' => $context,
@@ -2220,7 +2220,7 @@  discard block
 block discarded – undo
2220 2220
         $preview_title = sprintf(
2221 2221
             esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2222 2222
             $active_messenger_label,
2223
-            ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2223
+            ucwords($message_types[$this->_active_message_type_name]->label['singular'])
2224 2224
         );
2225 2225
         if (empty($preview)) {
2226 2226
             $this->noEventsErrorMessage();
@@ -2228,7 +2228,7 @@  discard block
 block discarded – undo
2228 2228
         // setup display of preview.
2229 2229
         $this->_admin_page_title                    = $preview_title;
2230 2230
         $this->_template_args['admin_page_title']   = $preview_title;
2231
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2231
+        $this->_template_args['admin_page_content'] = $preview_button.'<br />'.$preview;
2232 2232
         $this->_template_args['data']['force_json'] = true;
2233 2233
 
2234 2234
         return '';
@@ -2249,7 +2249,7 @@  discard block
 block discarded – undo
2249 2249
             ],
2250 2250
             admin_url('admin.php')
2251 2251
         );
2252
-        $message    = $test_send
2252
+        $message = $test_send
2253 2253
             ? esc_html__(
2254 2254
                 '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!',
2255 2255
                 'event_espresso'
@@ -2342,10 +2342,10 @@  discard block
 block discarded – undo
2342 2342
             // only include template packs that support this messenger and message type!
2343 2343
             $supports = $tp->get_supports();
2344 2344
             if (
2345
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2345
+                ! isset($supports[$this->_message_template_group->messenger()])
2346 2346
                 || ! in_array(
2347 2347
                     $this->_message_template_group->message_type(),
2348
-                    $supports[ $this->_message_template_group->messenger() ],
2348
+                    $supports[$this->_message_template_group->messenger()],
2349 2349
                     true
2350 2350
                 )
2351 2351
             ) {
@@ -2369,7 +2369,7 @@  discard block
 block discarded – undo
2369 2369
         }
2370 2370
 
2371 2371
         // setup variation select values for the currently selected template.
2372
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
2372
+        $variations = $this->_message_template_group->get_template_pack()->get_variations(
2373 2373
             $this->_message_template_group->messenger(),
2374 2374
             $this->_message_template_group->message_type()
2375 2375
         );
@@ -2383,12 +2383,12 @@  discard block
 block discarded – undo
2383 2383
 
2384 2384
         $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2385 2385
 
2386
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2386
+        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2387 2387
             'MTP_template_pack',
2388 2388
             $tp_select_values,
2389 2389
             $this->_message_template_group->get_template_pack_name()
2390 2390
         );
2391
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
2391
+        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
2392 2392
             'MTP_template_variation',
2393 2393
             $variations_select_values,
2394 2394
             $this->_message_template_group->get_template_pack_variation()
@@ -2398,7 +2398,7 @@  discard block
 block discarded – undo
2398 2398
         $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2399 2399
         $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2400 2400
 
2401
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2401
+        $template = EE_MSG_TEMPLATE_PATH.'template_pack_and_variations_metabox.template.php';
2402 2402
 
2403 2403
         EEH_Template::display_template($template, $template_args);
2404 2404
     }
@@ -2424,33 +2424,33 @@  discard block
 block discarded – undo
2424 2424
         // first we need to see if there are any fields
2425 2425
         $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2426 2426
 
2427
-        if (! empty($fields)) {
2427
+        if ( ! empty($fields)) {
2428 2428
             // yup there be fields
2429 2429
             foreach ($fields as $field => $config) {
2430
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2430
+                $field_id = $this->_message_template_group->messenger().'_'.$field;
2431 2431
                 $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2432 2432
                 $default  = isset($config['default']) ? $config['default'] : '';
2433 2433
                 $default  = isset($config['value']) ? $config['value'] : $default;
2434 2434
 
2435 2435
                 // if type is hidden and the value is empty
2436 2436
                 // something may have gone wrong so let's correct with the defaults
2437
-                $fix                = $config['input'] === 'hidden'
2438
-                                      && isset($existing[ $field ])
2439
-                                      && empty($existing[ $field ])
2437
+                $fix = $config['input'] === 'hidden'
2438
+                                      && isset($existing[$field])
2439
+                                      && empty($existing[$field])
2440 2440
                     ? $default
2441 2441
                     : '';
2442
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2443
-                    ? $existing[ $field ]
2442
+                $existing[$field] = isset($existing[$field]) && empty($fix)
2443
+                    ? $existing[$field]
2444 2444
                     : $fix;
2445 2445
 
2446
-                $template_form_fields[ $field_id ] = [
2447
-                    'name'       => 'test_settings_fld[' . $field . ']',
2446
+                $template_form_fields[$field_id] = [
2447
+                    'name'       => 'test_settings_fld['.$field.']',
2448 2448
                     'label'      => $config['label'],
2449 2449
                     'input'      => $config['input'],
2450 2450
                     'type'       => $config['type'],
2451 2451
                     'required'   => $config['required'],
2452 2452
                     'validation' => $config['validation'],
2453
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2453
+                    'value'      => isset($existing[$field]) ? $existing[$field] : $default,
2454 2454
                     'css_class'  => $config['css_class'],
2455 2455
                     'options'    => isset($config['options']) ? $config['options'] : [],
2456 2456
                     'default'    => $default,
@@ -2464,7 +2464,7 @@  discard block
 block discarded – undo
2464 2464
             : '';
2465 2465
 
2466 2466
         // print out $test_settings_fields
2467
-        if (! empty($test_settings_html)) {
2467
+        if ( ! empty($test_settings_html)) {
2468 2468
             $test_settings_html .= '<input type="submit" class="button-primary mtp-test-button alignright" ';
2469 2469
             $test_settings_html .= 'name="test_button" value="';
2470 2470
             $test_settings_html .= esc_html__('Test Send', 'event_espresso');
@@ -2510,7 +2510,7 @@  discard block
 block discarded – undo
2510 2510
         ];
2511 2511
 
2512 2512
         return EEH_Template::display_template(
2513
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2513
+            EE_MSG_TEMPLATE_PATH.'shortcode_selector_skeleton.template.php',
2514 2514
             $template_args,
2515 2515
             true
2516 2516
         );
@@ -2536,7 +2536,7 @@  discard block
 block discarded – undo
2536 2536
         // $messenger = $this->_message_template_group->messenger_obj();
2537 2537
         // now let's set the content depending on the status of the shortcodes array
2538 2538
         if (empty($shortcodes)) {
2539
-            echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2539
+            echo '<p>'.esc_html__('There are no valid shortcodes available', 'event_espresso').'</p>';
2540 2540
             return;
2541 2541
         }
2542 2542
         ?>
@@ -2572,7 +2572,7 @@  discard block
 block discarded – undo
2572 2572
     {
2573 2573
 
2574 2574
         // no need to run this if the property is already set
2575
-        if (! empty($this->_shortcodes)) {
2575
+        if ( ! empty($this->_shortcodes)) {
2576 2576
             return;
2577 2577
         }
2578 2578
 
@@ -2627,7 +2627,7 @@  discard block
 block discarded – undo
2627 2627
     protected function _set_message_template_group()
2628 2628
     {
2629 2629
         // get out if this is already set.
2630
-        if (! empty($this->_message_template_group)) {
2630
+        if ( ! empty($this->_message_template_group)) {
2631 2631
             return;
2632 2632
         }
2633 2633
 
@@ -2673,8 +2673,8 @@  discard block
 block discarded – undo
2673 2673
                     <?php
2674 2674
                 }
2675 2675
                 // setup nonce_url
2676
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2677
-                $id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2676
+                wp_nonce_field($args['action'].'_nonce', $args['action'].'_nonce', false);
2677
+                $id = 'ee-'.sanitize_key($context_label['label']).'-select';
2678 2678
                 ?>
2679 2679
                 <label for='<?php echo esc_attr($id); ?>' class='screen-reader-text'>
2680 2680
                     <?php esc_html_e('message context options', 'event_espresso'); ?>
@@ -2687,7 +2687,7 @@  discard block
 block discarded – undo
2687 2687
                             $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2688 2688
                             ?>
2689 2689
                             <option value="<?php echo esc_attr($context); ?>" <?php echo esc_attr($checked); ?>>
2690
-                                <?php echo $context_details[ $context ]['label']; // already escaped
2690
+                                <?php echo $context_details[$context]['label']; // already escaped
2691 2691
                                 ?>
2692 2692
                             </option>
2693 2693
                         <?php endforeach;
@@ -3081,7 +3081,7 @@  discard block
 block discarded – undo
3081 3081
     {
3082 3082
         if (is_array($content)) {
3083 3083
             foreach ($content as $key => $value) {
3084
-                $content[ $key ] = $this->sanitizeMessageTemplateContent($value);
3084
+                $content[$key] = $this->sanitizeMessageTemplateContent($value);
3085 3085
             }
3086 3086
             return $content;
3087 3087
         }
@@ -3119,7 +3119,7 @@  discard block
 block discarded – undo
3119 3119
 
3120 3120
         $context   = ucwords(str_replace('_', ' ', $context));
3121 3121
         $item_desc = $messenger_label && $message_type_label
3122
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
3122
+            ? $messenger_label.' '.$message_type_label.' '.$context.' '
3123 3123
             : '';
3124 3124
         $item_desc .= 'Message Template';
3125 3125
         return $item_desc;
@@ -3271,7 +3271,7 @@  discard block
 block discarded – undo
3271 3271
         if ($all) {
3272 3272
             // Checkboxes
3273 3273
             $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3274
-            if (! empty($checkboxes)) {
3274
+            if ( ! empty($checkboxes)) {
3275 3275
                 // if array has more than one element then success message should be plural.
3276 3276
                 // todo: what about nonce?
3277 3277
                 $success = count($checkboxes) > 1 ? 2 : 1;
@@ -3281,18 +3281,18 @@  discard block
 block discarded – undo
3281 3281
                     $trashed_or_restored = $trash
3282 3282
                         ? $this->getMtgModel()->delete_by_ID($GRP_ID)
3283 3283
                         : $this->getMtgModel()->restore_by_ID($GRP_ID);
3284
-                    if (! $trashed_or_restored) {
3284
+                    if ( ! $trashed_or_restored) {
3285 3285
                         $success = 0;
3286 3286
                     }
3287 3287
                 }
3288 3288
             } else {
3289 3289
                 // grab single GRP_ID and handle
3290 3290
                 $GRP_ID = $this->request->getRequestParam('id', 0, 'int');
3291
-                if (! empty($GRP_ID)) {
3291
+                if ( ! empty($GRP_ID)) {
3292 3292
                     $trashed_or_restored = $trash
3293 3293
                         ? $this->getMtgModel()->delete_by_ID($GRP_ID)
3294 3294
                         : $this->getMtgModel()->restore_by_ID($GRP_ID);
3295
-                    if (! $trashed_or_restored) {
3295
+                    if ( ! $trashed_or_restored) {
3296 3296
                         $success = 0;
3297 3297
                     }
3298 3298
                 } else {
@@ -3340,7 +3340,7 @@  discard block
 block discarded – undo
3340 3340
 
3341 3341
         // checkboxes
3342 3342
         $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3343
-        if (! empty($checkboxes)) {
3343
+        if ( ! empty($checkboxes)) {
3344 3344
             // if array has more than one element then success message should be plural
3345 3345
             $success = count($checkboxes) > 1 ? 2 : 1;
3346 3346
 
@@ -3444,7 +3444,7 @@  discard block
 block discarded – undo
3444 3444
     protected function _set_m_mt_settings()
3445 3445
     {
3446 3446
         // first if this is already set then lets get out no need to regenerate data.
3447
-        if (! empty($this->_m_mt_settings)) {
3447
+        if ( ! empty($this->_m_mt_settings)) {
3448 3448
             return;
3449 3449
         }
3450 3450
 
@@ -3456,7 +3456,7 @@  discard block
 block discarded – undo
3456 3456
         // assemble the array for the _tab_text_links helper
3457 3457
 
3458 3458
         foreach ($messengers as $messenger) {
3459
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3459
+            $this->_m_mt_settings['messenger_tabs'][$messenger->name] = [
3460 3460
                 'label' => ucwords($messenger->label['singular']),
3461 3461
                 'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3462 3462
                     ? 'messenger-active'
@@ -3473,7 +3473,7 @@  discard block
 block discarded – undo
3473 3473
             foreach ($message_types as $message_type) {
3474 3474
                 // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3475 3475
                 // it shouldn't show in either the inactive OR active metabox.
3476
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3476
+                if ( ! in_array($message_type->name, $message_types_for_messenger, true)) {
3477 3477
                     continue;
3478 3478
                 }
3479 3479
 
@@ -3484,12 +3484,12 @@  discard block
 block discarded – undo
3484 3484
                     ? 'active'
3485 3485
                     : 'inactive';
3486 3486
 
3487
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3487
+                $this->_m_mt_settings['message_type_tabs'][$messenger->name][$a_or_i][$message_type->name] = [
3488 3488
                     'label'    => ucwords($message_type->label['singular']),
3489
-                    'class'    => 'message-type-' . $a_or_i,
3490
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3491
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3492
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3489
+                    'class'    => 'message-type-'.$a_or_i,
3490
+                    'slug_id'  => $message_type->name.'-messagetype-'.$messenger->name,
3491
+                    'mt_nonce' => wp_create_nonce($message_type->name.'_nonce'),
3492
+                    'href'     => 'espresso_'.$message_type->name.'_message_type_settings',
3493 3493
                     'title'    => $a_or_i === 'active'
3494 3494
                         ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3495 3495
                         : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
@@ -3520,25 +3520,25 @@  discard block
 block discarded – undo
3520 3520
         $fields                                         = $message_type->get_admin_settings_fields();
3521 3521
         $settings_template_args['template_form_fields'] = '';
3522 3522
 
3523
-        if (! empty($fields) && $active) {
3523
+        if ( ! empty($fields) && $active) {
3524 3524
             $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3525 3525
             foreach ($fields as $fldname => $fldprops) {
3526
-                $field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3527
-                $template_form_field[ $field_id ] = [
3528
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3526
+                $field_id                         = $messenger->name.'-'.$message_type->name.'-'.$fldname;
3527
+                $template_form_field[$field_id] = [
3528
+                    'name'       => 'message_type_settings['.$fldname.']',
3529 3529
                     'label'      => $fldprops['label'],
3530 3530
                     'input'      => $fldprops['field_type'],
3531 3531
                     'type'       => $fldprops['value_type'],
3532 3532
                     'required'   => $fldprops['required'],
3533 3533
                     'validation' => $fldprops['validation'],
3534
-                    'value'      => isset($existing_settings[ $fldname ])
3535
-                        ? $existing_settings[ $fldname ]
3534
+                    'value'      => isset($existing_settings[$fldname])
3535
+                        ? $existing_settings[$fldname]
3536 3536
                         : $fldprops['default'],
3537 3537
                     'options'    => isset($fldprops['options'])
3538 3538
                         ? $fldprops['options']
3539 3539
                         : [],
3540
-                    'default'    => isset($existing_settings[ $fldname ])
3541
-                        ? $existing_settings[ $fldname ]
3540
+                    'default'    => isset($existing_settings[$fldname])
3541
+                        ? $existing_settings[$fldname]
3542 3542
                         : $fldprops['default'],
3543 3543
                     'css_class'  => 'no-drag',
3544 3544
                     'format'     => $fldprops['format'],
@@ -3558,15 +3558,15 @@  discard block
 block discarded – undo
3558 3558
         $settings_template_args['description'] = $message_type->description;
3559 3559
         // we also need some hidden fields
3560 3560
         $hidden_fields = [
3561
-            'message_type_settings[messenger]' . $message_type->name    => [
3561
+            'message_type_settings[messenger]'.$message_type->name    => [
3562 3562
                 'type'  => 'hidden',
3563 3563
                 'value' => $messenger->name,
3564 3564
             ],
3565
-            'message_type_settings[message_type]' . $message_type->name => [
3565
+            'message_type_settings[message_type]'.$message_type->name => [
3566 3566
                 'type'  => 'hidden',
3567 3567
                 'value' => $message_type->name,
3568 3568
             ],
3569
-            'type' . $message_type->name                                => [
3569
+            'type'.$message_type->name                                => [
3570 3570
                 'type'  => 'hidden',
3571 3571
                 'value' => 'message_type',
3572 3572
             ],
@@ -3576,12 +3576,12 @@  discard block
 block discarded – undo
3576 3576
             $hidden_fields,
3577 3577
             'array'
3578 3578
         );
3579
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3579
+        $settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3580 3580
             ? ' hidden'
3581 3581
             : '';
3582 3582
 
3583 3583
 
3584
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3584
+        $template = EE_MSG_TEMPLATE_PATH.'ee_msg_mt_settings_content.template.php';
3585 3585
         return EEH_Template::display_template($template, $settings_template_args, true);
3586 3586
     }
3587 3587
 
@@ -3609,21 +3609,21 @@  discard block
 block discarded – undo
3609 3609
 
3610 3610
                 // messenger meta boxes
3611 3611
                 $active         = $selected_messenger === $messenger;
3612
-                $active_mt_tabs = isset($this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'])
3613
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3612
+                $active_mt_tabs = isset($this->_m_mt_settings['message_type_tabs'][$messenger]['active'])
3613
+                    ? $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
3614 3614
                     : '';
3615 3615
 
3616
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3616
+                $m_boxes[$messenger.'_a_box'] = sprintf(
3617 3617
                     esc_html__('%s Settings', 'event_espresso'),
3618 3618
                     $tab_array['label']
3619 3619
                 );
3620 3620
 
3621
-                $m_template_args[ $messenger . '_a_box' ] = [
3621
+                $m_template_args[$messenger.'_a_box'] = [
3622 3622
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3623 3623
                     'inactive_message_types' => isset(
3624
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3624
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3625 3625
                     )
3626
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3626
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3627 3627
                         : '',
3628 3628
                     'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3629 3629
                     'hidden'                 => $active ? '' : ' hidden',
@@ -3635,13 +3635,13 @@  discard block
 block discarded – undo
3635 3635
                 // message type meta boxes
3636 3636
                 // (which is really just the inactive container for each messenger
3637 3637
                 // showing inactive message types for that messenger)
3638
-                $mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3639
-                $mt_template_args[ $messenger . '_i_box' ] = [
3638
+                $mt_boxes[$messenger.'_i_box']         = esc_html__('Inactive Message Types', 'event_espresso');
3639
+                $mt_template_args[$messenger.'_i_box'] = [
3640 3640
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3641 3641
                     'inactive_message_types' => isset(
3642
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3642
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3643 3643
                     )
3644
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3644
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3645 3645
                         : '',
3646 3646
                     'hidden'                 => $active ? '' : ' hidden',
3647 3647
                     'hide_on_message'        => $hide_on_message,
@@ -3654,14 +3654,14 @@  discard block
 block discarded – undo
3654 3654
 
3655 3655
 
3656 3656
         // register messenger metaboxes
3657
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3657
+        $m_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_mt_meta_box.template.php';
3658 3658
         foreach ($m_boxes as $box => $label) {
3659
-            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3659
+            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[$box]];
3660 3660
             $msgr          = str_replace('_a_box', '', $box);
3661 3661
             add_meta_box(
3662
-                'espresso_' . $msgr . '_settings',
3662
+                'espresso_'.$msgr.'_settings',
3663 3663
                 $label,
3664
-                function ($post, $metabox) {
3664
+                function($post, $metabox) {
3665 3665
                     EEH_Template::display_template(
3666 3666
                         $metabox['args']['template_path'],
3667 3667
                         $metabox['args']['template_args']
@@ -3675,17 +3675,17 @@  discard block
 block discarded – undo
3675 3675
         }
3676 3676
 
3677 3677
         // register message type metaboxes
3678
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3678
+        $mt_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_meta_box.template.php';
3679 3679
         foreach ($mt_boxes as $box => $label) {
3680 3680
             $callback_args = [
3681 3681
                 'template_path' => $mt_template_path,
3682
-                'template_args' => $mt_template_args[ $box ],
3682
+                'template_args' => $mt_template_args[$box],
3683 3683
             ];
3684
-            $mt            = str_replace('_i_box', '', $box);
3684
+            $mt = str_replace('_i_box', '', $box);
3685 3685
             add_meta_box(
3686
-                'espresso_' . $mt . '_inactive_mts',
3686
+                'espresso_'.$mt.'_inactive_mts',
3687 3687
                 $label,
3688
-                function ($post, $metabox) {
3688
+                function($post, $metabox) {
3689 3689
                     EEH_Template::display_template(
3690 3690
                         $metabox['args']['template_path'],
3691 3691
                         $metabox['args']['template_args']
@@ -3830,7 +3830,7 @@  discard block
 block discarded – undo
3830 3830
             if ($form->is_valid()) {
3831 3831
                 $valid_data = $form->valid_data();
3832 3832
                 foreach ($valid_data as $property => $value) {
3833
-                    $setter = 'set_' . $property;
3833
+                    $setter = 'set_'.$property;
3834 3834
                     if (method_exists($network_config, $setter)) {
3835 3835
                         $network_config->{$setter}($value);
3836 3836
                     } elseif (
@@ -3866,7 +3866,7 @@  discard block
 block discarded – undo
3866 3866
     protected function _get_mt_tabs($tab_array)
3867 3867
     {
3868 3868
         $tab_array = (array) $tab_array;
3869
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3869
+        $template  = EE_MSG_TEMPLATE_PATH.'ee_msg_details_mt_settings_tab_item.template.php';
3870 3870
         $tabs      = '';
3871 3871
 
3872 3872
         foreach ($tab_array as $tab) {
@@ -3894,20 +3894,20 @@  discard block
 block discarded – undo
3894 3894
         $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3895 3895
 
3896 3896
 
3897
-        if (! empty($fields)) {
3897
+        if ( ! empty($fields)) {
3898 3898
             $existing_settings = $messenger->get_existing_admin_settings();
3899 3899
 
3900 3900
             foreach ($fields as $fldname => $fldprops) {
3901
-                $field_id                         = $messenger->name . '-' . $fldname;
3902
-                $template_form_field[ $field_id ] = [
3903
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3901
+                $field_id                         = $messenger->name.'-'.$fldname;
3902
+                $template_form_field[$field_id] = [
3903
+                    'name'       => 'messenger_settings['.$field_id.']',
3904 3904
                     'label'      => $fldprops['label'],
3905 3905
                     'input'      => $fldprops['field_type'],
3906 3906
                     'type'       => $fldprops['value_type'],
3907 3907
                     'required'   => $fldprops['required'],
3908 3908
                     'validation' => $fldprops['validation'],
3909
-                    'value'      => isset($existing_settings[ $field_id ])
3910
-                        ? $existing_settings[ $field_id ]
3909
+                    'value'      => isset($existing_settings[$field_id])
3910
+                        ? $existing_settings[$field_id]
3911 3911
                         : $fldprops['default'],
3912 3912
                     'css_class'  => '',
3913 3913
                     'format'     => $fldprops['format'],
@@ -3922,20 +3922,20 @@  discard block
 block discarded – undo
3922 3922
 
3923 3923
         // we also need some hidden fields
3924 3924
         $settings_template_args['hidden_fields'] = [
3925
-            'messenger_settings[messenger]' . $messenger->name => [
3925
+            'messenger_settings[messenger]'.$messenger->name => [
3926 3926
                 'type'  => 'hidden',
3927 3927
                 'value' => $messenger->name,
3928 3928
             ],
3929
-            'type' . $messenger->name                          => [
3929
+            'type'.$messenger->name                          => [
3930 3930
                 'type'  => 'hidden',
3931 3931
                 'value' => 'messenger',
3932 3932
             ],
3933 3933
         ];
3934 3934
 
3935 3935
         // make sure any active message types that are existing are included in the hidden fields
3936
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3937
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3938
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3936
+        if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3937
+            foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3938
+                $settings_template_args['hidden_fields']['messenger_settings[message_types]['.$mt.']'] = [
3939 3939
                     'type'  => 'hidden',
3940 3940
                     'value' => $mt,
3941 3941
                 ];
@@ -3945,7 +3945,7 @@  discard block
 block discarded – undo
3945 3945
             $settings_template_args['hidden_fields'],
3946 3946
             'array'
3947 3947
         );
3948
-        $active                                  =
3948
+        $active =
3949 3949
             $this->_message_resource_manager->is_messenger_active($messenger->name);
3950 3950
 
3951 3951
         $settings_template_args['messenger']           = $messenger->name;
@@ -3965,9 +3965,9 @@  discard block
 block discarded – undo
3965 3965
 
3966 3966
 
3967 3967
         $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3968
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3968
+        $settings_template_args['nonce']         = wp_create_nonce('activate_'.$messenger->name.'_toggle_nonce');
3969 3969
         $settings_template_args['on_off_status'] = $active;
3970
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3970
+        $template                                = EE_MSG_TEMPLATE_PATH.'ee_msg_m_settings_content.template.php';
3971 3971
         return EEH_Template::display_template(
3972 3972
             $template,
3973 3973
             $settings_template_args,
@@ -3992,7 +3992,7 @@  discard block
 block discarded – undo
3992 3992
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
3993 3993
         // let's check that we have required data
3994 3994
 
3995
-        if (! $this->_active_messenger_name) {
3995
+        if ( ! $this->_active_messenger_name) {
3996 3996
             EE_Error::add_error(
3997 3997
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3998 3998
                 __FILE__,
@@ -4010,7 +4010,7 @@  discard block
 block discarded – undo
4010 4010
 
4011 4011
 
4012 4012
         $status = $this->request->getRequestParam('status');
4013
-        if (! $status) {
4013
+        if ( ! $status) {
4014 4014
             EE_Error::add_error(
4015 4015
                 esc_html__(
4016 4016
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -4067,7 +4067,7 @@  discard block
 block discarded – undo
4067 4067
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
4068 4068
 
4069 4069
         // let's make sure we have the necessary data
4070
-        if (! $this->_active_message_type_name) {
4070
+        if ( ! $this->_active_message_type_name) {
4071 4071
             EE_Error::add_error(
4072 4072
                 esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
4073 4073
                 __FILE__,
@@ -4077,7 +4077,7 @@  discard block
 block discarded – undo
4077 4077
             $success = false;
4078 4078
         }
4079 4079
 
4080
-        if (! $this->_active_messenger_name) {
4080
+        if ( ! $this->_active_messenger_name) {
4081 4081
             EE_Error::add_error(
4082 4082
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
4083 4083
                 __FILE__,
@@ -4088,7 +4088,7 @@  discard block
 block discarded – undo
4088 4088
         }
4089 4089
 
4090 4090
         $status = $this->request->getRequestParam('status');
4091
-        if (! $status) {
4091
+        if ( ! $status) {
4092 4092
             EE_Error::add_error(
4093 4093
                 esc_html__(
4094 4094
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -4300,7 +4300,7 @@  discard block
 block discarded – undo
4300 4300
         EE_Message_Type $message_type = null
4301 4301
     ) {
4302 4302
         // if $messenger isn't a valid messenger object then get out.
4303
-        if (! $messenger instanceof EE_Messenger) {
4303
+        if ( ! $messenger instanceof EE_Messenger) {
4304 4304
             EE_Error::add_error(
4305 4305
                 esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4306 4306
                 __FILE__,
@@ -4354,7 +4354,7 @@  discard block
 block discarded – undo
4354 4354
             // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4355 4355
             // in which case we just give a success message for the messenger being successfully activated.
4356 4356
         } else {
4357
-            if (! $messenger->get_default_message_types()) {
4357
+            if ( ! $messenger->get_default_message_types()) {
4358 4358
                 // messenger doesn't have any default message types so still a success.
4359 4359
                 EE_Error::add_success(
4360 4360
                     sprintf(
@@ -4410,7 +4410,7 @@  discard block
 block discarded – undo
4410 4410
         EE_Error::overwrite_success();
4411 4411
 
4412 4412
         // if $messenger isn't a valid messenger object then get out.
4413
-        if (! $messenger instanceof EE_Messenger) {
4413
+        if ( ! $messenger instanceof EE_Messenger) {
4414 4414
             EE_Error::add_error(
4415 4415
                 esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4416 4416
                 __FILE__,
@@ -4474,7 +4474,7 @@  discard block
 block discarded – undo
4474 4474
      */
4475 4475
     public function update_mt_form()
4476 4476
     {
4477
-        if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
4477
+        if ( ! $this->_active_messenger_name || ! $this->_active_message_type_name) {
4478 4478
             EE_Error::add_error(
4479 4479
                 esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4480 4480
                 __FILE__,
@@ -4485,7 +4485,7 @@  discard block
 block discarded – undo
4485 4485
         }
4486 4486
 
4487 4487
         $message_types = $this->get_installed_message_types();
4488
-        $message_type  = $message_types[ $this->_active_message_type_name ];
4488
+        $message_type  = $message_types[$this->_active_message_type_name];
4489 4489
         $messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
4490 4490
         $content       = $this->_message_type_settings_content($message_type, $messenger, true);
4491 4491
 
@@ -4504,7 +4504,7 @@  discard block
 block discarded – undo
4504 4504
     public function save_settings()
4505 4505
     {
4506 4506
         $type = $this->request->getRequestParam('type');
4507
-        if (! $type) {
4507
+        if ( ! $type) {
4508 4508
             EE_Error::add_error(
4509 4509
                 esc_html__(
4510 4510
                     'Cannot save settings because type is unknown (messenger settings or message type settings?)',
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 1 patch
Indentation   +2809 added lines, -2809 removed lines patch added patch discarded remove patch
@@ -16,2816 +16,2816 @@
 block discarded – undo
16 16
 class Events_Admin_Page extends EE_Admin_Page_CPT
17 17
 {
18 18
 
19
-    /**
20
-     * This will hold the event object for event_details screen.
19
+	/**
20
+	 * This will hold the event object for event_details screen.
21
+	 *
22
+	 * @var EE_Event $_event
23
+	 */
24
+	protected $_event;
25
+
26
+
27
+	/**
28
+	 * This will hold the category object for category_details screen.
29
+	 *
30
+	 * @var stdClass $_category
31
+	 */
32
+	protected $_category;
33
+
34
+
35
+	/**
36
+	 * This will hold the event model instance
37
+	 *
38
+	 * @var EEM_Event $_event_model
39
+	 */
40
+	protected $_event_model;
41
+
42
+
43
+	/**
44
+	 * @var EE_Event
45
+	 */
46
+	protected $_cpt_model_obj = false;
47
+
48
+
49
+	/**
50
+	 * @var NodeGroupDao
51
+	 */
52
+	protected $model_obj_node_group_persister;
53
+
54
+
55
+	/**
56
+	 * Initialize page props for this admin page group.
57
+	 */
58
+	protected function _init_page_props()
59
+	{
60
+		$this->page_slug        = EVENTS_PG_SLUG;
61
+		$this->page_label       = EVENTS_LABEL;
62
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
63
+		$this->_admin_base_path = EVENTS_ADMIN;
64
+		$this->_cpt_model_names = [
65
+			'create_new' => 'EEM_Event',
66
+			'edit'       => 'EEM_Event',
67
+		];
68
+		$this->_cpt_edit_routes = [
69
+			'espresso_events' => 'edit',
70
+		];
71
+		add_action(
72
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
+			[$this, 'verify_event_edit'],
74
+			10,
75
+			2
76
+		);
77
+	}
78
+
79
+
80
+	/**
81
+	 * Sets the ajax hooks used for this admin page group.
82
+	 */
83
+	protected function _ajax_hooks()
84
+	{
85
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
+	}
87
+
88
+
89
+	/**
90
+	 * Sets the page properties for this admin page group.
91
+	 */
92
+	protected function _define_page_props()
93
+	{
94
+		$this->_admin_page_title = EVENTS_LABEL;
95
+		$this->_labels           = [
96
+			'buttons'      => [
97
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
98
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
+			],
104
+			'editor_title' => [
105
+				'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
106
+			],
107
+			'publishbox'   => [
108
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
110
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
+			],
114
+		];
115
+	}
116
+
117
+
118
+	/**
119
+	 * Sets the page routes property for this admin page group.
120
+	 */
121
+	protected function _set_page_routes()
122
+	{
123
+		// load formatter helper
124
+		// load field generator helper
125
+		// is there a evt_id in the request?
126
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
127
+		$EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
128
+
129
+		$this->_page_routes = [
130
+			'default'                       => [
131
+				'func'       => '_events_overview_list_table',
132
+				'capability' => 'ee_read_events',
133
+			],
134
+			'create_new'                    => [
135
+				'func'       => '_create_new_cpt_item',
136
+				'capability' => 'ee_edit_events',
137
+			],
138
+			'edit'                          => [
139
+				'func'       => '_edit_cpt_item',
140
+				'capability' => 'ee_edit_event',
141
+				'obj_id'     => $EVT_ID,
142
+			],
143
+			'copy_event'                    => [
144
+				'func'       => '_copy_events',
145
+				'capability' => 'ee_edit_event',
146
+				'obj_id'     => $EVT_ID,
147
+				'noheader'   => true,
148
+			],
149
+			'trash_event'                   => [
150
+				'func'       => '_trash_or_restore_event',
151
+				'args'       => ['event_status' => 'trash'],
152
+				'capability' => 'ee_delete_event',
153
+				'obj_id'     => $EVT_ID,
154
+				'noheader'   => true,
155
+			],
156
+			'trash_events'                  => [
157
+				'func'       => '_trash_or_restore_events',
158
+				'args'       => ['event_status' => 'trash'],
159
+				'capability' => 'ee_delete_events',
160
+				'noheader'   => true,
161
+			],
162
+			'restore_event'                 => [
163
+				'func'       => '_trash_or_restore_event',
164
+				'args'       => ['event_status' => 'draft'],
165
+				'capability' => 'ee_delete_event',
166
+				'obj_id'     => $EVT_ID,
167
+				'noheader'   => true,
168
+			],
169
+			'restore_events'                => [
170
+				'func'       => '_trash_or_restore_events',
171
+				'args'       => ['event_status' => 'draft'],
172
+				'capability' => 'ee_delete_events',
173
+				'noheader'   => true,
174
+			],
175
+			'delete_event'                  => [
176
+				'func'       => '_delete_event',
177
+				'capability' => 'ee_delete_event',
178
+				'obj_id'     => $EVT_ID,
179
+				'noheader'   => true,
180
+			],
181
+			'delete_events'                 => [
182
+				'func'       => '_delete_events',
183
+				'capability' => 'ee_delete_events',
184
+				'noheader'   => true,
185
+			],
186
+			'view_report'                   => [
187
+				'func'       => '_view_report',
188
+				'capability' => 'ee_edit_events',
189
+			],
190
+			'default_event_settings'        => [
191
+				'func'       => '_default_event_settings',
192
+				'capability' => 'manage_options',
193
+			],
194
+			'update_default_event_settings' => [
195
+				'func'       => '_update_default_event_settings',
196
+				'capability' => 'manage_options',
197
+				'noheader'   => true,
198
+			],
199
+			'template_settings'             => [
200
+				'func'       => '_template_settings',
201
+				'capability' => 'manage_options',
202
+			],
203
+			// event category tab related
204
+			'add_category'                  => [
205
+				'func'       => '_category_details',
206
+				'capability' => 'ee_edit_event_category',
207
+				'args'       => ['add'],
208
+			],
209
+			'edit_category'                 => [
210
+				'func'       => '_category_details',
211
+				'capability' => 'ee_edit_event_category',
212
+				'args'       => ['edit'],
213
+			],
214
+			'delete_categories'             => [
215
+				'func'       => '_delete_categories',
216
+				'capability' => 'ee_delete_event_category',
217
+				'noheader'   => true,
218
+			],
219
+			'delete_category'               => [
220
+				'func'       => '_delete_categories',
221
+				'capability' => 'ee_delete_event_category',
222
+				'noheader'   => true,
223
+			],
224
+			'insert_category'               => [
225
+				'func'       => '_insert_or_update_category',
226
+				'args'       => ['new_category' => true],
227
+				'capability' => 'ee_edit_event_category',
228
+				'noheader'   => true,
229
+			],
230
+			'update_category'               => [
231
+				'func'       => '_insert_or_update_category',
232
+				'args'       => ['new_category' => false],
233
+				'capability' => 'ee_edit_event_category',
234
+				'noheader'   => true,
235
+			],
236
+			'category_list'                 => [
237
+				'func'       => '_category_list_table',
238
+				'capability' => 'ee_manage_event_categories',
239
+			],
240
+			'preview_deletion'              => [
241
+				'func'       => 'previewDeletion',
242
+				'capability' => 'ee_delete_events',
243
+			],
244
+			'confirm_deletion'              => [
245
+				'func'       => 'confirmDeletion',
246
+				'capability' => 'ee_delete_events',
247
+				'noheader'   => true,
248
+			],
249
+		];
250
+	}
251
+
252
+
253
+	/**
254
+	 * Set the _page_config property for this admin page group.
255
+	 */
256
+	protected function _set_page_config()
257
+	{
258
+		$post_id            = $this->request->getRequestParam('post', 0, 'int');
259
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
260
+		$this->_page_config = [
261
+			'default'                => [
262
+				'nav'           => [
263
+					'label' => esc_html__('Overview', 'event_espresso'),
264
+					'order' => 10,
265
+				],
266
+				'list_table'    => 'Events_Admin_List_Table',
267
+				'help_tabs'     => [
268
+					'events_overview_help_tab'                       => [
269
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
270
+						'filename' => 'events_overview',
271
+					],
272
+					'events_overview_table_column_headings_help_tab' => [
273
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
274
+						'filename' => 'events_overview_table_column_headings',
275
+					],
276
+					'events_overview_filters_help_tab'               => [
277
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
278
+						'filename' => 'events_overview_filters',
279
+					],
280
+					'events_overview_view_help_tab'                  => [
281
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
282
+						'filename' => 'events_overview_views',
283
+					],
284
+					'events_overview_other_help_tab'                 => [
285
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
286
+						'filename' => 'events_overview_other',
287
+					],
288
+				],
289
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
290
+				// 'help_tour'     => array(
291
+				//     'Event_Overview_Help_Tour',
292
+				//     // 'New_Features_Test_Help_Tour' for testing multiple help tour
293
+				// ),
294
+				'qtips'         => [
295
+					'EE_Event_List_Table_Tips',
296
+				],
297
+				'require_nonce' => false,
298
+			],
299
+			'create_new'             => [
300
+				'nav'           => [
301
+					'label'      => esc_html__('Add Event', 'event_espresso'),
302
+					'order'      => 5,
303
+					'persistent' => false,
304
+				],
305
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
306
+				'help_tabs'     => [
307
+					'event_editor_help_tab'                            => [
308
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
309
+						'filename' => 'event_editor',
310
+					],
311
+					'event_editor_title_richtexteditor_help_tab'       => [
312
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
313
+						'filename' => 'event_editor_title_richtexteditor',
314
+					],
315
+					'event_editor_venue_details_help_tab'              => [
316
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
317
+						'filename' => 'event_editor_venue_details',
318
+					],
319
+					'event_editor_event_datetimes_help_tab'            => [
320
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
321
+						'filename' => 'event_editor_event_datetimes',
322
+					],
323
+					'event_editor_event_tickets_help_tab'              => [
324
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
325
+						'filename' => 'event_editor_event_tickets',
326
+					],
327
+					'event_editor_event_registration_options_help_tab' => [
328
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
329
+						'filename' => 'event_editor_event_registration_options',
330
+					],
331
+					'event_editor_tags_categories_help_tab'            => [
332
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
333
+						'filename' => 'event_editor_tags_categories',
334
+					],
335
+					'event_editor_questions_registrants_help_tab'      => [
336
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
337
+						'filename' => 'event_editor_questions_registrants',
338
+					],
339
+					'event_editor_save_new_event_help_tab'             => [
340
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
341
+						'filename' => 'event_editor_save_new_event',
342
+					],
343
+					'event_editor_other_help_tab'                      => [
344
+						'title'    => esc_html__('Event Other', 'event_espresso'),
345
+						'filename' => 'event_editor_other',
346
+					],
347
+				],
348
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
349
+				// 'help_tour'     => array(
350
+				//     'Event_Editor_Help_Tour',
351
+				// ),
352
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
353
+				'require_nonce' => false,
354
+			],
355
+			'edit'                   => [
356
+				'nav'           => [
357
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
358
+					'order'      => 5,
359
+					'persistent' => false,
360
+					'url'        => $post_id
361
+						? EE_Admin_Page::add_query_args_and_nonce(
362
+							['post' => $post_id, 'action' => 'edit'],
363
+							$this->_current_page_view_url
364
+						)
365
+						: $this->_admin_base_url,
366
+				],
367
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
368
+				'help_tabs'     => [
369
+					'event_editor_help_tab'                            => [
370
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
371
+						'filename' => 'event_editor',
372
+					],
373
+					'event_editor_title_richtexteditor_help_tab'       => [
374
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
375
+						'filename' => 'event_editor_title_richtexteditor',
376
+					],
377
+					'event_editor_venue_details_help_tab'              => [
378
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
379
+						'filename' => 'event_editor_venue_details',
380
+					],
381
+					'event_editor_event_datetimes_help_tab'            => [
382
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
383
+						'filename' => 'event_editor_event_datetimes',
384
+					],
385
+					'event_editor_event_tickets_help_tab'              => [
386
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
387
+						'filename' => 'event_editor_event_tickets',
388
+					],
389
+					'event_editor_event_registration_options_help_tab' => [
390
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
391
+						'filename' => 'event_editor_event_registration_options',
392
+					],
393
+					'event_editor_tags_categories_help_tab'            => [
394
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
395
+						'filename' => 'event_editor_tags_categories',
396
+					],
397
+					'event_editor_questions_registrants_help_tab'      => [
398
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
399
+						'filename' => 'event_editor_questions_registrants',
400
+					],
401
+					'event_editor_save_new_event_help_tab'             => [
402
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
403
+						'filename' => 'event_editor_save_new_event',
404
+					],
405
+					'event_editor_other_help_tab'                      => [
406
+						'title'    => esc_html__('Event Other', 'event_espresso'),
407
+						'filename' => 'event_editor_other',
408
+					],
409
+				],
410
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
411
+				'require_nonce' => false,
412
+			],
413
+			'default_event_settings' => [
414
+				'nav'           => [
415
+					'label' => esc_html__('Default Settings', 'event_espresso'),
416
+					'order' => 40,
417
+				],
418
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
419
+				'labels'        => [
420
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
421
+				],
422
+				'help_tabs'     => [
423
+					'default_settings_help_tab'        => [
424
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
425
+						'filename' => 'events_default_settings',
426
+					],
427
+					'default_settings_status_help_tab' => [
428
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
429
+						'filename' => 'events_default_settings_status',
430
+					],
431
+					'default_maximum_tickets_help_tab' => [
432
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
433
+						'filename' => 'events_default_settings_max_tickets',
434
+					],
435
+				],
436
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
437
+				// 'help_tour'     => array('Event_Default_Settings_Help_Tour'),
438
+				'require_nonce' => false,
439
+			],
440
+			// template settings
441
+			'template_settings'      => [
442
+				'nav'           => [
443
+					'label' => esc_html__('Templates', 'event_espresso'),
444
+					'order' => 30,
445
+				],
446
+				'metaboxes'     => $this->_default_espresso_metaboxes,
447
+				'help_tabs'     => [
448
+					'general_settings_templates_help_tab' => [
449
+						'title'    => esc_html__('Templates', 'event_espresso'),
450
+						'filename' => 'general_settings_templates',
451
+					],
452
+				],
453
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
454
+				// 'help_tour'     => array('Templates_Help_Tour'),
455
+				'require_nonce' => false,
456
+			],
457
+			// event category stuff
458
+			'add_category'           => [
459
+				'nav'           => [
460
+					'label'      => esc_html__('Add Category', 'event_espresso'),
461
+					'order'      => 15,
462
+					'persistent' => false,
463
+				],
464
+				'help_tabs'     => [
465
+					'add_category_help_tab' => [
466
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
467
+						'filename' => 'events_add_category',
468
+					],
469
+				],
470
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
471
+				// 'help_tour'     => array('Event_Add_Category_Help_Tour'),
472
+				'metaboxes'     => ['_publish_post_box'],
473
+				'require_nonce' => false,
474
+			],
475
+			'edit_category'          => [
476
+				'nav'           => [
477
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
478
+					'order'      => 15,
479
+					'persistent' => false,
480
+					'url'        => $EVT_CAT_ID
481
+						? add_query_arg(
482
+							['EVT_CAT_ID' => $EVT_CAT_ID],
483
+							$this->_current_page_view_url
484
+						)
485
+						: $this->_admin_base_url,
486
+				],
487
+				'help_tabs'     => [
488
+					'edit_category_help_tab' => [
489
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
490
+						'filename' => 'events_edit_category',
491
+					],
492
+				],
493
+				/*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
494
+				'metaboxes'     => ['_publish_post_box'],
495
+				'require_nonce' => false,
496
+			],
497
+			'category_list'          => [
498
+				'nav'           => [
499
+					'label' => esc_html__('Categories', 'event_espresso'),
500
+					'order' => 20,
501
+				],
502
+				'list_table'    => 'Event_Categories_Admin_List_Table',
503
+				'help_tabs'     => [
504
+					'events_categories_help_tab'                       => [
505
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
506
+						'filename' => 'events_categories',
507
+					],
508
+					'events_categories_table_column_headings_help_tab' => [
509
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
510
+						'filename' => 'events_categories_table_column_headings',
511
+					],
512
+					'events_categories_view_help_tab'                  => [
513
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
514
+						'filename' => 'events_categories_views',
515
+					],
516
+					'events_categories_other_help_tab'                 => [
517
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
518
+						'filename' => 'events_categories_other',
519
+					],
520
+				],
521
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
522
+				// 'help_tour'     => array(
523
+				//     'Event_Categories_Help_Tour',
524
+				// ),
525
+				'metaboxes'     => $this->_default_espresso_metaboxes,
526
+				'require_nonce' => false,
527
+			],
528
+			'preview_deletion'       => [
529
+				'nav'           => [
530
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
531
+					'order'      => 15,
532
+					'persistent' => false,
533
+					'url'        => '',
534
+				],
535
+				'require_nonce' => false,
536
+			],
537
+		];
538
+	}
539
+
540
+
541
+	/**
542
+	 * Used to register any global screen options if necessary for every route in this admin page group.
543
+	 */
544
+	protected function _add_screen_options()
545
+	{
546
+	}
547
+
548
+
549
+	/**
550
+	 * Implementing the screen options for the 'default' route.
551
+	 */
552
+	protected function _add_screen_options_default()
553
+	{
554
+		$this->_per_page_screen_option();
555
+	}
556
+
557
+
558
+	/**
559
+	 * Implementing screen options for the category list route.
560
+	 */
561
+	protected function _add_screen_options_category_list()
562
+	{
563
+		$page_title              = $this->_admin_page_title;
564
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
565
+		$this->_per_page_screen_option();
566
+		$this->_admin_page_title = $page_title;
567
+	}
568
+
569
+
570
+	/**
571
+	 * Used to register any global feature pointers for the admin page group.
572
+	 */
573
+	protected function _add_feature_pointers()
574
+	{
575
+	}
576
+
577
+
578
+	/**
579
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
580
+	 */
581
+	public function load_scripts_styles()
582
+	{
583
+		wp_register_style(
584
+			'events-admin-css',
585
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
586
+			[],
587
+			EVENT_ESPRESSO_VERSION
588
+		);
589
+		wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
590
+		wp_enqueue_style('events-admin-css');
591
+		wp_enqueue_style('ee-cat-admin');
592
+		// todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
593
+		// registers for all views
594
+		// scripts
595
+		wp_register_script(
596
+			'event_editor_js',
597
+			EVENTS_ASSETS_URL . 'event_editor.js',
598
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
599
+			EVENT_ESPRESSO_VERSION,
600
+			true
601
+		);
602
+	}
603
+
604
+
605
+	/**
606
+	 * Enqueuing scripts and styles specific to this view
607
+	 */
608
+	public function load_scripts_styles_create_new()
609
+	{
610
+		$this->load_scripts_styles_edit();
611
+	}
612
+
613
+
614
+	/**
615
+	 * Enqueuing scripts and styles specific to this view
616
+	 */
617
+	public function load_scripts_styles_edit()
618
+	{
619
+		// styles
620
+		wp_enqueue_style('espresso-ui-theme');
621
+		wp_register_style(
622
+			'event-editor-css',
623
+			EVENTS_ASSETS_URL . 'event-editor.css',
624
+			['ee-admin-css'],
625
+			EVENT_ESPRESSO_VERSION
626
+		);
627
+		wp_enqueue_style('event-editor-css');
628
+		// scripts
629
+		wp_register_script(
630
+			'event-datetime-metabox',
631
+			EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
632
+			['event_editor_js', 'ee-datepicker'],
633
+			EVENT_ESPRESSO_VERSION
634
+		);
635
+		wp_enqueue_script('event-datetime-metabox');
636
+	}
637
+
638
+
639
+	/**
640
+	 * Populating the _views property for the category list table view.
641
+	 */
642
+	protected function _set_list_table_views_category_list()
643
+	{
644
+		$this->_views = [
645
+			'all' => [
646
+				'slug'        => 'all',
647
+				'label'       => esc_html__('All', 'event_espresso'),
648
+				'count'       => 0,
649
+				'bulk_action' => [
650
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
651
+				],
652
+			],
653
+		];
654
+	}
655
+
656
+
657
+	/**
658
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
659
+	 */
660
+	public function admin_init()
661
+	{
662
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
663
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
664
+			'event_espresso'
665
+		);
666
+	}
667
+
668
+
669
+	/**
670
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
671
+	 * group.
672
+	 */
673
+	public function admin_notices()
674
+	{
675
+	}
676
+
677
+
678
+	/**
679
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
680
+	 * this admin page group.
681
+	 */
682
+	public function admin_footer_scripts()
683
+	{
684
+	}
685
+
686
+
687
+	/**
688
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
689
+	 * warning (via EE_Error::add_error());
690
+	 *
691
+	 * @param EE_Event $event Event object
692
+	 * @param string   $req_type
693
+	 * @return void
694
+	 * @throws EE_Error
695
+	 * @throws ReflectionException
696
+	 */
697
+	public function verify_event_edit($event = null, $req_type = '')
698
+	{
699
+		// don't need to do this when processing
700
+		if (! empty($req_type)) {
701
+			return;
702
+		}
703
+		// no event?
704
+		if (empty($event)) {
705
+			// set event
706
+			$event = $this->_cpt_model_obj;
707
+		}
708
+		// STILL no event?
709
+		if (! $event instanceof EE_Event) {
710
+			return;
711
+		}
712
+		$orig_status = $event->status();
713
+		// first check if event is active.
714
+		if (
715
+			$orig_status === EEM_Event::cancelled
716
+			|| $orig_status === EEM_Event::postponed
717
+			|| $event->is_expired()
718
+			|| $event->is_inactive()
719
+		) {
720
+			return;
721
+		}
722
+		// made it here so it IS active... next check that any of the tickets are sold.
723
+		if ($event->is_sold_out(true)) {
724
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
725
+				EE_Error::add_attention(
726
+					sprintf(
727
+						esc_html__(
728
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
729
+							'event_espresso'
730
+						),
731
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
732
+					)
733
+				);
734
+			}
735
+			return;
736
+		} elseif ($orig_status === EEM_Event::sold_out) {
737
+			EE_Error::add_attention(
738
+				sprintf(
739
+					esc_html__(
740
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
741
+						'event_espresso'
742
+					),
743
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
744
+				)
745
+			);
746
+		}
747
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
748
+		if (! $event->tickets_on_sale()) {
749
+			return;
750
+		}
751
+		// made it here so show warning
752
+		$this->_edit_event_warning();
753
+	}
754
+
755
+
756
+	/**
757
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
758
+	 * When needed, hook this into a EE_Error::add_error() notice.
759
+	 *
760
+	 * @access protected
761
+	 * @return void
762
+	 */
763
+	protected function _edit_event_warning()
764
+	{
765
+		// we don't want to add warnings during these requests
766
+		if ($this->request->getRequestParam('action') === 'editpost') {
767
+			return;
768
+		}
769
+		EE_Error::add_attention(
770
+			sprintf(
771
+				esc_html__(
772
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
773
+					'event_espresso'
774
+				),
775
+				'<a class="espresso-help-tab-lnk">',
776
+				'</a>'
777
+			)
778
+		);
779
+	}
780
+
781
+
782
+	/**
783
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
784
+	 * Otherwise, do the normal logic
785
+	 *
786
+	 * @return void
787
+	 * @throws EE_Error
788
+	 */
789
+	protected function _create_new_cpt_item()
790
+	{
791
+		$has_timezone_string = get_option('timezone_string');
792
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
793
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
794
+			EE_Error::add_attention(
795
+				sprintf(
796
+					esc_html__(
797
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
798
+						'event_espresso'
799
+					),
800
+					'<br>',
801
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
802
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
803
+					. '</select>',
804
+					'<button class="button button-secondary timezone-submit">',
805
+					'</button><span class="spinner"></span>'
806
+				),
807
+				__FILE__,
808
+				__FUNCTION__,
809
+				__LINE__
810
+			);
811
+		}
812
+		parent::_create_new_cpt_item();
813
+	}
814
+
815
+
816
+	/**
817
+	 * Sets the _views property for the default route in this admin page group.
818
+	 */
819
+	protected function _set_list_table_views_default()
820
+	{
821
+		$this->_views = [
822
+			'all'   => [
823
+				'slug'        => 'all',
824
+				'label'       => esc_html__('View All Events', 'event_espresso'),
825
+				'count'       => 0,
826
+				'bulk_action' => [
827
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
828
+				],
829
+			],
830
+			'draft' => [
831
+				'slug'        => 'draft',
832
+				'label'       => esc_html__('Draft', 'event_espresso'),
833
+				'count'       => 0,
834
+				'bulk_action' => [
835
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
836
+				],
837
+			],
838
+		];
839
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
840
+			$this->_views['trash'] = [
841
+				'slug'        => 'trash',
842
+				'label'       => esc_html__('Trash', 'event_espresso'),
843
+				'count'       => 0,
844
+				'bulk_action' => [
845
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
846
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
847
+				],
848
+			];
849
+		}
850
+	}
851
+
852
+
853
+	/**
854
+	 * Provides the legend item array for the default list table view.
855
+	 *
856
+	 * @return array
857
+	 * @throws EE_Error
858
+	 * @throws EE_Error
859
+	 */
860
+	protected function _event_legend_items()
861
+	{
862
+		$items    = [
863
+			'view_details'   => [
864
+				'class' => 'dashicons dashicons-search',
865
+				'desc'  => esc_html__('View Event', 'event_espresso'),
866
+			],
867
+			'edit_event'     => [
868
+				'class' => 'ee-icon ee-icon-calendar-edit',
869
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
870
+			],
871
+			'view_attendees' => [
872
+				'class' => 'dashicons dashicons-groups',
873
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
874
+			],
875
+		];
876
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
877
+		$statuses = [
878
+			'sold_out_status'  => [
879
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
880
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
881
+			],
882
+			'active_status'    => [
883
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
884
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
885
+			],
886
+			'upcoming_status'  => [
887
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
888
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
889
+			],
890
+			'postponed_status' => [
891
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
892
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
893
+			],
894
+			'cancelled_status' => [
895
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
896
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
897
+			],
898
+			'expired_status'   => [
899
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
900
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
901
+			],
902
+			'inactive_status'  => [
903
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
904
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
905
+			],
906
+		];
907
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
908
+		return array_merge($items, $statuses);
909
+	}
910
+
911
+
912
+	/**
913
+	 * @return EEM_Event
914
+	 * @throws EE_Error
915
+	 * @throws ReflectionException
916
+	 */
917
+	private function _event_model()
918
+	{
919
+		if (! $this->_event_model instanceof EEM_Event) {
920
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
921
+		}
922
+		return $this->_event_model;
923
+	}
924
+
925
+
926
+	/**
927
+	 * Adds extra buttons to the WP CPT permalink field row.
928
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
929
+	 *
930
+	 * @param string $return    the current html
931
+	 * @param int    $id        the post id for the page
932
+	 * @param string $new_title What the title is
933
+	 * @param string $new_slug  what the slug is
934
+	 * @return string            The new html string for the permalink area
935
+	 */
936
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
937
+	{
938
+		// make sure this is only when editing
939
+		if (! empty($id)) {
940
+			$post   = get_post($id);
941
+			$return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
942
+					   . esc_html__('Shortcode', 'event_espresso')
943
+					   . '</a> ';
944
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
945
+					   . $post->ID
946
+					   . ']">';
947
+		}
948
+		return $return;
949
+	}
950
+
951
+
952
+	/**
953
+	 * _events_overview_list_table
954
+	 * This contains the logic for showing the events_overview list
955
+	 *
956
+	 * @access protected
957
+	 * @return void
958
+	 * @throws EE_Error
959
+	 */
960
+	protected function _events_overview_list_table()
961
+	{
962
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
963
+		$this->_template_args['after_list_table']                           =
964
+			! empty($this->_template_args['after_list_table'])
965
+				? (array) $this->_template_args['after_list_table']
966
+				: [];
967
+		$this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
968
+			. EEH_Template::get_button_or_link(
969
+				get_post_type_archive_link('espresso_events'),
970
+				esc_html__("View Event Archive Page", "event_espresso"),
971
+				'button'
972
+			);
973
+		$this->_template_args['after_list_table']['legend']                 = $this->_display_legend(
974
+			$this->_event_legend_items()
975
+		);
976
+		$this->_admin_page_title                                            .= ' ' . $this->get_action_link_or_button(
977
+			'create_new',
978
+			'add',
979
+			[],
980
+			'add-new-h2'
981
+		);
982
+		$this->display_admin_list_table_page_with_no_sidebar();
983
+	}
984
+
985
+
986
+	/**
987
+	 * this allows for extra misc actions in the default WP publish box
988
+	 *
989
+	 * @return void
990
+	 * @throws EE_Error
991
+	 * @throws ReflectionException
992
+	 */
993
+	public function extra_misc_actions_publish_box()
994
+	{
995
+		$this->_generate_publish_box_extra_content();
996
+	}
997
+
998
+
999
+	/**
1000
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1001
+	 * saved.
1002
+	 * Typically you would use this to save any additional data.
1003
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1004
+	 * ALSO very important.  When a post transitions from scheduled to published,
1005
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1006
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1007
+	 *
1008
+	 * @access protected
1009
+	 * @abstract
1010
+	 * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1011
+	 * @param object $post    The post object of the cpt that was saved.
1012
+	 * @return void
1013
+	 * @throws EE_Error
1014
+	 * @throws ReflectionException
1015
+	 */
1016
+	protected function _insert_update_cpt_item($post_id, $post)
1017
+	{
1018
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1019
+			// get out we're not processing an event save.
1020
+			return;
1021
+		}
1022
+
1023
+		$event_values = [
1024
+			'EVT_display_desc'                => $this->request->getRequestParam('display_desc', false, 'bool'),
1025
+			'EVT_display_ticket_selector'     => $this->request->getRequestParam(
1026
+				'display_ticket_selector',
1027
+				false,
1028
+				'bool'
1029
+			),
1030
+			'EVT_additional_limit'            => min(
1031
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1032
+				$this->request->getRequestParam('additional_limit', null, 'int')
1033
+			),
1034
+			'EVT_default_registration_status' => $this->request->getRequestParam(
1035
+				'EVT_default_registration_status',
1036
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1037
+			),
1038
+
1039
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1040
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1041
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1042
+			'EVT_external_URL'    => $this->request->getRequestParam('externalURL'),
1043
+			'EVT_phone'           => $this->request->getRequestParam('event_phone'),
1044
+		];
1045
+		// update event
1046
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1047
+		// get event_object for other metaboxes...
1048
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1049
+		// i have to setup where conditions to override the filters in the model
1050
+		// that filter out autodraft and inherit statuses so we GET the inherit id!
1051
+		$event = $this->_event_model()->get_one(
1052
+			[
1053
+				[
1054
+					$this->_event_model()->primary_key_name() => $post_id,
1055
+					'OR'                                      => [
1056
+						'status'   => $post->post_status,
1057
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1058
+						// but the returned object here has a status of "publish", so use the original post status as well
1059
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1060
+					],
1061
+				],
1062
+			]
1063
+		);
1064
+		// the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1065
+		$event_update_callbacks = apply_filters(
1066
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1067
+			[
1068
+				[$this, '_default_venue_update'],
1069
+				[$this, '_default_tickets_update'],
1070
+			]
1071
+		);
1072
+		$att_success            = true;
1073
+		foreach ($event_update_callbacks as $e_callback) {
1074
+			$_success = is_callable($e_callback)
1075
+				? call_user_func($e_callback, $event, $this->request->requestParams())
1076
+				: false;
1077
+			// if ANY of these updates fail then we want the appropriate global error message
1078
+			$att_success = ! $att_success ? $att_success : $_success;
1079
+		}
1080
+		// any errors?
1081
+		if ($success && false === $att_success) {
1082
+			EE_Error::add_error(
1083
+				esc_html__(
1084
+					'Event Details saved successfully but something went wrong with saving attachments.',
1085
+					'event_espresso'
1086
+				),
1087
+				__FILE__,
1088
+				__FUNCTION__,
1089
+				__LINE__
1090
+			);
1091
+		} elseif ($success === false) {
1092
+			EE_Error::add_error(
1093
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1094
+				__FILE__,
1095
+				__FUNCTION__,
1096
+				__LINE__
1097
+			);
1098
+		}
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * @param int $post_id
1104
+	 * @param int $revision_id
1105
+	 * @throws EE_Error
1106
+	 * @throws EE_Error
1107
+	 * @throws ReflectionException
1108
+	 * @see parent::restore_item()
1109
+	 */
1110
+	protected function _restore_cpt_item($post_id, $revision_id)
1111
+	{
1112
+		// copy existing event meta to new post
1113
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1114
+		if ($post_evt instanceof EE_Event) {
1115
+			// meta revision restore
1116
+			$post_evt->restore_revision($revision_id);
1117
+			// related objs restore
1118
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1119
+		}
1120
+	}
1121
+
1122
+
1123
+	/**
1124
+	 * Attach the venue to the Event
1125
+	 *
1126
+	 * @param EE_Event $event Event Object to add the venue to
1127
+	 * @param array    $data  The request data from the form
1128
+	 * @return bool           Success or fail.
1129
+	 * @throws EE_Error
1130
+	 * @throws ReflectionException
1131
+	 */
1132
+	protected function _default_venue_update(EE_Event $event, $data)
1133
+	{
1134
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1135
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1136
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1137
+		// very important.  If we don't have a venue name...
1138
+		// then we'll get out because not necessary to create empty venue
1139
+		if (empty($data['venue_title'])) {
1140
+			return false;
1141
+		}
1142
+		$venue_array = [
1143
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1144
+			'VNU_name'            => $data['venue_title'],
1145
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1146
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1147
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1148
+				? $data['venue_short_description']
1149
+				: null,
1150
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1151
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1152
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1153
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1154
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1155
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1156
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1157
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1158
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1159
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1160
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1161
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1162
+			'status'              => 'publish',
1163
+		];
1164
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1165
+		if (! empty($venue_id)) {
1166
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1167
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1168
+			// we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1169
+			$event->_add_relation_to($venue_id, 'Venue');
1170
+			return $rows_affected > 0;
1171
+		}
1172
+		// we insert the venue
1173
+		$venue_id = $venue_model->insert($venue_array);
1174
+		$event->_add_relation_to($venue_id, 'Venue');
1175
+		return ! empty($venue_id);
1176
+		// when we have the ancestor come in it's already been handled by the revision save.
1177
+	}
1178
+
1179
+
1180
+	/**
1181
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1182
+	 *
1183
+	 * @param EE_Event $event The Event object we're attaching data to
1184
+	 * @param array    $data  The request data from the form
1185
+	 * @return array
1186
+	 * @throws EE_Error
1187
+	 * @throws ReflectionException
1188
+	 * @throws Exception
1189
+	 */
1190
+	protected function _default_tickets_update(EE_Event $event, $data)
1191
+	{
1192
+		$datetime       = null;
1193
+		$saved_tickets  = [];
1194
+		$event_timezone = $event->get_timezone();
1195
+		$date_formats   = ['Y-m-d', 'h:i a'];
1196
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1197
+			// trim all values to ensure any excess whitespace is removed.
1198
+			$datetime_data                = array_map('trim', $datetime_data);
1199
+			$datetime_data['DTT_EVT_end'] =
1200
+				isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1201
+					? $datetime_data['DTT_EVT_end']
1202
+					: $datetime_data['DTT_EVT_start'];
1203
+			$datetime_values              = [
1204
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1205
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1206
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1207
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1208
+				'DTT_order'     => $row,
1209
+			];
1210
+			// if we have an id then let's get existing object first and then set the new values.
1211
+			//  Otherwise we instantiate a new object for save.
1212
+			if (! empty($datetime_data['DTT_ID'])) {
1213
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1214
+				if (! $datetime instanceof EE_Ticket) {
1215
+					throw new RuntimeException(
1216
+						sprintf(
1217
+							esc_html__(
1218
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1219
+								'event_espresso'
1220
+							),
1221
+							$datetime_data['DTT_ID']
1222
+						)
1223
+					);
1224
+				}
1225
+				$datetime->set_date_format($date_formats[0]);
1226
+				$datetime->set_time_format($date_formats[1]);
1227
+				foreach ($datetime_values as $field => $value) {
1228
+					$datetime->set($field, $value);
1229
+				}
1230
+			} else {
1231
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1232
+			}
1233
+			if (! $datetime instanceof EE_Datetime) {
1234
+				throw new RuntimeException(
1235
+					sprintf(
1236
+						esc_html__(
1237
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1238
+							'event_espresso'
1239
+						),
1240
+						print_r($datetime_values, true)
1241
+					)
1242
+				);
1243
+			}
1244
+			// before going any further make sure our dates are setup correctly
1245
+			// so that the end date is always equal or greater than the start date.
1246
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1247
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1248
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1249
+			}
1250
+			$datetime->save();
1251
+			$event->_add_relation_to($datetime, 'Datetime');
1252
+		}
1253
+		// no datetimes get deleted so we don't do any of that logic here.
1254
+		// update tickets next
1255
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1256
+
1257
+		// set up some default start and end dates in case those are not present in the incoming data
1258
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1259
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1260
+		// use the start date of the first datetime for the end date
1261
+		$first_datetime   = $event->first_datetime();
1262
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1263
+
1264
+		// now process the incoming data
1265
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1266
+			$update_prices = false;
1267
+			$ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1268
+				? $data['edit_prices'][ $row ][1]['PRC_amount']
1269
+				: 0;
1270
+			// trim inputs to ensure any excess whitespace is removed.
1271
+			$ticket_data   = array_map('trim', $ticket_data);
1272
+			$ticket_values = [
1273
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1274
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1275
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1276
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1277
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1278
+					? $ticket_data['TKT_start_date']
1279
+					: $default_start_date,
1280
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1281
+					? $ticket_data['TKT_end_date']
1282
+					: $default_end_date,
1283
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1284
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1285
+					? $ticket_data['TKT_qty']
1286
+					: EE_INF,
1287
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1288
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1289
+					? $ticket_data['TKT_uses']
1290
+					: EE_INF,
1291
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1292
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1293
+				'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1294
+				'TKT_price'       => $ticket_price,
1295
+				'TKT_row'         => $row,
1296
+			];
1297
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1298
+			// which means in turn that the prices will become new prices as well.
1299
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1300
+				$ticket_values['TKT_ID']         = 0;
1301
+				$ticket_values['TKT_is_default'] = 0;
1302
+				$update_prices                   = true;
1303
+			}
1304
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1305
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1306
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1307
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1308
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1309
+			if (! empty($ticket_data['TKT_ID'])) {
1310
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1311
+				if (! $existing_ticket instanceof EE_Ticket) {
1312
+					throw new RuntimeException(
1313
+						sprintf(
1314
+							esc_html__(
1315
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1316
+								'event_espresso'
1317
+							),
1318
+							$ticket_data['TKT_ID']
1319
+						)
1320
+					);
1321
+				}
1322
+				$ticket_sold = $existing_ticket->count_related(
1323
+					'Registration',
1324
+					[
1325
+						[
1326
+							'STS_ID' => [
1327
+								'NOT IN',
1328
+								[EEM_Registration::status_id_incomplete],
1329
+							],
1330
+						],
1331
+					]
1332
+				) > 0;
1333
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1334
+				// if they are different then we create a new ticket (if $ticket_sold)
1335
+				// if they aren't different then we go ahead and modify existing ticket.
1336
+				$create_new_ticket = $ticket_sold
1337
+									 && $ticket_price !== $existing_ticket->price()
1338
+									 && ! $existing_ticket->deleted();
1339
+				$existing_ticket->set_date_format($date_formats[0]);
1340
+				$existing_ticket->set_time_format($date_formats[1]);
1341
+				// set new values
1342
+				foreach ($ticket_values as $field => $value) {
1343
+					if ($field == 'TKT_qty') {
1344
+						$existing_ticket->set_qty($value);
1345
+					} elseif ($field == 'TKT_price') {
1346
+						$existing_ticket->set('TKT_price', $ticket_price);
1347
+					} else {
1348
+						$existing_ticket->set($field, $value);
1349
+					}
1350
+				}
1351
+				$ticket = $existing_ticket;
1352
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1353
+				//  Otherwise we have to create a new ticket.
1354
+				if ($create_new_ticket) {
1355
+					// archive the old ticket first
1356
+					$existing_ticket->set('TKT_deleted', 1);
1357
+					$existing_ticket->save();
1358
+					// make sure this ticket is still recorded in our $saved_tickets
1359
+					// so we don't run it through the regular trash routine.
1360
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1361
+					// create new ticket that's a copy of the existing except,
1362
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1363
+					$new_ticket = clone $existing_ticket;
1364
+					$new_ticket->set('TKT_ID', 0);
1365
+					$new_ticket->set('TKT_deleted', 0);
1366
+					$new_ticket->set('TKT_sold', 0);
1367
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1368
+					$update_prices = true;
1369
+					$ticket        = $new_ticket;
1370
+				}
1371
+			} else {
1372
+				// no TKT_id so a new ticket
1373
+				$ticket_values['TKT_price'] = $ticket_price;
1374
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1375
+				$update_prices              = true;
1376
+			}
1377
+			if (! $ticket instanceof EE_Ticket) {
1378
+				throw new RuntimeException(
1379
+					sprintf(
1380
+						esc_html__(
1381
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1382
+							'event_espresso'
1383
+						),
1384
+						print_r($ticket_values, true)
1385
+					)
1386
+				);
1387
+			}
1388
+			// cap ticket qty by datetime reg limits
1389
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1390
+			// update ticket.
1391
+			$ticket->save();
1392
+			// before going any further make sure our dates are setup correctly
1393
+			// so that the end date is always equal or greater than the start date.
1394
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1395
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1396
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1397
+				$ticket->save();
1398
+			}
1399
+			// initially let's add the ticket to the datetime
1400
+			$datetime->_add_relation_to($ticket, 'Ticket');
1401
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1402
+			// add prices to ticket
1403
+			$this->_add_prices_to_ticket($data['edit_prices'][ $row ], $ticket, $update_prices);
1404
+		}
1405
+		// however now we need to handle permanently deleting tickets via the ui.
1406
+		//  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1407
+		//  However, it does allow for deleting tickets that have no tickets sold,
1408
+		// in which case we want to get rid of permanently because there is no need to save in db.
1409
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] == '' ? [] : $old_tickets;
1410
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1411
+		foreach ($tickets_removed as $id) {
1412
+			$id = absint($id);
1413
+			// get the ticket for this id
1414
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1415
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1416
+				continue;
1417
+			}
1418
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1419
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1420
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1421
+			foreach ($related_datetimes as $related_datetime) {
1422
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1423
+			}
1424
+			// need to do the same for prices (except these prices can also be deleted because again,
1425
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1426
+			$ticket_to_remove->delete_related_permanently('Price');
1427
+			// finally let's delete this ticket
1428
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1429
+			$ticket_to_remove->delete_permanently();
1430
+		}
1431
+		return [$datetime, $saved_tickets];
1432
+	}
1433
+
1434
+
1435
+	/**
1436
+	 * This attaches a list of given prices to a ticket.
1437
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1438
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1439
+	 * price info and prices are automatically "archived" via the ticket.
1440
+	 *
1441
+	 * @access  private
1442
+	 * @param array     $prices_data Array of prices from the form.
1443
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1444
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1445
+	 * @return  void
1446
+	 * @throws EE_Error
1447
+	 * @throws ReflectionException
1448
+	 */
1449
+	private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1450
+	{
1451
+		$timezone = $ticket->get_timezone();
1452
+		foreach ($prices_data as $row => $price_data) {
1453
+			$price_values = [
1454
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1455
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1456
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1457
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1458
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1459
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1460
+				'PRC_order'      => $row,
1461
+			];
1462
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1463
+				$price_values['PRC_ID'] = 0;
1464
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1465
+			} else {
1466
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1467
+				// update this price with new values
1468
+				foreach ($price_values as $field => $new_price) {
1469
+					$price->set($field, $new_price);
1470
+				}
1471
+			}
1472
+			if (! $price instanceof EE_Price) {
1473
+				throw new RuntimeException(
1474
+					sprintf(
1475
+						esc_html__(
1476
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1477
+							'event_espresso'
1478
+						),
1479
+						print_r($price_values, true)
1480
+					)
1481
+				);
1482
+			}
1483
+			$price->save();
1484
+			$ticket->_add_relation_to($price, 'Price');
1485
+		}
1486
+	}
1487
+
1488
+
1489
+	/**
1490
+	 * Add in our autosave ajax handlers
1491
+	 *
1492
+	 */
1493
+	protected function _ee_autosave_create_new()
1494
+	{
1495
+	}
1496
+
1497
+
1498
+	/**
1499
+	 * More autosave handlers.
1500
+	 */
1501
+	protected function _ee_autosave_edit()
1502
+	{
1503
+		// TEMPORARILY EXITING CAUSE THIS IS A TODO
1504
+	}
1505
+
1506
+
1507
+	/**
1508
+	 * @throws EE_Error
1509
+	 * @throws ReflectionException
1510
+	 */
1511
+	private function _generate_publish_box_extra_content()
1512
+	{
1513
+		// load formatter helper
1514
+		// args for getting related registrations
1515
+		$approved_query_args        = [
1516
+			[
1517
+				'REG_deleted' => 0,
1518
+				'STS_ID'      => EEM_Registration::status_id_approved,
1519
+			],
1520
+		];
1521
+		$not_approved_query_args    = [
1522
+			[
1523
+				'REG_deleted' => 0,
1524
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1525
+			],
1526
+		];
1527
+		$pending_payment_query_args = [
1528
+			[
1529
+				'REG_deleted' => 0,
1530
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1531
+			],
1532
+		];
1533
+		// publish box
1534
+		$publish_box_extra_args = [
1535
+			'view_approved_reg_url'        => add_query_arg(
1536
+				[
1537
+					'action'      => 'default',
1538
+					'event_id'    => $this->_cpt_model_obj->ID(),
1539
+					'_reg_status' => EEM_Registration::status_id_approved,
1540
+				],
1541
+				REG_ADMIN_URL
1542
+			),
1543
+			'view_not_approved_reg_url'    => add_query_arg(
1544
+				[
1545
+					'action'      => 'default',
1546
+					'event_id'    => $this->_cpt_model_obj->ID(),
1547
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1548
+				],
1549
+				REG_ADMIN_URL
1550
+			),
1551
+			'view_pending_payment_reg_url' => add_query_arg(
1552
+				[
1553
+					'action'      => 'default',
1554
+					'event_id'    => $this->_cpt_model_obj->ID(),
1555
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1556
+				],
1557
+				REG_ADMIN_URL
1558
+			),
1559
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1560
+				'Registration',
1561
+				$approved_query_args
1562
+			),
1563
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1564
+				'Registration',
1565
+				$not_approved_query_args
1566
+			),
1567
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1568
+				'Registration',
1569
+				$pending_payment_query_args
1570
+			),
1571
+			'misc_pub_section_class'       => apply_filters(
1572
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1573
+				'misc-pub-section'
1574
+			),
1575
+		];
1576
+		ob_start();
1577
+		do_action(
1578
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1579
+			$this->_cpt_model_obj
1580
+		);
1581
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1582
+		// load template
1583
+		EEH_Template::display_template(
1584
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1585
+			$publish_box_extra_args
1586
+		);
1587
+	}
1588
+
1589
+
1590
+	/**
1591
+	 * @return EE_Event
1592
+	 */
1593
+	public function get_event_object()
1594
+	{
1595
+		return $this->_cpt_model_obj;
1596
+	}
1597
+
1598
+
1599
+
1600
+
1601
+	/** METABOXES * */
1602
+	/**
1603
+	 * _register_event_editor_meta_boxes
1604
+	 * add all metaboxes related to the event_editor
1605
+	 *
1606
+	 * @return void
1607
+	 * @throws EE_Error
1608
+	 * @throws ReflectionException
1609
+	 */
1610
+	protected function _register_event_editor_meta_boxes()
1611
+	{
1612
+		$this->verify_cpt_object();
1613
+		add_meta_box(
1614
+			'espresso_event_editor_tickets',
1615
+			esc_html__('Event Datetime & Ticket', 'event_espresso'),
1616
+			[$this, 'ticket_metabox'],
1617
+			$this->page_slug,
1618
+			'normal',
1619
+			'high'
1620
+		);
1621
+		add_meta_box(
1622
+			'espresso_event_editor_event_options',
1623
+			esc_html__('Event Registration Options', 'event_espresso'),
1624
+			[$this, 'registration_options_meta_box'],
1625
+			$this->page_slug,
1626
+			'side'
1627
+		);
1628
+		// NOTE: if you're looking for other metaboxes in here,
1629
+		// where a metabox has a related management page in the admin
1630
+		// you will find it setup in the related management page's "_Hooks" file.
1631
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1632
+	}
1633
+
1634
+
1635
+	/**
1636
+	 * @throws DomainException
1637
+	 * @throws EE_Error
1638
+	 * @throws ReflectionException
1639
+	 */
1640
+	public function ticket_metabox()
1641
+	{
1642
+		$existing_datetime_ids = $existing_ticket_ids = [];
1643
+		// defaults for template args
1644
+		$template_args = [
1645
+			'existing_datetime_ids'    => '',
1646
+			'event_datetime_help_link' => '',
1647
+			'ticket_options_help_link' => '',
1648
+			'time'                     => null,
1649
+			'ticket_rows'              => '',
1650
+			'existing_ticket_ids'      => '',
1651
+			'total_ticket_rows'        => 1,
1652
+			'ticket_js_structure'      => '',
1653
+			'trash_icon'               => 'ee-lock-icon',
1654
+			'disabled'                 => '',
1655
+		];
1656
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1657
+		/**
1658
+		 * 1. Start with retrieving Datetimes
1659
+		 * 2. Fore each datetime get related tickets
1660
+		 * 3. For each ticket get related prices
1661
+		 */
1662
+		$times          = EEM_Datetime::instance()->get_all_event_dates($event_id);
1663
+		$first_datetime = reset($times);
1664
+		// do we get related tickets?
1665
+		if (
1666
+			$first_datetime instanceof EE_Datetime
1667
+			&& $first_datetime->ID() !== 0
1668
+		) {
1669
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1670
+			$template_args['time']   = $first_datetime;
1671
+			$related_tickets         = $first_datetime->tickets(
1672
+				[
1673
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1674
+					'default_where_conditions' => 'none',
1675
+				]
1676
+			);
1677
+			if (! empty($related_tickets)) {
1678
+				$template_args['total_ticket_rows'] = count($related_tickets);
1679
+				$row                                = 0;
1680
+				foreach ($related_tickets as $ticket) {
1681
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1682
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1683
+					$row++;
1684
+				}
1685
+			} else {
1686
+				$template_args['total_ticket_rows'] = 1;
1687
+				/** @type EE_Ticket $ticket */
1688
+				$ticket                       = EEM_Ticket::instance()->create_default_object();
1689
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1690
+			}
1691
+		} else {
1692
+			$template_args['time']        = $times[0];
1693
+			$tickets                      = EEM_Ticket::instance()->get_all_default_tickets();
1694
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1695
+			// NOTE: we're just sending the first default row
1696
+			// (decaf can't manage default tickets so this should be sufficient);
1697
+		}
1698
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1699
+			'event_editor_event_datetimes_help_tab'
1700
+		);
1701
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1702
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1703
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1704
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1705
+			EEM_Ticket::instance()->create_default_object(),
1706
+			true
1707
+		);
1708
+		$template                                  = apply_filters(
1709
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1710
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1711
+		);
1712
+		EEH_Template::display_template($template, $template_args);
1713
+	}
1714
+
1715
+
1716
+	/**
1717
+	 * Setup an individual ticket form for the decaf event editor page
1718
+	 *
1719
+	 * @access private
1720
+	 * @param EE_Ticket $ticket   the ticket object
1721
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1722
+	 * @param int       $row
1723
+	 * @return string generated html for the ticket row.
1724
+	 * @throws EE_Error
1725
+	 * @throws ReflectionException
1726
+	 */
1727
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1728
+	{
1729
+		$template_args = [
1730
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1731
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1732
+				: '',
1733
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1734
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1735
+			'TKT_name'            => $ticket->get('TKT_name'),
1736
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1737
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1738
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1739
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1740
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1741
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1742
+			'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1743
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1744
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1745
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1746
+				: ' disabled=disabled',
1747
+		];
1748
+		$price         = $ticket->ID() !== 0
1749
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1750
+			: null;
1751
+		$price         = $price instanceof EE_Price
1752
+			? $price
1753
+			: EEM_Price::instance()->create_default_object();
1754
+		$price_args    = [
1755
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1756
+			'PRC_amount'            => $price->get('PRC_amount'),
1757
+			'PRT_ID'                => $price->get('PRT_ID'),
1758
+			'PRC_ID'                => $price->get('PRC_ID'),
1759
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1760
+		];
1761
+		// make sure we have default start and end dates if skeleton
1762
+		// handle rows that should NOT be empty
1763
+		if (empty($template_args['TKT_start_date'])) {
1764
+			// if empty then the start date will be now.
1765
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1766
+		}
1767
+		if (empty($template_args['TKT_end_date'])) {
1768
+			// get the earliest datetime (if present);
1769
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1770
+				? $this->_cpt_model_obj->get_first_related(
1771
+					'Datetime',
1772
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1773
+				)
1774
+				: null;
1775
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1776
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1777
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1778
+		}
1779
+		$template_args = array_merge($template_args, $price_args);
1780
+		$template      = apply_filters(
1781
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1782
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1783
+			$ticket
1784
+		);
1785
+		return EEH_Template::display_template($template, $template_args, true);
1786
+	}
1787
+
1788
+
1789
+	/**
1790
+	 * @throws EE_Error
1791
+	 * @throws ReflectionException
1792
+	 */
1793
+	public function registration_options_meta_box()
1794
+	{
1795
+		$yes_no_values             = [
1796
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1797
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1798
+		];
1799
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1800
+			[
1801
+				EEM_Registration::status_id_cancelled,
1802
+				EEM_Registration::status_id_declined,
1803
+				EEM_Registration::status_id_incomplete,
1804
+			],
1805
+			true
1806
+		);
1807
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1808
+		$template_args['_event']                          = $this->_cpt_model_obj;
1809
+		$template_args['event']                           = $this->_cpt_model_obj;
1810
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1811
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1812
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1813
+			'default_reg_status',
1814
+			$default_reg_status_values,
1815
+			$this->_cpt_model_obj->default_registration_status()
1816
+		);
1817
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1818
+			'display_desc',
1819
+			$yes_no_values,
1820
+			$this->_cpt_model_obj->display_description()
1821
+		);
1822
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1823
+			'display_ticket_selector',
1824
+			$yes_no_values,
1825
+			$this->_cpt_model_obj->display_ticket_selector(),
1826
+			'',
1827
+			'',
1828
+			false
1829
+		);
1830
+		$template_args['additional_registration_options'] = apply_filters(
1831
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1832
+			'',
1833
+			$template_args,
1834
+			$yes_no_values,
1835
+			$default_reg_status_values
1836
+		);
1837
+		EEH_Template::display_template(
1838
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1839
+			$template_args
1840
+		);
1841
+	}
1842
+
1843
+
1844
+	/**
1845
+	 * _get_events()
1846
+	 * This method simply returns all the events (for the given _view and paging)
1847
+	 *
1848
+	 * @access public
1849
+	 * @param int  $per_page     count of items per page (20 default);
1850
+	 * @param int  $current_page what is the current page being viewed.
1851
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1852
+	 *                           If FALSE then we return an array of event objects
1853
+	 *                           that match the given _view and paging parameters.
1854
+	 * @return array|int         an array of event objects or a count of them.
1855
+	 * @throws Exception
1856
+	 */
1857
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1858
+	{
1859
+		$EEM_Event   = $this->_event_model();
1860
+		$offset      = ($current_page - 1) * $per_page;
1861
+		$limit       = $count ? null : $offset . ',' . $per_page;
1862
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1863
+		$order       = $this->request->getRequestParam('order', 'DESC');
1864
+		$month_range = $this->request->getRequestParam('month_range');
1865
+		if ($month_range) {
1866
+			$pieces = explode(' ', $month_range, 3);
1867
+			// simulate the FIRST day of the month, that fixes issues for months like February
1868
+			// where PHP doesn't know what to assume for date.
1869
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1870
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1871
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1872
+		}
1873
+		$where  = [];
1874
+		$status = $this->request->getRequestParam('status');
1875
+		// determine what post_status our condition will have for the query.
1876
+		switch ($status) {
1877
+			case 'month':
1878
+			case 'today':
1879
+			case null:
1880
+			case 'all':
1881
+				break;
1882
+			case 'draft':
1883
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1884
+				break;
1885
+			default:
1886
+				$where['status'] = $status;
1887
+		}
1888
+		// categories? The default for all categories is -1
1889
+		$category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1890
+		if ($category !== -1) {
1891
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1892
+			$where['Term_Taxonomy.term_id']  = $category;
1893
+		}
1894
+		// date where conditions
1895
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1896
+		if ($month_range) {
1897
+			$DateTime = new DateTime(
1898
+				$year_r . '-' . $month_r . '-01 00:00:00',
1899
+				new DateTimeZone('UTC')
1900
+			);
1901
+			$start    = $DateTime->getTimestamp();
1902
+			// set the datetime to be the end of the month
1903
+			$DateTime->setDate(
1904
+				$year_r,
1905
+				$month_r,
1906
+				$DateTime->format('t')
1907
+			)->setTime(23, 59, 59);
1908
+			$end                             = $DateTime->getTimestamp();
1909
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1910
+		} elseif ($status === 'today') {
1911
+			$DateTime                        =
1912
+				new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1913
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1914
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1915
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1916
+		} elseif ($status === 'month') {
1917
+			$now                             = date('Y-m-01');
1918
+			$DateTime                        =
1919
+				new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1920
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1921
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1922
+														->setTime(23, 59, 59)
1923
+														->format(implode(' ', $start_formats));
1924
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1925
+		}
1926
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1927
+			$where['EVT_wp_user'] = get_current_user_id();
1928
+		} else {
1929
+			if (! isset($where['status'])) {
1930
+				if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1931
+					$where['OR'] = [
1932
+						'status*restrict_private' => ['!=', 'private'],
1933
+						'AND'                     => [
1934
+							'status*inclusive' => ['=', 'private'],
1935
+							'EVT_wp_user'      => get_current_user_id(),
1936
+						],
1937
+					];
1938
+				}
1939
+			}
1940
+		}
1941
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
1942
+		if (
1943
+			$wp_user
1944
+			&& $wp_user !== get_current_user_id()
1945
+			&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1946
+		) {
1947
+			$where['EVT_wp_user'] = $wp_user;
1948
+		}
1949
+		// search query handling
1950
+		$search_term = $this->request->getRequestParam('s');
1951
+		if ($search_term) {
1952
+			$search_term = '%' . $search_term . '%';
1953
+			$where['OR'] = [
1954
+				'EVT_name'       => ['LIKE', $search_term],
1955
+				'EVT_desc'       => ['LIKE', $search_term],
1956
+				'EVT_short_desc' => ['LIKE', $search_term],
1957
+			];
1958
+		}
1959
+		// filter events by venue.
1960
+		$venue = $this->request->getRequestParam('venue', 0, 'int');
1961
+		if ($venue) {
1962
+			$where['Venue.VNU_ID'] = $venue;
1963
+		}
1964
+		$request_params = $this->request->requestParams();
1965
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
1966
+		$query_params   = apply_filters(
1967
+			'FHEE__Events_Admin_Page__get_events__query_params',
1968
+			[
1969
+				$where,
1970
+				'limit'    => $limit,
1971
+				'order_by' => $orderby,
1972
+				'order'    => $order,
1973
+				'group_by' => 'EVT_ID',
1974
+			],
1975
+			$request_params
1976
+		);
1977
+
1978
+		// let's first check if we have special requests coming in.
1979
+		$active_status = $this->request->getRequestParam('active_status');
1980
+		if ($active_status) {
1981
+			switch ($active_status) {
1982
+				case 'upcoming':
1983
+					return $EEM_Event->get_upcoming_events($query_params, $count);
1984
+				case 'expired':
1985
+					return $EEM_Event->get_expired_events($query_params, $count);
1986
+				case 'active':
1987
+					return $EEM_Event->get_active_events($query_params, $count);
1988
+				case 'inactive':
1989
+					return $EEM_Event->get_inactive_events($query_params, $count);
1990
+			}
1991
+		}
1992
+
1993
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
1994
+	}
1995
+
1996
+
1997
+	/**
1998
+	 * handling for WordPress CPT actions (trash, restore, delete)
1999
+	 *
2000
+	 * @param string $post_id
2001
+	 * @throws EE_Error
2002
+	 * @throws ReflectionException
2003
+	 */
2004
+	public function trash_cpt_item($post_id)
2005
+	{
2006
+		$this->request->setRequestParam('EVT_ID', $post_id);
2007
+		$this->_trash_or_restore_event('trash', false);
2008
+	}
2009
+
2010
+
2011
+	/**
2012
+	 * @param string $post_id
2013
+	 * @throws EE_Error
2014
+	 * @throws ReflectionException
2015
+	 */
2016
+	public function restore_cpt_item($post_id)
2017
+	{
2018
+		$this->request->setRequestParam('EVT_ID', $post_id);
2019
+		$this->_trash_or_restore_event('draft', false);
2020
+	}
2021
+
2022
+
2023
+	/**
2024
+	 * @param string $post_id
2025
+	 * @throws EE_Error
2026
+	 * @throws EE_Error
2027
+	 */
2028
+	public function delete_cpt_item($post_id)
2029
+	{
2030
+		throw new EE_Error(
2031
+			esc_html__(
2032
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2033
+				'event_espresso'
2034
+			)
2035
+		);
2036
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2037
+		// $this->_delete_event();
2038
+	}
2039
+
2040
+
2041
+	/**
2042
+	 * _trash_or_restore_event
2043
+	 *
2044
+	 * @access protected
2045
+	 * @param string $event_status
2046
+	 * @param bool   $redirect_after
2047
+	 * @throws EE_Error
2048
+	 * @throws EE_Error
2049
+	 * @throws ReflectionException
2050
+	 */
2051
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2052
+	{
2053
+		// determine the event id and set to array.
2054
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2055
+		// loop thru events
2056
+		if ($EVT_ID) {
2057
+			// clean status
2058
+			$event_status = sanitize_key($event_status);
2059
+			// grab status
2060
+			if (! empty($event_status)) {
2061
+				$success = $this->_change_event_status($EVT_ID, $event_status);
2062
+			} else {
2063
+				$success = false;
2064
+				$msg     = esc_html__(
2065
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2066
+					'event_espresso'
2067
+				);
2068
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2069
+			}
2070
+		} else {
2071
+			$success = false;
2072
+			$msg     = esc_html__(
2073
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2074
+				'event_espresso'
2075
+			);
2076
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2077
+		}
2078
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2079
+		if ($redirect_after) {
2080
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2081
+		}
2082
+	}
2083
+
2084
+
2085
+	/**
2086
+	 * _trash_or_restore_events
2087
+	 *
2088
+	 * @access protected
2089
+	 * @param string $event_status
2090
+	 * @return void
2091
+	 * @throws EE_Error
2092
+	 * @throws EE_Error
2093
+	 * @throws ReflectionException
2094
+	 */
2095
+	protected function _trash_or_restore_events($event_status = 'trash')
2096
+	{
2097
+		// clean status
2098
+		$event_status = sanitize_key($event_status);
2099
+		// grab status
2100
+		if (! empty($event_status)) {
2101
+			$success = true;
2102
+			// determine the event id and set to array.
2103
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2104
+			// loop thru events
2105
+			foreach ($EVT_IDs as $EVT_ID) {
2106
+				if ($EVT_ID = absint($EVT_ID)) {
2107
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2108
+					$success = $results !== false ? $success : false;
2109
+				} else {
2110
+					$msg = sprintf(
2111
+						esc_html__(
2112
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2113
+							'event_espresso'
2114
+						),
2115
+						$EVT_ID
2116
+					);
2117
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2118
+					$success = false;
2119
+				}
2120
+			}
2121
+		} else {
2122
+			$success = false;
2123
+			$msg     = esc_html__(
2124
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2125
+				'event_espresso'
2126
+			);
2127
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2128
+		}
2129
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2130
+		$success = $success ? 2 : false;
2131
+		$action  = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2132
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2133
+	}
2134
+
2135
+
2136
+	/**
2137
+	 * @param int    $EVT_ID
2138
+	 * @param string $event_status
2139
+	 * @return bool
2140
+	 * @throws EE_Error
2141
+	 * @throws ReflectionException
2142
+	 */
2143
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2144
+	{
2145
+		// grab event id
2146
+		if (! $EVT_ID) {
2147
+			$msg = esc_html__(
2148
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2149
+				'event_espresso'
2150
+			);
2151
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2152
+			return false;
2153
+		}
2154
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2155
+		// clean status
2156
+		$event_status = sanitize_key($event_status);
2157
+		// grab status
2158
+		if (empty($event_status)) {
2159
+			$msg = esc_html__(
2160
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2161
+				'event_espresso'
2162
+			);
2163
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2164
+			return false;
2165
+		}
2166
+		// was event trashed or restored ?
2167
+		switch ($event_status) {
2168
+			case 'draft':
2169
+				$action = 'restored from the trash';
2170
+				$hook   = 'AHEE_event_restored_from_trash';
2171
+				break;
2172
+			case 'trash':
2173
+				$action = 'moved to the trash';
2174
+				$hook   = 'AHEE_event_moved_to_trash';
2175
+				break;
2176
+			default:
2177
+				$action = 'updated';
2178
+				$hook   = false;
2179
+		}
2180
+		// use class to change status
2181
+		$this->_cpt_model_obj->set_status($event_status);
2182
+		$success = $this->_cpt_model_obj->save();
2183
+		if (! $success) {
2184
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2185
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2186
+			return false;
2187
+		}
2188
+		if ($hook) {
2189
+			do_action($hook);
2190
+		}
2191
+		return true;
2192
+	}
2193
+
2194
+
2195
+	/**
2196
+	 * @param array $event_ids
2197
+	 * @return array
2198
+	 * @since   4.10.23.p
2199
+	 */
2200
+	private function cleanEventIds(array $event_ids)
2201
+	{
2202
+		return array_map('absint', $event_ids);
2203
+	}
2204
+
2205
+
2206
+	/**
2207
+	 * @return array
2208
+	 * @since   4.10.23.p
2209
+	 */
2210
+	private function getEventIdsFromRequest()
2211
+	{
2212
+		return $this->request->getRequestParam('EVT_IDs', [], 'int', true, ',');
2213
+	}
2214
+
2215
+
2216
+	/**
2217
+	 * @param bool $preview_delete
2218
+	 * @throws EE_Error
2219
+	 */
2220
+	protected function _delete_event($preview_delete = true)
2221
+	{
2222
+		$this->_delete_events($preview_delete);
2223
+	}
2224
+
2225
+
2226
+	/**
2227
+	 * Gets the tree traversal batch persister.
2228
+	 *
2229
+	 * @return NodeGroupDao
2230
+	 * @throws InvalidArgumentException
2231
+	 * @throws InvalidDataTypeException
2232
+	 * @throws InvalidInterfaceException
2233
+	 * @since 4.10.12.p
2234
+	 */
2235
+	protected function getModelObjNodeGroupPersister()
2236
+	{
2237
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2238
+			$this->model_obj_node_group_persister =
2239
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2240
+		}
2241
+		return $this->model_obj_node_group_persister;
2242
+	}
2243
+
2244
+
2245
+	/**
2246
+	 * @param bool $preview_delete
2247
+	 * @return void
2248
+	 * @throws EE_Error
2249
+	 */
2250
+	protected function _delete_events($preview_delete = true)
2251
+	{
2252
+		$event_ids = $this->getEventIdsFromRequest();
2253
+		if ($preview_delete) {
2254
+			$this->generateDeletionPreview($event_ids);
2255
+		} else {
2256
+			EEM_Event::instance()->delete_permanently([['EVT_ID' => ['IN', $event_ids]]]);
2257
+		}
2258
+	}
2259
+
2260
+
2261
+	/**
2262
+	 * @param array $event_ids
2263
+	 */
2264
+	protected function generateDeletionPreview(array $event_ids)
2265
+	{
2266
+		$event_ids = $this->cleanEventIds($event_ids);
2267
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2268
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2269
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2270
+			[
2271
+				'action'            => 'preview_deletion',
2272
+				'deletion_job_code' => $deletion_job_code,
2273
+			],
2274
+			$this->_admin_base_url
2275
+		);
2276
+		EEH_URL::safeRedirectAndExit(
2277
+			EE_Admin_Page::add_query_args_and_nonce(
2278
+				[
2279
+					'page'              => 'espresso_batch',
2280
+					'batch'             => EED_Batch::batch_job,
2281
+					'EVT_IDs'           => $event_ids,
2282
+					'deletion_job_code' => $deletion_job_code,
2283
+					'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2284
+					'return_url'        => urlencode($return_url),
2285
+				],
2286
+				admin_url()
2287
+			)
2288
+		);
2289
+	}
2290
+
2291
+
2292
+	/**
2293
+	 * Checks for a POST submission
2294
+	 *
2295
+	 * @since 4.10.12.p
2296
+	 */
2297
+	protected function confirmDeletion()
2298
+	{
2299
+		$deletion_redirect_logic =
2300
+			$this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion');
2301
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2302
+	}
2303
+
2304
+
2305
+	/**
2306
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2307
+	 *
2308
+	 * @throws EE_Error
2309
+	 * @since 4.10.12.p
2310
+	 */
2311
+	protected function previewDeletion()
2312
+	{
2313
+		$preview_deletion_logic =
2314
+			$this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion');
2315
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2316
+		$this->display_admin_page_with_no_sidebar();
2317
+	}
2318
+
2319
+
2320
+	/**
2321
+	 * get total number of events
2322
+	 *
2323
+	 * @access public
2324
+	 * @return int
2325
+	 * @throws EE_Error
2326
+	 * @throws EE_Error
2327
+	 */
2328
+	public function total_events()
2329
+	{
2330
+		return EEM_Event::instance()->count(
2331
+			['caps' => 'read_admin'],
2332
+			'EVT_ID',
2333
+			true
2334
+		);
2335
+	}
2336
+
2337
+
2338
+	/**
2339
+	 * get total number of draft events
2340
+	 *
2341
+	 * @access public
2342
+	 * @return int
2343
+	 * @throws EE_Error
2344
+	 * @throws EE_Error
2345
+	 */
2346
+	public function total_events_draft()
2347
+	{
2348
+		return EEM_Event::instance()->count(
2349
+			[
2350
+				['status' => ['IN', ['draft', 'auto-draft']]],
2351
+				'caps' => 'read_admin',
2352
+			],
2353
+			'EVT_ID',
2354
+			true
2355
+		);
2356
+	}
2357
+
2358
+
2359
+	/**
2360
+	 * get total number of trashed events
2361
+	 *
2362
+	 * @access public
2363
+	 * @return int
2364
+	 * @throws EE_Error
2365
+	 * @throws EE_Error
2366
+	 */
2367
+	public function total_trashed_events()
2368
+	{
2369
+		return EEM_Event::instance()->count(
2370
+			[
2371
+				['status' => 'trash'],
2372
+				'caps' => 'read_admin',
2373
+			],
2374
+			'EVT_ID',
2375
+			true
2376
+		);
2377
+	}
2378
+
2379
+
2380
+	/**
2381
+	 *    _default_event_settings
2382
+	 *    This generates the Default Settings Tab
2383
+	 *
2384
+	 * @return void
2385
+	 * @throws EE_Error
2386
+	 */
2387
+	protected function _default_event_settings()
2388
+	{
2389
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2390
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2391
+		$this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2392
+		$this->display_admin_page_with_sidebar();
2393
+	}
2394
+
2395
+
2396
+	/**
2397
+	 * Return the form for event settings.
2398
+	 *
2399
+	 * @return EE_Form_Section_Proper
2400
+	 * @throws EE_Error
2401
+	 */
2402
+	protected function _default_event_settings_form()
2403
+	{
2404
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2405
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2406
+		// exclude
2407
+			[
2408
+				EEM_Registration::status_id_cancelled,
2409
+				EEM_Registration::status_id_declined,
2410
+				EEM_Registration::status_id_incomplete,
2411
+				EEM_Registration::status_id_wait_list,
2412
+			],
2413
+			true
2414
+		);
2415
+		return new EE_Form_Section_Proper(
2416
+			[
2417
+				'name'            => 'update_default_event_settings',
2418
+				'html_id'         => 'update_default_event_settings',
2419
+				'html_class'      => 'form-table',
2420
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2421
+				'subsections'     => apply_filters(
2422
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2423
+					[
2424
+						'default_reg_status'  => new EE_Select_Input(
2425
+							$registration_stati_for_selection,
2426
+							[
2427
+								'default'         => isset($registration_config->default_STS_ID)
2428
+													 && array_key_exists(
2429
+														 $registration_config->default_STS_ID,
2430
+														 $registration_stati_for_selection
2431
+													 )
2432
+									? sanitize_text_field($registration_config->default_STS_ID)
2433
+									: EEM_Registration::status_id_pending_payment,
2434
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2435
+													 . EEH_Template::get_help_tab_link(
2436
+														 'default_settings_status_help_tab'
2437
+													 ),
2438
+								'html_help_text'  => esc_html__(
2439
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2440
+									'event_espresso'
2441
+								),
2442
+							]
2443
+						),
2444
+						'default_max_tickets' => new EE_Integer_Input(
2445
+							[
2446
+								'default'         => isset($registration_config->default_maximum_number_of_tickets)
2447
+									? $registration_config->default_maximum_number_of_tickets
2448
+									: EEM_Event::get_default_additional_limit(),
2449
+								'html_label_text' => esc_html__(
2450
+									'Default Maximum Tickets Allowed Per Order:',
2451
+									'event_espresso'
2452
+								)
2453
+								. EEH_Template::get_help_tab_link(
2454
+									'default_maximum_tickets_help_tab"'
2455
+								),
2456
+								'html_help_text'  => esc_html__(
2457
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2458
+									'event_espresso'
2459
+								),
2460
+							]
2461
+						),
2462
+					]
2463
+				),
2464
+			]
2465
+		);
2466
+	}
2467
+
2468
+
2469
+	/**
2470
+	 * _update_default_event_settings
2471
+	 *
2472
+	 * @access protected
2473
+	 * @return void
2474
+	 * @throws EE_Error
2475
+	 */
2476
+	protected function _update_default_event_settings()
2477
+	{
2478
+		$registration_config = EE_Registry::instance()->CFG->registration;
2479
+		$form                = $this->_default_event_settings_form();
2480
+		if ($form->was_submitted()) {
2481
+			$form->receive_form_submission();
2482
+			if ($form->is_valid()) {
2483
+				$valid_data = $form->valid_data();
2484
+				if (isset($valid_data['default_reg_status'])) {
2485
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2486
+				}
2487
+				if (isset($valid_data['default_max_tickets'])) {
2488
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2489
+				}
2490
+				// update because data was valid!
2491
+				EE_Registry::instance()->CFG->update_espresso_config();
2492
+				EE_Error::overwrite_success();
2493
+				EE_Error::add_success(
2494
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2495
+				);
2496
+			}
2497
+		}
2498
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2499
+	}
2500
+
2501
+
2502
+	/*************        Templates        *************
21 2503
      *
22
-     * @var EE_Event $_event
23
-     */
24
-    protected $_event;
25
-
26
-
27
-    /**
28
-     * This will hold the category object for category_details screen.
29
-     *
30
-     * @var stdClass $_category
31
-     */
32
-    protected $_category;
33
-
34
-
35
-    /**
36
-     * This will hold the event model instance
37
-     *
38
-     * @var EEM_Event $_event_model
39
-     */
40
-    protected $_event_model;
41
-
42
-
43
-    /**
44
-     * @var EE_Event
45
-     */
46
-    protected $_cpt_model_obj = false;
47
-
48
-
49
-    /**
50
-     * @var NodeGroupDao
51
-     */
52
-    protected $model_obj_node_group_persister;
53
-
54
-
55
-    /**
56
-     * Initialize page props for this admin page group.
57
-     */
58
-    protected function _init_page_props()
59
-    {
60
-        $this->page_slug        = EVENTS_PG_SLUG;
61
-        $this->page_label       = EVENTS_LABEL;
62
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
63
-        $this->_admin_base_path = EVENTS_ADMIN;
64
-        $this->_cpt_model_names = [
65
-            'create_new' => 'EEM_Event',
66
-            'edit'       => 'EEM_Event',
67
-        ];
68
-        $this->_cpt_edit_routes = [
69
-            'espresso_events' => 'edit',
70
-        ];
71
-        add_action(
72
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
-            [$this, 'verify_event_edit'],
74
-            10,
75
-            2
76
-        );
77
-    }
78
-
79
-
80
-    /**
81
-     * Sets the ajax hooks used for this admin page group.
82
-     */
83
-    protected function _ajax_hooks()
84
-    {
85
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
-    }
87
-
88
-
89
-    /**
90
-     * Sets the page properties for this admin page group.
91
-     */
92
-    protected function _define_page_props()
93
-    {
94
-        $this->_admin_page_title = EVENTS_LABEL;
95
-        $this->_labels           = [
96
-            'buttons'      => [
97
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
98
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
-            ],
104
-            'editor_title' => [
105
-                'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
106
-            ],
107
-            'publishbox'   => [
108
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
110
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
-            ],
114
-        ];
115
-    }
116
-
117
-
118
-    /**
119
-     * Sets the page routes property for this admin page group.
120
-     */
121
-    protected function _set_page_routes()
122
-    {
123
-        // load formatter helper
124
-        // load field generator helper
125
-        // is there a evt_id in the request?
126
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
127
-        $EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
128
-
129
-        $this->_page_routes = [
130
-            'default'                       => [
131
-                'func'       => '_events_overview_list_table',
132
-                'capability' => 'ee_read_events',
133
-            ],
134
-            'create_new'                    => [
135
-                'func'       => '_create_new_cpt_item',
136
-                'capability' => 'ee_edit_events',
137
-            ],
138
-            'edit'                          => [
139
-                'func'       => '_edit_cpt_item',
140
-                'capability' => 'ee_edit_event',
141
-                'obj_id'     => $EVT_ID,
142
-            ],
143
-            'copy_event'                    => [
144
-                'func'       => '_copy_events',
145
-                'capability' => 'ee_edit_event',
146
-                'obj_id'     => $EVT_ID,
147
-                'noheader'   => true,
148
-            ],
149
-            'trash_event'                   => [
150
-                'func'       => '_trash_or_restore_event',
151
-                'args'       => ['event_status' => 'trash'],
152
-                'capability' => 'ee_delete_event',
153
-                'obj_id'     => $EVT_ID,
154
-                'noheader'   => true,
155
-            ],
156
-            'trash_events'                  => [
157
-                'func'       => '_trash_or_restore_events',
158
-                'args'       => ['event_status' => 'trash'],
159
-                'capability' => 'ee_delete_events',
160
-                'noheader'   => true,
161
-            ],
162
-            'restore_event'                 => [
163
-                'func'       => '_trash_or_restore_event',
164
-                'args'       => ['event_status' => 'draft'],
165
-                'capability' => 'ee_delete_event',
166
-                'obj_id'     => $EVT_ID,
167
-                'noheader'   => true,
168
-            ],
169
-            'restore_events'                => [
170
-                'func'       => '_trash_or_restore_events',
171
-                'args'       => ['event_status' => 'draft'],
172
-                'capability' => 'ee_delete_events',
173
-                'noheader'   => true,
174
-            ],
175
-            'delete_event'                  => [
176
-                'func'       => '_delete_event',
177
-                'capability' => 'ee_delete_event',
178
-                'obj_id'     => $EVT_ID,
179
-                'noheader'   => true,
180
-            ],
181
-            'delete_events'                 => [
182
-                'func'       => '_delete_events',
183
-                'capability' => 'ee_delete_events',
184
-                'noheader'   => true,
185
-            ],
186
-            'view_report'                   => [
187
-                'func'       => '_view_report',
188
-                'capability' => 'ee_edit_events',
189
-            ],
190
-            'default_event_settings'        => [
191
-                'func'       => '_default_event_settings',
192
-                'capability' => 'manage_options',
193
-            ],
194
-            'update_default_event_settings' => [
195
-                'func'       => '_update_default_event_settings',
196
-                'capability' => 'manage_options',
197
-                'noheader'   => true,
198
-            ],
199
-            'template_settings'             => [
200
-                'func'       => '_template_settings',
201
-                'capability' => 'manage_options',
202
-            ],
203
-            // event category tab related
204
-            'add_category'                  => [
205
-                'func'       => '_category_details',
206
-                'capability' => 'ee_edit_event_category',
207
-                'args'       => ['add'],
208
-            ],
209
-            'edit_category'                 => [
210
-                'func'       => '_category_details',
211
-                'capability' => 'ee_edit_event_category',
212
-                'args'       => ['edit'],
213
-            ],
214
-            'delete_categories'             => [
215
-                'func'       => '_delete_categories',
216
-                'capability' => 'ee_delete_event_category',
217
-                'noheader'   => true,
218
-            ],
219
-            'delete_category'               => [
220
-                'func'       => '_delete_categories',
221
-                'capability' => 'ee_delete_event_category',
222
-                'noheader'   => true,
223
-            ],
224
-            'insert_category'               => [
225
-                'func'       => '_insert_or_update_category',
226
-                'args'       => ['new_category' => true],
227
-                'capability' => 'ee_edit_event_category',
228
-                'noheader'   => true,
229
-            ],
230
-            'update_category'               => [
231
-                'func'       => '_insert_or_update_category',
232
-                'args'       => ['new_category' => false],
233
-                'capability' => 'ee_edit_event_category',
234
-                'noheader'   => true,
235
-            ],
236
-            'category_list'                 => [
237
-                'func'       => '_category_list_table',
238
-                'capability' => 'ee_manage_event_categories',
239
-            ],
240
-            'preview_deletion'              => [
241
-                'func'       => 'previewDeletion',
242
-                'capability' => 'ee_delete_events',
243
-            ],
244
-            'confirm_deletion'              => [
245
-                'func'       => 'confirmDeletion',
246
-                'capability' => 'ee_delete_events',
247
-                'noheader'   => true,
248
-            ],
249
-        ];
250
-    }
251
-
252
-
253
-    /**
254
-     * Set the _page_config property for this admin page group.
255
-     */
256
-    protected function _set_page_config()
257
-    {
258
-        $post_id            = $this->request->getRequestParam('post', 0, 'int');
259
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
260
-        $this->_page_config = [
261
-            'default'                => [
262
-                'nav'           => [
263
-                    'label' => esc_html__('Overview', 'event_espresso'),
264
-                    'order' => 10,
265
-                ],
266
-                'list_table'    => 'Events_Admin_List_Table',
267
-                'help_tabs'     => [
268
-                    'events_overview_help_tab'                       => [
269
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
270
-                        'filename' => 'events_overview',
271
-                    ],
272
-                    'events_overview_table_column_headings_help_tab' => [
273
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
274
-                        'filename' => 'events_overview_table_column_headings',
275
-                    ],
276
-                    'events_overview_filters_help_tab'               => [
277
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
278
-                        'filename' => 'events_overview_filters',
279
-                    ],
280
-                    'events_overview_view_help_tab'                  => [
281
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
282
-                        'filename' => 'events_overview_views',
283
-                    ],
284
-                    'events_overview_other_help_tab'                 => [
285
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
286
-                        'filename' => 'events_overview_other',
287
-                    ],
288
-                ],
289
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
290
-                // 'help_tour'     => array(
291
-                //     'Event_Overview_Help_Tour',
292
-                //     // 'New_Features_Test_Help_Tour' for testing multiple help tour
293
-                // ),
294
-                'qtips'         => [
295
-                    'EE_Event_List_Table_Tips',
296
-                ],
297
-                'require_nonce' => false,
298
-            ],
299
-            'create_new'             => [
300
-                'nav'           => [
301
-                    'label'      => esc_html__('Add Event', 'event_espresso'),
302
-                    'order'      => 5,
303
-                    'persistent' => false,
304
-                ],
305
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
306
-                'help_tabs'     => [
307
-                    'event_editor_help_tab'                            => [
308
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
309
-                        'filename' => 'event_editor',
310
-                    ],
311
-                    'event_editor_title_richtexteditor_help_tab'       => [
312
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
313
-                        'filename' => 'event_editor_title_richtexteditor',
314
-                    ],
315
-                    'event_editor_venue_details_help_tab'              => [
316
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
317
-                        'filename' => 'event_editor_venue_details',
318
-                    ],
319
-                    'event_editor_event_datetimes_help_tab'            => [
320
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
321
-                        'filename' => 'event_editor_event_datetimes',
322
-                    ],
323
-                    'event_editor_event_tickets_help_tab'              => [
324
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
325
-                        'filename' => 'event_editor_event_tickets',
326
-                    ],
327
-                    'event_editor_event_registration_options_help_tab' => [
328
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
329
-                        'filename' => 'event_editor_event_registration_options',
330
-                    ],
331
-                    'event_editor_tags_categories_help_tab'            => [
332
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
333
-                        'filename' => 'event_editor_tags_categories',
334
-                    ],
335
-                    'event_editor_questions_registrants_help_tab'      => [
336
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
337
-                        'filename' => 'event_editor_questions_registrants',
338
-                    ],
339
-                    'event_editor_save_new_event_help_tab'             => [
340
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
341
-                        'filename' => 'event_editor_save_new_event',
342
-                    ],
343
-                    'event_editor_other_help_tab'                      => [
344
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
345
-                        'filename' => 'event_editor_other',
346
-                    ],
347
-                ],
348
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
349
-                // 'help_tour'     => array(
350
-                //     'Event_Editor_Help_Tour',
351
-                // ),
352
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
353
-                'require_nonce' => false,
354
-            ],
355
-            'edit'                   => [
356
-                'nav'           => [
357
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
358
-                    'order'      => 5,
359
-                    'persistent' => false,
360
-                    'url'        => $post_id
361
-                        ? EE_Admin_Page::add_query_args_and_nonce(
362
-                            ['post' => $post_id, 'action' => 'edit'],
363
-                            $this->_current_page_view_url
364
-                        )
365
-                        : $this->_admin_base_url,
366
-                ],
367
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
368
-                'help_tabs'     => [
369
-                    'event_editor_help_tab'                            => [
370
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
371
-                        'filename' => 'event_editor',
372
-                    ],
373
-                    'event_editor_title_richtexteditor_help_tab'       => [
374
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
375
-                        'filename' => 'event_editor_title_richtexteditor',
376
-                    ],
377
-                    'event_editor_venue_details_help_tab'              => [
378
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
379
-                        'filename' => 'event_editor_venue_details',
380
-                    ],
381
-                    'event_editor_event_datetimes_help_tab'            => [
382
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
383
-                        'filename' => 'event_editor_event_datetimes',
384
-                    ],
385
-                    'event_editor_event_tickets_help_tab'              => [
386
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
387
-                        'filename' => 'event_editor_event_tickets',
388
-                    ],
389
-                    'event_editor_event_registration_options_help_tab' => [
390
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
391
-                        'filename' => 'event_editor_event_registration_options',
392
-                    ],
393
-                    'event_editor_tags_categories_help_tab'            => [
394
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
395
-                        'filename' => 'event_editor_tags_categories',
396
-                    ],
397
-                    'event_editor_questions_registrants_help_tab'      => [
398
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
399
-                        'filename' => 'event_editor_questions_registrants',
400
-                    ],
401
-                    'event_editor_save_new_event_help_tab'             => [
402
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
403
-                        'filename' => 'event_editor_save_new_event',
404
-                    ],
405
-                    'event_editor_other_help_tab'                      => [
406
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
407
-                        'filename' => 'event_editor_other',
408
-                    ],
409
-                ],
410
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
411
-                'require_nonce' => false,
412
-            ],
413
-            'default_event_settings' => [
414
-                'nav'           => [
415
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
416
-                    'order' => 40,
417
-                ],
418
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
419
-                'labels'        => [
420
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
421
-                ],
422
-                'help_tabs'     => [
423
-                    'default_settings_help_tab'        => [
424
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
425
-                        'filename' => 'events_default_settings',
426
-                    ],
427
-                    'default_settings_status_help_tab' => [
428
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
429
-                        'filename' => 'events_default_settings_status',
430
-                    ],
431
-                    'default_maximum_tickets_help_tab' => [
432
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
433
-                        'filename' => 'events_default_settings_max_tickets',
434
-                    ],
435
-                ],
436
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
437
-                // 'help_tour'     => array('Event_Default_Settings_Help_Tour'),
438
-                'require_nonce' => false,
439
-            ],
440
-            // template settings
441
-            'template_settings'      => [
442
-                'nav'           => [
443
-                    'label' => esc_html__('Templates', 'event_espresso'),
444
-                    'order' => 30,
445
-                ],
446
-                'metaboxes'     => $this->_default_espresso_metaboxes,
447
-                'help_tabs'     => [
448
-                    'general_settings_templates_help_tab' => [
449
-                        'title'    => esc_html__('Templates', 'event_espresso'),
450
-                        'filename' => 'general_settings_templates',
451
-                    ],
452
-                ],
453
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
454
-                // 'help_tour'     => array('Templates_Help_Tour'),
455
-                'require_nonce' => false,
456
-            ],
457
-            // event category stuff
458
-            'add_category'           => [
459
-                'nav'           => [
460
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
461
-                    'order'      => 15,
462
-                    'persistent' => false,
463
-                ],
464
-                'help_tabs'     => [
465
-                    'add_category_help_tab' => [
466
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
467
-                        'filename' => 'events_add_category',
468
-                    ],
469
-                ],
470
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
471
-                // 'help_tour'     => array('Event_Add_Category_Help_Tour'),
472
-                'metaboxes'     => ['_publish_post_box'],
473
-                'require_nonce' => false,
474
-            ],
475
-            'edit_category'          => [
476
-                'nav'           => [
477
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
478
-                    'order'      => 15,
479
-                    'persistent' => false,
480
-                    'url'        => $EVT_CAT_ID
481
-                        ? add_query_arg(
482
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
483
-                            $this->_current_page_view_url
484
-                        )
485
-                        : $this->_admin_base_url,
486
-                ],
487
-                'help_tabs'     => [
488
-                    'edit_category_help_tab' => [
489
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
490
-                        'filename' => 'events_edit_category',
491
-                    ],
492
-                ],
493
-                /*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
494
-                'metaboxes'     => ['_publish_post_box'],
495
-                'require_nonce' => false,
496
-            ],
497
-            'category_list'          => [
498
-                'nav'           => [
499
-                    'label' => esc_html__('Categories', 'event_espresso'),
500
-                    'order' => 20,
501
-                ],
502
-                'list_table'    => 'Event_Categories_Admin_List_Table',
503
-                'help_tabs'     => [
504
-                    'events_categories_help_tab'                       => [
505
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
506
-                        'filename' => 'events_categories',
507
-                    ],
508
-                    'events_categories_table_column_headings_help_tab' => [
509
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
510
-                        'filename' => 'events_categories_table_column_headings',
511
-                    ],
512
-                    'events_categories_view_help_tab'                  => [
513
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
514
-                        'filename' => 'events_categories_views',
515
-                    ],
516
-                    'events_categories_other_help_tab'                 => [
517
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
518
-                        'filename' => 'events_categories_other',
519
-                    ],
520
-                ],
521
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
522
-                // 'help_tour'     => array(
523
-                //     'Event_Categories_Help_Tour',
524
-                // ),
525
-                'metaboxes'     => $this->_default_espresso_metaboxes,
526
-                'require_nonce' => false,
527
-            ],
528
-            'preview_deletion'       => [
529
-                'nav'           => [
530
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
531
-                    'order'      => 15,
532
-                    'persistent' => false,
533
-                    'url'        => '',
534
-                ],
535
-                'require_nonce' => false,
536
-            ],
537
-        ];
538
-    }
539
-
540
-
541
-    /**
542
-     * Used to register any global screen options if necessary for every route in this admin page group.
543
-     */
544
-    protected function _add_screen_options()
545
-    {
546
-    }
547
-
548
-
549
-    /**
550
-     * Implementing the screen options for the 'default' route.
551
-     */
552
-    protected function _add_screen_options_default()
553
-    {
554
-        $this->_per_page_screen_option();
555
-    }
556
-
557
-
558
-    /**
559
-     * Implementing screen options for the category list route.
560
-     */
561
-    protected function _add_screen_options_category_list()
562
-    {
563
-        $page_title              = $this->_admin_page_title;
564
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
565
-        $this->_per_page_screen_option();
566
-        $this->_admin_page_title = $page_title;
567
-    }
568
-
569
-
570
-    /**
571
-     * Used to register any global feature pointers for the admin page group.
572
-     */
573
-    protected function _add_feature_pointers()
574
-    {
575
-    }
576
-
577
-
578
-    /**
579
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
580
-     */
581
-    public function load_scripts_styles()
582
-    {
583
-        wp_register_style(
584
-            'events-admin-css',
585
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
586
-            [],
587
-            EVENT_ESPRESSO_VERSION
588
-        );
589
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
590
-        wp_enqueue_style('events-admin-css');
591
-        wp_enqueue_style('ee-cat-admin');
592
-        // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
593
-        // registers for all views
594
-        // scripts
595
-        wp_register_script(
596
-            'event_editor_js',
597
-            EVENTS_ASSETS_URL . 'event_editor.js',
598
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
599
-            EVENT_ESPRESSO_VERSION,
600
-            true
601
-        );
602
-    }
603
-
604
-
605
-    /**
606
-     * Enqueuing scripts and styles specific to this view
607
-     */
608
-    public function load_scripts_styles_create_new()
609
-    {
610
-        $this->load_scripts_styles_edit();
611
-    }
612
-
613
-
614
-    /**
615
-     * Enqueuing scripts and styles specific to this view
616
-     */
617
-    public function load_scripts_styles_edit()
618
-    {
619
-        // styles
620
-        wp_enqueue_style('espresso-ui-theme');
621
-        wp_register_style(
622
-            'event-editor-css',
623
-            EVENTS_ASSETS_URL . 'event-editor.css',
624
-            ['ee-admin-css'],
625
-            EVENT_ESPRESSO_VERSION
626
-        );
627
-        wp_enqueue_style('event-editor-css');
628
-        // scripts
629
-        wp_register_script(
630
-            'event-datetime-metabox',
631
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
632
-            ['event_editor_js', 'ee-datepicker'],
633
-            EVENT_ESPRESSO_VERSION
634
-        );
635
-        wp_enqueue_script('event-datetime-metabox');
636
-    }
637
-
638
-
639
-    /**
640
-     * Populating the _views property for the category list table view.
641
-     */
642
-    protected function _set_list_table_views_category_list()
643
-    {
644
-        $this->_views = [
645
-            'all' => [
646
-                'slug'        => 'all',
647
-                'label'       => esc_html__('All', 'event_espresso'),
648
-                'count'       => 0,
649
-                'bulk_action' => [
650
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
651
-                ],
652
-            ],
653
-        ];
654
-    }
655
-
656
-
657
-    /**
658
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
659
-     */
660
-    public function admin_init()
661
-    {
662
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
663
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
664
-            'event_espresso'
665
-        );
666
-    }
667
-
668
-
669
-    /**
670
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
671
-     * group.
672
-     */
673
-    public function admin_notices()
674
-    {
675
-    }
676
-
677
-
678
-    /**
679
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
680
-     * this admin page group.
681
-     */
682
-    public function admin_footer_scripts()
683
-    {
684
-    }
685
-
686
-
687
-    /**
688
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
689
-     * warning (via EE_Error::add_error());
690
-     *
691
-     * @param EE_Event $event Event object
692
-     * @param string   $req_type
693
-     * @return void
694
-     * @throws EE_Error
695
-     * @throws ReflectionException
696
-     */
697
-    public function verify_event_edit($event = null, $req_type = '')
698
-    {
699
-        // don't need to do this when processing
700
-        if (! empty($req_type)) {
701
-            return;
702
-        }
703
-        // no event?
704
-        if (empty($event)) {
705
-            // set event
706
-            $event = $this->_cpt_model_obj;
707
-        }
708
-        // STILL no event?
709
-        if (! $event instanceof EE_Event) {
710
-            return;
711
-        }
712
-        $orig_status = $event->status();
713
-        // first check if event is active.
714
-        if (
715
-            $orig_status === EEM_Event::cancelled
716
-            || $orig_status === EEM_Event::postponed
717
-            || $event->is_expired()
718
-            || $event->is_inactive()
719
-        ) {
720
-            return;
721
-        }
722
-        // made it here so it IS active... next check that any of the tickets are sold.
723
-        if ($event->is_sold_out(true)) {
724
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
725
-                EE_Error::add_attention(
726
-                    sprintf(
727
-                        esc_html__(
728
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
729
-                            'event_espresso'
730
-                        ),
731
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
732
-                    )
733
-                );
734
-            }
735
-            return;
736
-        } elseif ($orig_status === EEM_Event::sold_out) {
737
-            EE_Error::add_attention(
738
-                sprintf(
739
-                    esc_html__(
740
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
741
-                        'event_espresso'
742
-                    ),
743
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
744
-                )
745
-            );
746
-        }
747
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
748
-        if (! $event->tickets_on_sale()) {
749
-            return;
750
-        }
751
-        // made it here so show warning
752
-        $this->_edit_event_warning();
753
-    }
754
-
755
-
756
-    /**
757
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
758
-     * When needed, hook this into a EE_Error::add_error() notice.
759
-     *
760
-     * @access protected
761
-     * @return void
762
-     */
763
-    protected function _edit_event_warning()
764
-    {
765
-        // we don't want to add warnings during these requests
766
-        if ($this->request->getRequestParam('action') === 'editpost') {
767
-            return;
768
-        }
769
-        EE_Error::add_attention(
770
-            sprintf(
771
-                esc_html__(
772
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
773
-                    'event_espresso'
774
-                ),
775
-                '<a class="espresso-help-tab-lnk">',
776
-                '</a>'
777
-            )
778
-        );
779
-    }
780
-
781
-
782
-    /**
783
-     * When a user is creating a new event, notify them if they haven't set their timezone.
784
-     * Otherwise, do the normal logic
785
-     *
786
-     * @return void
787
-     * @throws EE_Error
788
-     */
789
-    protected function _create_new_cpt_item()
790
-    {
791
-        $has_timezone_string = get_option('timezone_string');
792
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
793
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
794
-            EE_Error::add_attention(
795
-                sprintf(
796
-                    esc_html__(
797
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
798
-                        'event_espresso'
799
-                    ),
800
-                    '<br>',
801
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
802
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
803
-                    . '</select>',
804
-                    '<button class="button button-secondary timezone-submit">',
805
-                    '</button><span class="spinner"></span>'
806
-                ),
807
-                __FILE__,
808
-                __FUNCTION__,
809
-                __LINE__
810
-            );
811
-        }
812
-        parent::_create_new_cpt_item();
813
-    }
814
-
815
-
816
-    /**
817
-     * Sets the _views property for the default route in this admin page group.
818
-     */
819
-    protected function _set_list_table_views_default()
820
-    {
821
-        $this->_views = [
822
-            'all'   => [
823
-                'slug'        => 'all',
824
-                'label'       => esc_html__('View All Events', 'event_espresso'),
825
-                'count'       => 0,
826
-                'bulk_action' => [
827
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
828
-                ],
829
-            ],
830
-            'draft' => [
831
-                'slug'        => 'draft',
832
-                'label'       => esc_html__('Draft', 'event_espresso'),
833
-                'count'       => 0,
834
-                'bulk_action' => [
835
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
836
-                ],
837
-            ],
838
-        ];
839
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
840
-            $this->_views['trash'] = [
841
-                'slug'        => 'trash',
842
-                'label'       => esc_html__('Trash', 'event_espresso'),
843
-                'count'       => 0,
844
-                'bulk_action' => [
845
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
846
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
847
-                ],
848
-            ];
849
-        }
850
-    }
851
-
852
-
853
-    /**
854
-     * Provides the legend item array for the default list table view.
855
-     *
856
-     * @return array
857
-     * @throws EE_Error
858
-     * @throws EE_Error
859
-     */
860
-    protected function _event_legend_items()
861
-    {
862
-        $items    = [
863
-            'view_details'   => [
864
-                'class' => 'dashicons dashicons-search',
865
-                'desc'  => esc_html__('View Event', 'event_espresso'),
866
-            ],
867
-            'edit_event'     => [
868
-                'class' => 'ee-icon ee-icon-calendar-edit',
869
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
870
-            ],
871
-            'view_attendees' => [
872
-                'class' => 'dashicons dashicons-groups',
873
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
874
-            ],
875
-        ];
876
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
877
-        $statuses = [
878
-            'sold_out_status'  => [
879
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
880
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
881
-            ],
882
-            'active_status'    => [
883
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
884
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
885
-            ],
886
-            'upcoming_status'  => [
887
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
888
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
889
-            ],
890
-            'postponed_status' => [
891
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
892
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
893
-            ],
894
-            'cancelled_status' => [
895
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
896
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
897
-            ],
898
-            'expired_status'   => [
899
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
900
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
901
-            ],
902
-            'inactive_status'  => [
903
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
904
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
905
-            ],
906
-        ];
907
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
908
-        return array_merge($items, $statuses);
909
-    }
910
-
911
-
912
-    /**
913
-     * @return EEM_Event
914
-     * @throws EE_Error
915
-     * @throws ReflectionException
916
-     */
917
-    private function _event_model()
918
-    {
919
-        if (! $this->_event_model instanceof EEM_Event) {
920
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
921
-        }
922
-        return $this->_event_model;
923
-    }
924
-
925
-
926
-    /**
927
-     * Adds extra buttons to the WP CPT permalink field row.
928
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
929
-     *
930
-     * @param string $return    the current html
931
-     * @param int    $id        the post id for the page
932
-     * @param string $new_title What the title is
933
-     * @param string $new_slug  what the slug is
934
-     * @return string            The new html string for the permalink area
935
-     */
936
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
937
-    {
938
-        // make sure this is only when editing
939
-        if (! empty($id)) {
940
-            $post   = get_post($id);
941
-            $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
942
-                       . esc_html__('Shortcode', 'event_espresso')
943
-                       . '</a> ';
944
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
945
-                       . $post->ID
946
-                       . ']">';
947
-        }
948
-        return $return;
949
-    }
950
-
951
-
952
-    /**
953
-     * _events_overview_list_table
954
-     * This contains the logic for showing the events_overview list
955
-     *
956
-     * @access protected
957
-     * @return void
958
-     * @throws EE_Error
959
-     */
960
-    protected function _events_overview_list_table()
961
-    {
962
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
963
-        $this->_template_args['after_list_table']                           =
964
-            ! empty($this->_template_args['after_list_table'])
965
-                ? (array) $this->_template_args['after_list_table']
966
-                : [];
967
-        $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
968
-            . EEH_Template::get_button_or_link(
969
-                get_post_type_archive_link('espresso_events'),
970
-                esc_html__("View Event Archive Page", "event_espresso"),
971
-                'button'
972
-            );
973
-        $this->_template_args['after_list_table']['legend']                 = $this->_display_legend(
974
-            $this->_event_legend_items()
975
-        );
976
-        $this->_admin_page_title                                            .= ' ' . $this->get_action_link_or_button(
977
-            'create_new',
978
-            'add',
979
-            [],
980
-            'add-new-h2'
981
-        );
982
-        $this->display_admin_list_table_page_with_no_sidebar();
983
-    }
984
-
985
-
986
-    /**
987
-     * this allows for extra misc actions in the default WP publish box
988
-     *
989
-     * @return void
990
-     * @throws EE_Error
991
-     * @throws ReflectionException
992
-     */
993
-    public function extra_misc_actions_publish_box()
994
-    {
995
-        $this->_generate_publish_box_extra_content();
996
-    }
997
-
998
-
999
-    /**
1000
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1001
-     * saved.
1002
-     * Typically you would use this to save any additional data.
1003
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1004
-     * ALSO very important.  When a post transitions from scheduled to published,
1005
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1006
-     * other meta saves. So MAKE sure that you handle this accordingly.
1007
-     *
1008
-     * @access protected
1009
-     * @abstract
1010
-     * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1011
-     * @param object $post    The post object of the cpt that was saved.
1012
-     * @return void
1013
-     * @throws EE_Error
1014
-     * @throws ReflectionException
1015
-     */
1016
-    protected function _insert_update_cpt_item($post_id, $post)
1017
-    {
1018
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1019
-            // get out we're not processing an event save.
1020
-            return;
1021
-        }
1022
-
1023
-        $event_values = [
1024
-            'EVT_display_desc'                => $this->request->getRequestParam('display_desc', false, 'bool'),
1025
-            'EVT_display_ticket_selector'     => $this->request->getRequestParam(
1026
-                'display_ticket_selector',
1027
-                false,
1028
-                'bool'
1029
-            ),
1030
-            'EVT_additional_limit'            => min(
1031
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1032
-                $this->request->getRequestParam('additional_limit', null, 'int')
1033
-            ),
1034
-            'EVT_default_registration_status' => $this->request->getRequestParam(
1035
-                'EVT_default_registration_status',
1036
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1037
-            ),
1038
-
1039
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1040
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1041
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1042
-            'EVT_external_URL'    => $this->request->getRequestParam('externalURL'),
1043
-            'EVT_phone'           => $this->request->getRequestParam('event_phone'),
1044
-        ];
1045
-        // update event
1046
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1047
-        // get event_object for other metaboxes...
1048
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1049
-        // i have to setup where conditions to override the filters in the model
1050
-        // that filter out autodraft and inherit statuses so we GET the inherit id!
1051
-        $event = $this->_event_model()->get_one(
1052
-            [
1053
-                [
1054
-                    $this->_event_model()->primary_key_name() => $post_id,
1055
-                    'OR'                                      => [
1056
-                        'status'   => $post->post_status,
1057
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1058
-                        // but the returned object here has a status of "publish", so use the original post status as well
1059
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1060
-                    ],
1061
-                ],
1062
-            ]
1063
-        );
1064
-        // the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1065
-        $event_update_callbacks = apply_filters(
1066
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1067
-            [
1068
-                [$this, '_default_venue_update'],
1069
-                [$this, '_default_tickets_update'],
1070
-            ]
1071
-        );
1072
-        $att_success            = true;
1073
-        foreach ($event_update_callbacks as $e_callback) {
1074
-            $_success = is_callable($e_callback)
1075
-                ? call_user_func($e_callback, $event, $this->request->requestParams())
1076
-                : false;
1077
-            // if ANY of these updates fail then we want the appropriate global error message
1078
-            $att_success = ! $att_success ? $att_success : $_success;
1079
-        }
1080
-        // any errors?
1081
-        if ($success && false === $att_success) {
1082
-            EE_Error::add_error(
1083
-                esc_html__(
1084
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1085
-                    'event_espresso'
1086
-                ),
1087
-                __FILE__,
1088
-                __FUNCTION__,
1089
-                __LINE__
1090
-            );
1091
-        } elseif ($success === false) {
1092
-            EE_Error::add_error(
1093
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1094
-                __FILE__,
1095
-                __FUNCTION__,
1096
-                __LINE__
1097
-            );
1098
-        }
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * @param int $post_id
1104
-     * @param int $revision_id
1105
-     * @throws EE_Error
1106
-     * @throws EE_Error
1107
-     * @throws ReflectionException
1108
-     * @see parent::restore_item()
1109
-     */
1110
-    protected function _restore_cpt_item($post_id, $revision_id)
1111
-    {
1112
-        // copy existing event meta to new post
1113
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1114
-        if ($post_evt instanceof EE_Event) {
1115
-            // meta revision restore
1116
-            $post_evt->restore_revision($revision_id);
1117
-            // related objs restore
1118
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1119
-        }
1120
-    }
1121
-
1122
-
1123
-    /**
1124
-     * Attach the venue to the Event
1125
-     *
1126
-     * @param EE_Event $event Event Object to add the venue to
1127
-     * @param array    $data  The request data from the form
1128
-     * @return bool           Success or fail.
1129
-     * @throws EE_Error
1130
-     * @throws ReflectionException
1131
-     */
1132
-    protected function _default_venue_update(EE_Event $event, $data)
1133
-    {
1134
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1135
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1136
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1137
-        // very important.  If we don't have a venue name...
1138
-        // then we'll get out because not necessary to create empty venue
1139
-        if (empty($data['venue_title'])) {
1140
-            return false;
1141
-        }
1142
-        $venue_array = [
1143
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1144
-            'VNU_name'            => $data['venue_title'],
1145
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1146
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1147
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1148
-                ? $data['venue_short_description']
1149
-                : null,
1150
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1151
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1152
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1153
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1154
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1155
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1156
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1157
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1158
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1159
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1160
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1161
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1162
-            'status'              => 'publish',
1163
-        ];
1164
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1165
-        if (! empty($venue_id)) {
1166
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1167
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1168
-            // we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1169
-            $event->_add_relation_to($venue_id, 'Venue');
1170
-            return $rows_affected > 0;
1171
-        }
1172
-        // we insert the venue
1173
-        $venue_id = $venue_model->insert($venue_array);
1174
-        $event->_add_relation_to($venue_id, 'Venue');
1175
-        return ! empty($venue_id);
1176
-        // when we have the ancestor come in it's already been handled by the revision save.
1177
-    }
1178
-
1179
-
1180
-    /**
1181
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1182
-     *
1183
-     * @param EE_Event $event The Event object we're attaching data to
1184
-     * @param array    $data  The request data from the form
1185
-     * @return array
1186
-     * @throws EE_Error
1187
-     * @throws ReflectionException
1188
-     * @throws Exception
1189
-     */
1190
-    protected function _default_tickets_update(EE_Event $event, $data)
1191
-    {
1192
-        $datetime       = null;
1193
-        $saved_tickets  = [];
1194
-        $event_timezone = $event->get_timezone();
1195
-        $date_formats   = ['Y-m-d', 'h:i a'];
1196
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1197
-            // trim all values to ensure any excess whitespace is removed.
1198
-            $datetime_data                = array_map('trim', $datetime_data);
1199
-            $datetime_data['DTT_EVT_end'] =
1200
-                isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1201
-                    ? $datetime_data['DTT_EVT_end']
1202
-                    : $datetime_data['DTT_EVT_start'];
1203
-            $datetime_values              = [
1204
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1205
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1206
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1207
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1208
-                'DTT_order'     => $row,
1209
-            ];
1210
-            // if we have an id then let's get existing object first and then set the new values.
1211
-            //  Otherwise we instantiate a new object for save.
1212
-            if (! empty($datetime_data['DTT_ID'])) {
1213
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1214
-                if (! $datetime instanceof EE_Ticket) {
1215
-                    throw new RuntimeException(
1216
-                        sprintf(
1217
-                            esc_html__(
1218
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1219
-                                'event_espresso'
1220
-                            ),
1221
-                            $datetime_data['DTT_ID']
1222
-                        )
1223
-                    );
1224
-                }
1225
-                $datetime->set_date_format($date_formats[0]);
1226
-                $datetime->set_time_format($date_formats[1]);
1227
-                foreach ($datetime_values as $field => $value) {
1228
-                    $datetime->set($field, $value);
1229
-                }
1230
-            } else {
1231
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1232
-            }
1233
-            if (! $datetime instanceof EE_Datetime) {
1234
-                throw new RuntimeException(
1235
-                    sprintf(
1236
-                        esc_html__(
1237
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1238
-                            'event_espresso'
1239
-                        ),
1240
-                        print_r($datetime_values, true)
1241
-                    )
1242
-                );
1243
-            }
1244
-            // before going any further make sure our dates are setup correctly
1245
-            // so that the end date is always equal or greater than the start date.
1246
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1247
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1248
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1249
-            }
1250
-            $datetime->save();
1251
-            $event->_add_relation_to($datetime, 'Datetime');
1252
-        }
1253
-        // no datetimes get deleted so we don't do any of that logic here.
1254
-        // update tickets next
1255
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1256
-
1257
-        // set up some default start and end dates in case those are not present in the incoming data
1258
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1259
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1260
-        // use the start date of the first datetime for the end date
1261
-        $first_datetime   = $event->first_datetime();
1262
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1263
-
1264
-        // now process the incoming data
1265
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1266
-            $update_prices = false;
1267
-            $ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1268
-                ? $data['edit_prices'][ $row ][1]['PRC_amount']
1269
-                : 0;
1270
-            // trim inputs to ensure any excess whitespace is removed.
1271
-            $ticket_data   = array_map('trim', $ticket_data);
1272
-            $ticket_values = [
1273
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1274
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1275
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1276
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1277
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1278
-                    ? $ticket_data['TKT_start_date']
1279
-                    : $default_start_date,
1280
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1281
-                    ? $ticket_data['TKT_end_date']
1282
-                    : $default_end_date,
1283
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1284
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1285
-                    ? $ticket_data['TKT_qty']
1286
-                    : EE_INF,
1287
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1288
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1289
-                    ? $ticket_data['TKT_uses']
1290
-                    : EE_INF,
1291
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1292
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1293
-                'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1294
-                'TKT_price'       => $ticket_price,
1295
-                'TKT_row'         => $row,
1296
-            ];
1297
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1298
-            // which means in turn that the prices will become new prices as well.
1299
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1300
-                $ticket_values['TKT_ID']         = 0;
1301
-                $ticket_values['TKT_is_default'] = 0;
1302
-                $update_prices                   = true;
1303
-            }
1304
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1305
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1306
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1307
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1308
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1309
-            if (! empty($ticket_data['TKT_ID'])) {
1310
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1311
-                if (! $existing_ticket instanceof EE_Ticket) {
1312
-                    throw new RuntimeException(
1313
-                        sprintf(
1314
-                            esc_html__(
1315
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1316
-                                'event_espresso'
1317
-                            ),
1318
-                            $ticket_data['TKT_ID']
1319
-                        )
1320
-                    );
1321
-                }
1322
-                $ticket_sold = $existing_ticket->count_related(
1323
-                    'Registration',
1324
-                    [
1325
-                        [
1326
-                            'STS_ID' => [
1327
-                                'NOT IN',
1328
-                                [EEM_Registration::status_id_incomplete],
1329
-                            ],
1330
-                        ],
1331
-                    ]
1332
-                ) > 0;
1333
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1334
-                // if they are different then we create a new ticket (if $ticket_sold)
1335
-                // if they aren't different then we go ahead and modify existing ticket.
1336
-                $create_new_ticket = $ticket_sold
1337
-                                     && $ticket_price !== $existing_ticket->price()
1338
-                                     && ! $existing_ticket->deleted();
1339
-                $existing_ticket->set_date_format($date_formats[0]);
1340
-                $existing_ticket->set_time_format($date_formats[1]);
1341
-                // set new values
1342
-                foreach ($ticket_values as $field => $value) {
1343
-                    if ($field == 'TKT_qty') {
1344
-                        $existing_ticket->set_qty($value);
1345
-                    } elseif ($field == 'TKT_price') {
1346
-                        $existing_ticket->set('TKT_price', $ticket_price);
1347
-                    } else {
1348
-                        $existing_ticket->set($field, $value);
1349
-                    }
1350
-                }
1351
-                $ticket = $existing_ticket;
1352
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1353
-                //  Otherwise we have to create a new ticket.
1354
-                if ($create_new_ticket) {
1355
-                    // archive the old ticket first
1356
-                    $existing_ticket->set('TKT_deleted', 1);
1357
-                    $existing_ticket->save();
1358
-                    // make sure this ticket is still recorded in our $saved_tickets
1359
-                    // so we don't run it through the regular trash routine.
1360
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1361
-                    // create new ticket that's a copy of the existing except,
1362
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1363
-                    $new_ticket = clone $existing_ticket;
1364
-                    $new_ticket->set('TKT_ID', 0);
1365
-                    $new_ticket->set('TKT_deleted', 0);
1366
-                    $new_ticket->set('TKT_sold', 0);
1367
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1368
-                    $update_prices = true;
1369
-                    $ticket        = $new_ticket;
1370
-                }
1371
-            } else {
1372
-                // no TKT_id so a new ticket
1373
-                $ticket_values['TKT_price'] = $ticket_price;
1374
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1375
-                $update_prices              = true;
1376
-            }
1377
-            if (! $ticket instanceof EE_Ticket) {
1378
-                throw new RuntimeException(
1379
-                    sprintf(
1380
-                        esc_html__(
1381
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1382
-                            'event_espresso'
1383
-                        ),
1384
-                        print_r($ticket_values, true)
1385
-                    )
1386
-                );
1387
-            }
1388
-            // cap ticket qty by datetime reg limits
1389
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1390
-            // update ticket.
1391
-            $ticket->save();
1392
-            // before going any further make sure our dates are setup correctly
1393
-            // so that the end date is always equal or greater than the start date.
1394
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1395
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1396
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1397
-                $ticket->save();
1398
-            }
1399
-            // initially let's add the ticket to the datetime
1400
-            $datetime->_add_relation_to($ticket, 'Ticket');
1401
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1402
-            // add prices to ticket
1403
-            $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $ticket, $update_prices);
1404
-        }
1405
-        // however now we need to handle permanently deleting tickets via the ui.
1406
-        //  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1407
-        //  However, it does allow for deleting tickets that have no tickets sold,
1408
-        // in which case we want to get rid of permanently because there is no need to save in db.
1409
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] == '' ? [] : $old_tickets;
1410
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1411
-        foreach ($tickets_removed as $id) {
1412
-            $id = absint($id);
1413
-            // get the ticket for this id
1414
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1415
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1416
-                continue;
1417
-            }
1418
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1419
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1420
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1421
-            foreach ($related_datetimes as $related_datetime) {
1422
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1423
-            }
1424
-            // need to do the same for prices (except these prices can also be deleted because again,
1425
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1426
-            $ticket_to_remove->delete_related_permanently('Price');
1427
-            // finally let's delete this ticket
1428
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1429
-            $ticket_to_remove->delete_permanently();
1430
-        }
1431
-        return [$datetime, $saved_tickets];
1432
-    }
1433
-
1434
-
1435
-    /**
1436
-     * This attaches a list of given prices to a ticket.
1437
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1438
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1439
-     * price info and prices are automatically "archived" via the ticket.
1440
-     *
1441
-     * @access  private
1442
-     * @param array     $prices_data Array of prices from the form.
1443
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1444
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1445
-     * @return  void
1446
-     * @throws EE_Error
1447
-     * @throws ReflectionException
1448
-     */
1449
-    private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1450
-    {
1451
-        $timezone = $ticket->get_timezone();
1452
-        foreach ($prices_data as $row => $price_data) {
1453
-            $price_values = [
1454
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1455
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1456
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1457
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1458
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1459
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1460
-                'PRC_order'      => $row,
1461
-            ];
1462
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1463
-                $price_values['PRC_ID'] = 0;
1464
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1465
-            } else {
1466
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1467
-                // update this price with new values
1468
-                foreach ($price_values as $field => $new_price) {
1469
-                    $price->set($field, $new_price);
1470
-                }
1471
-            }
1472
-            if (! $price instanceof EE_Price) {
1473
-                throw new RuntimeException(
1474
-                    sprintf(
1475
-                        esc_html__(
1476
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1477
-                            'event_espresso'
1478
-                        ),
1479
-                        print_r($price_values, true)
1480
-                    )
1481
-                );
1482
-            }
1483
-            $price->save();
1484
-            $ticket->_add_relation_to($price, 'Price');
1485
-        }
1486
-    }
1487
-
1488
-
1489
-    /**
1490
-     * Add in our autosave ajax handlers
1491
-     *
1492
-     */
1493
-    protected function _ee_autosave_create_new()
1494
-    {
1495
-    }
1496
-
1497
-
1498
-    /**
1499
-     * More autosave handlers.
1500
-     */
1501
-    protected function _ee_autosave_edit()
1502
-    {
1503
-        // TEMPORARILY EXITING CAUSE THIS IS A TODO
1504
-    }
1505
-
1506
-
1507
-    /**
1508
-     * @throws EE_Error
1509
-     * @throws ReflectionException
1510
-     */
1511
-    private function _generate_publish_box_extra_content()
1512
-    {
1513
-        // load formatter helper
1514
-        // args for getting related registrations
1515
-        $approved_query_args        = [
1516
-            [
1517
-                'REG_deleted' => 0,
1518
-                'STS_ID'      => EEM_Registration::status_id_approved,
1519
-            ],
1520
-        ];
1521
-        $not_approved_query_args    = [
1522
-            [
1523
-                'REG_deleted' => 0,
1524
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1525
-            ],
1526
-        ];
1527
-        $pending_payment_query_args = [
1528
-            [
1529
-                'REG_deleted' => 0,
1530
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1531
-            ],
1532
-        ];
1533
-        // publish box
1534
-        $publish_box_extra_args = [
1535
-            'view_approved_reg_url'        => add_query_arg(
1536
-                [
1537
-                    'action'      => 'default',
1538
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1539
-                    '_reg_status' => EEM_Registration::status_id_approved,
1540
-                ],
1541
-                REG_ADMIN_URL
1542
-            ),
1543
-            'view_not_approved_reg_url'    => add_query_arg(
1544
-                [
1545
-                    'action'      => 'default',
1546
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1547
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1548
-                ],
1549
-                REG_ADMIN_URL
1550
-            ),
1551
-            'view_pending_payment_reg_url' => add_query_arg(
1552
-                [
1553
-                    'action'      => 'default',
1554
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1555
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1556
-                ],
1557
-                REG_ADMIN_URL
1558
-            ),
1559
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1560
-                'Registration',
1561
-                $approved_query_args
1562
-            ),
1563
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1564
-                'Registration',
1565
-                $not_approved_query_args
1566
-            ),
1567
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1568
-                'Registration',
1569
-                $pending_payment_query_args
1570
-            ),
1571
-            'misc_pub_section_class'       => apply_filters(
1572
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1573
-                'misc-pub-section'
1574
-            ),
1575
-        ];
1576
-        ob_start();
1577
-        do_action(
1578
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1579
-            $this->_cpt_model_obj
1580
-        );
1581
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1582
-        // load template
1583
-        EEH_Template::display_template(
1584
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1585
-            $publish_box_extra_args
1586
-        );
1587
-    }
1588
-
1589
-
1590
-    /**
1591
-     * @return EE_Event
1592
-     */
1593
-    public function get_event_object()
1594
-    {
1595
-        return $this->_cpt_model_obj;
1596
-    }
1597
-
1598
-
1599
-
1600
-
1601
-    /** METABOXES * */
1602
-    /**
1603
-     * _register_event_editor_meta_boxes
1604
-     * add all metaboxes related to the event_editor
1605
-     *
1606
-     * @return void
1607
-     * @throws EE_Error
1608
-     * @throws ReflectionException
1609
-     */
1610
-    protected function _register_event_editor_meta_boxes()
1611
-    {
1612
-        $this->verify_cpt_object();
1613
-        add_meta_box(
1614
-            'espresso_event_editor_tickets',
1615
-            esc_html__('Event Datetime & Ticket', 'event_espresso'),
1616
-            [$this, 'ticket_metabox'],
1617
-            $this->page_slug,
1618
-            'normal',
1619
-            'high'
1620
-        );
1621
-        add_meta_box(
1622
-            'espresso_event_editor_event_options',
1623
-            esc_html__('Event Registration Options', 'event_espresso'),
1624
-            [$this, 'registration_options_meta_box'],
1625
-            $this->page_slug,
1626
-            'side'
1627
-        );
1628
-        // NOTE: if you're looking for other metaboxes in here,
1629
-        // where a metabox has a related management page in the admin
1630
-        // you will find it setup in the related management page's "_Hooks" file.
1631
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1632
-    }
1633
-
1634
-
1635
-    /**
1636
-     * @throws DomainException
1637
-     * @throws EE_Error
1638
-     * @throws ReflectionException
1639
-     */
1640
-    public function ticket_metabox()
1641
-    {
1642
-        $existing_datetime_ids = $existing_ticket_ids = [];
1643
-        // defaults for template args
1644
-        $template_args = [
1645
-            'existing_datetime_ids'    => '',
1646
-            'event_datetime_help_link' => '',
1647
-            'ticket_options_help_link' => '',
1648
-            'time'                     => null,
1649
-            'ticket_rows'              => '',
1650
-            'existing_ticket_ids'      => '',
1651
-            'total_ticket_rows'        => 1,
1652
-            'ticket_js_structure'      => '',
1653
-            'trash_icon'               => 'ee-lock-icon',
1654
-            'disabled'                 => '',
1655
-        ];
1656
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1657
-        /**
1658
-         * 1. Start with retrieving Datetimes
1659
-         * 2. Fore each datetime get related tickets
1660
-         * 3. For each ticket get related prices
1661
-         */
1662
-        $times          = EEM_Datetime::instance()->get_all_event_dates($event_id);
1663
-        $first_datetime = reset($times);
1664
-        // do we get related tickets?
1665
-        if (
1666
-            $first_datetime instanceof EE_Datetime
1667
-            && $first_datetime->ID() !== 0
1668
-        ) {
1669
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1670
-            $template_args['time']   = $first_datetime;
1671
-            $related_tickets         = $first_datetime->tickets(
1672
-                [
1673
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1674
-                    'default_where_conditions' => 'none',
1675
-                ]
1676
-            );
1677
-            if (! empty($related_tickets)) {
1678
-                $template_args['total_ticket_rows'] = count($related_tickets);
1679
-                $row                                = 0;
1680
-                foreach ($related_tickets as $ticket) {
1681
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1682
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1683
-                    $row++;
1684
-                }
1685
-            } else {
1686
-                $template_args['total_ticket_rows'] = 1;
1687
-                /** @type EE_Ticket $ticket */
1688
-                $ticket                       = EEM_Ticket::instance()->create_default_object();
1689
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1690
-            }
1691
-        } else {
1692
-            $template_args['time']        = $times[0];
1693
-            $tickets                      = EEM_Ticket::instance()->get_all_default_tickets();
1694
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1695
-            // NOTE: we're just sending the first default row
1696
-            // (decaf can't manage default tickets so this should be sufficient);
1697
-        }
1698
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1699
-            'event_editor_event_datetimes_help_tab'
1700
-        );
1701
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1702
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1703
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1704
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1705
-            EEM_Ticket::instance()->create_default_object(),
1706
-            true
1707
-        );
1708
-        $template                                  = apply_filters(
1709
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1710
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1711
-        );
1712
-        EEH_Template::display_template($template, $template_args);
1713
-    }
1714
-
1715
-
1716
-    /**
1717
-     * Setup an individual ticket form for the decaf event editor page
1718
-     *
1719
-     * @access private
1720
-     * @param EE_Ticket $ticket   the ticket object
1721
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1722
-     * @param int       $row
1723
-     * @return string generated html for the ticket row.
1724
-     * @throws EE_Error
1725
-     * @throws ReflectionException
1726
-     */
1727
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1728
-    {
1729
-        $template_args = [
1730
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1731
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1732
-                : '',
1733
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1734
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1735
-            'TKT_name'            => $ticket->get('TKT_name'),
1736
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1737
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1738
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1739
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1740
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1741
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1742
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1743
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1744
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1745
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1746
-                : ' disabled=disabled',
1747
-        ];
1748
-        $price         = $ticket->ID() !== 0
1749
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1750
-            : null;
1751
-        $price         = $price instanceof EE_Price
1752
-            ? $price
1753
-            : EEM_Price::instance()->create_default_object();
1754
-        $price_args    = [
1755
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1756
-            'PRC_amount'            => $price->get('PRC_amount'),
1757
-            'PRT_ID'                => $price->get('PRT_ID'),
1758
-            'PRC_ID'                => $price->get('PRC_ID'),
1759
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1760
-        ];
1761
-        // make sure we have default start and end dates if skeleton
1762
-        // handle rows that should NOT be empty
1763
-        if (empty($template_args['TKT_start_date'])) {
1764
-            // if empty then the start date will be now.
1765
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1766
-        }
1767
-        if (empty($template_args['TKT_end_date'])) {
1768
-            // get the earliest datetime (if present);
1769
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1770
-                ? $this->_cpt_model_obj->get_first_related(
1771
-                    'Datetime',
1772
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1773
-                )
1774
-                : null;
1775
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1776
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1777
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1778
-        }
1779
-        $template_args = array_merge($template_args, $price_args);
1780
-        $template      = apply_filters(
1781
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1782
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1783
-            $ticket
1784
-        );
1785
-        return EEH_Template::display_template($template, $template_args, true);
1786
-    }
1787
-
1788
-
1789
-    /**
1790
-     * @throws EE_Error
1791
-     * @throws ReflectionException
1792
-     */
1793
-    public function registration_options_meta_box()
1794
-    {
1795
-        $yes_no_values             = [
1796
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1797
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1798
-        ];
1799
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1800
-            [
1801
-                EEM_Registration::status_id_cancelled,
1802
-                EEM_Registration::status_id_declined,
1803
-                EEM_Registration::status_id_incomplete,
1804
-            ],
1805
-            true
1806
-        );
1807
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1808
-        $template_args['_event']                          = $this->_cpt_model_obj;
1809
-        $template_args['event']                           = $this->_cpt_model_obj;
1810
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1811
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1812
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1813
-            'default_reg_status',
1814
-            $default_reg_status_values,
1815
-            $this->_cpt_model_obj->default_registration_status()
1816
-        );
1817
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1818
-            'display_desc',
1819
-            $yes_no_values,
1820
-            $this->_cpt_model_obj->display_description()
1821
-        );
1822
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1823
-            'display_ticket_selector',
1824
-            $yes_no_values,
1825
-            $this->_cpt_model_obj->display_ticket_selector(),
1826
-            '',
1827
-            '',
1828
-            false
1829
-        );
1830
-        $template_args['additional_registration_options'] = apply_filters(
1831
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1832
-            '',
1833
-            $template_args,
1834
-            $yes_no_values,
1835
-            $default_reg_status_values
1836
-        );
1837
-        EEH_Template::display_template(
1838
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1839
-            $template_args
1840
-        );
1841
-    }
1842
-
1843
-
1844
-    /**
1845
-     * _get_events()
1846
-     * This method simply returns all the events (for the given _view and paging)
1847
-     *
1848
-     * @access public
1849
-     * @param int  $per_page     count of items per page (20 default);
1850
-     * @param int  $current_page what is the current page being viewed.
1851
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1852
-     *                           If FALSE then we return an array of event objects
1853
-     *                           that match the given _view and paging parameters.
1854
-     * @return array|int         an array of event objects or a count of them.
1855
-     * @throws Exception
1856
-     */
1857
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1858
-    {
1859
-        $EEM_Event   = $this->_event_model();
1860
-        $offset      = ($current_page - 1) * $per_page;
1861
-        $limit       = $count ? null : $offset . ',' . $per_page;
1862
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1863
-        $order       = $this->request->getRequestParam('order', 'DESC');
1864
-        $month_range = $this->request->getRequestParam('month_range');
1865
-        if ($month_range) {
1866
-            $pieces = explode(' ', $month_range, 3);
1867
-            // simulate the FIRST day of the month, that fixes issues for months like February
1868
-            // where PHP doesn't know what to assume for date.
1869
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1870
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1871
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1872
-        }
1873
-        $where  = [];
1874
-        $status = $this->request->getRequestParam('status');
1875
-        // determine what post_status our condition will have for the query.
1876
-        switch ($status) {
1877
-            case 'month':
1878
-            case 'today':
1879
-            case null:
1880
-            case 'all':
1881
-                break;
1882
-            case 'draft':
1883
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1884
-                break;
1885
-            default:
1886
-                $where['status'] = $status;
1887
-        }
1888
-        // categories? The default for all categories is -1
1889
-        $category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1890
-        if ($category !== -1) {
1891
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1892
-            $where['Term_Taxonomy.term_id']  = $category;
1893
-        }
1894
-        // date where conditions
1895
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1896
-        if ($month_range) {
1897
-            $DateTime = new DateTime(
1898
-                $year_r . '-' . $month_r . '-01 00:00:00',
1899
-                new DateTimeZone('UTC')
1900
-            );
1901
-            $start    = $DateTime->getTimestamp();
1902
-            // set the datetime to be the end of the month
1903
-            $DateTime->setDate(
1904
-                $year_r,
1905
-                $month_r,
1906
-                $DateTime->format('t')
1907
-            )->setTime(23, 59, 59);
1908
-            $end                             = $DateTime->getTimestamp();
1909
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1910
-        } elseif ($status === 'today') {
1911
-            $DateTime                        =
1912
-                new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1913
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1914
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1915
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1916
-        } elseif ($status === 'month') {
1917
-            $now                             = date('Y-m-01');
1918
-            $DateTime                        =
1919
-                new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1920
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1921
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1922
-                                                        ->setTime(23, 59, 59)
1923
-                                                        ->format(implode(' ', $start_formats));
1924
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1925
-        }
1926
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1927
-            $where['EVT_wp_user'] = get_current_user_id();
1928
-        } else {
1929
-            if (! isset($where['status'])) {
1930
-                if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1931
-                    $where['OR'] = [
1932
-                        'status*restrict_private' => ['!=', 'private'],
1933
-                        'AND'                     => [
1934
-                            'status*inclusive' => ['=', 'private'],
1935
-                            'EVT_wp_user'      => get_current_user_id(),
1936
-                        ],
1937
-                    ];
1938
-                }
1939
-            }
1940
-        }
1941
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
1942
-        if (
1943
-            $wp_user
1944
-            && $wp_user !== get_current_user_id()
1945
-            && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1946
-        ) {
1947
-            $where['EVT_wp_user'] = $wp_user;
1948
-        }
1949
-        // search query handling
1950
-        $search_term = $this->request->getRequestParam('s');
1951
-        if ($search_term) {
1952
-            $search_term = '%' . $search_term . '%';
1953
-            $where['OR'] = [
1954
-                'EVT_name'       => ['LIKE', $search_term],
1955
-                'EVT_desc'       => ['LIKE', $search_term],
1956
-                'EVT_short_desc' => ['LIKE', $search_term],
1957
-            ];
1958
-        }
1959
-        // filter events by venue.
1960
-        $venue = $this->request->getRequestParam('venue', 0, 'int');
1961
-        if ($venue) {
1962
-            $where['Venue.VNU_ID'] = $venue;
1963
-        }
1964
-        $request_params = $this->request->requestParams();
1965
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
1966
-        $query_params   = apply_filters(
1967
-            'FHEE__Events_Admin_Page__get_events__query_params',
1968
-            [
1969
-                $where,
1970
-                'limit'    => $limit,
1971
-                'order_by' => $orderby,
1972
-                'order'    => $order,
1973
-                'group_by' => 'EVT_ID',
1974
-            ],
1975
-            $request_params
1976
-        );
1977
-
1978
-        // let's first check if we have special requests coming in.
1979
-        $active_status = $this->request->getRequestParam('active_status');
1980
-        if ($active_status) {
1981
-            switch ($active_status) {
1982
-                case 'upcoming':
1983
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
1984
-                case 'expired':
1985
-                    return $EEM_Event->get_expired_events($query_params, $count);
1986
-                case 'active':
1987
-                    return $EEM_Event->get_active_events($query_params, $count);
1988
-                case 'inactive':
1989
-                    return $EEM_Event->get_inactive_events($query_params, $count);
1990
-            }
1991
-        }
1992
-
1993
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
1994
-    }
1995
-
1996
-
1997
-    /**
1998
-     * handling for WordPress CPT actions (trash, restore, delete)
1999
-     *
2000
-     * @param string $post_id
2001
-     * @throws EE_Error
2002
-     * @throws ReflectionException
2003
-     */
2004
-    public function trash_cpt_item($post_id)
2005
-    {
2006
-        $this->request->setRequestParam('EVT_ID', $post_id);
2007
-        $this->_trash_or_restore_event('trash', false);
2008
-    }
2009
-
2010
-
2011
-    /**
2012
-     * @param string $post_id
2013
-     * @throws EE_Error
2014
-     * @throws ReflectionException
2015
-     */
2016
-    public function restore_cpt_item($post_id)
2017
-    {
2018
-        $this->request->setRequestParam('EVT_ID', $post_id);
2019
-        $this->_trash_or_restore_event('draft', false);
2020
-    }
2021
-
2022
-
2023
-    /**
2024
-     * @param string $post_id
2025
-     * @throws EE_Error
2026
-     * @throws EE_Error
2027
-     */
2028
-    public function delete_cpt_item($post_id)
2029
-    {
2030
-        throw new EE_Error(
2031
-            esc_html__(
2032
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2033
-                'event_espresso'
2034
-            )
2035
-        );
2036
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2037
-        // $this->_delete_event();
2038
-    }
2039
-
2040
-
2041
-    /**
2042
-     * _trash_or_restore_event
2043
-     *
2044
-     * @access protected
2045
-     * @param string $event_status
2046
-     * @param bool   $redirect_after
2047
-     * @throws EE_Error
2048
-     * @throws EE_Error
2049
-     * @throws ReflectionException
2050
-     */
2051
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2052
-    {
2053
-        // determine the event id and set to array.
2054
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2055
-        // loop thru events
2056
-        if ($EVT_ID) {
2057
-            // clean status
2058
-            $event_status = sanitize_key($event_status);
2059
-            // grab status
2060
-            if (! empty($event_status)) {
2061
-                $success = $this->_change_event_status($EVT_ID, $event_status);
2062
-            } else {
2063
-                $success = false;
2064
-                $msg     = esc_html__(
2065
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2066
-                    'event_espresso'
2067
-                );
2068
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2069
-            }
2070
-        } else {
2071
-            $success = false;
2072
-            $msg     = esc_html__(
2073
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2074
-                'event_espresso'
2075
-            );
2076
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2077
-        }
2078
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2079
-        if ($redirect_after) {
2080
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2081
-        }
2082
-    }
2083
-
2084
-
2085
-    /**
2086
-     * _trash_or_restore_events
2087
-     *
2088
-     * @access protected
2089
-     * @param string $event_status
2090
-     * @return void
2091
-     * @throws EE_Error
2092
-     * @throws EE_Error
2093
-     * @throws ReflectionException
2094
-     */
2095
-    protected function _trash_or_restore_events($event_status = 'trash')
2096
-    {
2097
-        // clean status
2098
-        $event_status = sanitize_key($event_status);
2099
-        // grab status
2100
-        if (! empty($event_status)) {
2101
-            $success = true;
2102
-            // determine the event id and set to array.
2103
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2104
-            // loop thru events
2105
-            foreach ($EVT_IDs as $EVT_ID) {
2106
-                if ($EVT_ID = absint($EVT_ID)) {
2107
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2108
-                    $success = $results !== false ? $success : false;
2109
-                } else {
2110
-                    $msg = sprintf(
2111
-                        esc_html__(
2112
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2113
-                            'event_espresso'
2114
-                        ),
2115
-                        $EVT_ID
2116
-                    );
2117
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2118
-                    $success = false;
2119
-                }
2120
-            }
2121
-        } else {
2122
-            $success = false;
2123
-            $msg     = esc_html__(
2124
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2125
-                'event_espresso'
2126
-            );
2127
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2128
-        }
2129
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2130
-        $success = $success ? 2 : false;
2131
-        $action  = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
2132
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2133
-    }
2134
-
2135
-
2136
-    /**
2137
-     * @param int    $EVT_ID
2138
-     * @param string $event_status
2139
-     * @return bool
2140
-     * @throws EE_Error
2141
-     * @throws ReflectionException
2142
-     */
2143
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2144
-    {
2145
-        // grab event id
2146
-        if (! $EVT_ID) {
2147
-            $msg = esc_html__(
2148
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2149
-                'event_espresso'
2150
-            );
2151
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2152
-            return false;
2153
-        }
2154
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2155
-        // clean status
2156
-        $event_status = sanitize_key($event_status);
2157
-        // grab status
2158
-        if (empty($event_status)) {
2159
-            $msg = esc_html__(
2160
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2161
-                'event_espresso'
2162
-            );
2163
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2164
-            return false;
2165
-        }
2166
-        // was event trashed or restored ?
2167
-        switch ($event_status) {
2168
-            case 'draft':
2169
-                $action = 'restored from the trash';
2170
-                $hook   = 'AHEE_event_restored_from_trash';
2171
-                break;
2172
-            case 'trash':
2173
-                $action = 'moved to the trash';
2174
-                $hook   = 'AHEE_event_moved_to_trash';
2175
-                break;
2176
-            default:
2177
-                $action = 'updated';
2178
-                $hook   = false;
2179
-        }
2180
-        // use class to change status
2181
-        $this->_cpt_model_obj->set_status($event_status);
2182
-        $success = $this->_cpt_model_obj->save();
2183
-        if (! $success) {
2184
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2185
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2186
-            return false;
2187
-        }
2188
-        if ($hook) {
2189
-            do_action($hook);
2190
-        }
2191
-        return true;
2192
-    }
2193
-
2194
-
2195
-    /**
2196
-     * @param array $event_ids
2197
-     * @return array
2198
-     * @since   4.10.23.p
2199
-     */
2200
-    private function cleanEventIds(array $event_ids)
2201
-    {
2202
-        return array_map('absint', $event_ids);
2203
-    }
2204
-
2205
-
2206
-    /**
2207
-     * @return array
2208
-     * @since   4.10.23.p
2209
-     */
2210
-    private function getEventIdsFromRequest()
2211
-    {
2212
-        return $this->request->getRequestParam('EVT_IDs', [], 'int', true, ',');
2213
-    }
2214
-
2215
-
2216
-    /**
2217
-     * @param bool $preview_delete
2218
-     * @throws EE_Error
2219
-     */
2220
-    protected function _delete_event($preview_delete = true)
2221
-    {
2222
-        $this->_delete_events($preview_delete);
2223
-    }
2224
-
2225
-
2226
-    /**
2227
-     * Gets the tree traversal batch persister.
2228
-     *
2229
-     * @return NodeGroupDao
2230
-     * @throws InvalidArgumentException
2231
-     * @throws InvalidDataTypeException
2232
-     * @throws InvalidInterfaceException
2233
-     * @since 4.10.12.p
2234
-     */
2235
-    protected function getModelObjNodeGroupPersister()
2236
-    {
2237
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2238
-            $this->model_obj_node_group_persister =
2239
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2240
-        }
2241
-        return $this->model_obj_node_group_persister;
2242
-    }
2243
-
2244
-
2245
-    /**
2246
-     * @param bool $preview_delete
2247
-     * @return void
2248
-     * @throws EE_Error
2249
-     */
2250
-    protected function _delete_events($preview_delete = true)
2251
-    {
2252
-        $event_ids = $this->getEventIdsFromRequest();
2253
-        if ($preview_delete) {
2254
-            $this->generateDeletionPreview($event_ids);
2255
-        } else {
2256
-            EEM_Event::instance()->delete_permanently([['EVT_ID' => ['IN', $event_ids]]]);
2257
-        }
2258
-    }
2259
-
2260
-
2261
-    /**
2262
-     * @param array $event_ids
2263
-     */
2264
-    protected function generateDeletionPreview(array $event_ids)
2265
-    {
2266
-        $event_ids = $this->cleanEventIds($event_ids);
2267
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2268
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2269
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2270
-            [
2271
-                'action'            => 'preview_deletion',
2272
-                'deletion_job_code' => $deletion_job_code,
2273
-            ],
2274
-            $this->_admin_base_url
2275
-        );
2276
-        EEH_URL::safeRedirectAndExit(
2277
-            EE_Admin_Page::add_query_args_and_nonce(
2278
-                [
2279
-                    'page'              => 'espresso_batch',
2280
-                    'batch'             => EED_Batch::batch_job,
2281
-                    'EVT_IDs'           => $event_ids,
2282
-                    'deletion_job_code' => $deletion_job_code,
2283
-                    'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2284
-                    'return_url'        => urlencode($return_url),
2285
-                ],
2286
-                admin_url()
2287
-            )
2288
-        );
2289
-    }
2290
-
2291
-
2292
-    /**
2293
-     * Checks for a POST submission
2294
-     *
2295
-     * @since 4.10.12.p
2296
-     */
2297
-    protected function confirmDeletion()
2298
-    {
2299
-        $deletion_redirect_logic =
2300
-            $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion');
2301
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2302
-    }
2303
-
2304
-
2305
-    /**
2306
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2307
-     *
2308
-     * @throws EE_Error
2309
-     * @since 4.10.12.p
2310
-     */
2311
-    protected function previewDeletion()
2312
-    {
2313
-        $preview_deletion_logic =
2314
-            $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion');
2315
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2316
-        $this->display_admin_page_with_no_sidebar();
2317
-    }
2318
-
2319
-
2320
-    /**
2321
-     * get total number of events
2322
-     *
2323
-     * @access public
2324
-     * @return int
2325
-     * @throws EE_Error
2326
-     * @throws EE_Error
2327
-     */
2328
-    public function total_events()
2329
-    {
2330
-        return EEM_Event::instance()->count(
2331
-            ['caps' => 'read_admin'],
2332
-            'EVT_ID',
2333
-            true
2334
-        );
2335
-    }
2336
-
2337
-
2338
-    /**
2339
-     * get total number of draft events
2340
-     *
2341
-     * @access public
2342
-     * @return int
2343
-     * @throws EE_Error
2344
-     * @throws EE_Error
2345
-     */
2346
-    public function total_events_draft()
2347
-    {
2348
-        return EEM_Event::instance()->count(
2349
-            [
2350
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2351
-                'caps' => 'read_admin',
2352
-            ],
2353
-            'EVT_ID',
2354
-            true
2355
-        );
2356
-    }
2357
-
2358
-
2359
-    /**
2360
-     * get total number of trashed events
2361
-     *
2362
-     * @access public
2363
-     * @return int
2364
-     * @throws EE_Error
2365
-     * @throws EE_Error
2366
-     */
2367
-    public function total_trashed_events()
2368
-    {
2369
-        return EEM_Event::instance()->count(
2370
-            [
2371
-                ['status' => 'trash'],
2372
-                'caps' => 'read_admin',
2373
-            ],
2374
-            'EVT_ID',
2375
-            true
2376
-        );
2377
-    }
2378
-
2379
-
2380
-    /**
2381
-     *    _default_event_settings
2382
-     *    This generates the Default Settings Tab
2383
-     *
2384
-     * @return void
2385
-     * @throws EE_Error
2386
-     */
2387
-    protected function _default_event_settings()
2388
-    {
2389
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2390
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2391
-        $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2392
-        $this->display_admin_page_with_sidebar();
2393
-    }
2394
-
2395
-
2396
-    /**
2397
-     * Return the form for event settings.
2398
-     *
2399
-     * @return EE_Form_Section_Proper
2400
-     * @throws EE_Error
2401
-     */
2402
-    protected function _default_event_settings_form()
2403
-    {
2404
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2405
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2406
-        // exclude
2407
-            [
2408
-                EEM_Registration::status_id_cancelled,
2409
-                EEM_Registration::status_id_declined,
2410
-                EEM_Registration::status_id_incomplete,
2411
-                EEM_Registration::status_id_wait_list,
2412
-            ],
2413
-            true
2414
-        );
2415
-        return new EE_Form_Section_Proper(
2416
-            [
2417
-                'name'            => 'update_default_event_settings',
2418
-                'html_id'         => 'update_default_event_settings',
2419
-                'html_class'      => 'form-table',
2420
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2421
-                'subsections'     => apply_filters(
2422
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2423
-                    [
2424
-                        'default_reg_status'  => new EE_Select_Input(
2425
-                            $registration_stati_for_selection,
2426
-                            [
2427
-                                'default'         => isset($registration_config->default_STS_ID)
2428
-                                                     && array_key_exists(
2429
-                                                         $registration_config->default_STS_ID,
2430
-                                                         $registration_stati_for_selection
2431
-                                                     )
2432
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2433
-                                    : EEM_Registration::status_id_pending_payment,
2434
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2435
-                                                     . EEH_Template::get_help_tab_link(
2436
-                                                         'default_settings_status_help_tab'
2437
-                                                     ),
2438
-                                'html_help_text'  => esc_html__(
2439
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2440
-                                    'event_espresso'
2441
-                                ),
2442
-                            ]
2443
-                        ),
2444
-                        'default_max_tickets' => new EE_Integer_Input(
2445
-                            [
2446
-                                'default'         => isset($registration_config->default_maximum_number_of_tickets)
2447
-                                    ? $registration_config->default_maximum_number_of_tickets
2448
-                                    : EEM_Event::get_default_additional_limit(),
2449
-                                'html_label_text' => esc_html__(
2450
-                                    'Default Maximum Tickets Allowed Per Order:',
2451
-                                    'event_espresso'
2452
-                                )
2453
-                                . EEH_Template::get_help_tab_link(
2454
-                                    'default_maximum_tickets_help_tab"'
2455
-                                ),
2456
-                                'html_help_text'  => esc_html__(
2457
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2458
-                                    'event_espresso'
2459
-                                ),
2460
-                            ]
2461
-                        ),
2462
-                    ]
2463
-                ),
2464
-            ]
2465
-        );
2466
-    }
2467
-
2468
-
2469
-    /**
2470
-     * _update_default_event_settings
2471
-     *
2472
-     * @access protected
2473
-     * @return void
2474
-     * @throws EE_Error
2475
-     */
2476
-    protected function _update_default_event_settings()
2477
-    {
2478
-        $registration_config = EE_Registry::instance()->CFG->registration;
2479
-        $form                = $this->_default_event_settings_form();
2480
-        if ($form->was_submitted()) {
2481
-            $form->receive_form_submission();
2482
-            if ($form->is_valid()) {
2483
-                $valid_data = $form->valid_data();
2484
-                if (isset($valid_data['default_reg_status'])) {
2485
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2486
-                }
2487
-                if (isset($valid_data['default_max_tickets'])) {
2488
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2489
-                }
2490
-                // update because data was valid!
2491
-                EE_Registry::instance()->CFG->update_espresso_config();
2492
-                EE_Error::overwrite_success();
2493
-                EE_Error::add_success(
2494
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2495
-                );
2496
-            }
2497
-        }
2498
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2499
-    }
2500
-
2501
-
2502
-    /*************        Templates        *************
2503
-     *
2504
-     * @throws EE_Error
2505
-     */
2506
-    protected function _template_settings()
2507
-    {
2508
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2509
-        $this->_template_args['preview_img']  = '<img src="'
2510
-                                                . EVENTS_ASSETS_URL
2511
-                                                . '/images/'
2512
-                                                . 'caffeinated_template_features.jpg" alt="'
2513
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2514
-                                                . '" />';
2515
-        $this->_template_args['preview_text'] = '<strong>'
2516
-                                                . esc_html__(
2517
-                                                    'Template Settings 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. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2518
-                                                    'event_espresso'
2519
-                                                ) . '</strong>';
2520
-        $this->display_admin_caf_preview_page('template_settings_tab');
2521
-    }
2522
-
2523
-
2524
-    /** Event Category Stuff **/
2525
-    /**
2526
-     * set the _category property with the category object for the loaded page.
2527
-     *
2528
-     * @access private
2529
-     * @return void
2530
-     */
2531
-    private function _set_category_object()
2532
-    {
2533
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2534
-            return;
2535
-        } //already have the category object so get out.
2536
-        // set default category object
2537
-        $this->_set_empty_category_object();
2538
-        // only set if we've got an id
2539
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2540
-        if (! $category_ID) {
2541
-            return;
2542
-        }
2543
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2544
-        if (! empty($term)) {
2545
-            $this->_category->category_name       = $term->name;
2546
-            $this->_category->category_identifier = $term->slug;
2547
-            $this->_category->category_desc       = $term->description;
2548
-            $this->_category->id                  = $term->term_id;
2549
-            $this->_category->parent              = $term->parent;
2550
-        }
2551
-    }
2552
-
2553
-
2554
-    /**
2555
-     * Clears out category properties.
2556
-     */
2557
-    private function _set_empty_category_object()
2558
-    {
2559
-        $this->_category                = new stdClass();
2560
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2561
-        $this->_category->id            = $this->_category->parent = 0;
2562
-    }
2563
-
2564
-
2565
-    /**
2566
-     * @throws EE_Error
2567
-     */
2568
-    protected function _category_list_table()
2569
-    {
2570
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2571
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2572
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2573
-            'add_category',
2574
-            'add_category',
2575
-            [],
2576
-            'add-new-h2'
2577
-        );
2578
-        $this->display_admin_list_table_page_with_sidebar();
2579
-    }
2580
-
2581
-
2582
-    /**
2583
-     * Output category details view.
2584
-     *
2585
-     * @throws EE_Error
2586
-     * @throws EE_Error
2587
-     */
2588
-    protected function _category_details($view)
2589
-    {
2590
-        // load formatter helper
2591
-        // load field generator helper
2592
-        $route = $view == 'edit' ? 'update_category' : 'insert_category';
2593
-        $this->_set_add_edit_form_tags($route);
2594
-        $this->_set_category_object();
2595
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2596
-        $delete_action = 'delete_category';
2597
-        // custom redirect
2598
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2599
-            ['action' => 'category_list'],
2600
-            $this->_admin_base_url
2601
-        );
2602
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2603
-        // take care of contents
2604
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2605
-        $this->display_admin_page_with_sidebar();
2606
-    }
2607
-
2608
-
2609
-    /**
2610
-     * Output category details content.
2611
-     */
2612
-    protected function _category_details_content()
2613
-    {
2614
-        $editor_args['category_desc'] = [
2615
-            'type'          => 'wp_editor',
2616
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2617
-            'class'         => 'my_editor_custom',
2618
-            'wpeditor_args' => ['media_buttons' => false],
2619
-        ];
2620
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2621
-        $all_terms                    = get_terms(
2622
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2623
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2624
-        );
2625
-        // setup category select for term parents.
2626
-        $category_select_values[] = [
2627
-            'text' => esc_html__('No Parent', 'event_espresso'),
2628
-            'id'   => 0,
2629
-        ];
2630
-        foreach ($all_terms as $term) {
2631
-            $category_select_values[] = [
2632
-                'text' => $term->name,
2633
-                'id'   => $term->term_id,
2634
-            ];
2635
-        }
2636
-        $category_select = EEH_Form_Fields::select_input(
2637
-            'category_parent',
2638
-            $category_select_values,
2639
-            $this->_category->parent
2640
-        );
2641
-        $template_args   = [
2642
-            'category'                 => $this->_category,
2643
-            'category_select'          => $category_select,
2644
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2645
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2646
-            'disable'                  => '',
2647
-            'disabled_message'         => false,
2648
-        ];
2649
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2650
-        return EEH_Template::display_template($template, $template_args, true);
2651
-    }
2652
-
2653
-
2654
-    /**
2655
-     * Handles deleting categories.
2656
-     *
2657
-     * @throws EE_Error
2658
-     */
2659
-    protected function _delete_categories()
2660
-    {
2661
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2662
-        foreach ($category_IDs as $category_ID) {
2663
-            $this->_delete_category($category_ID);
2664
-        }
2665
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2666
-        $query_args = [
2667
-            'action' => 'category_list',
2668
-        ];
2669
-        $this->_redirect_after_action(0, '', '', $query_args);
2670
-    }
2671
-
2672
-
2673
-    /**
2674
-     * Handles deleting specific category.
2675
-     *
2676
-     * @param int $cat_id
2677
-     */
2678
-    protected function _delete_category($cat_id)
2679
-    {
2680
-        $cat_id = absint($cat_id);
2681
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2682
-    }
2683
-
2684
-
2685
-    /**
2686
-     * Handles triggering the update or insertion of a new category.
2687
-     *
2688
-     * @param bool $new_category true means we're triggering the insert of a new category.
2689
-     * @throws EE_Error
2690
-     * @throws EE_Error
2691
-     */
2692
-    protected function _insert_or_update_category($new_category)
2693
-    {
2694
-        $cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2695
-        $success = 0; // we already have a success message so lets not send another.
2696
-        if ($cat_id) {
2697
-            $query_args = [
2698
-                'action'     => 'edit_category',
2699
-                'EVT_CAT_ID' => $cat_id,
2700
-            ];
2701
-        } else {
2702
-            $query_args = ['action' => 'add_category'];
2703
-        }
2704
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2705
-    }
2706
-
2707
-
2708
-    /**
2709
-     * Inserts or updates category
2710
-     *
2711
-     * @param bool $update (true indicates we're updating a category).
2712
-     * @return bool|mixed|string
2713
-     */
2714
-    private function _insert_category($update = false)
2715
-    {
2716
-        $category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2717
-        $category_name       = $this->request->getRequestParam('category_name', '');
2718
-        $category_desc       = $this->request->getRequestParam('category_desc', '');
2719
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2720
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2721
-
2722
-        if (empty($category_name)) {
2723
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2724
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2725
-            return false;
2726
-        }
2727
-        $term_args = [
2728
-            'name'        => $category_name,
2729
-            'description' => $category_desc,
2730
-            'parent'      => $category_parent,
2731
-        ];
2732
-        // was the category_identifier input disabled?
2733
-        if ($category_identifier) {
2734
-            $term_args['slug'] = $category_identifier;
2735
-        }
2736
-        $insert_ids = $update
2737
-            ? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2738
-            : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2739
-        if (! is_array($insert_ids)) {
2740
-            $msg = esc_html__(
2741
-                'An error occurred and the category has not been saved to the database.',
2742
-                'event_espresso'
2743
-            );
2744
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2745
-        } else {
2746
-            $category_ID = $insert_ids['term_id'];
2747
-            $msg         =
2748
-                sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2749
-            EE_Error::add_success($msg);
2750
-        }
2751
-        return $category_ID;
2752
-    }
2753
-
2754
-
2755
-    /**
2756
-     * Gets categories or count of categories matching the arguments in the request.
2757
-     *
2758
-     * @param int  $per_page
2759
-     * @param int  $current_page
2760
-     * @param bool $count
2761
-     * @return EE_Term_Taxonomy[]|int
2762
-     * @throws EE_Error
2763
-     * @throws EE_Error
2764
-     */
2765
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2766
-    {
2767
-        // testing term stuff
2768
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2769
-        $order       = $this->request->getRequestParam('order', 'DESC');
2770
-        $limit       = ($current_page - 1) * $per_page;
2771
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2772
-        $search_term = $this->request->getRequestParam('s');
2773
-        if ($search_term) {
2774
-            $search_term = '%' . $search_term . '%';
2775
-            $where['OR'] = [
2776
-                'Term.name'   => ['LIKE', $search_term],
2777
-                'description' => ['LIKE', $search_term],
2778
-            ];
2779
-        }
2780
-        $query_params = [
2781
-            $where,
2782
-            'order_by'   => [$orderby => $order],
2783
-            'limit'      => $limit . ',' . $per_page,
2784
-            'force_join' => ['Term'],
2785
-        ];
2786
-        return $count
2787
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2788
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2789
-    }
2790
-
2791
-    /* end category stuff */
2792
-    /**************/
2793
-
2794
-
2795
-    /**
2796
-     * Callback for the `ee_save_timezone_setting` ajax action.
2797
-     *
2798
-     * @throws EE_Error
2799
-     */
2800
-    public function saveTimezoneString()
2801
-    {
2802
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2803
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2804
-            EE_Error::add_error(
2805
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2806
-                __FILE__,
2807
-                __FUNCTION__,
2808
-                __LINE__
2809
-            );
2810
-            $this->_template_args['error'] = true;
2811
-            $this->_return_json();
2812
-        }
2813
-
2814
-        update_option('timezone_string', $timezone_string);
2815
-        EE_Error::add_success(
2816
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2817
-        );
2818
-        $this->_template_args['success'] = true;
2819
-        $this->_return_json(true, ['action' => 'create_new']);
2820
-    }
2821
-
2822
-
2823
-    /**
2824 2504
      * @throws EE_Error
2825
-     * @deprecated 4.10.25.p
2826 2505
      */
2827
-    public function save_timezonestring_setting()
2828
-    {
2829
-        $this->saveTimezoneString();
2830
-    }
2506
+	protected function _template_settings()
2507
+	{
2508
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2509
+		$this->_template_args['preview_img']  = '<img src="'
2510
+												. EVENTS_ASSETS_URL
2511
+												. '/images/'
2512
+												. 'caffeinated_template_features.jpg" alt="'
2513
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2514
+												. '" />';
2515
+		$this->_template_args['preview_text'] = '<strong>'
2516
+												. esc_html__(
2517
+													'Template Settings 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. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2518
+													'event_espresso'
2519
+												) . '</strong>';
2520
+		$this->display_admin_caf_preview_page('template_settings_tab');
2521
+	}
2522
+
2523
+
2524
+	/** Event Category Stuff **/
2525
+	/**
2526
+	 * set the _category property with the category object for the loaded page.
2527
+	 *
2528
+	 * @access private
2529
+	 * @return void
2530
+	 */
2531
+	private function _set_category_object()
2532
+	{
2533
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2534
+			return;
2535
+		} //already have the category object so get out.
2536
+		// set default category object
2537
+		$this->_set_empty_category_object();
2538
+		// only set if we've got an id
2539
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2540
+		if (! $category_ID) {
2541
+			return;
2542
+		}
2543
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2544
+		if (! empty($term)) {
2545
+			$this->_category->category_name       = $term->name;
2546
+			$this->_category->category_identifier = $term->slug;
2547
+			$this->_category->category_desc       = $term->description;
2548
+			$this->_category->id                  = $term->term_id;
2549
+			$this->_category->parent              = $term->parent;
2550
+		}
2551
+	}
2552
+
2553
+
2554
+	/**
2555
+	 * Clears out category properties.
2556
+	 */
2557
+	private function _set_empty_category_object()
2558
+	{
2559
+		$this->_category                = new stdClass();
2560
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2561
+		$this->_category->id            = $this->_category->parent = 0;
2562
+	}
2563
+
2564
+
2565
+	/**
2566
+	 * @throws EE_Error
2567
+	 */
2568
+	protected function _category_list_table()
2569
+	{
2570
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2571
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2572
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2573
+			'add_category',
2574
+			'add_category',
2575
+			[],
2576
+			'add-new-h2'
2577
+		);
2578
+		$this->display_admin_list_table_page_with_sidebar();
2579
+	}
2580
+
2581
+
2582
+	/**
2583
+	 * Output category details view.
2584
+	 *
2585
+	 * @throws EE_Error
2586
+	 * @throws EE_Error
2587
+	 */
2588
+	protected function _category_details($view)
2589
+	{
2590
+		// load formatter helper
2591
+		// load field generator helper
2592
+		$route = $view == 'edit' ? 'update_category' : 'insert_category';
2593
+		$this->_set_add_edit_form_tags($route);
2594
+		$this->_set_category_object();
2595
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2596
+		$delete_action = 'delete_category';
2597
+		// custom redirect
2598
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2599
+			['action' => 'category_list'],
2600
+			$this->_admin_base_url
2601
+		);
2602
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2603
+		// take care of contents
2604
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2605
+		$this->display_admin_page_with_sidebar();
2606
+	}
2607
+
2608
+
2609
+	/**
2610
+	 * Output category details content.
2611
+	 */
2612
+	protected function _category_details_content()
2613
+	{
2614
+		$editor_args['category_desc'] = [
2615
+			'type'          => 'wp_editor',
2616
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2617
+			'class'         => 'my_editor_custom',
2618
+			'wpeditor_args' => ['media_buttons' => false],
2619
+		];
2620
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2621
+		$all_terms                    = get_terms(
2622
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2623
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2624
+		);
2625
+		// setup category select for term parents.
2626
+		$category_select_values[] = [
2627
+			'text' => esc_html__('No Parent', 'event_espresso'),
2628
+			'id'   => 0,
2629
+		];
2630
+		foreach ($all_terms as $term) {
2631
+			$category_select_values[] = [
2632
+				'text' => $term->name,
2633
+				'id'   => $term->term_id,
2634
+			];
2635
+		}
2636
+		$category_select = EEH_Form_Fields::select_input(
2637
+			'category_parent',
2638
+			$category_select_values,
2639
+			$this->_category->parent
2640
+		);
2641
+		$template_args   = [
2642
+			'category'                 => $this->_category,
2643
+			'category_select'          => $category_select,
2644
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2645
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2646
+			'disable'                  => '',
2647
+			'disabled_message'         => false,
2648
+		];
2649
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2650
+		return EEH_Template::display_template($template, $template_args, true);
2651
+	}
2652
+
2653
+
2654
+	/**
2655
+	 * Handles deleting categories.
2656
+	 *
2657
+	 * @throws EE_Error
2658
+	 */
2659
+	protected function _delete_categories()
2660
+	{
2661
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2662
+		foreach ($category_IDs as $category_ID) {
2663
+			$this->_delete_category($category_ID);
2664
+		}
2665
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2666
+		$query_args = [
2667
+			'action' => 'category_list',
2668
+		];
2669
+		$this->_redirect_after_action(0, '', '', $query_args);
2670
+	}
2671
+
2672
+
2673
+	/**
2674
+	 * Handles deleting specific category.
2675
+	 *
2676
+	 * @param int $cat_id
2677
+	 */
2678
+	protected function _delete_category($cat_id)
2679
+	{
2680
+		$cat_id = absint($cat_id);
2681
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2682
+	}
2683
+
2684
+
2685
+	/**
2686
+	 * Handles triggering the update or insertion of a new category.
2687
+	 *
2688
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2689
+	 * @throws EE_Error
2690
+	 * @throws EE_Error
2691
+	 */
2692
+	protected function _insert_or_update_category($new_category)
2693
+	{
2694
+		$cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2695
+		$success = 0; // we already have a success message so lets not send another.
2696
+		if ($cat_id) {
2697
+			$query_args = [
2698
+				'action'     => 'edit_category',
2699
+				'EVT_CAT_ID' => $cat_id,
2700
+			];
2701
+		} else {
2702
+			$query_args = ['action' => 'add_category'];
2703
+		}
2704
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2705
+	}
2706
+
2707
+
2708
+	/**
2709
+	 * Inserts or updates category
2710
+	 *
2711
+	 * @param bool $update (true indicates we're updating a category).
2712
+	 * @return bool|mixed|string
2713
+	 */
2714
+	private function _insert_category($update = false)
2715
+	{
2716
+		$category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2717
+		$category_name       = $this->request->getRequestParam('category_name', '');
2718
+		$category_desc       = $this->request->getRequestParam('category_desc', '');
2719
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2720
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2721
+
2722
+		if (empty($category_name)) {
2723
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2724
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2725
+			return false;
2726
+		}
2727
+		$term_args = [
2728
+			'name'        => $category_name,
2729
+			'description' => $category_desc,
2730
+			'parent'      => $category_parent,
2731
+		];
2732
+		// was the category_identifier input disabled?
2733
+		if ($category_identifier) {
2734
+			$term_args['slug'] = $category_identifier;
2735
+		}
2736
+		$insert_ids = $update
2737
+			? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2738
+			: wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2739
+		if (! is_array($insert_ids)) {
2740
+			$msg = esc_html__(
2741
+				'An error occurred and the category has not been saved to the database.',
2742
+				'event_espresso'
2743
+			);
2744
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2745
+		} else {
2746
+			$category_ID = $insert_ids['term_id'];
2747
+			$msg         =
2748
+				sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2749
+			EE_Error::add_success($msg);
2750
+		}
2751
+		return $category_ID;
2752
+	}
2753
+
2754
+
2755
+	/**
2756
+	 * Gets categories or count of categories matching the arguments in the request.
2757
+	 *
2758
+	 * @param int  $per_page
2759
+	 * @param int  $current_page
2760
+	 * @param bool $count
2761
+	 * @return EE_Term_Taxonomy[]|int
2762
+	 * @throws EE_Error
2763
+	 * @throws EE_Error
2764
+	 */
2765
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2766
+	{
2767
+		// testing term stuff
2768
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2769
+		$order       = $this->request->getRequestParam('order', 'DESC');
2770
+		$limit       = ($current_page - 1) * $per_page;
2771
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2772
+		$search_term = $this->request->getRequestParam('s');
2773
+		if ($search_term) {
2774
+			$search_term = '%' . $search_term . '%';
2775
+			$where['OR'] = [
2776
+				'Term.name'   => ['LIKE', $search_term],
2777
+				'description' => ['LIKE', $search_term],
2778
+			];
2779
+		}
2780
+		$query_params = [
2781
+			$where,
2782
+			'order_by'   => [$orderby => $order],
2783
+			'limit'      => $limit . ',' . $per_page,
2784
+			'force_join' => ['Term'],
2785
+		];
2786
+		return $count
2787
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2788
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2789
+	}
2790
+
2791
+	/* end category stuff */
2792
+	/**************/
2793
+
2794
+
2795
+	/**
2796
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2797
+	 *
2798
+	 * @throws EE_Error
2799
+	 */
2800
+	public function saveTimezoneString()
2801
+	{
2802
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2803
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2804
+			EE_Error::add_error(
2805
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2806
+				__FILE__,
2807
+				__FUNCTION__,
2808
+				__LINE__
2809
+			);
2810
+			$this->_template_args['error'] = true;
2811
+			$this->_return_json();
2812
+		}
2813
+
2814
+		update_option('timezone_string', $timezone_string);
2815
+		EE_Error::add_success(
2816
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2817
+		);
2818
+		$this->_template_args['success'] = true;
2819
+		$this->_return_json(true, ['action' => 'create_new']);
2820
+	}
2821
+
2822
+
2823
+	/**
2824
+	 * @throws EE_Error
2825
+	 * @deprecated 4.10.25.p
2826
+	 */
2827
+	public function save_timezonestring_setting()
2828
+	{
2829
+		$this->saveTimezoneString();
2830
+	}
2831 2831
 }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.27.rc.000');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.27.rc.000');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.