Completed
Branch BUG/fix-table-exists-query (7059df)
by
unknown
09:49 queued 07:55
created
core/services/database/TableAnalysis.php 2 patches
Indentation   +118 added lines, -118 removed lines patch added patch discarded remove patch
@@ -18,129 +18,129 @@
 block discarded – undo
18 18
 class TableAnalysis extends EE_Base
19 19
 {
20 20
 
21
-    /**
22
-     * The maximum number of characters that can be indexed on a column using utf8mb4 collation,
23
-     * see https://events.codebasehq.com/redirect?https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/
24
-     */
25
-    const INDEX_COLUMN_SIZE = 191;
21
+	/**
22
+	 * The maximum number of characters that can be indexed on a column using utf8mb4 collation,
23
+	 * see https://events.codebasehq.com/redirect?https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/
24
+	 */
25
+	const INDEX_COLUMN_SIZE = 191;
26 26
 
27
-    /**
28
-     * Returns the table name which will definitely have the wpdb prefix on the front,
29
-     * except if it currently has the wpdb->base_prefix on the front, in which case
30
-     * it will have the wpdb->base_prefix on it
31
-     *
32
-     * @global wpdb $wpdb
33
-     * @param string $table_name
34
-     * @return string $tableName, having ensured it has the wpdb prefix on the front
35
-     */
36
-    public function ensureTableNameHasPrefix($table_name)
37
-    {
38
-        global $wpdb;
39
-        return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name;
40
-    }
27
+	/**
28
+	 * Returns the table name which will definitely have the wpdb prefix on the front,
29
+	 * except if it currently has the wpdb->base_prefix on the front, in which case
30
+	 * it will have the wpdb->base_prefix on it
31
+	 *
32
+	 * @global wpdb $wpdb
33
+	 * @param string $table_name
34
+	 * @return string $tableName, having ensured it has the wpdb prefix on the front
35
+	 */
36
+	public function ensureTableNameHasPrefix($table_name)
37
+	{
38
+		global $wpdb;
39
+		return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name;
40
+	}
41 41
 
42 42
 
43
-    /**
44
-     * Indicates whether or not the table has any entries. $table_name can
45
-     * optionally start with $wpdb->prefix or not
46
-     *
47
-     * @global wpdb $wpdb
48
-     * @param string $table_name
49
-     * @return bool
50
-     */
51
-    public function tableIsEmpty($table_name)
52
-    {
53
-        global $wpdb;
54
-        $table_name = $this->ensureTableNameHasPrefix($table_name);
55
-        if ($this->tableExists($table_name)) {
56
-            $count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
57
-            return absint($count) === 0;
58
-        }
59
-        return false;
60
-    }
43
+	/**
44
+	 * Indicates whether or not the table has any entries. $table_name can
45
+	 * optionally start with $wpdb->prefix or not
46
+	 *
47
+	 * @global wpdb $wpdb
48
+	 * @param string $table_name
49
+	 * @return bool
50
+	 */
51
+	public function tableIsEmpty($table_name)
52
+	{
53
+		global $wpdb;
54
+		$table_name = $this->ensureTableNameHasPrefix($table_name);
55
+		if ($this->tableExists($table_name)) {
56
+			$count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
57
+			return absint($count) === 0;
58
+		}
59
+		return false;
60
+	}
61 61
 
62 62
 
63
-    /**
64
-     * Indicates whether or not the table exists. $table_name can optionally
65
-     * have the $wpdb->prefix on the beginning, or not.
66
-     *
67
-     * @global wpdb $wpdb
68
-     * @param string $table_name
69
-     * @return bool
70
-     */
71
-    public function tableExists($table_name)
72
-    {
73
-        global $wpdb, $EZSQL_ERROR;
74
-        $table_name = $this->ensureTableNameHasPrefix($table_name);
75
-        // ignore if this causes an sql error
76
-        $prev_last_error      = $wpdb->last_error;
77
-        $prev_EZSQL_ERROR     = $EZSQL_ERROR;
78
-        $prev_suppress_errors = $wpdb->suppress_errors();
79
-        $prev_show_errors     = $wpdb->hide_errors();
80
-        ob_start();
81
-        $wpdb->get_results("SELECT COUNT(*) from $table_name LIMIT 1");
82
-        ob_get_clean();
83
-        // grab any new errors that were just generated
84
-        $new_error        = $wpdb->last_error;
85
-        // reset error handling values to previous state
86
-        $wpdb->last_error = $prev_last_error;
87
-        $EZSQL_ERROR      = $prev_EZSQL_ERROR;
88
-        $wpdb->show_errors($prev_show_errors);
89
-        $wpdb->suppress_errors($prev_suppress_errors);
90
-        // if there was no "table doesn't exist" error then the table must exist
91
-        if (empty($new_error)) {
92
-            return true;
93
-        }
94
-        $error_codes = [
95
-            1051, // bad table
96
-            1109, // unknown table
97
-            117, // no such table
98
-        ];
99
-        if (in_array(EEH_Activation::last_wpdb_error_code(), $error_codes)
100
-            // in case not using mysql and error codes aren't reliable, just check for this error string
101
-            || preg_match('~^Table .* doesn\'t exist~', $new_error)
102
-        ) {
103
-            return false;
104
-        }
105
-        // log this because that's weird. Just use the normal PHP error log
106
-        error_log(
107
-            sprintf(
108
-                __(
109
-                    'Event Espresso error detected when checking if table existed: %1$s (it wasn\'t just that the table didn\'t exist either)',
110
-                    'event_espresso'
111
-                ),
112
-                $new_error
113
-            )
114
-        );
115
-        return false;
116
-    }
63
+	/**
64
+	 * Indicates whether or not the table exists. $table_name can optionally
65
+	 * have the $wpdb->prefix on the beginning, or not.
66
+	 *
67
+	 * @global wpdb $wpdb
68
+	 * @param string $table_name
69
+	 * @return bool
70
+	 */
71
+	public function tableExists($table_name)
72
+	{
73
+		global $wpdb, $EZSQL_ERROR;
74
+		$table_name = $this->ensureTableNameHasPrefix($table_name);
75
+		// ignore if this causes an sql error
76
+		$prev_last_error      = $wpdb->last_error;
77
+		$prev_EZSQL_ERROR     = $EZSQL_ERROR;
78
+		$prev_suppress_errors = $wpdb->suppress_errors();
79
+		$prev_show_errors     = $wpdb->hide_errors();
80
+		ob_start();
81
+		$wpdb->get_results("SELECT COUNT(*) from $table_name LIMIT 1");
82
+		ob_get_clean();
83
+		// grab any new errors that were just generated
84
+		$new_error        = $wpdb->last_error;
85
+		// reset error handling values to previous state
86
+		$wpdb->last_error = $prev_last_error;
87
+		$EZSQL_ERROR      = $prev_EZSQL_ERROR;
88
+		$wpdb->show_errors($prev_show_errors);
89
+		$wpdb->suppress_errors($prev_suppress_errors);
90
+		// if there was no "table doesn't exist" error then the table must exist
91
+		if (empty($new_error)) {
92
+			return true;
93
+		}
94
+		$error_codes = [
95
+			1051, // bad table
96
+			1109, // unknown table
97
+			117, // no such table
98
+		];
99
+		if (in_array(EEH_Activation::last_wpdb_error_code(), $error_codes)
100
+			// in case not using mysql and error codes aren't reliable, just check for this error string
101
+			|| preg_match('~^Table .* doesn\'t exist~', $new_error)
102
+		) {
103
+			return false;
104
+		}
105
+		// log this because that's weird. Just use the normal PHP error log
106
+		error_log(
107
+			sprintf(
108
+				__(
109
+					'Event Espresso error detected when checking if table existed: %1$s (it wasn\'t just that the table didn\'t exist either)',
110
+					'event_espresso'
111
+				),
112
+				$new_error
113
+			)
114
+		);
115
+		return false;
116
+	}
117 117
 
118 118
 
119
-    /**
120
-     * @param string $table_name
121
-     * @param string $index_name
122
-     * @return array of columns used on that index, Each entry is an object with the following properties {
123
-     * @type string Table
124
-     * @type string Non_unique "0" or "1"
125
-     * @type string Key_name
126
-     * @type string Seq_in_index
127
-     * @type string Column_name
128
-     * @type string Collation
129
-     * @type string Cardinality
130
-     * @type string Sub_part on a column, usually this is just the number of characters from this column to use in
131
-     *       indexing
132
-     * @type string|null Packed
133
-     * @type string Null
134
-     * @type string Index_type
135
-     * @type string Comment
136
-     * @type string Index_comment
137
-     * }
138
-     */
139
-    public function showIndexes($table_name, $index_name)
140
-    {
141
-        global $wpdb;
142
-        $table_name = $this->ensureTableNameHasPrefix($table_name);
143
-        $index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'";
144
-        return $wpdb->get_results($index_exists_query);
145
-    }
119
+	/**
120
+	 * @param string $table_name
121
+	 * @param string $index_name
122
+	 * @return array of columns used on that index, Each entry is an object with the following properties {
123
+	 * @type string Table
124
+	 * @type string Non_unique "0" or "1"
125
+	 * @type string Key_name
126
+	 * @type string Seq_in_index
127
+	 * @type string Column_name
128
+	 * @type string Collation
129
+	 * @type string Cardinality
130
+	 * @type string Sub_part on a column, usually this is just the number of characters from this column to use in
131
+	 *       indexing
132
+	 * @type string|null Packed
133
+	 * @type string Null
134
+	 * @type string Index_type
135
+	 * @type string Comment
136
+	 * @type string Index_comment
137
+	 * }
138
+	 */
139
+	public function showIndexes($table_name, $index_name)
140
+	{
141
+		global $wpdb;
142
+		$table_name = $this->ensureTableNameHasPrefix($table_name);
143
+		$index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'";
144
+		return $wpdb->get_results($index_exists_query);
145
+	}
146 146
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -36,7 +36,7 @@
 block discarded – undo
36 36
     public function ensureTableNameHasPrefix($table_name)
37 37
     {
38 38
         global $wpdb;
39
-        return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name;
39
+        return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix.$table_name;
40 40
     }
41 41
 
42 42
 
Please login to merge, or discard this patch.
core/services/database/TableManager.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
         global $wpdb;
71 71
         $full_table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
72 72
         $columns = $this->getTableColumns($table_name);
73
-        if (! in_array($column_name, $columns)) {
73
+        if ( ! in_array($column_name, $columns)) {
74 74
             $alter_query = "ALTER TABLE {$full_table_name} ADD {$column_name} {$column_info}";
75 75
             return $wpdb->query($alter_query);
76 76
         }
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
         global $wpdb;
94 94
         $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
95 95
         $field_array = array();
96
-        if (! empty($table_name)) {
96
+        if ( ! empty($table_name)) {
97 97
             $columns = $wpdb->get_results("SHOW COLUMNS FROM {$table_name} ");
98 98
             if ($columns !== false) {
99 99
                 foreach ($columns as $column) {
@@ -143,14 +143,14 @@  discard block
 block discarded – undo
143 143
         foreach ($table_names as $table_name) {
144 144
             $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
145 145
             if ($this->getTableAnalysis()->tableExists($table_name)) {
146
-                $tables_to_delete[ $table_name ] = $table_name;
146
+                $tables_to_delete[$table_name] = $table_name;
147 147
             }
148 148
         }
149
-        if (! empty($tables_to_delete)) {
149
+        if ( ! empty($tables_to_delete)) {
150 150
             global $wpdb;
151 151
             // make sure we only have a unique strings in the array.
152 152
             $tables_to_delete = array_unique($tables_to_delete);
153
-            $wpdb->query('DROP TABLE ' . implode(', ', $tables_to_delete));
153
+            $wpdb->query('DROP TABLE '.implode(', ', $tables_to_delete));
154 154
         }
155 155
         return $tables_to_delete;
156 156
     }
@@ -199,7 +199,7 @@  discard block
 block discarded – undo
199 199
     {
200 200
         // does $sql contain valid column information?
201 201
         // LPT: https://regex101.com/ is great for working out regex patterns
202
-        if (! preg_match('(((.*?)(,\s))+)', $create_sql, $valid_column_data)) {
202
+        if ( ! preg_match('(((.*?)(,\s))+)', $create_sql, $valid_column_data)) {
203 203
             throw new EE_Error(
204 204
                 sprintf(
205 205
                     __(
@@ -235,7 +235,7 @@  discard block
 block discarded – undo
235 235
         $output = ob_get_clean();
236 236
         $wpdb->show_errors($old_show_errors_policy);
237 237
         $wpdb->suppress_errors($old_error_suppression_policy);
238
-        if (! empty($output)) {
238
+        if ( ! empty($output)) {
239 239
             throw new EE_Error($output);
240 240
         }
241 241
     }
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
         if ($column_name === null) {
265 265
             $column_name = $index_name;
266 266
         }
267
-        if (! $this->getTableAnalysis()->tableExists($table_name)) {
267
+        if ( ! $this->getTableAnalysis()->tableExists($table_name)) {
268 268
             return false;
269 269
         }
270 270
         $index_entries = $this->getTableAnalysis()->showIndexes($table_name, $index_name);
Please login to merge, or discard this patch.
Indentation   +236 added lines, -236 removed lines patch added patch discarded remove patch
@@ -16,258 +16,258 @@
 block discarded – undo
16 16
 class TableManager extends \EE_Base
17 17
 {
18 18
 
19
-    /**
20
-     * @var TableAnalysis $table_analysis
21
-     */
22
-    private $table_analysis;
19
+	/**
20
+	 * @var TableAnalysis $table_analysis
21
+	 */
22
+	private $table_analysis;
23 23
 
24 24
 
25
-    /**
26
-     * TableManager constructor.
27
-     *
28
-     * @param TableAnalysis $TableAnalysis
29
-     */
30
-    public function __construct(TableAnalysis $TableAnalysis)
31
-    {
32
-        $this->table_analysis = $TableAnalysis;
33
-    }
25
+	/**
26
+	 * TableManager constructor.
27
+	 *
28
+	 * @param TableAnalysis $TableAnalysis
29
+	 */
30
+	public function __construct(TableAnalysis $TableAnalysis)
31
+	{
32
+		$this->table_analysis = $TableAnalysis;
33
+	}
34 34
 
35 35
 
36
-    /**
37
-     * Gets the injected table analyzer, or throws an exception
38
-     *
39
-     * @return TableAnalysis
40
-     * @throws EE_Error
41
-     */
42
-    protected function getTableAnalysis()
43
-    {
44
-        if ($this->table_analysis instanceof TableAnalysis) {
45
-            return $this->table_analysis;
46
-        } else {
47
-            throw new EE_Error(
48
-                sprintf(
49
-                    __('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
50
-                    get_class($this)
51
-                )
52
-            );
53
-        }
54
-    }
36
+	/**
37
+	 * Gets the injected table analyzer, or throws an exception
38
+	 *
39
+	 * @return TableAnalysis
40
+	 * @throws EE_Error
41
+	 */
42
+	protected function getTableAnalysis()
43
+	{
44
+		if ($this->table_analysis instanceof TableAnalysis) {
45
+			return $this->table_analysis;
46
+		} else {
47
+			throw new EE_Error(
48
+				sprintf(
49
+					__('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
50
+					get_class($this)
51
+				)
52
+			);
53
+		}
54
+	}
55 55
 
56 56
 
57
-    /**
58
-     * @param string $table_name which can optionally start with $wpdb->prefix or not
59
-     * @param string $column_name
60
-     * @param string $column_info
61
-     * @return bool|false|int
62
-     * @throws EE_Error
63
-     */
64
-    public function addColumn($table_name, $column_name, $column_info = 'INT UNSIGNED NOT NULL')
65
-    {
66
-        if (apply_filters('FHEE__EEH_Activation__add_column_if_it_doesnt_exist__short_circuit', false)) {
67
-            return false;
68
-        }
69
-        global $wpdb;
70
-        $full_table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
71
-        $columns = $this->getTableColumns($table_name);
72
-        if (! in_array($column_name, $columns)) {
73
-            $alter_query = "ALTER TABLE {$full_table_name} ADD {$column_name} {$column_info}";
74
-            return $wpdb->query($alter_query);
75
-        }
76
-        return true;
77
-    }
57
+	/**
58
+	 * @param string $table_name which can optionally start with $wpdb->prefix or not
59
+	 * @param string $column_name
60
+	 * @param string $column_info
61
+	 * @return bool|false|int
62
+	 * @throws EE_Error
63
+	 */
64
+	public function addColumn($table_name, $column_name, $column_info = 'INT UNSIGNED NOT NULL')
65
+	{
66
+		if (apply_filters('FHEE__EEH_Activation__add_column_if_it_doesnt_exist__short_circuit', false)) {
67
+			return false;
68
+		}
69
+		global $wpdb;
70
+		$full_table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
71
+		$columns = $this->getTableColumns($table_name);
72
+		if (! in_array($column_name, $columns)) {
73
+			$alter_query = "ALTER TABLE {$full_table_name} ADD {$column_name} {$column_info}";
74
+			return $wpdb->query($alter_query);
75
+		}
76
+		return true;
77
+	}
78 78
 
79 79
 
80
-    /**
81
-     * Gets the name of all columns on the  table. $table_name can
82
-     * optionally start with $wpdb->prefix or not
83
-     *
84
-     * @param string $table_name
85
-     * @return array
86
-     * @throws EE_Error
87
-     * @global wpdb $wpdb
88
-     */
89
-    public function getTableColumns($table_name)
90
-    {
91
-        global $wpdb;
92
-        $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
93
-        $field_array = array();
94
-        if (! empty($table_name)) {
95
-            $columns = $wpdb->get_results("SHOW COLUMNS FROM {$table_name} ");
96
-            if ($columns !== false) {
97
-                foreach ($columns as $column) {
98
-                    $field_array[] = $column->Field;
99
-                }
100
-            }
101
-        }
102
-        return $field_array;
103
-    }
80
+	/**
81
+	 * Gets the name of all columns on the  table. $table_name can
82
+	 * optionally start with $wpdb->prefix or not
83
+	 *
84
+	 * @param string $table_name
85
+	 * @return array
86
+	 * @throws EE_Error
87
+	 * @global wpdb $wpdb
88
+	 */
89
+	public function getTableColumns($table_name)
90
+	{
91
+		global $wpdb;
92
+		$table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
93
+		$field_array = array();
94
+		if (! empty($table_name)) {
95
+			$columns = $wpdb->get_results("SHOW COLUMNS FROM {$table_name} ");
96
+			if ($columns !== false) {
97
+				foreach ($columns as $column) {
98
+					$field_array[] = $column->Field;
99
+				}
100
+			}
101
+		}
102
+		return $field_array;
103
+	}
104 104
 
105 105
 
106
-    /**
107
-     * Drops the specified table from the database. $table_name can
108
-     * optionally start with $wpdb->prefix or not
109
-     *
110
-     * @param string $table_name
111
-     * @return int
112
-     * @throws EE_Error
113
-     * @global wpdb $wpdb
114
-     */
115
-    public function dropTable($table_name)
116
-    {
117
-        global $wpdb;
118
-        if ($this->getTableAnalysis()->tableExists($table_name)) {
119
-            $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
120
-            return $wpdb->query("DROP TABLE IF EXISTS {$table_name}");
121
-        }
122
-        return 0;
123
-    }
106
+	/**
107
+	 * Drops the specified table from the database. $table_name can
108
+	 * optionally start with $wpdb->prefix or not
109
+	 *
110
+	 * @param string $table_name
111
+	 * @return int
112
+	 * @throws EE_Error
113
+	 * @global wpdb $wpdb
114
+	 */
115
+	public function dropTable($table_name)
116
+	{
117
+		global $wpdb;
118
+		if ($this->getTableAnalysis()->tableExists($table_name)) {
119
+			$table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
120
+			return $wpdb->query("DROP TABLE IF EXISTS {$table_name}");
121
+		}
122
+		return 0;
123
+	}
124 124
 
125 125
 
126
-    /**
127
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
128
-     * each table name provided has a wpdb prefix attached, and that it exists.
129
-     * Returns the list actually deleted
130
-     *
131
-     * @param array $table_names
132
-     * @return array of table names which we deleted
133
-     * @throws EE_Error
134
-     * @global WPDB $wpdb
135
-     */
136
-    public function dropTables($table_names)
137
-    {
138
-        $tables_to_delete = array();
139
-        foreach ($table_names as $table_name) {
140
-            $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
141
-            if ($this->getTableAnalysis()->tableExists($table_name)) {
142
-                $tables_to_delete[ $table_name ] = $table_name;
143
-            }
144
-        }
145
-        if (! empty($tables_to_delete)) {
146
-            global $wpdb;
147
-            // make sure we only have a unique strings in the array.
148
-            $tables_to_delete = array_unique($tables_to_delete);
149
-            $wpdb->query('DROP TABLE ' . implode(', ', $tables_to_delete));
150
-        }
151
-        return $tables_to_delete;
152
-    }
126
+	/**
127
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
128
+	 * each table name provided has a wpdb prefix attached, and that it exists.
129
+	 * Returns the list actually deleted
130
+	 *
131
+	 * @param array $table_names
132
+	 * @return array of table names which we deleted
133
+	 * @throws EE_Error
134
+	 * @global WPDB $wpdb
135
+	 */
136
+	public function dropTables($table_names)
137
+	{
138
+		$tables_to_delete = array();
139
+		foreach ($table_names as $table_name) {
140
+			$table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
141
+			if ($this->getTableAnalysis()->tableExists($table_name)) {
142
+				$tables_to_delete[ $table_name ] = $table_name;
143
+			}
144
+		}
145
+		if (! empty($tables_to_delete)) {
146
+			global $wpdb;
147
+			// make sure we only have a unique strings in the array.
148
+			$tables_to_delete = array_unique($tables_to_delete);
149
+			$wpdb->query('DROP TABLE ' . implode(', ', $tables_to_delete));
150
+		}
151
+		return $tables_to_delete;
152
+	}
153 153
 
154 154
 
155
-    /**
156
-     * Drops the specified index from the specified table. $table_name can
157
-     * optionally start with $wpdb->prefix or not
158
-     *
159
-     * @param string $table_name
160
-     * @param string $index_name
161
-     * @return int the number of indexes dropped. False if there was a database error
162
-     * @throws EE_Error
163
-     * @global wpdb $wpdb
164
-     */
165
-    public function dropIndex($table_name, $index_name)
166
-    {
167
-        if (apply_filters('FHEE__EEH_Activation__drop_index__short_circuit', false)) {
168
-            return 0;
169
-        }
170
-        global $wpdb;
171
-        $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
172
-        $index_exists_query = "SHOW INDEX FROM {$table_name} WHERE key_name = '{$index_name}'";
173
-        if ($this->getTableAnalysis()->tableExists($table_name)
174
-            && $wpdb->get_var($index_exists_query) === $table_name
175
-            // using get_var with the $index_exists_query returns the table's name
176
-        ) {
177
-            return $wpdb->query("ALTER TABLE {$table_name} DROP INDEX {$index_name}");
178
-        }
179
-        return 0;
180
-    }
155
+	/**
156
+	 * Drops the specified index from the specified table. $table_name can
157
+	 * optionally start with $wpdb->prefix or not
158
+	 *
159
+	 * @param string $table_name
160
+	 * @param string $index_name
161
+	 * @return int the number of indexes dropped. False if there was a database error
162
+	 * @throws EE_Error
163
+	 * @global wpdb $wpdb
164
+	 */
165
+	public function dropIndex($table_name, $index_name)
166
+	{
167
+		if (apply_filters('FHEE__EEH_Activation__drop_index__short_circuit', false)) {
168
+			return 0;
169
+		}
170
+		global $wpdb;
171
+		$table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
172
+		$index_exists_query = "SHOW INDEX FROM {$table_name} WHERE key_name = '{$index_name}'";
173
+		if ($this->getTableAnalysis()->tableExists($table_name)
174
+			&& $wpdb->get_var($index_exists_query) === $table_name
175
+			// using get_var with the $index_exists_query returns the table's name
176
+		) {
177
+			return $wpdb->query("ALTER TABLE {$table_name} DROP INDEX {$index_name}");
178
+		}
179
+		return 0;
180
+	}
181 181
 
182 182
 
183
-    /**
184
-     * Just creates the requested table. $table_name can
185
-     * optionally start with $wpdb->prefix or not
186
-     *
187
-     * @param string $table_name
188
-     * @param string $create_sql defining the table's columns and indexes
189
-     * @param string $engine     (no need to specify "ENGINE=", that's implied)
190
-     * @return void
191
-     * @throws EE_Error
192
-     * @global wpdb $wpdb
193
-     */
194
-    public function createTable($table_name, $create_sql, $engine = 'MyISAM')
195
-    {
196
-        // does $sql contain valid column information?
197
-        // LPT: https://regex101.com/ is great for working out regex patterns
198
-        if (! preg_match('(((.*?)(,\s))+)', $create_sql, $valid_column_data)) {
199
-            throw new EE_Error(
200
-                sprintf(
201
-                    __(
202
-                        'The following table creation SQL does not contain valid information about the table columns: %1$s %2$s',
203
-                        'event_espresso'
204
-                    ),
205
-                    '<br />',
206
-                    $create_sql
207
-                )
208
-            );
209
-        }
210
-        $engine = apply_filters(
211
-            'FHEE__EventEspresso_core_services_database_TableManager__createTable__engine',
212
-            $engine,
213
-            $table_name,
214
-            $create_sql
215
-        );
216
-        $table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
217
-        global $wpdb;
218
-        $collation = $wpdb->get_charset_collate();
219
-        $SQL = "CREATE TABLE {$table_name} ({$create_sql}) ENGINE={$engine} {$collation}";
220
-        // get $wpdb to echo errors, but buffer them. This way at least WE know an error
221
-        // happened. And then we can choose to tell the end user
222
-        $old_show_errors_policy = $wpdb->show_errors(true);
223
-        $old_error_suppression_policy = $wpdb->suppress_errors(false);
224
-        ob_start();
225
-        dbDelta($SQL);
226
-        $output = ob_get_clean();
227
-        $wpdb->show_errors($old_show_errors_policy);
228
-        $wpdb->suppress_errors($old_error_suppression_policy);
229
-        if (! empty($output)) {
230
-            throw new EE_Error($output);
231
-        }
232
-    }
183
+	/**
184
+	 * Just creates the requested table. $table_name can
185
+	 * optionally start with $wpdb->prefix or not
186
+	 *
187
+	 * @param string $table_name
188
+	 * @param string $create_sql defining the table's columns and indexes
189
+	 * @param string $engine     (no need to specify "ENGINE=", that's implied)
190
+	 * @return void
191
+	 * @throws EE_Error
192
+	 * @global wpdb $wpdb
193
+	 */
194
+	public function createTable($table_name, $create_sql, $engine = 'MyISAM')
195
+	{
196
+		// does $sql contain valid column information?
197
+		// LPT: https://regex101.com/ is great for working out regex patterns
198
+		if (! preg_match('(((.*?)(,\s))+)', $create_sql, $valid_column_data)) {
199
+			throw new EE_Error(
200
+				sprintf(
201
+					__(
202
+						'The following table creation SQL does not contain valid information about the table columns: %1$s %2$s',
203
+						'event_espresso'
204
+					),
205
+					'<br />',
206
+					$create_sql
207
+				)
208
+			);
209
+		}
210
+		$engine = apply_filters(
211
+			'FHEE__EventEspresso_core_services_database_TableManager__createTable__engine',
212
+			$engine,
213
+			$table_name,
214
+			$create_sql
215
+		);
216
+		$table_name = $this->getTableAnalysis()->ensureTableNameHasPrefix($table_name);
217
+		global $wpdb;
218
+		$collation = $wpdb->get_charset_collate();
219
+		$SQL = "CREATE TABLE {$table_name} ({$create_sql}) ENGINE={$engine} {$collation}";
220
+		// get $wpdb to echo errors, but buffer them. This way at least WE know an error
221
+		// happened. And then we can choose to tell the end user
222
+		$old_show_errors_policy = $wpdb->show_errors(true);
223
+		$old_error_suppression_policy = $wpdb->suppress_errors(false);
224
+		ob_start();
225
+		dbDelta($SQL);
226
+		$output = ob_get_clean();
227
+		$wpdb->show_errors($old_show_errors_policy);
228
+		$wpdb->suppress_errors($old_error_suppression_policy);
229
+		if (! empty($output)) {
230
+			throw new EE_Error($output);
231
+		}
232
+	}
233 233
 
234 234
 
235
-    /**
236
-     * Drops the specified index if it's size differs from $desired_index_size.
237
-     * WordPress' dbDelta method doesn't automatically change index sizes, so this
238
-     * method can be used to only drop the index if needed, and afterwards dbDelta can be used as normal.
239
-     * If the table doesn't exist, or it exists but the index does not, or returns false
240
-     *
241
-     * @param string     $table_name
242
-     * @param string     $index_name
243
-     * @param string|null $column_name       if none is provided, we assume the column name matches the index
244
-     *                                       (often true in EE)
245
-     * @param string|int $desired_index_size defaults to TableAnalysis::index_col_size, the max for utf8mb4.
246
-     * @return bool whether an index was dropped or not
247
-     * @throws EE_Error if table analysis object isn't defined
248
-     */
249
-    public function dropIndexIfSizeNot(
250
-        $table_name,
251
-        $index_name,
252
-        $column_name = null,
253
-        $desired_index_size = TableAnalysis::INDEX_COLUMN_SIZE
254
-    ) {
255
-        if ($column_name === null) {
256
-            $column_name = $index_name;
257
-        }
258
-        if (! $this->getTableAnalysis()->tableExists($table_name)) {
259
-            return false;
260
-        }
261
-        $index_entries = $this->getTableAnalysis()->showIndexes($table_name, $index_name);
262
-        if (empty($index_entries)) {
263
-            return false;
264
-        }
265
-        foreach ($index_entries as $index_entry) {
266
-            if ($column_name === $index_entry->Column_name
267
-                && (string) $desired_index_size !== $index_entry->Sub_part) {
268
-                return $this->dropIndex($table_name, $index_name);
269
-            }
270
-        }
271
-        return false;
272
-    }
235
+	/**
236
+	 * Drops the specified index if it's size differs from $desired_index_size.
237
+	 * WordPress' dbDelta method doesn't automatically change index sizes, so this
238
+	 * method can be used to only drop the index if needed, and afterwards dbDelta can be used as normal.
239
+	 * If the table doesn't exist, or it exists but the index does not, or returns false
240
+	 *
241
+	 * @param string     $table_name
242
+	 * @param string     $index_name
243
+	 * @param string|null $column_name       if none is provided, we assume the column name matches the index
244
+	 *                                       (often true in EE)
245
+	 * @param string|int $desired_index_size defaults to TableAnalysis::index_col_size, the max for utf8mb4.
246
+	 * @return bool whether an index was dropped or not
247
+	 * @throws EE_Error if table analysis object isn't defined
248
+	 */
249
+	public function dropIndexIfSizeNot(
250
+		$table_name,
251
+		$index_name,
252
+		$column_name = null,
253
+		$desired_index_size = TableAnalysis::INDEX_COLUMN_SIZE
254
+	) {
255
+		if ($column_name === null) {
256
+			$column_name = $index_name;
257
+		}
258
+		if (! $this->getTableAnalysis()->tableExists($table_name)) {
259
+			return false;
260
+		}
261
+		$index_entries = $this->getTableAnalysis()->showIndexes($table_name, $index_name);
262
+		if (empty($index_entries)) {
263
+			return false;
264
+		}
265
+		foreach ($index_entries as $index_entry) {
266
+			if ($column_name === $index_entry->Column_name
267
+				&& (string) $desired_index_size !== $index_entry->Sub_part) {
268
+				return $this->dropIndex($table_name, $index_name);
269
+			}
270
+		}
271
+		return false;
272
+	}
273 273
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Import.class.php 2 patches
Indentation   +975 added lines, -975 removed lines patch added patch discarded remove patch
@@ -14,97 +14,97 @@  discard block
 block discarded – undo
14 14
 class EE_Import implements ResettableInterface
15 15
 {
16 16
 
17
-    const do_insert  = 'insert';
18
-
19
-    const do_update  = 'update';
20
-
21
-    const do_nothing = 'nothing';
22
-
23
-
24
-    // instance of the EE_Import object
25
-    private static $_instance  = null;
26
-
27
-    private static $_csv_array = [];
28
-
29
-    /**
30
-     *
31
-     * @var array of model names
32
-     */
33
-    private static $_model_list          = [];
34
-
35
-    private static $_columns_to_save     = [];
36
-
37
-    protected $_total_inserts       = 0;
38
-
39
-    protected $_total_updates       = 0;
40
-
41
-    protected $_total_insert_errors = 0;
42
-
43
-    protected $_total_update_errors = 0;
44
-
45
-
46
-    /**
47
-     *        private constructor to prevent direct creation
48
-     *
49
-     * @Constructor
50
-     * @access private
51
-     * @return void
52
-     */
53
-    private function __construct()
54
-    {
55
-        $this->_total_inserts       = 0;
56
-        $this->_total_updates       = 0;
57
-        $this->_total_insert_errors = 0;
58
-        $this->_total_update_errors = 0;
59
-    }
60
-
61
-
62
-    /**
63
-     *    @ singleton method used to instantiate class object
64
-     *    @ access public
65
-     *
66
-     * @return EE_Import
67
-     */
68
-    public static function instance()
69
-    {
70
-        // check if class object is instantiated
71
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
72
-            self::$_instance = new self();
73
-        }
74
-        return self::$_instance;
75
-    }
76
-
77
-
78
-    /**
79
-     * Resets the importer
80
-     *
81
-     * @return EE_Import
82
-     */
83
-    public static function reset()
84
-    {
85
-        self::$_instance = null;
86
-        return self::instance();
87
-    }
88
-
89
-
90
-    /**
91
-     *    @ generates HTML for a file upload input and form
92
-     *    @ access    public
93
-     *
94
-     * @param string $title     - heading for the form
95
-     * @param string $intro     - additional text explaing what to do
96
-     * @param string $page      - EE Admin page to direct form to - in the form "espresso_{pageslug}"
97
-     * @param string $action    - EE Admin page route array "action" that form will direct to
98
-     * @param string $type      - type of file to import
99
-     *                          @ return    string
100
-     */
101
-    public function upload_form($title, $intro, $form_url, $action, $type)
102
-    {
103
-
104
-        $form_url = EE_Admin_Page::add_query_args_and_nonce(['action' => $action], $form_url);
105
-
106
-        ob_start();
107
-        ?>
17
+	const do_insert  = 'insert';
18
+
19
+	const do_update  = 'update';
20
+
21
+	const do_nothing = 'nothing';
22
+
23
+
24
+	// instance of the EE_Import object
25
+	private static $_instance  = null;
26
+
27
+	private static $_csv_array = [];
28
+
29
+	/**
30
+	 *
31
+	 * @var array of model names
32
+	 */
33
+	private static $_model_list          = [];
34
+
35
+	private static $_columns_to_save     = [];
36
+
37
+	protected $_total_inserts       = 0;
38
+
39
+	protected $_total_updates       = 0;
40
+
41
+	protected $_total_insert_errors = 0;
42
+
43
+	protected $_total_update_errors = 0;
44
+
45
+
46
+	/**
47
+	 *        private constructor to prevent direct creation
48
+	 *
49
+	 * @Constructor
50
+	 * @access private
51
+	 * @return void
52
+	 */
53
+	private function __construct()
54
+	{
55
+		$this->_total_inserts       = 0;
56
+		$this->_total_updates       = 0;
57
+		$this->_total_insert_errors = 0;
58
+		$this->_total_update_errors = 0;
59
+	}
60
+
61
+
62
+	/**
63
+	 *    @ singleton method used to instantiate class object
64
+	 *    @ access public
65
+	 *
66
+	 * @return EE_Import
67
+	 */
68
+	public static function instance()
69
+	{
70
+		// check if class object is instantiated
71
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
72
+			self::$_instance = new self();
73
+		}
74
+		return self::$_instance;
75
+	}
76
+
77
+
78
+	/**
79
+	 * Resets the importer
80
+	 *
81
+	 * @return EE_Import
82
+	 */
83
+	public static function reset()
84
+	{
85
+		self::$_instance = null;
86
+		return self::instance();
87
+	}
88
+
89
+
90
+	/**
91
+	 *    @ generates HTML for a file upload input and form
92
+	 *    @ access    public
93
+	 *
94
+	 * @param string $title     - heading for the form
95
+	 * @param string $intro     - additional text explaing what to do
96
+	 * @param string $page      - EE Admin page to direct form to - in the form "espresso_{pageslug}"
97
+	 * @param string $action    - EE Admin page route array "action" that form will direct to
98
+	 * @param string $type      - type of file to import
99
+	 *                          @ return    string
100
+	 */
101
+	public function upload_form($title, $intro, $form_url, $action, $type)
102
+	{
103
+
104
+		$form_url = EE_Admin_Page::add_query_args_and_nonce(['action' => $action], $form_url);
105
+
106
+		ob_start();
107
+		?>
108 108
         <div class="ee-upload-form-dv">
109 109
             <h3><?php echo $title; ?></h3>
110 110
             <p><?php echo $intro; ?></p>
@@ -120,893 +120,893 @@  discard block
 block discarded – undo
120 120
                 <b><?php _e('Attention', 'event_espresso'); ?></b><br/>
121 121
                 <?php echo sprintf(__('Accepts .%s file types only.', 'event_espresso'), $type); ?>
122 122
                 <?php echo __(
123
-                    'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
124
-                    'event_espresso'
125
-                ); ?>
123
+					'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
124
+					'event_espresso'
125
+				); ?>
126 126
             </p>
127 127
 
128 128
         </div>
129 129
 
130 130
         <?php
131
-        $uploader = ob_get_clean();
132
-        return $uploader;
133
-    }
134
-
135
-
136
-    /**
137
-     * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
138
-     * @access public
139
-     * @return boolean success
140
-     * @throws EE_Error
141
-     */
142
-    public function import()
143
-    {
144
-
145
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
146
-        $this->EE_CSV = EE_CSV::instance();
147
-
148
-        if (isset($_REQUEST['import'])) {
149
-            if (isset($_POST['csv_submitted'])) {
150
-                switch ($_FILES['file']['error'][0]) {
151
-                    case UPLOAD_ERR_OK:
152
-                        $error_msg = false;
153
-                        break;
154
-                    case UPLOAD_ERR_INI_SIZE:
155
-                        $error_msg = __(
156
-                            "'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
157
-                            "event_espresso"
158
-                        );
159
-                        break;
160
-                    case UPLOAD_ERR_FORM_SIZE:
161
-                        $error_msg = __(
162
-                            'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
163
-                            "event_espresso"
164
-                        );
165
-                        break;
166
-                    case UPLOAD_ERR_PARTIAL:
167
-                        $error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
168
-                        break;
169
-                    case UPLOAD_ERR_NO_FILE:
170
-                        $error_msg = __('No file was uploaded.', "event_espresso");
171
-                        break;
172
-                    case UPLOAD_ERR_NO_TMP_DIR:
173
-                        $error_msg = __('Missing a temporary folder.', "event_espresso");
174
-                        break;
175
-                    case UPLOAD_ERR_CANT_WRITE:
176
-                        $error_msg = __('Failed to write file to disk.', "event_espresso");
177
-                        break;
178
-                    case UPLOAD_ERR_EXTENSION:
179
-                        $error_msg = __('File upload stopped by extension.', "event_espresso");
180
-                        break;
181
-                    default:
182
-                        $error_msg = __(
183
-                            'An unknown error occurred and the file could not be uploaded',
184
-                            "event_espresso"
185
-                        );
186
-                        break;
187
-                }
188
-
189
-                if (! $error_msg) {
190
-                    $filename  = $_FILES['file']['name'][0];
191
-                    $file_ext  = substr(strrchr($filename, '.'), 1);
192
-                    $file_type = $_FILES['file']['type'][0];
193
-                    $temp_file = $_FILES['file']['tmp_name'][0];
194
-                    $filesize  = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
195
-
196
-                    if ($file_ext == 'csv') {
197
-                        $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
198
-                        if ($filesize < $max_upload || true) {
199
-                            $wp_upload_dir = str_replace(['\\', '/'], '/', wp_upload_dir());
200
-                            $path_to_file  = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
201
-
202
-                            if (move_uploaded_file($temp_file, $path_to_file)) {
203
-                                // convert csv to array
204
-                                $this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
205
-
206
-                                // was data successfully stored in an array?
207
-                                if (is_array($this->csv_array)) {
208
-                                    $import_what           = str_replace('csv_import_', '', $_REQUEST['action']);
209
-                                    $import_what           = str_replace('_', ' ', ucwords($import_what));
210
-                                    $processed_data        = $this->csv_array;
211
-                                    $this->columns_to_save = false;
212
-
213
-                                    // if any imports require funcky processing, we'll catch them in the switch
214
-                                    switch ($_REQUEST['action']) {
215
-                                        case "import_events":
216
-                                        case "event_list":
217
-                                            $import_what = 'Event Details';
218
-                                            break;
219
-
220
-                                        case 'groupon_import_csv':
221
-                                            $import_what    = 'Groupon Codes';
222
-                                            $processed_data = $this->process_groupon_codes();
223
-                                            break;
224
-                                    }
225
-                                    // save processed codes to db
226
-                                    if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
227
-                                        return true;
228
-                                    }
229
-                                } else {
230
-                                    // no array? must be an error
231
-                                    EE_Error::add_error(
232
-                                        sprintf(__("No file seems to have been uploaded", "event_espresso")),
233
-                                        __FILE__,
234
-                                        __FUNCTION__,
235
-                                        __LINE__
236
-                                    );
237
-                                    return false;
238
-                                }
239
-                            } else {
240
-                                EE_Error::add_error(
241
-                                    sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
242
-                                    __FILE__,
243
-                                    __FUNCTION__,
244
-                                    __LINE__
245
-                                );
246
-                                return false;
247
-                            }
248
-                        } else {
249
-                            EE_Error::add_error(
250
-                                sprintf(
251
-                                    __(
252
-                                        "%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
253
-                                        "event_espresso"
254
-                                    ),
255
-                                    $filename,
256
-                                    $max_upload
257
-                                ),
258
-                                __FILE__,
259
-                                __FUNCTION__,
260
-                                __LINE__
261
-                            );
262
-                            return false;
263
-                        }
264
-                    } else {
265
-                        EE_Error::add_error(
266
-                            sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
267
-                            __FILE__,
268
-                            __FUNCTION__,
269
-                            __LINE__
270
-                        );
271
-                        return false;
272
-                    }
273
-                } else {
274
-                    EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
275
-                    return false;
276
-                }
277
-            }
278
-        }
279
-        return;
280
-    }
281
-
282
-
283
-    /**
284
-     *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
285
-     *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
286
-     *    next level being numeric indexes adn each value representing a model object, and the last layer down
287
-     *    being keys of model fields and their proposed values.
288
-     *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
289
-     *    If the CSV data says (in the metadata row) that it's from the SAME database,
290
-     *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
291
-     *    IDs DON'T exist in the database, they're treated as temporary IDs,
292
-     *    which can used elsewhere to refer to the same object. Once an item
293
-     *    with a temporary ID gets inserted, we record its mapping from temporary
294
-     *    ID to real ID, and use the real ID in place of the temporary ID
295
-     *    when that temporary ID was used as a foreign key.
296
-     *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
297
-     *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
298
-     *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
299
-     *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
300
-     *    An important exception are non-auto-increment primary keys. If one entry in the
301
-     *    CSV file has the same ID as one in the DB, we assume they are meant to be
302
-     *    the same item, and instead update the item in the DB with that same ID.
303
-     *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
304
-     *    time you import a CSV from a different site, we remember their mappings, and
305
-     * will try to update the item in the DB instead of inserting another item (eg
306
-     * if we previously imported an event with temporary ID 1, and then it got a
307
-     * real ID of 123, we remember that. So the next time we import an event with
308
-     * temporary ID, from the same site, we know that it's real ID is 123, and will
309
-     * update that event, instead of adding a new event).
310
-     *
311
-     * @access public
312
-     * @param array $csv_data_array - the array containing the csv data produced from
313
-     *                              EE_CSV::import_csv_to_model_data_array()
314
-     * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
315
-     *                              fields they will be saved to
316
-     * @return TRUE on success, FALSE on fail
317
-     * @throws \EE_Error
318
-     */
319
-    public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
320
-    {
321
-        $success = false;
322
-        $error   = false;
323
-        // whther to treat this import as if it's data froma different database or not
324
-        // ie, if it IS from a different database, ignore foreign keys whihf
325
-        $export_from_site_a_to_b = true;
326
-        // first level of array is not table information but a table name was passed to the function
327
-        // array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
328
-        if ($model_name) {
329
-            $csv_data_array = [$csv_data_array];
330
-        }
331
-        // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
332
-        $old_site_url = 'none-specified';
333
-        // hanlde metadata
334
-        if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
335
-            $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
336
-            // ok so its metadata, dont try to save it to ehte db obviously...
337
-            if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
338
-                EE_Error::add_attention(
339
-                    sprintf(
340
-                        __(
341
-                            "CSV Data appears to be from the same database, so attempting to update data",
342
-                            "event_espresso"
343
-                        )
344
-                    )
345
-                );
346
-                $export_from_site_a_to_b = false;
347
-            } else {
348
-                $old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
349
-                EE_Error::add_attention(
350
-                    sprintf(
351
-                        __(
352
-                            "CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
353
-                            "event_espresso"
354
-                        ),
355
-                        $old_site_url,
356
-                        site_url()
357
-                    )
358
-                );
359
-            };
360
-            unset($csv_data_array[ EE_CSV::metadata_header ]);
361
-        }
362
-        /**
363
-         * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
364
-         * the value will be the newly-inserted ID.
365
-         * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
366
-         */
367
-        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), []);
368
-        if ($old_db_to_new_db_mapping) {
369
-            EE_Error::add_attention(
370
-                sprintf(
371
-                    __(
372
-                        "We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
373
-                        "event_espresso"
374
-                    ),
375
-                    $old_site_url,
376
-                    site_url()
377
-                )
378
-            );
379
-        }
380
-        $old_db_to_new_db_mapping = $this->save_data_rows_to_db(
381
-            $csv_data_array,
382
-            $export_from_site_a_to_b,
383
-            $old_db_to_new_db_mapping
384
-        );
385
-
386
-        // save the mapping from old db to new db in case they try re-importing the same data from the same website again
387
-        update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
388
-
389
-        if ($this->_total_updates > 0) {
390
-            EE_Error::add_success(
391
-                sprintf(
392
-                    __("%s existing records in the database were updated.", "event_espresso"),
393
-                    $this->_total_updates
394
-                )
395
-            );
396
-            $success = true;
397
-        }
398
-        if ($this->_total_inserts > 0) {
399
-            EE_Error::add_success(
400
-                sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
401
-            );
402
-            $success = true;
403
-        }
404
-
405
-        if ($this->_total_update_errors > 0) {
406
-            EE_Error::add_error(
407
-                sprintf(
408
-                    __(
409
-                        "'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
410
-                        "event_espresso"
411
-                    ),
412
-                    $this->_total_update_errors
413
-                ),
414
-                __FILE__,
415
-                __FUNCTION__,
416
-                __LINE__
417
-            );
418
-            $error = true;
419
-        }
420
-        if ($this->_total_insert_errors > 0) {
421
-            EE_Error::add_error(
422
-                sprintf(
423
-                    __(
424
-                        "One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
425
-                        "event_espresso"
426
-                    ),
427
-                    $this->_total_insert_errors
428
-                ),
429
-                __FILE__,
430
-                __FUNCTION__,
431
-                __LINE__
432
-            );
433
-            $error = true;
434
-        }
435
-
436
-        // lastly, we need to update the datetime and ticket sold amounts
437
-        // as those may have been affected by this
438
-        EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
439
-
440
-        // if there was at least one success and absolutely no errors
441
-        if ($success && ! $error) {
442
-            return true;
443
-        } else {
444
-            return false;
445
-        }
446
-    }
447
-
448
-
449
-    /**
450
-     * Processes the array of data, given the knowledge that it's from the same database or a different one,
451
-     * and the mapping from temporary IDs to real IDs.
452
-     * If the data is from a different database, we treat the primary keys and their corresponding
453
-     * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
454
-     * in the real target database. As items are inserted, their temporary primary keys
455
-     * are mapped to the real IDs in the target database. Also, before doing any update or
456
-     * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
457
-     * An exception: string primary keys are treated as real IDs, or else we'd need to
458
-     * dynamically generate new string primary keys which would be very awkward for the country table etc.
459
-     * Also, models with no primary key are strange too. We combine use their primary key INDEX (a
460
-     * combination of fields) to create a unique string identifying the row and store
461
-     * those in the mapping.
462
-     *
463
-     * If the data is from the same database, we usually treat primary keys as real IDs.
464
-     * An exception is if there is nothing in the database for that ID. If that's the case,
465
-     * we need to insert a new row for that ID, and then map from the non-existent ID
466
-     * to the newly-inserted real ID.
467
-     *
468
-     * @param array   $csv_data_array
469
-     * @param boolean $export_from_site_a_to_b
470
-     * @param array   $old_db_to_new_db_mapping
471
-     * @return array updated $old_db_to_new_db_mapping
472
-     * @throws EE_Error
473
-     * @throws ReflectionException
474
-     */
475
-    public function save_data_rows_to_db(
476
-        array $csv_data_array,
477
-        $export_from_site_a_to_b,
478
-        array $old_db_to_new_db_mapping
479
-    ) {
480
-        foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
481
-            // now check that assumption was correct. If
482
-            if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
483
-                $model_name = $model_name_in_csv_data;
484
-            } else {
485
-                // no table info in the array and no table name passed to the function?? FAIL
486
-                EE_Error::add_error(
487
-                    __(
488
-                        'No table information was specified and/or found, therefore the import could not be completed',
489
-                        'event_espresso'
490
-                    ),
491
-                    __FILE__,
492
-                    __FUNCTION__,
493
-                    __LINE__
494
-                );
495
-                return [];
496
-            }
497
-            /* @var $model EEM_Base */
498
-            $model = EE_Registry::instance()->load_model($model_name);
499
-
500
-            // so without further ado, scanning all the data provided for primary keys and their initial values
501
-            foreach ($model_data_from_import as $model_object_data) {
502
-                // before we do ANYTHING, make sure the csv row wasn't just completely blank
503
-                $row_is_completely_empty = true;
504
-                foreach ($model_object_data as $field) {
505
-                    if ($field) {
506
-                        $row_is_completely_empty = false;
507
-                    }
508
-                }
509
-                if ($row_is_completely_empty) {
510
-                    continue;
511
-                }
512
-                // find the PK in the row of data (or a combined key if
513
-                // there is no primary key)
514
-                if ($model->has_primary_key_field()) {
515
-                    $id_in_csv = $model_object_data[ $model->primary_key_name() ];
516
-                } else {
517
-                    $id_in_csv = $model->get_index_primary_key_string($model_object_data);
518
-                }
519
-
520
-
521
-                $model_object_data = $this->_replace_temp_ids_with_mappings(
522
-                    $model_object_data,
523
-                    $model,
524
-                    $old_db_to_new_db_mapping,
525
-                    $export_from_site_a_to_b
526
-                );
527
-                // now we need to decide if we're going to add a new model object given the $model_object_data,
528
-                // or just update.
529
-                if ($export_from_site_a_to_b) {
530
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
531
-                        $id_in_csv,
532
-                        $model_object_data,
533
-                        $model,
534
-                        $old_db_to_new_db_mapping
535
-                    );
536
-                } else {// this is just a re-import
537
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
538
-                        $id_in_csv,
539
-                        $model_object_data,
540
-                        $model
541
-                    );
542
-                }
543
-                if ($what_to_do == self::do_nothing) {
544
-                    continue;
545
-                }
546
-
547
-                // double-check we actually want to insert, if that's what we're planning
548
-                // based on whether this item would be unique in the DB or not
549
-                if ($what_to_do == self::do_insert) {
550
-                    // we're supposed to be inserting. But wait, will this thing
551
-                    // be acceptable if inserted?
552
-                    $conflicting = $model->get_one_conflicting($model_object_data, false);
553
-                    if ($conflicting) {
554
-                        // ok, this item would conflict if inserted. Just update the item that it conflicts with.
555
-                        $what_to_do = self::do_update;
556
-                        // and if this model has a primary key, remember its mapping
557
-                        if ($model->has_primary_key_field()) {
558
-                            $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
559
-                            $model_object_data[ $model->primary_key_name() ]       = $conflicting->ID();
560
-                        } else {
561
-                            // we want to update this conflicting item, instead of inserting a conflicting item
562
-                            // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
563
-                            // for the WHERE conditions in the update). At the time of this comment, there were no models like this
564
-                            foreach ($model->get_combined_primary_key_fields() as $key_field) {
565
-                                $model_object_data[ $key_field->get_name() ] = $conflicting->get(
566
-                                    $key_field->get_name()
567
-                                );
568
-                            }
569
-                        }
570
-                    }
571
-                }
572
-                if ($what_to_do == self::do_insert) {
573
-                    $old_db_to_new_db_mapping = $this->_insert_from_data_array(
574
-                        $id_in_csv,
575
-                        $model_object_data,
576
-                        $model,
577
-                        $old_db_to_new_db_mapping
578
-                    );
579
-                } elseif ($what_to_do == self::do_update) {
580
-                    $old_db_to_new_db_mapping = $this->_update_from_data_array(
581
-                        $id_in_csv,
582
-                        $model_object_data,
583
-                        $model,
584
-                        $old_db_to_new_db_mapping
585
-                    );
586
-                } else {
587
-                    throw new EE_Error(
588
-                        sprintf(
589
-                            __(
590
-                                'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
591
-                                'event_espresso'
592
-                            ),
593
-                            $what_to_do
594
-                        )
595
-                    );
596
-                }
597
-            }
598
-        }
599
-        return $old_db_to_new_db_mapping;
600
-    }
601
-
602
-
603
-    /**
604
-     * Decides whether or not to insert, given that this data is from another database.
605
-     * So, if the primary key of this $model_object_data already exists in the database,
606
-     * it's just a coincidence and we should still insert. The only time we should
607
-     * update is when we know what it maps to, or there's something that would
608
-     * conflict (and we should instead just update that conflicting thing)
609
-     *
610
-     * @param string   $id_in_csv
611
-     * @param array    $model_object_data        by reference so it can be modified
612
-     * @param EEM_Base $model
613
-     * @param array    $old_db_to_new_db_mapping by reference so it can be modified
614
-     * @return string one of the consts on this class that starts with do_*
615
-     */
616
-    protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
617
-        $id_in_csv,
618
-        $model_object_data,
619
-        $model,
620
-        $old_db_to_new_db_mapping
621
-    ) {
622
-        $model_name = $model->get_this_model_name();
623
-        // if it's a site-to-site export-and-import, see if this modelobject's id
624
-        // in the old data that we know of
625
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
626
-            return self::do_update;
627
-        } else {
628
-            return self::do_insert;
629
-        }
630
-    }
631
-
632
-
633
-    /**
634
-     * If this thing basically already exists in the database, we want to update it;
635
-     * otherwise insert it (ie, someone tweaked the CSV file, or the item was
636
-     * deleted in the database so it should be re-inserted)
637
-     *
638
-     * @param type     $id_in_csv
639
-     * @param type     $model_object_data
640
-     * @param EEM_Base $model
641
-     * @return string
642
-     * @throws EE_Error
643
-     */
644
-    protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
645
-        $id_in_csv,
646
-        $model_object_data,
647
-        $model
648
-    ) {
649
-        // in this case, check if this thing ACTUALLY exists in the database
650
-        if ($model->get_one_conflicting($model_object_data)) {
651
-            return self::do_update;
652
-        } else {
653
-            return self::do_insert;
654
-        }
655
-    }
656
-
657
-
658
-    /**
659
-     * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
660
-     * with their mapped real IDs. Eg, if importing from site A to B, the mapping
661
-     * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
662
-     * So this function searches for any event temp Ids called "my_event_id" and
663
-     * replaces them with 123.
664
-     * Also, if there is no temp ID for the INT foreign keys from another database,
665
-     * replaces them with 0 or the field's default.
666
-     *
667
-     * @param type     $model_object_data
668
-     * @param EEM_Base $model
669
-     * @param type     $old_db_to_new_db_mapping
670
-     * @param boolean  $export_from_site_a_to_b
671
-     * @return array updated model object data with temp IDs removed
672
-     * @throws EE_Error
673
-     */
674
-    protected function _replace_temp_ids_with_mappings(
675
-        $model_object_data,
676
-        $model,
677
-        $old_db_to_new_db_mapping,
678
-        $export_from_site_a_to_b
679
-    ) {
680
-        // if this model object's primary key is in the mapping, replace it
681
-        if ($model->has_primary_key_field()
682
-            && $model->get_primary_key_field()->is_auto_increment()
683
-            && isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ])
684
-            && isset(
685
-                $old_db_to_new_db_mapping[ $model->get_this_model_name(
686
-                ) ][ $model_object_data[ $model->primary_key_name() ] ]
687
-            )) {
688
-            $model_object_data[ $model->primary_key_name() ] =
689
-                $old_db_to_new_db_mapping[ $model->get_this_model_name(
690
-                ) ][ $model_object_data[ $model->primary_key_name() ] ];
691
-        }
692
-
693
-        try {
694
-            $model_name_field                      = $model->get_field_containing_related_model_name();
695
-            $models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
696
-        } catch (EE_Error $e) {
697
-            $model_name_field                      = null;
698
-            $models_pointed_to_by_model_name_field = [];
699
-        }
700
-        foreach ($model->field_settings(true) as $field_obj) {
701
-            if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
702
-                $models_pointed_to = $field_obj->get_model_names_pointed_to();
703
-                $found_a_mapping   = false;
704
-                foreach ($models_pointed_to as $model_pointed_to_by_fk) {
705
-                    if ($model_name_field) {
706
-                        $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
707
-                        if ($value_of_model_name_field == $model_pointed_to_by_fk) {
708
-                            $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
709
-                                $model_object_data[ $field_obj->get_name() ],
710
-                                $model_pointed_to_by_fk,
711
-                                $old_db_to_new_db_mapping,
712
-                                $export_from_site_a_to_b
713
-                            );
714
-                            $found_a_mapping                             = true;
715
-                            break;
716
-                        }
717
-                    } else {
718
-                        $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
719
-                            $model_object_data[ $field_obj->get_name() ],
720
-                            $model_pointed_to_by_fk,
721
-                            $old_db_to_new_db_mapping,
722
-                            $export_from_site_a_to_b
723
-                        );
724
-                        $found_a_mapping                             = true;
725
-                    }
726
-                    // once we've found a mapping for this field no need to continue
727
-                    if ($found_a_mapping) {
728
-                        break;
729
-                    }
730
-                }
731
-            } else {
732
-                // it's a string foreign key (which we leave alone, because those are things
733
-                // like country names, which we'd really rather not make 2 USAs etc (we'd actually
734
-                // prefer to just update one)
735
-                // or it's just a regular value that ought to be replaced
736
-            }
737
-        }
738
-        //
739
-        if ($model instanceof EEM_Term_Taxonomy) {
740
-            $model_object_data = $this->_handle_split_term_ids($model_object_data);
741
-        }
742
-        return $model_object_data;
743
-    }
744
-
745
-
746
-    /**
747
-     * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
748
-     * this term-taxonomy refers to may be out-of-date so we need to update it.
749
-     * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
750
-     *
751
-     * @param type $model_object_data
752
-     * @return array new model object data
753
-     */
754
-    protected function _handle_split_term_ids($model_object_data)
755
-    {
756
-        if (isset($model_object_data['term_id'])
757
-            && isset($model_object_data['taxonomy'])
758
-            && apply_filters(
759
-                'FHEE__EE_Import__handle_split_term_ids__function_exists',
760
-                function_exists('wp_get_split_term'),
761
-                $model_object_data
762
-            )) {
763
-            $new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
764
-            if ($new_term_id) {
765
-                $model_object_data['term_id'] = $new_term_id;
766
-            }
767
-        }
768
-        return $model_object_data;
769
-    }
770
-
771
-
772
-    /**
773
-     * Given the object's ID and its model's name, find it int he mapping data,
774
-     * bearing in mind where it came from
775
-     *
776
-     * @param type   $object_id
777
-     * @param string $model_name
778
-     * @param array  $old_db_to_new_db_mapping
779
-     * @param type   $export_from_site_a_to_b
780
-     * @return int
781
-     */
782
-    protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
783
-    {
784
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
785
-            return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
786
-        } elseif ($object_id == '0' || $object_id == '') {
787
-            // leave as-is
788
-            return $object_id;
789
-        } elseif ($export_from_site_a_to_b) {
790
-            // we couldn't find a mapping for this, and it's from a different site,
791
-            // so blank it out
792
-            return null;
793
-        } elseif (! $export_from_site_a_to_b) {
794
-            // we coudln't find a mapping for this, but it's from thsi DB anyway
795
-            // so let's just leave it as-is
796
-            return $object_id;
797
-        }
798
-    }
799
-
800
-
801
-    /**
802
-     *
803
-     * @param type     $id_in_csv
804
-     * @param type     $model_object_data
805
-     * @param EEM_Base $model
806
-     * @param type     $old_db_to_new_db_mapping
807
-     * @return type updated $old_db_to_new_db_mapping
808
-     * @throws EE_Error
809
-     */
810
-    protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
811
-    {
812
-        // remove the primary key, if there is one (we don't want it for inserts OR updates)
813
-        // we'll put it back in if we need it
814
-        if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
815
-            $effective_id = $model_object_data[ $model->primary_key_name() ];
816
-            unset($model_object_data[ $model->primary_key_name() ]);
817
-        } else {
818
-            $effective_id = $model->get_index_primary_key_string($model_object_data);
819
-        }
820
-        // the model takes care of validating the CSV's input
821
-        try {
822
-            $new_id = $model->insert($model_object_data);
823
-            if ($new_id) {
824
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
825
-                $this->_total_inserts++;
826
-                EE_Error::add_success(
827
-                    sprintf(
828
-                        __("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
829
-                        $model->get_this_model_name(),
830
-                        $new_id,
831
-                        implode(",", $model_object_data)
832
-                    )
833
-                );
834
-            } else {
835
-                $this->_total_insert_errors++;
836
-                // put the ID used back in there for the error message
837
-                if ($model->has_primary_key_field()) {
838
-                    $model_object_data[ $model->primary_key_name() ] = $effective_id;
839
-                }
840
-                EE_Error::add_error(
841
-                    sprintf(
842
-                        __("Could not insert new %s with the csv data: %s", "event_espresso"),
843
-                        $model->get_this_model_name(),
844
-                        http_build_query($model_object_data)
845
-                    ),
846
-                    __FILE__,
847
-                    __FUNCTION__,
848
-                    __LINE__
849
-                );
850
-            }
851
-        } catch (EE_Error $e) {
852
-            $this->_total_insert_errors++;
853
-            if ($model->has_primary_key_field()) {
854
-                $model_object_data[ $model->primary_key_name() ] = $effective_id;
855
-            }
856
-            EE_Error::add_error(
857
-                sprintf(
858
-                    __("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
859
-                    $model->get_this_model_name(),
860
-                    implode(",", $model_object_data),
861
-                    $e->getMessage()
862
-                ),
863
-                __FILE__,
864
-                __FUNCTION__,
865
-                __LINE__
866
-            );
867
-        }
868
-        return $old_db_to_new_db_mapping;
869
-    }
870
-
871
-
872
-    /**
873
-     * Given the model object data, finds the row to update and updates it
874
-     *
875
-     * @param string|int $id_in_csv
876
-     * @param array      $model_object_data
877
-     * @param EEM_Base   $model
878
-     * @param array      $old_db_to_new_db_mapping
879
-     * @return array updated $old_db_to_new_db_mapping
880
-     */
881
-    protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
882
-    {
883
-        try {
884
-            // let's keep two copies of the model object data:
885
-            // one for performing an update, one for everthing else
886
-            $model_object_data_for_update = $model_object_data;
887
-            if ($model->has_primary_key_field()) {
888
-                $conditions = [$model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]];
889
-                // remove the primary key because we shouldn't use it for updating
890
-                unset($model_object_data_for_update[ $model->primary_key_name() ]);
891
-            } elseif ($model->get_combined_primary_key_fields() > 1) {
892
-                $conditions = [];
893
-                foreach ($model->get_combined_primary_key_fields() as $key_field) {
894
-                    $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
895
-                }
896
-            } else {
897
-                $model->primary_key_name(
898
-                );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
899
-            }
900
-
901
-            $success = $model->update($model_object_data_for_update, [$conditions]);
902
-            if ($success) {
903
-                $this->_total_updates++;
904
-                EE_Error::add_success(
905
-                    sprintf(
906
-                        __("Successfully updated %s with csv data %s", "event_espresso"),
907
-                        $model->get_this_model_name(),
908
-                        implode(",", $model_object_data_for_update)
909
-                    )
910
-                );
911
-                // we should still record the mapping even though it was an update
912
-                // because if we were going to insert somethign but it was going to conflict
913
-                // we would have last-minute decided to update. So we'd like to know what we updated
914
-                // and so we record what record ended up being updated using the mapping
915
-                if ($model->has_primary_key_field()) {
916
-                    $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
917
-                } else {
918
-                    // no primary key just a combined key
919
-                    $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
920
-                }
921
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
922
-            } else {
923
-                $matched_items = $model->get_all([$conditions]);
924
-                if (! $matched_items) {
925
-                    // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
926
-                    $this->_total_update_errors++;
927
-                    EE_Error::add_error(
928
-                        sprintf(
929
-                            __(
930
-                                "Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
931
-                                "event_espresso"
932
-                            ),
933
-                            $model->get_this_model_name(),
934
-                            http_build_query($model_object_data),
935
-                            http_build_query($conditions)
936
-                        ),
937
-                        __FILE__,
938
-                        __FUNCTION__,
939
-                        __LINE__
940
-                    );
941
-                } else {
942
-                    $this->_total_updates++;
943
-                    EE_Error::add_success(
944
-                        sprintf(
945
-                            __(
946
-                                "%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
947
-                                "event_espresso"
948
-                            ),
949
-                            $model->get_this_model_name(),
950
-                            implode(",", $model_object_data)
951
-                        )
952
-                    );
953
-                }
954
-            }
955
-        } catch (EE_Error $e) {
956
-            $this->_total_update_errors++;
957
-            $basic_message = sprintf(
958
-                __("Could not update %s with the csv data: %s because %s", "event_espresso"),
959
-                $model->get_this_model_name(),
960
-                implode(",", $model_object_data),
961
-                $e->getMessage()
962
-            );
963
-            $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
964
-            EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
965
-        }
966
-        return $old_db_to_new_db_mapping;
967
-    }
968
-
969
-
970
-    /**
971
-     * Gets the number of inserts performed since importer was instantiated or reset
972
-     *
973
-     * @return int
974
-     */
975
-    public function get_total_inserts()
976
-    {
977
-        return $this->_total_inserts;
978
-    }
979
-
980
-
981
-    /**
982
-     *  Gets the number of insert errors since importer was instantiated or reset
983
-     *
984
-     * @return int
985
-     */
986
-    public function get_total_insert_errors()
987
-    {
988
-        return $this->_total_insert_errors;
989
-    }
990
-
991
-
992
-    /**
993
-     *  Gets the number of updates performed since importer was instantiated or reset
994
-     *
995
-     * @return int
996
-     */
997
-    public function get_total_updates()
998
-    {
999
-        return $this->_total_updates;
1000
-    }
1001
-
1002
-
1003
-    /**
1004
-     *  Gets the number of update errors since importer was instantiated or reset
1005
-     *
1006
-     * @return int
1007
-     */
1008
-    public function get_total_update_errors()
1009
-    {
1010
-        return $this->_total_update_errors;
1011
-    }
131
+		$uploader = ob_get_clean();
132
+		return $uploader;
133
+	}
134
+
135
+
136
+	/**
137
+	 * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
138
+	 * @access public
139
+	 * @return boolean success
140
+	 * @throws EE_Error
141
+	 */
142
+	public function import()
143
+	{
144
+
145
+		require_once(EE_CLASSES . 'EE_CSV.class.php');
146
+		$this->EE_CSV = EE_CSV::instance();
147
+
148
+		if (isset($_REQUEST['import'])) {
149
+			if (isset($_POST['csv_submitted'])) {
150
+				switch ($_FILES['file']['error'][0]) {
151
+					case UPLOAD_ERR_OK:
152
+						$error_msg = false;
153
+						break;
154
+					case UPLOAD_ERR_INI_SIZE:
155
+						$error_msg = __(
156
+							"'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
157
+							"event_espresso"
158
+						);
159
+						break;
160
+					case UPLOAD_ERR_FORM_SIZE:
161
+						$error_msg = __(
162
+							'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
163
+							"event_espresso"
164
+						);
165
+						break;
166
+					case UPLOAD_ERR_PARTIAL:
167
+						$error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
168
+						break;
169
+					case UPLOAD_ERR_NO_FILE:
170
+						$error_msg = __('No file was uploaded.', "event_espresso");
171
+						break;
172
+					case UPLOAD_ERR_NO_TMP_DIR:
173
+						$error_msg = __('Missing a temporary folder.', "event_espresso");
174
+						break;
175
+					case UPLOAD_ERR_CANT_WRITE:
176
+						$error_msg = __('Failed to write file to disk.', "event_espresso");
177
+						break;
178
+					case UPLOAD_ERR_EXTENSION:
179
+						$error_msg = __('File upload stopped by extension.', "event_espresso");
180
+						break;
181
+					default:
182
+						$error_msg = __(
183
+							'An unknown error occurred and the file could not be uploaded',
184
+							"event_espresso"
185
+						);
186
+						break;
187
+				}
188
+
189
+				if (! $error_msg) {
190
+					$filename  = $_FILES['file']['name'][0];
191
+					$file_ext  = substr(strrchr($filename, '.'), 1);
192
+					$file_type = $_FILES['file']['type'][0];
193
+					$temp_file = $_FILES['file']['tmp_name'][0];
194
+					$filesize  = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
195
+
196
+					if ($file_ext == 'csv') {
197
+						$max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
198
+						if ($filesize < $max_upload || true) {
199
+							$wp_upload_dir = str_replace(['\\', '/'], '/', wp_upload_dir());
200
+							$path_to_file  = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
201
+
202
+							if (move_uploaded_file($temp_file, $path_to_file)) {
203
+								// convert csv to array
204
+								$this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
205
+
206
+								// was data successfully stored in an array?
207
+								if (is_array($this->csv_array)) {
208
+									$import_what           = str_replace('csv_import_', '', $_REQUEST['action']);
209
+									$import_what           = str_replace('_', ' ', ucwords($import_what));
210
+									$processed_data        = $this->csv_array;
211
+									$this->columns_to_save = false;
212
+
213
+									// if any imports require funcky processing, we'll catch them in the switch
214
+									switch ($_REQUEST['action']) {
215
+										case "import_events":
216
+										case "event_list":
217
+											$import_what = 'Event Details';
218
+											break;
219
+
220
+										case 'groupon_import_csv':
221
+											$import_what    = 'Groupon Codes';
222
+											$processed_data = $this->process_groupon_codes();
223
+											break;
224
+									}
225
+									// save processed codes to db
226
+									if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
227
+										return true;
228
+									}
229
+								} else {
230
+									// no array? must be an error
231
+									EE_Error::add_error(
232
+										sprintf(__("No file seems to have been uploaded", "event_espresso")),
233
+										__FILE__,
234
+										__FUNCTION__,
235
+										__LINE__
236
+									);
237
+									return false;
238
+								}
239
+							} else {
240
+								EE_Error::add_error(
241
+									sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
242
+									__FILE__,
243
+									__FUNCTION__,
244
+									__LINE__
245
+								);
246
+								return false;
247
+							}
248
+						} else {
249
+							EE_Error::add_error(
250
+								sprintf(
251
+									__(
252
+										"%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
253
+										"event_espresso"
254
+									),
255
+									$filename,
256
+									$max_upload
257
+								),
258
+								__FILE__,
259
+								__FUNCTION__,
260
+								__LINE__
261
+							);
262
+							return false;
263
+						}
264
+					} else {
265
+						EE_Error::add_error(
266
+							sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
267
+							__FILE__,
268
+							__FUNCTION__,
269
+							__LINE__
270
+						);
271
+						return false;
272
+					}
273
+				} else {
274
+					EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
275
+					return false;
276
+				}
277
+			}
278
+		}
279
+		return;
280
+	}
281
+
282
+
283
+	/**
284
+	 *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
285
+	 *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
286
+	 *    next level being numeric indexes adn each value representing a model object, and the last layer down
287
+	 *    being keys of model fields and their proposed values.
288
+	 *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
289
+	 *    If the CSV data says (in the metadata row) that it's from the SAME database,
290
+	 *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
291
+	 *    IDs DON'T exist in the database, they're treated as temporary IDs,
292
+	 *    which can used elsewhere to refer to the same object. Once an item
293
+	 *    with a temporary ID gets inserted, we record its mapping from temporary
294
+	 *    ID to real ID, and use the real ID in place of the temporary ID
295
+	 *    when that temporary ID was used as a foreign key.
296
+	 *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
297
+	 *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
298
+	 *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
299
+	 *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
300
+	 *    An important exception are non-auto-increment primary keys. If one entry in the
301
+	 *    CSV file has the same ID as one in the DB, we assume they are meant to be
302
+	 *    the same item, and instead update the item in the DB with that same ID.
303
+	 *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
304
+	 *    time you import a CSV from a different site, we remember their mappings, and
305
+	 * will try to update the item in the DB instead of inserting another item (eg
306
+	 * if we previously imported an event with temporary ID 1, and then it got a
307
+	 * real ID of 123, we remember that. So the next time we import an event with
308
+	 * temporary ID, from the same site, we know that it's real ID is 123, and will
309
+	 * update that event, instead of adding a new event).
310
+	 *
311
+	 * @access public
312
+	 * @param array $csv_data_array - the array containing the csv data produced from
313
+	 *                              EE_CSV::import_csv_to_model_data_array()
314
+	 * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
315
+	 *                              fields they will be saved to
316
+	 * @return TRUE on success, FALSE on fail
317
+	 * @throws \EE_Error
318
+	 */
319
+	public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
320
+	{
321
+		$success = false;
322
+		$error   = false;
323
+		// whther to treat this import as if it's data froma different database or not
324
+		// ie, if it IS from a different database, ignore foreign keys whihf
325
+		$export_from_site_a_to_b = true;
326
+		// first level of array is not table information but a table name was passed to the function
327
+		// array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
328
+		if ($model_name) {
329
+			$csv_data_array = [$csv_data_array];
330
+		}
331
+		// begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
332
+		$old_site_url = 'none-specified';
333
+		// hanlde metadata
334
+		if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
335
+			$csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
336
+			// ok so its metadata, dont try to save it to ehte db obviously...
337
+			if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
338
+				EE_Error::add_attention(
339
+					sprintf(
340
+						__(
341
+							"CSV Data appears to be from the same database, so attempting to update data",
342
+							"event_espresso"
343
+						)
344
+					)
345
+				);
346
+				$export_from_site_a_to_b = false;
347
+			} else {
348
+				$old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
349
+				EE_Error::add_attention(
350
+					sprintf(
351
+						__(
352
+							"CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
353
+							"event_espresso"
354
+						),
355
+						$old_site_url,
356
+						site_url()
357
+					)
358
+				);
359
+			};
360
+			unset($csv_data_array[ EE_CSV::metadata_header ]);
361
+		}
362
+		/**
363
+		 * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
364
+		 * the value will be the newly-inserted ID.
365
+		 * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
366
+		 */
367
+		$old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), []);
368
+		if ($old_db_to_new_db_mapping) {
369
+			EE_Error::add_attention(
370
+				sprintf(
371
+					__(
372
+						"We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
373
+						"event_espresso"
374
+					),
375
+					$old_site_url,
376
+					site_url()
377
+				)
378
+			);
379
+		}
380
+		$old_db_to_new_db_mapping = $this->save_data_rows_to_db(
381
+			$csv_data_array,
382
+			$export_from_site_a_to_b,
383
+			$old_db_to_new_db_mapping
384
+		);
385
+
386
+		// save the mapping from old db to new db in case they try re-importing the same data from the same website again
387
+		update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
388
+
389
+		if ($this->_total_updates > 0) {
390
+			EE_Error::add_success(
391
+				sprintf(
392
+					__("%s existing records in the database were updated.", "event_espresso"),
393
+					$this->_total_updates
394
+				)
395
+			);
396
+			$success = true;
397
+		}
398
+		if ($this->_total_inserts > 0) {
399
+			EE_Error::add_success(
400
+				sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
401
+			);
402
+			$success = true;
403
+		}
404
+
405
+		if ($this->_total_update_errors > 0) {
406
+			EE_Error::add_error(
407
+				sprintf(
408
+					__(
409
+						"'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
410
+						"event_espresso"
411
+					),
412
+					$this->_total_update_errors
413
+				),
414
+				__FILE__,
415
+				__FUNCTION__,
416
+				__LINE__
417
+			);
418
+			$error = true;
419
+		}
420
+		if ($this->_total_insert_errors > 0) {
421
+			EE_Error::add_error(
422
+				sprintf(
423
+					__(
424
+						"One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
425
+						"event_espresso"
426
+					),
427
+					$this->_total_insert_errors
428
+				),
429
+				__FILE__,
430
+				__FUNCTION__,
431
+				__LINE__
432
+			);
433
+			$error = true;
434
+		}
435
+
436
+		// lastly, we need to update the datetime and ticket sold amounts
437
+		// as those may have been affected by this
438
+		EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
439
+
440
+		// if there was at least one success and absolutely no errors
441
+		if ($success && ! $error) {
442
+			return true;
443
+		} else {
444
+			return false;
445
+		}
446
+	}
447
+
448
+
449
+	/**
450
+	 * Processes the array of data, given the knowledge that it's from the same database or a different one,
451
+	 * and the mapping from temporary IDs to real IDs.
452
+	 * If the data is from a different database, we treat the primary keys and their corresponding
453
+	 * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
454
+	 * in the real target database. As items are inserted, their temporary primary keys
455
+	 * are mapped to the real IDs in the target database. Also, before doing any update or
456
+	 * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
457
+	 * An exception: string primary keys are treated as real IDs, or else we'd need to
458
+	 * dynamically generate new string primary keys which would be very awkward for the country table etc.
459
+	 * Also, models with no primary key are strange too. We combine use their primary key INDEX (a
460
+	 * combination of fields) to create a unique string identifying the row and store
461
+	 * those in the mapping.
462
+	 *
463
+	 * If the data is from the same database, we usually treat primary keys as real IDs.
464
+	 * An exception is if there is nothing in the database for that ID. If that's the case,
465
+	 * we need to insert a new row for that ID, and then map from the non-existent ID
466
+	 * to the newly-inserted real ID.
467
+	 *
468
+	 * @param array   $csv_data_array
469
+	 * @param boolean $export_from_site_a_to_b
470
+	 * @param array   $old_db_to_new_db_mapping
471
+	 * @return array updated $old_db_to_new_db_mapping
472
+	 * @throws EE_Error
473
+	 * @throws ReflectionException
474
+	 */
475
+	public function save_data_rows_to_db(
476
+		array $csv_data_array,
477
+		$export_from_site_a_to_b,
478
+		array $old_db_to_new_db_mapping
479
+	) {
480
+		foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
481
+			// now check that assumption was correct. If
482
+			if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
483
+				$model_name = $model_name_in_csv_data;
484
+			} else {
485
+				// no table info in the array and no table name passed to the function?? FAIL
486
+				EE_Error::add_error(
487
+					__(
488
+						'No table information was specified and/or found, therefore the import could not be completed',
489
+						'event_espresso'
490
+					),
491
+					__FILE__,
492
+					__FUNCTION__,
493
+					__LINE__
494
+				);
495
+				return [];
496
+			}
497
+			/* @var $model EEM_Base */
498
+			$model = EE_Registry::instance()->load_model($model_name);
499
+
500
+			// so without further ado, scanning all the data provided for primary keys and their initial values
501
+			foreach ($model_data_from_import as $model_object_data) {
502
+				// before we do ANYTHING, make sure the csv row wasn't just completely blank
503
+				$row_is_completely_empty = true;
504
+				foreach ($model_object_data as $field) {
505
+					if ($field) {
506
+						$row_is_completely_empty = false;
507
+					}
508
+				}
509
+				if ($row_is_completely_empty) {
510
+					continue;
511
+				}
512
+				// find the PK in the row of data (or a combined key if
513
+				// there is no primary key)
514
+				if ($model->has_primary_key_field()) {
515
+					$id_in_csv = $model_object_data[ $model->primary_key_name() ];
516
+				} else {
517
+					$id_in_csv = $model->get_index_primary_key_string($model_object_data);
518
+				}
519
+
520
+
521
+				$model_object_data = $this->_replace_temp_ids_with_mappings(
522
+					$model_object_data,
523
+					$model,
524
+					$old_db_to_new_db_mapping,
525
+					$export_from_site_a_to_b
526
+				);
527
+				// now we need to decide if we're going to add a new model object given the $model_object_data,
528
+				// or just update.
529
+				if ($export_from_site_a_to_b) {
530
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
531
+						$id_in_csv,
532
+						$model_object_data,
533
+						$model,
534
+						$old_db_to_new_db_mapping
535
+					);
536
+				} else {// this is just a re-import
537
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
538
+						$id_in_csv,
539
+						$model_object_data,
540
+						$model
541
+					);
542
+				}
543
+				if ($what_to_do == self::do_nothing) {
544
+					continue;
545
+				}
546
+
547
+				// double-check we actually want to insert, if that's what we're planning
548
+				// based on whether this item would be unique in the DB or not
549
+				if ($what_to_do == self::do_insert) {
550
+					// we're supposed to be inserting. But wait, will this thing
551
+					// be acceptable if inserted?
552
+					$conflicting = $model->get_one_conflicting($model_object_data, false);
553
+					if ($conflicting) {
554
+						// ok, this item would conflict if inserted. Just update the item that it conflicts with.
555
+						$what_to_do = self::do_update;
556
+						// and if this model has a primary key, remember its mapping
557
+						if ($model->has_primary_key_field()) {
558
+							$old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
559
+							$model_object_data[ $model->primary_key_name() ]       = $conflicting->ID();
560
+						} else {
561
+							// we want to update this conflicting item, instead of inserting a conflicting item
562
+							// so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
563
+							// for the WHERE conditions in the update). At the time of this comment, there were no models like this
564
+							foreach ($model->get_combined_primary_key_fields() as $key_field) {
565
+								$model_object_data[ $key_field->get_name() ] = $conflicting->get(
566
+									$key_field->get_name()
567
+								);
568
+							}
569
+						}
570
+					}
571
+				}
572
+				if ($what_to_do == self::do_insert) {
573
+					$old_db_to_new_db_mapping = $this->_insert_from_data_array(
574
+						$id_in_csv,
575
+						$model_object_data,
576
+						$model,
577
+						$old_db_to_new_db_mapping
578
+					);
579
+				} elseif ($what_to_do == self::do_update) {
580
+					$old_db_to_new_db_mapping = $this->_update_from_data_array(
581
+						$id_in_csv,
582
+						$model_object_data,
583
+						$model,
584
+						$old_db_to_new_db_mapping
585
+					);
586
+				} else {
587
+					throw new EE_Error(
588
+						sprintf(
589
+							__(
590
+								'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
591
+								'event_espresso'
592
+							),
593
+							$what_to_do
594
+						)
595
+					);
596
+				}
597
+			}
598
+		}
599
+		return $old_db_to_new_db_mapping;
600
+	}
601
+
602
+
603
+	/**
604
+	 * Decides whether or not to insert, given that this data is from another database.
605
+	 * So, if the primary key of this $model_object_data already exists in the database,
606
+	 * it's just a coincidence and we should still insert. The only time we should
607
+	 * update is when we know what it maps to, or there's something that would
608
+	 * conflict (and we should instead just update that conflicting thing)
609
+	 *
610
+	 * @param string   $id_in_csv
611
+	 * @param array    $model_object_data        by reference so it can be modified
612
+	 * @param EEM_Base $model
613
+	 * @param array    $old_db_to_new_db_mapping by reference so it can be modified
614
+	 * @return string one of the consts on this class that starts with do_*
615
+	 */
616
+	protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
617
+		$id_in_csv,
618
+		$model_object_data,
619
+		$model,
620
+		$old_db_to_new_db_mapping
621
+	) {
622
+		$model_name = $model->get_this_model_name();
623
+		// if it's a site-to-site export-and-import, see if this modelobject's id
624
+		// in the old data that we know of
625
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
626
+			return self::do_update;
627
+		} else {
628
+			return self::do_insert;
629
+		}
630
+	}
631
+
632
+
633
+	/**
634
+	 * If this thing basically already exists in the database, we want to update it;
635
+	 * otherwise insert it (ie, someone tweaked the CSV file, or the item was
636
+	 * deleted in the database so it should be re-inserted)
637
+	 *
638
+	 * @param type     $id_in_csv
639
+	 * @param type     $model_object_data
640
+	 * @param EEM_Base $model
641
+	 * @return string
642
+	 * @throws EE_Error
643
+	 */
644
+	protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
645
+		$id_in_csv,
646
+		$model_object_data,
647
+		$model
648
+	) {
649
+		// in this case, check if this thing ACTUALLY exists in the database
650
+		if ($model->get_one_conflicting($model_object_data)) {
651
+			return self::do_update;
652
+		} else {
653
+			return self::do_insert;
654
+		}
655
+	}
656
+
657
+
658
+	/**
659
+	 * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
660
+	 * with their mapped real IDs. Eg, if importing from site A to B, the mapping
661
+	 * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
662
+	 * So this function searches for any event temp Ids called "my_event_id" and
663
+	 * replaces them with 123.
664
+	 * Also, if there is no temp ID for the INT foreign keys from another database,
665
+	 * replaces them with 0 or the field's default.
666
+	 *
667
+	 * @param type     $model_object_data
668
+	 * @param EEM_Base $model
669
+	 * @param type     $old_db_to_new_db_mapping
670
+	 * @param boolean  $export_from_site_a_to_b
671
+	 * @return array updated model object data with temp IDs removed
672
+	 * @throws EE_Error
673
+	 */
674
+	protected function _replace_temp_ids_with_mappings(
675
+		$model_object_data,
676
+		$model,
677
+		$old_db_to_new_db_mapping,
678
+		$export_from_site_a_to_b
679
+	) {
680
+		// if this model object's primary key is in the mapping, replace it
681
+		if ($model->has_primary_key_field()
682
+			&& $model->get_primary_key_field()->is_auto_increment()
683
+			&& isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ])
684
+			&& isset(
685
+				$old_db_to_new_db_mapping[ $model->get_this_model_name(
686
+				) ][ $model_object_data[ $model->primary_key_name() ] ]
687
+			)) {
688
+			$model_object_data[ $model->primary_key_name() ] =
689
+				$old_db_to_new_db_mapping[ $model->get_this_model_name(
690
+				) ][ $model_object_data[ $model->primary_key_name() ] ];
691
+		}
692
+
693
+		try {
694
+			$model_name_field                      = $model->get_field_containing_related_model_name();
695
+			$models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
696
+		} catch (EE_Error $e) {
697
+			$model_name_field                      = null;
698
+			$models_pointed_to_by_model_name_field = [];
699
+		}
700
+		foreach ($model->field_settings(true) as $field_obj) {
701
+			if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
702
+				$models_pointed_to = $field_obj->get_model_names_pointed_to();
703
+				$found_a_mapping   = false;
704
+				foreach ($models_pointed_to as $model_pointed_to_by_fk) {
705
+					if ($model_name_field) {
706
+						$value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
707
+						if ($value_of_model_name_field == $model_pointed_to_by_fk) {
708
+							$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
709
+								$model_object_data[ $field_obj->get_name() ],
710
+								$model_pointed_to_by_fk,
711
+								$old_db_to_new_db_mapping,
712
+								$export_from_site_a_to_b
713
+							);
714
+							$found_a_mapping                             = true;
715
+							break;
716
+						}
717
+					} else {
718
+						$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
719
+							$model_object_data[ $field_obj->get_name() ],
720
+							$model_pointed_to_by_fk,
721
+							$old_db_to_new_db_mapping,
722
+							$export_from_site_a_to_b
723
+						);
724
+						$found_a_mapping                             = true;
725
+					}
726
+					// once we've found a mapping for this field no need to continue
727
+					if ($found_a_mapping) {
728
+						break;
729
+					}
730
+				}
731
+			} else {
732
+				// it's a string foreign key (which we leave alone, because those are things
733
+				// like country names, which we'd really rather not make 2 USAs etc (we'd actually
734
+				// prefer to just update one)
735
+				// or it's just a regular value that ought to be replaced
736
+			}
737
+		}
738
+		//
739
+		if ($model instanceof EEM_Term_Taxonomy) {
740
+			$model_object_data = $this->_handle_split_term_ids($model_object_data);
741
+		}
742
+		return $model_object_data;
743
+	}
744
+
745
+
746
+	/**
747
+	 * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
748
+	 * this term-taxonomy refers to may be out-of-date so we need to update it.
749
+	 * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
750
+	 *
751
+	 * @param type $model_object_data
752
+	 * @return array new model object data
753
+	 */
754
+	protected function _handle_split_term_ids($model_object_data)
755
+	{
756
+		if (isset($model_object_data['term_id'])
757
+			&& isset($model_object_data['taxonomy'])
758
+			&& apply_filters(
759
+				'FHEE__EE_Import__handle_split_term_ids__function_exists',
760
+				function_exists('wp_get_split_term'),
761
+				$model_object_data
762
+			)) {
763
+			$new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
764
+			if ($new_term_id) {
765
+				$model_object_data['term_id'] = $new_term_id;
766
+			}
767
+		}
768
+		return $model_object_data;
769
+	}
770
+
771
+
772
+	/**
773
+	 * Given the object's ID and its model's name, find it int he mapping data,
774
+	 * bearing in mind where it came from
775
+	 *
776
+	 * @param type   $object_id
777
+	 * @param string $model_name
778
+	 * @param array  $old_db_to_new_db_mapping
779
+	 * @param type   $export_from_site_a_to_b
780
+	 * @return int
781
+	 */
782
+	protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
783
+	{
784
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
785
+			return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
786
+		} elseif ($object_id == '0' || $object_id == '') {
787
+			// leave as-is
788
+			return $object_id;
789
+		} elseif ($export_from_site_a_to_b) {
790
+			// we couldn't find a mapping for this, and it's from a different site,
791
+			// so blank it out
792
+			return null;
793
+		} elseif (! $export_from_site_a_to_b) {
794
+			// we coudln't find a mapping for this, but it's from thsi DB anyway
795
+			// so let's just leave it as-is
796
+			return $object_id;
797
+		}
798
+	}
799
+
800
+
801
+	/**
802
+	 *
803
+	 * @param type     $id_in_csv
804
+	 * @param type     $model_object_data
805
+	 * @param EEM_Base $model
806
+	 * @param type     $old_db_to_new_db_mapping
807
+	 * @return type updated $old_db_to_new_db_mapping
808
+	 * @throws EE_Error
809
+	 */
810
+	protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
811
+	{
812
+		// remove the primary key, if there is one (we don't want it for inserts OR updates)
813
+		// we'll put it back in if we need it
814
+		if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
815
+			$effective_id = $model_object_data[ $model->primary_key_name() ];
816
+			unset($model_object_data[ $model->primary_key_name() ]);
817
+		} else {
818
+			$effective_id = $model->get_index_primary_key_string($model_object_data);
819
+		}
820
+		// the model takes care of validating the CSV's input
821
+		try {
822
+			$new_id = $model->insert($model_object_data);
823
+			if ($new_id) {
824
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
825
+				$this->_total_inserts++;
826
+				EE_Error::add_success(
827
+					sprintf(
828
+						__("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
829
+						$model->get_this_model_name(),
830
+						$new_id,
831
+						implode(",", $model_object_data)
832
+					)
833
+				);
834
+			} else {
835
+				$this->_total_insert_errors++;
836
+				// put the ID used back in there for the error message
837
+				if ($model->has_primary_key_field()) {
838
+					$model_object_data[ $model->primary_key_name() ] = $effective_id;
839
+				}
840
+				EE_Error::add_error(
841
+					sprintf(
842
+						__("Could not insert new %s with the csv data: %s", "event_espresso"),
843
+						$model->get_this_model_name(),
844
+						http_build_query($model_object_data)
845
+					),
846
+					__FILE__,
847
+					__FUNCTION__,
848
+					__LINE__
849
+				);
850
+			}
851
+		} catch (EE_Error $e) {
852
+			$this->_total_insert_errors++;
853
+			if ($model->has_primary_key_field()) {
854
+				$model_object_data[ $model->primary_key_name() ] = $effective_id;
855
+			}
856
+			EE_Error::add_error(
857
+				sprintf(
858
+					__("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
859
+					$model->get_this_model_name(),
860
+					implode(",", $model_object_data),
861
+					$e->getMessage()
862
+				),
863
+				__FILE__,
864
+				__FUNCTION__,
865
+				__LINE__
866
+			);
867
+		}
868
+		return $old_db_to_new_db_mapping;
869
+	}
870
+
871
+
872
+	/**
873
+	 * Given the model object data, finds the row to update and updates it
874
+	 *
875
+	 * @param string|int $id_in_csv
876
+	 * @param array      $model_object_data
877
+	 * @param EEM_Base   $model
878
+	 * @param array      $old_db_to_new_db_mapping
879
+	 * @return array updated $old_db_to_new_db_mapping
880
+	 */
881
+	protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
882
+	{
883
+		try {
884
+			// let's keep two copies of the model object data:
885
+			// one for performing an update, one for everthing else
886
+			$model_object_data_for_update = $model_object_data;
887
+			if ($model->has_primary_key_field()) {
888
+				$conditions = [$model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]];
889
+				// remove the primary key because we shouldn't use it for updating
890
+				unset($model_object_data_for_update[ $model->primary_key_name() ]);
891
+			} elseif ($model->get_combined_primary_key_fields() > 1) {
892
+				$conditions = [];
893
+				foreach ($model->get_combined_primary_key_fields() as $key_field) {
894
+					$conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
895
+				}
896
+			} else {
897
+				$model->primary_key_name(
898
+				);// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
899
+			}
900
+
901
+			$success = $model->update($model_object_data_for_update, [$conditions]);
902
+			if ($success) {
903
+				$this->_total_updates++;
904
+				EE_Error::add_success(
905
+					sprintf(
906
+						__("Successfully updated %s with csv data %s", "event_espresso"),
907
+						$model->get_this_model_name(),
908
+						implode(",", $model_object_data_for_update)
909
+					)
910
+				);
911
+				// we should still record the mapping even though it was an update
912
+				// because if we were going to insert somethign but it was going to conflict
913
+				// we would have last-minute decided to update. So we'd like to know what we updated
914
+				// and so we record what record ended up being updated using the mapping
915
+				if ($model->has_primary_key_field()) {
916
+					$new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
917
+				} else {
918
+					// no primary key just a combined key
919
+					$new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
920
+				}
921
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
922
+			} else {
923
+				$matched_items = $model->get_all([$conditions]);
924
+				if (! $matched_items) {
925
+					// no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
926
+					$this->_total_update_errors++;
927
+					EE_Error::add_error(
928
+						sprintf(
929
+							__(
930
+								"Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
931
+								"event_espresso"
932
+							),
933
+							$model->get_this_model_name(),
934
+							http_build_query($model_object_data),
935
+							http_build_query($conditions)
936
+						),
937
+						__FILE__,
938
+						__FUNCTION__,
939
+						__LINE__
940
+					);
941
+				} else {
942
+					$this->_total_updates++;
943
+					EE_Error::add_success(
944
+						sprintf(
945
+							__(
946
+								"%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
947
+								"event_espresso"
948
+							),
949
+							$model->get_this_model_name(),
950
+							implode(",", $model_object_data)
951
+						)
952
+					);
953
+				}
954
+			}
955
+		} catch (EE_Error $e) {
956
+			$this->_total_update_errors++;
957
+			$basic_message = sprintf(
958
+				__("Could not update %s with the csv data: %s because %s", "event_espresso"),
959
+				$model->get_this_model_name(),
960
+				implode(",", $model_object_data),
961
+				$e->getMessage()
962
+			);
963
+			$debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
964
+			EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
965
+		}
966
+		return $old_db_to_new_db_mapping;
967
+	}
968
+
969
+
970
+	/**
971
+	 * Gets the number of inserts performed since importer was instantiated or reset
972
+	 *
973
+	 * @return int
974
+	 */
975
+	public function get_total_inserts()
976
+	{
977
+		return $this->_total_inserts;
978
+	}
979
+
980
+
981
+	/**
982
+	 *  Gets the number of insert errors since importer was instantiated or reset
983
+	 *
984
+	 * @return int
985
+	 */
986
+	public function get_total_insert_errors()
987
+	{
988
+		return $this->_total_insert_errors;
989
+	}
990
+
991
+
992
+	/**
993
+	 *  Gets the number of updates performed since importer was instantiated or reset
994
+	 *
995
+	 * @return int
996
+	 */
997
+	public function get_total_updates()
998
+	{
999
+		return $this->_total_updates;
1000
+	}
1001
+
1002
+
1003
+	/**
1004
+	 *  Gets the number of update errors since importer was instantiated or reset
1005
+	 *
1006
+	 * @return int
1007
+	 */
1008
+	public function get_total_update_errors()
1009
+	{
1010
+		return $this->_total_update_errors;
1011
+	}
1012 1012
 }
Please login to merge, or discard this patch.
Spacing   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
     public function import()
143 143
     {
144 144
 
145
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
145
+        require_once(EE_CLASSES.'EE_CSV.class.php');
146 146
         $this->EE_CSV = EE_CSV::instance();
147 147
 
148 148
         if (isset($_REQUEST['import'])) {
@@ -186,18 +186,18 @@  discard block
 block discarded – undo
186 186
                         break;
187 187
                 }
188 188
 
189
-                if (! $error_msg) {
189
+                if ( ! $error_msg) {
190 190
                     $filename  = $_FILES['file']['name'][0];
191 191
                     $file_ext  = substr(strrchr($filename, '.'), 1);
192 192
                     $file_type = $_FILES['file']['type'][0];
193 193
                     $temp_file = $_FILES['file']['tmp_name'][0];
194
-                    $filesize  = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
194
+                    $filesize  = $_FILES['file']['size'][0] / 1024; // convert from bytes to KB
195 195
 
196 196
                     if ($file_ext == 'csv') {
197
-                        $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
197
+                        $max_upload = $this->EE_CSV->get_max_upload_size(); // max upload size in KB
198 198
                         if ($filesize < $max_upload || true) {
199 199
                             $wp_upload_dir = str_replace(['\\', '/'], '/', wp_upload_dir());
200
-                            $path_to_file  = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
200
+                            $path_to_file  = $wp_upload_dir['basedir'].'/espresso/'.$filename;
201 201
 
202 202
                             if (move_uploaded_file($temp_file, $path_to_file)) {
203 203
                                 // convert csv to array
@@ -331,8 +331,8 @@  discard block
 block discarded – undo
331 331
         // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
332 332
         $old_site_url = 'none-specified';
333 333
         // hanlde metadata
334
-        if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
335
-            $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
334
+        if (isset($csv_data_array[EE_CSV::metadata_header])) {
335
+            $csv_metadata = array_shift($csv_data_array[EE_CSV::metadata_header]);
336 336
             // ok so its metadata, dont try to save it to ehte db obviously...
337 337
             if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
338 338
                 EE_Error::add_attention(
@@ -357,14 +357,14 @@  discard block
 block discarded – undo
357 357
                     )
358 358
                 );
359 359
             };
360
-            unset($csv_data_array[ EE_CSV::metadata_header ]);
360
+            unset($csv_data_array[EE_CSV::metadata_header]);
361 361
         }
362 362
         /**
363 363
          * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
364 364
          * the value will be the newly-inserted ID.
365 365
          * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
366 366
          */
367
-        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), []);
367
+        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from'.sanitize_title($old_site_url), []);
368 368
         if ($old_db_to_new_db_mapping) {
369 369
             EE_Error::add_attention(
370 370
                 sprintf(
@@ -384,7 +384,7 @@  discard block
 block discarded – undo
384 384
         );
385 385
 
386 386
         // save the mapping from old db to new db in case they try re-importing the same data from the same website again
387
-        update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
387
+        update_option('ee_id_mapping_from'.sanitize_title($old_site_url), $old_db_to_new_db_mapping);
388 388
 
389 389
         if ($this->_total_updates > 0) {
390 390
             EE_Error::add_success(
@@ -512,7 +512,7 @@  discard block
 block discarded – undo
512 512
                 // find the PK in the row of data (or a combined key if
513 513
                 // there is no primary key)
514 514
                 if ($model->has_primary_key_field()) {
515
-                    $id_in_csv = $model_object_data[ $model->primary_key_name() ];
515
+                    $id_in_csv = $model_object_data[$model->primary_key_name()];
516 516
                 } else {
517 517
                     $id_in_csv = $model->get_index_primary_key_string($model_object_data);
518 518
                 }
@@ -555,14 +555,14 @@  discard block
 block discarded – undo
555 555
                         $what_to_do = self::do_update;
556 556
                         // and if this model has a primary key, remember its mapping
557 557
                         if ($model->has_primary_key_field()) {
558
-                            $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
559
-                            $model_object_data[ $model->primary_key_name() ]       = $conflicting->ID();
558
+                            $old_db_to_new_db_mapping[$model_name][$id_in_csv] = $conflicting->ID();
559
+                            $model_object_data[$model->primary_key_name()]       = $conflicting->ID();
560 560
                         } else {
561 561
                             // we want to update this conflicting item, instead of inserting a conflicting item
562 562
                             // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
563 563
                             // for the WHERE conditions in the update). At the time of this comment, there were no models like this
564 564
                             foreach ($model->get_combined_primary_key_fields() as $key_field) {
565
-                                $model_object_data[ $key_field->get_name() ] = $conflicting->get(
565
+                                $model_object_data[$key_field->get_name()] = $conflicting->get(
566 566
                                     $key_field->get_name()
567 567
                                 );
568 568
                             }
@@ -622,7 +622,7 @@  discard block
 block discarded – undo
622 622
         $model_name = $model->get_this_model_name();
623 623
         // if it's a site-to-site export-and-import, see if this modelobject's id
624 624
         // in the old data that we know of
625
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
625
+        if (isset($old_db_to_new_db_mapping[$model_name][$id_in_csv])) {
626 626
             return self::do_update;
627 627
         } else {
628 628
             return self::do_insert;
@@ -680,14 +680,14 @@  discard block
 block discarded – undo
680 680
         // if this model object's primary key is in the mapping, replace it
681 681
         if ($model->has_primary_key_field()
682 682
             && $model->get_primary_key_field()->is_auto_increment()
683
-            && isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ])
683
+            && isset($old_db_to_new_db_mapping[$model->get_this_model_name()])
684 684
             && isset(
685
-                $old_db_to_new_db_mapping[ $model->get_this_model_name(
686
-                ) ][ $model_object_data[ $model->primary_key_name() ] ]
685
+                $old_db_to_new_db_mapping[$model->get_this_model_name(
686
+                )][$model_object_data[$model->primary_key_name()]]
687 687
             )) {
688
-            $model_object_data[ $model->primary_key_name() ] =
689
-                $old_db_to_new_db_mapping[ $model->get_this_model_name(
690
-                ) ][ $model_object_data[ $model->primary_key_name() ] ];
688
+            $model_object_data[$model->primary_key_name()] =
689
+                $old_db_to_new_db_mapping[$model->get_this_model_name(
690
+                )][$model_object_data[$model->primary_key_name()]];
691 691
         }
692 692
 
693 693
         try {
@@ -703,25 +703,25 @@  discard block
 block discarded – undo
703 703
                 $found_a_mapping   = false;
704 704
                 foreach ($models_pointed_to as $model_pointed_to_by_fk) {
705 705
                     if ($model_name_field) {
706
-                        $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
706
+                        $value_of_model_name_field = $model_object_data[$model_name_field->get_name()];
707 707
                         if ($value_of_model_name_field == $model_pointed_to_by_fk) {
708
-                            $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
709
-                                $model_object_data[ $field_obj->get_name() ],
708
+                            $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in(
709
+                                $model_object_data[$field_obj->get_name()],
710 710
                                 $model_pointed_to_by_fk,
711 711
                                 $old_db_to_new_db_mapping,
712 712
                                 $export_from_site_a_to_b
713 713
                             );
714
-                            $found_a_mapping                             = true;
714
+                            $found_a_mapping = true;
715 715
                             break;
716 716
                         }
717 717
                     } else {
718
-                        $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
719
-                            $model_object_data[ $field_obj->get_name() ],
718
+                        $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in(
719
+                            $model_object_data[$field_obj->get_name()],
720 720
                             $model_pointed_to_by_fk,
721 721
                             $old_db_to_new_db_mapping,
722 722
                             $export_from_site_a_to_b
723 723
                         );
724
-                        $found_a_mapping                             = true;
724
+                        $found_a_mapping = true;
725 725
                     }
726 726
                     // once we've found a mapping for this field no need to continue
727 727
                     if ($found_a_mapping) {
@@ -781,8 +781,8 @@  discard block
 block discarded – undo
781 781
      */
782 782
     protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
783 783
     {
784
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
785
-            return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
784
+        if (isset($old_db_to_new_db_mapping[$model_name][$object_id])) {
785
+            return $old_db_to_new_db_mapping[$model_name][$object_id];
786 786
         } elseif ($object_id == '0' || $object_id == '') {
787 787
             // leave as-is
788 788
             return $object_id;
@@ -790,7 +790,7 @@  discard block
 block discarded – undo
790 790
             // we couldn't find a mapping for this, and it's from a different site,
791 791
             // so blank it out
792 792
             return null;
793
-        } elseif (! $export_from_site_a_to_b) {
793
+        } elseif ( ! $export_from_site_a_to_b) {
794 794
             // we coudln't find a mapping for this, but it's from thsi DB anyway
795 795
             // so let's just leave it as-is
796 796
             return $object_id;
@@ -812,8 +812,8 @@  discard block
 block discarded – undo
812 812
         // remove the primary key, if there is one (we don't want it for inserts OR updates)
813 813
         // we'll put it back in if we need it
814 814
         if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
815
-            $effective_id = $model_object_data[ $model->primary_key_name() ];
816
-            unset($model_object_data[ $model->primary_key_name() ]);
815
+            $effective_id = $model_object_data[$model->primary_key_name()];
816
+            unset($model_object_data[$model->primary_key_name()]);
817 817
         } else {
818 818
             $effective_id = $model->get_index_primary_key_string($model_object_data);
819 819
         }
@@ -821,7 +821,7 @@  discard block
 block discarded – undo
821 821
         try {
822 822
             $new_id = $model->insert($model_object_data);
823 823
             if ($new_id) {
824
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
824
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_id;
825 825
                 $this->_total_inserts++;
826 826
                 EE_Error::add_success(
827 827
                     sprintf(
@@ -835,7 +835,7 @@  discard block
 block discarded – undo
835 835
                 $this->_total_insert_errors++;
836 836
                 // put the ID used back in there for the error message
837 837
                 if ($model->has_primary_key_field()) {
838
-                    $model_object_data[ $model->primary_key_name() ] = $effective_id;
838
+                    $model_object_data[$model->primary_key_name()] = $effective_id;
839 839
                 }
840 840
                 EE_Error::add_error(
841 841
                     sprintf(
@@ -851,7 +851,7 @@  discard block
 block discarded – undo
851 851
         } catch (EE_Error $e) {
852 852
             $this->_total_insert_errors++;
853 853
             if ($model->has_primary_key_field()) {
854
-                $model_object_data[ $model->primary_key_name() ] = $effective_id;
854
+                $model_object_data[$model->primary_key_name()] = $effective_id;
855 855
             }
856 856
             EE_Error::add_error(
857 857
                 sprintf(
@@ -885,17 +885,17 @@  discard block
 block discarded – undo
885 885
             // one for performing an update, one for everthing else
886 886
             $model_object_data_for_update = $model_object_data;
887 887
             if ($model->has_primary_key_field()) {
888
-                $conditions = [$model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]];
888
+                $conditions = [$model->primary_key_name() => $model_object_data[$model->primary_key_name()]];
889 889
                 // remove the primary key because we shouldn't use it for updating
890
-                unset($model_object_data_for_update[ $model->primary_key_name() ]);
890
+                unset($model_object_data_for_update[$model->primary_key_name()]);
891 891
             } elseif ($model->get_combined_primary_key_fields() > 1) {
892 892
                 $conditions = [];
893 893
                 foreach ($model->get_combined_primary_key_fields() as $key_field) {
894
-                    $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
894
+                    $conditions[$key_field->get_name()] = $model_object_data[$key_field->get_name()];
895 895
                 }
896 896
             } else {
897 897
                 $model->primary_key_name(
898
-                );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
898
+                ); // this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
899 899
             }
900 900
 
901 901
             $success = $model->update($model_object_data_for_update, [$conditions]);
@@ -913,15 +913,15 @@  discard block
 block discarded – undo
913 913
                 // we would have last-minute decided to update. So we'd like to know what we updated
914 914
                 // and so we record what record ended up being updated using the mapping
915 915
                 if ($model->has_primary_key_field()) {
916
-                    $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
916
+                    $new_key_for_mapping = $model_object_data[$model->primary_key_name()];
917 917
                 } else {
918 918
                     // no primary key just a combined key
919 919
                     $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
920 920
                 }
921
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
921
+                $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_key_for_mapping;
922 922
             } else {
923 923
                 $matched_items = $model->get_all([$conditions]);
924
-                if (! $matched_items) {
924
+                if ( ! $matched_items) {
925 925
                     // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
926 926
                     $this->_total_update_errors++;
927 927
                     EE_Error::add_error(
@@ -960,7 +960,7 @@  discard block
 block discarded – undo
960 960
                 implode(",", $model_object_data),
961 961
                 $e->getMessage()
962 962
             );
963
-            $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
963
+            $debug_message = $basic_message.' Stack trace: '.$e->getTraceAsString();
964 964
             EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
965 965
         }
966 966
         return $old_db_to_new_db_mapping;
Please login to merge, or discard this patch.
core/helpers/EEH_Activation.helper.php 2 patches
Spacing   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -58,7 +58,7 @@  discard block
 block discarded – undo
58 58
      */
59 59
     public static function getTableAnalysis()
60 60
     {
61
-        if (! self::$table_analysis instanceof TableAnalysis) {
61
+        if ( ! self::$table_analysis instanceof TableAnalysis) {
62 62
             self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', [], true);
63 63
         }
64 64
         return self::$table_analysis;
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
      */
73 73
     public static function getTableManager()
74 74
     {
75
-        if (! self::$table_manager instanceof TableManager) {
75
+        if ( ! self::$table_manager instanceof TableManager) {
76 76
             self::$table_manager = EE_Registry::instance()->create('TableManager', [], true);
77 77
         }
78 78
         return self::$table_manager;
@@ -193,7 +193,7 @@  discard block
 block discarded – undo
193 193
         if ($which_to_include === 'old') {
194 194
             $cron_tasks = array_filter(
195 195
                 $cron_tasks,
196
-                function ($value) {
196
+                function($value) {
197 197
                     return $value === EEH_Activation::cron_task_no_longer_in_use;
198 198
                 }
199 199
             );
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
     {
224 224
 
225 225
         foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
226
-            if (! wp_next_scheduled($hook_name)) {
226
+            if ( ! wp_next_scheduled($hook_name)) {
227 227
                 /**
228 228
                  * This allows client code to define the initial start timestamp for this schedule.
229 229
                  */
@@ -274,15 +274,15 @@  discard block
 block discarded – undo
274 274
         foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
275 275
             if (is_array($hooks_to_fire_at_time)) {
276 276
                 foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
277
-                    if (isset($ee_cron_tasks_to_remove[ $hook_name ])
278
-                        && is_array($ee_cron_tasks_to_remove[ $hook_name ])
277
+                    if (isset($ee_cron_tasks_to_remove[$hook_name])
278
+                        && is_array($ee_cron_tasks_to_remove[$hook_name])
279 279
                     ) {
280
-                        unset($crons[ $timestamp ][ $hook_name ]);
280
+                        unset($crons[$timestamp][$hook_name]);
281 281
                     }
282 282
                 }
283 283
                 // also take care of any empty cron timestamps.
284 284
                 if (empty($hooks_to_fire_at_time)) {
285
-                    unset($crons[ $timestamp ]);
285
+                    unset($crons[$timestamp]);
286 286
                 }
287 287
             }
288 288
         }
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
             3
329 329
         );
330 330
         // EE_Config::reset();
331
-        if (! EE_Config::logging_enabled()) {
331
+        if ( ! EE_Config::logging_enabled()) {
332 332
             delete_option(EE_Config::LOG_NAME);
333 333
         }
334 334
     }
@@ -343,7 +343,7 @@  discard block
 block discarded – undo
343 343
     public static function load_calendar_config()
344 344
     {
345 345
         // grab array of all plugin folders and loop thru it
346
-        $plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
346
+        $plugins = glob(WP_PLUGIN_DIR.'/*', GLOB_ONLYDIR);
347 347
         if (empty($plugins)) {
348 348
             return;
349 349
         }
@@ -359,7 +359,7 @@  discard block
 block discarded – undo
359 359
                 || strpos($plugin, 'calendar') !== false
360 360
             ) {
361 361
                 // this is what we are looking for
362
-                $calendar_config = $plugin_path . '/EE_Calendar_Config.php';
362
+                $calendar_config = $plugin_path.'/EE_Calendar_Config.php';
363 363
                 // does it exist in this folder ?
364 364
                 if (is_readable($calendar_config)) {
365 365
                     // YEAH! let's load it
@@ -453,7 +453,7 @@  discard block
 block discarded – undo
453 453
                 'code' => 'ESPRESSO_CANCELLED',
454 454
             ],
455 455
         ];
456
-        $EE_Core_Config        = EE_Registry::instance()->CFG->core;
456
+        $EE_Core_Config = EE_Registry::instance()->CFG->core;
457 457
         foreach ($critical_pages as $critical_page) {
458 458
             // is critical page ID set in config ?
459 459
             if ($EE_Core_Config->{$critical_page['id']} !== false) {
@@ -484,7 +484,7 @@  discard block
 block discarded – undo
484 484
             ) {
485 485
                 // update Config with post ID
486 486
                 $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
487
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
487
+                if ( ! EE_Config::instance()->update_espresso_config(false, false)) {
488 488
                     $msg = __(
489 489
                         'The Event Espresso critical page configuration settings could not be updated.',
490 490
                         'event_espresso'
@@ -507,7 +507,7 @@  discard block
 block discarded – undo
507 507
                         'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
508 508
                         'event_espresso'
509 509
                     ),
510
-                    '<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
510
+                    '<a href="'.admin_url('admin.php?page=espresso_general_settings&action=critical_pages').'">'
511 511
                     . __('Event Espresso Critical Pages Settings', 'event_espresso')
512 512
                     . '</a>'
513 513
                 )
@@ -532,7 +532,7 @@  discard block
 block discarded – undo
532 532
     public static function get_page_by_ee_shortcode($ee_shortcode)
533 533
     {
534 534
         global $wpdb;
535
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
535
+        $shortcode_and_opening_bracket = '['.$ee_shortcode;
536 536
         $post_id                       =
537 537
             $wpdb->get_var(
538 538
                 "SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1"
@@ -561,11 +561,11 @@  discard block
 block discarded – undo
561 561
             'post_status'    => 'publish',
562 562
             'post_type'      => 'page',
563 563
             'comment_status' => 'closed',
564
-            'post_content'   => '[' . $critical_page['code'] . ']',
564
+            'post_content'   => '['.$critical_page['code'].']',
565 565
         ];
566 566
 
567 567
         $post_id = wp_insert_post($post_args);
568
-        if (! $post_id) {
568
+        if ( ! $post_id) {
569 569
             $msg = sprintf(
570 570
                 __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
571 571
                 $critical_page['name']
@@ -574,7 +574,7 @@  discard block
 block discarded – undo
574 574
             return $critical_page;
575 575
         }
576 576
         // get newly created post's details
577
-        if (! $critical_page['post'] = get_post($post_id)) {
577
+        if ( ! $critical_page['post'] = get_post($post_id)) {
578 578
             $msg = sprintf(
579 579
                 __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
580 580
                 $critical_page['name']
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
     public static function get_default_creator_id()
600 600
     {
601 601
         global $wpdb;
602
-        if (! empty(self::$_default_creator_id)) {
602
+        if ( ! empty(self::$_default_creator_id)) {
603 603
             return self::$_default_creator_id;
604 604
         }/**/
605 605
         $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
@@ -615,7 +615,7 @@  discard block
 block discarded – undo
615 615
         $capabilities_key = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
616 616
         $query            = $wpdb->prepare(
617 617
             "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
618
-            '%' . $role_to_check . '%'
618
+            '%'.$role_to_check.'%'
619 619
         );
620 620
         $user_id          = $wpdb->get_var($query);
621 621
         $user_id          = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
@@ -654,8 +654,8 @@  discard block
 block discarded – undo
654 654
             return;
655 655
         }
656 656
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
657
-        if (! function_exists('dbDelta')) {
658
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
657
+        if ( ! function_exists('dbDelta')) {
658
+            require_once(ABSPATH.'wp-admin/includes/upgrade.php');
659 659
         }
660 660
         $tableAnalysis = EEH_Activation::getTableAnalysis();
661 661
         $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
@@ -664,9 +664,9 @@  discard block
 block discarded – undo
664 664
             // ok, delete the table... but ONLY if it's empty
665 665
             $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
666 666
             // table is NOT empty, are you SURE you want to delete this table ???
667
-            if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
667
+            if ( ! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
668 668
                 EEH_Activation::getTableManager()->dropTable($wp_table_name);
669
-            } elseif (! $deleted_safely) {
669
+            } elseif ( ! $deleted_safely) {
670 670
                 // so we should be more cautious rather than just dropping tables so easily
671 671
                 error_log(
672 672
                     sprintf(
@@ -878,13 +878,13 @@  discard block
 block discarded – undo
878 878
             // reset values array
879 879
             $QSG_values = [];
880 880
             // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
881
-            if (! in_array("$QSG_system", $question_groups)) {
881
+            if ( ! in_array("$QSG_system", $question_groups)) {
882 882
                 // add it
883 883
                 switch ($QSG_system) {
884 884
                     case 1:
885 885
                         $QSG_values = [
886 886
                             'QSG_name'            => __('Personal Information', 'event_espresso'),
887
-                            'QSG_identifier'      => 'personal-information-' . time(),
887
+                            'QSG_identifier'      => 'personal-information-'.time(),
888 888
                             'QSG_desc'            => '',
889 889
                             'QSG_order'           => 1,
890 890
                             'QSG_show_group_name' => 1,
@@ -896,7 +896,7 @@  discard block
 block discarded – undo
896 896
                     case 2:
897 897
                         $QSG_values = [
898 898
                             'QSG_name'            => __('Address Information', 'event_espresso'),
899
-                            'QSG_identifier'      => 'address-information-' . time(),
899
+                            'QSG_identifier'      => 'address-information-'.time(),
900 900
                             'QSG_desc'            => '',
901 901
                             'QSG_order'           => 2,
902 902
                             'QSG_show_group_name' => 1,
@@ -907,14 +907,14 @@  discard block
 block discarded – undo
907 907
                         break;
908 908
                 }
909 909
                 // make sure we have some values before inserting them
910
-                if (! empty($QSG_values)) {
910
+                if ( ! empty($QSG_values)) {
911 911
                     // insert system question
912 912
                     $wpdb->insert(
913 913
                         $table_name,
914 914
                         $QSG_values,
915 915
                         ['%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d']
916 916
                     );
917
-                    $QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
917
+                    $QSG_IDs[$QSG_system] = $wpdb->insert_id;
918 918
                 }
919 919
             }
920 920
         }
@@ -929,7 +929,7 @@  discard block
 block discarded – undo
929 929
         $address_system_group_questions  = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
930 930
         $system_questions_not_in_group   = ['email_confirm'];
931 931
         // merge all of the system questions we should have
932
-        $QST_systems       = array_merge(
932
+        $QST_systems = array_merge(
933 933
             $personal_system_group_questions,
934 934
             $address_system_group_questions,
935 935
             $system_questions_not_in_group
@@ -941,7 +941,7 @@  discard block
 block discarded – undo
941 941
             // reset values array
942 942
             $QST_values = [];
943 943
             // if we don't have what we should have
944
-            if (! in_array($QST_system, $questions)) {
944
+            if ( ! in_array($QST_system, $questions)) {
945 945
                 // add it
946 946
                 switch ($QST_system) {
947 947
                     case 'fname':
@@ -1126,7 +1126,7 @@  discard block
 block discarded – undo
1126 1126
                         ];
1127 1127
                         break;
1128 1128
                 }
1129
-                if (! empty($QST_values)) {
1129
+                if ( ! empty($QST_values)) {
1130 1130
                     // insert system question
1131 1131
                     $wpdb->insert(
1132 1132
                         $table_name,
@@ -1144,8 +1144,8 @@  discard block
 block discarded – undo
1144 1144
                         // QST_system should not be assigned to any group
1145 1145
                         continue;
1146 1146
                     }
1147
-                    if (isset($QSG_IDs[ $system_question_we_want ])) {
1148
-                        $QSG_ID = $QSG_IDs[ $system_question_we_want ];
1147
+                    if (isset($QSG_IDs[$system_question_we_want])) {
1148
+                        $QSG_ID = $QSG_IDs[$system_question_we_want];
1149 1149
                     } else {
1150 1150
                         $id_col = EEM_Question_Group::instance()
1151 1151
                                                     ->get_col([['QSG_system' => $system_question_we_want]]);
@@ -1194,7 +1194,7 @@  discard block
 block discarded – undo
1194 1194
      */
1195 1195
     public static function insert_default_payment_methods()
1196 1196
     {
1197
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1197
+        if ( ! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1198 1198
             EE_Registry::instance()->load_lib('Payment_Method_Manager');
1199 1199
             EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1200 1200
         } else {
@@ -1328,7 +1328,7 @@  discard block
 block discarded – undo
1328 1328
                 // if already active or has already been activated before we skip
1329 1329
                 // (otherwise we might reactivate something user's intentionally deactivated.)
1330 1330
                 // we also skip if the message type is not installed.
1331
-                if (! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1331
+                if ( ! isset($installed_message_types[$default_message_type_name_for_messenger])
1332 1332
                     || $message_resource_manager->has_message_type_been_activated_for_messenger(
1333 1333
                         $default_message_type_name_for_messenger,
1334 1334
                         $active_messenger->name
@@ -1349,7 +1349,7 @@  discard block
 block discarded – undo
1349 1349
                 false
1350 1350
             );
1351 1351
             // activate the templates for these message types
1352
-            if (! empty($default_message_type_names_to_activate)) {
1352
+            if ( ! empty($default_message_type_names_to_activate)) {
1353 1353
                 $templates_created = EEH_MSG_Template::generate_new_templates(
1354 1354
                     $active_messenger->name,
1355 1355
                     $default_message_type_names_for_messenger,
@@ -1382,13 +1382,13 @@  discard block
 block discarded – undo
1382 1382
             $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1383 1383
             // verify the default message types match an installed message type.
1384 1384
             foreach ($default_message_type_names_for_messenger as $key => $name) {
1385
-                if (! isset($installed_message_types[ $name ])
1385
+                if ( ! isset($installed_message_types[$name])
1386 1386
                     || $message_resource_manager->has_message_type_been_activated_for_messenger(
1387 1387
                         $name,
1388 1388
                         $messenger_to_generate->name
1389 1389
                     )
1390 1390
                 ) {
1391
-                    unset($default_message_type_names_for_messenger[ $key ]);
1391
+                    unset($default_message_type_names_for_messenger[$key]);
1392 1392
                 }
1393 1393
             }
1394 1394
             // in previous iterations, the active_messengers option in the db
@@ -1402,7 +1402,7 @@  discard block
 block discarded – undo
1402 1402
                 false
1403 1403
             );
1404 1404
             // create any templates needing created (or will reactivate templates already generated as necessary).
1405
-            if (! empty($default_message_type_names_for_messenger)) {
1405
+            if ( ! empty($default_message_type_names_for_messenger)) {
1406 1406
                 $templates_generated = EEH_MSG_Template::generate_new_templates(
1407 1407
                     $messenger_to_generate->name,
1408 1408
                     $default_message_type_names_for_messenger,
@@ -1437,13 +1437,13 @@  discard block
 block discarded – undo
1437 1437
             // if installed messenger is a messenger that should be activated on install
1438 1438
             // and is not already active
1439 1439
             // and has never been activated
1440
-            if (! $installed_messenger->activate_on_install
1441
-                || isset($active_messengers[ $installed_messenger->name ])
1442
-                || isset($has_activated[ $installed_messenger->name ])
1440
+            if ( ! $installed_messenger->activate_on_install
1441
+                || isset($active_messengers[$installed_messenger->name])
1442
+                || isset($has_activated[$installed_messenger->name])
1443 1443
             ) {
1444 1444
                 continue;
1445 1445
             }
1446
-            $messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1446
+            $messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1447 1447
         }
1448 1448
         return $messengers_to_generate;
1449 1449
     }
@@ -1483,7 +1483,7 @@  discard block
 block discarded – undo
1483 1483
         // this creates an array for tracking events that have no active ticket prices created
1484 1484
         // this allows us to warn admins of the situation so that it can be corrected
1485 1485
         $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1486
-        if (! $espresso_no_ticket_prices) {
1486
+        if ( ! $espresso_no_ticket_prices) {
1487 1487
             add_option('ee_no_ticket_prices', [], '', false);
1488 1488
         }
1489 1489
     }
@@ -1522,7 +1522,7 @@  discard block
 block discarded – undo
1522 1522
             }
1523 1523
         }
1524 1524
         // get all our CPTs
1525
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1525
+        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (".implode(",", $ee_post_types).")";
1526 1526
         $cpt_ids = $wpdb->get_col($query);
1527 1527
         // delete each post meta and term relations too
1528 1528
         foreach ($cpt_ids as $post_id) {
@@ -1553,7 +1553,7 @@  discard block
 block discarded – undo
1553 1553
                                 || ! $table->is_global()// not main site,but not global either. nuke it
1554 1554
                             )
1555 1555
                         ) {
1556
-                            $tables[ $table->get_table_name() ] = $table->get_table_name();
1556
+                            $tables[$table->get_table_name()] = $table->get_table_name();
1557 1557
                         }
1558 1558
                     }
1559 1559
                 }
@@ -1570,7 +1570,7 @@  discard block
 block discarded – undo
1570 1570
             'esp_rule',
1571 1571
         ];
1572 1572
         foreach ($tables_without_models as $table) {
1573
-            $tables[ $table ] = $table;
1573
+            $tables[$table] = $table;
1574 1574
         }
1575 1575
         return EEH_Activation::getTableManager()->dropTables($tables);
1576 1576
     }
@@ -1649,14 +1649,14 @@  discard block
 block discarded – undo
1649 1649
         $undeleted_options = [];
1650 1650
         foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1651 1651
             if ($no_wildcard) {
1652
-                if (! delete_option($option_name)) {
1652
+                if ( ! delete_option($option_name)) {
1653 1653
                     $undeleted_options[] = $option_name;
1654 1654
                 }
1655 1655
             } else {
1656 1656
                 $option_names_to_delete_from_wildcard =
1657 1657
                     $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1658 1658
                 foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1659
-                    if (! delete_option($option_name_from_wildcard)) {
1659
+                    if ( ! delete_option($option_name_from_wildcard)) {
1660 1660
                         $undeleted_options[] = $option_name_from_wildcard;
1661 1661
                     }
1662 1662
                 }
@@ -1668,20 +1668,20 @@  discard block
 block discarded – undo
1668 1668
             $db_update_sans_ee4 = [];
1669 1669
             foreach ($espresso_db_update as $version => $times_activated) {
1670 1670
                 if ((string) $version[0] === '3') {// if its NON EE4
1671
-                    $db_update_sans_ee4[ $version ] = $times_activated;
1671
+                    $db_update_sans_ee4[$version] = $times_activated;
1672 1672
                 }
1673 1673
             }
1674 1674
             update_option('espresso_db_update', $db_update_sans_ee4);
1675 1675
         }
1676 1676
         $errors = '';
1677
-        if (! empty($undeleted_options)) {
1677
+        if ( ! empty($undeleted_options)) {
1678 1678
             $errors .= sprintf(
1679 1679
                 __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1680 1680
                 '<br/>',
1681 1681
                 implode(',<br/>', $undeleted_options)
1682 1682
             );
1683 1683
         }
1684
-        if (! empty($errors)) {
1684
+        if ( ! empty($errors)) {
1685 1685
             EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1686 1686
         }
1687 1687
     }
Please login to merge, or discard this patch.
Indentation   +1676 added lines, -1676 removed lines patch added patch discarded remove patch
@@ -17,243 +17,243 @@  discard block
 block discarded – undo
17 17
 class EEH_Activation implements ResettableInterface
18 18
 {
19 19
 
20
-    /**
21
-     * constant used to indicate a cron task is no longer in use
22
-     */
23
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
24
-
25
-    /**
26
-     * WP_User->ID
27
-     *
28
-     * @var int
29
-     */
30
-    private static $_default_creator_id;
31
-
32
-    /**
33
-     * indicates whether or not we've already verified core's default data during this request,
34
-     * because after migrations are done, any addons activated while in maintenance mode
35
-     * will want to setup their own default data, and they might hook into core's default data
36
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
37
-     * This prevents doing that for EVERY single addon.
38
-     *
39
-     * @var boolean
40
-     */
41
-    protected static $_initialized_db_content_already_in_this_request = false;
42
-
43
-    /**
44
-     * @var TableAnalysis $table_analysis
45
-     */
46
-    private static $table_analysis;
47
-
48
-    /**
49
-     * @var TableManager $table_manager
50
-     */
51
-    private static $table_manager;
52
-
53
-
54
-    /**
55
-     * @return TableAnalysis
56
-     * @throws EE_Error
57
-     * @throws ReflectionException
58
-     */
59
-    public static function getTableAnalysis()
60
-    {
61
-        if (! self::$table_analysis instanceof TableAnalysis) {
62
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', [], true);
63
-        }
64
-        return self::$table_analysis;
65
-    }
66
-
67
-
68
-    /**
69
-     * @return TableManager
70
-     * @throws EE_Error
71
-     * @throws ReflectionException
72
-     */
73
-    public static function getTableManager()
74
-    {
75
-        if (! self::$table_manager instanceof TableManager) {
76
-            self::$table_manager = EE_Registry::instance()->create('TableManager', [], true);
77
-        }
78
-        return self::$table_manager;
79
-    }
80
-
81
-
82
-    /**
83
-     *    _ensure_table_name_has_prefix
84
-     *
85
-     * @param $table_name
86
-     * @return string
87
-     * @throws EE_Error
88
-     * @throws ReflectionException
89
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
90
-     * @access     public
91
-     * @static
92
-     */
93
-    public static function ensure_table_name_has_prefix($table_name)
94
-    {
95
-        return EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
96
-    }
97
-
98
-
99
-    /**
100
-     *    system_initialization
101
-     *    ensures the EE configuration settings are loaded with at least default options set
102
-     *    and that all critical EE pages have been generated with the appropriate shortcodes in place
103
-     *
104
-     * @access public
105
-     * @static
106
-     * @return void
107
-     */
108
-    public static function system_initialization()
109
-    {
110
-        EEH_Activation::reset_and_update_config();
111
-        // which is fired BEFORE activation of plugin anyways
112
-        EEH_Activation::verify_default_pages_exist();
113
-    }
114
-
115
-
116
-    /**
117
-     * Sets the database schema and creates folders. This should
118
-     * be called on plugin activation and reactivation
119
-     *
120
-     * @return boolean success, whether the database and folders are setup properly
121
-     * @throws EE_Error
122
-     * @throws ReflectionException
123
-     */
124
-    public static function initialize_db_and_folders()
125
-    {
126
-        return EEH_Activation::create_database_tables();
127
-    }
128
-
129
-
130
-    /**
131
-     * assuming we have an up-to-date database schema, this will populate it
132
-     * with default and initial data. This should be called
133
-     * upon activation of a new plugin, reactivation, and at the end
134
-     * of running migration scripts
135
-     *
136
-     * @throws EE_Error
137
-     * @throws ReflectionException
138
-     */
139
-    public static function initialize_db_content()
140
-    {
141
-        // let's avoid doing all this logic repeatedly, especially when addons are requesting it
142
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
143
-            return;
144
-        }
145
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
146
-
147
-        EEH_Activation::initialize_system_questions();
148
-        EEH_Activation::insert_default_status_codes();
149
-        EEH_Activation::generate_default_message_templates();
150
-        EEH_Activation::create_no_ticket_prices_array();
151
-        EEH_Activation::removeEmailConfirmFromAddressGroup();
152
-
153
-        EEH_Activation::validate_messages_system();
154
-        EEH_Activation::insert_default_payment_methods();
155
-        // in case we've
156
-        EEH_Activation::remove_cron_tasks();
157
-        EEH_Activation::create_cron_tasks();
158
-        // remove all TXN locks since that is being done via extra meta now
159
-        delete_option('ee_locked_transactions');
160
-        // also, check for CAF default db content
161
-        do_action('AHEE__EEH_Activation__initialize_db_content');
162
-        // also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
163
-        // which users really won't care about on initial activation
164
-        EE_Error::overwrite_success();
165
-    }
166
-
167
-
168
-    /**
169
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
170
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
171
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
172
-     * (null)
173
-     *
174
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
175
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
176
-     * @return array
177
-     * @throws EE_Error
178
-     */
179
-    public static function get_cron_tasks($which_to_include)
180
-    {
181
-        $cron_tasks = apply_filters(
182
-            'FHEE__EEH_Activation__get_cron_tasks',
183
-            [
184
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
185
-                // 'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' =>
186
-                // EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
187
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
188
-                // there may have been a bug which prevented these cron tasks from getting unscheduled,
189
-                // so we might want to remove these for a few updates
190
-                'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
191
-            ]
192
-        );
193
-        if ($which_to_include === 'old') {
194
-            $cron_tasks = array_filter(
195
-                $cron_tasks,
196
-                function ($value) {
197
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
198
-                }
199
-            );
200
-        } elseif ($which_to_include === 'current') {
201
-            $cron_tasks = array_filter($cron_tasks);
202
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
203
-            throw new EE_Error(
204
-                sprintf(
205
-                    __(
206
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
207
-                        'event_espresso'
208
-                    ),
209
-                    $which_to_include
210
-                )
211
-            );
212
-        }
213
-        return $cron_tasks;
214
-    }
215
-
216
-
217
-    /**
218
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
219
-     *
220
-     * @throws EE_Error
221
-     */
222
-    public static function create_cron_tasks()
223
-    {
224
-
225
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
226
-            if (! wp_next_scheduled($hook_name)) {
227
-                /**
228
-                 * This allows client code to define the initial start timestamp for this schedule.
229
-                 */
230
-                if (is_array($frequency)
231
-                    && count($frequency) === 2
232
-                    && isset($frequency[0], $frequency[1])
233
-                ) {
234
-                    $start_timestamp = $frequency[0];
235
-                    $frequency       = $frequency[1];
236
-                } else {
237
-                    $start_timestamp = time();
238
-                }
239
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
240
-            }
241
-        }
242
-    }
243
-
244
-
245
-    /**
246
-     * Remove the currently-existing and now-removed cron tasks.
247
-     *
248
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
249
-     * @throws EE_Error
250
-     */
251
-    public static function remove_cron_tasks($remove_all = true)
252
-    {
253
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
254
-        $crons                = _get_cron_array();
255
-        $crons                = is_array($crons) ? $crons : [];
256
-        /* reminder of what $crons look like:
20
+	/**
21
+	 * constant used to indicate a cron task is no longer in use
22
+	 */
23
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
24
+
25
+	/**
26
+	 * WP_User->ID
27
+	 *
28
+	 * @var int
29
+	 */
30
+	private static $_default_creator_id;
31
+
32
+	/**
33
+	 * indicates whether or not we've already verified core's default data during this request,
34
+	 * because after migrations are done, any addons activated while in maintenance mode
35
+	 * will want to setup their own default data, and they might hook into core's default data
36
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
37
+	 * This prevents doing that for EVERY single addon.
38
+	 *
39
+	 * @var boolean
40
+	 */
41
+	protected static $_initialized_db_content_already_in_this_request = false;
42
+
43
+	/**
44
+	 * @var TableAnalysis $table_analysis
45
+	 */
46
+	private static $table_analysis;
47
+
48
+	/**
49
+	 * @var TableManager $table_manager
50
+	 */
51
+	private static $table_manager;
52
+
53
+
54
+	/**
55
+	 * @return TableAnalysis
56
+	 * @throws EE_Error
57
+	 * @throws ReflectionException
58
+	 */
59
+	public static function getTableAnalysis()
60
+	{
61
+		if (! self::$table_analysis instanceof TableAnalysis) {
62
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', [], true);
63
+		}
64
+		return self::$table_analysis;
65
+	}
66
+
67
+
68
+	/**
69
+	 * @return TableManager
70
+	 * @throws EE_Error
71
+	 * @throws ReflectionException
72
+	 */
73
+	public static function getTableManager()
74
+	{
75
+		if (! self::$table_manager instanceof TableManager) {
76
+			self::$table_manager = EE_Registry::instance()->create('TableManager', [], true);
77
+		}
78
+		return self::$table_manager;
79
+	}
80
+
81
+
82
+	/**
83
+	 *    _ensure_table_name_has_prefix
84
+	 *
85
+	 * @param $table_name
86
+	 * @return string
87
+	 * @throws EE_Error
88
+	 * @throws ReflectionException
89
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
90
+	 * @access     public
91
+	 * @static
92
+	 */
93
+	public static function ensure_table_name_has_prefix($table_name)
94
+	{
95
+		return EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
96
+	}
97
+
98
+
99
+	/**
100
+	 *    system_initialization
101
+	 *    ensures the EE configuration settings are loaded with at least default options set
102
+	 *    and that all critical EE pages have been generated with the appropriate shortcodes in place
103
+	 *
104
+	 * @access public
105
+	 * @static
106
+	 * @return void
107
+	 */
108
+	public static function system_initialization()
109
+	{
110
+		EEH_Activation::reset_and_update_config();
111
+		// which is fired BEFORE activation of plugin anyways
112
+		EEH_Activation::verify_default_pages_exist();
113
+	}
114
+
115
+
116
+	/**
117
+	 * Sets the database schema and creates folders. This should
118
+	 * be called on plugin activation and reactivation
119
+	 *
120
+	 * @return boolean success, whether the database and folders are setup properly
121
+	 * @throws EE_Error
122
+	 * @throws ReflectionException
123
+	 */
124
+	public static function initialize_db_and_folders()
125
+	{
126
+		return EEH_Activation::create_database_tables();
127
+	}
128
+
129
+
130
+	/**
131
+	 * assuming we have an up-to-date database schema, this will populate it
132
+	 * with default and initial data. This should be called
133
+	 * upon activation of a new plugin, reactivation, and at the end
134
+	 * of running migration scripts
135
+	 *
136
+	 * @throws EE_Error
137
+	 * @throws ReflectionException
138
+	 */
139
+	public static function initialize_db_content()
140
+	{
141
+		// let's avoid doing all this logic repeatedly, especially when addons are requesting it
142
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
143
+			return;
144
+		}
145
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
146
+
147
+		EEH_Activation::initialize_system_questions();
148
+		EEH_Activation::insert_default_status_codes();
149
+		EEH_Activation::generate_default_message_templates();
150
+		EEH_Activation::create_no_ticket_prices_array();
151
+		EEH_Activation::removeEmailConfirmFromAddressGroup();
152
+
153
+		EEH_Activation::validate_messages_system();
154
+		EEH_Activation::insert_default_payment_methods();
155
+		// in case we've
156
+		EEH_Activation::remove_cron_tasks();
157
+		EEH_Activation::create_cron_tasks();
158
+		// remove all TXN locks since that is being done via extra meta now
159
+		delete_option('ee_locked_transactions');
160
+		// also, check for CAF default db content
161
+		do_action('AHEE__EEH_Activation__initialize_db_content');
162
+		// also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
163
+		// which users really won't care about on initial activation
164
+		EE_Error::overwrite_success();
165
+	}
166
+
167
+
168
+	/**
169
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
170
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
171
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
172
+	 * (null)
173
+	 *
174
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
175
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
176
+	 * @return array
177
+	 * @throws EE_Error
178
+	 */
179
+	public static function get_cron_tasks($which_to_include)
180
+	{
181
+		$cron_tasks = apply_filters(
182
+			'FHEE__EEH_Activation__get_cron_tasks',
183
+			[
184
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
185
+				// 'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' =>
186
+				// EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
187
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
188
+				// there may have been a bug which prevented these cron tasks from getting unscheduled,
189
+				// so we might want to remove these for a few updates
190
+				'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
191
+			]
192
+		);
193
+		if ($which_to_include === 'old') {
194
+			$cron_tasks = array_filter(
195
+				$cron_tasks,
196
+				function ($value) {
197
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
198
+				}
199
+			);
200
+		} elseif ($which_to_include === 'current') {
201
+			$cron_tasks = array_filter($cron_tasks);
202
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
203
+			throw new EE_Error(
204
+				sprintf(
205
+					__(
206
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
207
+						'event_espresso'
208
+					),
209
+					$which_to_include
210
+				)
211
+			);
212
+		}
213
+		return $cron_tasks;
214
+	}
215
+
216
+
217
+	/**
218
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
219
+	 *
220
+	 * @throws EE_Error
221
+	 */
222
+	public static function create_cron_tasks()
223
+	{
224
+
225
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
226
+			if (! wp_next_scheduled($hook_name)) {
227
+				/**
228
+				 * This allows client code to define the initial start timestamp for this schedule.
229
+				 */
230
+				if (is_array($frequency)
231
+					&& count($frequency) === 2
232
+					&& isset($frequency[0], $frequency[1])
233
+				) {
234
+					$start_timestamp = $frequency[0];
235
+					$frequency       = $frequency[1];
236
+				} else {
237
+					$start_timestamp = time();
238
+				}
239
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
240
+			}
241
+		}
242
+	}
243
+
244
+
245
+	/**
246
+	 * Remove the currently-existing and now-removed cron tasks.
247
+	 *
248
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
249
+	 * @throws EE_Error
250
+	 */
251
+	public static function remove_cron_tasks($remove_all = true)
252
+	{
253
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
254
+		$crons                = _get_cron_array();
255
+		$crons                = is_array($crons) ? $crons : [];
256
+		/* reminder of what $crons look like:
257 257
          * Top-level keys are timestamps, and their values are arrays.
258 258
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
259 259
          * and their values are arrays.
@@ -270,961 +270,961 @@  discard block
 block discarded – undo
270 270
          *                  ...
271 271
          *      ...
272 272
          */
273
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
274
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
275
-            if (is_array($hooks_to_fire_at_time)) {
276
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
277
-                    if (isset($ee_cron_tasks_to_remove[ $hook_name ])
278
-                        && is_array($ee_cron_tasks_to_remove[ $hook_name ])
279
-                    ) {
280
-                        unset($crons[ $timestamp ][ $hook_name ]);
281
-                    }
282
-                }
283
-                // also take care of any empty cron timestamps.
284
-                if (empty($hooks_to_fire_at_time)) {
285
-                    unset($crons[ $timestamp ]);
286
-                }
287
-            }
288
-        }
289
-        _set_cron_array($crons);
290
-    }
291
-
292
-
293
-    /**
294
-     *    CPT_initialization
295
-     *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
296
-     *
297
-     * @access public
298
-     * @static
299
-     * @return void
300
-     * @throws EE_Error
301
-     * @throws ReflectionException
302
-     */
303
-    public static function CPT_initialization()
304
-    {
305
-        // register Custom Post Types
306
-        EE_Registry::instance()->load_core('Register_CPTs');
307
-        flush_rewrite_rules();
308
-    }
309
-
310
-
311
-    /**
312
-     *    reset_and_update_config
313
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
314
-     * If there is old calendar config data saved, then it will get converted on activation.
315
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
316
-     *
317
-     * @access public
318
-     * @static
319
-     * @return void
320
-     */
321
-    public static function reset_and_update_config()
322
-    {
323
-        do_action('AHEE__EE_Config___load_core_config__start', ['EEH_Activation', 'load_calendar_config']);
324
-        add_filter(
325
-            'FHEE__EE_Config___load_core_config__config_settings',
326
-            ['EEH_Activation', 'migrate_old_config_data'],
327
-            10,
328
-            3
329
-        );
330
-        // EE_Config::reset();
331
-        if (! EE_Config::logging_enabled()) {
332
-            delete_option(EE_Config::LOG_NAME);
333
-        }
334
-    }
335
-
336
-
337
-    /**
338
-     *    load_calendar_config
339
-     *
340
-     * @access    public
341
-     * @return    void
342
-     */
343
-    public static function load_calendar_config()
344
-    {
345
-        // grab array of all plugin folders and loop thru it
346
-        $plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
347
-        if (empty($plugins)) {
348
-            return;
349
-        }
350
-        foreach ($plugins as $plugin_path) {
351
-            // grab plugin folder name from path
352
-            $plugin = basename($plugin_path);
353
-            // drill down to Espresso plugins
354
-            // then to calendar related plugins
355
-            if (strpos($plugin, 'espresso') !== false
356
-                || strpos($plugin, 'Espresso') !== false
357
-                || strpos($plugin, 'ee4') !== false
358
-                || strpos($plugin, 'EE4') !== false
359
-                || strpos($plugin, 'calendar') !== false
360
-            ) {
361
-                // this is what we are looking for
362
-                $calendar_config = $plugin_path . '/EE_Calendar_Config.php';
363
-                // does it exist in this folder ?
364
-                if (is_readable($calendar_config)) {
365
-                    // YEAH! let's load it
366
-                    require_once($calendar_config);
367
-                }
368
-            }
369
-        }
370
-    }
371
-
372
-
373
-    /**
374
-     *    _migrate_old_config_data
375
-     *
376
-     * @access    public
377
-     * @param array|stdClass $settings
378
-     * @param string         $config
379
-     * @param EE_Config      $EE_Config
380
-     * @return stdClass
381
-     */
382
-    public static function migrate_old_config_data($settings = [], $config = '', EE_Config $EE_Config)
383
-    {
384
-        $convert_from_array = ['addons'];
385
-        // in case old settings were saved as an array
386
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
387
-            // convert existing settings to an object
388
-            $config_array = $settings;
389
-            $settings     = new stdClass();
390
-            foreach ($config_array as $key => $value) {
391
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
392
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
393
-                } else {
394
-                    $settings->{$key} = $value;
395
-                }
396
-            }
397
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
398
-        }
399
-        return $settings;
400
-    }
401
-
402
-
403
-    /**
404
-     * deactivate_event_espresso
405
-     *
406
-     * @access public
407
-     * @static
408
-     * @return void
409
-     */
410
-    public static function deactivate_event_espresso()
411
-    {
412
-        // check permissions
413
-        if (current_user_can('activate_plugins')) {
414
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
415
-        }
416
-    }
417
-
418
-
419
-    /**
420
-     * verify_default_pages_exist
421
-     *
422
-     * @access public
423
-     * @static
424
-     * @return void
425
-     * @throws InvalidDataTypeException
426
-     */
427
-    public static function verify_default_pages_exist()
428
-    {
429
-        $critical_page_problem = false;
430
-        $critical_pages        = [
431
-            [
432
-                'id'   => 'reg_page_id',
433
-                'name' => __('Registration Checkout', 'event_espresso'),
434
-                'post' => null,
435
-                'code' => 'ESPRESSO_CHECKOUT',
436
-            ],
437
-            [
438
-                'id'   => 'txn_page_id',
439
-                'name' => __('Transactions', 'event_espresso'),
440
-                'post' => null,
441
-                'code' => 'ESPRESSO_TXN_PAGE',
442
-            ],
443
-            [
444
-                'id'   => 'thank_you_page_id',
445
-                'name' => __('Thank You', 'event_espresso'),
446
-                'post' => null,
447
-                'code' => 'ESPRESSO_THANK_YOU',
448
-            ],
449
-            [
450
-                'id'   => 'cancel_page_id',
451
-                'name' => __('Registration Cancelled', 'event_espresso'),
452
-                'post' => null,
453
-                'code' => 'ESPRESSO_CANCELLED',
454
-            ],
455
-        ];
456
-        $EE_Core_Config        = EE_Registry::instance()->CFG->core;
457
-        foreach ($critical_pages as $critical_page) {
458
-            // is critical page ID set in config ?
459
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
460
-                // attempt to find post by ID
461
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
462
-            }
463
-            // no dice?
464
-            if ($critical_page['post'] === null) {
465
-                // attempt to find post by title
466
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
467
-                // still nothing?
468
-                if ($critical_page['post'] === null) {
469
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
470
-                    // REALLY? Still nothing ??!?!?
471
-                    if ($critical_page['post'] === null) {
472
-                        $msg = __(
473
-                            'The Event Espresso critical page configuration settings could not be updated.',
474
-                            'event_espresso'
475
-                        );
476
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
477
-                        break;
478
-                    }
479
-                }
480
-            }
481
-            // check that Post ID matches critical page ID in config
482
-            if (isset($critical_page['post']->ID)
483
-                && $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
484
-            ) {
485
-                // update Config with post ID
486
-                $EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
487
-                if (! EE_Config::instance()->update_espresso_config(false, false)) {
488
-                    $msg = __(
489
-                        'The Event Espresso critical page configuration settings could not be updated.',
490
-                        'event_espresso'
491
-                    );
492
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
493
-                }
494
-            }
495
-            $critical_page_problem =
496
-                ! isset($critical_page['post']->post_status)
497
-                || $critical_page['post']->post_status !== 'publish'
498
-                || strpos($critical_page['post']->post_content, $critical_page['code']) === false
499
-                    ? true
500
-                    : $critical_page_problem;
501
-        }
502
-        if ($critical_page_problem) {
503
-            new PersistentAdminNotice(
504
-                'critical_page_problem',
505
-                sprintf(
506
-                    esc_html__(
507
-                        'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
508
-                        'event_espresso'
509
-                    ),
510
-                    '<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
511
-                    . __('Event Espresso Critical Pages Settings', 'event_espresso')
512
-                    . '</a>'
513
-                )
514
-            );
515
-        }
516
-        if (EE_Error::has_notices()) {
517
-            EE_Error::get_notices(false, true, true);
518
-        }
519
-    }
520
-
521
-
522
-    /**
523
-     * Returns the first post which uses the specified shortcode
524
-     *
525
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
526
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
527
-     *                             "[ESPRESSO_THANK_YOU"
528
-     *                             (we don't search for the closing shortcode bracket because they might have added
529
-     *                             parameter to the shortcode
530
-     * @return WP_Post or NULl
531
-     */
532
-    public static function get_page_by_ee_shortcode($ee_shortcode)
533
-    {
534
-        global $wpdb;
535
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
536
-        $post_id                       =
537
-            $wpdb->get_var(
538
-                "SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1"
539
-            );
540
-        if ($post_id) {
541
-            return get_post($post_id);
542
-        } else {
543
-            return null;
544
-        }
545
-    }
546
-
547
-
548
-    /**
549
-     *    This function generates a post for critical espresso pages
550
-     *
551
-     * @access public
552
-     * @static
553
-     * @param array $critical_page
554
-     * @return array
555
-     */
556
-    public static function create_critical_page($critical_page)
557
-    {
558
-
559
-        $post_args = [
560
-            'post_title'     => $critical_page['name'],
561
-            'post_status'    => 'publish',
562
-            'post_type'      => 'page',
563
-            'comment_status' => 'closed',
564
-            'post_content'   => '[' . $critical_page['code'] . ']',
565
-        ];
566
-
567
-        $post_id = wp_insert_post($post_args);
568
-        if (! $post_id) {
569
-            $msg = sprintf(
570
-                __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
571
-                $critical_page['name']
572
-            );
573
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
574
-            return $critical_page;
575
-        }
576
-        // get newly created post's details
577
-        if (! $critical_page['post'] = get_post($post_id)) {
578
-            $msg = sprintf(
579
-                __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
580
-                $critical_page['name']
581
-            );
582
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
583
-        }
584
-
585
-        return $critical_page;
586
-    }
587
-
588
-
589
-    /**
590
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
591
-     * The role being used to check is filterable.
592
-     *
593
-     * @return mixed null|int WP_user ID or NULL
594
-     * @throws EE_Error
595
-     * @throws ReflectionException
596
-     * @since  4.6.0
597
-     * @global WPDB $wpdb
598
-     */
599
-    public static function get_default_creator_id()
600
-    {
601
-        global $wpdb;
602
-        if (! empty(self::$_default_creator_id)) {
603
-            return self::$_default_creator_id;
604
-        }/**/
605
-        $role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
606
-        // let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
607
-        $pre_filtered_id = apply_filters(
608
-            'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
609
-            false,
610
-            $role_to_check
611
-        );
612
-        if ($pre_filtered_id !== false) {
613
-            return (int) $pre_filtered_id;
614
-        }
615
-        $capabilities_key = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
616
-        $query            = $wpdb->prepare(
617
-            "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
618
-            '%' . $role_to_check . '%'
619
-        );
620
-        $user_id          = $wpdb->get_var($query);
621
-        $user_id          = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
622
-        if ($user_id && (int) $user_id) {
623
-            self::$_default_creator_id = (int) $user_id;
624
-            return self::$_default_creator_id;
625
-        } else {
626
-            return null;
627
-        }
628
-    }
629
-
630
-
631
-    /**
632
-     * used by EE and EE addons during plugin activation to create tables.
633
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
634
-     * but includes extra logic regarding activations.
635
-     *
636
-     * @access public
637
-     * @static
638
-     * @param string  $table_name              without the $wpdb->prefix
639
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
640
-     *                                         table query)
641
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
642
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
643
-     *                                         and new once this function is done (ie, you really do want to CREATE a
644
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
645
-     *                                         you just want to verify the table exists and matches this definition
646
-     *                                         (and if it HAS data in it you want to leave it be)
647
-     * @return void
648
-     * @throws EE_Error if there are database errors
649
-     * @throws ReflectionException
650
-     */
651
-    public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
652
-    {
653
-        if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
654
-            return;
655
-        }
656
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
657
-        if (! function_exists('dbDelta')) {
658
-            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
659
-        }
660
-        $tableAnalysis = EEH_Activation::getTableAnalysis();
661
-        $wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
662
-        // do we need to first delete an existing version of this table ?
663
-        if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
664
-            // ok, delete the table... but ONLY if it's empty
665
-            $deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
666
-            // table is NOT empty, are you SURE you want to delete this table ???
667
-            if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
668
-                EEH_Activation::getTableManager()->dropTable($wp_table_name);
669
-            } elseif (! $deleted_safely) {
670
-                // so we should be more cautious rather than just dropping tables so easily
671
-                error_log(
672
-                    sprintf(
673
-                        __(
674
-                            'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
675
-                            'event_espresso'
676
-                        ),
677
-                        $wp_table_name,
678
-                        '<br/>',
679
-                        'espresso_db_update'
680
-                    )
681
-                );
682
-            }
683
-        }
684
-        $engine = str_replace('ENGINE=', '', $engine);
685
-        EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
686
-    }
687
-
688
-
689
-    /**
690
-     *    add_column_if_it_doesnt_exist
691
-     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
692
-     *
693
-     * @access     public
694
-     * @static
695
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
696
-     * @param string $column_name
697
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
698
-     *                            'VARCHAR(10)'
699
-     * @return bool|int
700
-     * @throws EE_Error
701
-     * @throws ReflectionException
702
-     * @deprecated instead use TableManager::addColumn()
703
-     */
704
-    public static function add_column_if_it_doesnt_exist(
705
-        $table_name,
706
-        $column_name,
707
-        $column_info = 'INT UNSIGNED NOT NULL'
708
-    ) {
709
-        return EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
710
-    }
711
-
712
-
713
-    /**
714
-     * get_fields_on_table
715
-     * Gets all the fields on the database table.
716
-     *
717
-     * @access     public
718
-     * @param string $table_name , without prefixed $wpdb->prefix
719
-     * @return array of database column names
720
-     * @throws EE_Error
721
-     * @throws ReflectionException
722
-     * @deprecated instead use TableManager::getTableColumns()
723
-     * @static
724
-     */
725
-    public static function get_fields_on_table($table_name = null)
726
-    {
727
-        return EEH_Activation::getTableManager()->getTableColumns($table_name);
728
-    }
729
-
730
-
731
-    /**
732
-     * db_table_is_empty
733
-     *
734
-     * @access     public\
735
-     * @param string $table_name
736
-     * @return bool
737
-     * @throws EE_Error
738
-     * @throws ReflectionException
739
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
740
-     * @static
741
-     */
742
-    public static function db_table_is_empty($table_name)
743
-    {
744
-        return EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
745
-    }
746
-
747
-
748
-    /**
749
-     * delete_db_table_if_empty
750
-     *
751
-     * @access public
752
-     * @static
753
-     * @param string $table_name
754
-     * @return bool | int
755
-     * @throws EE_Error
756
-     * @throws ReflectionException
757
-     */
758
-    public static function delete_db_table_if_empty($table_name)
759
-    {
760
-        if (EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
761
-            return EEH_Activation::getTableManager()->dropTable($table_name);
762
-        }
763
-        return false;
764
-    }
765
-
766
-
767
-    /**
768
-     * delete_unused_db_table
769
-     *
770
-     * @access     public
771
-     * @static
772
-     * @param string $table_name
773
-     * @return bool | int
774
-     * @throws EE_Error
775
-     * @throws ReflectionException
776
-     * @deprecated instead use TableManager::dropTable()
777
-     */
778
-    public static function delete_unused_db_table($table_name)
779
-    {
780
-        return EEH_Activation::getTableManager()->dropTable($table_name);
781
-    }
782
-
783
-
784
-    /**
785
-     * drop_index
786
-     *
787
-     * @access     public
788
-     * @static
789
-     * @param string $table_name
790
-     * @param string $index_name
791
-     * @return bool | int
792
-     * @throws EE_Error
793
-     * @throws ReflectionException
794
-     * @deprecated instead use TableManager::dropIndex()
795
-     */
796
-    public static function drop_index($table_name, $index_name)
797
-    {
798
-        return EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
799
-    }
800
-
801
-
802
-    /**
803
-     * create_database_tables
804
-     *
805
-     * @access public
806
-     * @static
807
-     * @return boolean success (whether database is setup properly or not)
808
-     * @throws ReflectionException
809
-     * @throws EE_Error
810
-     */
811
-    public static function create_database_tables()
812
-    {
813
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
814
-        // find the migration script that sets the database to be compatible with the code
815
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
816
-        if ($dms_name) {
817
-            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
818
-            $current_data_migration_script->set_migrating(false);
819
-            $current_data_migration_script->schema_changes_before_migration();
820
-            $current_data_migration_script->schema_changes_after_migration();
821
-            if ($current_data_migration_script->get_errors()) {
822
-                if (WP_DEBUG) {
823
-                    foreach ($current_data_migration_script->get_errors() as $error) {
824
-                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
825
-                    }
826
-                } else {
827
-                    EE_Error::add_error(
828
-                        __(
829
-                            'There were errors creating the Event Espresso database tables and Event Espresso has been
273
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
274
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
275
+			if (is_array($hooks_to_fire_at_time)) {
276
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
277
+					if (isset($ee_cron_tasks_to_remove[ $hook_name ])
278
+						&& is_array($ee_cron_tasks_to_remove[ $hook_name ])
279
+					) {
280
+						unset($crons[ $timestamp ][ $hook_name ]);
281
+					}
282
+				}
283
+				// also take care of any empty cron timestamps.
284
+				if (empty($hooks_to_fire_at_time)) {
285
+					unset($crons[ $timestamp ]);
286
+				}
287
+			}
288
+		}
289
+		_set_cron_array($crons);
290
+	}
291
+
292
+
293
+	/**
294
+	 *    CPT_initialization
295
+	 *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
296
+	 *
297
+	 * @access public
298
+	 * @static
299
+	 * @return void
300
+	 * @throws EE_Error
301
+	 * @throws ReflectionException
302
+	 */
303
+	public static function CPT_initialization()
304
+	{
305
+		// register Custom Post Types
306
+		EE_Registry::instance()->load_core('Register_CPTs');
307
+		flush_rewrite_rules();
308
+	}
309
+
310
+
311
+	/**
312
+	 *    reset_and_update_config
313
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
314
+	 * If there is old calendar config data saved, then it will get converted on activation.
315
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
316
+	 *
317
+	 * @access public
318
+	 * @static
319
+	 * @return void
320
+	 */
321
+	public static function reset_and_update_config()
322
+	{
323
+		do_action('AHEE__EE_Config___load_core_config__start', ['EEH_Activation', 'load_calendar_config']);
324
+		add_filter(
325
+			'FHEE__EE_Config___load_core_config__config_settings',
326
+			['EEH_Activation', 'migrate_old_config_data'],
327
+			10,
328
+			3
329
+		);
330
+		// EE_Config::reset();
331
+		if (! EE_Config::logging_enabled()) {
332
+			delete_option(EE_Config::LOG_NAME);
333
+		}
334
+	}
335
+
336
+
337
+	/**
338
+	 *    load_calendar_config
339
+	 *
340
+	 * @access    public
341
+	 * @return    void
342
+	 */
343
+	public static function load_calendar_config()
344
+	{
345
+		// grab array of all plugin folders and loop thru it
346
+		$plugins = glob(WP_PLUGIN_DIR . '/*', GLOB_ONLYDIR);
347
+		if (empty($plugins)) {
348
+			return;
349
+		}
350
+		foreach ($plugins as $plugin_path) {
351
+			// grab plugin folder name from path
352
+			$plugin = basename($plugin_path);
353
+			// drill down to Espresso plugins
354
+			// then to calendar related plugins
355
+			if (strpos($plugin, 'espresso') !== false
356
+				|| strpos($plugin, 'Espresso') !== false
357
+				|| strpos($plugin, 'ee4') !== false
358
+				|| strpos($plugin, 'EE4') !== false
359
+				|| strpos($plugin, 'calendar') !== false
360
+			) {
361
+				// this is what we are looking for
362
+				$calendar_config = $plugin_path . '/EE_Calendar_Config.php';
363
+				// does it exist in this folder ?
364
+				if (is_readable($calendar_config)) {
365
+					// YEAH! let's load it
366
+					require_once($calendar_config);
367
+				}
368
+			}
369
+		}
370
+	}
371
+
372
+
373
+	/**
374
+	 *    _migrate_old_config_data
375
+	 *
376
+	 * @access    public
377
+	 * @param array|stdClass $settings
378
+	 * @param string         $config
379
+	 * @param EE_Config      $EE_Config
380
+	 * @return stdClass
381
+	 */
382
+	public static function migrate_old_config_data($settings = [], $config = '', EE_Config $EE_Config)
383
+	{
384
+		$convert_from_array = ['addons'];
385
+		// in case old settings were saved as an array
386
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
387
+			// convert existing settings to an object
388
+			$config_array = $settings;
389
+			$settings     = new stdClass();
390
+			foreach ($config_array as $key => $value) {
391
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
392
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
393
+				} else {
394
+					$settings->{$key} = $value;
395
+				}
396
+			}
397
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
398
+		}
399
+		return $settings;
400
+	}
401
+
402
+
403
+	/**
404
+	 * deactivate_event_espresso
405
+	 *
406
+	 * @access public
407
+	 * @static
408
+	 * @return void
409
+	 */
410
+	public static function deactivate_event_espresso()
411
+	{
412
+		// check permissions
413
+		if (current_user_can('activate_plugins')) {
414
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
415
+		}
416
+	}
417
+
418
+
419
+	/**
420
+	 * verify_default_pages_exist
421
+	 *
422
+	 * @access public
423
+	 * @static
424
+	 * @return void
425
+	 * @throws InvalidDataTypeException
426
+	 */
427
+	public static function verify_default_pages_exist()
428
+	{
429
+		$critical_page_problem = false;
430
+		$critical_pages        = [
431
+			[
432
+				'id'   => 'reg_page_id',
433
+				'name' => __('Registration Checkout', 'event_espresso'),
434
+				'post' => null,
435
+				'code' => 'ESPRESSO_CHECKOUT',
436
+			],
437
+			[
438
+				'id'   => 'txn_page_id',
439
+				'name' => __('Transactions', 'event_espresso'),
440
+				'post' => null,
441
+				'code' => 'ESPRESSO_TXN_PAGE',
442
+			],
443
+			[
444
+				'id'   => 'thank_you_page_id',
445
+				'name' => __('Thank You', 'event_espresso'),
446
+				'post' => null,
447
+				'code' => 'ESPRESSO_THANK_YOU',
448
+			],
449
+			[
450
+				'id'   => 'cancel_page_id',
451
+				'name' => __('Registration Cancelled', 'event_espresso'),
452
+				'post' => null,
453
+				'code' => 'ESPRESSO_CANCELLED',
454
+			],
455
+		];
456
+		$EE_Core_Config        = EE_Registry::instance()->CFG->core;
457
+		foreach ($critical_pages as $critical_page) {
458
+			// is critical page ID set in config ?
459
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
460
+				// attempt to find post by ID
461
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
462
+			}
463
+			// no dice?
464
+			if ($critical_page['post'] === null) {
465
+				// attempt to find post by title
466
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
467
+				// still nothing?
468
+				if ($critical_page['post'] === null) {
469
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
470
+					// REALLY? Still nothing ??!?!?
471
+					if ($critical_page['post'] === null) {
472
+						$msg = __(
473
+							'The Event Espresso critical page configuration settings could not be updated.',
474
+							'event_espresso'
475
+						);
476
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
477
+						break;
478
+					}
479
+				}
480
+			}
481
+			// check that Post ID matches critical page ID in config
482
+			if (isset($critical_page['post']->ID)
483
+				&& $critical_page['post']->ID !== $EE_Core_Config->{$critical_page['id']}
484
+			) {
485
+				// update Config with post ID
486
+				$EE_Core_Config->{$critical_page['id']} = $critical_page['post']->ID;
487
+				if (! EE_Config::instance()->update_espresso_config(false, false)) {
488
+					$msg = __(
489
+						'The Event Espresso critical page configuration settings could not be updated.',
490
+						'event_espresso'
491
+					);
492
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
493
+				}
494
+			}
495
+			$critical_page_problem =
496
+				! isset($critical_page['post']->post_status)
497
+				|| $critical_page['post']->post_status !== 'publish'
498
+				|| strpos($critical_page['post']->post_content, $critical_page['code']) === false
499
+					? true
500
+					: $critical_page_problem;
501
+		}
502
+		if ($critical_page_problem) {
503
+			new PersistentAdminNotice(
504
+				'critical_page_problem',
505
+				sprintf(
506
+					esc_html__(
507
+						'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
508
+						'event_espresso'
509
+					),
510
+					'<a href="' . admin_url('admin.php?page=espresso_general_settings&action=critical_pages') . '">'
511
+					. __('Event Espresso Critical Pages Settings', 'event_espresso')
512
+					. '</a>'
513
+				)
514
+			);
515
+		}
516
+		if (EE_Error::has_notices()) {
517
+			EE_Error::get_notices(false, true, true);
518
+		}
519
+	}
520
+
521
+
522
+	/**
523
+	 * Returns the first post which uses the specified shortcode
524
+	 *
525
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
526
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
527
+	 *                             "[ESPRESSO_THANK_YOU"
528
+	 *                             (we don't search for the closing shortcode bracket because they might have added
529
+	 *                             parameter to the shortcode
530
+	 * @return WP_Post or NULl
531
+	 */
532
+	public static function get_page_by_ee_shortcode($ee_shortcode)
533
+	{
534
+		global $wpdb;
535
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
536
+		$post_id                       =
537
+			$wpdb->get_var(
538
+				"SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1"
539
+			);
540
+		if ($post_id) {
541
+			return get_post($post_id);
542
+		} else {
543
+			return null;
544
+		}
545
+	}
546
+
547
+
548
+	/**
549
+	 *    This function generates a post for critical espresso pages
550
+	 *
551
+	 * @access public
552
+	 * @static
553
+	 * @param array $critical_page
554
+	 * @return array
555
+	 */
556
+	public static function create_critical_page($critical_page)
557
+	{
558
+
559
+		$post_args = [
560
+			'post_title'     => $critical_page['name'],
561
+			'post_status'    => 'publish',
562
+			'post_type'      => 'page',
563
+			'comment_status' => 'closed',
564
+			'post_content'   => '[' . $critical_page['code'] . ']',
565
+		];
566
+
567
+		$post_id = wp_insert_post($post_args);
568
+		if (! $post_id) {
569
+			$msg = sprintf(
570
+				__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
571
+				$critical_page['name']
572
+			);
573
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
574
+			return $critical_page;
575
+		}
576
+		// get newly created post's details
577
+		if (! $critical_page['post'] = get_post($post_id)) {
578
+			$msg = sprintf(
579
+				__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
580
+				$critical_page['name']
581
+			);
582
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
583
+		}
584
+
585
+		return $critical_page;
586
+	}
587
+
588
+
589
+	/**
590
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
591
+	 * The role being used to check is filterable.
592
+	 *
593
+	 * @return mixed null|int WP_user ID or NULL
594
+	 * @throws EE_Error
595
+	 * @throws ReflectionException
596
+	 * @since  4.6.0
597
+	 * @global WPDB $wpdb
598
+	 */
599
+	public static function get_default_creator_id()
600
+	{
601
+		global $wpdb;
602
+		if (! empty(self::$_default_creator_id)) {
603
+			return self::$_default_creator_id;
604
+		}/**/
605
+		$role_to_check = apply_filters('FHEE__EEH_Activation__get_default_creator_id__role_to_check', 'administrator');
606
+		// let's allow pre_filtering for early exits by alternative methods for getting id.  We check for truthy result and if so then exit early.
607
+		$pre_filtered_id = apply_filters(
608
+			'FHEE__EEH_Activation__get_default_creator_id__pre_filtered_id',
609
+			false,
610
+			$role_to_check
611
+		);
612
+		if ($pre_filtered_id !== false) {
613
+			return (int) $pre_filtered_id;
614
+		}
615
+		$capabilities_key = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('capabilities');
616
+		$query            = $wpdb->prepare(
617
+			"SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$capabilities_key' AND meta_value LIKE %s ORDER BY user_id ASC LIMIT 0,1",
618
+			'%' . $role_to_check . '%'
619
+		);
620
+		$user_id          = $wpdb->get_var($query);
621
+		$user_id          = apply_filters('FHEE__EEH_Activation_Helper__get_default_creator_id__user_id', $user_id);
622
+		if ($user_id && (int) $user_id) {
623
+			self::$_default_creator_id = (int) $user_id;
624
+			return self::$_default_creator_id;
625
+		} else {
626
+			return null;
627
+		}
628
+	}
629
+
630
+
631
+	/**
632
+	 * used by EE and EE addons during plugin activation to create tables.
633
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
634
+	 * but includes extra logic regarding activations.
635
+	 *
636
+	 * @access public
637
+	 * @static
638
+	 * @param string  $table_name              without the $wpdb->prefix
639
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
640
+	 *                                         table query)
641
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
642
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
643
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
644
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
645
+	 *                                         you just want to verify the table exists and matches this definition
646
+	 *                                         (and if it HAS data in it you want to leave it be)
647
+	 * @return void
648
+	 * @throws EE_Error if there are database errors
649
+	 * @throws ReflectionException
650
+	 */
651
+	public static function create_table($table_name, $sql, $engine = 'ENGINE=MyISAM ', $drop_pre_existing_table = false)
652
+	{
653
+		if (apply_filters('FHEE__EEH_Activation__create_table__short_circuit', false, $table_name, $sql)) {
654
+			return;
655
+		}
656
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
657
+		if (! function_exists('dbDelta')) {
658
+			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
659
+		}
660
+		$tableAnalysis = EEH_Activation::getTableAnalysis();
661
+		$wp_table_name = $tableAnalysis->ensureTableNameHasPrefix($table_name);
662
+		// do we need to first delete an existing version of this table ?
663
+		if ($drop_pre_existing_table && $tableAnalysis->tableExists($wp_table_name)) {
664
+			// ok, delete the table... but ONLY if it's empty
665
+			$deleted_safely = EEH_Activation::delete_db_table_if_empty($wp_table_name);
666
+			// table is NOT empty, are you SURE you want to delete this table ???
667
+			if (! $deleted_safely && defined('EE_DROP_BAD_TABLES') && EE_DROP_BAD_TABLES) {
668
+				EEH_Activation::getTableManager()->dropTable($wp_table_name);
669
+			} elseif (! $deleted_safely) {
670
+				// so we should be more cautious rather than just dropping tables so easily
671
+				error_log(
672
+					sprintf(
673
+						__(
674
+							'It appears that database table "%1$s" exists when it shouldn\'t, and therefore may contain erroneous data. If you have previously restored your database from a backup that didn\'t remove the old tables, then we recommend: %2$s 1. create a new COMPLETE backup of your database, %2$s 2. delete ALL tables from your database, %2$s 3. restore to your previous backup. %2$s If, however, you have not restored to a backup, then somehow your "%3$s" WordPress option could not be read. You can probably ignore this message, but should investigate why that option is being removed.',
675
+							'event_espresso'
676
+						),
677
+						$wp_table_name,
678
+						'<br/>',
679
+						'espresso_db_update'
680
+					)
681
+				);
682
+			}
683
+		}
684
+		$engine = str_replace('ENGINE=', '', $engine);
685
+		EEH_Activation::getTableManager()->createTable($table_name, $sql, $engine);
686
+	}
687
+
688
+
689
+	/**
690
+	 *    add_column_if_it_doesnt_exist
691
+	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
692
+	 *
693
+	 * @access     public
694
+	 * @static
695
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
696
+	 * @param string $column_name
697
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
698
+	 *                            'VARCHAR(10)'
699
+	 * @return bool|int
700
+	 * @throws EE_Error
701
+	 * @throws ReflectionException
702
+	 * @deprecated instead use TableManager::addColumn()
703
+	 */
704
+	public static function add_column_if_it_doesnt_exist(
705
+		$table_name,
706
+		$column_name,
707
+		$column_info = 'INT UNSIGNED NOT NULL'
708
+	) {
709
+		return EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
710
+	}
711
+
712
+
713
+	/**
714
+	 * get_fields_on_table
715
+	 * Gets all the fields on the database table.
716
+	 *
717
+	 * @access     public
718
+	 * @param string $table_name , without prefixed $wpdb->prefix
719
+	 * @return array of database column names
720
+	 * @throws EE_Error
721
+	 * @throws ReflectionException
722
+	 * @deprecated instead use TableManager::getTableColumns()
723
+	 * @static
724
+	 */
725
+	public static function get_fields_on_table($table_name = null)
726
+	{
727
+		return EEH_Activation::getTableManager()->getTableColumns($table_name);
728
+	}
729
+
730
+
731
+	/**
732
+	 * db_table_is_empty
733
+	 *
734
+	 * @access     public\
735
+	 * @param string $table_name
736
+	 * @return bool
737
+	 * @throws EE_Error
738
+	 * @throws ReflectionException
739
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
740
+	 * @static
741
+	 */
742
+	public static function db_table_is_empty($table_name)
743
+	{
744
+		return EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
745
+	}
746
+
747
+
748
+	/**
749
+	 * delete_db_table_if_empty
750
+	 *
751
+	 * @access public
752
+	 * @static
753
+	 * @param string $table_name
754
+	 * @return bool | int
755
+	 * @throws EE_Error
756
+	 * @throws ReflectionException
757
+	 */
758
+	public static function delete_db_table_if_empty($table_name)
759
+	{
760
+		if (EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
761
+			return EEH_Activation::getTableManager()->dropTable($table_name);
762
+		}
763
+		return false;
764
+	}
765
+
766
+
767
+	/**
768
+	 * delete_unused_db_table
769
+	 *
770
+	 * @access     public
771
+	 * @static
772
+	 * @param string $table_name
773
+	 * @return bool | int
774
+	 * @throws EE_Error
775
+	 * @throws ReflectionException
776
+	 * @deprecated instead use TableManager::dropTable()
777
+	 */
778
+	public static function delete_unused_db_table($table_name)
779
+	{
780
+		return EEH_Activation::getTableManager()->dropTable($table_name);
781
+	}
782
+
783
+
784
+	/**
785
+	 * drop_index
786
+	 *
787
+	 * @access     public
788
+	 * @static
789
+	 * @param string $table_name
790
+	 * @param string $index_name
791
+	 * @return bool | int
792
+	 * @throws EE_Error
793
+	 * @throws ReflectionException
794
+	 * @deprecated instead use TableManager::dropIndex()
795
+	 */
796
+	public static function drop_index($table_name, $index_name)
797
+	{
798
+		return EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
799
+	}
800
+
801
+
802
+	/**
803
+	 * create_database_tables
804
+	 *
805
+	 * @access public
806
+	 * @static
807
+	 * @return boolean success (whether database is setup properly or not)
808
+	 * @throws ReflectionException
809
+	 * @throws EE_Error
810
+	 */
811
+	public static function create_database_tables()
812
+	{
813
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
814
+		// find the migration script that sets the database to be compatible with the code
815
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
816
+		if ($dms_name) {
817
+			$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
818
+			$current_data_migration_script->set_migrating(false);
819
+			$current_data_migration_script->schema_changes_before_migration();
820
+			$current_data_migration_script->schema_changes_after_migration();
821
+			if ($current_data_migration_script->get_errors()) {
822
+				if (WP_DEBUG) {
823
+					foreach ($current_data_migration_script->get_errors() as $error) {
824
+						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
825
+					}
826
+				} else {
827
+					EE_Error::add_error(
828
+						__(
829
+							'There were errors creating the Event Espresso database tables and Event Espresso has been
830 830
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
831
-                            'event_espresso'
832
-                        )
833
-                    );
834
-                }
835
-                return false;
836
-            }
837
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
838
-        } else {
839
-            EE_Error::add_error(
840
-                __(
841
-                    'Could not determine most up-to-date data migration script from which to pull database schema
831
+							'event_espresso'
832
+						)
833
+					);
834
+				}
835
+				return false;
836
+			}
837
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
838
+		} else {
839
+			EE_Error::add_error(
840
+				__(
841
+					'Could not determine most up-to-date data migration script from which to pull database schema
842 842
                      structure. So database is probably not setup properly',
843
-                    'event_espresso'
844
-                ),
845
-                __FILE__,
846
-                __FUNCTION__,
847
-                __LINE__
848
-            );
849
-            return false;
850
-        }
851
-        return true;
852
-    }
853
-
854
-
855
-    /**
856
-     * initialize_system_questions
857
-     *
858
-     * @access public
859
-     * @static
860
-     * @return void
861
-     * @throws EE_Error
862
-     * @throws ReflectionException
863
-     */
864
-    public static function initialize_system_questions()
865
-    {
866
-        // QUESTION GROUPS
867
-        global $wpdb;
868
-        $table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
869
-        $SQL        = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
870
-        // what we have
871
-        $question_groups = $wpdb->get_col($SQL);
872
-        // check the response
873
-        $question_groups = is_array($question_groups) ? $question_groups : [];
874
-        // what we should have
875
-        $QSG_systems = [1, 2];
876
-        // loop thru what we should have and compare to what we have
877
-        foreach ($QSG_systems as $QSG_system) {
878
-            // reset values array
879
-            $QSG_values = [];
880
-            // if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
881
-            if (! in_array("$QSG_system", $question_groups)) {
882
-                // add it
883
-                switch ($QSG_system) {
884
-                    case 1:
885
-                        $QSG_values = [
886
-                            'QSG_name'            => __('Personal Information', 'event_espresso'),
887
-                            'QSG_identifier'      => 'personal-information-' . time(),
888
-                            'QSG_desc'            => '',
889
-                            'QSG_order'           => 1,
890
-                            'QSG_show_group_name' => 1,
891
-                            'QSG_show_group_desc' => 1,
892
-                            'QSG_system'          => EEM_Question_Group::system_personal,
893
-                            'QSG_deleted'         => 0,
894
-                        ];
895
-                        break;
896
-                    case 2:
897
-                        $QSG_values = [
898
-                            'QSG_name'            => __('Address Information', 'event_espresso'),
899
-                            'QSG_identifier'      => 'address-information-' . time(),
900
-                            'QSG_desc'            => '',
901
-                            'QSG_order'           => 2,
902
-                            'QSG_show_group_name' => 1,
903
-                            'QSG_show_group_desc' => 1,
904
-                            'QSG_system'          => EEM_Question_Group::system_address,
905
-                            'QSG_deleted'         => 0,
906
-                        ];
907
-                        break;
908
-                }
909
-                // make sure we have some values before inserting them
910
-                if (! empty($QSG_values)) {
911
-                    // insert system question
912
-                    $wpdb->insert(
913
-                        $table_name,
914
-                        $QSG_values,
915
-                        ['%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d']
916
-                    );
917
-                    $QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
918
-                }
919
-            }
920
-        }
921
-        // QUESTIONS
922
-        global $wpdb;
923
-        $table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
924
-        $SQL        = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
925
-        // what we have
926
-        $questions = $wpdb->get_col($SQL);
927
-        // all system questions
928
-        $personal_system_group_questions = ['fname', 'lname', 'email'];
929
-        $address_system_group_questions  = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
930
-        $system_questions_not_in_group   = ['email_confirm'];
931
-        // merge all of the system questions we should have
932
-        $QST_systems       = array_merge(
933
-            $personal_system_group_questions,
934
-            $address_system_group_questions,
935
-            $system_questions_not_in_group
936
-        );
937
-        $order_for_group_1 = 1;
938
-        $order_for_group_2 = 1;
939
-        // loop thru what we should have and compare to what we have
940
-        foreach ($QST_systems as $QST_system) {
941
-            // reset values array
942
-            $QST_values = [];
943
-            // if we don't have what we should have
944
-            if (! in_array($QST_system, $questions)) {
945
-                // add it
946
-                switch ($QST_system) {
947
-                    case 'fname':
948
-                        $QST_values = [
949
-                            'QST_display_text'  => __('First Name', 'event_espresso'),
950
-                            'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
951
-                            'QST_system'        => 'fname',
952
-                            'QST_type'          => 'TEXT',
953
-                            'QST_required'      => 1,
954
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
955
-                            'QST_order'         => 1,
956
-                            'QST_admin_only'    => 0,
957
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
958
-                                $QST_system
959
-                            ),
960
-                            'QST_wp_user'       => self::get_default_creator_id(),
961
-                            'QST_deleted'       => 0,
962
-                        ];
963
-                        break;
964
-                    case 'lname':
965
-                        $QST_values = [
966
-                            'QST_display_text'  => __('Last Name', 'event_espresso'),
967
-                            'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
968
-                            'QST_system'        => 'lname',
969
-                            'QST_type'          => 'TEXT',
970
-                            'QST_required'      => 1,
971
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
972
-                            'QST_order'         => 2,
973
-                            'QST_admin_only'    => 0,
974
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
975
-                                $QST_system
976
-                            ),
977
-                            'QST_wp_user'       => self::get_default_creator_id(),
978
-                            'QST_deleted'       => 0,
979
-                        ];
980
-                        break;
981
-                    case 'email':
982
-                        $QST_values = [
983
-                            'QST_display_text'  => __('Email Address', 'event_espresso'),
984
-                            'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
985
-                            'QST_system'        => 'email',
986
-                            'QST_type'          => 'EMAIL',
987
-                            'QST_required'      => 1,
988
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
989
-                            'QST_order'         => 3,
990
-                            'QST_admin_only'    => 0,
991
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
992
-                                $QST_system
993
-                            ),
994
-                            'QST_wp_user'       => self::get_default_creator_id(),
995
-                            'QST_deleted'       => 0,
996
-                        ];
997
-                        break;
998
-                    case 'email_confirm':
999
-                        $QST_values = [
1000
-                            'QST_display_text'  => __('Confirm Email Address', 'event_espresso'),
1001
-                            'QST_admin_label'   => __('Confirm Email Address - System Question', 'event_espresso'),
1002
-                            'QST_system'        => 'email_confirm',
1003
-                            'QST_type'          => 'EMAIL_CONFIRM',
1004
-                            'QST_required'      => 1,
1005
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1006
-                            'QST_order'         => 4,
1007
-                            'QST_admin_only'    => 0,
1008
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1009
-                                $QST_system
1010
-                            ),
1011
-                            'QST_wp_user'       => self::get_default_creator_id(),
1012
-                            'QST_deleted'       => 0,
1013
-                        ];
1014
-                        break;
1015
-                    case 'address':
1016
-                        $QST_values = [
1017
-                            'QST_display_text'  => __('Address', 'event_espresso'),
1018
-                            'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
1019
-                            'QST_system'        => 'address',
1020
-                            'QST_type'          => 'TEXT',
1021
-                            'QST_required'      => 0,
1022
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1023
-                            'QST_order'         => 5,
1024
-                            'QST_admin_only'    => 0,
1025
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1026
-                                $QST_system
1027
-                            ),
1028
-                            'QST_wp_user'       => self::get_default_creator_id(),
1029
-                            'QST_deleted'       => 0,
1030
-                        ];
1031
-                        break;
1032
-                    case 'address2':
1033
-                        $QST_values = [
1034
-                            'QST_display_text'  => __('Address2', 'event_espresso'),
1035
-                            'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1036
-                            'QST_system'        => 'address2',
1037
-                            'QST_type'          => 'TEXT',
1038
-                            'QST_required'      => 0,
1039
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1040
-                            'QST_order'         => 6,
1041
-                            'QST_admin_only'    => 0,
1042
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1043
-                                $QST_system
1044
-                            ),
1045
-                            'QST_wp_user'       => self::get_default_creator_id(),
1046
-                            'QST_deleted'       => 0,
1047
-                        ];
1048
-                        break;
1049
-                    case 'city':
1050
-                        $QST_values = [
1051
-                            'QST_display_text'  => __('City', 'event_espresso'),
1052
-                            'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1053
-                            'QST_system'        => 'city',
1054
-                            'QST_type'          => 'TEXT',
1055
-                            'QST_required'      => 0,
1056
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1057
-                            'QST_order'         => 7,
1058
-                            'QST_admin_only'    => 0,
1059
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1060
-                                $QST_system
1061
-                            ),
1062
-                            'QST_wp_user'       => self::get_default_creator_id(),
1063
-                            'QST_deleted'       => 0,
1064
-                        ];
1065
-                        break;
1066
-                    case 'country':
1067
-                        $QST_values = [
1068
-                            'QST_display_text'  => __('Country', 'event_espresso'),
1069
-                            'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1070
-                            'QST_system'        => 'country',
1071
-                            'QST_type'          => 'COUNTRY',
1072
-                            'QST_required'      => 0,
1073
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1074
-                            'QST_order'         => 8,
1075
-                            'QST_admin_only'    => 0,
1076
-                            'QST_wp_user'       => self::get_default_creator_id(),
1077
-                            'QST_deleted'       => 0,
1078
-                        ];
1079
-                        break;
1080
-                    case 'state':
1081
-                        $QST_values = [
1082
-                            'QST_display_text'  => __('State/Province', 'event_espresso'),
1083
-                            'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1084
-                            'QST_system'        => 'state',
1085
-                            'QST_type'          => 'STATE',
1086
-                            'QST_required'      => 0,
1087
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1088
-                            'QST_order'         => 9,
1089
-                            'QST_admin_only'    => 0,
1090
-                            'QST_wp_user'       => self::get_default_creator_id(),
1091
-                            'QST_deleted'       => 0,
1092
-                        ];
1093
-                        break;
1094
-                    case 'zip':
1095
-                        $QST_values = [
1096
-                            'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1097
-                            'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1098
-                            'QST_system'        => 'zip',
1099
-                            'QST_type'          => 'TEXT',
1100
-                            'QST_required'      => 0,
1101
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1102
-                            'QST_order'         => 10,
1103
-                            'QST_admin_only'    => 0,
1104
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1105
-                                $QST_system
1106
-                            ),
1107
-                            'QST_wp_user'       => self::get_default_creator_id(),
1108
-                            'QST_deleted'       => 0,
1109
-                        ];
1110
-                        break;
1111
-                    case 'phone':
1112
-                        $QST_values = [
1113
-                            'QST_display_text'  => __('Phone Number', 'event_espresso'),
1114
-                            'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1115
-                            'QST_system'        => 'phone',
1116
-                            'QST_type'          => 'TEXT',
1117
-                            'QST_required'      => 0,
1118
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1119
-                            'QST_order'         => 11,
1120
-                            'QST_admin_only'    => 0,
1121
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1122
-                                $QST_system
1123
-                            ),
1124
-                            'QST_wp_user'       => self::get_default_creator_id(),
1125
-                            'QST_deleted'       => 0,
1126
-                        ];
1127
-                        break;
1128
-                }
1129
-                if (! empty($QST_values)) {
1130
-                    // insert system question
1131
-                    $wpdb->insert(
1132
-                        $table_name,
1133
-                        $QST_values,
1134
-                        ['%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d']
1135
-                    );
1136
-                    $QST_ID = $wpdb->insert_id;
1137
-
1138
-                    // QUESTION GROUP QUESTIONS
1139
-                    if (in_array($QST_system, $personal_system_group_questions)) {
1140
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1141
-                    } elseif (in_array($QST_system, $address_system_group_questions)) {
1142
-                        $system_question_we_want = EEM_Question_Group::system_address;
1143
-                    } else {
1144
-                        // QST_system should not be assigned to any group
1145
-                        continue;
1146
-                    }
1147
-                    if (isset($QSG_IDs[ $system_question_we_want ])) {
1148
-                        $QSG_ID = $QSG_IDs[ $system_question_we_want ];
1149
-                    } else {
1150
-                        $id_col = EEM_Question_Group::instance()
1151
-                                                    ->get_col([['QSG_system' => $system_question_we_want]]);
1152
-                        if (is_array($id_col)) {
1153
-                            $QSG_ID = reset($id_col);
1154
-                        } else {
1155
-                            // ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1156
-                            EE_Log::instance()->log(
1157
-                                __FILE__,
1158
-                                __FUNCTION__,
1159
-                                sprintf(
1160
-                                    __(
1161
-                                        'Could not associate question %1$s to a question group because no system question
843
+					'event_espresso'
844
+				),
845
+				__FILE__,
846
+				__FUNCTION__,
847
+				__LINE__
848
+			);
849
+			return false;
850
+		}
851
+		return true;
852
+	}
853
+
854
+
855
+	/**
856
+	 * initialize_system_questions
857
+	 *
858
+	 * @access public
859
+	 * @static
860
+	 * @return void
861
+	 * @throws EE_Error
862
+	 * @throws ReflectionException
863
+	 */
864
+	public static function initialize_system_questions()
865
+	{
866
+		// QUESTION GROUPS
867
+		global $wpdb;
868
+		$table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
869
+		$SQL        = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
870
+		// what we have
871
+		$question_groups = $wpdb->get_col($SQL);
872
+		// check the response
873
+		$question_groups = is_array($question_groups) ? $question_groups : [];
874
+		// what we should have
875
+		$QSG_systems = [1, 2];
876
+		// loop thru what we should have and compare to what we have
877
+		foreach ($QSG_systems as $QSG_system) {
878
+			// reset values array
879
+			$QSG_values = [];
880
+			// if we don't have what we should have (but use $QST_system as as string because that's what we got from the db)
881
+			if (! in_array("$QSG_system", $question_groups)) {
882
+				// add it
883
+				switch ($QSG_system) {
884
+					case 1:
885
+						$QSG_values = [
886
+							'QSG_name'            => __('Personal Information', 'event_espresso'),
887
+							'QSG_identifier'      => 'personal-information-' . time(),
888
+							'QSG_desc'            => '',
889
+							'QSG_order'           => 1,
890
+							'QSG_show_group_name' => 1,
891
+							'QSG_show_group_desc' => 1,
892
+							'QSG_system'          => EEM_Question_Group::system_personal,
893
+							'QSG_deleted'         => 0,
894
+						];
895
+						break;
896
+					case 2:
897
+						$QSG_values = [
898
+							'QSG_name'            => __('Address Information', 'event_espresso'),
899
+							'QSG_identifier'      => 'address-information-' . time(),
900
+							'QSG_desc'            => '',
901
+							'QSG_order'           => 2,
902
+							'QSG_show_group_name' => 1,
903
+							'QSG_show_group_desc' => 1,
904
+							'QSG_system'          => EEM_Question_Group::system_address,
905
+							'QSG_deleted'         => 0,
906
+						];
907
+						break;
908
+				}
909
+				// make sure we have some values before inserting them
910
+				if (! empty($QSG_values)) {
911
+					// insert system question
912
+					$wpdb->insert(
913
+						$table_name,
914
+						$QSG_values,
915
+						['%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d']
916
+					);
917
+					$QSG_IDs[ $QSG_system ] = $wpdb->insert_id;
918
+				}
919
+			}
920
+		}
921
+		// QUESTIONS
922
+		global $wpdb;
923
+		$table_name = EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
924
+		$SQL        = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
925
+		// what we have
926
+		$questions = $wpdb->get_col($SQL);
927
+		// all system questions
928
+		$personal_system_group_questions = ['fname', 'lname', 'email'];
929
+		$address_system_group_questions  = ['address', 'address2', 'city', 'country', 'state', 'zip', 'phone'];
930
+		$system_questions_not_in_group   = ['email_confirm'];
931
+		// merge all of the system questions we should have
932
+		$QST_systems       = array_merge(
933
+			$personal_system_group_questions,
934
+			$address_system_group_questions,
935
+			$system_questions_not_in_group
936
+		);
937
+		$order_for_group_1 = 1;
938
+		$order_for_group_2 = 1;
939
+		// loop thru what we should have and compare to what we have
940
+		foreach ($QST_systems as $QST_system) {
941
+			// reset values array
942
+			$QST_values = [];
943
+			// if we don't have what we should have
944
+			if (! in_array($QST_system, $questions)) {
945
+				// add it
946
+				switch ($QST_system) {
947
+					case 'fname':
948
+						$QST_values = [
949
+							'QST_display_text'  => __('First Name', 'event_espresso'),
950
+							'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
951
+							'QST_system'        => 'fname',
952
+							'QST_type'          => 'TEXT',
953
+							'QST_required'      => 1,
954
+							'QST_required_text' => __('This field is required', 'event_espresso'),
955
+							'QST_order'         => 1,
956
+							'QST_admin_only'    => 0,
957
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
958
+								$QST_system
959
+							),
960
+							'QST_wp_user'       => self::get_default_creator_id(),
961
+							'QST_deleted'       => 0,
962
+						];
963
+						break;
964
+					case 'lname':
965
+						$QST_values = [
966
+							'QST_display_text'  => __('Last Name', 'event_espresso'),
967
+							'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
968
+							'QST_system'        => 'lname',
969
+							'QST_type'          => 'TEXT',
970
+							'QST_required'      => 1,
971
+							'QST_required_text' => __('This field is required', 'event_espresso'),
972
+							'QST_order'         => 2,
973
+							'QST_admin_only'    => 0,
974
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
975
+								$QST_system
976
+							),
977
+							'QST_wp_user'       => self::get_default_creator_id(),
978
+							'QST_deleted'       => 0,
979
+						];
980
+						break;
981
+					case 'email':
982
+						$QST_values = [
983
+							'QST_display_text'  => __('Email Address', 'event_espresso'),
984
+							'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
985
+							'QST_system'        => 'email',
986
+							'QST_type'          => 'EMAIL',
987
+							'QST_required'      => 1,
988
+							'QST_required_text' => __('This field is required', 'event_espresso'),
989
+							'QST_order'         => 3,
990
+							'QST_admin_only'    => 0,
991
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
992
+								$QST_system
993
+							),
994
+							'QST_wp_user'       => self::get_default_creator_id(),
995
+							'QST_deleted'       => 0,
996
+						];
997
+						break;
998
+					case 'email_confirm':
999
+						$QST_values = [
1000
+							'QST_display_text'  => __('Confirm Email Address', 'event_espresso'),
1001
+							'QST_admin_label'   => __('Confirm Email Address - System Question', 'event_espresso'),
1002
+							'QST_system'        => 'email_confirm',
1003
+							'QST_type'          => 'EMAIL_CONFIRM',
1004
+							'QST_required'      => 1,
1005
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1006
+							'QST_order'         => 4,
1007
+							'QST_admin_only'    => 0,
1008
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1009
+								$QST_system
1010
+							),
1011
+							'QST_wp_user'       => self::get_default_creator_id(),
1012
+							'QST_deleted'       => 0,
1013
+						];
1014
+						break;
1015
+					case 'address':
1016
+						$QST_values = [
1017
+							'QST_display_text'  => __('Address', 'event_espresso'),
1018
+							'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
1019
+							'QST_system'        => 'address',
1020
+							'QST_type'          => 'TEXT',
1021
+							'QST_required'      => 0,
1022
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1023
+							'QST_order'         => 5,
1024
+							'QST_admin_only'    => 0,
1025
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1026
+								$QST_system
1027
+							),
1028
+							'QST_wp_user'       => self::get_default_creator_id(),
1029
+							'QST_deleted'       => 0,
1030
+						];
1031
+						break;
1032
+					case 'address2':
1033
+						$QST_values = [
1034
+							'QST_display_text'  => __('Address2', 'event_espresso'),
1035
+							'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1036
+							'QST_system'        => 'address2',
1037
+							'QST_type'          => 'TEXT',
1038
+							'QST_required'      => 0,
1039
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1040
+							'QST_order'         => 6,
1041
+							'QST_admin_only'    => 0,
1042
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1043
+								$QST_system
1044
+							),
1045
+							'QST_wp_user'       => self::get_default_creator_id(),
1046
+							'QST_deleted'       => 0,
1047
+						];
1048
+						break;
1049
+					case 'city':
1050
+						$QST_values = [
1051
+							'QST_display_text'  => __('City', 'event_espresso'),
1052
+							'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1053
+							'QST_system'        => 'city',
1054
+							'QST_type'          => 'TEXT',
1055
+							'QST_required'      => 0,
1056
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1057
+							'QST_order'         => 7,
1058
+							'QST_admin_only'    => 0,
1059
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1060
+								$QST_system
1061
+							),
1062
+							'QST_wp_user'       => self::get_default_creator_id(),
1063
+							'QST_deleted'       => 0,
1064
+						];
1065
+						break;
1066
+					case 'country':
1067
+						$QST_values = [
1068
+							'QST_display_text'  => __('Country', 'event_espresso'),
1069
+							'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1070
+							'QST_system'        => 'country',
1071
+							'QST_type'          => 'COUNTRY',
1072
+							'QST_required'      => 0,
1073
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1074
+							'QST_order'         => 8,
1075
+							'QST_admin_only'    => 0,
1076
+							'QST_wp_user'       => self::get_default_creator_id(),
1077
+							'QST_deleted'       => 0,
1078
+						];
1079
+						break;
1080
+					case 'state':
1081
+						$QST_values = [
1082
+							'QST_display_text'  => __('State/Province', 'event_espresso'),
1083
+							'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1084
+							'QST_system'        => 'state',
1085
+							'QST_type'          => 'STATE',
1086
+							'QST_required'      => 0,
1087
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1088
+							'QST_order'         => 9,
1089
+							'QST_admin_only'    => 0,
1090
+							'QST_wp_user'       => self::get_default_creator_id(),
1091
+							'QST_deleted'       => 0,
1092
+						];
1093
+						break;
1094
+					case 'zip':
1095
+						$QST_values = [
1096
+							'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1097
+							'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1098
+							'QST_system'        => 'zip',
1099
+							'QST_type'          => 'TEXT',
1100
+							'QST_required'      => 0,
1101
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1102
+							'QST_order'         => 10,
1103
+							'QST_admin_only'    => 0,
1104
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1105
+								$QST_system
1106
+							),
1107
+							'QST_wp_user'       => self::get_default_creator_id(),
1108
+							'QST_deleted'       => 0,
1109
+						];
1110
+						break;
1111
+					case 'phone':
1112
+						$QST_values = [
1113
+							'QST_display_text'  => __('Phone Number', 'event_espresso'),
1114
+							'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1115
+							'QST_system'        => 'phone',
1116
+							'QST_type'          => 'TEXT',
1117
+							'QST_required'      => 0,
1118
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1119
+							'QST_order'         => 11,
1120
+							'QST_admin_only'    => 0,
1121
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question(
1122
+								$QST_system
1123
+							),
1124
+							'QST_wp_user'       => self::get_default_creator_id(),
1125
+							'QST_deleted'       => 0,
1126
+						];
1127
+						break;
1128
+				}
1129
+				if (! empty($QST_values)) {
1130
+					// insert system question
1131
+					$wpdb->insert(
1132
+						$table_name,
1133
+						$QST_values,
1134
+						['%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d']
1135
+					);
1136
+					$QST_ID = $wpdb->insert_id;
1137
+
1138
+					// QUESTION GROUP QUESTIONS
1139
+					if (in_array($QST_system, $personal_system_group_questions)) {
1140
+						$system_question_we_want = EEM_Question_Group::system_personal;
1141
+					} elseif (in_array($QST_system, $address_system_group_questions)) {
1142
+						$system_question_we_want = EEM_Question_Group::system_address;
1143
+					} else {
1144
+						// QST_system should not be assigned to any group
1145
+						continue;
1146
+					}
1147
+					if (isset($QSG_IDs[ $system_question_we_want ])) {
1148
+						$QSG_ID = $QSG_IDs[ $system_question_we_want ];
1149
+					} else {
1150
+						$id_col = EEM_Question_Group::instance()
1151
+													->get_col([['QSG_system' => $system_question_we_want]]);
1152
+						if (is_array($id_col)) {
1153
+							$QSG_ID = reset($id_col);
1154
+						} else {
1155
+							// ok so we didn't find it in the db either?? that's weird because we should have inserted it at the start of this method
1156
+							EE_Log::instance()->log(
1157
+								__FILE__,
1158
+								__FUNCTION__,
1159
+								sprintf(
1160
+									__(
1161
+										'Could not associate question %1$s to a question group because no system question
1162 1162
                                          group existed',
1163
-                                        'event_espresso'
1164
-                                    ),
1165
-                                    $QST_ID
1166
-                                ),
1167
-                                'error'
1168
-                            );
1169
-                            continue;
1170
-                        }
1171
-                    }
1172
-                    // add system questions to groups
1173
-                    $wpdb->insert(
1174
-                        EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1175
-                        [
1176
-                            'QSG_ID'    => $QSG_ID,
1177
-                            'QST_ID'    => $QST_ID,
1178
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1179
-                        ],
1180
-                        ['%d', '%d', '%d']
1181
-                    );
1182
-                }
1183
-            }
1184
-        }
1185
-    }
1186
-
1187
-
1188
-    /**
1189
-     * Makes sure the default payment method (Invoice) is active.
1190
-     * This used to be done automatically as part of constructing the old gateways config
1191
-     *
1192
-     * @throws EE_Error
1193
-     * @throws ReflectionException
1194
-     */
1195
-    public static function insert_default_payment_methods()
1196
-    {
1197
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1198
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1199
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1200
-        } else {
1201
-            EEM_Payment_Method::instance()->verify_button_urls();
1202
-        }
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * insert_default_status_codes
1208
-     *
1209
-     * @access public
1210
-     * @static
1211
-     * @return void
1212
-     * @throws EE_Error
1213
-     * @throws ReflectionException
1214
-     */
1215
-    public static function insert_default_status_codes()
1216
-    {
1217
-
1218
-        global $wpdb;
1219
-
1220
-        if (EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1221
-            $table_name = EEM_Status::instance()->table();
1222
-
1223
-            $SQL =
1224
-                "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1225
-            $wpdb->query($SQL);
1226
-
1227
-            $SQL = "INSERT INTO $table_name
1163
+										'event_espresso'
1164
+									),
1165
+									$QST_ID
1166
+								),
1167
+								'error'
1168
+							);
1169
+							continue;
1170
+						}
1171
+					}
1172
+					// add system questions to groups
1173
+					$wpdb->insert(
1174
+						EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1175
+						[
1176
+							'QSG_ID'    => $QSG_ID,
1177
+							'QST_ID'    => $QST_ID,
1178
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1179
+						],
1180
+						['%d', '%d', '%d']
1181
+					);
1182
+				}
1183
+			}
1184
+		}
1185
+	}
1186
+
1187
+
1188
+	/**
1189
+	 * Makes sure the default payment method (Invoice) is active.
1190
+	 * This used to be done automatically as part of constructing the old gateways config
1191
+	 *
1192
+	 * @throws EE_Error
1193
+	 * @throws ReflectionException
1194
+	 */
1195
+	public static function insert_default_payment_methods()
1196
+	{
1197
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1198
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1199
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1200
+		} else {
1201
+			EEM_Payment_Method::instance()->verify_button_urls();
1202
+		}
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * insert_default_status_codes
1208
+	 *
1209
+	 * @access public
1210
+	 * @static
1211
+	 * @return void
1212
+	 * @throws EE_Error
1213
+	 * @throws ReflectionException
1214
+	 */
1215
+	public static function insert_default_status_codes()
1216
+	{
1217
+
1218
+		global $wpdb;
1219
+
1220
+		if (EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1221
+			$table_name = EEM_Status::instance()->table();
1222
+
1223
+			$SQL =
1224
+				"DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1225
+			$wpdb->query($SQL);
1226
+
1227
+			$SQL = "INSERT INTO $table_name
1228 1228
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1229 1229
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1230 1230
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1264,494 +1264,494 @@  discard block
 block discarded – undo
1264 1264
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1265 1265
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1266 1266
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1267
-            $wpdb->query($SQL);
1268
-        }
1269
-    }
1270
-
1271
-
1272
-    /**
1273
-     * generate_default_message_templates
1274
-     *
1275
-     * @static
1276
-     * @return bool     true means new templates were created.
1277
-     *                  false means no templates were created.
1278
-     *                  This is NOT an error flag. To check for errors you will want
1279
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1280
-     * @throws ReflectionException
1281
-     * @throws EE_Error
1282
-     */
1283
-    public static function generate_default_message_templates()
1284
-    {
1285
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1286
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1287
-        /*
1267
+			$wpdb->query($SQL);
1268
+		}
1269
+	}
1270
+
1271
+
1272
+	/**
1273
+	 * generate_default_message_templates
1274
+	 *
1275
+	 * @static
1276
+	 * @return bool     true means new templates were created.
1277
+	 *                  false means no templates were created.
1278
+	 *                  This is NOT an error flag. To check for errors you will want
1279
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1280
+	 * @throws ReflectionException
1281
+	 * @throws EE_Error
1282
+	 */
1283
+	public static function generate_default_message_templates()
1284
+	{
1285
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1286
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1287
+		/*
1288 1288
          * This first method is taking care of ensuring any default messengers
1289 1289
          * that should be made active and have templates generated are done.
1290 1290
          */
1291
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1292
-            $message_resource_manager
1293
-        );
1294
-        /**
1295
-         * This method is verifying there are no NEW default message types
1296
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1297
-         */
1298
-        $new_templates_created_for_message_type =
1299
-            self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1300
-                $message_resource_manager
1301
-            );
1302
-        // after all is done, let's persist these changes to the db.
1303
-        $message_resource_manager->update_has_activated_messengers_option();
1304
-        $message_resource_manager->update_active_messengers_option();
1305
-        // will return true if either of these are true.  Otherwise will return false.
1306
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1307
-    }
1308
-
1309
-
1310
-    /**
1311
-     * @param EE_Message_Resource_Manager $message_resource_manager
1312
-     * @return array|bool
1313
-     * @throws EE_Error
1314
-     */
1315
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1316
-        EE_Message_Resource_Manager $message_resource_manager
1317
-    ) {
1318
-        /** @type EE_messenger[] $active_messengers */
1319
-        $active_messengers       = $message_resource_manager->active_messengers();
1320
-        $installed_message_types = $message_resource_manager->installed_message_types();
1321
-        $templates_created       = false;
1322
-        foreach ($active_messengers as $active_messenger) {
1323
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1324
-            $default_message_type_names_to_activate   = [];
1325
-            // looping through each default message type reported by the messenger
1326
-            // and setup the actual message types to activate.
1327
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1328
-                // if already active or has already been activated before we skip
1329
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1330
-                // we also skip if the message type is not installed.
1331
-                if (! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1332
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1333
-                        $default_message_type_name_for_messenger,
1334
-                        $active_messenger->name
1335
-                    )
1336
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1337
-                        $active_messenger->name,
1338
-                        $default_message_type_name_for_messenger
1339
-                    )
1340
-                ) {
1341
-                    continue;
1342
-                }
1343
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1344
-            }
1345
-            // let's activate!
1346
-            $message_resource_manager->ensure_message_types_are_active(
1347
-                $default_message_type_names_to_activate,
1348
-                $active_messenger->name,
1349
-                false
1350
-            );
1351
-            // activate the templates for these message types
1352
-            if (! empty($default_message_type_names_to_activate)) {
1353
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1354
-                    $active_messenger->name,
1355
-                    $default_message_type_names_for_messenger,
1356
-                    '',
1357
-                    true
1358
-                );
1359
-            }
1360
-        }
1361
-        return $templates_created;
1362
-    }
1363
-
1364
-
1365
-    /**
1366
-     * This will activate and generate default messengers and default message types for those messengers.
1367
-     *
1368
-     * @param EE_message_Resource_Manager $message_resource_manager
1369
-     * @return array|bool  True means there were default messengers and message type templates generated.
1370
-     *                     False means that there were no templates generated
1371
-     *                     (which could simply mean there are no default message types for a messenger).
1372
-     * @throws EE_Error
1373
-     */
1374
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1375
-        EE_Message_Resource_Manager $message_resource_manager
1376
-    ) {
1377
-        /** @type EE_messenger[] $messengers_to_generate */
1378
-        $messengers_to_generate  = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1379
-        $installed_message_types = $message_resource_manager->installed_message_types();
1380
-        $templates_generated     = false;
1381
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1382
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1383
-            // verify the default message types match an installed message type.
1384
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1385
-                if (! isset($installed_message_types[ $name ])
1386
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1387
-                        $name,
1388
-                        $messenger_to_generate->name
1389
-                    )
1390
-                ) {
1391
-                    unset($default_message_type_names_for_messenger[ $key ]);
1392
-                }
1393
-            }
1394
-            // in previous iterations, the active_messengers option in the db
1395
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1396
-            // This comment is left here just in case we discover that we _do_ need to update before
1397
-            // passing off to create templates (after the refactor is done).
1398
-            // @todo remove this comment when determined not necessary.
1399
-            $message_resource_manager->activate_messenger(
1400
-                $messenger_to_generate,
1401
-                $default_message_type_names_for_messenger,
1402
-                false
1403
-            );
1404
-            // create any templates needing created (or will reactivate templates already generated as necessary).
1405
-            if (! empty($default_message_type_names_for_messenger)) {
1406
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1407
-                    $messenger_to_generate->name,
1408
-                    $default_message_type_names_for_messenger,
1409
-                    '',
1410
-                    true
1411
-                );
1412
-            }
1413
-        }
1414
-        return $templates_generated;
1415
-    }
1416
-
1417
-
1418
-    /**
1419
-     * This returns the default messengers to generate templates for on activation of EE.
1420
-     * It considers:
1421
-     * - whether a messenger is already active in the db.
1422
-     * - whether a messenger has been made active at any time in the past.
1423
-     *
1424
-     * @static
1425
-     * @param EE_Message_Resource_Manager $message_resource_manager
1426
-     * @return EE_messenger[]
1427
-     */
1428
-    protected static function _get_default_messengers_to_generate_on_activation(
1429
-        EE_Message_Resource_Manager $message_resource_manager
1430
-    ) {
1431
-        $active_messengers    = $message_resource_manager->active_messengers();
1432
-        $installed_messengers = $message_resource_manager->installed_messengers();
1433
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1434
-
1435
-        $messengers_to_generate = [];
1436
-        foreach ($installed_messengers as $installed_messenger) {
1437
-            // if installed messenger is a messenger that should be activated on install
1438
-            // and is not already active
1439
-            // and has never been activated
1440
-            if (! $installed_messenger->activate_on_install
1441
-                || isset($active_messengers[ $installed_messenger->name ])
1442
-                || isset($has_activated[ $installed_messenger->name ])
1443
-            ) {
1444
-                continue;
1445
-            }
1446
-            $messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1447
-        }
1448
-        return $messengers_to_generate;
1449
-    }
1450
-
1451
-
1452
-    /**
1453
-     * This simply validates active message types to ensure they actually match installed
1454
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1455
-     * rows are set inactive.
1456
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1457
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1458
-     * are still handled in here.
1459
-     *
1460
-     * @return void
1461
-     * @throws EE_Error
1462
-     * @throws ReflectionException
1463
-     * @since 4.3.1
1464
-     */
1465
-    public static function validate_messages_system()
1466
-    {
1467
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1468
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1469
-        $message_resource_manager->validate_active_message_types_are_installed();
1470
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1471
-    }
1472
-
1473
-
1474
-    /**
1475
-     * create_no_ticket_prices_array
1476
-     *
1477
-     * @access public
1478
-     * @static
1479
-     * @return void
1480
-     */
1481
-    public static function create_no_ticket_prices_array()
1482
-    {
1483
-        // this creates an array for tracking events that have no active ticket prices created
1484
-        // this allows us to warn admins of the situation so that it can be corrected
1485
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1486
-        if (! $espresso_no_ticket_prices) {
1487
-            add_option('ee_no_ticket_prices', [], '', false);
1488
-        }
1489
-    }
1490
-
1491
-
1492
-    /**
1493
-     * plugin_deactivation
1494
-     *
1495
-     * @access public
1496
-     * @static
1497
-     * @return void
1498
-     */
1499
-    public static function plugin_deactivation()
1500
-    {
1501
-    }
1502
-
1503
-
1504
-    /**
1505
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1506
-     * (like post meta or term relations)
1507
-     *
1508
-     * @throws EE_Error
1509
-     * @global wpdb $wpdb
1510
-     */
1511
-    public static function delete_all_espresso_cpt_data()
1512
-    {
1513
-        global $wpdb;
1514
-        // get all the CPT post_types
1515
-        $ee_post_types = [];
1516
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1517
-            if (method_exists($model_name, 'instance')) {
1518
-                $model_obj = call_user_func([$model_name, 'instance']);
1519
-                if ($model_obj instanceof EEM_CPT_Base) {
1520
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1521
-                }
1522
-            }
1523
-        }
1524
-        // get all our CPTs
1525
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1526
-        $cpt_ids = $wpdb->get_col($query);
1527
-        // delete each post meta and term relations too
1528
-        foreach ($cpt_ids as $post_id) {
1529
-            wp_delete_post($post_id, true);
1530
-        }
1531
-    }
1532
-
1533
-
1534
-    /**
1535
-     * Deletes all EE custom tables
1536
-     *
1537
-     * @return array
1538
-     * @throws EE_Error
1539
-     * @throws ReflectionException
1540
-     */
1541
-    public static function drop_espresso_tables()
1542
-    {
1543
-        $tables = [];
1544
-        // load registry
1545
-        foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1546
-            if (method_exists($model_name, 'instance')) {
1547
-                $model_obj = call_user_func([$model_name, 'instance']);
1548
-                if ($model_obj instanceof EEM_Base) {
1549
-                    foreach ($model_obj->get_tables() as $table) {
1550
-                        if (strpos($table->get_table_name(), 'esp_')
1551
-                            && (
1552
-                                is_main_site()// main site? nuke them all
1553
-                                || ! $table->is_global()// not main site,but not global either. nuke it
1554
-                            )
1555
-                        ) {
1556
-                            $tables[ $table->get_table_name() ] = $table->get_table_name();
1557
-                        }
1558
-                    }
1559
-                }
1560
-            }
1561
-        }
1562
-
1563
-        // there are some tables whose models were removed.
1564
-        // they should be removed when removing all EE core's data
1565
-        $tables_without_models = [
1566
-            'esp_promotion',
1567
-            'esp_promotion_applied',
1568
-            'esp_promotion_object',
1569
-            'esp_promotion_rule',
1570
-            'esp_rule',
1571
-        ];
1572
-        foreach ($tables_without_models as $table) {
1573
-            $tables[ $table ] = $table;
1574
-        }
1575
-        return EEH_Activation::getTableManager()->dropTables($tables);
1576
-    }
1577
-
1578
-
1579
-    /**
1580
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1581
-     * each table name provided has a wpdb prefix attached, and that it exists.
1582
-     * Returns the list actually deleted
1583
-     *
1584
-     * @param array $table_names
1585
-     * @return array of table names which we deleted
1586
-     * @throws EE_Error
1587
-     * @throws ReflectionException
1588
-     * @global WPDB $wpdb
1589
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1590
-     */
1591
-    public static function drop_tables($table_names)
1592
-    {
1593
-        return EEH_Activation::getTableManager()->dropTables($table_names);
1594
-    }
1595
-
1596
-
1597
-    /**
1598
-     * plugin_uninstall
1599
-     *
1600
-     * @access public
1601
-     * @static
1602
-     * @param bool $remove_all
1603
-     * @return void
1604
-     * @throws EE_Error
1605
-     * @throws ReflectionException
1606
-     */
1607
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1608
-    {
1609
-        global $wpdb;
1610
-        self::drop_espresso_tables();
1611
-        $wp_options_to_delete = [
1612
-            'ee_no_ticket_prices'                        => true,
1613
-            'ee_active_messengers'                       => true,
1614
-            'ee_has_activated_messenger'                 => true,
1615
-            RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1616
-            'ee_config'                                  => false,
1617
-            'ee_data_migration_current_db_state'         => true,
1618
-            'ee_data_migration_mapping_'                 => false,
1619
-            'ee_data_migration_script_'                  => false,
1620
-            'ee_data_migrations'                         => true,
1621
-            'ee_dms_map'                                 => false,
1622
-            'ee_notices'                                 => true,
1623
-            'lang_file_check_'                           => false,
1624
-            'ee_maintenance_mode'                        => true,
1625
-            'ee_ueip_optin'                              => true,
1626
-            'ee_ueip_has_notified'                       => true,
1627
-            'ee_plugin_activation_errors'                => true,
1628
-            'ee_id_mapping_from'                         => false,
1629
-            'espresso_persistent_admin_notices'          => true,
1630
-            'ee_encryption_key'                          => true,
1631
-            'pue_force_upgrade_'                         => false,
1632
-            'pue_json_error_'                            => false,
1633
-            'pue_install_key_'                           => false,
1634
-            'pue_verification_error_'                    => false,
1635
-            'pu_dismissed_upgrade_'                      => false,
1636
-            'external_updates-'                          => false,
1637
-            'ee_extra_data'                              => true,
1638
-            'ee_ssn_'                                    => false,
1639
-            'ee_rss_'                                    => false,
1640
-            'ee_rte_n_tx_'                               => false,
1641
-            'ee_pers_admin_notices'                      => true,
1642
-            'ee_job_parameters_'                         => false,
1643
-            'ee_upload_directories_incomplete'           => true,
1644
-            'ee_verified_db_collations'                  => true,
1645
-        ];
1646
-        if (is_main_site()) {
1647
-            $wp_options_to_delete['ee_network_config'] = true;
1648
-        }
1649
-        $undeleted_options = [];
1650
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1651
-            if ($no_wildcard) {
1652
-                if (! delete_option($option_name)) {
1653
-                    $undeleted_options[] = $option_name;
1654
-                }
1655
-            } else {
1656
-                $option_names_to_delete_from_wildcard =
1657
-                    $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1658
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1659
-                    if (! delete_option($option_name_from_wildcard)) {
1660
-                        $undeleted_options[] = $option_name_from_wildcard;
1661
-                    }
1662
-                }
1663
-            }
1664
-        }
1665
-        // also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1666
-        remove_action('shutdown', [EE_Config::instance(), 'shutdown'], 10);
1667
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1668
-            $db_update_sans_ee4 = [];
1669
-            foreach ($espresso_db_update as $version => $times_activated) {
1670
-                if ((string) $version[0] === '3') {// if its NON EE4
1671
-                    $db_update_sans_ee4[ $version ] = $times_activated;
1672
-                }
1673
-            }
1674
-            update_option('espresso_db_update', $db_update_sans_ee4);
1675
-        }
1676
-        $errors = '';
1677
-        if (! empty($undeleted_options)) {
1678
-            $errors .= sprintf(
1679
-                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1680
-                '<br/>',
1681
-                implode(',<br/>', $undeleted_options)
1682
-            );
1683
-        }
1684
-        if (! empty($errors)) {
1685
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1686
-        }
1687
-    }
1688
-
1689
-
1690
-    /**
1691
-     * Gets the mysql error code from the last used query by wpdb
1692
-     *
1693
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1694
-     */
1695
-    public static function last_wpdb_error_code()
1696
-    {
1697
-        // phpcs:disable PHPCompatibility.PHP.RemovedExtensions.mysql_DeprecatedRemoved
1698
-        global $wpdb;
1699
-        if ($wpdb->use_mysqli) {
1700
-            return mysqli_errno($wpdb->dbh);
1701
-        } else {
1702
-            return mysql_errno($wpdb->dbh);
1703
-        }
1704
-        // phpcs:enable
1705
-    }
1706
-
1707
-
1708
-    /**
1709
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1710
-     *
1711
-     * @param string $table_name with or without $wpdb->prefix
1712
-     * @return boolean
1713
-     * @throws EE_Error
1714
-     * @throws ReflectionException
1715
-     * @global wpdb  $wpdb
1716
-     * @deprecated instead use TableAnalysis::tableExists()
1717
-     */
1718
-    public static function table_exists($table_name)
1719
-    {
1720
-        return EEH_Activation::getTableAnalysis()->tableExists($table_name);
1721
-    }
1722
-
1723
-
1724
-    /**
1725
-     * Resets the cache on EEH_Activation
1726
-     */
1727
-    public static function reset()
1728
-    {
1729
-        self::$_default_creator_id                             = null;
1730
-        self::$_initialized_db_content_already_in_this_request = false;
1731
-    }
1732
-
1733
-
1734
-    /**
1735
-     * Removes 'email_confirm' from the Address info question group on activation
1736
-     *
1737
-     * @return void
1738
-     * @throws EE_Error
1739
-     */
1740
-    public static function removeEmailConfirmFromAddressGroup()
1741
-    {
1742
-
1743
-        // Pull the email_confirm question ID.
1744
-        $email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1745
-            EEM_Attendee::system_question_email_confirm
1746
-        );
1747
-        // Remove the email_confirm question group from the address group questions.
1748
-        EEM_Question_Group_Question::instance()->delete(
1749
-            [
1750
-                [
1751
-                    'QST_ID'                    => $email_confirm_question_id,
1752
-                    'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1753
-                ],
1754
-            ]
1755
-        );
1756
-    }
1291
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1292
+			$message_resource_manager
1293
+		);
1294
+		/**
1295
+		 * This method is verifying there are no NEW default message types
1296
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1297
+		 */
1298
+		$new_templates_created_for_message_type =
1299
+			self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1300
+				$message_resource_manager
1301
+			);
1302
+		// after all is done, let's persist these changes to the db.
1303
+		$message_resource_manager->update_has_activated_messengers_option();
1304
+		$message_resource_manager->update_active_messengers_option();
1305
+		// will return true if either of these are true.  Otherwise will return false.
1306
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1307
+	}
1308
+
1309
+
1310
+	/**
1311
+	 * @param EE_Message_Resource_Manager $message_resource_manager
1312
+	 * @return array|bool
1313
+	 * @throws EE_Error
1314
+	 */
1315
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1316
+		EE_Message_Resource_Manager $message_resource_manager
1317
+	) {
1318
+		/** @type EE_messenger[] $active_messengers */
1319
+		$active_messengers       = $message_resource_manager->active_messengers();
1320
+		$installed_message_types = $message_resource_manager->installed_message_types();
1321
+		$templates_created       = false;
1322
+		foreach ($active_messengers as $active_messenger) {
1323
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1324
+			$default_message_type_names_to_activate   = [];
1325
+			// looping through each default message type reported by the messenger
1326
+			// and setup the actual message types to activate.
1327
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1328
+				// if already active or has already been activated before we skip
1329
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1330
+				// we also skip if the message type is not installed.
1331
+				if (! isset($installed_message_types[ $default_message_type_name_for_messenger ])
1332
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1333
+						$default_message_type_name_for_messenger,
1334
+						$active_messenger->name
1335
+					)
1336
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1337
+						$active_messenger->name,
1338
+						$default_message_type_name_for_messenger
1339
+					)
1340
+				) {
1341
+					continue;
1342
+				}
1343
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1344
+			}
1345
+			// let's activate!
1346
+			$message_resource_manager->ensure_message_types_are_active(
1347
+				$default_message_type_names_to_activate,
1348
+				$active_messenger->name,
1349
+				false
1350
+			);
1351
+			// activate the templates for these message types
1352
+			if (! empty($default_message_type_names_to_activate)) {
1353
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1354
+					$active_messenger->name,
1355
+					$default_message_type_names_for_messenger,
1356
+					'',
1357
+					true
1358
+				);
1359
+			}
1360
+		}
1361
+		return $templates_created;
1362
+	}
1363
+
1364
+
1365
+	/**
1366
+	 * This will activate and generate default messengers and default message types for those messengers.
1367
+	 *
1368
+	 * @param EE_message_Resource_Manager $message_resource_manager
1369
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1370
+	 *                     False means that there were no templates generated
1371
+	 *                     (which could simply mean there are no default message types for a messenger).
1372
+	 * @throws EE_Error
1373
+	 */
1374
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1375
+		EE_Message_Resource_Manager $message_resource_manager
1376
+	) {
1377
+		/** @type EE_messenger[] $messengers_to_generate */
1378
+		$messengers_to_generate  = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1379
+		$installed_message_types = $message_resource_manager->installed_message_types();
1380
+		$templates_generated     = false;
1381
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1382
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1383
+			// verify the default message types match an installed message type.
1384
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1385
+				if (! isset($installed_message_types[ $name ])
1386
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1387
+						$name,
1388
+						$messenger_to_generate->name
1389
+					)
1390
+				) {
1391
+					unset($default_message_type_names_for_messenger[ $key ]);
1392
+				}
1393
+			}
1394
+			// in previous iterations, the active_messengers option in the db
1395
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1396
+			// This comment is left here just in case we discover that we _do_ need to update before
1397
+			// passing off to create templates (after the refactor is done).
1398
+			// @todo remove this comment when determined not necessary.
1399
+			$message_resource_manager->activate_messenger(
1400
+				$messenger_to_generate,
1401
+				$default_message_type_names_for_messenger,
1402
+				false
1403
+			);
1404
+			// create any templates needing created (or will reactivate templates already generated as necessary).
1405
+			if (! empty($default_message_type_names_for_messenger)) {
1406
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1407
+					$messenger_to_generate->name,
1408
+					$default_message_type_names_for_messenger,
1409
+					'',
1410
+					true
1411
+				);
1412
+			}
1413
+		}
1414
+		return $templates_generated;
1415
+	}
1416
+
1417
+
1418
+	/**
1419
+	 * This returns the default messengers to generate templates for on activation of EE.
1420
+	 * It considers:
1421
+	 * - whether a messenger is already active in the db.
1422
+	 * - whether a messenger has been made active at any time in the past.
1423
+	 *
1424
+	 * @static
1425
+	 * @param EE_Message_Resource_Manager $message_resource_manager
1426
+	 * @return EE_messenger[]
1427
+	 */
1428
+	protected static function _get_default_messengers_to_generate_on_activation(
1429
+		EE_Message_Resource_Manager $message_resource_manager
1430
+	) {
1431
+		$active_messengers    = $message_resource_manager->active_messengers();
1432
+		$installed_messengers = $message_resource_manager->installed_messengers();
1433
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1434
+
1435
+		$messengers_to_generate = [];
1436
+		foreach ($installed_messengers as $installed_messenger) {
1437
+			// if installed messenger is a messenger that should be activated on install
1438
+			// and is not already active
1439
+			// and has never been activated
1440
+			if (! $installed_messenger->activate_on_install
1441
+				|| isset($active_messengers[ $installed_messenger->name ])
1442
+				|| isset($has_activated[ $installed_messenger->name ])
1443
+			) {
1444
+				continue;
1445
+			}
1446
+			$messengers_to_generate[ $installed_messenger->name ] = $installed_messenger;
1447
+		}
1448
+		return $messengers_to_generate;
1449
+	}
1450
+
1451
+
1452
+	/**
1453
+	 * This simply validates active message types to ensure they actually match installed
1454
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1455
+	 * rows are set inactive.
1456
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1457
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1458
+	 * are still handled in here.
1459
+	 *
1460
+	 * @return void
1461
+	 * @throws EE_Error
1462
+	 * @throws ReflectionException
1463
+	 * @since 4.3.1
1464
+	 */
1465
+	public static function validate_messages_system()
1466
+	{
1467
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1468
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1469
+		$message_resource_manager->validate_active_message_types_are_installed();
1470
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1471
+	}
1472
+
1473
+
1474
+	/**
1475
+	 * create_no_ticket_prices_array
1476
+	 *
1477
+	 * @access public
1478
+	 * @static
1479
+	 * @return void
1480
+	 */
1481
+	public static function create_no_ticket_prices_array()
1482
+	{
1483
+		// this creates an array for tracking events that have no active ticket prices created
1484
+		// this allows us to warn admins of the situation so that it can be corrected
1485
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1486
+		if (! $espresso_no_ticket_prices) {
1487
+			add_option('ee_no_ticket_prices', [], '', false);
1488
+		}
1489
+	}
1490
+
1491
+
1492
+	/**
1493
+	 * plugin_deactivation
1494
+	 *
1495
+	 * @access public
1496
+	 * @static
1497
+	 * @return void
1498
+	 */
1499
+	public static function plugin_deactivation()
1500
+	{
1501
+	}
1502
+
1503
+
1504
+	/**
1505
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1506
+	 * (like post meta or term relations)
1507
+	 *
1508
+	 * @throws EE_Error
1509
+	 * @global wpdb $wpdb
1510
+	 */
1511
+	public static function delete_all_espresso_cpt_data()
1512
+	{
1513
+		global $wpdb;
1514
+		// get all the CPT post_types
1515
+		$ee_post_types = [];
1516
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1517
+			if (method_exists($model_name, 'instance')) {
1518
+				$model_obj = call_user_func([$model_name, 'instance']);
1519
+				if ($model_obj instanceof EEM_CPT_Base) {
1520
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1521
+				}
1522
+			}
1523
+		}
1524
+		// get all our CPTs
1525
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1526
+		$cpt_ids = $wpdb->get_col($query);
1527
+		// delete each post meta and term relations too
1528
+		foreach ($cpt_ids as $post_id) {
1529
+			wp_delete_post($post_id, true);
1530
+		}
1531
+	}
1532
+
1533
+
1534
+	/**
1535
+	 * Deletes all EE custom tables
1536
+	 *
1537
+	 * @return array
1538
+	 * @throws EE_Error
1539
+	 * @throws ReflectionException
1540
+	 */
1541
+	public static function drop_espresso_tables()
1542
+	{
1543
+		$tables = [];
1544
+		// load registry
1545
+		foreach (EE_Registry::instance()->non_abstract_db_models as $model_name) {
1546
+			if (method_exists($model_name, 'instance')) {
1547
+				$model_obj = call_user_func([$model_name, 'instance']);
1548
+				if ($model_obj instanceof EEM_Base) {
1549
+					foreach ($model_obj->get_tables() as $table) {
1550
+						if (strpos($table->get_table_name(), 'esp_')
1551
+							&& (
1552
+								is_main_site()// main site? nuke them all
1553
+								|| ! $table->is_global()// not main site,but not global either. nuke it
1554
+							)
1555
+						) {
1556
+							$tables[ $table->get_table_name() ] = $table->get_table_name();
1557
+						}
1558
+					}
1559
+				}
1560
+			}
1561
+		}
1562
+
1563
+		// there are some tables whose models were removed.
1564
+		// they should be removed when removing all EE core's data
1565
+		$tables_without_models = [
1566
+			'esp_promotion',
1567
+			'esp_promotion_applied',
1568
+			'esp_promotion_object',
1569
+			'esp_promotion_rule',
1570
+			'esp_rule',
1571
+		];
1572
+		foreach ($tables_without_models as $table) {
1573
+			$tables[ $table ] = $table;
1574
+		}
1575
+		return EEH_Activation::getTableManager()->dropTables($tables);
1576
+	}
1577
+
1578
+
1579
+	/**
1580
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1581
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1582
+	 * Returns the list actually deleted
1583
+	 *
1584
+	 * @param array $table_names
1585
+	 * @return array of table names which we deleted
1586
+	 * @throws EE_Error
1587
+	 * @throws ReflectionException
1588
+	 * @global WPDB $wpdb
1589
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1590
+	 */
1591
+	public static function drop_tables($table_names)
1592
+	{
1593
+		return EEH_Activation::getTableManager()->dropTables($table_names);
1594
+	}
1595
+
1596
+
1597
+	/**
1598
+	 * plugin_uninstall
1599
+	 *
1600
+	 * @access public
1601
+	 * @static
1602
+	 * @param bool $remove_all
1603
+	 * @return void
1604
+	 * @throws EE_Error
1605
+	 * @throws ReflectionException
1606
+	 */
1607
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1608
+	{
1609
+		global $wpdb;
1610
+		self::drop_espresso_tables();
1611
+		$wp_options_to_delete = [
1612
+			'ee_no_ticket_prices'                        => true,
1613
+			'ee_active_messengers'                       => true,
1614
+			'ee_has_activated_messenger'                 => true,
1615
+			RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES => true,
1616
+			'ee_config'                                  => false,
1617
+			'ee_data_migration_current_db_state'         => true,
1618
+			'ee_data_migration_mapping_'                 => false,
1619
+			'ee_data_migration_script_'                  => false,
1620
+			'ee_data_migrations'                         => true,
1621
+			'ee_dms_map'                                 => false,
1622
+			'ee_notices'                                 => true,
1623
+			'lang_file_check_'                           => false,
1624
+			'ee_maintenance_mode'                        => true,
1625
+			'ee_ueip_optin'                              => true,
1626
+			'ee_ueip_has_notified'                       => true,
1627
+			'ee_plugin_activation_errors'                => true,
1628
+			'ee_id_mapping_from'                         => false,
1629
+			'espresso_persistent_admin_notices'          => true,
1630
+			'ee_encryption_key'                          => true,
1631
+			'pue_force_upgrade_'                         => false,
1632
+			'pue_json_error_'                            => false,
1633
+			'pue_install_key_'                           => false,
1634
+			'pue_verification_error_'                    => false,
1635
+			'pu_dismissed_upgrade_'                      => false,
1636
+			'external_updates-'                          => false,
1637
+			'ee_extra_data'                              => true,
1638
+			'ee_ssn_'                                    => false,
1639
+			'ee_rss_'                                    => false,
1640
+			'ee_rte_n_tx_'                               => false,
1641
+			'ee_pers_admin_notices'                      => true,
1642
+			'ee_job_parameters_'                         => false,
1643
+			'ee_upload_directories_incomplete'           => true,
1644
+			'ee_verified_db_collations'                  => true,
1645
+		];
1646
+		if (is_main_site()) {
1647
+			$wp_options_to_delete['ee_network_config'] = true;
1648
+		}
1649
+		$undeleted_options = [];
1650
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1651
+			if ($no_wildcard) {
1652
+				if (! delete_option($option_name)) {
1653
+					$undeleted_options[] = $option_name;
1654
+				}
1655
+			} else {
1656
+				$option_names_to_delete_from_wildcard =
1657
+					$wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1658
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1659
+					if (! delete_option($option_name_from_wildcard)) {
1660
+						$undeleted_options[] = $option_name_from_wildcard;
1661
+					}
1662
+				}
1663
+			}
1664
+		}
1665
+		// also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1666
+		remove_action('shutdown', [EE_Config::instance(), 'shutdown'], 10);
1667
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1668
+			$db_update_sans_ee4 = [];
1669
+			foreach ($espresso_db_update as $version => $times_activated) {
1670
+				if ((string) $version[0] === '3') {// if its NON EE4
1671
+					$db_update_sans_ee4[ $version ] = $times_activated;
1672
+				}
1673
+			}
1674
+			update_option('espresso_db_update', $db_update_sans_ee4);
1675
+		}
1676
+		$errors = '';
1677
+		if (! empty($undeleted_options)) {
1678
+			$errors .= sprintf(
1679
+				__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1680
+				'<br/>',
1681
+				implode(',<br/>', $undeleted_options)
1682
+			);
1683
+		}
1684
+		if (! empty($errors)) {
1685
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1686
+		}
1687
+	}
1688
+
1689
+
1690
+	/**
1691
+	 * Gets the mysql error code from the last used query by wpdb
1692
+	 *
1693
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1694
+	 */
1695
+	public static function last_wpdb_error_code()
1696
+	{
1697
+		// phpcs:disable PHPCompatibility.PHP.RemovedExtensions.mysql_DeprecatedRemoved
1698
+		global $wpdb;
1699
+		if ($wpdb->use_mysqli) {
1700
+			return mysqli_errno($wpdb->dbh);
1701
+		} else {
1702
+			return mysql_errno($wpdb->dbh);
1703
+		}
1704
+		// phpcs:enable
1705
+	}
1706
+
1707
+
1708
+	/**
1709
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1710
+	 *
1711
+	 * @param string $table_name with or without $wpdb->prefix
1712
+	 * @return boolean
1713
+	 * @throws EE_Error
1714
+	 * @throws ReflectionException
1715
+	 * @global wpdb  $wpdb
1716
+	 * @deprecated instead use TableAnalysis::tableExists()
1717
+	 */
1718
+	public static function table_exists($table_name)
1719
+	{
1720
+		return EEH_Activation::getTableAnalysis()->tableExists($table_name);
1721
+	}
1722
+
1723
+
1724
+	/**
1725
+	 * Resets the cache on EEH_Activation
1726
+	 */
1727
+	public static function reset()
1728
+	{
1729
+		self::$_default_creator_id                             = null;
1730
+		self::$_initialized_db_content_already_in_this_request = false;
1731
+	}
1732
+
1733
+
1734
+	/**
1735
+	 * Removes 'email_confirm' from the Address info question group on activation
1736
+	 *
1737
+	 * @return void
1738
+	 * @throws EE_Error
1739
+	 */
1740
+	public static function removeEmailConfirmFromAddressGroup()
1741
+	{
1742
+
1743
+		// Pull the email_confirm question ID.
1744
+		$email_confirm_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
1745
+			EEM_Attendee::system_question_email_confirm
1746
+		);
1747
+		// Remove the email_confirm question group from the address group questions.
1748
+		EEM_Question_Group_Question::instance()->delete(
1749
+			[
1750
+				[
1751
+					'QST_ID'                    => $email_confirm_question_id,
1752
+					'Question_Group.QSG_system' => EEM_Question_Group::system_address,
1753
+				],
1754
+			]
1755
+		);
1756
+	}
1757 1757
 }
Please login to merge, or discard this patch.
core/db_models/helpers/EE_Table_Base.php 2 patches
Indentation   +147 added lines, -147 removed lines patch added patch discarded remove patch
@@ -7,151 +7,151 @@
 block discarded – undo
7 7
 abstract class EE_Table_Base
8 8
 {
9 9
 
10
-    /**
11
-     * This holds the table_name without the table prefix.
12
-     *
13
-     * @var string
14
-     */
15
-    public $_table_name;
16
-
17
-
18
-    /**
19
-     * This holds what is used as the alias for the table in queries.
20
-     *
21
-     * @var string
22
-     */
23
-    public $_table_alias;
24
-
25
-
26
-    /**
27
-     * Table's private key column
28
-     *
29
-     * @var string
30
-     */
31
-    protected $_pk_column;
32
-
33
-
34
-    /**
35
-     * Whether this table is a global table (in multisite) or specific to site.
36
-     *
37
-     * @var bool
38
-     */
39
-    protected $_global;
40
-
41
-
42
-    /**
43
-     * @param string  $table_name with or without wpdb prefix
44
-     * @param string  $pk_column
45
-     * @param boolean $global     whether the table is "global" as in there is only 1 table on an entire multisite
46
-     *                            install, or whether each site on a multisite install has a copy of this table
47
-     * @global wpdb   $wpdb
48
-     */
49
-    public function __construct($table_name, $pk_column, $global = false)
50
-    {
51
-        $this->_global = $global;
52
-        $prefix        = $this->get_table_prefix();
53
-        // if they added the prefix, let's remove it because we delay adding the prefix until right when its needed.
54
-        if (strpos($table_name, $prefix) === 0) {
55
-            $table_name = substr_replace($table_name, '', 0, strlen($prefix));
56
-        }
57
-        $this->_table_name = $table_name;
58
-        $this->_pk_column  = $pk_column;
59
-    }
60
-
61
-
62
-    /**
63
-     * This returns the table prefix for the current model state.
64
-     *
65
-     * @return string
66
-     * @global wpdb $wpdb
67
-     */
68
-    public function get_table_prefix()
69
-    {
70
-        global $wpdb;
71
-        if ($this->_global) {
72
-            return $wpdb->base_prefix;
73
-        }
74
-        return $wpdb->get_blog_prefix(EEM_Base::get_model_query_blog_id());
75
-    }
76
-
77
-
78
-    /**
79
-     * Used to set the table_alias property
80
-     *
81
-     * @param string $table_alias
82
-     */
83
-    public function _construct_finalize_with_alias($table_alias)
84
-    {
85
-        $this->_table_alias = $table_alias;
86
-    }
87
-
88
-
89
-    /**
90
-     * Returns the fully qualified table name for the database (includes the table prefix current for the blog).
91
-     *
92
-     * @return string
93
-     */
94
-    public function get_table_name()
95
-    {
96
-        return $this->get_table_prefix() . $this->_table_name;
97
-    }
98
-
99
-
100
-    /**
101
-     * Provides what is currently set as the alias for the table to be used in queries.
102
-     *
103
-     * @return string
104
-     * @throws EE_Error
105
-     */
106
-    public function get_table_alias()
107
-    {
108
-        if (! $this->_table_alias) {
109
-            throw new EE_Error("You must call _construct_finalize_with_alias before using the EE_Table_Base. Did you forget to call parent::__construct at the end of your EEMerimental_Base child's __construct?");
110
-        }
111
-        return $this->_table_alias;
112
-    }
113
-
114
-
115
-    /**
116
-     * @return string name of column of PK
117
-     */
118
-    public function get_pk_column()
119
-    {
120
-        return $this->_pk_column;
121
-    }
122
-
123
-
124
-    /**
125
-     * returns a string with the table alias, a period, and the private key's column.
126
-     *
127
-     * @return string
128
-     */
129
-    public function get_fully_qualified_pk_column()
130
-    {
131
-        return $this->get_table_alias() . "." . $this->get_pk_column();
132
-    }
133
-
134
-
135
-    /**
136
-     * returns the special sql for a inner select with a limit.
137
-     *
138
-     * @return string    SQL select
139
-     */
140
-    public function get_select_join_limit($limit)
141
-    {
142
-        $limit = is_array($limit) ? 'LIMIT ' . implode(',', array_map('intval', $limit)) : 'LIMIT ' . (int) $limit;
143
-        return SP . '(SELECT * FROM ' . $this->_table_name . SP . $limit . ') AS ' . $this->_table_alias;
144
-    }
145
-
146
-
147
-    /**
148
-     * Returns whether or not htis is a global table (ie, on multisite there's
149
-     * only one of these tables, on the main blog)
150
-     *
151
-     * @return boolean
152
-     */
153
-    public function is_global()
154
-    {
155
-        return $this->_global;
156
-    }
10
+	/**
11
+	 * This holds the table_name without the table prefix.
12
+	 *
13
+	 * @var string
14
+	 */
15
+	public $_table_name;
16
+
17
+
18
+	/**
19
+	 * This holds what is used as the alias for the table in queries.
20
+	 *
21
+	 * @var string
22
+	 */
23
+	public $_table_alias;
24
+
25
+
26
+	/**
27
+	 * Table's private key column
28
+	 *
29
+	 * @var string
30
+	 */
31
+	protected $_pk_column;
32
+
33
+
34
+	/**
35
+	 * Whether this table is a global table (in multisite) or specific to site.
36
+	 *
37
+	 * @var bool
38
+	 */
39
+	protected $_global;
40
+
41
+
42
+	/**
43
+	 * @param string  $table_name with or without wpdb prefix
44
+	 * @param string  $pk_column
45
+	 * @param boolean $global     whether the table is "global" as in there is only 1 table on an entire multisite
46
+	 *                            install, or whether each site on a multisite install has a copy of this table
47
+	 * @global wpdb   $wpdb
48
+	 */
49
+	public function __construct($table_name, $pk_column, $global = false)
50
+	{
51
+		$this->_global = $global;
52
+		$prefix        = $this->get_table_prefix();
53
+		// if they added the prefix, let's remove it because we delay adding the prefix until right when its needed.
54
+		if (strpos($table_name, $prefix) === 0) {
55
+			$table_name = substr_replace($table_name, '', 0, strlen($prefix));
56
+		}
57
+		$this->_table_name = $table_name;
58
+		$this->_pk_column  = $pk_column;
59
+	}
60
+
61
+
62
+	/**
63
+	 * This returns the table prefix for the current model state.
64
+	 *
65
+	 * @return string
66
+	 * @global wpdb $wpdb
67
+	 */
68
+	public function get_table_prefix()
69
+	{
70
+		global $wpdb;
71
+		if ($this->_global) {
72
+			return $wpdb->base_prefix;
73
+		}
74
+		return $wpdb->get_blog_prefix(EEM_Base::get_model_query_blog_id());
75
+	}
76
+
77
+
78
+	/**
79
+	 * Used to set the table_alias property
80
+	 *
81
+	 * @param string $table_alias
82
+	 */
83
+	public function _construct_finalize_with_alias($table_alias)
84
+	{
85
+		$this->_table_alias = $table_alias;
86
+	}
87
+
88
+
89
+	/**
90
+	 * Returns the fully qualified table name for the database (includes the table prefix current for the blog).
91
+	 *
92
+	 * @return string
93
+	 */
94
+	public function get_table_name()
95
+	{
96
+		return $this->get_table_prefix() . $this->_table_name;
97
+	}
98
+
99
+
100
+	/**
101
+	 * Provides what is currently set as the alias for the table to be used in queries.
102
+	 *
103
+	 * @return string
104
+	 * @throws EE_Error
105
+	 */
106
+	public function get_table_alias()
107
+	{
108
+		if (! $this->_table_alias) {
109
+			throw new EE_Error("You must call _construct_finalize_with_alias before using the EE_Table_Base. Did you forget to call parent::__construct at the end of your EEMerimental_Base child's __construct?");
110
+		}
111
+		return $this->_table_alias;
112
+	}
113
+
114
+
115
+	/**
116
+	 * @return string name of column of PK
117
+	 */
118
+	public function get_pk_column()
119
+	{
120
+		return $this->_pk_column;
121
+	}
122
+
123
+
124
+	/**
125
+	 * returns a string with the table alias, a period, and the private key's column.
126
+	 *
127
+	 * @return string
128
+	 */
129
+	public function get_fully_qualified_pk_column()
130
+	{
131
+		return $this->get_table_alias() . "." . $this->get_pk_column();
132
+	}
133
+
134
+
135
+	/**
136
+	 * returns the special sql for a inner select with a limit.
137
+	 *
138
+	 * @return string    SQL select
139
+	 */
140
+	public function get_select_join_limit($limit)
141
+	{
142
+		$limit = is_array($limit) ? 'LIMIT ' . implode(',', array_map('intval', $limit)) : 'LIMIT ' . (int) $limit;
143
+		return SP . '(SELECT * FROM ' . $this->_table_name . SP . $limit . ') AS ' . $this->_table_alias;
144
+	}
145
+
146
+
147
+	/**
148
+	 * Returns whether or not htis is a global table (ie, on multisite there's
149
+	 * only one of these tables, on the main blog)
150
+	 *
151
+	 * @return boolean
152
+	 */
153
+	public function is_global()
154
+	{
155
+		return $this->_global;
156
+	}
157 157
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
      */
94 94
     public function get_table_name()
95 95
     {
96
-        return $this->get_table_prefix() . $this->_table_name;
96
+        return $this->get_table_prefix().$this->_table_name;
97 97
     }
98 98
 
99 99
 
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
      */
106 106
     public function get_table_alias()
107 107
     {
108
-        if (! $this->_table_alias) {
108
+        if ( ! $this->_table_alias) {
109 109
             throw new EE_Error("You must call _construct_finalize_with_alias before using the EE_Table_Base. Did you forget to call parent::__construct at the end of your EEMerimental_Base child's __construct?");
110 110
         }
111 111
         return $this->_table_alias;
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
      */
129 129
     public function get_fully_qualified_pk_column()
130 130
     {
131
-        return $this->get_table_alias() . "." . $this->get_pk_column();
131
+        return $this->get_table_alias().".".$this->get_pk_column();
132 132
     }
133 133
 
134 134
 
@@ -139,8 +139,8 @@  discard block
 block discarded – undo
139 139
      */
140 140
     public function get_select_join_limit($limit)
141 141
     {
142
-        $limit = is_array($limit) ? 'LIMIT ' . implode(',', array_map('intval', $limit)) : 'LIMIT ' . (int) $limit;
143
-        return SP . '(SELECT * FROM ' . $this->_table_name . SP . $limit . ') AS ' . $this->_table_alias;
142
+        $limit = is_array($limit) ? 'LIMIT '.implode(',', array_map('intval', $limit)) : 'LIMIT '.(int) $limit;
143
+        return SP.'(SELECT * FROM '.$this->_table_name.SP.$limit.') AS '.$this->_table_alias;
144 144
     }
145 145
 
146 146
 
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 1 patch
Indentation   +4541 added lines, -4541 removed lines patch added patch discarded remove patch
@@ -19,2642 +19,2642 @@  discard block
 block discarded – undo
19 19
 class Messages_Admin_Page extends EE_Admin_Page
20 20
 {
21 21
 
22
-    /**
23
-     * @type EE_Message_Resource_Manager $_message_resource_manager
24
-     */
25
-    protected $_message_resource_manager;
26
-
27
-    /**
28
-     * @type string $_active_message_type_name
29
-     */
30
-    protected $_active_message_type_name = '';
31
-
32
-    /**
33
-     * @type EE_messenger $_active_messenger
34
-     */
35
-    protected $_active_messenger;
36
-    protected $_activate_state;
37
-    protected $_activate_meta_box_type;
38
-    protected $_current_message_meta_box;
39
-    protected $_current_message_meta_box_object;
40
-    protected $_context_switcher;
41
-    protected $_shortcodes = array();
42
-    protected $_active_messengers = array();
43
-    protected $_active_message_types = array();
44
-
45
-    /**
46
-     * @var EE_Message_Template_Group $_message_template_group
47
-     */
48
-    protected $_message_template_group;
49
-    protected $_m_mt_settings = array();
50
-
51
-
52
-    /**
53
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
-     * IF there is no group then it gets automatically set to the Default template pack.
55
-     *
56
-     * @since 4.5.0
57
-     *
58
-     * @var EE_Messages_Template_Pack
59
-     */
60
-    protected $_template_pack;
61
-
62
-
63
-    /**
64
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
-     * group is.  If there is no group then it automatically gets set to default.
66
-     *
67
-     * @since 4.5.0
68
-     *
69
-     * @var string
70
-     */
71
-    protected $_variation;
72
-
73
-
74
-    /**
75
-     * @param bool $routing
76
-     * @throws EE_Error
77
-     */
78
-    public function __construct($routing = true)
79
-    {
80
-        // make sure messages autoloader is running
81
-        EED_Messages::set_autoloaders();
82
-        parent::__construct($routing);
83
-    }
84
-
85
-
86
-    protected function _init_page_props()
87
-    {
88
-        $this->page_slug = EE_MSG_PG_SLUG;
89
-        $this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
-        $this->_admin_base_url = EE_MSG_ADMIN_URL;
91
-        $this->_admin_base_path = EE_MSG_ADMIN;
92
-
93
-        $this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
-            : array();
95
-
96
-        $this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
-        $this->_load_message_resource_manager();
98
-    }
99
-
100
-
101
-    /**
102
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
-     *
104
-     * @throws EE_Error
105
-     * @throws InvalidDataTypeException
106
-     * @throws InvalidInterfaceException
107
-     * @throws InvalidArgumentException
108
-     * @throws ReflectionException
109
-     */
110
-    protected function _load_message_resource_manager()
111
-    {
112
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
-    }
114
-
115
-
116
-    /**
117
-     * @deprecated 4.9.9.rc.014
118
-     * @return array
119
-     * @throws EE_Error
120
-     * @throws InvalidArgumentException
121
-     * @throws InvalidDataTypeException
122
-     * @throws InvalidInterfaceException
123
-     */
124
-    public function get_messengers_for_list_table()
125
-    {
126
-        EE_Error::doing_it_wrong(
127
-            __METHOD__,
128
-            sprintf(
129
-                esc_html__(
130
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
131
-                    'event_espresso'
132
-                ),
133
-                'Messages_Admin_Page::get_messengers_select_input()'
134
-            ),
135
-            '4.9.9.rc.014'
136
-        );
137
-
138
-        $m_values = array();
139
-        $active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
-        // setup messengers for selects
141
-        $i = 1;
142
-        foreach ($active_messengers as $active_messenger) {
143
-            if ($active_messenger instanceof EE_Message) {
144
-                $m_values[ $i ]['id'] = $active_messenger->messenger();
145
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
-                $i++;
147
-            }
148
-        }
149
-
150
-        return $m_values;
151
-    }
152
-
153
-
154
-    /**
155
-     * @deprecated 4.9.9.rc.014
156
-     * @return array
157
-     * @throws EE_Error
158
-     * @throws InvalidArgumentException
159
-     * @throws InvalidDataTypeException
160
-     * @throws InvalidInterfaceException
161
-     */
162
-    public function get_message_types_for_list_table()
163
-    {
164
-        EE_Error::doing_it_wrong(
165
-            __METHOD__,
166
-            sprintf(
167
-                esc_html__(
168
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
169
-                    'event_espresso'
170
-                ),
171
-                'Messages_Admin_Page::get_message_types_select_input()'
172
-            ),
173
-            '4.9.9.rc.014'
174
-        );
175
-
176
-        $mt_values = array();
177
-        $active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
-        $i = 1;
179
-        foreach ($active_messages as $active_message) {
180
-            if ($active_message instanceof EE_Message) {
181
-                $mt_values[ $i ]['id'] = $active_message->message_type();
182
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
-                $i++;
184
-            }
185
-        }
186
-
187
-        return $mt_values;
188
-    }
189
-
190
-
191
-    /**
192
-     * @deprecated 4.9.9.rc.014
193
-     * @return array
194
-     * @throws EE_Error
195
-     * @throws InvalidArgumentException
196
-     * @throws InvalidDataTypeException
197
-     * @throws InvalidInterfaceException
198
-     */
199
-    public function get_contexts_for_message_types_for_list_table()
200
-    {
201
-        EE_Error::doing_it_wrong(
202
-            __METHOD__,
203
-            sprintf(
204
-                esc_html__(
205
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
206
-                    'event_espresso'
207
-                ),
208
-                'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
-            ),
210
-            '4.9.9.rc.014'
211
-        );
212
-
213
-        $contexts = array();
214
-        $active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
-        foreach ($active_message_contexts as $active_message) {
216
-            if ($active_message instanceof EE_Message) {
217
-                $message_type = $active_message->message_type_object();
218
-                if ($message_type instanceof EE_message_type) {
219
-                    $message_type_contexts = $message_type->get_contexts();
220
-                    foreach ($message_type_contexts as $context => $context_details) {
221
-                        $contexts[ $context ] = $context_details['label'];
222
-                    }
223
-                }
224
-            }
225
-        }
226
-
227
-        return $contexts;
228
-    }
229
-
230
-
231
-    /**
232
-     * Generate select input with provided messenger options array.
233
-     *
234
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
-     *                                 labels.
236
-     * @return string
237
-     * @throws EE_Error
238
-     */
239
-    public function get_messengers_select_input($messenger_options)
240
-    {
241
-        // if empty or just one value then just return an empty string
242
-        if (empty($messenger_options)
243
-            || ! is_array($messenger_options)
244
-            || count($messenger_options) === 1
245
-        ) {
246
-            return '';
247
-        }
248
-        // merge in default
249
-        $messenger_options = array_merge(
250
-            array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
251
-            $messenger_options
252
-        );
253
-        $input = new EE_Select_Input(
254
-            $messenger_options,
255
-            array(
256
-                'html_name'  => 'ee_messenger_filter_by',
257
-                'html_id'    => 'ee_messenger_filter_by',
258
-                'html_class' => 'wide',
259
-                'default'    => isset($this->_req_data['ee_messenger_filter_by'])
260
-                    ? sanitize_title($this->_req_data['ee_messenger_filter_by'])
261
-                    : 'none_selected',
262
-            )
263
-        );
264
-
265
-        return $input->get_html_for_input();
266
-    }
267
-
268
-
269
-    /**
270
-     * Generate select input with provided message type options array.
271
-     *
272
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
273
-     *                                    message type labels
274
-     * @return string
275
-     * @throws EE_Error
276
-     */
277
-    public function get_message_types_select_input($message_type_options)
278
-    {
279
-        // if empty or count of options is 1 then just return an empty string
280
-        if (empty($message_type_options)
281
-            || ! is_array($message_type_options)
282
-            || count($message_type_options) === 1
283
-        ) {
284
-            return '';
285
-        }
286
-        // merge in default
287
-        $message_type_options = array_merge(
288
-            array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
289
-            $message_type_options
290
-        );
291
-        $input = new EE_Select_Input(
292
-            $message_type_options,
293
-            array(
294
-                'html_name'  => 'ee_message_type_filter_by',
295
-                'html_id'    => 'ee_message_type_filter_by',
296
-                'html_class' => 'wide',
297
-                'default'    => isset($this->_req_data['ee_message_type_filter_by'])
298
-                    ? sanitize_title($this->_req_data['ee_message_type_filter_by'])
299
-                    : 'none_selected',
300
-            )
301
-        );
302
-
303
-        return $input->get_html_for_input();
304
-    }
305
-
306
-
307
-    /**
308
-     * Generate select input with provide message type contexts array.
309
-     *
310
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
311
-     *                               context label.
312
-     * @return string
313
-     * @throws EE_Error
314
-     */
315
-    public function get_contexts_for_message_types_select_input($context_options)
316
-    {
317
-        // if empty or count of options is one then just return empty string
318
-        if (empty($context_options)
319
-            || ! is_array($context_options)
320
-            || count($context_options) === 1
321
-        ) {
322
-            return '';
323
-        }
324
-        // merge in default
325
-        $context_options = array_merge(
326
-            array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
327
-            $context_options
328
-        );
329
-        $input = new EE_Select_Input(
330
-            $context_options,
331
-            array(
332
-                'html_name'  => 'ee_context_filter_by',
333
-                'html_id'    => 'ee_context_filter_by',
334
-                'html_class' => 'wide',
335
-                'default'    => isset($this->_req_data['ee_context_filter_by'])
336
-                    ? sanitize_title($this->_req_data['ee_context_filter_by'])
337
-                    : 'none_selected',
338
-            )
339
-        );
340
-
341
-        return $input->get_html_for_input();
342
-    }
343
-
344
-
345
-    protected function _ajax_hooks()
346
-    {
347
-        add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
348
-        add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
349
-        add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
350
-        add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
351
-        add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
352
-        add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
353
-    }
354
-
355
-
356
-    protected function _define_page_props()
357
-    {
358
-        $this->_admin_page_title = $this->page_label;
359
-        $this->_labels = array(
360
-            'buttons'    => array(
361
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
362
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
363
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
364
-            ),
365
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
366
-        );
367
-    }
368
-
369
-
370
-    /**
371
-     *        an array for storing key => value pairs of request actions and their corresponding methods
372
-     *
373
-     * @access protected
374
-     * @return void
375
-     */
376
-    protected function _set_page_routes()
377
-    {
378
-        $grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
379
-            ? $this->_req_data['GRP_ID']
380
-            : 0;
381
-        $grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
382
-            ? $this->_req_data['id']
383
-            : $grp_id;
384
-        $msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
385
-            ? $this->_req_data['MSG_ID']
386
-            : 0;
387
-
388
-        $this->_page_routes = array(
389
-            'default'                          => array(
390
-                'func'       => '_message_queue_list_table',
391
-                'capability' => 'ee_read_global_messages',
392
-            ),
393
-            'global_mtps'                      => array(
394
-                'func'       => '_ee_default_messages_overview_list_table',
395
-                'capability' => 'ee_read_global_messages',
396
-            ),
397
-            'custom_mtps'                      => array(
398
-                'func'       => '_custom_mtps_preview',
399
-                'capability' => 'ee_read_messages',
400
-            ),
401
-            'add_new_message_template'         => array(
402
-                'func'       => '_add_message_template',
403
-                'capability' => 'ee_edit_messages',
404
-                'noheader'   => true,
405
-            ),
406
-            'edit_message_template'            => array(
407
-                'func'       => '_edit_message_template',
408
-                'capability' => 'ee_edit_message',
409
-                'obj_id'     => $grp_id,
410
-            ),
411
-            'preview_message'                  => array(
412
-                'func'               => '_preview_message',
413
-                'capability'         => 'ee_read_message',
414
-                'obj_id'             => $grp_id,
415
-                'noheader'           => true,
416
-                'headers_sent_route' => 'display_preview_message',
417
-            ),
418
-            'display_preview_message'          => array(
419
-                'func'       => '_display_preview_message',
420
-                'capability' => 'ee_read_message',
421
-                'obj_id'     => $grp_id,
422
-            ),
423
-            'insert_message_template'          => array(
424
-                'func'       => '_insert_or_update_message_template',
425
-                'capability' => 'ee_edit_messages',
426
-                'args'       => array('new_template' => true),
427
-                'noheader'   => true,
428
-            ),
429
-            'update_message_template'          => array(
430
-                'func'       => '_insert_or_update_message_template',
431
-                'capability' => 'ee_edit_message',
432
-                'obj_id'     => $grp_id,
433
-                'args'       => array('new_template' => false),
434
-                'noheader'   => true,
435
-            ),
436
-            'trash_message_template'           => array(
437
-                'func'       => '_trash_or_restore_message_template',
438
-                'capability' => 'ee_delete_message',
439
-                'obj_id'     => $grp_id,
440
-                'args'       => array('trash' => true, 'all' => true),
441
-                'noheader'   => true,
442
-            ),
443
-            'trash_message_template_context'   => array(
444
-                'func'       => '_trash_or_restore_message_template',
445
-                'capability' => 'ee_delete_message',
446
-                'obj_id'     => $grp_id,
447
-                'args'       => array('trash' => true),
448
-                'noheader'   => true,
449
-            ),
450
-            'restore_message_template'         => array(
451
-                'func'       => '_trash_or_restore_message_template',
452
-                'capability' => 'ee_delete_message',
453
-                'obj_id'     => $grp_id,
454
-                'args'       => array('trash' => false, 'all' => true),
455
-                'noheader'   => true,
456
-            ),
457
-            'restore_message_template_context' => array(
458
-                'func'       => '_trash_or_restore_message_template',
459
-                'capability' => 'ee_delete_message',
460
-                'obj_id'     => $grp_id,
461
-                'args'       => array('trash' => false),
462
-                'noheader'   => true,
463
-            ),
464
-            'delete_message_template'          => array(
465
-                'func'       => '_delete_message_template',
466
-                'capability' => 'ee_delete_message',
467
-                'obj_id'     => $grp_id,
468
-                'noheader'   => true,
469
-            ),
470
-            'reset_to_default'                 => array(
471
-                'func'       => '_reset_to_default_template',
472
-                'capability' => 'ee_edit_message',
473
-                'obj_id'     => $grp_id,
474
-                'noheader'   => true,
475
-            ),
476
-            'settings'                         => array(
477
-                'func'       => '_settings',
478
-                'capability' => 'manage_options',
479
-            ),
480
-            'update_global_settings'           => array(
481
-                'func'       => '_update_global_settings',
482
-                'capability' => 'manage_options',
483
-                'noheader'   => true,
484
-            ),
485
-            'generate_now'                     => array(
486
-                'func'       => '_generate_now',
487
-                'capability' => 'ee_send_message',
488
-                'noheader'   => true,
489
-            ),
490
-            'generate_and_send_now'            => array(
491
-                'func'       => '_generate_and_send_now',
492
-                'capability' => 'ee_send_message',
493
-                'noheader'   => true,
494
-            ),
495
-            'queue_for_resending'              => array(
496
-                'func'       => '_queue_for_resending',
497
-                'capability' => 'ee_send_message',
498
-                'noheader'   => true,
499
-            ),
500
-            'send_now'                         => array(
501
-                'func'       => '_send_now',
502
-                'capability' => 'ee_send_message',
503
-                'noheader'   => true,
504
-            ),
505
-            'delete_ee_message'                => array(
506
-                'func'       => '_delete_ee_messages',
507
-                'capability' => 'ee_delete_messages',
508
-                'noheader'   => true,
509
-            ),
510
-            'delete_ee_messages'               => array(
511
-                'func'       => '_delete_ee_messages',
512
-                'capability' => 'ee_delete_messages',
513
-                'noheader'   => true,
514
-                'obj_id'     => $msg_id,
515
-            ),
516
-        );
517
-    }
518
-
519
-
520
-    protected function _set_page_config()
521
-    {
522
-        $this->_page_config = array(
523
-            'default'                  => array(
524
-                'nav'           => array(
525
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
526
-                    'order' => 10,
527
-                ),
528
-                'list_table'    => 'EE_Message_List_Table',
529
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
530
-                'require_nonce' => false,
531
-            ),
532
-            'global_mtps'              => array(
533
-                'nav'           => array(
534
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
535
-                    'order' => 20,
536
-                ),
537
-                'list_table'    => 'Messages_Template_List_Table',
538
-                'help_tabs'     => array(
539
-                    'messages_overview_help_tab'                                => array(
540
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
541
-                        'filename' => 'messages_overview',
542
-                    ),
543
-                    'messages_overview_messages_table_column_headings_help_tab' => array(
544
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
545
-                        'filename' => 'messages_overview_table_column_headings',
546
-                    ),
547
-                    'messages_overview_messages_filters_help_tab'               => array(
548
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
549
-                        'filename' => 'messages_overview_filters',
550
-                    ),
551
-                    'messages_overview_messages_views_help_tab'                 => array(
552
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
553
-                        'filename' => 'messages_overview_views',
554
-                    ),
555
-                    'message_overview_message_types_help_tab'                   => array(
556
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
557
-                        'filename' => 'messages_overview_types',
558
-                    ),
559
-                    'messages_overview_messengers_help_tab'                     => array(
560
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
561
-                        'filename' => 'messages_overview_messengers',
562
-                    ),
563
-                ),
564
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
565
-                // 'help_tour'     => array('Messages_Overview_Help_Tour'),
566
-                'require_nonce' => false,
567
-            ),
568
-            'custom_mtps'              => array(
569
-                'nav'           => array(
570
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
571
-                    'order' => 30,
572
-                ),
573
-                'help_tabs'     => array(),
574
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
575
-                // 'help_tour'     => array(),
576
-                'require_nonce' => false,
577
-            ),
578
-            'add_new_message_template' => array(
579
-                'nav'           => array(
580
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
581
-                    'order'      => 5,
582
-                    'persistent' => false,
583
-                ),
584
-                'require_nonce' => false,
585
-            ),
586
-            'edit_message_template'    => array(
587
-                'labels'        => array(
588
-                    'buttons'    => array(
589
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
590
-                    ),
591
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
592
-                ),
593
-                'nav'           => array(
594
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
595
-                    'order'      => 5,
596
-                    'persistent' => false,
597
-                    'url'        => '',
598
-                ),
599
-                'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
600
-                'has_metaboxes' => true,
601
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
602
-                // 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
603
-                'help_tabs'     => array(
604
-                    'edit_message_template'            => array(
605
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
606
-                        'callback' => 'edit_message_template_help_tab',
607
-                    ),
608
-                    'message_templates_help_tab'       => array(
609
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
610
-                        'filename' => 'messages_templates',
611
-                    ),
612
-                    'message_template_shortcodes'      => array(
613
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
614
-                        'callback' => 'message_template_shortcodes_help_tab',
615
-                    ),
616
-                    'message_preview_help_tab'         => array(
617
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
618
-                        'filename' => 'messages_preview',
619
-                    ),
620
-                    'messages_overview_other_help_tab' => array(
621
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
622
-                        'filename' => 'messages_overview_other',
623
-                    ),
624
-                ),
625
-                'require_nonce' => false,
626
-            ),
627
-            'display_preview_message'  => array(
628
-                'nav'           => array(
629
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
630
-                    'order'      => 5,
631
-                    'url'        => '',
632
-                    'persistent' => false,
633
-                ),
634
-                'help_tabs'     => array(
635
-                    'preview_message' => array(
636
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
637
-                        'callback' => 'preview_message_help_tab',
638
-                    ),
639
-                ),
640
-                'require_nonce' => false,
641
-            ),
642
-            'settings'                 => array(
643
-                'nav'           => array(
644
-                    'label' => esc_html__('Settings', 'event_espresso'),
645
-                    'order' => 40,
646
-                ),
647
-                'metaboxes'     => array('_messages_settings_metaboxes'),
648
-                'help_tabs'     => array(
649
-                    'messages_settings_help_tab'               => array(
650
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
651
-                        'filename' => 'messages_settings',
652
-                    ),
653
-                    'messages_settings_message_types_help_tab' => array(
654
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
655
-                        'filename' => 'messages_settings_message_types',
656
-                    ),
657
-                    'messages_settings_messengers_help_tab'    => array(
658
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
659
-                        'filename' => 'messages_settings_messengers',
660
-                    ),
661
-                ),
662
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
663
-                // 'help_tour'     => array('Messages_Settings_Help_Tour'),
664
-                'require_nonce' => false,
665
-            ),
666
-        );
667
-    }
668
-
669
-
670
-    protected function _add_screen_options()
671
-    {
672
-        // todo
673
-    }
674
-
675
-
676
-    protected function _add_screen_options_global_mtps()
677
-    {
678
-        /**
679
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
680
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
681
-         */
682
-        $page_title = $this->_admin_page_title;
683
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
684
-        $this->_per_page_screen_option();
685
-        $this->_admin_page_title = $page_title;
686
-    }
687
-
688
-
689
-    protected function _add_screen_options_default()
690
-    {
691
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
692
-        $this->_per_page_screen_option();
693
-    }
694
-
695
-
696
-    // none of the below group are currently used for Messages
697
-    protected function _add_feature_pointers()
698
-    {
699
-    }
700
-
701
-    public function admin_init()
702
-    {
703
-    }
704
-
705
-    public function admin_notices()
706
-    {
707
-    }
708
-
709
-    public function admin_footer_scripts()
710
-    {
711
-    }
712
-
713
-
714
-    public function messages_help_tab()
715
-    {
716
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
717
-    }
718
-
719
-
720
-    public function messengers_help_tab()
721
-    {
722
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
723
-    }
724
-
725
-
726
-    public function message_types_help_tab()
727
-    {
728
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
729
-    }
730
-
731
-
732
-    public function messages_overview_help_tab()
733
-    {
734
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
735
-    }
736
-
737
-
738
-    public function message_templates_help_tab()
739
-    {
740
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
741
-    }
742
-
743
-
744
-    public function edit_message_template_help_tab()
745
-    {
746
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
747
-                        . esc_attr__('Editor Title', 'event_espresso')
748
-                        . '" />';
749
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
750
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
751
-                        . '" />';
752
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
753
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
754
-                        . '" />';
755
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
756
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
757
-                        . '" />';
758
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
759
-                        . esc_attr__('Publish Metabox', 'event_espresso')
760
-                        . '" />';
761
-        EEH_Template::display_template(
762
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
763
-            $args
764
-        );
765
-    }
766
-
767
-
768
-    public function message_template_shortcodes_help_tab()
769
-    {
770
-        $this->_set_shortcodes();
771
-        $args['shortcodes'] = $this->_shortcodes;
772
-        EEH_Template::display_template(
773
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
774
-            $args
775
-        );
776
-    }
777
-
778
-
779
-    public function preview_message_help_tab()
780
-    {
781
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
782
-    }
783
-
784
-
785
-    public function settings_help_tab()
786
-    {
787
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
788
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
789
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
790
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
791
-        $args['img3'] = '<div class="switch">'
792
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
793
-                        . ' type="checkbox" checked="checked">'
794
-                        . '<label for="ee-on-off-toggle-on"></label>'
795
-                        . '</div>';
796
-        $args['img4'] = '<div class="switch">'
797
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
798
-                        . ' type="checkbox">'
799
-                        . '<label for="ee-on-off-toggle-on"></label>'
800
-                        . '</div>';
801
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
802
-    }
803
-
804
-
805
-    public function load_scripts_styles()
806
-    {
807
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
808
-        wp_enqueue_style('espresso_ee_msg');
809
-
810
-        wp_register_script(
811
-            'ee-messages-settings',
812
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
813
-            array('jquery-ui-droppable', 'ee-serialize-full-array'),
814
-            EVENT_ESPRESSO_VERSION,
815
-            true
816
-        );
817
-        wp_register_script(
818
-            'ee-msg-list-table-js',
819
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
820
-            array('ee-dialog'),
821
-            EVENT_ESPRESSO_VERSION
822
-        );
823
-    }
824
-
825
-
826
-    public function load_scripts_styles_default()
827
-    {
828
-        wp_enqueue_script('ee-msg-list-table-js');
829
-    }
830
-
831
-
832
-    public function wp_editor_css($mce_css)
833
-    {
834
-        // if we're on the edit_message_template route
835
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
836
-            $message_type_name = $this->_active_message_type_name;
837
-
838
-            // we're going to REPLACE the existing mce css
839
-            // we need to get the css file location from the active messenger
840
-            $mce_css = $this->_active_messenger->get_variation(
841
-                $this->_template_pack,
842
-                $message_type_name,
843
-                true,
844
-                'wpeditor',
845
-                $this->_variation
846
-            );
847
-        }
848
-
849
-        return $mce_css;
850
-    }
851
-
852
-
853
-    public function load_scripts_styles_edit_message_template()
854
-    {
855
-
856
-        $this->_set_shortcodes();
857
-
858
-        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
859
-            esc_html__(
860
-                '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.',
861
-                'event_espresso'
862
-            ),
863
-            $this->_message_template_group->messenger_obj()->label['singular'],
864
-            $this->_message_template_group->message_type_obj()->label['singular']
865
-        );
866
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
867
-            '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?',
868
-            'event_espresso'
869
-        );
870
-        EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
871
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
872
-            'event_espresso'
873
-        );
874
-
875
-        wp_register_script(
876
-            'ee_msgs_edit_js',
877
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
878
-            array('jquery'),
879
-            EVENT_ESPRESSO_VERSION
880
-        );
881
-
882
-        wp_enqueue_script('ee_admin_js');
883
-        wp_enqueue_script('ee_msgs_edit_js');
884
-
885
-        // add in special css for tiny_mce
886
-        add_filter('mce_css', array($this, 'wp_editor_css'));
887
-    }
888
-
889
-
890
-    public function load_scripts_styles_display_preview_message()
891
-    {
892
-
893
-        $this->_set_message_template_group();
894
-
895
-        if (isset($this->_req_data['messenger'])) {
896
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
897
-                $this->_req_data['messenger']
898
-            );
899
-        }
900
-
901
-        $message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
902
-
903
-
904
-        wp_enqueue_style(
905
-            'espresso_preview_css',
906
-            $this->_active_messenger->get_variation(
907
-                $this->_template_pack,
908
-                $message_type_name,
909
-                true,
910
-                'preview',
911
-                $this->_variation
912
-            )
913
-        );
914
-    }
915
-
916
-
917
-    public function load_scripts_styles_settings()
918
-    {
919
-        wp_register_style(
920
-            'ee-message-settings',
921
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
922
-            array(),
923
-            EVENT_ESPRESSO_VERSION
924
-        );
925
-        wp_enqueue_style('ee-text-links');
926
-        wp_enqueue_style('ee-message-settings');
927
-        wp_enqueue_script('ee-messages-settings');
928
-    }
929
-
930
-
931
-    /**
932
-     * set views array for List Table
933
-     */
934
-    public function _set_list_table_views_global_mtps()
935
-    {
936
-        $this->_views = array(
937
-            'in_use' => array(
938
-                'slug'  => 'in_use',
939
-                'label' => esc_html__('In Use', 'event_espresso'),
940
-                'count' => 0,
941
-            ),
942
-        );
943
-    }
944
-
945
-
946
-    /**
947
-     * Set views array for the Custom Template List Table
948
-     */
949
-    public function _set_list_table_views_custom_mtps()
950
-    {
951
-        $this->_set_list_table_views_global_mtps();
952
-        $this->_views['in_use']['bulk_action'] = array(
953
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
954
-        );
955
-    }
956
-
957
-
958
-    /**
959
-     * set views array for message queue list table
960
-     *
961
-     * @throws InvalidDataTypeException
962
-     * @throws InvalidInterfaceException
963
-     * @throws InvalidArgumentException
964
-     * @throws EE_Error
965
-     * @throws ReflectionException
966
-     */
967
-    public function _set_list_table_views_default()
968
-    {
969
-        EE_Registry::instance()->load_helper('Template');
970
-
971
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
972
-            'ee_send_message',
973
-            'message_list_table_bulk_actions'
974
-        )
975
-            ? array(
976
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
977
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
978
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
979
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
980
-            )
981
-            : array();
982
-
983
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
984
-            'ee_delete_messages',
985
-            'message_list_table_bulk_actions'
986
-        )
987
-            ? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
988
-            : array();
989
-
990
-
991
-        $this->_views = array(
992
-            'all' => array(
993
-                'slug'        => 'all',
994
-                'label'       => esc_html__('All', 'event_espresso'),
995
-                'count'       => 0,
996
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
997
-            ),
998
-        );
999
-
1000
-
1001
-        foreach (EEM_Message::instance()->all_statuses() as $status) {
1002
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1003
-                continue;
1004
-            }
1005
-            $status_bulk_actions = $common_bulk_actions;
1006
-            // unset bulk actions not applying to status
1007
-            if (! empty($status_bulk_actions)) {
1008
-                switch ($status) {
1009
-                    case EEM_Message::status_idle:
1010
-                    case EEM_Message::status_resend:
1011
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1012
-                        break;
1013
-
1014
-                    case EEM_Message::status_failed:
1015
-                    case EEM_Message::status_debug_only:
1016
-                    case EEM_Message::status_messenger_executing:
1017
-                        $status_bulk_actions = array();
1018
-                        break;
1019
-
1020
-                    case EEM_Message::status_incomplete:
1021
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1022
-                        break;
1023
-
1024
-                    case EEM_Message::status_retry:
1025
-                    case EEM_Message::status_sent:
1026
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1027
-                        break;
1028
-                }
1029
-            }
1030
-
1031
-            // skip adding messenger executing status to views because it will be included with the Failed view.
1032
-            if ($status === EEM_Message::status_messenger_executing) {
1033
-                continue;
1034
-            }
1035
-
1036
-            $this->_views[ strtolower($status) ] = array(
1037
-                'slug'        => strtolower($status),
1038
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1039
-                'count'       => 0,
1040
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1041
-            );
1042
-        }
1043
-    }
1044
-
1045
-
1046
-    protected function _ee_default_messages_overview_list_table()
1047
-    {
1048
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1049
-        $this->display_admin_list_table_page_with_no_sidebar();
1050
-    }
1051
-
1052
-
1053
-    protected function _message_queue_list_table()
1054
-    {
1055
-        $this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1056
-        $this->_template_args['per_column'] = 6;
1057
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1058
-        $this->_template_args['before_list_table'] = '<h3>'
1059
-                                                     . EEM_Message::instance()->get_pretty_label_for_results()
1060
-                                                     . '</h3>';
1061
-        $this->display_admin_list_table_page_with_no_sidebar();
1062
-    }
1063
-
1064
-
1065
-    protected function _message_legend_items()
1066
-    {
1067
-
1068
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1069
-        $action_items = array();
1070
-
1071
-        foreach ($action_css_classes as $action_item => $action_details) {
1072
-            if ($action_item === 'see_notifications_for') {
1073
-                continue;
1074
-            }
1075
-            $action_items[ $action_item ] = array(
1076
-                'class' => $action_details['css_class'],
1077
-                'desc'  => $action_details['label'],
1078
-            );
1079
-        }
1080
-
1081
-        /** @type array $status_items status legend setup */
1082
-        $status_items = array(
1083
-            'sent_status'                => array(
1084
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1085
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1086
-            ),
1087
-            'idle_status'                => array(
1088
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1089
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1090
-            ),
1091
-            'failed_status'              => array(
1092
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1093
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1094
-            ),
1095
-            'messenger_executing_status' => array(
1096
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1097
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1098
-            ),
1099
-            'resend_status'              => array(
1100
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1101
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1102
-            ),
1103
-            'incomplete_status'          => array(
1104
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1105
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1106
-            ),
1107
-            'retry_status'               => array(
1108
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1109
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1110
-            ),
1111
-        );
1112
-        if (EEM_Message::debug()) {
1113
-            $status_items['debug_only_status'] = array(
1114
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1115
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1116
-            );
1117
-        }
1118
-
1119
-        return array_merge($action_items, $status_items);
1120
-    }
1121
-
1122
-
1123
-    protected function _custom_mtps_preview()
1124
-    {
1125
-        $this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1126
-        $this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1127
-                                               . ' alt="' . esc_attr__(
1128
-                                                   'Preview Custom Message Templates screenshot',
1129
-                                                   'event_espresso'
1130
-                                               ) . '" />';
1131
-        $this->_template_args['preview_text'] = '<strong>'
1132
-                                                . esc_html__(
1133
-                                                    '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.',
1134
-                                                    'event_espresso'
1135
-                                                )
1136
-                                                . '</strong>';
1137
-
1138
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1139
-    }
1140
-
1141
-
1142
-    /**
1143
-     * get_message_templates
1144
-     * This gets all the message templates for listing on the overview list.
1145
-     *
1146
-     * @access public
1147
-     * @param int    $perpage the amount of templates groups to show per page
1148
-     * @param string $type    the current _view we're getting templates for
1149
-     * @param bool   $count   return count?
1150
-     * @param bool   $all     disregard any paging info (get all data);
1151
-     * @param bool   $global  whether to return just global (true) or custom templates (false)
1152
-     * @return array
1153
-     * @throws EE_Error
1154
-     * @throws InvalidArgumentException
1155
-     * @throws InvalidDataTypeException
1156
-     * @throws InvalidInterfaceException
1157
-     */
1158
-    public function get_message_templates(
1159
-        $perpage = 10,
1160
-        $type = 'in_use',
1161
-        $count = false,
1162
-        $all = false,
1163
-        $global = true
1164
-    ) {
1165
-
1166
-        $MTP = EEM_Message_Template_Group::instance();
1167
-
1168
-        $this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1169
-        $orderby = $this->_req_data['orderby'];
1170
-
1171
-        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1172
-            ? $this->_req_data['order']
1173
-            : 'ASC';
1174
-
1175
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1176
-            ? $this->_req_data['paged']
1177
-            : 1;
1178
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1179
-            ? $this->_req_data['perpage']
1180
-            : $perpage;
1181
-
1182
-        $offset = ($current_page - 1) * $per_page;
1183
-        $limit = $all ? null : array($offset, $per_page);
1184
-
1185
-
1186
-        // options will match what is in the _views array property
1187
-        switch ($type) {
1188
-            case 'in_use':
1189
-                $templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1190
-                break;
1191
-            default:
1192
-                $templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1193
-        }
1194
-
1195
-        return $templates;
1196
-    }
1197
-
1198
-
1199
-    /**
1200
-     * filters etc might need a list of installed message_types
1201
-     *
1202
-     * @return array an array of message type objects
1203
-     */
1204
-    public function get_installed_message_types()
1205
-    {
1206
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1207
-        $installed = array();
1208
-
1209
-        foreach ($installed_message_types as $message_type) {
1210
-            $installed[ $message_type->name ] = $message_type;
1211
-        }
1212
-
1213
-        return $installed;
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * _add_message_template
1219
-     *
1220
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1221
-     *
1222
-     * @param string $message_type
1223
-     * @param string $messenger
1224
-     * @param string $GRP_ID
1225
-     *
1226
-     * @throws EE_error
1227
-     */
1228
-    protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1229
-    {
1230
-        // set values override any request data
1231
-        $message_type = ! empty($message_type) ? $message_type : '';
1232
-        $message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1233
-            ? $this->_req_data['message_type']
1234
-            : $message_type;
1235
-
1236
-        $messenger = ! empty($messenger) ? $messenger : '';
1237
-        $messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1238
-            ? $this->_req_data['messenger']
1239
-            : $messenger;
1240
-
1241
-        $GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1242
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1243
-
1244
-        // we need messenger and message type.  They should be coming from the event editor. If not here then return error
1245
-        if (empty($message_type) || empty($messenger)) {
1246
-            throw new EE_Error(
1247
-                esc_html__(
1248
-                    'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1249
-                    'event_espresso'
1250
-                )
1251
-            );
1252
-        }
1253
-
1254
-        // we need the GRP_ID for the template being used as the base for the new template
1255
-        if (empty($GRP_ID)) {
1256
-            throw new EE_Error(
1257
-                esc_html__(
1258
-                    'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1259
-                    'event_espresso'
1260
-                )
1261
-            );
1262
-        }
1263
-
1264
-        // let's just make sure the template gets generated!
1265
-
1266
-        // we need to reassign some variables for what the insert is expecting
1267
-        $this->_req_data['MTP_messenger'] = $messenger;
1268
-        $this->_req_data['MTP_message_type'] = $message_type;
1269
-        $this->_req_data['GRP_ID'] = $GRP_ID;
1270
-        $this->_insert_or_update_message_template(true);
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * public wrapper for the _add_message_template method
1276
-     *
1277
-     * @param string $message_type     message type slug
1278
-     * @param string $messenger        messenger slug
1279
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1280
-     *                                 off of.
1281
-     * @throws EE_error
1282
-     */
1283
-    public function add_message_template($message_type, $messenger, $GRP_ID)
1284
-    {
1285
-        $this->_add_message_template($message_type, $messenger, $GRP_ID);
1286
-    }
1287
-
1288
-
1289
-    /**
1290
-     * _edit_message_template
1291
-     *
1292
-     * @access protected
1293
-     * @return void
1294
-     * @throws InvalidIdentifierException
1295
-     * @throws DomainException
1296
-     * @throws EE_Error
1297
-     * @throws InvalidArgumentException
1298
-     * @throws ReflectionException
1299
-     * @throws InvalidDataTypeException
1300
-     * @throws InvalidInterfaceException
1301
-     */
1302
-    protected function _edit_message_template()
1303
-    {
1304
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1305
-        $template_fields = '';
1306
-        $sidebar_fields = '';
1307
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1308
-        // valid html in the templates.
1309
-        add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1310
-
1311
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1312
-            ? absint($this->_req_data['id'])
1313
-            : false;
1314
-
1315
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1316
-        ? absint($this->_req_data['evt_id'])
1317
-        : false;
1318
-
1319
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1320
-        $message_template_group = $this->_message_template_group;
1321
-        $c_label = $message_template_group->context_label();
1322
-        $c_config = $message_template_group->contexts_config();
1323
-
1324
-        reset($c_config);
1325
-        $context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1326
-            ? strtolower($this->_req_data['context'])
1327
-            : key($c_config);
1328
-
1329
-
1330
-        if (empty($GRP_ID)) {
1331
-            $action = 'insert_message_template';
1332
-            $edit_message_template_form_url = add_query_arg(
1333
-                array('action' => $action, 'noheader' => true),
1334
-                EE_MSG_ADMIN_URL
1335
-            );
1336
-        } else {
1337
-            $action = 'update_message_template';
1338
-            $edit_message_template_form_url = add_query_arg(
1339
-                array('action' => $action, 'noheader' => true),
1340
-                EE_MSG_ADMIN_URL
1341
-            );
1342
-        }
1343
-
1344
-        // set active messenger for this view
1345
-        $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1346
-            $message_template_group->messenger()
1347
-        );
1348
-        $this->_active_message_type_name = $message_template_group->message_type();
1349
-
1350
-
1351
-        // Do we have any validation errors?
1352
-        $validators = $this->_get_transient();
1353
-        $v_fields = ! empty($validators) ? array_keys($validators) : array();
1354
-
1355
-
1356
-        // we need to assemble the title from Various details
1357
-        $context_label = sprintf(
1358
-            esc_html__('(%s %s)', 'event_espresso'),
1359
-            $c_config[ $context ]['label'],
1360
-            ucwords($c_label['label'])
1361
-        );
1362
-
1363
-        $title = sprintf(
1364
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1365
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1366
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1367
-            $context_label
1368
-        );
1369
-
1370
-        $this->_template_args['GRP_ID'] = $GRP_ID;
1371
-        $this->_template_args['message_template'] = $message_template_group;
1372
-        $this->_template_args['is_extra_fields'] = false;
1373
-
1374
-
1375
-        // let's get EEH_MSG_Template so we can get template form fields
1376
-        $template_field_structure = EEH_MSG_Template::get_fields(
1377
-            $message_template_group->messenger(),
1378
-            $message_template_group->message_type()
1379
-        );
1380
-
1381
-        if (! $template_field_structure) {
1382
-            $template_field_structure = false;
1383
-            $template_fields = esc_html__(
1384
-                'There was an error in assembling the fields for this display (you should see an error message)',
1385
-                'event_espresso'
1386
-            );
1387
-        }
1388
-
1389
-
1390
-        $message_templates = $message_template_group->context_templates();
1391
-
1392
-
1393
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1394
-        // will get handled in the "extra" array.
1395
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1396
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1397
-                unset($template_field_structure[ $context ][ $reference_field ]);
1398
-            }
1399
-        }
1400
-
1401
-        // let's loop through the template_field_structure and actually assemble the input fields!
1402
-        if (! empty($template_field_structure)) {
1403
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1404
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1405
-                // the extra array and reset them.
1406
-                if ($template_field === 'extra') {
1407
-                    $this->_template_args['is_extra_fields'] = true;
1408
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1409
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1410
-                        $content = $message_template instanceof EE_Message_Template
1411
-                            ? $message_template->get('MTP_content')
1412
-                            : '';
1413
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1414
-                            // let's verify if we need this extra field via the shortcodes parameter.
1415
-                            $continue = false;
1416
-                            if (isset($extra_array['shortcodes_required'])) {
1417
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1418
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1419
-                                        $continue = true;
1420
-                                    }
1421
-                                }
1422
-                                if ($continue) {
1423
-                                    continue;
1424
-                                }
1425
-                            }
1426
-
1427
-                            $field_id = $reference_field
1428
-                                        . '-'
1429
-                                        . $extra_field
1430
-                                        . '-content';
1431
-                            $template_form_fields[ $field_id ] = $extra_array;
1432
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1433
-                                                                         . $reference_field
1434
-                                                                         . '][content]['
1435
-                                                                         . $extra_field . ']';
1436
-                            $css_class = isset($extra_array['css_class'])
1437
-                                ? $extra_array['css_class']
1438
-                                : '';
1439
-
1440
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1441
-                                                                              && in_array($extra_field, $v_fields, true)
1442
-                                                                              &&
1443
-                                                                              (
1444
-                                                                                  is_array($validators[ $extra_field ])
1445
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1446
-                                                                              )
1447
-                                ? 'validate-error ' . $css_class
1448
-                                : $css_class;
1449
-
1450
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1451
-                                                                          && isset($content[ $extra_field ])
1452
-                                ? $content[ $extra_field ]
1453
-                                : '';
1454
-
1455
-                            // do we have a validation error?  if we do then let's use that value instead
1456
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1457
-                                ? $validators[ $extra_field ]['value']
1458
-                                : $template_form_fields[ $field_id ]['value'];
1459
-
1460
-
1461
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1462
-
1463
-                            // shortcode selector
1464
-                            $field_name_to_use = $extra_field === 'main'
1465
-                                ? 'content'
1466
-                                : $extra_field;
1467
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1468
-                                $field_name_to_use,
1469
-                                $field_id
1470
-                            );
1471
-
1472
-                            if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1473
-                                // we want to decode the entities
1474
-                                $template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1475
-                            }/**/
1476
-                        }
1477
-                        $templatefield_MTP_id = $reference_field . '-MTP_ID';
1478
-                        $templatefield_templatename_id = $reference_field . '-name';
1479
-
1480
-                        $template_form_fields[ $templatefield_MTP_id ] = array(
1481
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1482
-                            'label'      => null,
1483
-                            'input'      => 'hidden',
1484
-                            'type'       => 'int',
1485
-                            'required'   => false,
1486
-                            'validation' => false,
1487
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1488
-                            'css_class'  => '',
1489
-                            'format'     => '%d',
1490
-                            'db-col'     => 'MTP_ID',
1491
-                        );
1492
-
1493
-                        $template_form_fields[ $templatefield_templatename_id ] = array(
1494
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1495
-                            'label'      => null,
1496
-                            'input'      => 'hidden',
1497
-                            'type'       => 'string',
1498
-                            'required'   => false,
1499
-                            'validation' => true,
1500
-                            'value'      => $reference_field,
1501
-                            'css_class'  => '',
1502
-                            'format'     => '%s',
1503
-                            'db-col'     => 'MTP_template_field',
1504
-                        );
1505
-                    }
1506
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1507
-                } else {
1508
-                    $field_id = $template_field . '-content';
1509
-                    $template_form_fields[ $field_id ] = $field_setup_array;
1510
-                    $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1511
-                    $message_template = isset($message_templates[ $context ][ $template_field ])
1512
-                        ? $message_templates[ $context ][ $template_field ]
1513
-                        : null;
1514
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1515
-                                                                  && is_array($message_templates[ $context ])
1516
-                                                                  && $message_template instanceof EE_Message_Template
1517
-                        ? $message_template->get('MTP_content')
1518
-                        : '';
1519
-
1520
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1521
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1522
-                        ? $validators[ $template_field ]['value']
1523
-                        : $template_form_fields[ $field_id ]['value'];
1524
-
1525
-
1526
-                    $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1527
-                    $css_class = isset($field_setup_array['css_class'])
1528
-                        ? $field_setup_array['css_class']
1529
-                        : '';
1530
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1531
-                                                                      && in_array($template_field, $v_fields, true)
1532
-                                                                      && isset($validators[ $template_field ]['msg'])
1533
-                        ? 'validate-error ' . $css_class
1534
-                        : $css_class;
1535
-
1536
-                    // shortcode selector
1537
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1538
-                        $template_field,
1539
-                        $field_id
1540
-                    );
1541
-                }
1542
-
1543
-                // k took care of content field(s) now let's take care of others.
1544
-
1545
-                $templatefield_MTP_id = $template_field . '-MTP_ID';
1546
-                $templatefield_field_templatename_id = $template_field . '-name';
1547
-
1548
-                // foreach template field there are actually two form fields created
1549
-                $template_form_fields[ $templatefield_MTP_id ] = array(
1550
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1551
-                    'label'      => null,
1552
-                    'input'      => 'hidden',
1553
-                    'type'       => 'int',
1554
-                    'required'   => false,
1555
-                    'validation' => true,
1556
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1557
-                    'css_class'  => '',
1558
-                    'format'     => '%d',
1559
-                    'db-col'     => 'MTP_ID',
1560
-                );
1561
-
1562
-                $template_form_fields[ $templatefield_field_templatename_id ] = array(
1563
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1564
-                    'label'      => null,
1565
-                    'input'      => 'hidden',
1566
-                    'type'       => 'string',
1567
-                    'required'   => false,
1568
-                    'validation' => true,
1569
-                    'value'      => $template_field,
1570
-                    'css_class'  => '',
1571
-                    'format'     => '%s',
1572
-                    'db-col'     => 'MTP_template_field',
1573
-                );
1574
-            }
1575
-
1576
-            // add other fields
1577
-            $template_form_fields['ee-msg-current-context'] = array(
1578
-                'name'       => 'MTP_context',
1579
-                'label'      => null,
1580
-                'input'      => 'hidden',
1581
-                'type'       => 'string',
1582
-                'required'   => false,
1583
-                'validation' => true,
1584
-                'value'      => $context,
1585
-                'css_class'  => '',
1586
-                'format'     => '%s',
1587
-                'db-col'     => 'MTP_context',
1588
-            );
1589
-
1590
-            $template_form_fields['ee-msg-grp-id'] = array(
1591
-                'name'       => 'GRP_ID',
1592
-                'label'      => null,
1593
-                'input'      => 'hidden',
1594
-                'type'       => 'int',
1595
-                'required'   => false,
1596
-                'validation' => true,
1597
-                'value'      => $GRP_ID,
1598
-                'css_class'  => '',
1599
-                'format'     => '%d',
1600
-                'db-col'     => 'GRP_ID',
1601
-            );
1602
-
1603
-            $template_form_fields['ee-msg-messenger'] = array(
1604
-                'name'       => 'MTP_messenger',
1605
-                'label'      => null,
1606
-                'input'      => 'hidden',
1607
-                'type'       => 'string',
1608
-                'required'   => false,
1609
-                'validation' => true,
1610
-                'value'      => $message_template_group->messenger(),
1611
-                'css_class'  => '',
1612
-                'format'     => '%s',
1613
-                'db-col'     => 'MTP_messenger',
1614
-            );
1615
-
1616
-            $template_form_fields['ee-msg-message-type'] = array(
1617
-                'name'       => 'MTP_message_type',
1618
-                'label'      => null,
1619
-                'input'      => 'hidden',
1620
-                'type'       => 'string',
1621
-                'required'   => false,
1622
-                'validation' => true,
1623
-                'value'      => $message_template_group->message_type(),
1624
-                'css_class'  => '',
1625
-                'format'     => '%s',
1626
-                'db-col'     => 'MTP_message_type',
1627
-            );
1628
-
1629
-            $sidebar_form_fields['ee-msg-is-global'] = array(
1630
-                'name'       => 'MTP_is_global',
1631
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1632
-                'input'      => 'hidden',
1633
-                'type'       => 'int',
1634
-                'required'   => false,
1635
-                'validation' => true,
1636
-                'value'      => $message_template_group->get('MTP_is_global'),
1637
-                'css_class'  => '',
1638
-                'format'     => '%d',
1639
-                'db-col'     => 'MTP_is_global',
1640
-            );
1641
-
1642
-            $sidebar_form_fields['ee-msg-is-override'] = array(
1643
-                'name'       => 'MTP_is_override',
1644
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1645
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1646
-                'type'       => 'int',
1647
-                'required'   => false,
1648
-                'validation' => true,
1649
-                'value'      => $message_template_group->get('MTP_is_override'),
1650
-                'css_class'  => '',
1651
-                'format'     => '%d',
1652
-                'db-col'     => 'MTP_is_override',
1653
-            );
1654
-
1655
-            $sidebar_form_fields['ee-msg-is-active'] = array(
1656
-                'name'       => 'MTP_is_active',
1657
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1658
-                'input'      => 'hidden',
1659
-                'type'       => 'int',
1660
-                'required'   => false,
1661
-                'validation' => true,
1662
-                'value'      => $message_template_group->is_active(),
1663
-                'css_class'  => '',
1664
-                'format'     => '%d',
1665
-                'db-col'     => 'MTP_is_active',
1666
-            );
1667
-
1668
-            $sidebar_form_fields['ee-msg-deleted'] = array(
1669
-                'name'       => 'MTP_deleted',
1670
-                'label'      => null,
1671
-                'input'      => 'hidden',
1672
-                'type'       => 'int',
1673
-                'required'   => false,
1674
-                'validation' => true,
1675
-                'value'      => $message_template_group->get('MTP_deleted'),
1676
-                'css_class'  => '',
1677
-                'format'     => '%d',
1678
-                'db-col'     => 'MTP_deleted',
1679
-            );
1680
-            $sidebar_form_fields['ee-msg-author'] = array(
1681
-                'name'       => 'MTP_user_id',
1682
-                'label'      => esc_html__('Author', 'event_espresso'),
1683
-                'input'      => 'hidden',
1684
-                'type'       => 'int',
1685
-                'required'   => false,
1686
-                'validation' => false,
1687
-                'value'      => $message_template_group->user(),
1688
-                'format'     => '%d',
1689
-                'db-col'     => 'MTP_user_id',
1690
-            );
1691
-
1692
-            $sidebar_form_fields['ee-msg-route'] = array(
1693
-                'name'  => 'action',
1694
-                'input' => 'hidden',
1695
-                'type'  => 'string',
1696
-                'value' => $action,
1697
-            );
1698
-
1699
-            $sidebar_form_fields['ee-msg-id'] = array(
1700
-                'name'  => 'id',
1701
-                'input' => 'hidden',
1702
-                'type'  => 'int',
1703
-                'value' => $GRP_ID,
1704
-            );
1705
-            $sidebar_form_fields['ee-msg-evt-nonce'] = array(
1706
-                'name'  => $action . '_nonce',
1707
-                'input' => 'hidden',
1708
-                'type'  => 'string',
1709
-                'value' => wp_create_nonce($action . '_nonce'),
1710
-            );
1711
-
1712
-            if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1713
-                $sidebar_form_fields['ee-msg-template-switch'] = array(
1714
-                    'name'  => 'template_switch',
1715
-                    'input' => 'hidden',
1716
-                    'type'  => 'int',
1717
-                    'value' => 1,
1718
-                );
1719
-            }
1720
-
1721
-
1722
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1723
-            $sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1724
-        } //end if ( !empty($template_field_structure) )
1725
-
1726
-        // set extra content for publish box
1727
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1728
-        $this->_set_publish_post_box_vars(
1729
-            'id',
1730
-            $GRP_ID,
1731
-            false,
1732
-            add_query_arg(
1733
-                array('action' => 'global_mtps'),
1734
-                $this->_admin_base_url
1735
-            )
1736
-        );
1737
-
1738
-        // add preview button
1739
-        $preview_url = parent::add_query_args_and_nonce(
1740
-            array(
1741
-                'message_type' => $message_template_group->message_type(),
1742
-                'messenger'    => $message_template_group->messenger(),
1743
-                'context'      => $context,
1744
-                'GRP_ID'       => $GRP_ID,
1745
-                'evt_id'       => $EVT_ID,
1746
-                'action'       => 'preview_message',
1747
-            ),
1748
-            $this->_admin_base_url
1749
-        );
1750
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1751
-                          . esc_html__('Preview', 'event_espresso')
1752
-                          . '</a>';
1753
-
1754
-
1755
-        // setup context switcher
1756
-        $context_switcher_args = array(
1757
-            'page'    => 'espresso_messages',
1758
-            'action'  => 'edit_message_template',
1759
-            'id'      => $GRP_ID,
1760
-            'evt_id'  => $EVT_ID,
1761
-            'context' => $context,
1762
-            'extra'   => $preview_button,
1763
-        );
1764
-        $this->_set_context_switcher($message_template_group, $context_switcher_args);
1765
-
1766
-
1767
-        // main box
1768
-        $this->_template_args['template_fields'] = $template_fields;
1769
-        $this->_template_args['sidebar_box_id'] = 'details';
1770
-        $this->_template_args['action'] = $action;
1771
-        $this->_template_args['context'] = $context;
1772
-        $this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1773
-        $this->_template_args['learn_more_about_message_templates_link'] =
1774
-            $this->_learn_more_about_message_templates_link();
1775
-
1776
-
1777
-        $this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1778
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1779
-            $message_template_group,
1780
-            $context,
1781
-            $context_label
1782
-        );
1783
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1784
-        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1785
-
1786
-        $this->_template_path = $this->_template_args['GRP_ID']
1787
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1788
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1789
-
1790
-        // send along EE_Message_Template_Group object for further template use.
1791
-        $this->_template_args['MTP'] = $message_template_group;
1792
-
1793
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1794
-            $this->_template_path,
1795
-            $this->_template_args,
1796
-            true
1797
-        );
1798
-
1799
-
1800
-        // finally, let's set the admin_page title
1801
-        $this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1802
-
1803
-
1804
-        // we need to take care of setting the shortcodes property for use elsewhere.
1805
-        $this->_set_shortcodes();
1806
-
1807
-
1808
-        // final template wrapper
1809
-        $this->display_admin_page_with_sidebar();
1810
-    }
1811
-
1812
-
1813
-    public function filter_tinymce_init($mceInit, $editor_id)
1814
-    {
1815
-        return $mceInit;
1816
-    }
1817
-
1818
-
1819
-    public function add_context_switcher()
1820
-    {
1821
-        return $this->_context_switcher;
1822
-    }
1823
-
1824
-
1825
-    /**
1826
-     * Adds the activation/deactivation toggle for the message template context.
1827
-     *
1828
-     * @param EE_Message_Template_Group $message_template_group
1829
-     * @param string                    $context
1830
-     * @param string                    $context_label
1831
-     * @return string
1832
-     * @throws DomainException
1833
-     * @throws EE_Error
1834
-     * @throws InvalidIdentifierException
1835
-     */
1836
-    protected function add_active_context_element(
1837
-        EE_Message_Template_Group $message_template_group,
1838
-        $context,
1839
-        $context_label
1840
-    ) {
1841
-        $template_args = array(
1842
-            'context'                   => $context,
1843
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1844
-            'is_active'                 => $message_template_group->is_context_active($context),
1845
-            'on_off_action'             => $message_template_group->is_context_active($context)
1846
-                ? 'context-off'
1847
-                : 'context-on',
1848
-            'context_label'             => str_replace(array('(', ')'), '', $context_label),
1849
-            'message_template_group_id' => $message_template_group->ID(),
1850
-        );
1851
-        return EEH_Template::display_template(
1852
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1853
-            $template_args,
1854
-            true
1855
-        );
1856
-    }
1857
-
1858
-
1859
-    /**
1860
-     * Ajax callback for `toggle_context_template` ajax action.
1861
-     * Handles toggling the message context on or off.
1862
-     *
1863
-     * @throws EE_Error
1864
-     * @throws InvalidArgumentException
1865
-     * @throws InvalidDataTypeException
1866
-     * @throws InvalidIdentifierException
1867
-     * @throws InvalidInterfaceException
1868
-     */
1869
-    public function toggle_context_template()
1870
-    {
1871
-        $success = true;
1872
-        // check for required data
1873
-        if (! isset(
1874
-            $this->_req_data['message_template_group_id'],
1875
-            $this->_req_data['context'],
1876
-            $this->_req_data['status']
1877
-        )) {
1878
-            EE_Error::add_error(
1879
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1880
-                __FILE__,
1881
-                __FUNCTION__,
1882
-                __LINE__
1883
-            );
1884
-            $success = false;
1885
-        }
1886
-
1887
-        $nonce = isset($this->_req_data['toggle_context_nonce'])
1888
-            ? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1889
-            : '';
1890
-        $nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1891
-        $this->_verify_nonce($nonce, $nonce_ref);
1892
-        $status = $this->_req_data['status'];
1893
-        if ($status !== 'off' && $status !== 'on') {
1894
-            EE_Error::add_error(
1895
-                sprintf(
1896
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1897
-                    $this->_req_data['status']
1898
-                ),
1899
-                __FILE__,
1900
-                __FUNCTION__,
1901
-                __LINE__
1902
-            );
1903
-            $success = false;
1904
-        }
1905
-        $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1906
-            $this->_req_data['message_template_group_id']
1907
-        );
1908
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1909
-            EE_Error::add_error(
1910
-                sprintf(
1911
-                    esc_html__(
1912
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1913
-                        'event_espresso'
1914
-                    ),
1915
-                    $this->_req_data['message_template_group_id'],
1916
-                    'EE_Message_Template_Group'
1917
-                ),
1918
-                __FILE__,
1919
-                __FUNCTION__,
1920
-                __LINE__
1921
-            );
1922
-            $success = false;
1923
-        }
1924
-        if ($success) {
1925
-            $success = $status === 'off'
1926
-                ? $message_template_group->deactivate_context($this->_req_data['context'])
1927
-                : $message_template_group->activate_context($this->_req_data['context']);
1928
-        }
1929
-        $this->_template_args['success'] = $success;
1930
-        $this->_return_json();
1931
-    }
1932
-
1933
-
1934
-    public function _add_form_element_before()
1935
-    {
1936
-        return '<form method="post" action="'
1937
-               . $this->_template_args["edit_message_template_form_url"]
1938
-               . '" id="ee-msg-edit-frm">';
1939
-    }
1940
-
1941
-    public function _add_form_element_after()
1942
-    {
1943
-        return '</form>';
1944
-    }
1945
-
1946
-
1947
-    /**
1948
-     * This executes switching the template pack for a message template.
1949
-     *
1950
-     * @since 4.5.0
1951
-     * @throws EE_Error
1952
-     * @throws InvalidDataTypeException
1953
-     * @throws InvalidInterfaceException
1954
-     * @throws InvalidArgumentException
1955
-     * @throws ReflectionException
1956
-     */
1957
-    public function switch_template_pack()
1958
-    {
1959
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1960
-        $template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1961
-
1962
-        // verify we have needed values.
1963
-        if (empty($GRP_ID) || empty($template_pack)) {
1964
-            $this->_template_args['error'] = true;
1965
-            EE_Error::add_error(
1966
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1967
-                __FILE__,
1968
-                __FUNCTION__,
1969
-                __LINE__
1970
-            );
1971
-        } else {
1972
-            // get template, set the new template_pack and then reset to default
1973
-            /** @type EE_Message_Template_Group $message_template_group */
1974
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1975
-
1976
-            $message_template_group->set_template_pack_name($template_pack);
1977
-            $this->_req_data['msgr'] = $message_template_group->messenger();
1978
-            $this->_req_data['mt'] = $message_template_group->message_type();
1979
-
1980
-            $query_args = $this->_reset_to_default_template();
1981
-
1982
-            if (empty($query_args['id'])) {
1983
-                EE_Error::add_error(
1984
-                    esc_html__(
1985
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
1986
-                        'event_espresso'
1987
-                    ),
1988
-                    __FILE__,
1989
-                    __FUNCTION__,
1990
-                    __LINE__
1991
-                );
1992
-                $this->_template_args['error'] = true;
1993
-            } else {
1994
-                $template_label = $message_template_group->get_template_pack()->label;
1995
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1996
-                EE_Error::add_success(
1997
-                    sprintf(
1998
-                        esc_html__(
1999
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2000
-                            'event_espresso'
2001
-                        ),
2002
-                        $template_label,
2003
-                        $template_pack_labels->template_pack
2004
-                    )
2005
-                );
2006
-                // generate the redirect url for js.
2007
-                $url = self::add_query_args_and_nonce(
2008
-                    $query_args,
2009
-                    $this->_admin_base_url
2010
-                );
2011
-                $this->_template_args['data']['redirect_url'] = $url;
2012
-                $this->_template_args['success'] = true;
2013
-            }
2014
-
2015
-            $this->_return_json();
2016
-        }
2017
-    }
2018
-
2019
-
2020
-    /**
2021
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2022
-     * they want.
2023
-     *
2024
-     * @access protected
2025
-     * @return array|null
2026
-     * @throws EE_Error
2027
-     * @throws InvalidArgumentException
2028
-     * @throws InvalidDataTypeException
2029
-     * @throws InvalidInterfaceException
2030
-     */
2031
-    protected function _reset_to_default_template()
2032
-    {
2033
-
2034
-        $templates = array();
2035
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2036
-        // we need to make sure we've got the info we need.
2037
-        if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2038
-            EE_Error::add_error(
2039
-                esc_html__(
2040
-                    '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.',
2041
-                    'event_espresso'
2042
-                ),
2043
-                __FILE__,
2044
-                __FUNCTION__,
2045
-                __LINE__
2046
-            );
2047
-        }
2048
-
2049
-        // all templates will be reset to whatever the defaults are
2050
-        // for the global template matching the messenger and message type.
2051
-        $success = ! empty($GRP_ID) ? true : false;
2052
-
2053
-        if ($success) {
2054
-            // let's first determine if the incoming template is a global template,
2055
-            // if it isn't then we need to get the global template matching messenger and message type.
2056
-            // $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2057
-
2058
-
2059
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2060
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
2061
-
2062
-            if ($success) {
2063
-                // if successfully deleted, lets generate the new ones.
2064
-                // Note. We set GLOBAL to true, because resets on ANY template
2065
-                // will use the related global template defaults for regeneration.
2066
-                // This means that if a custom template is reset it resets to whatever the related global template is.
2067
-                // HOWEVER, we DO keep the template pack and template variation set
2068
-                // for the current custom template when resetting.
2069
-                $templates = $this->_generate_new_templates(
2070
-                    $this->_req_data['msgr'],
2071
-                    $this->_req_data['mt'],
2072
-                    $GRP_ID,
2073
-                    true
2074
-                );
2075
-            }
2076
-        }
2077
-
2078
-        // any error messages?
2079
-        if (! $success) {
2080
-            EE_Error::add_error(
2081
-                esc_html__(
2082
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
2083
-                    'event_espresso'
2084
-                ),
2085
-                __FILE__,
2086
-                __FUNCTION__,
2087
-                __LINE__
2088
-            );
2089
-        }
2090
-
2091
-        // all good, let's add a success message!
2092
-        if ($success && ! empty($templates)) {
2093
-            // the info for the template we generated is the first element in the returned array
2094
-            // $templates = $templates[0];
2095
-            EE_Error::overwrite_success();
2096
-            EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2097
-        }
2098
-
2099
-
2100
-        $query_args = array(
2101
-            'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2102
-            'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2103
-            'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2104
-        );
2105
-
2106
-        // if called via ajax then we return query args otherwise redirect
2107
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2108
-            return $query_args;
2109
-        } else {
2110
-            $this->_redirect_after_action(false, '', '', $query_args, true);
2111
-
2112
-            return null;
2113
-        }
2114
-    }
2115
-
2116
-
2117
-    /**
2118
-     * Retrieve and set the message preview for display.
2119
-     *
2120
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2121
-     * @return string
2122
-     * @throws ReflectionException
2123
-     * @throws EE_Error
2124
-     * @throws InvalidArgumentException
2125
-     * @throws InvalidDataTypeException
2126
-     * @throws InvalidInterfaceException
2127
-     */
2128
-    public function _preview_message($send = false)
2129
-    {
2130
-        // first make sure we've got the necessary parameters
2131
-        if (! isset(
2132
-            $this->_req_data['message_type'],
2133
-            $this->_req_data['messenger'],
2134
-            $this->_req_data['messenger'],
2135
-            $this->_req_data['GRP_ID']
2136
-        )) {
2137
-            EE_Error::add_error(
2138
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2139
-                __FILE__,
2140
-                __FUNCTION__,
2141
-                __LINE__
2142
-            );
2143
-        }
2144
-
2145
-        EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
22
+	/**
23
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
24
+	 */
25
+	protected $_message_resource_manager;
26
+
27
+	/**
28
+	 * @type string $_active_message_type_name
29
+	 */
30
+	protected $_active_message_type_name = '';
31
+
32
+	/**
33
+	 * @type EE_messenger $_active_messenger
34
+	 */
35
+	protected $_active_messenger;
36
+	protected $_activate_state;
37
+	protected $_activate_meta_box_type;
38
+	protected $_current_message_meta_box;
39
+	protected $_current_message_meta_box_object;
40
+	protected $_context_switcher;
41
+	protected $_shortcodes = array();
42
+	protected $_active_messengers = array();
43
+	protected $_active_message_types = array();
44
+
45
+	/**
46
+	 * @var EE_Message_Template_Group $_message_template_group
47
+	 */
48
+	protected $_message_template_group;
49
+	protected $_m_mt_settings = array();
50
+
51
+
52
+	/**
53
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
+	 * IF there is no group then it gets automatically set to the Default template pack.
55
+	 *
56
+	 * @since 4.5.0
57
+	 *
58
+	 * @var EE_Messages_Template_Pack
59
+	 */
60
+	protected $_template_pack;
61
+
62
+
63
+	/**
64
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
+	 * group is.  If there is no group then it automatically gets set to default.
66
+	 *
67
+	 * @since 4.5.0
68
+	 *
69
+	 * @var string
70
+	 */
71
+	protected $_variation;
72
+
73
+
74
+	/**
75
+	 * @param bool $routing
76
+	 * @throws EE_Error
77
+	 */
78
+	public function __construct($routing = true)
79
+	{
80
+		// make sure messages autoloader is running
81
+		EED_Messages::set_autoloaders();
82
+		parent::__construct($routing);
83
+	}
84
+
85
+
86
+	protected function _init_page_props()
87
+	{
88
+		$this->page_slug = EE_MSG_PG_SLUG;
89
+		$this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
+		$this->_admin_base_url = EE_MSG_ADMIN_URL;
91
+		$this->_admin_base_path = EE_MSG_ADMIN;
92
+
93
+		$this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
+			: array();
95
+
96
+		$this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
+		$this->_load_message_resource_manager();
98
+	}
99
+
100
+
101
+	/**
102
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
+	 *
104
+	 * @throws EE_Error
105
+	 * @throws InvalidDataTypeException
106
+	 * @throws InvalidInterfaceException
107
+	 * @throws InvalidArgumentException
108
+	 * @throws ReflectionException
109
+	 */
110
+	protected function _load_message_resource_manager()
111
+	{
112
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
+	}
114
+
115
+
116
+	/**
117
+	 * @deprecated 4.9.9.rc.014
118
+	 * @return array
119
+	 * @throws EE_Error
120
+	 * @throws InvalidArgumentException
121
+	 * @throws InvalidDataTypeException
122
+	 * @throws InvalidInterfaceException
123
+	 */
124
+	public function get_messengers_for_list_table()
125
+	{
126
+		EE_Error::doing_it_wrong(
127
+			__METHOD__,
128
+			sprintf(
129
+				esc_html__(
130
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
131
+					'event_espresso'
132
+				),
133
+				'Messages_Admin_Page::get_messengers_select_input()'
134
+			),
135
+			'4.9.9.rc.014'
136
+		);
137
+
138
+		$m_values = array();
139
+		$active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
+		// setup messengers for selects
141
+		$i = 1;
142
+		foreach ($active_messengers as $active_messenger) {
143
+			if ($active_messenger instanceof EE_Message) {
144
+				$m_values[ $i ]['id'] = $active_messenger->messenger();
145
+				$m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
+				$i++;
147
+			}
148
+		}
149
+
150
+		return $m_values;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @deprecated 4.9.9.rc.014
156
+	 * @return array
157
+	 * @throws EE_Error
158
+	 * @throws InvalidArgumentException
159
+	 * @throws InvalidDataTypeException
160
+	 * @throws InvalidInterfaceException
161
+	 */
162
+	public function get_message_types_for_list_table()
163
+	{
164
+		EE_Error::doing_it_wrong(
165
+			__METHOD__,
166
+			sprintf(
167
+				esc_html__(
168
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
169
+					'event_espresso'
170
+				),
171
+				'Messages_Admin_Page::get_message_types_select_input()'
172
+			),
173
+			'4.9.9.rc.014'
174
+		);
175
+
176
+		$mt_values = array();
177
+		$active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
+		$i = 1;
179
+		foreach ($active_messages as $active_message) {
180
+			if ($active_message instanceof EE_Message) {
181
+				$mt_values[ $i ]['id'] = $active_message->message_type();
182
+				$mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
+				$i++;
184
+			}
185
+		}
186
+
187
+		return $mt_values;
188
+	}
189
+
190
+
191
+	/**
192
+	 * @deprecated 4.9.9.rc.014
193
+	 * @return array
194
+	 * @throws EE_Error
195
+	 * @throws InvalidArgumentException
196
+	 * @throws InvalidDataTypeException
197
+	 * @throws InvalidInterfaceException
198
+	 */
199
+	public function get_contexts_for_message_types_for_list_table()
200
+	{
201
+		EE_Error::doing_it_wrong(
202
+			__METHOD__,
203
+			sprintf(
204
+				esc_html__(
205
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
206
+					'event_espresso'
207
+				),
208
+				'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
+			),
210
+			'4.9.9.rc.014'
211
+		);
212
+
213
+		$contexts = array();
214
+		$active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
+		foreach ($active_message_contexts as $active_message) {
216
+			if ($active_message instanceof EE_Message) {
217
+				$message_type = $active_message->message_type_object();
218
+				if ($message_type instanceof EE_message_type) {
219
+					$message_type_contexts = $message_type->get_contexts();
220
+					foreach ($message_type_contexts as $context => $context_details) {
221
+						$contexts[ $context ] = $context_details['label'];
222
+					}
223
+				}
224
+			}
225
+		}
226
+
227
+		return $contexts;
228
+	}
229
+
230
+
231
+	/**
232
+	 * Generate select input with provided messenger options array.
233
+	 *
234
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
+	 *                                 labels.
236
+	 * @return string
237
+	 * @throws EE_Error
238
+	 */
239
+	public function get_messengers_select_input($messenger_options)
240
+	{
241
+		// if empty or just one value then just return an empty string
242
+		if (empty($messenger_options)
243
+			|| ! is_array($messenger_options)
244
+			|| count($messenger_options) === 1
245
+		) {
246
+			return '';
247
+		}
248
+		// merge in default
249
+		$messenger_options = array_merge(
250
+			array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
251
+			$messenger_options
252
+		);
253
+		$input = new EE_Select_Input(
254
+			$messenger_options,
255
+			array(
256
+				'html_name'  => 'ee_messenger_filter_by',
257
+				'html_id'    => 'ee_messenger_filter_by',
258
+				'html_class' => 'wide',
259
+				'default'    => isset($this->_req_data['ee_messenger_filter_by'])
260
+					? sanitize_title($this->_req_data['ee_messenger_filter_by'])
261
+					: 'none_selected',
262
+			)
263
+		);
264
+
265
+		return $input->get_html_for_input();
266
+	}
267
+
268
+
269
+	/**
270
+	 * Generate select input with provided message type options array.
271
+	 *
272
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
273
+	 *                                    message type labels
274
+	 * @return string
275
+	 * @throws EE_Error
276
+	 */
277
+	public function get_message_types_select_input($message_type_options)
278
+	{
279
+		// if empty or count of options is 1 then just return an empty string
280
+		if (empty($message_type_options)
281
+			|| ! is_array($message_type_options)
282
+			|| count($message_type_options) === 1
283
+		) {
284
+			return '';
285
+		}
286
+		// merge in default
287
+		$message_type_options = array_merge(
288
+			array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
289
+			$message_type_options
290
+		);
291
+		$input = new EE_Select_Input(
292
+			$message_type_options,
293
+			array(
294
+				'html_name'  => 'ee_message_type_filter_by',
295
+				'html_id'    => 'ee_message_type_filter_by',
296
+				'html_class' => 'wide',
297
+				'default'    => isset($this->_req_data['ee_message_type_filter_by'])
298
+					? sanitize_title($this->_req_data['ee_message_type_filter_by'])
299
+					: 'none_selected',
300
+			)
301
+		);
302
+
303
+		return $input->get_html_for_input();
304
+	}
305
+
306
+
307
+	/**
308
+	 * Generate select input with provide message type contexts array.
309
+	 *
310
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
311
+	 *                               context label.
312
+	 * @return string
313
+	 * @throws EE_Error
314
+	 */
315
+	public function get_contexts_for_message_types_select_input($context_options)
316
+	{
317
+		// if empty or count of options is one then just return empty string
318
+		if (empty($context_options)
319
+			|| ! is_array($context_options)
320
+			|| count($context_options) === 1
321
+		) {
322
+			return '';
323
+		}
324
+		// merge in default
325
+		$context_options = array_merge(
326
+			array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
327
+			$context_options
328
+		);
329
+		$input = new EE_Select_Input(
330
+			$context_options,
331
+			array(
332
+				'html_name'  => 'ee_context_filter_by',
333
+				'html_id'    => 'ee_context_filter_by',
334
+				'html_class' => 'wide',
335
+				'default'    => isset($this->_req_data['ee_context_filter_by'])
336
+					? sanitize_title($this->_req_data['ee_context_filter_by'])
337
+					: 'none_selected',
338
+			)
339
+		);
340
+
341
+		return $input->get_html_for_input();
342
+	}
343
+
344
+
345
+	protected function _ajax_hooks()
346
+	{
347
+		add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
348
+		add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
349
+		add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
350
+		add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
351
+		add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
352
+		add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
353
+	}
354
+
355
+
356
+	protected function _define_page_props()
357
+	{
358
+		$this->_admin_page_title = $this->page_label;
359
+		$this->_labels = array(
360
+			'buttons'    => array(
361
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
362
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
363
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
364
+			),
365
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
366
+		);
367
+	}
368
+
369
+
370
+	/**
371
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
372
+	 *
373
+	 * @access protected
374
+	 * @return void
375
+	 */
376
+	protected function _set_page_routes()
377
+	{
378
+		$grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
379
+			? $this->_req_data['GRP_ID']
380
+			: 0;
381
+		$grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
382
+			? $this->_req_data['id']
383
+			: $grp_id;
384
+		$msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
385
+			? $this->_req_data['MSG_ID']
386
+			: 0;
387
+
388
+		$this->_page_routes = array(
389
+			'default'                          => array(
390
+				'func'       => '_message_queue_list_table',
391
+				'capability' => 'ee_read_global_messages',
392
+			),
393
+			'global_mtps'                      => array(
394
+				'func'       => '_ee_default_messages_overview_list_table',
395
+				'capability' => 'ee_read_global_messages',
396
+			),
397
+			'custom_mtps'                      => array(
398
+				'func'       => '_custom_mtps_preview',
399
+				'capability' => 'ee_read_messages',
400
+			),
401
+			'add_new_message_template'         => array(
402
+				'func'       => '_add_message_template',
403
+				'capability' => 'ee_edit_messages',
404
+				'noheader'   => true,
405
+			),
406
+			'edit_message_template'            => array(
407
+				'func'       => '_edit_message_template',
408
+				'capability' => 'ee_edit_message',
409
+				'obj_id'     => $grp_id,
410
+			),
411
+			'preview_message'                  => array(
412
+				'func'               => '_preview_message',
413
+				'capability'         => 'ee_read_message',
414
+				'obj_id'             => $grp_id,
415
+				'noheader'           => true,
416
+				'headers_sent_route' => 'display_preview_message',
417
+			),
418
+			'display_preview_message'          => array(
419
+				'func'       => '_display_preview_message',
420
+				'capability' => 'ee_read_message',
421
+				'obj_id'     => $grp_id,
422
+			),
423
+			'insert_message_template'          => array(
424
+				'func'       => '_insert_or_update_message_template',
425
+				'capability' => 'ee_edit_messages',
426
+				'args'       => array('new_template' => true),
427
+				'noheader'   => true,
428
+			),
429
+			'update_message_template'          => array(
430
+				'func'       => '_insert_or_update_message_template',
431
+				'capability' => 'ee_edit_message',
432
+				'obj_id'     => $grp_id,
433
+				'args'       => array('new_template' => false),
434
+				'noheader'   => true,
435
+			),
436
+			'trash_message_template'           => array(
437
+				'func'       => '_trash_or_restore_message_template',
438
+				'capability' => 'ee_delete_message',
439
+				'obj_id'     => $grp_id,
440
+				'args'       => array('trash' => true, 'all' => true),
441
+				'noheader'   => true,
442
+			),
443
+			'trash_message_template_context'   => array(
444
+				'func'       => '_trash_or_restore_message_template',
445
+				'capability' => 'ee_delete_message',
446
+				'obj_id'     => $grp_id,
447
+				'args'       => array('trash' => true),
448
+				'noheader'   => true,
449
+			),
450
+			'restore_message_template'         => array(
451
+				'func'       => '_trash_or_restore_message_template',
452
+				'capability' => 'ee_delete_message',
453
+				'obj_id'     => $grp_id,
454
+				'args'       => array('trash' => false, 'all' => true),
455
+				'noheader'   => true,
456
+			),
457
+			'restore_message_template_context' => array(
458
+				'func'       => '_trash_or_restore_message_template',
459
+				'capability' => 'ee_delete_message',
460
+				'obj_id'     => $grp_id,
461
+				'args'       => array('trash' => false),
462
+				'noheader'   => true,
463
+			),
464
+			'delete_message_template'          => array(
465
+				'func'       => '_delete_message_template',
466
+				'capability' => 'ee_delete_message',
467
+				'obj_id'     => $grp_id,
468
+				'noheader'   => true,
469
+			),
470
+			'reset_to_default'                 => array(
471
+				'func'       => '_reset_to_default_template',
472
+				'capability' => 'ee_edit_message',
473
+				'obj_id'     => $grp_id,
474
+				'noheader'   => true,
475
+			),
476
+			'settings'                         => array(
477
+				'func'       => '_settings',
478
+				'capability' => 'manage_options',
479
+			),
480
+			'update_global_settings'           => array(
481
+				'func'       => '_update_global_settings',
482
+				'capability' => 'manage_options',
483
+				'noheader'   => true,
484
+			),
485
+			'generate_now'                     => array(
486
+				'func'       => '_generate_now',
487
+				'capability' => 'ee_send_message',
488
+				'noheader'   => true,
489
+			),
490
+			'generate_and_send_now'            => array(
491
+				'func'       => '_generate_and_send_now',
492
+				'capability' => 'ee_send_message',
493
+				'noheader'   => true,
494
+			),
495
+			'queue_for_resending'              => array(
496
+				'func'       => '_queue_for_resending',
497
+				'capability' => 'ee_send_message',
498
+				'noheader'   => true,
499
+			),
500
+			'send_now'                         => array(
501
+				'func'       => '_send_now',
502
+				'capability' => 'ee_send_message',
503
+				'noheader'   => true,
504
+			),
505
+			'delete_ee_message'                => array(
506
+				'func'       => '_delete_ee_messages',
507
+				'capability' => 'ee_delete_messages',
508
+				'noheader'   => true,
509
+			),
510
+			'delete_ee_messages'               => array(
511
+				'func'       => '_delete_ee_messages',
512
+				'capability' => 'ee_delete_messages',
513
+				'noheader'   => true,
514
+				'obj_id'     => $msg_id,
515
+			),
516
+		);
517
+	}
518
+
519
+
520
+	protected function _set_page_config()
521
+	{
522
+		$this->_page_config = array(
523
+			'default'                  => array(
524
+				'nav'           => array(
525
+					'label' => esc_html__('Message Activity', 'event_espresso'),
526
+					'order' => 10,
527
+				),
528
+				'list_table'    => 'EE_Message_List_Table',
529
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
530
+				'require_nonce' => false,
531
+			),
532
+			'global_mtps'              => array(
533
+				'nav'           => array(
534
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
535
+					'order' => 20,
536
+				),
537
+				'list_table'    => 'Messages_Template_List_Table',
538
+				'help_tabs'     => array(
539
+					'messages_overview_help_tab'                                => array(
540
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
541
+						'filename' => 'messages_overview',
542
+					),
543
+					'messages_overview_messages_table_column_headings_help_tab' => array(
544
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
545
+						'filename' => 'messages_overview_table_column_headings',
546
+					),
547
+					'messages_overview_messages_filters_help_tab'               => array(
548
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
549
+						'filename' => 'messages_overview_filters',
550
+					),
551
+					'messages_overview_messages_views_help_tab'                 => array(
552
+						'title'    => esc_html__('Message Views', 'event_espresso'),
553
+						'filename' => 'messages_overview_views',
554
+					),
555
+					'message_overview_message_types_help_tab'                   => array(
556
+						'title'    => esc_html__('Message Types', 'event_espresso'),
557
+						'filename' => 'messages_overview_types',
558
+					),
559
+					'messages_overview_messengers_help_tab'                     => array(
560
+						'title'    => esc_html__('Messengers', 'event_espresso'),
561
+						'filename' => 'messages_overview_messengers',
562
+					),
563
+				),
564
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
565
+				// 'help_tour'     => array('Messages_Overview_Help_Tour'),
566
+				'require_nonce' => false,
567
+			),
568
+			'custom_mtps'              => array(
569
+				'nav'           => array(
570
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
571
+					'order' => 30,
572
+				),
573
+				'help_tabs'     => array(),
574
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
575
+				// 'help_tour'     => array(),
576
+				'require_nonce' => false,
577
+			),
578
+			'add_new_message_template' => array(
579
+				'nav'           => array(
580
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
581
+					'order'      => 5,
582
+					'persistent' => false,
583
+				),
584
+				'require_nonce' => false,
585
+			),
586
+			'edit_message_template'    => array(
587
+				'labels'        => array(
588
+					'buttons'    => array(
589
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
590
+					),
591
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
592
+				),
593
+				'nav'           => array(
594
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
595
+					'order'      => 5,
596
+					'persistent' => false,
597
+					'url'        => '',
598
+				),
599
+				'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
600
+				'has_metaboxes' => true,
601
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
602
+				// 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
603
+				'help_tabs'     => array(
604
+					'edit_message_template'            => array(
605
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
606
+						'callback' => 'edit_message_template_help_tab',
607
+					),
608
+					'message_templates_help_tab'       => array(
609
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
610
+						'filename' => 'messages_templates',
611
+					),
612
+					'message_template_shortcodes'      => array(
613
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
614
+						'callback' => 'message_template_shortcodes_help_tab',
615
+					),
616
+					'message_preview_help_tab'         => array(
617
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
618
+						'filename' => 'messages_preview',
619
+					),
620
+					'messages_overview_other_help_tab' => array(
621
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
622
+						'filename' => 'messages_overview_other',
623
+					),
624
+				),
625
+				'require_nonce' => false,
626
+			),
627
+			'display_preview_message'  => array(
628
+				'nav'           => array(
629
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
630
+					'order'      => 5,
631
+					'url'        => '',
632
+					'persistent' => false,
633
+				),
634
+				'help_tabs'     => array(
635
+					'preview_message' => array(
636
+						'title'    => esc_html__('About Previews', 'event_espresso'),
637
+						'callback' => 'preview_message_help_tab',
638
+					),
639
+				),
640
+				'require_nonce' => false,
641
+			),
642
+			'settings'                 => array(
643
+				'nav'           => array(
644
+					'label' => esc_html__('Settings', 'event_espresso'),
645
+					'order' => 40,
646
+				),
647
+				'metaboxes'     => array('_messages_settings_metaboxes'),
648
+				'help_tabs'     => array(
649
+					'messages_settings_help_tab'               => array(
650
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
651
+						'filename' => 'messages_settings',
652
+					),
653
+					'messages_settings_message_types_help_tab' => array(
654
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
655
+						'filename' => 'messages_settings_message_types',
656
+					),
657
+					'messages_settings_messengers_help_tab'    => array(
658
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
659
+						'filename' => 'messages_settings_messengers',
660
+					),
661
+				),
662
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
663
+				// 'help_tour'     => array('Messages_Settings_Help_Tour'),
664
+				'require_nonce' => false,
665
+			),
666
+		);
667
+	}
668
+
669
+
670
+	protected function _add_screen_options()
671
+	{
672
+		// todo
673
+	}
674
+
675
+
676
+	protected function _add_screen_options_global_mtps()
677
+	{
678
+		/**
679
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
680
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
681
+		 */
682
+		$page_title = $this->_admin_page_title;
683
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
684
+		$this->_per_page_screen_option();
685
+		$this->_admin_page_title = $page_title;
686
+	}
687
+
688
+
689
+	protected function _add_screen_options_default()
690
+	{
691
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
692
+		$this->_per_page_screen_option();
693
+	}
694
+
695
+
696
+	// none of the below group are currently used for Messages
697
+	protected function _add_feature_pointers()
698
+	{
699
+	}
700
+
701
+	public function admin_init()
702
+	{
703
+	}
704
+
705
+	public function admin_notices()
706
+	{
707
+	}
708
+
709
+	public function admin_footer_scripts()
710
+	{
711
+	}
712
+
713
+
714
+	public function messages_help_tab()
715
+	{
716
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
717
+	}
718
+
719
+
720
+	public function messengers_help_tab()
721
+	{
722
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
723
+	}
724
+
725
+
726
+	public function message_types_help_tab()
727
+	{
728
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
729
+	}
730
+
731
+
732
+	public function messages_overview_help_tab()
733
+	{
734
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
735
+	}
736
+
737
+
738
+	public function message_templates_help_tab()
739
+	{
740
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
741
+	}
742
+
743
+
744
+	public function edit_message_template_help_tab()
745
+	{
746
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
747
+						. esc_attr__('Editor Title', 'event_espresso')
748
+						. '" />';
749
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
750
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
751
+						. '" />';
752
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
753
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
754
+						. '" />';
755
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
756
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
757
+						. '" />';
758
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
759
+						. esc_attr__('Publish Metabox', 'event_espresso')
760
+						. '" />';
761
+		EEH_Template::display_template(
762
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
763
+			$args
764
+		);
765
+	}
766
+
767
+
768
+	public function message_template_shortcodes_help_tab()
769
+	{
770
+		$this->_set_shortcodes();
771
+		$args['shortcodes'] = $this->_shortcodes;
772
+		EEH_Template::display_template(
773
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
774
+			$args
775
+		);
776
+	}
777
+
778
+
779
+	public function preview_message_help_tab()
780
+	{
781
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
782
+	}
783
+
784
+
785
+	public function settings_help_tab()
786
+	{
787
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
788
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
789
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
790
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
791
+		$args['img3'] = '<div class="switch">'
792
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
793
+						. ' type="checkbox" checked="checked">'
794
+						. '<label for="ee-on-off-toggle-on"></label>'
795
+						. '</div>';
796
+		$args['img4'] = '<div class="switch">'
797
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
798
+						. ' type="checkbox">'
799
+						. '<label for="ee-on-off-toggle-on"></label>'
800
+						. '</div>';
801
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
802
+	}
803
+
804
+
805
+	public function load_scripts_styles()
806
+	{
807
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
808
+		wp_enqueue_style('espresso_ee_msg');
809
+
810
+		wp_register_script(
811
+			'ee-messages-settings',
812
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
813
+			array('jquery-ui-droppable', 'ee-serialize-full-array'),
814
+			EVENT_ESPRESSO_VERSION,
815
+			true
816
+		);
817
+		wp_register_script(
818
+			'ee-msg-list-table-js',
819
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
820
+			array('ee-dialog'),
821
+			EVENT_ESPRESSO_VERSION
822
+		);
823
+	}
824
+
825
+
826
+	public function load_scripts_styles_default()
827
+	{
828
+		wp_enqueue_script('ee-msg-list-table-js');
829
+	}
830
+
831
+
832
+	public function wp_editor_css($mce_css)
833
+	{
834
+		// if we're on the edit_message_template route
835
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
836
+			$message_type_name = $this->_active_message_type_name;
837
+
838
+			// we're going to REPLACE the existing mce css
839
+			// we need to get the css file location from the active messenger
840
+			$mce_css = $this->_active_messenger->get_variation(
841
+				$this->_template_pack,
842
+				$message_type_name,
843
+				true,
844
+				'wpeditor',
845
+				$this->_variation
846
+			);
847
+		}
848
+
849
+		return $mce_css;
850
+	}
851
+
852
+
853
+	public function load_scripts_styles_edit_message_template()
854
+	{
855
+
856
+		$this->_set_shortcodes();
857
+
858
+		EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
859
+			esc_html__(
860
+				'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.',
861
+				'event_espresso'
862
+			),
863
+			$this->_message_template_group->messenger_obj()->label['singular'],
864
+			$this->_message_template_group->message_type_obj()->label['singular']
865
+		);
866
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
867
+			'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?',
868
+			'event_espresso'
869
+		);
870
+		EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
871
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
872
+			'event_espresso'
873
+		);
874
+
875
+		wp_register_script(
876
+			'ee_msgs_edit_js',
877
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
878
+			array('jquery'),
879
+			EVENT_ESPRESSO_VERSION
880
+		);
881
+
882
+		wp_enqueue_script('ee_admin_js');
883
+		wp_enqueue_script('ee_msgs_edit_js');
884
+
885
+		// add in special css for tiny_mce
886
+		add_filter('mce_css', array($this, 'wp_editor_css'));
887
+	}
888
+
889
+
890
+	public function load_scripts_styles_display_preview_message()
891
+	{
892
+
893
+		$this->_set_message_template_group();
894
+
895
+		if (isset($this->_req_data['messenger'])) {
896
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
897
+				$this->_req_data['messenger']
898
+			);
899
+		}
900
+
901
+		$message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
902
+
903
+
904
+		wp_enqueue_style(
905
+			'espresso_preview_css',
906
+			$this->_active_messenger->get_variation(
907
+				$this->_template_pack,
908
+				$message_type_name,
909
+				true,
910
+				'preview',
911
+				$this->_variation
912
+			)
913
+		);
914
+	}
915
+
916
+
917
+	public function load_scripts_styles_settings()
918
+	{
919
+		wp_register_style(
920
+			'ee-message-settings',
921
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
922
+			array(),
923
+			EVENT_ESPRESSO_VERSION
924
+		);
925
+		wp_enqueue_style('ee-text-links');
926
+		wp_enqueue_style('ee-message-settings');
927
+		wp_enqueue_script('ee-messages-settings');
928
+	}
929
+
930
+
931
+	/**
932
+	 * set views array for List Table
933
+	 */
934
+	public function _set_list_table_views_global_mtps()
935
+	{
936
+		$this->_views = array(
937
+			'in_use' => array(
938
+				'slug'  => 'in_use',
939
+				'label' => esc_html__('In Use', 'event_espresso'),
940
+				'count' => 0,
941
+			),
942
+		);
943
+	}
944
+
945
+
946
+	/**
947
+	 * Set views array for the Custom Template List Table
948
+	 */
949
+	public function _set_list_table_views_custom_mtps()
950
+	{
951
+		$this->_set_list_table_views_global_mtps();
952
+		$this->_views['in_use']['bulk_action'] = array(
953
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
954
+		);
955
+	}
956
+
957
+
958
+	/**
959
+	 * set views array for message queue list table
960
+	 *
961
+	 * @throws InvalidDataTypeException
962
+	 * @throws InvalidInterfaceException
963
+	 * @throws InvalidArgumentException
964
+	 * @throws EE_Error
965
+	 * @throws ReflectionException
966
+	 */
967
+	public function _set_list_table_views_default()
968
+	{
969
+		EE_Registry::instance()->load_helper('Template');
970
+
971
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
972
+			'ee_send_message',
973
+			'message_list_table_bulk_actions'
974
+		)
975
+			? array(
976
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
977
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
978
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
979
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
980
+			)
981
+			: array();
982
+
983
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
984
+			'ee_delete_messages',
985
+			'message_list_table_bulk_actions'
986
+		)
987
+			? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
988
+			: array();
989
+
990
+
991
+		$this->_views = array(
992
+			'all' => array(
993
+				'slug'        => 'all',
994
+				'label'       => esc_html__('All', 'event_espresso'),
995
+				'count'       => 0,
996
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
997
+			),
998
+		);
999
+
1000
+
1001
+		foreach (EEM_Message::instance()->all_statuses() as $status) {
1002
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1003
+				continue;
1004
+			}
1005
+			$status_bulk_actions = $common_bulk_actions;
1006
+			// unset bulk actions not applying to status
1007
+			if (! empty($status_bulk_actions)) {
1008
+				switch ($status) {
1009
+					case EEM_Message::status_idle:
1010
+					case EEM_Message::status_resend:
1011
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1012
+						break;
1013
+
1014
+					case EEM_Message::status_failed:
1015
+					case EEM_Message::status_debug_only:
1016
+					case EEM_Message::status_messenger_executing:
1017
+						$status_bulk_actions = array();
1018
+						break;
1019
+
1020
+					case EEM_Message::status_incomplete:
1021
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1022
+						break;
1023
+
1024
+					case EEM_Message::status_retry:
1025
+					case EEM_Message::status_sent:
1026
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1027
+						break;
1028
+				}
1029
+			}
1030
+
1031
+			// skip adding messenger executing status to views because it will be included with the Failed view.
1032
+			if ($status === EEM_Message::status_messenger_executing) {
1033
+				continue;
1034
+			}
1035
+
1036
+			$this->_views[ strtolower($status) ] = array(
1037
+				'slug'        => strtolower($status),
1038
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1039
+				'count'       => 0,
1040
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1041
+			);
1042
+		}
1043
+	}
1044
+
1045
+
1046
+	protected function _ee_default_messages_overview_list_table()
1047
+	{
1048
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1049
+		$this->display_admin_list_table_page_with_no_sidebar();
1050
+	}
1051
+
1052
+
1053
+	protected function _message_queue_list_table()
1054
+	{
1055
+		$this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1056
+		$this->_template_args['per_column'] = 6;
1057
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1058
+		$this->_template_args['before_list_table'] = '<h3>'
1059
+													 . EEM_Message::instance()->get_pretty_label_for_results()
1060
+													 . '</h3>';
1061
+		$this->display_admin_list_table_page_with_no_sidebar();
1062
+	}
1063
+
1064
+
1065
+	protected function _message_legend_items()
1066
+	{
1067
+
1068
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1069
+		$action_items = array();
1070
+
1071
+		foreach ($action_css_classes as $action_item => $action_details) {
1072
+			if ($action_item === 'see_notifications_for') {
1073
+				continue;
1074
+			}
1075
+			$action_items[ $action_item ] = array(
1076
+				'class' => $action_details['css_class'],
1077
+				'desc'  => $action_details['label'],
1078
+			);
1079
+		}
1080
+
1081
+		/** @type array $status_items status legend setup */
1082
+		$status_items = array(
1083
+			'sent_status'                => array(
1084
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1085
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1086
+			),
1087
+			'idle_status'                => array(
1088
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1089
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1090
+			),
1091
+			'failed_status'              => array(
1092
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1093
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1094
+			),
1095
+			'messenger_executing_status' => array(
1096
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1097
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1098
+			),
1099
+			'resend_status'              => array(
1100
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1101
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1102
+			),
1103
+			'incomplete_status'          => array(
1104
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1105
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1106
+			),
1107
+			'retry_status'               => array(
1108
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1109
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1110
+			),
1111
+		);
1112
+		if (EEM_Message::debug()) {
1113
+			$status_items['debug_only_status'] = array(
1114
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1115
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1116
+			);
1117
+		}
1118
+
1119
+		return array_merge($action_items, $status_items);
1120
+	}
1121
+
1122
+
1123
+	protected function _custom_mtps_preview()
1124
+	{
1125
+		$this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1126
+		$this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1127
+											   . ' alt="' . esc_attr__(
1128
+												   'Preview Custom Message Templates screenshot',
1129
+												   'event_espresso'
1130
+											   ) . '" />';
1131
+		$this->_template_args['preview_text'] = '<strong>'
1132
+												. esc_html__(
1133
+													'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.',
1134
+													'event_espresso'
1135
+												)
1136
+												. '</strong>';
1137
+
1138
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1139
+	}
1140
+
1141
+
1142
+	/**
1143
+	 * get_message_templates
1144
+	 * This gets all the message templates for listing on the overview list.
1145
+	 *
1146
+	 * @access public
1147
+	 * @param int    $perpage the amount of templates groups to show per page
1148
+	 * @param string $type    the current _view we're getting templates for
1149
+	 * @param bool   $count   return count?
1150
+	 * @param bool   $all     disregard any paging info (get all data);
1151
+	 * @param bool   $global  whether to return just global (true) or custom templates (false)
1152
+	 * @return array
1153
+	 * @throws EE_Error
1154
+	 * @throws InvalidArgumentException
1155
+	 * @throws InvalidDataTypeException
1156
+	 * @throws InvalidInterfaceException
1157
+	 */
1158
+	public function get_message_templates(
1159
+		$perpage = 10,
1160
+		$type = 'in_use',
1161
+		$count = false,
1162
+		$all = false,
1163
+		$global = true
1164
+	) {
1165
+
1166
+		$MTP = EEM_Message_Template_Group::instance();
1167
+
1168
+		$this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1169
+		$orderby = $this->_req_data['orderby'];
1170
+
1171
+		$order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1172
+			? $this->_req_data['order']
1173
+			: 'ASC';
1174
+
1175
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1176
+			? $this->_req_data['paged']
1177
+			: 1;
1178
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1179
+			? $this->_req_data['perpage']
1180
+			: $perpage;
1181
+
1182
+		$offset = ($current_page - 1) * $per_page;
1183
+		$limit = $all ? null : array($offset, $per_page);
1184
+
1185
+
1186
+		// options will match what is in the _views array property
1187
+		switch ($type) {
1188
+			case 'in_use':
1189
+				$templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1190
+				break;
1191
+			default:
1192
+				$templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1193
+		}
1194
+
1195
+		return $templates;
1196
+	}
1197
+
1198
+
1199
+	/**
1200
+	 * filters etc might need a list of installed message_types
1201
+	 *
1202
+	 * @return array an array of message type objects
1203
+	 */
1204
+	public function get_installed_message_types()
1205
+	{
1206
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1207
+		$installed = array();
1208
+
1209
+		foreach ($installed_message_types as $message_type) {
1210
+			$installed[ $message_type->name ] = $message_type;
1211
+		}
1212
+
1213
+		return $installed;
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * _add_message_template
1219
+	 *
1220
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1221
+	 *
1222
+	 * @param string $message_type
1223
+	 * @param string $messenger
1224
+	 * @param string $GRP_ID
1225
+	 *
1226
+	 * @throws EE_error
1227
+	 */
1228
+	protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1229
+	{
1230
+		// set values override any request data
1231
+		$message_type = ! empty($message_type) ? $message_type : '';
1232
+		$message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1233
+			? $this->_req_data['message_type']
1234
+			: $message_type;
1235
+
1236
+		$messenger = ! empty($messenger) ? $messenger : '';
1237
+		$messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1238
+			? $this->_req_data['messenger']
1239
+			: $messenger;
1240
+
1241
+		$GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1242
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1243
+
1244
+		// we need messenger and message type.  They should be coming from the event editor. If not here then return error
1245
+		if (empty($message_type) || empty($messenger)) {
1246
+			throw new EE_Error(
1247
+				esc_html__(
1248
+					'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1249
+					'event_espresso'
1250
+				)
1251
+			);
1252
+		}
1253
+
1254
+		// we need the GRP_ID for the template being used as the base for the new template
1255
+		if (empty($GRP_ID)) {
1256
+			throw new EE_Error(
1257
+				esc_html__(
1258
+					'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1259
+					'event_espresso'
1260
+				)
1261
+			);
1262
+		}
1263
+
1264
+		// let's just make sure the template gets generated!
1265
+
1266
+		// we need to reassign some variables for what the insert is expecting
1267
+		$this->_req_data['MTP_messenger'] = $messenger;
1268
+		$this->_req_data['MTP_message_type'] = $message_type;
1269
+		$this->_req_data['GRP_ID'] = $GRP_ID;
1270
+		$this->_insert_or_update_message_template(true);
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * public wrapper for the _add_message_template method
1276
+	 *
1277
+	 * @param string $message_type     message type slug
1278
+	 * @param string $messenger        messenger slug
1279
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1280
+	 *                                 off of.
1281
+	 * @throws EE_error
1282
+	 */
1283
+	public function add_message_template($message_type, $messenger, $GRP_ID)
1284
+	{
1285
+		$this->_add_message_template($message_type, $messenger, $GRP_ID);
1286
+	}
1287
+
1288
+
1289
+	/**
1290
+	 * _edit_message_template
1291
+	 *
1292
+	 * @access protected
1293
+	 * @return void
1294
+	 * @throws InvalidIdentifierException
1295
+	 * @throws DomainException
1296
+	 * @throws EE_Error
1297
+	 * @throws InvalidArgumentException
1298
+	 * @throws ReflectionException
1299
+	 * @throws InvalidDataTypeException
1300
+	 * @throws InvalidInterfaceException
1301
+	 */
1302
+	protected function _edit_message_template()
1303
+	{
1304
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1305
+		$template_fields = '';
1306
+		$sidebar_fields = '';
1307
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1308
+		// valid html in the templates.
1309
+		add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1310
+
1311
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1312
+			? absint($this->_req_data['id'])
1313
+			: false;
1314
+
1315
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1316
+		? absint($this->_req_data['evt_id'])
1317
+		: false;
1318
+
1319
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1320
+		$message_template_group = $this->_message_template_group;
1321
+		$c_label = $message_template_group->context_label();
1322
+		$c_config = $message_template_group->contexts_config();
1323
+
1324
+		reset($c_config);
1325
+		$context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1326
+			? strtolower($this->_req_data['context'])
1327
+			: key($c_config);
1328
+
1329
+
1330
+		if (empty($GRP_ID)) {
1331
+			$action = 'insert_message_template';
1332
+			$edit_message_template_form_url = add_query_arg(
1333
+				array('action' => $action, 'noheader' => true),
1334
+				EE_MSG_ADMIN_URL
1335
+			);
1336
+		} else {
1337
+			$action = 'update_message_template';
1338
+			$edit_message_template_form_url = add_query_arg(
1339
+				array('action' => $action, 'noheader' => true),
1340
+				EE_MSG_ADMIN_URL
1341
+			);
1342
+		}
1343
+
1344
+		// set active messenger for this view
1345
+		$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1346
+			$message_template_group->messenger()
1347
+		);
1348
+		$this->_active_message_type_name = $message_template_group->message_type();
1349
+
1350
+
1351
+		// Do we have any validation errors?
1352
+		$validators = $this->_get_transient();
1353
+		$v_fields = ! empty($validators) ? array_keys($validators) : array();
1354
+
1355
+
1356
+		// we need to assemble the title from Various details
1357
+		$context_label = sprintf(
1358
+			esc_html__('(%s %s)', 'event_espresso'),
1359
+			$c_config[ $context ]['label'],
1360
+			ucwords($c_label['label'])
1361
+		);
1362
+
1363
+		$title = sprintf(
1364
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1365
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1366
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1367
+			$context_label
1368
+		);
1369
+
1370
+		$this->_template_args['GRP_ID'] = $GRP_ID;
1371
+		$this->_template_args['message_template'] = $message_template_group;
1372
+		$this->_template_args['is_extra_fields'] = false;
1373
+
1374
+
1375
+		// let's get EEH_MSG_Template so we can get template form fields
1376
+		$template_field_structure = EEH_MSG_Template::get_fields(
1377
+			$message_template_group->messenger(),
1378
+			$message_template_group->message_type()
1379
+		);
1380
+
1381
+		if (! $template_field_structure) {
1382
+			$template_field_structure = false;
1383
+			$template_fields = esc_html__(
1384
+				'There was an error in assembling the fields for this display (you should see an error message)',
1385
+				'event_espresso'
1386
+			);
1387
+		}
1388
+
1389
+
1390
+		$message_templates = $message_template_group->context_templates();
1391
+
1392
+
1393
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1394
+		// will get handled in the "extra" array.
1395
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1396
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1397
+				unset($template_field_structure[ $context ][ $reference_field ]);
1398
+			}
1399
+		}
1400
+
1401
+		// let's loop through the template_field_structure and actually assemble the input fields!
1402
+		if (! empty($template_field_structure)) {
1403
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1404
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1405
+				// the extra array and reset them.
1406
+				if ($template_field === 'extra') {
1407
+					$this->_template_args['is_extra_fields'] = true;
1408
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1409
+						$message_template = $message_templates[ $context ][ $reference_field ];
1410
+						$content = $message_template instanceof EE_Message_Template
1411
+							? $message_template->get('MTP_content')
1412
+							: '';
1413
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1414
+							// let's verify if we need this extra field via the shortcodes parameter.
1415
+							$continue = false;
1416
+							if (isset($extra_array['shortcodes_required'])) {
1417
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1418
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1419
+										$continue = true;
1420
+									}
1421
+								}
1422
+								if ($continue) {
1423
+									continue;
1424
+								}
1425
+							}
1426
+
1427
+							$field_id = $reference_field
1428
+										. '-'
1429
+										. $extra_field
1430
+										. '-content';
1431
+							$template_form_fields[ $field_id ] = $extra_array;
1432
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1433
+																		 . $reference_field
1434
+																		 . '][content]['
1435
+																		 . $extra_field . ']';
1436
+							$css_class = isset($extra_array['css_class'])
1437
+								? $extra_array['css_class']
1438
+								: '';
1439
+
1440
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1441
+																			  && in_array($extra_field, $v_fields, true)
1442
+																			  &&
1443
+																			  (
1444
+																				  is_array($validators[ $extra_field ])
1445
+																				  && isset($validators[ $extra_field ]['msg'])
1446
+																			  )
1447
+								? 'validate-error ' . $css_class
1448
+								: $css_class;
1449
+
1450
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1451
+																		  && isset($content[ $extra_field ])
1452
+								? $content[ $extra_field ]
1453
+								: '';
1454
+
1455
+							// do we have a validation error?  if we do then let's use that value instead
1456
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1457
+								? $validators[ $extra_field ]['value']
1458
+								: $template_form_fields[ $field_id ]['value'];
1459
+
1460
+
1461
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1462
+
1463
+							// shortcode selector
1464
+							$field_name_to_use = $extra_field === 'main'
1465
+								? 'content'
1466
+								: $extra_field;
1467
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1468
+								$field_name_to_use,
1469
+								$field_id
1470
+							);
1471
+
1472
+							if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1473
+								// we want to decode the entities
1474
+								$template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1475
+							}/**/
1476
+						}
1477
+						$templatefield_MTP_id = $reference_field . '-MTP_ID';
1478
+						$templatefield_templatename_id = $reference_field . '-name';
1479
+
1480
+						$template_form_fields[ $templatefield_MTP_id ] = array(
1481
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1482
+							'label'      => null,
1483
+							'input'      => 'hidden',
1484
+							'type'       => 'int',
1485
+							'required'   => false,
1486
+							'validation' => false,
1487
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1488
+							'css_class'  => '',
1489
+							'format'     => '%d',
1490
+							'db-col'     => 'MTP_ID',
1491
+						);
1492
+
1493
+						$template_form_fields[ $templatefield_templatename_id ] = array(
1494
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1495
+							'label'      => null,
1496
+							'input'      => 'hidden',
1497
+							'type'       => 'string',
1498
+							'required'   => false,
1499
+							'validation' => true,
1500
+							'value'      => $reference_field,
1501
+							'css_class'  => '',
1502
+							'format'     => '%s',
1503
+							'db-col'     => 'MTP_template_field',
1504
+						);
1505
+					}
1506
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1507
+				} else {
1508
+					$field_id = $template_field . '-content';
1509
+					$template_form_fields[ $field_id ] = $field_setup_array;
1510
+					$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1511
+					$message_template = isset($message_templates[ $context ][ $template_field ])
1512
+						? $message_templates[ $context ][ $template_field ]
1513
+						: null;
1514
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1515
+																  && is_array($message_templates[ $context ])
1516
+																  && $message_template instanceof EE_Message_Template
1517
+						? $message_template->get('MTP_content')
1518
+						: '';
1519
+
1520
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1521
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1522
+						? $validators[ $template_field ]['value']
1523
+						: $template_form_fields[ $field_id ]['value'];
1524
+
1525
+
1526
+					$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1527
+					$css_class = isset($field_setup_array['css_class'])
1528
+						? $field_setup_array['css_class']
1529
+						: '';
1530
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1531
+																	  && in_array($template_field, $v_fields, true)
1532
+																	  && isset($validators[ $template_field ]['msg'])
1533
+						? 'validate-error ' . $css_class
1534
+						: $css_class;
1535
+
1536
+					// shortcode selector
1537
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1538
+						$template_field,
1539
+						$field_id
1540
+					);
1541
+				}
1542
+
1543
+				// k took care of content field(s) now let's take care of others.
1544
+
1545
+				$templatefield_MTP_id = $template_field . '-MTP_ID';
1546
+				$templatefield_field_templatename_id = $template_field . '-name';
1547
+
1548
+				// foreach template field there are actually two form fields created
1549
+				$template_form_fields[ $templatefield_MTP_id ] = array(
1550
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1551
+					'label'      => null,
1552
+					'input'      => 'hidden',
1553
+					'type'       => 'int',
1554
+					'required'   => false,
1555
+					'validation' => true,
1556
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1557
+					'css_class'  => '',
1558
+					'format'     => '%d',
1559
+					'db-col'     => 'MTP_ID',
1560
+				);
1561
+
1562
+				$template_form_fields[ $templatefield_field_templatename_id ] = array(
1563
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1564
+					'label'      => null,
1565
+					'input'      => 'hidden',
1566
+					'type'       => 'string',
1567
+					'required'   => false,
1568
+					'validation' => true,
1569
+					'value'      => $template_field,
1570
+					'css_class'  => '',
1571
+					'format'     => '%s',
1572
+					'db-col'     => 'MTP_template_field',
1573
+				);
1574
+			}
1575
+
1576
+			// add other fields
1577
+			$template_form_fields['ee-msg-current-context'] = array(
1578
+				'name'       => 'MTP_context',
1579
+				'label'      => null,
1580
+				'input'      => 'hidden',
1581
+				'type'       => 'string',
1582
+				'required'   => false,
1583
+				'validation' => true,
1584
+				'value'      => $context,
1585
+				'css_class'  => '',
1586
+				'format'     => '%s',
1587
+				'db-col'     => 'MTP_context',
1588
+			);
1589
+
1590
+			$template_form_fields['ee-msg-grp-id'] = array(
1591
+				'name'       => 'GRP_ID',
1592
+				'label'      => null,
1593
+				'input'      => 'hidden',
1594
+				'type'       => 'int',
1595
+				'required'   => false,
1596
+				'validation' => true,
1597
+				'value'      => $GRP_ID,
1598
+				'css_class'  => '',
1599
+				'format'     => '%d',
1600
+				'db-col'     => 'GRP_ID',
1601
+			);
1602
+
1603
+			$template_form_fields['ee-msg-messenger'] = array(
1604
+				'name'       => 'MTP_messenger',
1605
+				'label'      => null,
1606
+				'input'      => 'hidden',
1607
+				'type'       => 'string',
1608
+				'required'   => false,
1609
+				'validation' => true,
1610
+				'value'      => $message_template_group->messenger(),
1611
+				'css_class'  => '',
1612
+				'format'     => '%s',
1613
+				'db-col'     => 'MTP_messenger',
1614
+			);
1615
+
1616
+			$template_form_fields['ee-msg-message-type'] = array(
1617
+				'name'       => 'MTP_message_type',
1618
+				'label'      => null,
1619
+				'input'      => 'hidden',
1620
+				'type'       => 'string',
1621
+				'required'   => false,
1622
+				'validation' => true,
1623
+				'value'      => $message_template_group->message_type(),
1624
+				'css_class'  => '',
1625
+				'format'     => '%s',
1626
+				'db-col'     => 'MTP_message_type',
1627
+			);
1628
+
1629
+			$sidebar_form_fields['ee-msg-is-global'] = array(
1630
+				'name'       => 'MTP_is_global',
1631
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1632
+				'input'      => 'hidden',
1633
+				'type'       => 'int',
1634
+				'required'   => false,
1635
+				'validation' => true,
1636
+				'value'      => $message_template_group->get('MTP_is_global'),
1637
+				'css_class'  => '',
1638
+				'format'     => '%d',
1639
+				'db-col'     => 'MTP_is_global',
1640
+			);
1641
+
1642
+			$sidebar_form_fields['ee-msg-is-override'] = array(
1643
+				'name'       => 'MTP_is_override',
1644
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1645
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1646
+				'type'       => 'int',
1647
+				'required'   => false,
1648
+				'validation' => true,
1649
+				'value'      => $message_template_group->get('MTP_is_override'),
1650
+				'css_class'  => '',
1651
+				'format'     => '%d',
1652
+				'db-col'     => 'MTP_is_override',
1653
+			);
1654
+
1655
+			$sidebar_form_fields['ee-msg-is-active'] = array(
1656
+				'name'       => 'MTP_is_active',
1657
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1658
+				'input'      => 'hidden',
1659
+				'type'       => 'int',
1660
+				'required'   => false,
1661
+				'validation' => true,
1662
+				'value'      => $message_template_group->is_active(),
1663
+				'css_class'  => '',
1664
+				'format'     => '%d',
1665
+				'db-col'     => 'MTP_is_active',
1666
+			);
1667
+
1668
+			$sidebar_form_fields['ee-msg-deleted'] = array(
1669
+				'name'       => 'MTP_deleted',
1670
+				'label'      => null,
1671
+				'input'      => 'hidden',
1672
+				'type'       => 'int',
1673
+				'required'   => false,
1674
+				'validation' => true,
1675
+				'value'      => $message_template_group->get('MTP_deleted'),
1676
+				'css_class'  => '',
1677
+				'format'     => '%d',
1678
+				'db-col'     => 'MTP_deleted',
1679
+			);
1680
+			$sidebar_form_fields['ee-msg-author'] = array(
1681
+				'name'       => 'MTP_user_id',
1682
+				'label'      => esc_html__('Author', 'event_espresso'),
1683
+				'input'      => 'hidden',
1684
+				'type'       => 'int',
1685
+				'required'   => false,
1686
+				'validation' => false,
1687
+				'value'      => $message_template_group->user(),
1688
+				'format'     => '%d',
1689
+				'db-col'     => 'MTP_user_id',
1690
+			);
1691
+
1692
+			$sidebar_form_fields['ee-msg-route'] = array(
1693
+				'name'  => 'action',
1694
+				'input' => 'hidden',
1695
+				'type'  => 'string',
1696
+				'value' => $action,
1697
+			);
1698
+
1699
+			$sidebar_form_fields['ee-msg-id'] = array(
1700
+				'name'  => 'id',
1701
+				'input' => 'hidden',
1702
+				'type'  => 'int',
1703
+				'value' => $GRP_ID,
1704
+			);
1705
+			$sidebar_form_fields['ee-msg-evt-nonce'] = array(
1706
+				'name'  => $action . '_nonce',
1707
+				'input' => 'hidden',
1708
+				'type'  => 'string',
1709
+				'value' => wp_create_nonce($action . '_nonce'),
1710
+			);
1711
+
1712
+			if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1713
+				$sidebar_form_fields['ee-msg-template-switch'] = array(
1714
+					'name'  => 'template_switch',
1715
+					'input' => 'hidden',
1716
+					'type'  => 'int',
1717
+					'value' => 1,
1718
+				);
1719
+			}
1720
+
1721
+
1722
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1723
+			$sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1724
+		} //end if ( !empty($template_field_structure) )
1725
+
1726
+		// set extra content for publish box
1727
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1728
+		$this->_set_publish_post_box_vars(
1729
+			'id',
1730
+			$GRP_ID,
1731
+			false,
1732
+			add_query_arg(
1733
+				array('action' => 'global_mtps'),
1734
+				$this->_admin_base_url
1735
+			)
1736
+		);
1737
+
1738
+		// add preview button
1739
+		$preview_url = parent::add_query_args_and_nonce(
1740
+			array(
1741
+				'message_type' => $message_template_group->message_type(),
1742
+				'messenger'    => $message_template_group->messenger(),
1743
+				'context'      => $context,
1744
+				'GRP_ID'       => $GRP_ID,
1745
+				'evt_id'       => $EVT_ID,
1746
+				'action'       => 'preview_message',
1747
+			),
1748
+			$this->_admin_base_url
1749
+		);
1750
+		$preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1751
+						  . esc_html__('Preview', 'event_espresso')
1752
+						  . '</a>';
1753
+
1754
+
1755
+		// setup context switcher
1756
+		$context_switcher_args = array(
1757
+			'page'    => 'espresso_messages',
1758
+			'action'  => 'edit_message_template',
1759
+			'id'      => $GRP_ID,
1760
+			'evt_id'  => $EVT_ID,
1761
+			'context' => $context,
1762
+			'extra'   => $preview_button,
1763
+		);
1764
+		$this->_set_context_switcher($message_template_group, $context_switcher_args);
1765
+
1766
+
1767
+		// main box
1768
+		$this->_template_args['template_fields'] = $template_fields;
1769
+		$this->_template_args['sidebar_box_id'] = 'details';
1770
+		$this->_template_args['action'] = $action;
1771
+		$this->_template_args['context'] = $context;
1772
+		$this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1773
+		$this->_template_args['learn_more_about_message_templates_link'] =
1774
+			$this->_learn_more_about_message_templates_link();
1775
+
1776
+
1777
+		$this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1778
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1779
+			$message_template_group,
1780
+			$context,
1781
+			$context_label
1782
+		);
1783
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1784
+		$this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1785
+
1786
+		$this->_template_path = $this->_template_args['GRP_ID']
1787
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1788
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1789
+
1790
+		// send along EE_Message_Template_Group object for further template use.
1791
+		$this->_template_args['MTP'] = $message_template_group;
1792
+
1793
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1794
+			$this->_template_path,
1795
+			$this->_template_args,
1796
+			true
1797
+		);
1798
+
1799
+
1800
+		// finally, let's set the admin_page title
1801
+		$this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1802
+
1803
+
1804
+		// we need to take care of setting the shortcodes property for use elsewhere.
1805
+		$this->_set_shortcodes();
1806
+
1807
+
1808
+		// final template wrapper
1809
+		$this->display_admin_page_with_sidebar();
1810
+	}
1811
+
1812
+
1813
+	public function filter_tinymce_init($mceInit, $editor_id)
1814
+	{
1815
+		return $mceInit;
1816
+	}
1817
+
1818
+
1819
+	public function add_context_switcher()
1820
+	{
1821
+		return $this->_context_switcher;
1822
+	}
1823
+
1824
+
1825
+	/**
1826
+	 * Adds the activation/deactivation toggle for the message template context.
1827
+	 *
1828
+	 * @param EE_Message_Template_Group $message_template_group
1829
+	 * @param string                    $context
1830
+	 * @param string                    $context_label
1831
+	 * @return string
1832
+	 * @throws DomainException
1833
+	 * @throws EE_Error
1834
+	 * @throws InvalidIdentifierException
1835
+	 */
1836
+	protected function add_active_context_element(
1837
+		EE_Message_Template_Group $message_template_group,
1838
+		$context,
1839
+		$context_label
1840
+	) {
1841
+		$template_args = array(
1842
+			'context'                   => $context,
1843
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1844
+			'is_active'                 => $message_template_group->is_context_active($context),
1845
+			'on_off_action'             => $message_template_group->is_context_active($context)
1846
+				? 'context-off'
1847
+				: 'context-on',
1848
+			'context_label'             => str_replace(array('(', ')'), '', $context_label),
1849
+			'message_template_group_id' => $message_template_group->ID(),
1850
+		);
1851
+		return EEH_Template::display_template(
1852
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1853
+			$template_args,
1854
+			true
1855
+		);
1856
+	}
1857
+
1858
+
1859
+	/**
1860
+	 * Ajax callback for `toggle_context_template` ajax action.
1861
+	 * Handles toggling the message context on or off.
1862
+	 *
1863
+	 * @throws EE_Error
1864
+	 * @throws InvalidArgumentException
1865
+	 * @throws InvalidDataTypeException
1866
+	 * @throws InvalidIdentifierException
1867
+	 * @throws InvalidInterfaceException
1868
+	 */
1869
+	public function toggle_context_template()
1870
+	{
1871
+		$success = true;
1872
+		// check for required data
1873
+		if (! isset(
1874
+			$this->_req_data['message_template_group_id'],
1875
+			$this->_req_data['context'],
1876
+			$this->_req_data['status']
1877
+		)) {
1878
+			EE_Error::add_error(
1879
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1880
+				__FILE__,
1881
+				__FUNCTION__,
1882
+				__LINE__
1883
+			);
1884
+			$success = false;
1885
+		}
1886
+
1887
+		$nonce = isset($this->_req_data['toggle_context_nonce'])
1888
+			? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1889
+			: '';
1890
+		$nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1891
+		$this->_verify_nonce($nonce, $nonce_ref);
1892
+		$status = $this->_req_data['status'];
1893
+		if ($status !== 'off' && $status !== 'on') {
1894
+			EE_Error::add_error(
1895
+				sprintf(
1896
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1897
+					$this->_req_data['status']
1898
+				),
1899
+				__FILE__,
1900
+				__FUNCTION__,
1901
+				__LINE__
1902
+			);
1903
+			$success = false;
1904
+		}
1905
+		$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1906
+			$this->_req_data['message_template_group_id']
1907
+		);
1908
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1909
+			EE_Error::add_error(
1910
+				sprintf(
1911
+					esc_html__(
1912
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1913
+						'event_espresso'
1914
+					),
1915
+					$this->_req_data['message_template_group_id'],
1916
+					'EE_Message_Template_Group'
1917
+				),
1918
+				__FILE__,
1919
+				__FUNCTION__,
1920
+				__LINE__
1921
+			);
1922
+			$success = false;
1923
+		}
1924
+		if ($success) {
1925
+			$success = $status === 'off'
1926
+				? $message_template_group->deactivate_context($this->_req_data['context'])
1927
+				: $message_template_group->activate_context($this->_req_data['context']);
1928
+		}
1929
+		$this->_template_args['success'] = $success;
1930
+		$this->_return_json();
1931
+	}
1932
+
1933
+
1934
+	public function _add_form_element_before()
1935
+	{
1936
+		return '<form method="post" action="'
1937
+			   . $this->_template_args["edit_message_template_form_url"]
1938
+			   . '" id="ee-msg-edit-frm">';
1939
+	}
1940
+
1941
+	public function _add_form_element_after()
1942
+	{
1943
+		return '</form>';
1944
+	}
1945
+
1946
+
1947
+	/**
1948
+	 * This executes switching the template pack for a message template.
1949
+	 *
1950
+	 * @since 4.5.0
1951
+	 * @throws EE_Error
1952
+	 * @throws InvalidDataTypeException
1953
+	 * @throws InvalidInterfaceException
1954
+	 * @throws InvalidArgumentException
1955
+	 * @throws ReflectionException
1956
+	 */
1957
+	public function switch_template_pack()
1958
+	{
1959
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1960
+		$template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1961
+
1962
+		// verify we have needed values.
1963
+		if (empty($GRP_ID) || empty($template_pack)) {
1964
+			$this->_template_args['error'] = true;
1965
+			EE_Error::add_error(
1966
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1967
+				__FILE__,
1968
+				__FUNCTION__,
1969
+				__LINE__
1970
+			);
1971
+		} else {
1972
+			// get template, set the new template_pack and then reset to default
1973
+			/** @type EE_Message_Template_Group $message_template_group */
1974
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1975
+
1976
+			$message_template_group->set_template_pack_name($template_pack);
1977
+			$this->_req_data['msgr'] = $message_template_group->messenger();
1978
+			$this->_req_data['mt'] = $message_template_group->message_type();
1979
+
1980
+			$query_args = $this->_reset_to_default_template();
1981
+
1982
+			if (empty($query_args['id'])) {
1983
+				EE_Error::add_error(
1984
+					esc_html__(
1985
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
1986
+						'event_espresso'
1987
+					),
1988
+					__FILE__,
1989
+					__FUNCTION__,
1990
+					__LINE__
1991
+				);
1992
+				$this->_template_args['error'] = true;
1993
+			} else {
1994
+				$template_label = $message_template_group->get_template_pack()->label;
1995
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1996
+				EE_Error::add_success(
1997
+					sprintf(
1998
+						esc_html__(
1999
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2000
+							'event_espresso'
2001
+						),
2002
+						$template_label,
2003
+						$template_pack_labels->template_pack
2004
+					)
2005
+				);
2006
+				// generate the redirect url for js.
2007
+				$url = self::add_query_args_and_nonce(
2008
+					$query_args,
2009
+					$this->_admin_base_url
2010
+				);
2011
+				$this->_template_args['data']['redirect_url'] = $url;
2012
+				$this->_template_args['success'] = true;
2013
+			}
2014
+
2015
+			$this->_return_json();
2016
+		}
2017
+	}
2018
+
2019
+
2020
+	/**
2021
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2022
+	 * they want.
2023
+	 *
2024
+	 * @access protected
2025
+	 * @return array|null
2026
+	 * @throws EE_Error
2027
+	 * @throws InvalidArgumentException
2028
+	 * @throws InvalidDataTypeException
2029
+	 * @throws InvalidInterfaceException
2030
+	 */
2031
+	protected function _reset_to_default_template()
2032
+	{
2033
+
2034
+		$templates = array();
2035
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2036
+		// we need to make sure we've got the info we need.
2037
+		if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2038
+			EE_Error::add_error(
2039
+				esc_html__(
2040
+					'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.',
2041
+					'event_espresso'
2042
+				),
2043
+				__FILE__,
2044
+				__FUNCTION__,
2045
+				__LINE__
2046
+			);
2047
+		}
2048
+
2049
+		// all templates will be reset to whatever the defaults are
2050
+		// for the global template matching the messenger and message type.
2051
+		$success = ! empty($GRP_ID) ? true : false;
2052
+
2053
+		if ($success) {
2054
+			// let's first determine if the incoming template is a global template,
2055
+			// if it isn't then we need to get the global template matching messenger and message type.
2056
+			// $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2057
+
2058
+
2059
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2060
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
2061
+
2062
+			if ($success) {
2063
+				// if successfully deleted, lets generate the new ones.
2064
+				// Note. We set GLOBAL to true, because resets on ANY template
2065
+				// will use the related global template defaults for regeneration.
2066
+				// This means that if a custom template is reset it resets to whatever the related global template is.
2067
+				// HOWEVER, we DO keep the template pack and template variation set
2068
+				// for the current custom template when resetting.
2069
+				$templates = $this->_generate_new_templates(
2070
+					$this->_req_data['msgr'],
2071
+					$this->_req_data['mt'],
2072
+					$GRP_ID,
2073
+					true
2074
+				);
2075
+			}
2076
+		}
2077
+
2078
+		// any error messages?
2079
+		if (! $success) {
2080
+			EE_Error::add_error(
2081
+				esc_html__(
2082
+					'Something went wrong with deleting existing templates. Unable to reset to default',
2083
+					'event_espresso'
2084
+				),
2085
+				__FILE__,
2086
+				__FUNCTION__,
2087
+				__LINE__
2088
+			);
2089
+		}
2090
+
2091
+		// all good, let's add a success message!
2092
+		if ($success && ! empty($templates)) {
2093
+			// the info for the template we generated is the first element in the returned array
2094
+			// $templates = $templates[0];
2095
+			EE_Error::overwrite_success();
2096
+			EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2097
+		}
2098
+
2099
+
2100
+		$query_args = array(
2101
+			'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2102
+			'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2103
+			'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2104
+		);
2105
+
2106
+		// if called via ajax then we return query args otherwise redirect
2107
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2108
+			return $query_args;
2109
+		} else {
2110
+			$this->_redirect_after_action(false, '', '', $query_args, true);
2111
+
2112
+			return null;
2113
+		}
2114
+	}
2115
+
2116
+
2117
+	/**
2118
+	 * Retrieve and set the message preview for display.
2119
+	 *
2120
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2121
+	 * @return string
2122
+	 * @throws ReflectionException
2123
+	 * @throws EE_Error
2124
+	 * @throws InvalidArgumentException
2125
+	 * @throws InvalidDataTypeException
2126
+	 * @throws InvalidInterfaceException
2127
+	 */
2128
+	public function _preview_message($send = false)
2129
+	{
2130
+		// first make sure we've got the necessary parameters
2131
+		if (! isset(
2132
+			$this->_req_data['message_type'],
2133
+			$this->_req_data['messenger'],
2134
+			$this->_req_data['messenger'],
2135
+			$this->_req_data['GRP_ID']
2136
+		)) {
2137
+			EE_Error::add_error(
2138
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2139
+				__FILE__,
2140
+				__FUNCTION__,
2141
+				__LINE__
2142
+			);
2143
+		}
2144
+
2145
+		EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
2146 2146
         
2147
-        // if we have an evt_id set on the request, use it.
2148
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2149
-        ? absint($this->_req_data['evt_id'])
2150
-        : false;
2151
-
2152
-
2153
-        // get the preview!
2154
-        $preview = EED_Messages::preview_message(
2155
-            $this->_req_data['message_type'],
2156
-            $this->_req_data['context'],
2157
-            $this->_req_data['messenger'],
2158
-            $send
2159
-        );
2160
-
2161
-        if ($send) {
2162
-            return $preview;
2163
-        }
2164
-
2165
-        // let's add a button to go back to the edit view
2166
-        $query_args = array(
2167
-            'id'      => $this->_req_data['GRP_ID'],
2168
-            'evt_id'  => $EVT_ID,
2169
-            'context' => $this->_req_data['context'],
2170
-            'action'  => 'edit_message_template',
2171
-        );
2172
-        $go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2173
-        $preview_button = '<a href="'
2174
-                          . $go_back_url
2175
-                          . '" class="button-secondary messages-preview-go-back-button">'
2176
-                          . esc_html__('Go Back to Edit', 'event_espresso')
2177
-                          . '</a>';
2178
-        $message_types = $this->get_installed_message_types();
2179
-        $active_messenger = $this->_message_resource_manager->get_active_messenger(
2180
-            $this->_req_data['messenger']
2181
-        );
2182
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2183
-            ? ucwords($active_messenger->label['singular'])
2184
-            : esc_html__('Unknown Messenger', 'event_espresso');
2185
-        // let's provide a helpful title for context
2186
-        $preview_title = sprintf(
2187
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2188
-            $active_messenger_label,
2189
-            ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2190
-        );
2191
-        if (empty($preview)) {
2192
-            $this->noEventsErrorMessage();
2193
-        }
2194
-        // setup display of preview.
2195
-        $this->_admin_page_title = $preview_title;
2196
-        $this->_template_args['admin_page_title'] = $preview_title;
2197
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2198
-        $this->_template_args['data']['force_json'] = true;
2199
-
2200
-        return '';
2201
-    }
2202
-
2203
-
2204
-    /**
2205
-     * Used to set an error if there are no events available for generating a preview/test send.
2206
-     *
2207
-     * @param bool $test_send  Whether the error should be generated for the context of a test send.
2208
-     */
2209
-    protected function noEventsErrorMessage($test_send = false)
2210
-    {
2211
-        $events_url = parent::add_query_args_and_nonce(
2212
-            array(
2213
-                'action' => 'default',
2214
-                'page'   => 'espresso_events',
2215
-            ),
2216
-            admin_url('admin.php')
2217
-        );
2218
-        $message = $test_send
2219
-            ? __(
2220
-                '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!',
2221
-                'event_espresso'
2222
-            )
2223
-            : __(
2224
-                '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!',
2225
-                'event_espresso'
2226
-            );
2227
-
2228
-        EE_Error::add_attention(
2229
-            sprintf(
2230
-                $message,
2231
-                "<a href='{$events_url}'>",
2232
-                '</a>'
2233
-            )
2234
-        );
2235
-    }
2236
-
2237
-
2238
-    /**
2239
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2240
-     * gets called automatically.
2241
-     *
2242
-     * @since 4.5.0
2243
-     *
2244
-     * @return string
2245
-     */
2246
-    protected function _display_preview_message()
2247
-    {
2248
-        $this->display_admin_page_with_no_sidebar();
2249
-    }
2250
-
2251
-
2252
-    /**
2253
-     * registers metaboxes that should show up on the "edit_message_template" page
2254
-     *
2255
-     * @access protected
2256
-     * @return void
2257
-     */
2258
-    protected function _register_edit_meta_boxes()
2259
-    {
2260
-        add_meta_box(
2261
-            'mtp_valid_shortcodes',
2262
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2263
-            array($this, 'shortcode_meta_box'),
2264
-            $this->_current_screen->id,
2265
-            'side',
2266
-            'default'
2267
-        );
2268
-        add_meta_box(
2269
-            'mtp_extra_actions',
2270
-            esc_html__('Extra Actions', 'event_espresso'),
2271
-            array($this, 'extra_actions_meta_box'),
2272
-            $this->_current_screen->id,
2273
-            'side',
2274
-            'high'
2275
-        );
2276
-        add_meta_box(
2277
-            'mtp_templates',
2278
-            esc_html__('Template Styles', 'event_espresso'),
2279
-            array($this, 'template_pack_meta_box'),
2280
-            $this->_current_screen->id,
2281
-            'side',
2282
-            'high'
2283
-        );
2284
-    }
2285
-
2286
-
2287
-    /**
2288
-     * metabox content for all template pack and variation selection.
2289
-     *
2290
-     * @since 4.5.0
2291
-     * @return string
2292
-     * @throws DomainException
2293
-     * @throws EE_Error
2294
-     * @throws InvalidArgumentException
2295
-     * @throws ReflectionException
2296
-     * @throws InvalidDataTypeException
2297
-     * @throws InvalidInterfaceException
2298
-     */
2299
-    public function template_pack_meta_box()
2300
-    {
2301
-        $this->_set_message_template_group();
2302
-
2303
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2304
-
2305
-        $tp_select_values = array();
2306
-
2307
-        foreach ($tp_collection as $tp) {
2308
-            // only include template packs that support this messenger and message type!
2309
-            $supports = $tp->get_supports();
2310
-            if (! isset($supports[ $this->_message_template_group->messenger() ])
2311
-                || ! in_array(
2312
-                    $this->_message_template_group->message_type(),
2313
-                    $supports[ $this->_message_template_group->messenger() ],
2314
-                    true
2315
-                )
2316
-            ) {
2317
-                // not supported
2318
-                continue;
2319
-            }
2320
-
2321
-            $tp_select_values[] = array(
2322
-                'text' => $tp->label,
2323
-                'id'   => $tp->dbref,
2324
-            );
2325
-        }
2326
-
2327
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2328
-        // the default template pack.  This still allows for the odd template pack to override.
2329
-        if (empty($tp_select_values)) {
2330
-            $tp_select_values[] = array(
2331
-                'text' => esc_html__('Default', 'event_espresso'),
2332
-                'id'   => 'default',
2333
-            );
2334
-        }
2335
-
2336
-        // setup variation select values for the currently selected template.
2337
-        $variations = $this->_message_template_group->get_template_pack()->get_variations(
2338
-            $this->_message_template_group->messenger(),
2339
-            $this->_message_template_group->message_type()
2340
-        );
2341
-        $variations_select_values = array();
2342
-        foreach ($variations as $variation => $label) {
2343
-            $variations_select_values[] = array(
2344
-                'text' => $label,
2345
-                'id'   => $variation,
2346
-            );
2347
-        }
2348
-
2349
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2350
-
2351
-        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2352
-            'MTP_template_pack',
2353
-            $tp_select_values,
2354
-            $this->_message_template_group->get_template_pack_name()
2355
-        );
2356
-        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
2357
-            'MTP_template_variation',
2358
-            $variations_select_values,
2359
-            $this->_message_template_group->get_template_pack_variation()
2360
-        );
2361
-        $template_args['template_pack_label'] = $template_pack_labels->template_pack;
2362
-        $template_args['template_variation_label'] = $template_pack_labels->template_variation;
2363
-        $template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2364
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2365
-
2366
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2367
-
2368
-        EEH_Template::display_template($template, $template_args);
2369
-    }
2370
-
2371
-
2372
-    /**
2373
-     * This meta box holds any extra actions related to Message Templates
2374
-     * For now, this includes Resetting templates to defaults and sending a test email.
2375
-     *
2376
-     * @access  public
2377
-     * @return void
2378
-     * @throws EE_Error
2379
-     */
2380
-    public function extra_actions_meta_box()
2381
-    {
2382
-        $template_form_fields = array();
2383
-
2384
-        $extra_args = array(
2385
-            'msgr'   => $this->_message_template_group->messenger(),
2386
-            'mt'     => $this->_message_template_group->message_type(),
2387
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2388
-        );
2389
-        // first we need to see if there are any fields
2390
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2391
-
2392
-        if (! empty($fields)) {
2393
-            // yup there be fields
2394
-            foreach ($fields as $field => $config) {
2395
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2396
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2397
-                $default = isset($config['default']) ? $config['default'] : '';
2398
-                $default = isset($config['value']) ? $config['value'] : $default;
2399
-
2400
-                // if type is hidden and the value is empty
2401
-                // something may have gone wrong so let's correct with the defaults
2402
-                $fix = $config['input'] === 'hidden'
2403
-                       && isset($existing[ $field ])
2404
-                       && empty($existing[ $field ])
2405
-                    ? $default
2406
-                    : '';
2407
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2408
-                    ? $existing[ $field ]
2409
-                    : $fix;
2410
-
2411
-                $template_form_fields[ $field_id ] = array(
2412
-                    'name'       => 'test_settings_fld[' . $field . ']',
2413
-                    'label'      => $config['label'],
2414
-                    'input'      => $config['input'],
2415
-                    'type'       => $config['type'],
2416
-                    'required'   => $config['required'],
2417
-                    'validation' => $config['validation'],
2418
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2419
-                    'css_class'  => $config['css_class'],
2420
-                    'options'    => isset($config['options']) ? $config['options'] : array(),
2421
-                    'default'    => $default,
2422
-                    'format'     => $config['format'],
2423
-                );
2424
-            }
2425
-        }
2426
-
2427
-        $test_settings_fields = ! empty($template_form_fields)
2428
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2429
-            : '';
2430
-
2431
-        $test_settings_html = '';
2432
-        // print out $test_settings_fields
2433
-        if (! empty($test_settings_fields)) {
2434
-            echo $test_settings_fields;
2435
-            $test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2436
-            $test_settings_html .= 'name="test_button" value="';
2437
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2438
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2439
-        }
2440
-
2441
-        // and button
2442
-        $test_settings_html .= '<p>'
2443
-                               . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2444
-                               . '</p>';
2445
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2446
-        $test_settings_html .= $this->get_action_link_or_button(
2447
-            'reset_to_default',
2448
-            'reset',
2449
-            $extra_args,
2450
-            'button-primary reset-default-button'
2451
-        );
2452
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2453
-        echo $test_settings_html;
2454
-    }
2455
-
2456
-
2457
-    /**
2458
-     * This returns the shortcode selector skeleton for a given context and field.
2459
-     *
2460
-     * @since 4.9.rc.000
2461
-     * @param string $field           The name of the field retrieving shortcodes for.
2462
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2463
-     * @return string
2464
-     * @throws DomainException
2465
-     * @throws EE_Error
2466
-     * @throws InvalidArgumentException
2467
-     * @throws ReflectionException
2468
-     * @throws InvalidDataTypeException
2469
-     * @throws InvalidInterfaceException
2470
-     */
2471
-    protected function _get_shortcode_selector($field, $linked_input_id)
2472
-    {
2473
-        $template_args = array(
2474
-            'shortcodes'      => $this->_get_shortcodes(array($field), true),
2475
-            'fieldname'       => $field,
2476
-            'linked_input_id' => $linked_input_id,
2477
-        );
2478
-
2479
-        return EEH_Template::display_template(
2480
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2481
-            $template_args,
2482
-            true
2483
-        );
2484
-    }
2485
-
2486
-
2487
-    /**
2488
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2489
-     * page)
2490
-     *
2491
-     * @access public
2492
-     * @return void
2493
-     * @throws EE_Error
2494
-     * @throws InvalidArgumentException
2495
-     * @throws ReflectionException
2496
-     * @throws InvalidDataTypeException
2497
-     * @throws InvalidInterfaceException
2498
-     */
2499
-    public function shortcode_meta_box()
2500
-    {
2501
-        $shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2502
-        // $messenger = $this->_message_template_group->messenger_obj();
2503
-        // now let's set the content depending on the status of the shortcodes array
2504
-        if (empty($shortcodes)) {
2505
-            $content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2506
-            echo $content;
2507
-        } else {
2508
-            // $alt = 0;
2509
-            ?>
2147
+		// if we have an evt_id set on the request, use it.
2148
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2149
+		? absint($this->_req_data['evt_id'])
2150
+		: false;
2151
+
2152
+
2153
+		// get the preview!
2154
+		$preview = EED_Messages::preview_message(
2155
+			$this->_req_data['message_type'],
2156
+			$this->_req_data['context'],
2157
+			$this->_req_data['messenger'],
2158
+			$send
2159
+		);
2160
+
2161
+		if ($send) {
2162
+			return $preview;
2163
+		}
2164
+
2165
+		// let's add a button to go back to the edit view
2166
+		$query_args = array(
2167
+			'id'      => $this->_req_data['GRP_ID'],
2168
+			'evt_id'  => $EVT_ID,
2169
+			'context' => $this->_req_data['context'],
2170
+			'action'  => 'edit_message_template',
2171
+		);
2172
+		$go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2173
+		$preview_button = '<a href="'
2174
+						  . $go_back_url
2175
+						  . '" class="button-secondary messages-preview-go-back-button">'
2176
+						  . esc_html__('Go Back to Edit', 'event_espresso')
2177
+						  . '</a>';
2178
+		$message_types = $this->get_installed_message_types();
2179
+		$active_messenger = $this->_message_resource_manager->get_active_messenger(
2180
+			$this->_req_data['messenger']
2181
+		);
2182
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2183
+			? ucwords($active_messenger->label['singular'])
2184
+			: esc_html__('Unknown Messenger', 'event_espresso');
2185
+		// let's provide a helpful title for context
2186
+		$preview_title = sprintf(
2187
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2188
+			$active_messenger_label,
2189
+			ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2190
+		);
2191
+		if (empty($preview)) {
2192
+			$this->noEventsErrorMessage();
2193
+		}
2194
+		// setup display of preview.
2195
+		$this->_admin_page_title = $preview_title;
2196
+		$this->_template_args['admin_page_title'] = $preview_title;
2197
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2198
+		$this->_template_args['data']['force_json'] = true;
2199
+
2200
+		return '';
2201
+	}
2202
+
2203
+
2204
+	/**
2205
+	 * Used to set an error if there are no events available for generating a preview/test send.
2206
+	 *
2207
+	 * @param bool $test_send  Whether the error should be generated for the context of a test send.
2208
+	 */
2209
+	protected function noEventsErrorMessage($test_send = false)
2210
+	{
2211
+		$events_url = parent::add_query_args_and_nonce(
2212
+			array(
2213
+				'action' => 'default',
2214
+				'page'   => 'espresso_events',
2215
+			),
2216
+			admin_url('admin.php')
2217
+		);
2218
+		$message = $test_send
2219
+			? __(
2220
+				'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!',
2221
+				'event_espresso'
2222
+			)
2223
+			: __(
2224
+				'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!',
2225
+				'event_espresso'
2226
+			);
2227
+
2228
+		EE_Error::add_attention(
2229
+			sprintf(
2230
+				$message,
2231
+				"<a href='{$events_url}'>",
2232
+				'</a>'
2233
+			)
2234
+		);
2235
+	}
2236
+
2237
+
2238
+	/**
2239
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2240
+	 * gets called automatically.
2241
+	 *
2242
+	 * @since 4.5.0
2243
+	 *
2244
+	 * @return string
2245
+	 */
2246
+	protected function _display_preview_message()
2247
+	{
2248
+		$this->display_admin_page_with_no_sidebar();
2249
+	}
2250
+
2251
+
2252
+	/**
2253
+	 * registers metaboxes that should show up on the "edit_message_template" page
2254
+	 *
2255
+	 * @access protected
2256
+	 * @return void
2257
+	 */
2258
+	protected function _register_edit_meta_boxes()
2259
+	{
2260
+		add_meta_box(
2261
+			'mtp_valid_shortcodes',
2262
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2263
+			array($this, 'shortcode_meta_box'),
2264
+			$this->_current_screen->id,
2265
+			'side',
2266
+			'default'
2267
+		);
2268
+		add_meta_box(
2269
+			'mtp_extra_actions',
2270
+			esc_html__('Extra Actions', 'event_espresso'),
2271
+			array($this, 'extra_actions_meta_box'),
2272
+			$this->_current_screen->id,
2273
+			'side',
2274
+			'high'
2275
+		);
2276
+		add_meta_box(
2277
+			'mtp_templates',
2278
+			esc_html__('Template Styles', 'event_espresso'),
2279
+			array($this, 'template_pack_meta_box'),
2280
+			$this->_current_screen->id,
2281
+			'side',
2282
+			'high'
2283
+		);
2284
+	}
2285
+
2286
+
2287
+	/**
2288
+	 * metabox content for all template pack and variation selection.
2289
+	 *
2290
+	 * @since 4.5.0
2291
+	 * @return string
2292
+	 * @throws DomainException
2293
+	 * @throws EE_Error
2294
+	 * @throws InvalidArgumentException
2295
+	 * @throws ReflectionException
2296
+	 * @throws InvalidDataTypeException
2297
+	 * @throws InvalidInterfaceException
2298
+	 */
2299
+	public function template_pack_meta_box()
2300
+	{
2301
+		$this->_set_message_template_group();
2302
+
2303
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2304
+
2305
+		$tp_select_values = array();
2306
+
2307
+		foreach ($tp_collection as $tp) {
2308
+			// only include template packs that support this messenger and message type!
2309
+			$supports = $tp->get_supports();
2310
+			if (! isset($supports[ $this->_message_template_group->messenger() ])
2311
+				|| ! in_array(
2312
+					$this->_message_template_group->message_type(),
2313
+					$supports[ $this->_message_template_group->messenger() ],
2314
+					true
2315
+				)
2316
+			) {
2317
+				// not supported
2318
+				continue;
2319
+			}
2320
+
2321
+			$tp_select_values[] = array(
2322
+				'text' => $tp->label,
2323
+				'id'   => $tp->dbref,
2324
+			);
2325
+		}
2326
+
2327
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2328
+		// the default template pack.  This still allows for the odd template pack to override.
2329
+		if (empty($tp_select_values)) {
2330
+			$tp_select_values[] = array(
2331
+				'text' => esc_html__('Default', 'event_espresso'),
2332
+				'id'   => 'default',
2333
+			);
2334
+		}
2335
+
2336
+		// setup variation select values for the currently selected template.
2337
+		$variations = $this->_message_template_group->get_template_pack()->get_variations(
2338
+			$this->_message_template_group->messenger(),
2339
+			$this->_message_template_group->message_type()
2340
+		);
2341
+		$variations_select_values = array();
2342
+		foreach ($variations as $variation => $label) {
2343
+			$variations_select_values[] = array(
2344
+				'text' => $label,
2345
+				'id'   => $variation,
2346
+			);
2347
+		}
2348
+
2349
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2350
+
2351
+		$template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2352
+			'MTP_template_pack',
2353
+			$tp_select_values,
2354
+			$this->_message_template_group->get_template_pack_name()
2355
+		);
2356
+		$template_args['variations_selector'] = EEH_Form_Fields::select_input(
2357
+			'MTP_template_variation',
2358
+			$variations_select_values,
2359
+			$this->_message_template_group->get_template_pack_variation()
2360
+		);
2361
+		$template_args['template_pack_label'] = $template_pack_labels->template_pack;
2362
+		$template_args['template_variation_label'] = $template_pack_labels->template_variation;
2363
+		$template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2364
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2365
+
2366
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2367
+
2368
+		EEH_Template::display_template($template, $template_args);
2369
+	}
2370
+
2371
+
2372
+	/**
2373
+	 * This meta box holds any extra actions related to Message Templates
2374
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2375
+	 *
2376
+	 * @access  public
2377
+	 * @return void
2378
+	 * @throws EE_Error
2379
+	 */
2380
+	public function extra_actions_meta_box()
2381
+	{
2382
+		$template_form_fields = array();
2383
+
2384
+		$extra_args = array(
2385
+			'msgr'   => $this->_message_template_group->messenger(),
2386
+			'mt'     => $this->_message_template_group->message_type(),
2387
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2388
+		);
2389
+		// first we need to see if there are any fields
2390
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2391
+
2392
+		if (! empty($fields)) {
2393
+			// yup there be fields
2394
+			foreach ($fields as $field => $config) {
2395
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2396
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2397
+				$default = isset($config['default']) ? $config['default'] : '';
2398
+				$default = isset($config['value']) ? $config['value'] : $default;
2399
+
2400
+				// if type is hidden and the value is empty
2401
+				// something may have gone wrong so let's correct with the defaults
2402
+				$fix = $config['input'] === 'hidden'
2403
+					   && isset($existing[ $field ])
2404
+					   && empty($existing[ $field ])
2405
+					? $default
2406
+					: '';
2407
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2408
+					? $existing[ $field ]
2409
+					: $fix;
2410
+
2411
+				$template_form_fields[ $field_id ] = array(
2412
+					'name'       => 'test_settings_fld[' . $field . ']',
2413
+					'label'      => $config['label'],
2414
+					'input'      => $config['input'],
2415
+					'type'       => $config['type'],
2416
+					'required'   => $config['required'],
2417
+					'validation' => $config['validation'],
2418
+					'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2419
+					'css_class'  => $config['css_class'],
2420
+					'options'    => isset($config['options']) ? $config['options'] : array(),
2421
+					'default'    => $default,
2422
+					'format'     => $config['format'],
2423
+				);
2424
+			}
2425
+		}
2426
+
2427
+		$test_settings_fields = ! empty($template_form_fields)
2428
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2429
+			: '';
2430
+
2431
+		$test_settings_html = '';
2432
+		// print out $test_settings_fields
2433
+		if (! empty($test_settings_fields)) {
2434
+			echo $test_settings_fields;
2435
+			$test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2436
+			$test_settings_html .= 'name="test_button" value="';
2437
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2438
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2439
+		}
2440
+
2441
+		// and button
2442
+		$test_settings_html .= '<p>'
2443
+							   . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2444
+							   . '</p>';
2445
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2446
+		$test_settings_html .= $this->get_action_link_or_button(
2447
+			'reset_to_default',
2448
+			'reset',
2449
+			$extra_args,
2450
+			'button-primary reset-default-button'
2451
+		);
2452
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2453
+		echo $test_settings_html;
2454
+	}
2455
+
2456
+
2457
+	/**
2458
+	 * This returns the shortcode selector skeleton for a given context and field.
2459
+	 *
2460
+	 * @since 4.9.rc.000
2461
+	 * @param string $field           The name of the field retrieving shortcodes for.
2462
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2463
+	 * @return string
2464
+	 * @throws DomainException
2465
+	 * @throws EE_Error
2466
+	 * @throws InvalidArgumentException
2467
+	 * @throws ReflectionException
2468
+	 * @throws InvalidDataTypeException
2469
+	 * @throws InvalidInterfaceException
2470
+	 */
2471
+	protected function _get_shortcode_selector($field, $linked_input_id)
2472
+	{
2473
+		$template_args = array(
2474
+			'shortcodes'      => $this->_get_shortcodes(array($field), true),
2475
+			'fieldname'       => $field,
2476
+			'linked_input_id' => $linked_input_id,
2477
+		);
2478
+
2479
+		return EEH_Template::display_template(
2480
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2481
+			$template_args,
2482
+			true
2483
+		);
2484
+	}
2485
+
2486
+
2487
+	/**
2488
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2489
+	 * page)
2490
+	 *
2491
+	 * @access public
2492
+	 * @return void
2493
+	 * @throws EE_Error
2494
+	 * @throws InvalidArgumentException
2495
+	 * @throws ReflectionException
2496
+	 * @throws InvalidDataTypeException
2497
+	 * @throws InvalidInterfaceException
2498
+	 */
2499
+	public function shortcode_meta_box()
2500
+	{
2501
+		$shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2502
+		// $messenger = $this->_message_template_group->messenger_obj();
2503
+		// now let's set the content depending on the status of the shortcodes array
2504
+		if (empty($shortcodes)) {
2505
+			$content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2506
+			echo $content;
2507
+		} else {
2508
+			// $alt = 0;
2509
+			?>
2510 2510
             <div style="float:right; margin-top:10px"><?php
2511
-                            echo $this->_get_help_tab_link('message_template_shortcodes');
2512
-                            ?></div>
2511
+							echo $this->_get_help_tab_link('message_template_shortcodes');
2512
+							?></div>
2513 2513
             <p class="small-text"><?php
2514
-                                  printf(
2515
-                                      esc_html__(
2516
-                                          'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2517
-                                          'event_espresso'
2518
-                                      ),
2519
-                                      '<span class="dashicons dashicons-menu"></span>'
2520
-                                  );
2521
-                                ?>
2514
+								  printf(
2515
+									  esc_html__(
2516
+										  'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2517
+										  'event_espresso'
2518
+									  ),
2519
+									  '<span class="dashicons dashicons-menu"></span>'
2520
+								  );
2521
+								?>
2522 2522
             </p>
2523 2523
             <?php
2524
-        }
2525
-    }
2526
-
2527
-
2528
-    /**
2529
-     * used to set the $_shortcodes property for when its needed elsewhere.
2530
-     *
2531
-     * @access protected
2532
-     * @return void
2533
-     * @throws EE_Error
2534
-     * @throws InvalidArgumentException
2535
-     * @throws ReflectionException
2536
-     * @throws InvalidDataTypeException
2537
-     * @throws InvalidInterfaceException
2538
-     */
2539
-    protected function _set_shortcodes()
2540
-    {
2541
-
2542
-        // no need to run this if the property is already set
2543
-        if (! empty($this->_shortcodes)) {
2544
-            return;
2545
-        }
2546
-
2547
-        $this->_shortcodes = $this->_get_shortcodes();
2548
-    }
2549
-
2550
-
2551
-    /**
2552
-     * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2553
-     * property)
2554
-     *
2555
-     * @access  protected
2556
-     * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2557
-     *                         for. Defaults to all (for the given context)
2558
-     * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2559
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2560
-     *                         true just an array of shortcode/label pairs.
2561
-     * @throws EE_Error
2562
-     * @throws InvalidArgumentException
2563
-     * @throws ReflectionException
2564
-     * @throws InvalidDataTypeException
2565
-     * @throws InvalidInterfaceException
2566
-     */
2567
-    protected function _get_shortcodes($fields = array(), $merged = true)
2568
-    {
2569
-        $this->_set_message_template_group();
2570
-
2571
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2572
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2573
-            ? absint($this->_req_data['id'])
2574
-            : false;
2575
-        $context = isset($this->_req_data['context'])
2576
-            ? $this->_req_data['context']
2577
-            : key($this->_message_template_group->contexts_config());
2578
-
2579
-        return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2580
-    }
2581
-
2582
-
2583
-    /**
2584
-     * This sets the _message_template property (containing the called message_template object)
2585
-     *
2586
-     * @access protected
2587
-     * @return void
2588
-     * @throws EE_Error
2589
-     * @throws InvalidArgumentException
2590
-     * @throws ReflectionException
2591
-     * @throws InvalidDataTypeException
2592
-     * @throws InvalidInterfaceException
2593
-     */
2594
-    protected function _set_message_template_group()
2595
-    {
2596
-
2597
-        if (! empty($this->_message_template_group)) {
2598
-            return;
2599
-        } //get out if this is already set.
2600
-
2601
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2602
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2603
-
2604
-        // let's get the message templates
2605
-        $MTP = EEM_Message_Template_Group::instance();
2606
-
2607
-        if (empty($GRP_ID)) {
2608
-            $this->_message_template_group = $MTP->create_default_object();
2609
-        } else {
2610
-            $this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2611
-        }
2612
-
2613
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2614
-        $this->_variation = $this->_message_template_group->get_template_pack_variation();
2615
-    }
2616
-
2617
-
2618
-    /**
2619
-     * sets up a context switcher for edit forms
2620
-     *
2621
-     * @access  protected
2622
-     * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2623
-     * @param array                      $args                  various things the context switcher needs.
2624
-     * @throws EE_Error
2625
-     */
2626
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2627
-    {
2628
-        $context_details = $template_group_object->contexts_config();
2629
-        $context_label = $template_group_object->context_label();
2630
-        ob_start();
2631
-        ?>
2524
+		}
2525
+	}
2526
+
2527
+
2528
+	/**
2529
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2530
+	 *
2531
+	 * @access protected
2532
+	 * @return void
2533
+	 * @throws EE_Error
2534
+	 * @throws InvalidArgumentException
2535
+	 * @throws ReflectionException
2536
+	 * @throws InvalidDataTypeException
2537
+	 * @throws InvalidInterfaceException
2538
+	 */
2539
+	protected function _set_shortcodes()
2540
+	{
2541
+
2542
+		// no need to run this if the property is already set
2543
+		if (! empty($this->_shortcodes)) {
2544
+			return;
2545
+		}
2546
+
2547
+		$this->_shortcodes = $this->_get_shortcodes();
2548
+	}
2549
+
2550
+
2551
+	/**
2552
+	 * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2553
+	 * property)
2554
+	 *
2555
+	 * @access  protected
2556
+	 * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2557
+	 *                         for. Defaults to all (for the given context)
2558
+	 * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2559
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2560
+	 *                         true just an array of shortcode/label pairs.
2561
+	 * @throws EE_Error
2562
+	 * @throws InvalidArgumentException
2563
+	 * @throws ReflectionException
2564
+	 * @throws InvalidDataTypeException
2565
+	 * @throws InvalidInterfaceException
2566
+	 */
2567
+	protected function _get_shortcodes($fields = array(), $merged = true)
2568
+	{
2569
+		$this->_set_message_template_group();
2570
+
2571
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2572
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2573
+			? absint($this->_req_data['id'])
2574
+			: false;
2575
+		$context = isset($this->_req_data['context'])
2576
+			? $this->_req_data['context']
2577
+			: key($this->_message_template_group->contexts_config());
2578
+
2579
+		return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2580
+	}
2581
+
2582
+
2583
+	/**
2584
+	 * This sets the _message_template property (containing the called message_template object)
2585
+	 *
2586
+	 * @access protected
2587
+	 * @return void
2588
+	 * @throws EE_Error
2589
+	 * @throws InvalidArgumentException
2590
+	 * @throws ReflectionException
2591
+	 * @throws InvalidDataTypeException
2592
+	 * @throws InvalidInterfaceException
2593
+	 */
2594
+	protected function _set_message_template_group()
2595
+	{
2596
+
2597
+		if (! empty($this->_message_template_group)) {
2598
+			return;
2599
+		} //get out if this is already set.
2600
+
2601
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2602
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2603
+
2604
+		// let's get the message templates
2605
+		$MTP = EEM_Message_Template_Group::instance();
2606
+
2607
+		if (empty($GRP_ID)) {
2608
+			$this->_message_template_group = $MTP->create_default_object();
2609
+		} else {
2610
+			$this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2611
+		}
2612
+
2613
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2614
+		$this->_variation = $this->_message_template_group->get_template_pack_variation();
2615
+	}
2616
+
2617
+
2618
+	/**
2619
+	 * sets up a context switcher for edit forms
2620
+	 *
2621
+	 * @access  protected
2622
+	 * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2623
+	 * @param array                      $args                  various things the context switcher needs.
2624
+	 * @throws EE_Error
2625
+	 */
2626
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2627
+	{
2628
+		$context_details = $template_group_object->contexts_config();
2629
+		$context_label = $template_group_object->context_label();
2630
+		ob_start();
2631
+		?>
2632 2632
         <div class="ee-msg-switcher-container">
2633 2633
             <form method="get" action="<?php echo EE_MSG_ADMIN_URL; ?>" id="ee-msg-context-switcher-frm">
2634 2634
                 <?php
2635
-                foreach ($args as $name => $value) {
2636
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2637
-                        continue;
2638
-                    }
2639
-                    ?>
2635
+				foreach ($args as $name => $value) {
2636
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2637
+						continue;
2638
+					}
2639
+					?>
2640 2640
                     <input type="hidden" name="<?php echo $name; ?>" value="<?php echo $value; ?>"/>
2641 2641
                     <?php
2642
-                }
2643
-                // setup nonce_url
2644
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2645
-                ?>
2642
+				}
2643
+				// setup nonce_url
2644
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2645
+				?>
2646 2646
                 <select name="context">
2647 2647
                     <?php
2648
-                    $context_templates = $template_group_object->context_templates();
2649
-                    if (is_array($context_templates)) :
2650
-                        foreach ($context_templates as $context => $template_fields) :
2651
-                            $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2652
-                            ?>
2648
+					$context_templates = $template_group_object->context_templates();
2649
+					if (is_array($context_templates)) :
2650
+						foreach ($context_templates as $context => $template_fields) :
2651
+							$checked = ($context === $args['context']) ? 'selected="selected"' : '';
2652
+							?>
2653 2653
                             <option value="<?php echo $context; ?>" <?php echo $checked; ?>>
2654 2654
                                 <?php echo $context_details[ $context ]['label']; ?>
2655 2655
                             </option>
2656 2656
                         <?php endforeach;
2657
-                    endif; ?>
2657
+					endif; ?>
2658 2658
                 </select>
2659 2659
                 <?php $button_text = sprintf(__('Switch %s', 'event_espresso'), ucwords($context_label['label'])); ?>
2660 2660
                 <input id="submit-msg-context-switcher-sbmt" class="button-secondary" type="submit"
@@ -2663,1925 +2663,1925 @@  discard block
 block discarded – undo
2663 2663
             <?php echo $args['extra']; ?>
2664 2664
         </div> <!-- end .ee-msg-switcher-container -->
2665 2665
         <?php
2666
-        $output = ob_get_contents();
2667
-        ob_clean();
2668
-        $this->_context_switcher = $output;
2669
-    }
2670
-
2671
-
2672
-    /**
2673
-     * utility for sanitizing new values coming in.
2674
-     * Note: this is only used when updating a context.
2675
-     *
2676
-     * @access protected
2677
-     *
2678
-     * @param int $index This helps us know which template field to select from the request array.
2679
-     *
2680
-     * @return array
2681
-     */
2682
-    protected function _set_message_template_column_values($index)
2683
-    {
2684
-        if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2685
-            foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2686
-                $this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2687
-            }
2688
-        }
2689
-
2690
-
2691
-        $set_column_values = array(
2692
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2693
-            'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2694
-            'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2695
-            'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2696
-            'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2697
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2698
-            'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2699
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2700
-            'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2701
-                ? absint($this->_req_data['MTP_is_global'])
2702
-                : 0,
2703
-            'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2704
-                ? absint($this->_req_data['MTP_is_override'])
2705
-                : 0,
2706
-            'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2707
-            'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2708
-        );
2709
-
2710
-
2711
-        return $set_column_values;
2712
-    }
2713
-
2714
-
2715
-    protected function _insert_or_update_message_template($new = false)
2716
-    {
2717
-
2718
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2719
-        $success = 0;
2720
-        $override = false;
2721
-
2722
-        // setup notices description
2723
-        $messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2724
-
2725
-        // need the message type and messenger objects to be able to use the labels for the notices
2726
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2727
-        $messenger_label = $messenger_object instanceof EE_messenger
2728
-            ? ucwords($messenger_object->label['singular'])
2729
-            : '';
2730
-
2731
-        $message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2732
-            ? $this->_req_data['MTP_message_type']
2733
-            : '';
2734
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2735
-
2736
-        $message_type_label = $message_type_object instanceof EE_message_type
2737
-            ? ucwords($message_type_object->label['singular'])
2738
-            : '';
2739
-
2740
-        $context_slug = ! empty($this->_req_data['MTP_context'])
2741
-            ? $this->_req_data['MTP_context']
2742
-            : '';
2743
-        $context = ucwords(str_replace('_', ' ', $context_slug));
2744
-
2745
-        $item_desc = $messenger_label && $message_type_label
2746
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2747
-            : '';
2748
-        $item_desc .= 'Message Template';
2749
-        $query_args = array();
2750
-        $edit_array = array();
2751
-        $action_desc = '';
2752
-
2753
-        // if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2754
-        // user to edit.
2755
-        if ($new) {
2756
-            $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2757
-            if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2758
-                if (empty($edit_array)) {
2759
-                    $success = 0;
2760
-                } else {
2761
-                    $success = 1;
2762
-                    $edit_array = $edit_array[0];
2763
-                    $query_args = array(
2764
-                        'id'      => $edit_array['GRP_ID'],
2765
-                        'context' => $edit_array['MTP_context'],
2766
-                        'action'  => 'edit_message_template',
2767
-                    );
2768
-                }
2769
-            }
2770
-            $action_desc = 'created';
2771
-        } else {
2772
-            $MTPG = EEM_Message_Template_Group::instance();
2773
-            $MTP = EEM_Message_Template::instance();
2774
-
2775
-
2776
-            // run update for each template field in displayed context
2777
-            if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2778
-                EE_Error::add_error(
2779
-                    esc_html__(
2780
-                        'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2781
-                        'event_espresso'
2782
-                    ),
2783
-                    __FILE__,
2784
-                    __FUNCTION__,
2785
-                    __LINE__
2786
-                );
2787
-                $success = 0;
2788
-            } else {
2789
-                // first validate all fields!
2790
-                // this filter allows client code to add its own validation to the template fields as well.
2791
-                // returning an empty array means everything passed validation.
2792
-                // errors in validation should be represented in an array with the following shape:
2793
-                // array(
2794
-                //   'fieldname' => array(
2795
-                //          'msg' => 'error message'
2796
-                //          'value' => 'value for field producing error'
2797
-                // )
2798
-                $custom_validation = (array) apply_filters(
2799
-                    'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2800
-                    array(),
2801
-                    $this->_req_data['MTP_template_fields'],
2802
-                    $context_slug,
2803
-                    $messenger_slug,
2804
-                    $message_type_slug
2805
-                );
2806
-
2807
-                $system_validation = $MTPG->validate(
2808
-                    $this->_req_data['MTP_template_fields'],
2809
-                    $context_slug,
2810
-                    $messenger_slug,
2811
-                    $message_type_slug
2812
-                );
2813
-
2814
-                $system_validation = ! is_array($system_validation) && $system_validation ? array()
2815
-                    : $system_validation;
2816
-                $validates = array_merge($custom_validation, $system_validation);
2817
-
2818
-                // if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2819
-                // appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2820
-                //  WE need to make sure there is no actual error messages in validates.
2821
-                if (is_array($validates) && ! empty($validates)) {
2822
-                    // add the transient so when the form loads we know which fields to highlight
2823
-                    $this->_add_transient('edit_message_template', $validates);
2824
-
2825
-                    $success = 0;
2826
-
2827
-                    // setup notices
2828
-                    foreach ($validates as $field => $error) {
2829
-                        if (isset($error['msg'])) {
2830
-                            EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2831
-                        }
2832
-                    }
2833
-                } else {
2834
-                    $set_column_values = array();
2835
-                    foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2836
-                        $set_column_values = $this->_set_message_template_column_values($template_field);
2837
-
2838
-                        $where_cols_n_values = array(
2839
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2840
-                        );
2841
-                        // if they aren't allowed to use all JS, restrict them to just posty-y tags
2842
-                        if (! current_user_can('unfiltered_html')) {
2843
-                            if (is_array($set_column_values['MTP_content'])) {
2844
-                                foreach ($set_column_values['MTP_content'] as $key => $value) {
2845
-                                    // remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2846
-                                    // only removes slashes from double-quotes, so attributes using single quotes always
2847
-                                    // appear invalid.) But currently the models expect slashed data, so after wp_kses
2848
-                                    // runs we need to re-slash the data. Sheesh. See
2849
-                                    // https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2850
-                                    $set_column_values['MTP_content'][ $key ] = addslashes(
2851
-                                        wp_kses(
2852
-                                            stripslashes($value),
2853
-                                            wp_kses_allowed_html('post')
2854
-                                        )
2855
-                                    );
2856
-                                }
2857
-                            } else {
2858
-                                $set_column_values['MTP_content'] = wp_kses(
2859
-                                    $set_column_values['MTP_content'],
2860
-                                    wp_kses_allowed_html('post')
2861
-                                );
2862
-                            }
2863
-                        }
2864
-                        $message_template_fields = array(
2865
-                            'GRP_ID'             => $set_column_values['GRP_ID'],
2866
-                            'MTP_template_field' => $set_column_values['MTP_template_field'],
2867
-                            'MTP_context'        => $set_column_values['MTP_context'],
2868
-                            'MTP_content'        => $set_column_values['MTP_content'],
2869
-                        );
2870
-                        if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2871
-                            if ($updated === false) {
2872
-                                EE_Error::add_error(
2873
-                                    sprintf(
2874
-                                        esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2875
-                                        $template_field
2876
-                                    ),
2877
-                                    __FILE__,
2878
-                                    __FUNCTION__,
2879
-                                    __LINE__
2880
-                                );
2881
-                            } else {
2882
-                                $success = 1;
2883
-                            }
2884
-                        } else {
2885
-                            // only do this logic if we don't have a MTP_ID for this field
2886
-                            if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2887
-                                // this has already been through the template field validator and sanitized, so it will be
2888
-                                // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2889
-                                // message template field in a messenger/message type and existing users don't have the
2890
-                                // default setup for it.
2891
-                                // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2892
-                                $updated = $MTP->insert($message_template_fields);
2893
-                                if (! $updated || is_wp_error($updated)) {
2894
-                                    EE_Error::add_error(
2895
-                                        sprintf(
2896
-                                            esc_html__('%s field could not be updated.', 'event_espresso'),
2897
-                                            $template_field
2898
-                                        ),
2899
-                                        __FILE__,
2900
-                                        __FUNCTION__,
2901
-                                        __LINE__
2902
-                                    );
2903
-                                    $success = 0;
2904
-                                } else {
2905
-                                    $success = 1;
2906
-                                }
2907
-                            }
2908
-                        }
2909
-                        $action_desc = 'updated';
2910
-                    }
2911
-
2912
-                    // we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2913
-                    $mtpg_fields = array(
2914
-                        'MTP_user_id'      => $set_column_values['MTP_user_id'],
2915
-                        'MTP_messenger'    => $set_column_values['MTP_messenger'],
2916
-                        'MTP_message_type' => $set_column_values['MTP_message_type'],
2917
-                        'MTP_is_global'    => $set_column_values['MTP_is_global'],
2918
-                        'MTP_is_override'  => $set_column_values['MTP_is_override'],
2919
-                        'MTP_deleted'      => $set_column_values['MTP_deleted'],
2920
-                        'MTP_is_active'    => $set_column_values['MTP_is_active'],
2921
-                        'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2922
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2923
-                            : '',
2924
-                        'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2925
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2926
-                            : '',
2927
-                    );
2928
-
2929
-                    $mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2930
-                    $updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2931
-
2932
-                    if ($updated === false) {
2933
-                        EE_Error::add_error(
2934
-                            sprintf(
2935
-                                esc_html__(
2936
-                                    'The Message Template Group (%d) was NOT updated for some reason',
2937
-                                    'event_espresso'
2938
-                                ),
2939
-                                $set_column_values['GRP_ID']
2940
-                            ),
2941
-                            __FILE__,
2942
-                            __FUNCTION__,
2943
-                            __LINE__
2944
-                        );
2945
-                    } else {
2946
-                        // k now we need to ensure the template_pack and template_variation fields are set.
2947
-                        $template_pack = ! empty($this->_req_data['MTP_template_pack'])
2948
-                            ? $this->_req_data['MTP_template_pack']
2949
-                            : 'default';
2950
-
2951
-                        $template_variation = ! empty($this->_req_data['MTP_template_variation'])
2952
-                            ? $this->_req_data['MTP_template_variation']
2953
-                            : 'default';
2954
-
2955
-                        $mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2956
-                        if ($mtpg_obj instanceof EE_Message_Template_Group) {
2957
-                            $mtpg_obj->set_template_pack_name($template_pack);
2958
-                            $mtpg_obj->set_template_pack_variation($template_variation);
2959
-                        }
2960
-                        $success = 1;
2961
-                    }
2962
-                }
2963
-            }
2964
-        }
2965
-
2966
-        // we return things differently if doing ajax
2967
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2968
-            $this->_template_args['success'] = $success;
2969
-            $this->_template_args['error'] = ! $success ? true : false;
2970
-            $this->_template_args['content'] = '';
2971
-            $this->_template_args['data'] = array(
2972
-                'grpID'        => $edit_array['GRP_ID'],
2973
-                'templateName' => $edit_array['template_name'],
2974
-            );
2975
-            if ($success) {
2976
-                EE_Error::overwrite_success();
2977
-                EE_Error::add_success(
2978
-                    esc_html__(
2979
-                        '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.',
2980
-                        'event_espresso'
2981
-                    )
2982
-                );
2983
-            }
2984
-
2985
-            $this->_return_json();
2986
-        }
2987
-
2988
-
2989
-        // was a test send triggered?
2990
-        if (isset($this->_req_data['test_button'])) {
2991
-            EE_Error::overwrite_success();
2992
-            $this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2993
-            $override = true;
2994
-        }
2995
-
2996
-        if (empty($query_args)) {
2997
-            $query_args = array(
2998
-                'id'      => $this->_req_data['GRP_ID'],
2999
-                'context' => $context_slug,
3000
-                'action'  => 'edit_message_template',
3001
-            );
3002
-        }
3003
-
3004
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3005
-    }
3006
-
3007
-
3008
-    /**
3009
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
3010
-     *
3011
-     * @param  string $context      what context being tested
3012
-     * @param  string $messenger    messenger being tested
3013
-     * @param  string $message_type message type being tested
3014
-     * @throws EE_Error
3015
-     * @throws InvalidArgumentException
3016
-     * @throws InvalidDataTypeException
3017
-     * @throws InvalidInterfaceException
3018
-     */
3019
-    protected function _do_test_send($context, $messenger, $message_type)
3020
-    {
3021
-        // set things up for preview
3022
-        $this->_req_data['messenger'] = $messenger;
3023
-        $this->_req_data['message_type'] = $message_type;
3024
-        $this->_req_data['context'] = $context;
3025
-        $this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3026
-        $active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3027
-
3028
-        // let's save any existing fields that might be required by the messenger
3029
-        if (isset($this->_req_data['test_settings_fld'])
3030
-            && $active_messenger instanceof EE_messenger
3031
-            && apply_filters(
3032
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3033
-                true,
3034
-                $this->_req_data['test_settings_fld'],
3035
-                $active_messenger
3036
-            )
3037
-        ) {
3038
-            $active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3039
-        }
3040
-
3041
-        /**
3042
-         * Use filter to add additional controls on whether message can send or not
3043
-         */
3044
-        if (apply_filters(
3045
-            'FHEE__Messages_Admin_Page__do_test_send__can_send',
3046
-            true,
3047
-            $context,
3048
-            $this->_req_data,
3049
-            $messenger,
3050
-            $message_type
3051
-        )) {
3052
-            if (EEM_Event::instance()->count() > 0) {
3053
-                $success = $this->_preview_message(true);
3054
-                if ($success) {
3055
-                    EE_Error::add_success(__('Test message sent', 'event_espresso'));
3056
-                } else {
3057
-                    EE_Error::add_error(
3058
-                        esc_html__('The test message was not sent', 'event_espresso'),
3059
-                        __FILE__,
3060
-                        __FUNCTION__,
3061
-                        __LINE__
3062
-                    );
3063
-                }
3064
-            } else {
3065
-                $this->noEventsErrorMessage(true);
3066
-            }
3067
-        }
3068
-    }
3069
-
3070
-
3071
-    /**
3072
-     * _generate_new_templates
3073
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3074
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3075
-     * for the event.
3076
-     *
3077
-     *
3078
-     * @param  string $messenger     the messenger we are generating templates for
3079
-     * @param array   $message_types array of message types that the templates are generated for.
3080
-     * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3081
-     *                               indicate the message_template_group being used as the base.
3082
-     *
3083
-     * @param bool    $global
3084
-     *
3085
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
3086
-     *                               encountering problems.
3087
-     * @throws EE_Error
3088
-     */
3089
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3090
-    {
3091
-
3092
-        // if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3093
-        // just don't generate any templates.
3094
-        if (empty($message_types)) {
3095
-            return true;
3096
-        }
3097
-
3098
-        return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3099
-    }
3100
-
3101
-
3102
-    /**
3103
-     * [_trash_or_restore_message_template]
3104
-     *
3105
-     * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3106
-     * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3107
-     *                        an individual context (FALSE).
3108
-     * @return void
3109
-     * @throws EE_Error
3110
-     * @throws InvalidArgumentException
3111
-     * @throws InvalidDataTypeException
3112
-     * @throws InvalidInterfaceException
3113
-     */
3114
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
3115
-    {
3116
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3117
-        $MTP = EEM_Message_Template_Group::instance();
3118
-
3119
-        $success = 1;
3120
-
3121
-        // incoming GRP_IDs
3122
-        if ($all) {
3123
-            // Checkboxes
3124
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3125
-                // if array has more than one element then success message should be plural.
3126
-                // todo: what about nonce?
3127
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3128
-
3129
-                // cycle through checkboxes
3130
-                while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3131
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3132
-                    if (! $trashed_or_restored) {
3133
-                        $success = 0;
3134
-                    }
3135
-                }
3136
-            } else {
3137
-                // grab single GRP_ID and handle
3138
-                $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3139
-                if (! empty($GRP_ID)) {
3140
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3141
-                    if (! $trashed_or_restored) {
3142
-                        $success = 0;
3143
-                    }
3144
-                } else {
3145
-                    $success = 0;
3146
-                }
3147
-            }
3148
-        }
3149
-
3150
-        $action_desc = $trash
3151
-            ? esc_html__('moved to the trash', 'event_espresso')
3152
-            : esc_html__('restored', 'event_espresso');
3153
-
3154
-        $action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3155
-
3156
-        $item_desc = $all ? _n(
3157
-            'Message Template Group',
3158
-            'Message Template Groups',
3159
-            $success,
3160
-            'event_espresso'
3161
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3162
-
3163
-        $item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3164
-            'template',
3165
-            'templates',
3166
-            $success,
3167
-            'event_espresso'
3168
-        ) : $item_desc;
3169
-
3170
-        $this->_redirect_after_action($success, $item_desc, $action_desc, array());
3171
-    }
3172
-
3173
-
3174
-    /**
3175
-     * [_delete_message_template]
3176
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3177
-     *
3178
-     * @return void
3179
-     * @throws EE_Error
3180
-     * @throws InvalidArgumentException
3181
-     * @throws InvalidDataTypeException
3182
-     * @throws InvalidInterfaceException
3183
-     */
3184
-    protected function _delete_message_template()
3185
-    {
3186
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3187
-
3188
-        // checkboxes
3189
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3190
-            // if array has more than one element then success message should be plural
3191
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3192
-
3193
-            // cycle through bulk action checkboxes
3194
-            while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3195
-                $success = $this->_delete_mtp_permanently($GRP_ID);
3196
-            }
3197
-        } else {
3198
-            // grab single grp_id and delete
3199
-            $GRP_ID = absint($this->_req_data['id']);
3200
-            $success = $this->_delete_mtp_permanently($GRP_ID);
3201
-        }
3202
-
3203
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3204
-    }
3205
-
3206
-
3207
-    /**
3208
-     * helper for permanently deleting a mtP group and all related message_templates
3209
-     *
3210
-     * @param  int  $GRP_ID        The group being deleted
3211
-     * @param  bool $include_group whether to delete the Message Template Group as well.
3212
-     * @return bool boolean to indicate the success of the deletes or not.
3213
-     * @throws EE_Error
3214
-     * @throws InvalidArgumentException
3215
-     * @throws InvalidDataTypeException
3216
-     * @throws InvalidInterfaceException
3217
-     */
3218
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3219
-    {
3220
-        $success = 1;
3221
-        $MTPG = EEM_Message_Template_Group::instance();
3222
-        // first let's GET this group
3223
-        $MTG = $MTPG->get_one_by_ID($GRP_ID);
3224
-        // then delete permanently all the related Message Templates
3225
-        $deleted = $MTG->delete_related_permanently('Message_Template');
3226
-
3227
-        if ($deleted === 0) {
3228
-            $success = 0;
3229
-        }
3230
-
3231
-        // now delete permanently this particular group
3232
-
3233
-        if ($include_group && ! $MTG->delete_permanently()) {
3234
-            $success = 0;
3235
-        }
3236
-
3237
-        return $success;
3238
-    }
3239
-
3240
-
3241
-    /**
3242
-     *    _learn_more_about_message_templates_link
3243
-     *
3244
-     * @access protected
3245
-     * @return string
3246
-     */
3247
-    protected function _learn_more_about_message_templates_link()
3248
-    {
3249
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3250
-               . esc_html__('learn more about how message templates works', 'event_espresso')
3251
-               . '</a>';
3252
-    }
3253
-
3254
-
3255
-    /**
3256
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3257
-     * ajax and other routes.
3258
-     *
3259
-     * @return void
3260
-     * @throws DomainException
3261
-     */
3262
-    protected function _settings()
3263
-    {
3264
-
3265
-
3266
-        $this->_set_m_mt_settings();
3267
-
3268
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3269
-            ? $this->_req_data['selected_messenger']
3270
-            : 'email';
3271
-
3272
-        // let's setup the messenger tabs
3273
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3274
-            $this->_m_mt_settings['messenger_tabs'],
3275
-            'messenger_links',
3276
-            '|',
3277
-            $selected_messenger
3278
-        );
3279
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3280
-        $this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3281
-
3282
-        $this->display_admin_page_with_sidebar();
3283
-    }
3284
-
3285
-
3286
-    /**
3287
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3288
-     *
3289
-     * @access protected
3290
-     * @return void
3291
-     * @throws DomainException
3292
-     */
3293
-    protected function _set_m_mt_settings()
3294
-    {
3295
-        // first if this is already set then lets get out no need to regenerate data.
3296
-        if (! empty($this->_m_mt_settings)) {
3297
-            return;
3298
-        }
3299
-
3300
-        // get all installed messengers and message_types
3301
-        /** @type EE_messenger[] $messengers */
3302
-        $messengers = $this->_message_resource_manager->installed_messengers();
3303
-        /** @type EE_message_type[] $message_types */
3304
-        $message_types = $this->_message_resource_manager->installed_message_types();
3305
-
3306
-
3307
-        // assemble the array for the _tab_text_links helper
3308
-
3309
-        foreach ($messengers as $messenger) {
3310
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3311
-                'label' => ucwords($messenger->label['singular']),
3312
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3313
-                    ? 'messenger-active'
3314
-                    : '',
3315
-                'href'  => $messenger->name,
3316
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3317
-                'slug'  => $messenger->name,
3318
-                'obj'   => $messenger,
3319
-            );
3320
-
3321
-
3322
-            $message_types_for_messenger = $messenger->get_valid_message_types();
3323
-
3324
-            foreach ($message_types as $message_type) {
3325
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3326
-                // it shouldn't show in either the inactive OR active metabox.
3327
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3328
-                    continue;
3329
-                }
3330
-
3331
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3332
-                    $messenger->name,
3333
-                    $message_type->name
3334
-                )
3335
-                    ? 'active'
3336
-                    : 'inactive';
3337
-
3338
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3339
-                    'label'    => ucwords($message_type->label['singular']),
3340
-                    'class'    => 'message-type-' . $a_or_i,
3341
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3342
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3343
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3344
-                    'title'    => $a_or_i === 'active'
3345
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3346
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3347
-                    'content'  => $a_or_i === 'active'
3348
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
3349
-                        : $this->_message_type_settings_content($message_type, $messenger),
3350
-                    'slug'     => $message_type->name,
3351
-                    'active'   => $a_or_i === 'active',
3352
-                    'obj'      => $message_type,
3353
-                );
3354
-            }
3355
-        }
3356
-    }
3357
-
3358
-
3359
-    /**
3360
-     * This just prepares the content for the message type settings
3361
-     *
3362
-     * @param  EE_message_type $message_type The message type object
3363
-     * @param  EE_messenger    $messenger    The messenger object
3364
-     * @param  boolean         $active       Whether the message type is active or not
3365
-     * @return string html output for the content
3366
-     * @throws DomainException
3367
-     */
3368
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
3369
-    {
3370
-        // get message type fields
3371
-        $fields = $message_type->get_admin_settings_fields();
3372
-        $settings_template_args['template_form_fields'] = '';
3373
-
3374
-        if (! empty($fields) && $active) {
3375
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3376
-            foreach ($fields as $fldname => $fldprops) {
3377
-                $field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3378
-                $template_form_field[ $field_id ] = array(
3379
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3380
-                    'label'      => $fldprops['label'],
3381
-                    'input'      => $fldprops['field_type'],
3382
-                    'type'       => $fldprops['value_type'],
3383
-                    'required'   => $fldprops['required'],
3384
-                    'validation' => $fldprops['validation'],
3385
-                    'value'      => isset($existing_settings[ $fldname ])
3386
-                        ? $existing_settings[ $fldname ]
3387
-                        : $fldprops['default'],
3388
-                    'options'    => isset($fldprops['options'])
3389
-                        ? $fldprops['options']
3390
-                        : array(),
3391
-                    'default'    => isset($existing_settings[ $fldname ])
3392
-                        ? $existing_settings[ $fldname ]
3393
-                        : $fldprops['default'],
3394
-                    'css_class'  => 'no-drag',
3395
-                    'format'     => $fldprops['format'],
3396
-                );
3397
-            }
3398
-
3399
-
3400
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3401
-                ? $this->_generate_admin_form_fields(
3402
-                    $template_form_field,
3403
-                    'string',
3404
-                    'ee_mt_activate_form'
3405
-                )
3406
-                : '';
3407
-        }
3408
-
3409
-        $settings_template_args['description'] = $message_type->description;
3410
-        // we also need some hidden fields
3411
-        $settings_template_args['hidden_fields'] = array(
3412
-            'message_type_settings[messenger]'    => array(
3413
-                'type'  => 'hidden',
3414
-                'value' => $messenger->name,
3415
-            ),
3416
-            'message_type_settings[message_type]' => array(
3417
-                'type'  => 'hidden',
3418
-                'value' => $message_type->name,
3419
-            ),
3420
-            'type'                                => array(
3421
-                'type'  => 'hidden',
3422
-                'value' => 'message_type',
3423
-            ),
3424
-        );
3425
-
3426
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3427
-            $settings_template_args['hidden_fields'],
3428
-            'array'
3429
-        );
3430
-        $settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3431
-            ? ' hidden'
3432
-            : '';
3433
-
3434
-
3435
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3436
-        $content = EEH_Template::display_template($template, $settings_template_args, true);
3437
-
3438
-        return $content;
3439
-    }
3440
-
3441
-
3442
-    /**
3443
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3444
-     *
3445
-     * @access protected
3446
-     * @return void
3447
-     * @throws DomainException
3448
-     */
3449
-    protected function _messages_settings_metaboxes()
3450
-    {
3451
-        $this->_set_m_mt_settings();
3452
-        $m_boxes = $mt_boxes = array();
3453
-        $m_template_args = $mt_template_args = array();
3454
-
3455
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3456
-            ? $this->_req_data['selected_messenger']
3457
-            : 'email';
3458
-
3459
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3460
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3461
-                $hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3462
-                $hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3463
-                // messenger meta boxes
3464
-                $active = $selected_messenger === $messenger;
3465
-                $active_mt_tabs = isset(
3466
-                    $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3467
-                )
3468
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3469
-                    : '';
3470
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3471
-                    esc_html__('%s Settings', 'event_espresso'),
3472
-                    $tab_array['label']
3473
-                );
3474
-                $m_template_args[ $messenger . '_a_box' ] = array(
3475
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3476
-                    'inactive_message_types' => isset(
3477
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3478
-                    )
3479
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3480
-                        : '',
3481
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3482
-                    'hidden'                 => $active ? '' : ' hidden',
3483
-                    'hide_on_message'        => $hide_on_message,
3484
-                    'messenger'              => $messenger,
3485
-                    'active'                 => $active,
3486
-                );
3487
-                // message type meta boxes
3488
-                // (which is really just the inactive container for each messenger
3489
-                // showing inactive message types for that messenger)
3490
-                $mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3491
-                $mt_template_args[ $messenger . '_i_box' ] = array(
3492
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3493
-                    'inactive_message_types' => isset(
3494
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3495
-                    )
3496
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3497
-                        : '',
3498
-                    'hidden'                 => $active ? '' : ' hidden',
3499
-                    'hide_on_message'        => $hide_on_message,
3500
-                    'hide_off_message'       => $hide_off_message,
3501
-                    'messenger'              => $messenger,
3502
-                    'active'                 => $active,
3503
-                );
3504
-            }
3505
-        }
3506
-
3507
-
3508
-        // register messenger metaboxes
3509
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3510
-        foreach ($m_boxes as $box => $label) {
3511
-            $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3512
-            $msgr = str_replace('_a_box', '', $box);
3513
-            add_meta_box(
3514
-                'espresso_' . $msgr . '_settings',
3515
-                $label,
3516
-                function ($post, $metabox) {
3517
-                    echo EEH_Template::display_template(
3518
-                        $metabox["args"]["template_path"],
3519
-                        $metabox["args"]["template_args"],
3520
-                        true
3521
-                    );
3522
-                },
3523
-                $this->_current_screen->id,
3524
-                'normal',
3525
-                'high',
3526
-                $callback_args
3527
-            );
3528
-        }
3529
-
3530
-        // register message type metaboxes
3531
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3532
-        foreach ($mt_boxes as $box => $label) {
3533
-            $callback_args = array(
3534
-                'template_path' => $mt_template_path,
3535
-                'template_args' => $mt_template_args[ $box ],
3536
-            );
3537
-            $mt = str_replace('_i_box', '', $box);
3538
-            add_meta_box(
3539
-                'espresso_' . $mt . '_inactive_mts',
3540
-                $label,
3541
-                function ($post, $metabox) {
3542
-                    echo EEH_Template::display_template(
3543
-                        $metabox["args"]["template_path"],
3544
-                        $metabox["args"]["template_args"],
3545
-                        true
3546
-                    );
3547
-                },
3548
-                $this->_current_screen->id,
3549
-                'side',
3550
-                'high',
3551
-                $callback_args
3552
-            );
3553
-        }
3554
-
3555
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3556
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3557
-        if (is_main_site()) {
3558
-            add_meta_box(
3559
-                'espresso_global_message_settings',
3560
-                esc_html__('Global Message Settings', 'event_espresso'),
3561
-                array($this, 'global_messages_settings_metabox_content'),
3562
-                $this->_current_screen->id,
3563
-                'normal',
3564
-                'low',
3565
-                array()
3566
-            );
3567
-        }
3568
-    }
3569
-
3570
-
3571
-    /**
3572
-     *  This generates the content for the global messages settings metabox.
3573
-     *
3574
-     * @return string
3575
-     * @throws EE_Error
3576
-     * @throws InvalidArgumentException
3577
-     * @throws ReflectionException
3578
-     * @throws InvalidDataTypeException
3579
-     * @throws InvalidInterfaceException
3580
-     */
3581
-    public function global_messages_settings_metabox_content()
3582
-    {
3583
-        $form = $this->_generate_global_settings_form();
3584
-        echo $form->form_open(
3585
-            $this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3586
-            'POST'
3587
-        )
3588
-             . $form->get_html()
3589
-             . $form->form_close();
3590
-    }
3591
-
3592
-
3593
-    /**
3594
-     * This generates and returns the form object for the global messages settings.
3595
-     *
3596
-     * @return EE_Form_Section_Proper
3597
-     * @throws EE_Error
3598
-     * @throws InvalidArgumentException
3599
-     * @throws ReflectionException
3600
-     * @throws InvalidDataTypeException
3601
-     * @throws InvalidInterfaceException
3602
-     */
3603
-    protected function _generate_global_settings_form()
3604
-    {
3605
-        EE_Registry::instance()->load_helper('HTML');
3606
-        /** @var EE_Network_Core_Config $network_config */
3607
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3608
-
3609
-        return new EE_Form_Section_Proper(
3610
-            array(
3611
-                'name'            => 'global_messages_settings',
3612
-                'html_id'         => 'global_messages_settings',
3613
-                'html_class'      => 'form-table',
3614
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3615
-                'subsections'     => apply_filters(
3616
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3617
-                    array(
3618
-                        'do_messages_on_same_request' => new EE_Select_Input(
3619
-                            array(
3620
-                                true  => esc_html__("On the same request", "event_espresso"),
3621
-                                false => esc_html__("On a separate request", "event_espresso"),
3622
-                            ),
3623
-                            array(
3624
-                                'default'         => $network_config->do_messages_on_same_request,
3625
-                                'html_label_text' => esc_html__(
3626
-                                    'Generate and send all messages:',
3627
-                                    'event_espresso'
3628
-                                ),
3629
-                                'html_help_text'  => esc_html__(
3630
-                                    '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.',
3631
-                                    'event_espresso'
3632
-                                ),
3633
-                            )
3634
-                        ),
3635
-                        'delete_threshold'            => new EE_Select_Input(
3636
-                            array(
3637
-                                0  => esc_html__('Forever', 'event_espresso'),
3638
-                                3  => esc_html__('3 Months', 'event_espresso'),
3639
-                                6  => esc_html__('6 Months', 'event_espresso'),
3640
-                                9  => esc_html__('9 Months', 'event_espresso'),
3641
-                                12 => esc_html__('12 Months', 'event_espresso'),
3642
-                                24 => esc_html__('24 Months', 'event_espresso'),
3643
-                                36 => esc_html__('36 Months', 'event_espresso'),
3644
-                            ),
3645
-                            array(
3646
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3647
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3648
-                                'html_help_text'  => esc_html__(
3649
-                                    'You can control how long a record of processed messages is kept via this option.',
3650
-                                    'event_espresso'
3651
-                                ),
3652
-                            )
3653
-                        ),
3654
-                        'update_settings'             => new EE_Submit_Input(
3655
-                            array(
3656
-                                'default'         => esc_html__('Update', 'event_espresso'),
3657
-                                'html_label_text' => '&nbsp',
3658
-                            )
3659
-                        ),
3660
-                    )
3661
-                ),
3662
-            )
3663
-        );
3664
-    }
3665
-
3666
-
3667
-    /**
3668
-     * This handles updating the global settings set on the admin page.
3669
-     *
3670
-     * @throws EE_Error
3671
-     * @throws InvalidDataTypeException
3672
-     * @throws InvalidInterfaceException
3673
-     * @throws InvalidArgumentException
3674
-     * @throws ReflectionException
3675
-     */
3676
-    protected function _update_global_settings()
3677
-    {
3678
-        /** @var EE_Network_Core_Config $network_config */
3679
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3680
-        $messages_config = EE_Registry::instance()->CFG->messages;
3681
-        $form = $this->_generate_global_settings_form();
3682
-        if ($form->was_submitted()) {
3683
-            $form->receive_form_submission();
3684
-            if ($form->is_valid()) {
3685
-                $valid_data = $form->valid_data();
3686
-                foreach ($valid_data as $property => $value) {
3687
-                    $setter = 'set_' . $property;
3688
-                    if (method_exists($network_config, $setter)) {
3689
-                        $network_config->{$setter}($value);
3690
-                    } elseif (property_exists($network_config, $property)
3691
-                        && $network_config->{$property} !== $value
3692
-                    ) {
3693
-                        $network_config->{$property} = $value;
3694
-                    } elseif (property_exists($messages_config, $property)
3695
-                        && $messages_config->{$property} !== $value
3696
-                    ) {
3697
-                        $messages_config->{$property} = $value;
3698
-                    }
3699
-                }
3700
-                // only update if the form submission was valid!
3701
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3702
-                EE_Registry::instance()->CFG->update_espresso_config();
3703
-                EE_Error::overwrite_success();
3704
-                EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3705
-            }
3706
-        }
3707
-        $this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3708
-    }
3709
-
3710
-
3711
-    /**
3712
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3713
-     *
3714
-     * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3715
-     * @return string html formatted tabs
3716
-     * @throws DomainException
3717
-     */
3718
-    protected function _get_mt_tabs($tab_array)
3719
-    {
3720
-        $tab_array = (array) $tab_array;
3721
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3722
-        $tabs = '';
3723
-
3724
-        foreach ($tab_array as $tab) {
3725
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3726
-        }
3727
-
3728
-        return $tabs;
3729
-    }
3730
-
3731
-
3732
-    /**
3733
-     * This prepares the content of the messenger meta box admin settings
3734
-     *
3735
-     * @param  EE_messenger $messenger The messenger we're setting up content for
3736
-     * @return string html formatted content
3737
-     * @throws DomainException
3738
-     */
3739
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3740
-    {
3741
-
3742
-        $fields = $messenger->get_admin_settings_fields();
3743
-        $settings_template_args['template_form_fields'] = '';
3744
-
3745
-        // is $messenger active?
3746
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3747
-
3748
-
3749
-        if (! empty($fields)) {
3750
-            $existing_settings = $messenger->get_existing_admin_settings();
3751
-
3752
-            foreach ($fields as $fldname => $fldprops) {
3753
-                $field_id = $messenger->name . '-' . $fldname;
3754
-                $template_form_field[ $field_id ] = array(
3755
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3756
-                    'label'      => $fldprops['label'],
3757
-                    'input'      => $fldprops['field_type'],
3758
-                    'type'       => $fldprops['value_type'],
3759
-                    'required'   => $fldprops['required'],
3760
-                    'validation' => $fldprops['validation'],
3761
-                    'value'      => isset($existing_settings[ $field_id ])
3762
-                        ? $existing_settings[ $field_id ]
3763
-                        : $fldprops['default'],
3764
-                    'css_class'  => '',
3765
-                    'format'     => $fldprops['format'],
3766
-                );
3767
-            }
3768
-
3769
-
3770
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3771
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3772
-                : '';
3773
-        }
3774
-
3775
-        // we also need some hidden fields
3776
-        $settings_template_args['hidden_fields'] = array(
3777
-            'messenger_settings[messenger]' => array(
3778
-                'type'  => 'hidden',
3779
-                'value' => $messenger->name,
3780
-            ),
3781
-            'type'                          => array(
3782
-                'type'  => 'hidden',
3783
-                'value' => 'messenger',
3784
-            ),
3785
-        );
3786
-
3787
-        // make sure any active message types that are existing are included in the hidden fields
3788
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3789
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3790
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3791
-                    'type'  => 'hidden',
3792
-                    'value' => $mt,
3793
-                );
3794
-            }
3795
-        }
3796
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3797
-            $settings_template_args['hidden_fields'],
3798
-            'array'
3799
-        );
3800
-        $active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3801
-
3802
-        $settings_template_args['messenger'] = $messenger->name;
3803
-        $settings_template_args['description'] = $messenger->description;
3804
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3805
-
3806
-
3807
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3808
-            $messenger->name
3809
-        )
3810
-            ? $settings_template_args['show_hide_edit_form']
3811
-            : ' hidden';
3812
-
3813
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3814
-            ? ' hidden'
3815
-            : $settings_template_args['show_hide_edit_form'];
3816
-
3817
-
3818
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3819
-        $settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3820
-        $settings_template_args['on_off_status'] = $active ? true : false;
3821
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3822
-        $content = EEH_Template::display_template(
3823
-            $template,
3824
-            $settings_template_args,
3825
-            true
3826
-        );
3827
-
3828
-        return $content;
3829
-    }
3830
-
3831
-
3832
-    /**
3833
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3834
-     *
3835
-     * @throws DomainException
3836
-     * @throws EE_Error
3837
-     * @throws InvalidDataTypeException
3838
-     * @throws InvalidInterfaceException
3839
-     * @throws InvalidArgumentException
3840
-     * @throws ReflectionException
3841
-     */
3842
-    public function activate_messenger_toggle()
3843
-    {
3844
-        $success = true;
3845
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3846
-        // let's check that we have required data
3847
-        if (! isset($this->_req_data['messenger'])) {
3848
-            EE_Error::add_error(
3849
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3850
-                __FILE__,
3851
-                __FUNCTION__,
3852
-                __LINE__
3853
-            );
3854
-            $success = false;
3855
-        }
3856
-
3857
-        // do a nonce check here since we're not arriving via a normal route
3858
-        $nonce = isset($this->_req_data['activate_nonce'])
3859
-            ? sanitize_text_field($this->_req_data['activate_nonce'])
3860
-            : '';
3861
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3862
-
3863
-        $this->_verify_nonce($nonce, $nonce_ref);
3864
-
3865
-
3866
-        if (! isset($this->_req_data['status'])) {
3867
-            EE_Error::add_error(
3868
-                esc_html__(
3869
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3870
-                    'event_espresso'
3871
-                ),
3872
-                __FILE__,
3873
-                __FUNCTION__,
3874
-                __LINE__
3875
-            );
3876
-            $success = false;
3877
-        }
3878
-
3879
-        // do check to verify we have a valid status.
3880
-        $status = $this->_req_data['status'];
3881
-
3882
-        if ($status !== 'off' && $status !== 'on') {
3883
-            EE_Error::add_error(
3884
-                sprintf(
3885
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3886
-                    $this->_req_data['status']
3887
-                ),
3888
-                __FILE__,
3889
-                __FUNCTION__,
3890
-                __LINE__
3891
-            );
3892
-            $success = false;
3893
-        }
3894
-
3895
-        if ($success) {
3896
-            // made it here?  Stop dawdling then!!
3897
-            $success = $status === 'off'
3898
-                ? $this->_deactivate_messenger($this->_req_data['messenger'])
3899
-                : $this->_activate_messenger($this->_req_data['messenger']);
3900
-        }
3901
-
3902
-        $this->_template_args['success'] = $success;
3903
-
3904
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
3905
-        $this->_return_json();
3906
-    }
3907
-
3908
-
3909
-    /**
3910
-     * used by ajax from the messages settings page to activate|deactivate a message type
3911
-     *
3912
-     * @throws DomainException
3913
-     * @throws EE_Error
3914
-     * @throws ReflectionException
3915
-     * @throws InvalidDataTypeException
3916
-     * @throws InvalidInterfaceException
3917
-     * @throws InvalidArgumentException
3918
-     */
3919
-    public function activate_mt_toggle()
3920
-    {
3921
-        $success = true;
3922
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3923
-
3924
-        // let's make sure we have the necessary data
3925
-        if (! isset($this->_req_data['message_type'])) {
3926
-            EE_Error::add_error(
3927
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3928
-                __FILE__,
3929
-                __FUNCTION__,
3930
-                __LINE__
3931
-            );
3932
-            $success = false;
3933
-        }
3934
-
3935
-        if (! isset($this->_req_data['messenger'])) {
3936
-            EE_Error::add_error(
3937
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3938
-                __FILE__,
3939
-                __FUNCTION__,
3940
-                __LINE__
3941
-            );
3942
-            $success = false;
3943
-        }
3944
-
3945
-        if (! isset($this->_req_data['status'])) {
3946
-            EE_Error::add_error(
3947
-                esc_html__(
3948
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3949
-                    'event_espresso'
3950
-                ),
3951
-                __FILE__,
3952
-                __FUNCTION__,
3953
-                __LINE__
3954
-            );
3955
-            $success = false;
3956
-        }
3957
-
3958
-
3959
-        // do check to verify we have a valid status.
3960
-        $status = $this->_req_data['status'];
3961
-
3962
-        if ($status !== 'activate' && $status !== 'deactivate') {
3963
-            EE_Error::add_error(
3964
-                sprintf(
3965
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3966
-                    $this->_req_data['status']
3967
-                ),
3968
-                __FILE__,
3969
-                __FUNCTION__,
3970
-                __LINE__
3971
-            );
3972
-            $success = false;
3973
-        }
3974
-
3975
-
3976
-        // do a nonce check here since we're not arriving via a normal route
3977
-        $nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3978
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3979
-
3980
-        $this->_verify_nonce($nonce, $nonce_ref);
3981
-
3982
-        if ($success) {
3983
-            // made it here? um, what are you waiting for then?
3984
-            $success = $status === 'deactivate'
3985
-                ? $this->_deactivate_message_type_for_messenger(
3986
-                    $this->_req_data['messenger'],
3987
-                    $this->_req_data['message_type']
3988
-                )
3989
-                : $this->_activate_message_type_for_messenger(
3990
-                    $this->_req_data['messenger'],
3991
-                    $this->_req_data['message_type']
3992
-                );
3993
-        }
3994
-
3995
-        $this->_template_args['success'] = $success;
3996
-        $this->_return_json();
3997
-    }
3998
-
3999
-
4000
-    /**
4001
-     * Takes care of processing activating a messenger and preparing the appropriate response.
4002
-     *
4003
-     * @param string $messenger_name The name of the messenger being activated
4004
-     * @return bool
4005
-     * @throws DomainException
4006
-     * @throws EE_Error
4007
-     * @throws InvalidArgumentException
4008
-     * @throws ReflectionException
4009
-     * @throws InvalidDataTypeException
4010
-     * @throws InvalidInterfaceException
4011
-     */
4012
-    protected function _activate_messenger($messenger_name)
4013
-    {
4014
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4015
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4016
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
4017
-            ? $active_messenger->get_default_message_types()
4018
-            : array();
4019
-
4020
-        // ensure is active
4021
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4022
-
4023
-        // set response_data for reload
4024
-        foreach ($message_types_to_activate as $message_type_name) {
4025
-            /** @var EE_message_type $message_type */
4026
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4027
-            if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4028
-                $messenger_name,
4029
-                $message_type_name
4030
-            )
4031
-                && $message_type instanceof EE_message_type
4032
-            ) {
4033
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
4034
-                if ($message_type->get_admin_settings_fields()) {
4035
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
4036
-                }
4037
-            }
4038
-        }
4039
-
4040
-        // add success message for activating messenger
4041
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4042
-    }
4043
-
4044
-
4045
-    /**
4046
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
4047
-     *
4048
-     * @param string $messenger_name The name of the messenger being activated
4049
-     * @return bool
4050
-     * @throws DomainException
4051
-     * @throws EE_Error
4052
-     * @throws InvalidArgumentException
4053
-     * @throws ReflectionException
4054
-     * @throws InvalidDataTypeException
4055
-     * @throws InvalidInterfaceException
4056
-     */
4057
-    protected function _deactivate_messenger($messenger_name)
4058
-    {
4059
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4060
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4061
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
4062
-
4063
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4064
-    }
4065
-
4066
-
4067
-    /**
4068
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4069
-     *
4070
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
4071
-     * @param string $message_type_name The name of the message type being activated for the messenger
4072
-     * @return bool
4073
-     * @throws DomainException
4074
-     * @throws EE_Error
4075
-     * @throws InvalidArgumentException
4076
-     * @throws ReflectionException
4077
-     * @throws InvalidDataTypeException
4078
-     * @throws InvalidInterfaceException
4079
-     */
4080
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4081
-    {
4082
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4083
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4084
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4085
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4086
-
4087
-        // ensure is active
4088
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4089
-
4090
-        // set response for load
4091
-        if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4092
-            $messenger_name,
4093
-            $message_type_name
4094
-        )
4095
-        ) {
4096
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
4097
-            if ($message_type_to_activate->get_admin_settings_fields()) {
4098
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
4099
-            }
4100
-        }
4101
-
4102
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
4103
-            $active_messenger,
4104
-            $message_type_to_activate
4105
-        );
4106
-    }
4107
-
4108
-
4109
-    /**
4110
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4111
-     *
4112
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4113
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
4114
-     * @return bool
4115
-     * @throws DomainException
4116
-     * @throws EE_Error
4117
-     * @throws InvalidArgumentException
4118
-     * @throws ReflectionException
4119
-     * @throws InvalidDataTypeException
4120
-     * @throws InvalidInterfaceException
4121
-     */
4122
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4123
-    {
4124
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4125
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4126
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4127
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4128
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4129
-
4130
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4131
-            $active_messenger,
4132
-            $message_type_to_deactivate
4133
-        );
4134
-    }
4135
-
4136
-
4137
-    /**
4138
-     * This just initializes the defaults for activating messenger and message type responses.
4139
-     */
4140
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
4141
-    {
4142
-        $this->_template_args['data']['active_mts'] = array();
4143
-        $this->_template_args['data']['mt_reload'] = array();
4144
-    }
4145
-
4146
-
4147
-    /**
4148
-     * Setup appropriate response for activating a messenger and/or message types
4149
-     *
4150
-     * @param EE_messenger         $messenger
4151
-     * @param EE_message_type|null $message_type
4152
-     * @return bool
4153
-     * @throws DomainException
4154
-     * @throws EE_Error
4155
-     * @throws InvalidArgumentException
4156
-     * @throws ReflectionException
4157
-     * @throws InvalidDataTypeException
4158
-     * @throws InvalidInterfaceException
4159
-     */
4160
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
4161
-        $messenger,
4162
-        EE_Message_Type $message_type = null
4163
-    ) {
4164
-        // if $messenger isn't a valid messenger object then get out.
4165
-        if (! $messenger instanceof EE_Messenger) {
4166
-            EE_Error::add_error(
4167
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4168
-                __FILE__,
4169
-                __FUNCTION__,
4170
-                __LINE__
4171
-            );
4172
-
4173
-            return false;
4174
-        }
4175
-        // activated
4176
-        if ($this->_template_args['data']['active_mts']) {
4177
-            EE_Error::overwrite_success();
4178
-            // activated a message type with the messenger
4179
-            if ($message_type instanceof EE_message_type) {
4180
-                EE_Error::add_success(
4181
-                    sprintf(
4182
-                        esc_html__(
4183
-                            '%s message type has been successfully activated with the %s messenger',
4184
-                            'event_espresso'
4185
-                        ),
4186
-                        ucwords($message_type->label['singular']),
4187
-                        ucwords($messenger->label['singular'])
4188
-                    )
4189
-                );
4190
-
4191
-                // if message type was invoice then let's make sure we activate the invoice payment method.
4192
-                if ($message_type->name === 'invoice') {
4193
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
4194
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4195
-                    if ($pm instanceof EE_Payment_Method) {
4196
-                        EE_Error::add_attention(
4197
-                            esc_html__(
4198
-                                '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.',
4199
-                                'event_espresso'
4200
-                            )
4201
-                        );
4202
-                    }
4203
-                }
4204
-                // just toggles the entire messenger
4205
-            } else {
4206
-                EE_Error::add_success(
4207
-                    sprintf(
4208
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4209
-                        ucwords($messenger->label['singular'])
4210
-                    )
4211
-                );
4212
-            }
4213
-
4214
-            return true;
4215
-
4216
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4217
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4218
-            // in which case we just give a success message for the messenger being successfully activated.
4219
-        } else {
4220
-            if (! $messenger->get_default_message_types()) {
4221
-                // messenger doesn't have any default message types so still a success.
4222
-                EE_Error::add_success(
4223
-                    sprintf(
4224
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4225
-                        ucwords($messenger->label['singular'])
4226
-                    )
4227
-                );
4228
-
4229
-                return true;
4230
-            } else {
4231
-                EE_Error::add_error(
4232
-                    $message_type instanceof EE_message_type
4233
-                        ? sprintf(
4234
-                            esc_html__(
4235
-                                '%s message type was not successfully activated with the %s messenger',
4236
-                                'event_espresso'
4237
-                            ),
4238
-                            ucwords($message_type->label['singular']),
4239
-                            ucwords($messenger->label['singular'])
4240
-                        )
4241
-                        : sprintf(
4242
-                            esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4243
-                            ucwords($messenger->label['singular'])
4244
-                        ),
4245
-                    __FILE__,
4246
-                    __FUNCTION__,
4247
-                    __LINE__
4248
-                );
4249
-
4250
-                return false;
4251
-            }
4252
-        }
4253
-    }
4254
-
4255
-
4256
-    /**
4257
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
4258
-     *
4259
-     * @param EE_messenger         $messenger
4260
-     * @param EE_message_type|null $message_type
4261
-     * @return bool
4262
-     * @throws DomainException
4263
-     * @throws EE_Error
4264
-     * @throws InvalidArgumentException
4265
-     * @throws ReflectionException
4266
-     * @throws InvalidDataTypeException
4267
-     * @throws InvalidInterfaceException
4268
-     */
4269
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4270
-        $messenger,
4271
-        EE_message_type $message_type = null
4272
-    ) {
4273
-        EE_Error::overwrite_success();
4274
-
4275
-        // if $messenger isn't a valid messenger object then get out.
4276
-        if (! $messenger instanceof EE_Messenger) {
4277
-            EE_Error::add_error(
4278
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4279
-                __FILE__,
4280
-                __FUNCTION__,
4281
-                __LINE__
4282
-            );
4283
-
4284
-            return false;
4285
-        }
4286
-
4287
-        if ($message_type instanceof EE_message_type) {
4288
-            $message_type_name = $message_type->name;
4289
-            EE_Error::add_success(
4290
-                sprintf(
4291
-                    esc_html__(
4292
-                        '%s message type has been successfully deactivated for the %s messenger.',
4293
-                        'event_espresso'
4294
-                    ),
4295
-                    ucwords($message_type->label['singular']),
4296
-                    ucwords($messenger->label['singular'])
4297
-                )
4298
-            );
4299
-        } else {
4300
-            $message_type_name = '';
4301
-            EE_Error::add_success(
4302
-                sprintf(
4303
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4304
-                    ucwords($messenger->label['singular'])
4305
-                )
4306
-            );
4307
-        }
4308
-
4309
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4310
-        if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4311
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
4312
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4313
-            if ($count_updated > 0) {
4314
-                $msg = $message_type_name === 'invoice'
4315
-                    ? esc_html__(
4316
-                        '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.',
4317
-                        'event_espresso'
4318
-                    )
4319
-                    : esc_html__(
4320
-                        '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.',
4321
-                        'event_espresso'
4322
-                    );
4323
-                EE_Error::add_attention($msg);
4324
-            }
4325
-        }
4326
-
4327
-        return true;
4328
-    }
4329
-
4330
-
4331
-    /**
4332
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4333
-     *
4334
-     * @throws DomainException
4335
-     */
4336
-    public function update_mt_form()
4337
-    {
4338
-        if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4339
-            EE_Error::add_error(
4340
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4341
-                __FILE__,
4342
-                __FUNCTION__,
4343
-                __LINE__
4344
-            );
4345
-            $this->_return_json();
4346
-        }
4347
-
4348
-        $message_types = $this->get_installed_message_types();
4349
-
4350
-        $message_type = $message_types[ $this->_req_data['message_type'] ];
4351
-        $messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4352
-
4353
-        $content = $this->_message_type_settings_content(
4354
-            $message_type,
4355
-            $messenger,
4356
-            true
4357
-        );
4358
-        $this->_template_args['success'] = true;
4359
-        $this->_template_args['content'] = $content;
4360
-        $this->_return_json();
4361
-    }
4362
-
4363
-
4364
-    /**
4365
-     * this handles saving the settings for a messenger or message type
4366
-     *
4367
-     */
4368
-    public function save_settings()
4369
-    {
4370
-        if (! isset($this->_req_data['type'])) {
4371
-            EE_Error::add_error(
4372
-                esc_html__(
4373
-                    'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4374
-                    'event_espresso'
4375
-                ),
4376
-                __FILE__,
4377
-                __FUNCTION__,
4378
-                __LINE__
4379
-            );
4380
-            $this->_template_args['error'] = true;
4381
-            $this->_return_json();
4382
-        }
4383
-
4384
-
4385
-        if ($this->_req_data['type'] === 'messenger') {
4386
-            // this should be an array.
4387
-            $settings = $this->_req_data['messenger_settings'];
4388
-            $messenger = $settings['messenger'];
4389
-            // let's setup the settings data
4390
-            foreach ($settings as $key => $value) {
4391
-                switch ($key) {
4392
-                    case 'messenger':
4393
-                        unset($settings['messenger']);
4394
-                        break;
4395
-                    case 'message_types':
4396
-                        unset($settings['message_types']);
4397
-                        break;
4398
-                    default:
4399
-                        $settings[ $key ] = $value;
4400
-                        break;
4401
-                }
4402
-            }
4403
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4404
-        } elseif ($this->_req_data['type'] === 'message_type') {
4405
-            $settings = $this->_req_data['message_type_settings'];
4406
-            $messenger = $settings['messenger'];
4407
-            $message_type = $settings['message_type'];
4408
-
4409
-            foreach ($settings as $key => $value) {
4410
-                switch ($key) {
4411
-                    case 'messenger':
4412
-                        unset($settings['messenger']);
4413
-                        break;
4414
-                    case 'message_type':
4415
-                        unset($settings['message_type']);
4416
-                        break;
4417
-                    default:
4418
-                        $settings[ $key ] = $value;
4419
-                        break;
4420
-                }
4421
-            }
4422
-
4423
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4424
-        }
4425
-
4426
-        // okay we should have the data all setup.  Now we just update!
4427
-        $success = $this->_message_resource_manager->update_active_messengers_option();
4428
-
4429
-        if ($success) {
4430
-            EE_Error::add_success(__('Settings updated', 'event_espresso'));
4431
-        } else {
4432
-            EE_Error::add_error(
4433
-                esc_html__(
4434
-                    'Settings did not get updated',
4435
-                    'event_espresso'
4436
-                ),
4437
-                __FILE__,
4438
-                __FUNCTION__,
4439
-                __LINE__
4440
-            );
4441
-        }
4442
-
4443
-        $this->_template_args['success'] = $success;
4444
-        $this->_return_json();
4445
-    }
4446
-
4447
-
4448
-
4449
-
4450
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4451
-
4452
-
4453
-    /**
4454
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4455
-     * However, this does not send immediately, it just queues for sending.
4456
-     *
4457
-     * @since 4.9.0
4458
-     * @throws EE_Error
4459
-     * @throws InvalidDataTypeException
4460
-     * @throws InvalidInterfaceException
4461
-     * @throws InvalidArgumentException
4462
-     * @throws ReflectionException
4463
-     */
4464
-    protected function _generate_now()
4465
-    {
4466
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4467
-        $this->_redirect_after_action(false, '', '', array(), true);
4468
-    }
4469
-
4470
-
4471
-    /**
4472
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4473
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4474
-     *
4475
-     * @since 4.9.0
4476
-     * @throws EE_Error
4477
-     * @throws InvalidDataTypeException
4478
-     * @throws InvalidInterfaceException
4479
-     * @throws InvalidArgumentException
4480
-     * @throws ReflectionException
4481
-     */
4482
-    protected function _generate_and_send_now()
4483
-    {
4484
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4485
-        $this->_redirect_after_action(false, '', '', array(), true);
4486
-    }
4487
-
4488
-
4489
-    /**
4490
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4491
-     *
4492
-     * @since 4.9.0
4493
-     * @throws EE_Error
4494
-     * @throws InvalidDataTypeException
4495
-     * @throws InvalidInterfaceException
4496
-     * @throws InvalidArgumentException
4497
-     * @throws ReflectionException
4498
-     */
4499
-    protected function _queue_for_resending()
4500
-    {
4501
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4502
-        $this->_redirect_after_action(false, '', '', array(), true);
4503
-    }
4504
-
4505
-
4506
-    /**
4507
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4508
-     *
4509
-     * @since 4.9.0
4510
-     * @throws EE_Error
4511
-     * @throws InvalidDataTypeException
4512
-     * @throws InvalidInterfaceException
4513
-     * @throws InvalidArgumentException
4514
-     * @throws ReflectionException
4515
-     */
4516
-    protected function _send_now()
4517
-    {
4518
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4519
-        $this->_redirect_after_action(false, '', '', array(), true);
4520
-    }
4521
-
4522
-
4523
-    /**
4524
-     * Deletes EE_messages for IDs in the request.
4525
-     *
4526
-     * @since 4.9.0
4527
-     * @throws EE_Error
4528
-     * @throws InvalidDataTypeException
4529
-     * @throws InvalidInterfaceException
4530
-     * @throws InvalidArgumentException
4531
-     */
4532
-    protected function _delete_ee_messages()
4533
-    {
4534
-        $msg_ids = $this->_get_msg_ids_from_request();
4535
-        $deleted_count = 0;
4536
-        foreach ($msg_ids as $msg_id) {
4537
-            if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4538
-                $deleted_count++;
4539
-            }
4540
-        }
4541
-        if ($deleted_count) {
4542
-            EE_Error::add_success(
4543
-                esc_html(
4544
-                    _n(
4545
-                        'Message successfully deleted',
4546
-                        'Messages successfully deleted',
4547
-                        $deleted_count,
4548
-                        'event_espresso'
4549
-                    )
4550
-                )
4551
-            );
4552
-            $this->_redirect_after_action(
4553
-                false,
4554
-                '',
4555
-                '',
4556
-                array(),
4557
-                true
4558
-            );
4559
-        } else {
4560
-            EE_Error::add_error(
4561
-                _n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4562
-                __FILE__,
4563
-                __FUNCTION__,
4564
-                __LINE__
4565
-            );
4566
-            $this->_redirect_after_action(false, '', '', array(), true);
4567
-        }
4568
-    }
4569
-
4570
-
4571
-    /**
4572
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4573
-     *
4574
-     * @since 4.9.0
4575
-     * @return array
4576
-     */
4577
-    protected function _get_msg_ids_from_request()
4578
-    {
4579
-        if (! isset($this->_req_data['MSG_ID'])) {
4580
-            return array();
4581
-        }
4582
-
4583
-        return is_array($this->_req_data['MSG_ID'])
4584
-            ? array_keys($this->_req_data['MSG_ID'])
4585
-            : array($this->_req_data['MSG_ID']);
4586
-    }
2666
+		$output = ob_get_contents();
2667
+		ob_clean();
2668
+		$this->_context_switcher = $output;
2669
+	}
2670
+
2671
+
2672
+	/**
2673
+	 * utility for sanitizing new values coming in.
2674
+	 * Note: this is only used when updating a context.
2675
+	 *
2676
+	 * @access protected
2677
+	 *
2678
+	 * @param int $index This helps us know which template field to select from the request array.
2679
+	 *
2680
+	 * @return array
2681
+	 */
2682
+	protected function _set_message_template_column_values($index)
2683
+	{
2684
+		if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2685
+			foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2686
+				$this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2687
+			}
2688
+		}
2689
+
2690
+
2691
+		$set_column_values = array(
2692
+			'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2693
+			'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2694
+			'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2695
+			'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2696
+			'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2697
+			'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2698
+			'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2699
+			'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2700
+			'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2701
+				? absint($this->_req_data['MTP_is_global'])
2702
+				: 0,
2703
+			'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2704
+				? absint($this->_req_data['MTP_is_override'])
2705
+				: 0,
2706
+			'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2707
+			'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2708
+		);
2709
+
2710
+
2711
+		return $set_column_values;
2712
+	}
2713
+
2714
+
2715
+	protected function _insert_or_update_message_template($new = false)
2716
+	{
2717
+
2718
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2719
+		$success = 0;
2720
+		$override = false;
2721
+
2722
+		// setup notices description
2723
+		$messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2724
+
2725
+		// need the message type and messenger objects to be able to use the labels for the notices
2726
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2727
+		$messenger_label = $messenger_object instanceof EE_messenger
2728
+			? ucwords($messenger_object->label['singular'])
2729
+			: '';
2730
+
2731
+		$message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2732
+			? $this->_req_data['MTP_message_type']
2733
+			: '';
2734
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2735
+
2736
+		$message_type_label = $message_type_object instanceof EE_message_type
2737
+			? ucwords($message_type_object->label['singular'])
2738
+			: '';
2739
+
2740
+		$context_slug = ! empty($this->_req_data['MTP_context'])
2741
+			? $this->_req_data['MTP_context']
2742
+			: '';
2743
+		$context = ucwords(str_replace('_', ' ', $context_slug));
2744
+
2745
+		$item_desc = $messenger_label && $message_type_label
2746
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2747
+			: '';
2748
+		$item_desc .= 'Message Template';
2749
+		$query_args = array();
2750
+		$edit_array = array();
2751
+		$action_desc = '';
2752
+
2753
+		// if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2754
+		// user to edit.
2755
+		if ($new) {
2756
+			$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2757
+			if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2758
+				if (empty($edit_array)) {
2759
+					$success = 0;
2760
+				} else {
2761
+					$success = 1;
2762
+					$edit_array = $edit_array[0];
2763
+					$query_args = array(
2764
+						'id'      => $edit_array['GRP_ID'],
2765
+						'context' => $edit_array['MTP_context'],
2766
+						'action'  => 'edit_message_template',
2767
+					);
2768
+				}
2769
+			}
2770
+			$action_desc = 'created';
2771
+		} else {
2772
+			$MTPG = EEM_Message_Template_Group::instance();
2773
+			$MTP = EEM_Message_Template::instance();
2774
+
2775
+
2776
+			// run update for each template field in displayed context
2777
+			if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2778
+				EE_Error::add_error(
2779
+					esc_html__(
2780
+						'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2781
+						'event_espresso'
2782
+					),
2783
+					__FILE__,
2784
+					__FUNCTION__,
2785
+					__LINE__
2786
+				);
2787
+				$success = 0;
2788
+			} else {
2789
+				// first validate all fields!
2790
+				// this filter allows client code to add its own validation to the template fields as well.
2791
+				// returning an empty array means everything passed validation.
2792
+				// errors in validation should be represented in an array with the following shape:
2793
+				// array(
2794
+				//   'fieldname' => array(
2795
+				//          'msg' => 'error message'
2796
+				//          'value' => 'value for field producing error'
2797
+				// )
2798
+				$custom_validation = (array) apply_filters(
2799
+					'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2800
+					array(),
2801
+					$this->_req_data['MTP_template_fields'],
2802
+					$context_slug,
2803
+					$messenger_slug,
2804
+					$message_type_slug
2805
+				);
2806
+
2807
+				$system_validation = $MTPG->validate(
2808
+					$this->_req_data['MTP_template_fields'],
2809
+					$context_slug,
2810
+					$messenger_slug,
2811
+					$message_type_slug
2812
+				);
2813
+
2814
+				$system_validation = ! is_array($system_validation) && $system_validation ? array()
2815
+					: $system_validation;
2816
+				$validates = array_merge($custom_validation, $system_validation);
2817
+
2818
+				// if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2819
+				// appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2820
+				//  WE need to make sure there is no actual error messages in validates.
2821
+				if (is_array($validates) && ! empty($validates)) {
2822
+					// add the transient so when the form loads we know which fields to highlight
2823
+					$this->_add_transient('edit_message_template', $validates);
2824
+
2825
+					$success = 0;
2826
+
2827
+					// setup notices
2828
+					foreach ($validates as $field => $error) {
2829
+						if (isset($error['msg'])) {
2830
+							EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2831
+						}
2832
+					}
2833
+				} else {
2834
+					$set_column_values = array();
2835
+					foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2836
+						$set_column_values = $this->_set_message_template_column_values($template_field);
2837
+
2838
+						$where_cols_n_values = array(
2839
+							'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2840
+						);
2841
+						// if they aren't allowed to use all JS, restrict them to just posty-y tags
2842
+						if (! current_user_can('unfiltered_html')) {
2843
+							if (is_array($set_column_values['MTP_content'])) {
2844
+								foreach ($set_column_values['MTP_content'] as $key => $value) {
2845
+									// remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2846
+									// only removes slashes from double-quotes, so attributes using single quotes always
2847
+									// appear invalid.) But currently the models expect slashed data, so after wp_kses
2848
+									// runs we need to re-slash the data. Sheesh. See
2849
+									// https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2850
+									$set_column_values['MTP_content'][ $key ] = addslashes(
2851
+										wp_kses(
2852
+											stripslashes($value),
2853
+											wp_kses_allowed_html('post')
2854
+										)
2855
+									);
2856
+								}
2857
+							} else {
2858
+								$set_column_values['MTP_content'] = wp_kses(
2859
+									$set_column_values['MTP_content'],
2860
+									wp_kses_allowed_html('post')
2861
+								);
2862
+							}
2863
+						}
2864
+						$message_template_fields = array(
2865
+							'GRP_ID'             => $set_column_values['GRP_ID'],
2866
+							'MTP_template_field' => $set_column_values['MTP_template_field'],
2867
+							'MTP_context'        => $set_column_values['MTP_context'],
2868
+							'MTP_content'        => $set_column_values['MTP_content'],
2869
+						);
2870
+						if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2871
+							if ($updated === false) {
2872
+								EE_Error::add_error(
2873
+									sprintf(
2874
+										esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2875
+										$template_field
2876
+									),
2877
+									__FILE__,
2878
+									__FUNCTION__,
2879
+									__LINE__
2880
+								);
2881
+							} else {
2882
+								$success = 1;
2883
+							}
2884
+						} else {
2885
+							// only do this logic if we don't have a MTP_ID for this field
2886
+							if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2887
+								// this has already been through the template field validator and sanitized, so it will be
2888
+								// safe to insert this field.  Why insert?  This typically happens when we introduce a new
2889
+								// message template field in a messenger/message type and existing users don't have the
2890
+								// default setup for it.
2891
+								// @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2892
+								$updated = $MTP->insert($message_template_fields);
2893
+								if (! $updated || is_wp_error($updated)) {
2894
+									EE_Error::add_error(
2895
+										sprintf(
2896
+											esc_html__('%s field could not be updated.', 'event_espresso'),
2897
+											$template_field
2898
+										),
2899
+										__FILE__,
2900
+										__FUNCTION__,
2901
+										__LINE__
2902
+									);
2903
+									$success = 0;
2904
+								} else {
2905
+									$success = 1;
2906
+								}
2907
+							}
2908
+						}
2909
+						$action_desc = 'updated';
2910
+					}
2911
+
2912
+					// we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2913
+					$mtpg_fields = array(
2914
+						'MTP_user_id'      => $set_column_values['MTP_user_id'],
2915
+						'MTP_messenger'    => $set_column_values['MTP_messenger'],
2916
+						'MTP_message_type' => $set_column_values['MTP_message_type'],
2917
+						'MTP_is_global'    => $set_column_values['MTP_is_global'],
2918
+						'MTP_is_override'  => $set_column_values['MTP_is_override'],
2919
+						'MTP_deleted'      => $set_column_values['MTP_deleted'],
2920
+						'MTP_is_active'    => $set_column_values['MTP_is_active'],
2921
+						'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2922
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2923
+							: '',
2924
+						'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2925
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2926
+							: '',
2927
+					);
2928
+
2929
+					$mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2930
+					$updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2931
+
2932
+					if ($updated === false) {
2933
+						EE_Error::add_error(
2934
+							sprintf(
2935
+								esc_html__(
2936
+									'The Message Template Group (%d) was NOT updated for some reason',
2937
+									'event_espresso'
2938
+								),
2939
+								$set_column_values['GRP_ID']
2940
+							),
2941
+							__FILE__,
2942
+							__FUNCTION__,
2943
+							__LINE__
2944
+						);
2945
+					} else {
2946
+						// k now we need to ensure the template_pack and template_variation fields are set.
2947
+						$template_pack = ! empty($this->_req_data['MTP_template_pack'])
2948
+							? $this->_req_data['MTP_template_pack']
2949
+							: 'default';
2950
+
2951
+						$template_variation = ! empty($this->_req_data['MTP_template_variation'])
2952
+							? $this->_req_data['MTP_template_variation']
2953
+							: 'default';
2954
+
2955
+						$mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2956
+						if ($mtpg_obj instanceof EE_Message_Template_Group) {
2957
+							$mtpg_obj->set_template_pack_name($template_pack);
2958
+							$mtpg_obj->set_template_pack_variation($template_variation);
2959
+						}
2960
+						$success = 1;
2961
+					}
2962
+				}
2963
+			}
2964
+		}
2965
+
2966
+		// we return things differently if doing ajax
2967
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2968
+			$this->_template_args['success'] = $success;
2969
+			$this->_template_args['error'] = ! $success ? true : false;
2970
+			$this->_template_args['content'] = '';
2971
+			$this->_template_args['data'] = array(
2972
+				'grpID'        => $edit_array['GRP_ID'],
2973
+				'templateName' => $edit_array['template_name'],
2974
+			);
2975
+			if ($success) {
2976
+				EE_Error::overwrite_success();
2977
+				EE_Error::add_success(
2978
+					esc_html__(
2979
+						'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.',
2980
+						'event_espresso'
2981
+					)
2982
+				);
2983
+			}
2984
+
2985
+			$this->_return_json();
2986
+		}
2987
+
2988
+
2989
+		// was a test send triggered?
2990
+		if (isset($this->_req_data['test_button'])) {
2991
+			EE_Error::overwrite_success();
2992
+			$this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2993
+			$override = true;
2994
+		}
2995
+
2996
+		if (empty($query_args)) {
2997
+			$query_args = array(
2998
+				'id'      => $this->_req_data['GRP_ID'],
2999
+				'context' => $context_slug,
3000
+				'action'  => 'edit_message_template',
3001
+			);
3002
+		}
3003
+
3004
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3005
+	}
3006
+
3007
+
3008
+	/**
3009
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
3010
+	 *
3011
+	 * @param  string $context      what context being tested
3012
+	 * @param  string $messenger    messenger being tested
3013
+	 * @param  string $message_type message type being tested
3014
+	 * @throws EE_Error
3015
+	 * @throws InvalidArgumentException
3016
+	 * @throws InvalidDataTypeException
3017
+	 * @throws InvalidInterfaceException
3018
+	 */
3019
+	protected function _do_test_send($context, $messenger, $message_type)
3020
+	{
3021
+		// set things up for preview
3022
+		$this->_req_data['messenger'] = $messenger;
3023
+		$this->_req_data['message_type'] = $message_type;
3024
+		$this->_req_data['context'] = $context;
3025
+		$this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3026
+		$active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3027
+
3028
+		// let's save any existing fields that might be required by the messenger
3029
+		if (isset($this->_req_data['test_settings_fld'])
3030
+			&& $active_messenger instanceof EE_messenger
3031
+			&& apply_filters(
3032
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3033
+				true,
3034
+				$this->_req_data['test_settings_fld'],
3035
+				$active_messenger
3036
+			)
3037
+		) {
3038
+			$active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3039
+		}
3040
+
3041
+		/**
3042
+		 * Use filter to add additional controls on whether message can send or not
3043
+		 */
3044
+		if (apply_filters(
3045
+			'FHEE__Messages_Admin_Page__do_test_send__can_send',
3046
+			true,
3047
+			$context,
3048
+			$this->_req_data,
3049
+			$messenger,
3050
+			$message_type
3051
+		)) {
3052
+			if (EEM_Event::instance()->count() > 0) {
3053
+				$success = $this->_preview_message(true);
3054
+				if ($success) {
3055
+					EE_Error::add_success(__('Test message sent', 'event_espresso'));
3056
+				} else {
3057
+					EE_Error::add_error(
3058
+						esc_html__('The test message was not sent', 'event_espresso'),
3059
+						__FILE__,
3060
+						__FUNCTION__,
3061
+						__LINE__
3062
+					);
3063
+				}
3064
+			} else {
3065
+				$this->noEventsErrorMessage(true);
3066
+			}
3067
+		}
3068
+	}
3069
+
3070
+
3071
+	/**
3072
+	 * _generate_new_templates
3073
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3074
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3075
+	 * for the event.
3076
+	 *
3077
+	 *
3078
+	 * @param  string $messenger     the messenger we are generating templates for
3079
+	 * @param array   $message_types array of message types that the templates are generated for.
3080
+	 * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3081
+	 *                               indicate the message_template_group being used as the base.
3082
+	 *
3083
+	 * @param bool    $global
3084
+	 *
3085
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
3086
+	 *                               encountering problems.
3087
+	 * @throws EE_Error
3088
+	 */
3089
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3090
+	{
3091
+
3092
+		// if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3093
+		// just don't generate any templates.
3094
+		if (empty($message_types)) {
3095
+			return true;
3096
+		}
3097
+
3098
+		return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3099
+	}
3100
+
3101
+
3102
+	/**
3103
+	 * [_trash_or_restore_message_template]
3104
+	 *
3105
+	 * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3106
+	 * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3107
+	 *                        an individual context (FALSE).
3108
+	 * @return void
3109
+	 * @throws EE_Error
3110
+	 * @throws InvalidArgumentException
3111
+	 * @throws InvalidDataTypeException
3112
+	 * @throws InvalidInterfaceException
3113
+	 */
3114
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
3115
+	{
3116
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3117
+		$MTP = EEM_Message_Template_Group::instance();
3118
+
3119
+		$success = 1;
3120
+
3121
+		// incoming GRP_IDs
3122
+		if ($all) {
3123
+			// Checkboxes
3124
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3125
+				// if array has more than one element then success message should be plural.
3126
+				// todo: what about nonce?
3127
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3128
+
3129
+				// cycle through checkboxes
3130
+				while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3131
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3132
+					if (! $trashed_or_restored) {
3133
+						$success = 0;
3134
+					}
3135
+				}
3136
+			} else {
3137
+				// grab single GRP_ID and handle
3138
+				$GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3139
+				if (! empty($GRP_ID)) {
3140
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3141
+					if (! $trashed_or_restored) {
3142
+						$success = 0;
3143
+					}
3144
+				} else {
3145
+					$success = 0;
3146
+				}
3147
+			}
3148
+		}
3149
+
3150
+		$action_desc = $trash
3151
+			? esc_html__('moved to the trash', 'event_espresso')
3152
+			: esc_html__('restored', 'event_espresso');
3153
+
3154
+		$action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3155
+
3156
+		$item_desc = $all ? _n(
3157
+			'Message Template Group',
3158
+			'Message Template Groups',
3159
+			$success,
3160
+			'event_espresso'
3161
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3162
+
3163
+		$item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3164
+			'template',
3165
+			'templates',
3166
+			$success,
3167
+			'event_espresso'
3168
+		) : $item_desc;
3169
+
3170
+		$this->_redirect_after_action($success, $item_desc, $action_desc, array());
3171
+	}
3172
+
3173
+
3174
+	/**
3175
+	 * [_delete_message_template]
3176
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3177
+	 *
3178
+	 * @return void
3179
+	 * @throws EE_Error
3180
+	 * @throws InvalidArgumentException
3181
+	 * @throws InvalidDataTypeException
3182
+	 * @throws InvalidInterfaceException
3183
+	 */
3184
+	protected function _delete_message_template()
3185
+	{
3186
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3187
+
3188
+		// checkboxes
3189
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3190
+			// if array has more than one element then success message should be plural
3191
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3192
+
3193
+			// cycle through bulk action checkboxes
3194
+			while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3195
+				$success = $this->_delete_mtp_permanently($GRP_ID);
3196
+			}
3197
+		} else {
3198
+			// grab single grp_id and delete
3199
+			$GRP_ID = absint($this->_req_data['id']);
3200
+			$success = $this->_delete_mtp_permanently($GRP_ID);
3201
+		}
3202
+
3203
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3204
+	}
3205
+
3206
+
3207
+	/**
3208
+	 * helper for permanently deleting a mtP group and all related message_templates
3209
+	 *
3210
+	 * @param  int  $GRP_ID        The group being deleted
3211
+	 * @param  bool $include_group whether to delete the Message Template Group as well.
3212
+	 * @return bool boolean to indicate the success of the deletes or not.
3213
+	 * @throws EE_Error
3214
+	 * @throws InvalidArgumentException
3215
+	 * @throws InvalidDataTypeException
3216
+	 * @throws InvalidInterfaceException
3217
+	 */
3218
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3219
+	{
3220
+		$success = 1;
3221
+		$MTPG = EEM_Message_Template_Group::instance();
3222
+		// first let's GET this group
3223
+		$MTG = $MTPG->get_one_by_ID($GRP_ID);
3224
+		// then delete permanently all the related Message Templates
3225
+		$deleted = $MTG->delete_related_permanently('Message_Template');
3226
+
3227
+		if ($deleted === 0) {
3228
+			$success = 0;
3229
+		}
3230
+
3231
+		// now delete permanently this particular group
3232
+
3233
+		if ($include_group && ! $MTG->delete_permanently()) {
3234
+			$success = 0;
3235
+		}
3236
+
3237
+		return $success;
3238
+	}
3239
+
3240
+
3241
+	/**
3242
+	 *    _learn_more_about_message_templates_link
3243
+	 *
3244
+	 * @access protected
3245
+	 * @return string
3246
+	 */
3247
+	protected function _learn_more_about_message_templates_link()
3248
+	{
3249
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3250
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
3251
+			   . '</a>';
3252
+	}
3253
+
3254
+
3255
+	/**
3256
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3257
+	 * ajax and other routes.
3258
+	 *
3259
+	 * @return void
3260
+	 * @throws DomainException
3261
+	 */
3262
+	protected function _settings()
3263
+	{
3264
+
3265
+
3266
+		$this->_set_m_mt_settings();
3267
+
3268
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3269
+			? $this->_req_data['selected_messenger']
3270
+			: 'email';
3271
+
3272
+		// let's setup the messenger tabs
3273
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3274
+			$this->_m_mt_settings['messenger_tabs'],
3275
+			'messenger_links',
3276
+			'|',
3277
+			$selected_messenger
3278
+		);
3279
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3280
+		$this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3281
+
3282
+		$this->display_admin_page_with_sidebar();
3283
+	}
3284
+
3285
+
3286
+	/**
3287
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3288
+	 *
3289
+	 * @access protected
3290
+	 * @return void
3291
+	 * @throws DomainException
3292
+	 */
3293
+	protected function _set_m_mt_settings()
3294
+	{
3295
+		// first if this is already set then lets get out no need to regenerate data.
3296
+		if (! empty($this->_m_mt_settings)) {
3297
+			return;
3298
+		}
3299
+
3300
+		// get all installed messengers and message_types
3301
+		/** @type EE_messenger[] $messengers */
3302
+		$messengers = $this->_message_resource_manager->installed_messengers();
3303
+		/** @type EE_message_type[] $message_types */
3304
+		$message_types = $this->_message_resource_manager->installed_message_types();
3305
+
3306
+
3307
+		// assemble the array for the _tab_text_links helper
3308
+
3309
+		foreach ($messengers as $messenger) {
3310
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3311
+				'label' => ucwords($messenger->label['singular']),
3312
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3313
+					? 'messenger-active'
3314
+					: '',
3315
+				'href'  => $messenger->name,
3316
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3317
+				'slug'  => $messenger->name,
3318
+				'obj'   => $messenger,
3319
+			);
3320
+
3321
+
3322
+			$message_types_for_messenger = $messenger->get_valid_message_types();
3323
+
3324
+			foreach ($message_types as $message_type) {
3325
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3326
+				// it shouldn't show in either the inactive OR active metabox.
3327
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3328
+					continue;
3329
+				}
3330
+
3331
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3332
+					$messenger->name,
3333
+					$message_type->name
3334
+				)
3335
+					? 'active'
3336
+					: 'inactive';
3337
+
3338
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3339
+					'label'    => ucwords($message_type->label['singular']),
3340
+					'class'    => 'message-type-' . $a_or_i,
3341
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3342
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3343
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3344
+					'title'    => $a_or_i === 'active'
3345
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3346
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3347
+					'content'  => $a_or_i === 'active'
3348
+						? $this->_message_type_settings_content($message_type, $messenger, true)
3349
+						: $this->_message_type_settings_content($message_type, $messenger),
3350
+					'slug'     => $message_type->name,
3351
+					'active'   => $a_or_i === 'active',
3352
+					'obj'      => $message_type,
3353
+				);
3354
+			}
3355
+		}
3356
+	}
3357
+
3358
+
3359
+	/**
3360
+	 * This just prepares the content for the message type settings
3361
+	 *
3362
+	 * @param  EE_message_type $message_type The message type object
3363
+	 * @param  EE_messenger    $messenger    The messenger object
3364
+	 * @param  boolean         $active       Whether the message type is active or not
3365
+	 * @return string html output for the content
3366
+	 * @throws DomainException
3367
+	 */
3368
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
3369
+	{
3370
+		// get message type fields
3371
+		$fields = $message_type->get_admin_settings_fields();
3372
+		$settings_template_args['template_form_fields'] = '';
3373
+
3374
+		if (! empty($fields) && $active) {
3375
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3376
+			foreach ($fields as $fldname => $fldprops) {
3377
+				$field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3378
+				$template_form_field[ $field_id ] = array(
3379
+					'name'       => 'message_type_settings[' . $fldname . ']',
3380
+					'label'      => $fldprops['label'],
3381
+					'input'      => $fldprops['field_type'],
3382
+					'type'       => $fldprops['value_type'],
3383
+					'required'   => $fldprops['required'],
3384
+					'validation' => $fldprops['validation'],
3385
+					'value'      => isset($existing_settings[ $fldname ])
3386
+						? $existing_settings[ $fldname ]
3387
+						: $fldprops['default'],
3388
+					'options'    => isset($fldprops['options'])
3389
+						? $fldprops['options']
3390
+						: array(),
3391
+					'default'    => isset($existing_settings[ $fldname ])
3392
+						? $existing_settings[ $fldname ]
3393
+						: $fldprops['default'],
3394
+					'css_class'  => 'no-drag',
3395
+					'format'     => $fldprops['format'],
3396
+				);
3397
+			}
3398
+
3399
+
3400
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3401
+				? $this->_generate_admin_form_fields(
3402
+					$template_form_field,
3403
+					'string',
3404
+					'ee_mt_activate_form'
3405
+				)
3406
+				: '';
3407
+		}
3408
+
3409
+		$settings_template_args['description'] = $message_type->description;
3410
+		// we also need some hidden fields
3411
+		$settings_template_args['hidden_fields'] = array(
3412
+			'message_type_settings[messenger]'    => array(
3413
+				'type'  => 'hidden',
3414
+				'value' => $messenger->name,
3415
+			),
3416
+			'message_type_settings[message_type]' => array(
3417
+				'type'  => 'hidden',
3418
+				'value' => $message_type->name,
3419
+			),
3420
+			'type'                                => array(
3421
+				'type'  => 'hidden',
3422
+				'value' => 'message_type',
3423
+			),
3424
+		);
3425
+
3426
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3427
+			$settings_template_args['hidden_fields'],
3428
+			'array'
3429
+		);
3430
+		$settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3431
+			? ' hidden'
3432
+			: '';
3433
+
3434
+
3435
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3436
+		$content = EEH_Template::display_template($template, $settings_template_args, true);
3437
+
3438
+		return $content;
3439
+	}
3440
+
3441
+
3442
+	/**
3443
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3444
+	 *
3445
+	 * @access protected
3446
+	 * @return void
3447
+	 * @throws DomainException
3448
+	 */
3449
+	protected function _messages_settings_metaboxes()
3450
+	{
3451
+		$this->_set_m_mt_settings();
3452
+		$m_boxes = $mt_boxes = array();
3453
+		$m_template_args = $mt_template_args = array();
3454
+
3455
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3456
+			? $this->_req_data['selected_messenger']
3457
+			: 'email';
3458
+
3459
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3460
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3461
+				$hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3462
+				$hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3463
+				// messenger meta boxes
3464
+				$active = $selected_messenger === $messenger;
3465
+				$active_mt_tabs = isset(
3466
+					$this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3467
+				)
3468
+					? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3469
+					: '';
3470
+				$m_boxes[ $messenger . '_a_box' ] = sprintf(
3471
+					esc_html__('%s Settings', 'event_espresso'),
3472
+					$tab_array['label']
3473
+				);
3474
+				$m_template_args[ $messenger . '_a_box' ] = array(
3475
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3476
+					'inactive_message_types' => isset(
3477
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3478
+					)
3479
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3480
+						: '',
3481
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3482
+					'hidden'                 => $active ? '' : ' hidden',
3483
+					'hide_on_message'        => $hide_on_message,
3484
+					'messenger'              => $messenger,
3485
+					'active'                 => $active,
3486
+				);
3487
+				// message type meta boxes
3488
+				// (which is really just the inactive container for each messenger
3489
+				// showing inactive message types for that messenger)
3490
+				$mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3491
+				$mt_template_args[ $messenger . '_i_box' ] = array(
3492
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3493
+					'inactive_message_types' => isset(
3494
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3495
+					)
3496
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3497
+						: '',
3498
+					'hidden'                 => $active ? '' : ' hidden',
3499
+					'hide_on_message'        => $hide_on_message,
3500
+					'hide_off_message'       => $hide_off_message,
3501
+					'messenger'              => $messenger,
3502
+					'active'                 => $active,
3503
+				);
3504
+			}
3505
+		}
3506
+
3507
+
3508
+		// register messenger metaboxes
3509
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3510
+		foreach ($m_boxes as $box => $label) {
3511
+			$callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3512
+			$msgr = str_replace('_a_box', '', $box);
3513
+			add_meta_box(
3514
+				'espresso_' . $msgr . '_settings',
3515
+				$label,
3516
+				function ($post, $metabox) {
3517
+					echo EEH_Template::display_template(
3518
+						$metabox["args"]["template_path"],
3519
+						$metabox["args"]["template_args"],
3520
+						true
3521
+					);
3522
+				},
3523
+				$this->_current_screen->id,
3524
+				'normal',
3525
+				'high',
3526
+				$callback_args
3527
+			);
3528
+		}
3529
+
3530
+		// register message type metaboxes
3531
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3532
+		foreach ($mt_boxes as $box => $label) {
3533
+			$callback_args = array(
3534
+				'template_path' => $mt_template_path,
3535
+				'template_args' => $mt_template_args[ $box ],
3536
+			);
3537
+			$mt = str_replace('_i_box', '', $box);
3538
+			add_meta_box(
3539
+				'espresso_' . $mt . '_inactive_mts',
3540
+				$label,
3541
+				function ($post, $metabox) {
3542
+					echo EEH_Template::display_template(
3543
+						$metabox["args"]["template_path"],
3544
+						$metabox["args"]["template_args"],
3545
+						true
3546
+					);
3547
+				},
3548
+				$this->_current_screen->id,
3549
+				'side',
3550
+				'high',
3551
+				$callback_args
3552
+			);
3553
+		}
3554
+
3555
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3556
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3557
+		if (is_main_site()) {
3558
+			add_meta_box(
3559
+				'espresso_global_message_settings',
3560
+				esc_html__('Global Message Settings', 'event_espresso'),
3561
+				array($this, 'global_messages_settings_metabox_content'),
3562
+				$this->_current_screen->id,
3563
+				'normal',
3564
+				'low',
3565
+				array()
3566
+			);
3567
+		}
3568
+	}
3569
+
3570
+
3571
+	/**
3572
+	 *  This generates the content for the global messages settings metabox.
3573
+	 *
3574
+	 * @return string
3575
+	 * @throws EE_Error
3576
+	 * @throws InvalidArgumentException
3577
+	 * @throws ReflectionException
3578
+	 * @throws InvalidDataTypeException
3579
+	 * @throws InvalidInterfaceException
3580
+	 */
3581
+	public function global_messages_settings_metabox_content()
3582
+	{
3583
+		$form = $this->_generate_global_settings_form();
3584
+		echo $form->form_open(
3585
+			$this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3586
+			'POST'
3587
+		)
3588
+			 . $form->get_html()
3589
+			 . $form->form_close();
3590
+	}
3591
+
3592
+
3593
+	/**
3594
+	 * This generates and returns the form object for the global messages settings.
3595
+	 *
3596
+	 * @return EE_Form_Section_Proper
3597
+	 * @throws EE_Error
3598
+	 * @throws InvalidArgumentException
3599
+	 * @throws ReflectionException
3600
+	 * @throws InvalidDataTypeException
3601
+	 * @throws InvalidInterfaceException
3602
+	 */
3603
+	protected function _generate_global_settings_form()
3604
+	{
3605
+		EE_Registry::instance()->load_helper('HTML');
3606
+		/** @var EE_Network_Core_Config $network_config */
3607
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3608
+
3609
+		return new EE_Form_Section_Proper(
3610
+			array(
3611
+				'name'            => 'global_messages_settings',
3612
+				'html_id'         => 'global_messages_settings',
3613
+				'html_class'      => 'form-table',
3614
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3615
+				'subsections'     => apply_filters(
3616
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3617
+					array(
3618
+						'do_messages_on_same_request' => new EE_Select_Input(
3619
+							array(
3620
+								true  => esc_html__("On the same request", "event_espresso"),
3621
+								false => esc_html__("On a separate request", "event_espresso"),
3622
+							),
3623
+							array(
3624
+								'default'         => $network_config->do_messages_on_same_request,
3625
+								'html_label_text' => esc_html__(
3626
+									'Generate and send all messages:',
3627
+									'event_espresso'
3628
+								),
3629
+								'html_help_text'  => esc_html__(
3630
+									'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.',
3631
+									'event_espresso'
3632
+								),
3633
+							)
3634
+						),
3635
+						'delete_threshold'            => new EE_Select_Input(
3636
+							array(
3637
+								0  => esc_html__('Forever', 'event_espresso'),
3638
+								3  => esc_html__('3 Months', 'event_espresso'),
3639
+								6  => esc_html__('6 Months', 'event_espresso'),
3640
+								9  => esc_html__('9 Months', 'event_espresso'),
3641
+								12 => esc_html__('12 Months', 'event_espresso'),
3642
+								24 => esc_html__('24 Months', 'event_espresso'),
3643
+								36 => esc_html__('36 Months', 'event_espresso'),
3644
+							),
3645
+							array(
3646
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3647
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3648
+								'html_help_text'  => esc_html__(
3649
+									'You can control how long a record of processed messages is kept via this option.',
3650
+									'event_espresso'
3651
+								),
3652
+							)
3653
+						),
3654
+						'update_settings'             => new EE_Submit_Input(
3655
+							array(
3656
+								'default'         => esc_html__('Update', 'event_espresso'),
3657
+								'html_label_text' => '&nbsp',
3658
+							)
3659
+						),
3660
+					)
3661
+				),
3662
+			)
3663
+		);
3664
+	}
3665
+
3666
+
3667
+	/**
3668
+	 * This handles updating the global settings set on the admin page.
3669
+	 *
3670
+	 * @throws EE_Error
3671
+	 * @throws InvalidDataTypeException
3672
+	 * @throws InvalidInterfaceException
3673
+	 * @throws InvalidArgumentException
3674
+	 * @throws ReflectionException
3675
+	 */
3676
+	protected function _update_global_settings()
3677
+	{
3678
+		/** @var EE_Network_Core_Config $network_config */
3679
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3680
+		$messages_config = EE_Registry::instance()->CFG->messages;
3681
+		$form = $this->_generate_global_settings_form();
3682
+		if ($form->was_submitted()) {
3683
+			$form->receive_form_submission();
3684
+			if ($form->is_valid()) {
3685
+				$valid_data = $form->valid_data();
3686
+				foreach ($valid_data as $property => $value) {
3687
+					$setter = 'set_' . $property;
3688
+					if (method_exists($network_config, $setter)) {
3689
+						$network_config->{$setter}($value);
3690
+					} elseif (property_exists($network_config, $property)
3691
+						&& $network_config->{$property} !== $value
3692
+					) {
3693
+						$network_config->{$property} = $value;
3694
+					} elseif (property_exists($messages_config, $property)
3695
+						&& $messages_config->{$property} !== $value
3696
+					) {
3697
+						$messages_config->{$property} = $value;
3698
+					}
3699
+				}
3700
+				// only update if the form submission was valid!
3701
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3702
+				EE_Registry::instance()->CFG->update_espresso_config();
3703
+				EE_Error::overwrite_success();
3704
+				EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3705
+			}
3706
+		}
3707
+		$this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3708
+	}
3709
+
3710
+
3711
+	/**
3712
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3713
+	 *
3714
+	 * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3715
+	 * @return string html formatted tabs
3716
+	 * @throws DomainException
3717
+	 */
3718
+	protected function _get_mt_tabs($tab_array)
3719
+	{
3720
+		$tab_array = (array) $tab_array;
3721
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3722
+		$tabs = '';
3723
+
3724
+		foreach ($tab_array as $tab) {
3725
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3726
+		}
3727
+
3728
+		return $tabs;
3729
+	}
3730
+
3731
+
3732
+	/**
3733
+	 * This prepares the content of the messenger meta box admin settings
3734
+	 *
3735
+	 * @param  EE_messenger $messenger The messenger we're setting up content for
3736
+	 * @return string html formatted content
3737
+	 * @throws DomainException
3738
+	 */
3739
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3740
+	{
3741
+
3742
+		$fields = $messenger->get_admin_settings_fields();
3743
+		$settings_template_args['template_form_fields'] = '';
3744
+
3745
+		// is $messenger active?
3746
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3747
+
3748
+
3749
+		if (! empty($fields)) {
3750
+			$existing_settings = $messenger->get_existing_admin_settings();
3751
+
3752
+			foreach ($fields as $fldname => $fldprops) {
3753
+				$field_id = $messenger->name . '-' . $fldname;
3754
+				$template_form_field[ $field_id ] = array(
3755
+					'name'       => 'messenger_settings[' . $field_id . ']',
3756
+					'label'      => $fldprops['label'],
3757
+					'input'      => $fldprops['field_type'],
3758
+					'type'       => $fldprops['value_type'],
3759
+					'required'   => $fldprops['required'],
3760
+					'validation' => $fldprops['validation'],
3761
+					'value'      => isset($existing_settings[ $field_id ])
3762
+						? $existing_settings[ $field_id ]
3763
+						: $fldprops['default'],
3764
+					'css_class'  => '',
3765
+					'format'     => $fldprops['format'],
3766
+				);
3767
+			}
3768
+
3769
+
3770
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3771
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3772
+				: '';
3773
+		}
3774
+
3775
+		// we also need some hidden fields
3776
+		$settings_template_args['hidden_fields'] = array(
3777
+			'messenger_settings[messenger]' => array(
3778
+				'type'  => 'hidden',
3779
+				'value' => $messenger->name,
3780
+			),
3781
+			'type'                          => array(
3782
+				'type'  => 'hidden',
3783
+				'value' => 'messenger',
3784
+			),
3785
+		);
3786
+
3787
+		// make sure any active message types that are existing are included in the hidden fields
3788
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3789
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3790
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3791
+					'type'  => 'hidden',
3792
+					'value' => $mt,
3793
+				);
3794
+			}
3795
+		}
3796
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3797
+			$settings_template_args['hidden_fields'],
3798
+			'array'
3799
+		);
3800
+		$active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3801
+
3802
+		$settings_template_args['messenger'] = $messenger->name;
3803
+		$settings_template_args['description'] = $messenger->description;
3804
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3805
+
3806
+
3807
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3808
+			$messenger->name
3809
+		)
3810
+			? $settings_template_args['show_hide_edit_form']
3811
+			: ' hidden';
3812
+
3813
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3814
+			? ' hidden'
3815
+			: $settings_template_args['show_hide_edit_form'];
3816
+
3817
+
3818
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3819
+		$settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3820
+		$settings_template_args['on_off_status'] = $active ? true : false;
3821
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3822
+		$content = EEH_Template::display_template(
3823
+			$template,
3824
+			$settings_template_args,
3825
+			true
3826
+		);
3827
+
3828
+		return $content;
3829
+	}
3830
+
3831
+
3832
+	/**
3833
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3834
+	 *
3835
+	 * @throws DomainException
3836
+	 * @throws EE_Error
3837
+	 * @throws InvalidDataTypeException
3838
+	 * @throws InvalidInterfaceException
3839
+	 * @throws InvalidArgumentException
3840
+	 * @throws ReflectionException
3841
+	 */
3842
+	public function activate_messenger_toggle()
3843
+	{
3844
+		$success = true;
3845
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3846
+		// let's check that we have required data
3847
+		if (! isset($this->_req_data['messenger'])) {
3848
+			EE_Error::add_error(
3849
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3850
+				__FILE__,
3851
+				__FUNCTION__,
3852
+				__LINE__
3853
+			);
3854
+			$success = false;
3855
+		}
3856
+
3857
+		// do a nonce check here since we're not arriving via a normal route
3858
+		$nonce = isset($this->_req_data['activate_nonce'])
3859
+			? sanitize_text_field($this->_req_data['activate_nonce'])
3860
+			: '';
3861
+		$nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3862
+
3863
+		$this->_verify_nonce($nonce, $nonce_ref);
3864
+
3865
+
3866
+		if (! isset($this->_req_data['status'])) {
3867
+			EE_Error::add_error(
3868
+				esc_html__(
3869
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3870
+					'event_espresso'
3871
+				),
3872
+				__FILE__,
3873
+				__FUNCTION__,
3874
+				__LINE__
3875
+			);
3876
+			$success = false;
3877
+		}
3878
+
3879
+		// do check to verify we have a valid status.
3880
+		$status = $this->_req_data['status'];
3881
+
3882
+		if ($status !== 'off' && $status !== 'on') {
3883
+			EE_Error::add_error(
3884
+				sprintf(
3885
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3886
+					$this->_req_data['status']
3887
+				),
3888
+				__FILE__,
3889
+				__FUNCTION__,
3890
+				__LINE__
3891
+			);
3892
+			$success = false;
3893
+		}
3894
+
3895
+		if ($success) {
3896
+			// made it here?  Stop dawdling then!!
3897
+			$success = $status === 'off'
3898
+				? $this->_deactivate_messenger($this->_req_data['messenger'])
3899
+				: $this->_activate_messenger($this->_req_data['messenger']);
3900
+		}
3901
+
3902
+		$this->_template_args['success'] = $success;
3903
+
3904
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
3905
+		$this->_return_json();
3906
+	}
3907
+
3908
+
3909
+	/**
3910
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3911
+	 *
3912
+	 * @throws DomainException
3913
+	 * @throws EE_Error
3914
+	 * @throws ReflectionException
3915
+	 * @throws InvalidDataTypeException
3916
+	 * @throws InvalidInterfaceException
3917
+	 * @throws InvalidArgumentException
3918
+	 */
3919
+	public function activate_mt_toggle()
3920
+	{
3921
+		$success = true;
3922
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3923
+
3924
+		// let's make sure we have the necessary data
3925
+		if (! isset($this->_req_data['message_type'])) {
3926
+			EE_Error::add_error(
3927
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3928
+				__FILE__,
3929
+				__FUNCTION__,
3930
+				__LINE__
3931
+			);
3932
+			$success = false;
3933
+		}
3934
+
3935
+		if (! isset($this->_req_data['messenger'])) {
3936
+			EE_Error::add_error(
3937
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3938
+				__FILE__,
3939
+				__FUNCTION__,
3940
+				__LINE__
3941
+			);
3942
+			$success = false;
3943
+		}
3944
+
3945
+		if (! isset($this->_req_data['status'])) {
3946
+			EE_Error::add_error(
3947
+				esc_html__(
3948
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3949
+					'event_espresso'
3950
+				),
3951
+				__FILE__,
3952
+				__FUNCTION__,
3953
+				__LINE__
3954
+			);
3955
+			$success = false;
3956
+		}
3957
+
3958
+
3959
+		// do check to verify we have a valid status.
3960
+		$status = $this->_req_data['status'];
3961
+
3962
+		if ($status !== 'activate' && $status !== 'deactivate') {
3963
+			EE_Error::add_error(
3964
+				sprintf(
3965
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3966
+					$this->_req_data['status']
3967
+				),
3968
+				__FILE__,
3969
+				__FUNCTION__,
3970
+				__LINE__
3971
+			);
3972
+			$success = false;
3973
+		}
3974
+
3975
+
3976
+		// do a nonce check here since we're not arriving via a normal route
3977
+		$nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3978
+		$nonce_ref = $this->_req_data['message_type'] . '_nonce';
3979
+
3980
+		$this->_verify_nonce($nonce, $nonce_ref);
3981
+
3982
+		if ($success) {
3983
+			// made it here? um, what are you waiting for then?
3984
+			$success = $status === 'deactivate'
3985
+				? $this->_deactivate_message_type_for_messenger(
3986
+					$this->_req_data['messenger'],
3987
+					$this->_req_data['message_type']
3988
+				)
3989
+				: $this->_activate_message_type_for_messenger(
3990
+					$this->_req_data['messenger'],
3991
+					$this->_req_data['message_type']
3992
+				);
3993
+		}
3994
+
3995
+		$this->_template_args['success'] = $success;
3996
+		$this->_return_json();
3997
+	}
3998
+
3999
+
4000
+	/**
4001
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
4002
+	 *
4003
+	 * @param string $messenger_name The name of the messenger being activated
4004
+	 * @return bool
4005
+	 * @throws DomainException
4006
+	 * @throws EE_Error
4007
+	 * @throws InvalidArgumentException
4008
+	 * @throws ReflectionException
4009
+	 * @throws InvalidDataTypeException
4010
+	 * @throws InvalidInterfaceException
4011
+	 */
4012
+	protected function _activate_messenger($messenger_name)
4013
+	{
4014
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4015
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4016
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
4017
+			? $active_messenger->get_default_message_types()
4018
+			: array();
4019
+
4020
+		// ensure is active
4021
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4022
+
4023
+		// set response_data for reload
4024
+		foreach ($message_types_to_activate as $message_type_name) {
4025
+			/** @var EE_message_type $message_type */
4026
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4027
+			if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4028
+				$messenger_name,
4029
+				$message_type_name
4030
+			)
4031
+				&& $message_type instanceof EE_message_type
4032
+			) {
4033
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
4034
+				if ($message_type->get_admin_settings_fields()) {
4035
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
4036
+				}
4037
+			}
4038
+		}
4039
+
4040
+		// add success message for activating messenger
4041
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4042
+	}
4043
+
4044
+
4045
+	/**
4046
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
4047
+	 *
4048
+	 * @param string $messenger_name The name of the messenger being activated
4049
+	 * @return bool
4050
+	 * @throws DomainException
4051
+	 * @throws EE_Error
4052
+	 * @throws InvalidArgumentException
4053
+	 * @throws ReflectionException
4054
+	 * @throws InvalidDataTypeException
4055
+	 * @throws InvalidInterfaceException
4056
+	 */
4057
+	protected function _deactivate_messenger($messenger_name)
4058
+	{
4059
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4060
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4061
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
4062
+
4063
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4064
+	}
4065
+
4066
+
4067
+	/**
4068
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4069
+	 *
4070
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
4071
+	 * @param string $message_type_name The name of the message type being activated for the messenger
4072
+	 * @return bool
4073
+	 * @throws DomainException
4074
+	 * @throws EE_Error
4075
+	 * @throws InvalidArgumentException
4076
+	 * @throws ReflectionException
4077
+	 * @throws InvalidDataTypeException
4078
+	 * @throws InvalidInterfaceException
4079
+	 */
4080
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4081
+	{
4082
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4083
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4084
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4085
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4086
+
4087
+		// ensure is active
4088
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4089
+
4090
+		// set response for load
4091
+		if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4092
+			$messenger_name,
4093
+			$message_type_name
4094
+		)
4095
+		) {
4096
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
4097
+			if ($message_type_to_activate->get_admin_settings_fields()) {
4098
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
4099
+			}
4100
+		}
4101
+
4102
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
4103
+			$active_messenger,
4104
+			$message_type_to_activate
4105
+		);
4106
+	}
4107
+
4108
+
4109
+	/**
4110
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4111
+	 *
4112
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4113
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
4114
+	 * @return bool
4115
+	 * @throws DomainException
4116
+	 * @throws EE_Error
4117
+	 * @throws InvalidArgumentException
4118
+	 * @throws ReflectionException
4119
+	 * @throws InvalidDataTypeException
4120
+	 * @throws InvalidInterfaceException
4121
+	 */
4122
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4123
+	{
4124
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4125
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4126
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4127
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4128
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4129
+
4130
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4131
+			$active_messenger,
4132
+			$message_type_to_deactivate
4133
+		);
4134
+	}
4135
+
4136
+
4137
+	/**
4138
+	 * This just initializes the defaults for activating messenger and message type responses.
4139
+	 */
4140
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
4141
+	{
4142
+		$this->_template_args['data']['active_mts'] = array();
4143
+		$this->_template_args['data']['mt_reload'] = array();
4144
+	}
4145
+
4146
+
4147
+	/**
4148
+	 * Setup appropriate response for activating a messenger and/or message types
4149
+	 *
4150
+	 * @param EE_messenger         $messenger
4151
+	 * @param EE_message_type|null $message_type
4152
+	 * @return bool
4153
+	 * @throws DomainException
4154
+	 * @throws EE_Error
4155
+	 * @throws InvalidArgumentException
4156
+	 * @throws ReflectionException
4157
+	 * @throws InvalidDataTypeException
4158
+	 * @throws InvalidInterfaceException
4159
+	 */
4160
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
4161
+		$messenger,
4162
+		EE_Message_Type $message_type = null
4163
+	) {
4164
+		// if $messenger isn't a valid messenger object then get out.
4165
+		if (! $messenger instanceof EE_Messenger) {
4166
+			EE_Error::add_error(
4167
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4168
+				__FILE__,
4169
+				__FUNCTION__,
4170
+				__LINE__
4171
+			);
4172
+
4173
+			return false;
4174
+		}
4175
+		// activated
4176
+		if ($this->_template_args['data']['active_mts']) {
4177
+			EE_Error::overwrite_success();
4178
+			// activated a message type with the messenger
4179
+			if ($message_type instanceof EE_message_type) {
4180
+				EE_Error::add_success(
4181
+					sprintf(
4182
+						esc_html__(
4183
+							'%s message type has been successfully activated with the %s messenger',
4184
+							'event_espresso'
4185
+						),
4186
+						ucwords($message_type->label['singular']),
4187
+						ucwords($messenger->label['singular'])
4188
+					)
4189
+				);
4190
+
4191
+				// if message type was invoice then let's make sure we activate the invoice payment method.
4192
+				if ($message_type->name === 'invoice') {
4193
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
4194
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4195
+					if ($pm instanceof EE_Payment_Method) {
4196
+						EE_Error::add_attention(
4197
+							esc_html__(
4198
+								'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.',
4199
+								'event_espresso'
4200
+							)
4201
+						);
4202
+					}
4203
+				}
4204
+				// just toggles the entire messenger
4205
+			} else {
4206
+				EE_Error::add_success(
4207
+					sprintf(
4208
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4209
+						ucwords($messenger->label['singular'])
4210
+					)
4211
+				);
4212
+			}
4213
+
4214
+			return true;
4215
+
4216
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4217
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4218
+			// in which case we just give a success message for the messenger being successfully activated.
4219
+		} else {
4220
+			if (! $messenger->get_default_message_types()) {
4221
+				// messenger doesn't have any default message types so still a success.
4222
+				EE_Error::add_success(
4223
+					sprintf(
4224
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4225
+						ucwords($messenger->label['singular'])
4226
+					)
4227
+				);
4228
+
4229
+				return true;
4230
+			} else {
4231
+				EE_Error::add_error(
4232
+					$message_type instanceof EE_message_type
4233
+						? sprintf(
4234
+							esc_html__(
4235
+								'%s message type was not successfully activated with the %s messenger',
4236
+								'event_espresso'
4237
+							),
4238
+							ucwords($message_type->label['singular']),
4239
+							ucwords($messenger->label['singular'])
4240
+						)
4241
+						: sprintf(
4242
+							esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4243
+							ucwords($messenger->label['singular'])
4244
+						),
4245
+					__FILE__,
4246
+					__FUNCTION__,
4247
+					__LINE__
4248
+				);
4249
+
4250
+				return false;
4251
+			}
4252
+		}
4253
+	}
4254
+
4255
+
4256
+	/**
4257
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
4258
+	 *
4259
+	 * @param EE_messenger         $messenger
4260
+	 * @param EE_message_type|null $message_type
4261
+	 * @return bool
4262
+	 * @throws DomainException
4263
+	 * @throws EE_Error
4264
+	 * @throws InvalidArgumentException
4265
+	 * @throws ReflectionException
4266
+	 * @throws InvalidDataTypeException
4267
+	 * @throws InvalidInterfaceException
4268
+	 */
4269
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4270
+		$messenger,
4271
+		EE_message_type $message_type = null
4272
+	) {
4273
+		EE_Error::overwrite_success();
4274
+
4275
+		// if $messenger isn't a valid messenger object then get out.
4276
+		if (! $messenger instanceof EE_Messenger) {
4277
+			EE_Error::add_error(
4278
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4279
+				__FILE__,
4280
+				__FUNCTION__,
4281
+				__LINE__
4282
+			);
4283
+
4284
+			return false;
4285
+		}
4286
+
4287
+		if ($message_type instanceof EE_message_type) {
4288
+			$message_type_name = $message_type->name;
4289
+			EE_Error::add_success(
4290
+				sprintf(
4291
+					esc_html__(
4292
+						'%s message type has been successfully deactivated for the %s messenger.',
4293
+						'event_espresso'
4294
+					),
4295
+					ucwords($message_type->label['singular']),
4296
+					ucwords($messenger->label['singular'])
4297
+				)
4298
+			);
4299
+		} else {
4300
+			$message_type_name = '';
4301
+			EE_Error::add_success(
4302
+				sprintf(
4303
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4304
+					ucwords($messenger->label['singular'])
4305
+				)
4306
+			);
4307
+		}
4308
+
4309
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4310
+		if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4311
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
4312
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4313
+			if ($count_updated > 0) {
4314
+				$msg = $message_type_name === 'invoice'
4315
+					? esc_html__(
4316
+						'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.',
4317
+						'event_espresso'
4318
+					)
4319
+					: esc_html__(
4320
+						'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.',
4321
+						'event_espresso'
4322
+					);
4323
+				EE_Error::add_attention($msg);
4324
+			}
4325
+		}
4326
+
4327
+		return true;
4328
+	}
4329
+
4330
+
4331
+	/**
4332
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4333
+	 *
4334
+	 * @throws DomainException
4335
+	 */
4336
+	public function update_mt_form()
4337
+	{
4338
+		if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4339
+			EE_Error::add_error(
4340
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4341
+				__FILE__,
4342
+				__FUNCTION__,
4343
+				__LINE__
4344
+			);
4345
+			$this->_return_json();
4346
+		}
4347
+
4348
+		$message_types = $this->get_installed_message_types();
4349
+
4350
+		$message_type = $message_types[ $this->_req_data['message_type'] ];
4351
+		$messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4352
+
4353
+		$content = $this->_message_type_settings_content(
4354
+			$message_type,
4355
+			$messenger,
4356
+			true
4357
+		);
4358
+		$this->_template_args['success'] = true;
4359
+		$this->_template_args['content'] = $content;
4360
+		$this->_return_json();
4361
+	}
4362
+
4363
+
4364
+	/**
4365
+	 * this handles saving the settings for a messenger or message type
4366
+	 *
4367
+	 */
4368
+	public function save_settings()
4369
+	{
4370
+		if (! isset($this->_req_data['type'])) {
4371
+			EE_Error::add_error(
4372
+				esc_html__(
4373
+					'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4374
+					'event_espresso'
4375
+				),
4376
+				__FILE__,
4377
+				__FUNCTION__,
4378
+				__LINE__
4379
+			);
4380
+			$this->_template_args['error'] = true;
4381
+			$this->_return_json();
4382
+		}
4383
+
4384
+
4385
+		if ($this->_req_data['type'] === 'messenger') {
4386
+			// this should be an array.
4387
+			$settings = $this->_req_data['messenger_settings'];
4388
+			$messenger = $settings['messenger'];
4389
+			// let's setup the settings data
4390
+			foreach ($settings as $key => $value) {
4391
+				switch ($key) {
4392
+					case 'messenger':
4393
+						unset($settings['messenger']);
4394
+						break;
4395
+					case 'message_types':
4396
+						unset($settings['message_types']);
4397
+						break;
4398
+					default:
4399
+						$settings[ $key ] = $value;
4400
+						break;
4401
+				}
4402
+			}
4403
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4404
+		} elseif ($this->_req_data['type'] === 'message_type') {
4405
+			$settings = $this->_req_data['message_type_settings'];
4406
+			$messenger = $settings['messenger'];
4407
+			$message_type = $settings['message_type'];
4408
+
4409
+			foreach ($settings as $key => $value) {
4410
+				switch ($key) {
4411
+					case 'messenger':
4412
+						unset($settings['messenger']);
4413
+						break;
4414
+					case 'message_type':
4415
+						unset($settings['message_type']);
4416
+						break;
4417
+					default:
4418
+						$settings[ $key ] = $value;
4419
+						break;
4420
+				}
4421
+			}
4422
+
4423
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4424
+		}
4425
+
4426
+		// okay we should have the data all setup.  Now we just update!
4427
+		$success = $this->_message_resource_manager->update_active_messengers_option();
4428
+
4429
+		if ($success) {
4430
+			EE_Error::add_success(__('Settings updated', 'event_espresso'));
4431
+		} else {
4432
+			EE_Error::add_error(
4433
+				esc_html__(
4434
+					'Settings did not get updated',
4435
+					'event_espresso'
4436
+				),
4437
+				__FILE__,
4438
+				__FUNCTION__,
4439
+				__LINE__
4440
+			);
4441
+		}
4442
+
4443
+		$this->_template_args['success'] = $success;
4444
+		$this->_return_json();
4445
+	}
4446
+
4447
+
4448
+
4449
+
4450
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4451
+
4452
+
4453
+	/**
4454
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4455
+	 * However, this does not send immediately, it just queues for sending.
4456
+	 *
4457
+	 * @since 4.9.0
4458
+	 * @throws EE_Error
4459
+	 * @throws InvalidDataTypeException
4460
+	 * @throws InvalidInterfaceException
4461
+	 * @throws InvalidArgumentException
4462
+	 * @throws ReflectionException
4463
+	 */
4464
+	protected function _generate_now()
4465
+	{
4466
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4467
+		$this->_redirect_after_action(false, '', '', array(), true);
4468
+	}
4469
+
4470
+
4471
+	/**
4472
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4473
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4474
+	 *
4475
+	 * @since 4.9.0
4476
+	 * @throws EE_Error
4477
+	 * @throws InvalidDataTypeException
4478
+	 * @throws InvalidInterfaceException
4479
+	 * @throws InvalidArgumentException
4480
+	 * @throws ReflectionException
4481
+	 */
4482
+	protected function _generate_and_send_now()
4483
+	{
4484
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4485
+		$this->_redirect_after_action(false, '', '', array(), true);
4486
+	}
4487
+
4488
+
4489
+	/**
4490
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4491
+	 *
4492
+	 * @since 4.9.0
4493
+	 * @throws EE_Error
4494
+	 * @throws InvalidDataTypeException
4495
+	 * @throws InvalidInterfaceException
4496
+	 * @throws InvalidArgumentException
4497
+	 * @throws ReflectionException
4498
+	 */
4499
+	protected function _queue_for_resending()
4500
+	{
4501
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4502
+		$this->_redirect_after_action(false, '', '', array(), true);
4503
+	}
4504
+
4505
+
4506
+	/**
4507
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4508
+	 *
4509
+	 * @since 4.9.0
4510
+	 * @throws EE_Error
4511
+	 * @throws InvalidDataTypeException
4512
+	 * @throws InvalidInterfaceException
4513
+	 * @throws InvalidArgumentException
4514
+	 * @throws ReflectionException
4515
+	 */
4516
+	protected function _send_now()
4517
+	{
4518
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4519
+		$this->_redirect_after_action(false, '', '', array(), true);
4520
+	}
4521
+
4522
+
4523
+	/**
4524
+	 * Deletes EE_messages for IDs in the request.
4525
+	 *
4526
+	 * @since 4.9.0
4527
+	 * @throws EE_Error
4528
+	 * @throws InvalidDataTypeException
4529
+	 * @throws InvalidInterfaceException
4530
+	 * @throws InvalidArgumentException
4531
+	 */
4532
+	protected function _delete_ee_messages()
4533
+	{
4534
+		$msg_ids = $this->_get_msg_ids_from_request();
4535
+		$deleted_count = 0;
4536
+		foreach ($msg_ids as $msg_id) {
4537
+			if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4538
+				$deleted_count++;
4539
+			}
4540
+		}
4541
+		if ($deleted_count) {
4542
+			EE_Error::add_success(
4543
+				esc_html(
4544
+					_n(
4545
+						'Message successfully deleted',
4546
+						'Messages successfully deleted',
4547
+						$deleted_count,
4548
+						'event_espresso'
4549
+					)
4550
+				)
4551
+			);
4552
+			$this->_redirect_after_action(
4553
+				false,
4554
+				'',
4555
+				'',
4556
+				array(),
4557
+				true
4558
+			);
4559
+		} else {
4560
+			EE_Error::add_error(
4561
+				_n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4562
+				__FILE__,
4563
+				__FUNCTION__,
4564
+				__LINE__
4565
+			);
4566
+			$this->_redirect_after_action(false, '', '', array(), true);
4567
+		}
4568
+	}
4569
+
4570
+
4571
+	/**
4572
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4573
+	 *
4574
+	 * @since 4.9.0
4575
+	 * @return array
4576
+	 */
4577
+	protected function _get_msg_ids_from_request()
4578
+	{
4579
+		if (! isset($this->_req_data['MSG_ID'])) {
4580
+			return array();
4581
+		}
4582
+
4583
+		return is_array($this->_req_data['MSG_ID'])
4584
+			? array_keys($this->_req_data['MSG_ID'])
4585
+			: array($this->_req_data['MSG_ID']);
4586
+	}
4587 4587
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Message_Resource_Manager.lib.php 2 patches
Indentation   +1115 added lines, -1115 removed lines patch added patch discarded remove patch
@@ -12,1119 +12,1119 @@
 block discarded – undo
12 12
 class EE_Message_Resource_Manager
13 13
 {
14 14
 
15
-    /**
16
-     * This option in the database is used to keep a record of message types that have been activated for a messenger
17
-     * at some point in the history of the site.  It is utilized by the implementation of the 'force' flag in
18
-     * EE_Register_Message_Type.  The force flag is an indication of whether a message type should be activated by
19
-     * default when the message type is registered.  However, if a user has explicitly deactivated a message type, then
20
-     * the force flag is ignored.  The method by which the code knows whether to ignore this flag is via this option.
21
-     * Note, that this is NOT a historical record.  Its entirely possible for a message type to have been activated for
22
-     * a messenger and yet not have a record in this option.  This occurs when a message type is inactivated through an
23
-     * automated process (when an add-on registering the message type deactivates, or when some other code calls the
24
-     * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to ensure
25
-     * the "force" flag is respected if that message type is later re-registered.
26
-     *
27
-     * This option should NOT be used to determine the current "active" state of a message type for a given messenger.
28
-     *
29
-     * The name of this option (and related methods/properties) is due to matching the original intended purpose for the
30
-     * option that got superseded by later behaviour requirements.
31
-     */
32
-    const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger';
33
-
34
-    /**
35
-     * @type boolean $_initialized
36
-     */
37
-    protected $_initialized = false;
38
-
39
-    /**
40
-     * @type EE_Messenger_Collection $_messenger_collection_loader
41
-     */
42
-    protected $_messenger_collection_loader;
43
-
44
-    /**
45
-     * @type EE_Message_Type_Collection $_message_type_collection_loader
46
-     */
47
-    protected $_message_type_collection_loader;
48
-
49
-    /**
50
-     * @type EEM_Message_Template_Group $_message_template_group_model
51
-     */
52
-    protected $_message_template_group_model;
53
-
54
-    /**
55
-     * @type EE_messenger[]
56
-     */
57
-    protected $_installed_messengers = array();
58
-
59
-    /**
60
-     * @type EE_message_type[]
61
-     */
62
-    protected $_installed_message_types = array();
63
-
64
-    /**
65
-     * Array of active messengers.
66
-     * Format is this:
67
-     * array(
68
-     *      'messenger_name' => EE_messenger
69
-     * )
70
-     *
71
-     * @type EE_messenger[]
72
-     */
73
-    protected $_active_messengers = array();
74
-
75
-    /**
76
-     * Formatted array of active message types grouped per messenger.
77
-     * Format is this:
78
-     * array(
79
-     *      'messenger_name' => array(
80
-     *          'settings' => array(
81
-     *              '{messenger_name}-message_types' => array(
82
-     *                  'message_type_name' => array() //variable array of settings corresponding to message type.
83
-     *              )
84
-     *          )
85
-     *      )
86
-     * )
87
-     *
88
-     * @type array
89
-     */
90
-    protected $_active_message_types = array();
91
-
92
-
93
-    /**
94
-     * This holds the array of messengers and their corresponding message types that have
95
-     * been activated on a site at some point.  This is an important record that helps the messages system
96
-     * not accidentally reactivate something that was intentionally deactivated by a user.
97
-     *
98
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
99
-     *
100
-     * @type array
101
-     */
102
-    protected $_has_activated_messengers_and_message_types = array();
103
-
104
-    /**
105
-     * An array of unique message type contexts across all active message types.
106
-     * The array will be indexed by either 'slugs' or 'all'.
107
-     * The slugs index contains an array indexed by unique context slugs with the latest label representation for that
108
-     * slug. array(
109
-     *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
110
-     * );
111
-     * The all index returns an array in this format:
112
-     * array(
113
-     *      'message_type_name' => array(
114
-     *          'context_slug' => array(
115
-     *              'label' => 'localized label for context',
116
-     *              'description' => 'localized description for context'
117
-     *          )
118
-     *      )
119
-     * );
120
-     *
121
-     * @type array
122
-     */
123
-    protected $_contexts = array();
124
-
125
-
126
-    /**
127
-     * EE_Message_Resource_Manager constructor.
128
-     *
129
-     * @param \EE_Messenger_Collection_Loader    $Messenger_Collection_Loader
130
-     * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader
131
-     * @param \EEM_Message_Template_Group        $Message_Template_Group_Model
132
-     */
133
-    public function __construct(
134
-        EE_Messenger_Collection_Loader $Messenger_Collection_Loader,
135
-        EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader,
136
-        EEM_Message_Template_Group $Message_Template_Group_Model
137
-    ) {
138
-        $this->_messenger_collection_loader    = $Messenger_Collection_Loader;
139
-        $this->_message_type_collection_loader = $Message_Type_Collection_Loader;
140
-        $this->_message_template_group_model   = $Message_Template_Group_Model;
141
-    }
142
-
143
-
144
-    /**
145
-     * @return void
146
-     */
147
-    protected function _initialize_collections()
148
-    {
149
-        if ($this->_initialized) {
150
-            return;
151
-        }
152
-        $this->_initialized = true;
153
-        $this->_messenger_collection_loader->load_messengers_from_folder();
154
-        $this->_message_type_collection_loader->load_message_types_from_folder();
155
-        $this->get_has_activated_messengers_option(true);
156
-        $this->_set_active_messengers_and_message_types();
157
-    }
158
-
159
-
160
-    /**
161
-     * @return EE_Messenger_Collection
162
-     */
163
-    public function messenger_collection()
164
-    {
165
-        $this->_initialize_collections();
166
-        return $this->_messenger_collection_loader->messenger_collection();
167
-    }
168
-
169
-
170
-    /**
171
-     * @return EE_messenger[]
172
-     */
173
-    public function active_messengers()
174
-    {
175
-        $this->_initialize_collections();
176
-        return $this->_active_messengers;
177
-    }
178
-
179
-
180
-    /**
181
-     * @param string $messenger_name
182
-     * @return \EE_messenger
183
-     */
184
-    public function get_messenger($messenger_name)
185
-    {
186
-        return $this->messenger_collection()->get_by_info($messenger_name);
187
-    }
188
-
189
-
190
-    /**
191
-     * This returns the corresponding EE_messenger object for the given string if it is active.
192
-     *
193
-     * @param string $messenger
194
-     * @return EE_messenger | null
195
-     */
196
-    public function get_active_messenger($messenger)
197
-    {
198
-        $this->_initialize_collections();
199
-        return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
200
-    }
201
-
202
-
203
-    /**
204
-     * @return \EE_messenger[]
205
-     */
206
-    public function installed_messengers()
207
-    {
208
-        if (empty($this->_installed_messengers)) {
209
-            $this->_installed_messengers = array();
210
-            $this->messenger_collection()->rewind();
211
-            while ($this->messenger_collection()->valid()) {
212
-                $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
213
-                $this->messenger_collection()->next();
214
-            }
215
-        }
216
-        return $this->_installed_messengers;
217
-    }
218
-
219
-
220
-    /**
221
-     * @param string $messenger_name
222
-     * @return \EE_messenger
223
-     * @throws EE_Error
224
-     */
225
-    public function valid_messenger($messenger_name)
226
-    {
227
-        $messenger = $this->get_messenger($messenger_name);
228
-        if ($messenger instanceof EE_messenger) {
229
-            return $messenger;
230
-        }
231
-        throw new EE_Error(
232
-            sprintf(
233
-                __('The "%1$s" messenger is either invalid or not installed', 'event_espresso'),
234
-                $messenger_name
235
-            )
236
-        );
237
-    }
238
-
239
-
240
-    /**
241
-     * @return EE_Message_Type_Collection
242
-     */
243
-    public function message_type_collection()
244
-    {
245
-        $this->_initialize_collections();
246
-        return $this->_message_type_collection_loader->message_type_collection();
247
-    }
248
-
249
-
250
-    /**
251
-     * @return array
252
-     */
253
-    public function active_message_types()
254
-    {
255
-        $this->_initialize_collections();
256
-        return $this->_active_message_types;
257
-    }
258
-
259
-
260
-    /**
261
-     * @param string $message_type_name
262
-     * @return \EE_message_type
263
-     */
264
-    public function get_message_type($message_type_name)
265
-    {
266
-        return $this->message_type_collection()->get_by_info($message_type_name);
267
-    }
268
-
269
-
270
-    /**
271
-     * This returns the EE_message_type from the active message types array ( if present );
272
-     *
273
-     * @param string $messenger_name
274
-     * @param string $message_type_name
275
-     * @return \EE_message_type|null
276
-     */
277
-    public function get_active_message_type_for_messenger($messenger_name, $message_type_name)
278
-    {
279
-        return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
280
-            ? $this->get_message_type($message_type_name)
281
-            : null;
282
-    }
283
-
284
-
285
-    /**
286
-     * Returns whether the given message type is active for the given messenger.
287
-     *
288
-     * @param string $messenger_name
289
-     * @param string $message_type_name
290
-     * @return bool
291
-     */
292
-    public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293
-    {
294
-        $this->_initialize_collections();
295
-        return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
296
-    }
297
-
298
-
299
-    /**
300
-     * Returns whether the given messenger is active.
301
-     *
302
-     * @param string $messenger_name the name of the messenger to check if active.
303
-     * @return bool
304
-     */
305
-    public function is_messenger_active($messenger_name)
306
-    {
307
-        $this->_initialize_collections();
308
-        return ! empty($this->_active_message_types[ $messenger_name ]);
309
-    }
310
-
311
-
312
-    /**
313
-     * This returns any settings that might be on a message type for a messenger
314
-     *
315
-     * @param string $messenger_name    The slug of the messenger
316
-     * @param string $message_type_name The slug of the message type getting the settings for.
317
-     * @return array
318
-     */
319
-    public function get_message_type_settings_for_messenger($messenger_name, $message_type_name)
320
-    {
321
-        $settings = array();
322
-        if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
-            $settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
-                ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
325
-                : array();
326
-        }
327
-        return $settings;
328
-    }
329
-
330
-
331
-    /**
332
-     * Returns whether the given messenger name has active message types on it.
333
-     * Infers whether the messenger is active or not as well.
334
-     *
335
-     * @param string $messenger_name
336
-     * @return bool
337
-     */
338
-    public function messenger_has_active_message_types($messenger_name)
339
-    {
340
-        $this->_initialize_collections();
341
-        return
342
-            ! empty($this->_active_message_types[ $messenger_name ])
343
-            && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
344
-    }
345
-
346
-
347
-    /**
348
-     * This checks the _active_message_types property for any active message types
349
-     * that are present for the given messenger and returns them.
350
-     *
351
-     * @since 4.9.0
352
-     * @param string $messenger_name The messenger being checked
353
-     * @return EE_message_type[]|array    (empty array if no active_message_types)
354
-     */
355
-    public function get_active_message_types_for_messenger($messenger_name)
356
-    {
357
-        $message_types = array();
358
-        if (! $this->messenger_has_active_message_types($messenger_name)) {
359
-            return $message_types;
360
-        }
361
-        $installed_message_types = $this->installed_message_types();
362
-        foreach ($installed_message_types as $message_type_name => $message_type) {
363
-            if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
-                $message_types[ $message_type_name ] = $message_type;
365
-            }
366
-        }
367
-        return $message_types;
368
-    }
369
-
370
-
371
-    /**
372
-     * This does NOT return the _active_message_types property but
373
-     * simply returns an array of active message type names from that property.
374
-     * (The _active_message_types property is indexed by messenger and active message_types per messenger).
375
-     *
376
-     * @return array message_type references (string)
377
-     */
378
-    public function list_of_active_message_types()
379
-    {
380
-        $active_message_type_names = array();
381
-        $this->_initialize_collections();
382
-        foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
-            if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
384
-                continue;
385
-            }
386
-            foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
-                if (! in_array($message_type_name, $active_message_type_names)) {
388
-                    $active_message_type_names[] = $message_type_name;
389
-                }
390
-            }
391
-        }
392
-        return $active_message_type_names;
393
-    }
394
-
395
-
396
-    /**
397
-     * Same as list_of_active_message_types() except this returns actual EE_message_type objects
398
-     *
399
-     * @since 4.9.0
400
-     * @return \EE_message_type[]
401
-     */
402
-    public function get_active_message_type_objects()
403
-    {
404
-        $active_message_types      = array();
405
-        $installed_message_types   = $this->installed_message_types();
406
-        $active_message_type_names = $this->list_of_active_message_types();
407
-        foreach ($active_message_type_names as $active_message_type_name) {
408
-            if (isset($installed_message_types[ $active_message_type_name ])) {
409
-                $active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
410
-            }
411
-        }
412
-        return $active_message_types;
413
-    }
414
-
415
-
416
-    /**
417
-     * @return \EE_message_type[]
418
-     */
419
-    public function installed_message_types()
420
-    {
421
-        if (empty($this->_installed_message_types)) {
422
-            $this->message_type_collection()->rewind();
423
-            while ($this->message_type_collection()->valid()) {
424
-                $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
425
-                $this->message_type_collection()->next();
426
-            }
427
-        }
428
-        return $this->_installed_message_types;
429
-    }
430
-
431
-
432
-    /**
433
-     * @param string $message_type_name
434
-     * @return \EE_message_type
435
-     * @throws EE_Error
436
-     */
437
-    public function valid_message_type($message_type_name)
438
-    {
439
-        $message_type = $this->get_message_type($message_type_name);
440
-        if ($message_type instanceof EE_message_type) {
441
-            return $message_type;
442
-        }
443
-        throw new EE_Error(
444
-            sprintf(
445
-                __('The "%1$s" message type is either invalid or not installed', 'event_espresso'),
446
-                $message_type_name
447
-            )
448
-        );
449
-    }
450
-
451
-
452
-    /**
453
-     * valid_message_type_for_messenger
454
-     *
455
-     * @param EE_messenger $messenger
456
-     * @param string       $message_type_name
457
-     * @return boolean
458
-     * @throws EE_Error
459
-     */
460
-    public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461
-    {
462
-        $valid_message_types = $messenger->get_valid_message_types();
463
-        if (! in_array($message_type_name, $valid_message_types)) {
464
-            throw new EE_Error(
465
-                sprintf(
466
-                    __(
467
-                        'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger.  Double-check the spelling and verify that message type has been registered as a valid type with the messenger.',
468
-                        'event_espresso'
469
-                    ),
470
-                    $message_type_name,
471
-                    __METHOD__,
472
-                    $messenger->name
473
-                )
474
-            );
475
-        }
476
-        return true;
477
-    }
478
-
479
-
480
-    /**
481
-     * Used to return active messengers array stored in the wp options table.
482
-     * If no value is present in the option then an empty array is returned.
483
-     *
484
-     * @param   bool $reset     If true then we ignore whether the option is cached on the _active_message_types
485
-     *                          property and pull directly from the db.  Otherwise whatever is currently on the
486
-     *                          $_active_message_types property is pulled.
487
-     * @return array
488
-     */
489
-    public function get_active_messengers_option($reset = false)
490
-    {
491
-        if ($reset) {
492
-            $this->_active_message_types = get_option('ee_active_messengers', array());
493
-        }
494
-        return $this->_active_message_types;
495
-    }
496
-
497
-
498
-    /**
499
-     * Used to update the active messengers array stored in the wp options table.
500
-     *
501
-     * @param array $active_messenger_settings Incoming data to save.  If empty, then the internal cached property
502
-     *                                         representing this data is used.
503
-     * @return bool FALSE if not updated, TRUE if updated.
504
-     */
505
-    public function update_active_messengers_option($active_messenger_settings = array())
506
-    {
507
-        $active_messenger_settings = empty($active_messenger_settings) ? $this->_active_message_types : $active_messenger_settings;
508
-        // make sure _active_message_types is updated (this is the internal cache for the settings).
509
-        $this->_active_message_types = $active_messenger_settings;
510
-        return update_option('ee_active_messengers', $active_messenger_settings);
511
-    }
512
-
513
-
514
-    /**
515
-     * Used to return has activated message types for messengers array stored in the wp options table.
516
-     * If no value is present in the option then an empty array is returned.
517
-     * The value is cached on the $_has_activated_messengers_and_message_types property for future calls.
518
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
519
-     *
520
-     * @param   bool $reset Used to indicate that any cached value should be ignored.
521
-     * @return array
522
-     */
523
-    public function get_has_activated_messengers_option($reset = false)
524
-    {
525
-        if ($reset || empty($this->_has_activated_messengers_and_message_types)) {
526
-            $this->_has_activated_messengers_and_message_types = get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, array());
527
-        }
528
-        return $this->_has_activated_messengers_and_message_types;
529
-    }
530
-
531
-
532
-    /**
533
-     * Used to update the has activated option in the db.
534
-     *
535
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
536
-     *
537
-     * @param array $has_activated_messengers Incoming data to save.  If empty, then the internal cached property
538
-     *                                        representing this data is used.
539
-     * @return bool FALSE if not updated, TRUE if updated.
540
-     */
541
-    public function update_has_activated_messengers_option($has_activated_messengers = array())
542
-    {
543
-        // make sure the option has been retrieved from first so we don't overwrite it accidentally.
544
-        if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) {
545
-            $this->get_has_activated_messengers_option();
546
-        }
547
-        $has_activated_messengers = empty($has_activated_messengers)
548
-            ? $this->_has_activated_messengers_and_message_types
549
-            : $has_activated_messengers;
550
-        return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers);
551
-    }
552
-
553
-
554
-    /**
555
-     * wrapper for _set_active_messengers_and_message_types()
556
-     */
557
-    public function reset_active_messengers_and_message_types()
558
-    {
559
-        $this->_set_active_messengers_and_message_types();
560
-    }
561
-
562
-
563
-    /**
564
-     * Generate list of active messengers and message types from collection.
565
-     * This sets up the active messengers from what is present in the database.
566
-     */
567
-    protected function _set_active_messengers_and_message_types()
568
-    {
569
-        // echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n";
570
-        // list of activated messengers as set via the admin
571
-        // note calling `get_active_messengers_options` also initializes the _active_message_types property.
572
-        $this->get_active_messengers_option(true);
573
-        $this->ensure_messengers_are_active(array(), false, true);
574
-        $this->update_active_messengers_option();
575
-        $this->update_has_activated_messengers_option();
576
-    }
577
-
578
-
579
-    /**
580
-     * Ensures that the specified messenger is currently active.
581
-     * If not, activates it and its default message types.
582
-     *
583
-     * @param string $messenger_name
584
-     * @param bool   $update_option Whether to update the option in the db or not.
585
-     * @return boolean true if either already active or successfully activated.
586
-     */
587
-    public function ensure_messenger_is_active($messenger_name, $update_option = true)
588
-    {
589
-        if (! isset($this->_active_messengers[ $messenger_name ])) {
590
-            try {
591
-                $this->activate_messenger($messenger_name, array(), $update_option);
592
-            } catch (EE_Error $e) {
593
-                EE_Error::add_error(
594
-                    $e->getMessage(),
595
-                    __FILE__,
596
-                    __FUNCTION__,
597
-                    __LINE__
598
-                );
599
-                return false;
600
-            }
601
-        }
602
-        return true;
603
-    }
604
-
605
-
606
-    /**
607
-     * This ensures the given array of messenger names is active in the system.
608
-     * Note, this method will not activate any NEW message types for the messenger when it is called. Instead,
609
-     * it will automatically activate the default message types for the messenger if its not active.
610
-     *
611
-     * @param array $messenger_names  Array of messenger names for messengers to be activated.  If an empty array
612
-     *                                (default) then will attempt to set the active messengers from the
613
-     *                                activated_messengers option
614
-     *                                (stored in $_active_message_types property).
615
-     * @param bool  $update_option    Whether to update the related active messengers option.
616
-     * @param bool  $verify           Whether to verify the messengers are installed before activating. Note if this is
617
-     *                                set to true and a messenger is indicated as active, but is NOT installed, then it
618
-     *                                will automatically be deactivated.
619
-     */
620
-    public function ensure_messengers_are_active($messenger_names = array(), $update_option = true, $verify = false)
621
-    {
622
-        $messenger_names = empty($messenger_names) ? array_keys($this->_active_message_types) : $messenger_names;
623
-
624
-        $not_installed = array();
625
-        foreach ($messenger_names as $messenger_name) {
626
-            if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) {
627
-                $not_installed[] = $messenger_name;
628
-                $this->deactivate_messenger($messenger_name);
629
-                continue;
630
-            }
631
-            $this->ensure_messenger_is_active($messenger_name, $update_option);
632
-        }
633
-
634
-        if (! empty($not_installed)) {
635
-            EE_Error::add_error(
636
-                sprintf(
637
-                    __('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
638
-                    '<br />',
639
-                    implode(', ', $not_installed)
640
-                ),
641
-                __FILE__,
642
-                __FUNCTION__,
643
-                __LINE__
644
-            );
645
-        }
646
-    }
647
-
648
-
649
-    /**
650
-     * Ensures that the specified message type for the given messenger is currently active, if not activates it.
651
-     * This ALSO ensures that the given messenger is active as well!
652
-     *
653
-     * @param string $message_type_name message type name.
654
-     * @param        $messenger_name
655
-     * @param bool   $update_option     Whether to update the option in the db or not.
656
-     * @return bool  Returns true if already is active or if was activated successfully.
657
-     * @throws EE_Error
658
-     */
659
-    public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true)
660
-    {
661
-        // grab the messenger to work with.
662
-        $messenger = $this->valid_messenger($messenger_name);
663
-        if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) {
664
-            // ensure messenger is active (that's an inherent coupling between active message types and the
665
-            // messenger they are being activated for.
666
-            try {
667
-                if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668
-                    // all is good so let's just get it active
669
-                    $this->activate_messenger($messenger, array($message_type_name), $update_option);
670
-                }
671
-            } catch (EE_Error $e) {
672
-                EE_Error::add_error(
673
-                    $e->getMessage(),
674
-                    __FILE__,
675
-                    __FUNCTION__,
676
-                    __LINE__
677
-                );
678
-                return false;
679
-            }
680
-        }
681
-        return true;
682
-    }
683
-
684
-
685
-    /**
686
-     * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a
687
-     * messenger are active in one go.
688
-     *
689
-     * @param array  $message_type_names Array of message type names to ensure are active.
690
-     * @param string $messenger_name     The name of the messenger that the message types are to be activated on.
691
-     * @param bool   $update_option      Whether to persist the activation to the database or not (default true).
692
-     */
693
-    public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true)
694
-    {
695
-        $message_type_names = (array) $message_type_names;
696
-        foreach ($message_type_names as $message_type_name) {
697
-            // note, intentionally not updating option here because we're in a loop.
698
-            // We'll follow the instructions of the incoming $update_option argument after the loop.
699
-            $this->ensure_message_type_is_active($message_type_name, $messenger_name, false);
700
-        }
701
-        if ($update_option) {
702
-            $this->update_active_messengers_option();
703
-            $this->update_has_activated_messengers_option();
704
-        }
705
-    }
706
-
707
-
708
-    /**
709
-     * Activates the specified messenger.
710
-     *
711
-     * @param EE_messenger|string $messenger    Instantiated EE_messenger OR messenger name if not already loaded!
712
-     * @param array  $message_type_names        An array of message type names to activate with this messenger.
713
-     *                                          If included we do NOT setup the default message types
714
-     *                                          (assuming they are already setup.)
715
-     * @param bool   $update_active_messengers_option
716
-     * @return array of generated templates
717
-     * @throws EE_Error
718
-     */
719
-    public function activate_messenger(
720
-        $messenger,
721
-        $message_type_names = array(),
722
-        $update_active_messengers_option = true
723
-    ) {
724
-        $templates = array();
725
-        // grab the messenger to work with.
726
-        $messenger = $messenger instanceof EE_messenger
727
-            ? $messenger
728
-            : $this->messenger_collection()->get_by_info($messenger);
729
-        // it's inactive. Activate it.
730
-        if ($messenger instanceof EE_messenger) {
731
-            $this->_active_messengers[ $messenger->name ] = $messenger;
732
-            // activate incoming message types set to be activated with messenger.
733
-            $message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734
-            // setup any initial settings for the messenger if necessary.
735
-            $this->add_settings_for_messenger($messenger->name);
736
-            if ($update_active_messengers_option) {
737
-                $this->update_active_messengers_option();
738
-                $this->update_has_activated_messengers_option();
739
-            }
740
-            // generate new templates if necessary and ensure all related templates that are already in the database are
741
-            // marked active.  Note, this will also deactivate a message type for a messenger if the template
742
-            // cannot be successfully created during its attempt (only happens for global template attempts).
743
-            if (! empty($message_type_names)) {
744
-                $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745
-                EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746
-            }
747
-        }
748
-        return $templates;
749
-    }
750
-
751
-
752
-    /**
753
-     * Activates given message types for the given EE_messenger object.
754
-     * Note: (very important) This method does not persist the activation to the database.
755
-     * See code implementing this method in this class for examples of how to persist.
756
-     *
757
-     * @param \EE_messenger $messenger
758
-     * @param  array        $message_type_names
759
-     * @return array
760
-     */
761
-    protected function _activate_message_types(EE_messenger $messenger, $message_type_names = array())
762
-    {
763
-        // If $message_type_names is empty, AND $this->_active_message_types is empty, then that means
764
-        // things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765
-        // So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766
-        // only override _active_message_types when an explicit array of $message_type_names has been provided.
767
-        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
768
-            ? $messenger->get_default_message_types()
769
-            : (array) $message_type_names;
770
-
771
-        // now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
-        if (! isset($this->_active_message_types[ $messenger->name ])) {
773
-            $this->_active_message_types[ $messenger->name ]['settings'] = array();
774
-        }
775
-
776
-        if ($message_type_names) {
777
-            // cycle thru message types
778
-            foreach ($message_type_names as $message_type_name) {
779
-                // only register the message type as active IF it isn't already active
780
-                // and if its actually installed.
781
-                if (! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
782
-                ) {
783
-                    $this->add_settings_for_message_type($messenger->name, $message_type_name);
784
-                    $this->_set_messenger_has_activated_message_type(
785
-                        $messenger,
786
-                        $message_type_name
787
-                    );
788
-                }
789
-            }
790
-        }
791
-        return $message_type_names;
792
-    }
793
-
794
-
795
-    /**
796
-     * add_settings_for_message_type
797
-     * NOTE This does NOT automatically persist any settings to the db.  Client code should call
798
-     * $this->update_active_messengers_option to persist.
799
-     *
800
-     * @param  string $messenger_name    The name of the messenger adding the settings for
801
-     * @param  string $message_type_name The name of the message type adding the settings for
802
-     * @param  array  $new_settings      Any new settings being set for the message type and messenger
803
-     */
804
-    public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = array())
805
-    {
806
-        // get installed message type from collection
807
-        $message_type      = $this->message_type_collection()->get_by_info($message_type_name);
808
-        $existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name);
809
-        // we need to setup any initial settings for message types
810
-        if ($message_type instanceof EE_message_type) {
811
-            $default_settings = $message_type->get_admin_settings_fields();
812
-            foreach ($default_settings as $field => $values) {
813
-                if (isset($new_settings[ $field ])) {
814
-                    $existing_settings[ $field ] = $new_settings[ $field ];
815
-                    continue;
816
-                }
817
-                if (! isset($existing_settings[ $field ])) {
818
-                    $existing_settings[ $field ] = $values['default'];
819
-                }
820
-            }
821
-        }
822
-        $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
823
-    }
824
-
825
-
826
-    /**
827
-     * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger
828
-     * and message type.
829
-     *
830
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
831
-     *
832
-     * @access protected
833
-     * @param \EE_messenger $messenger
834
-     * @param string        $message_type_name
835
-     */
836
-    protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name)
837
-    {
838
-
839
-        // if _has_activated_messengers_and_message_types is empty then lets ensure its initialized
840
-        if (empty($this->_has_activated_messengers_and_message_types)) {
841
-            $this->get_has_activated_messengers_option();
842
-        }
843
-
844
-        // make sure this messenger has a record in the has_activated array
845
-        if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
846
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
847
-        }
848
-        // check if message type has already been added
849
-        if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
850
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
851
-        }
852
-    }
853
-
854
-
855
-    /**
856
-     * add_settings_for_messenger
857
-     * NOTE This does NOT automatically persist any settings to the db.  Client code should call
858
-     * $this->update_active_messengers_option to persist.
859
-     *
860
-     * @param string $messenger_name The name of the messenger the settings is being added for.
861
-     * @param array  $new_settings   An array of settings to update the existing settings.
862
-     */
863
-    public function add_settings_for_messenger($messenger_name, $new_settings = array())
864
-    {
865
-        $messenger = $this->get_messenger($messenger_name);
866
-        if ($messenger instanceof EE_messenger) {
867
-            $msgr_settings = $messenger->get_admin_settings_fields();
868
-            if (! empty($msgr_settings)) {
869
-                foreach ($msgr_settings as $field => $value) {
870
-                    // is there a new setting for this?
871
-                    if (isset($new_settings[ $field ])) {
872
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
873
-                        continue;
874
-                    }
875
-                    // only set the default if it isn't already set.
876
-                    if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
877
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
878
-                    }
879
-                }
880
-            }
881
-        }
882
-    }
883
-
884
-
885
-    /**
886
-     * deactivate_messenger
887
-     *
888
-     * @param  string|EE_messenger $messenger_name name of messenger
889
-     * @return void
890
-     */
891
-    public function deactivate_messenger($messenger_name)
892
-    {
893
-        $this->_initialize_collections();
894
-        if ($messenger_name instanceof EE_messenger) {
895
-            $messenger_name = $messenger_name->name;
896
-        }
897
-        unset($this->_active_messengers[ $messenger_name ]);
898
-        unset($this->_active_message_types[ $messenger_name ]);
899
-        $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
900
-        $this->update_active_messengers_option();
901
-    }
902
-
903
-
904
-    /**
905
-     * Deactivates a message type (note this will deactivate across all messenger's it is active on.
906
-     *
907
-     * @param  string $message_type_name     name of message type being deactivated
908
-     * @param bool    $set_has_active_record By default we always record the has_active record when deactivating a message
909
-     *                                       type.  However, this can be overridden if we don't want this set (usually when
910
-     *                                       this is called as a part of deregistration of a custom message type)
911
-     */
912
-    public function deactivate_message_type($message_type_name, $set_has_active_record = true)
913
-    {
914
-        $this->_initialize_collections();
915
-        if ($message_type_name instanceof EE_message_type) {
916
-            $message_type_name = $message_type_name->name;
917
-        }
918
-        foreach ($this->_active_message_types as $messenger_name => $settings) {
919
-            unset(
920
-                $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
921
-            );
922
-
923
-            // we always record (even on deactivation) that a message type has been activated because there should at
924
-            // least be a record in the "has_activated" option that it WAS active at one point.
925
-            if ($set_has_active_record) {
926
-                $messenger = $this->get_messenger($messenger_name);
927
-                $this->_set_messenger_has_activated_message_type($messenger, $message_type_name);
928
-            }
929
-        }
930
-        $this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name);
931
-        $this->update_active_messengers_option();
932
-        $this->update_has_activated_messengers_option();
933
-    }
934
-
935
-
936
-    /**
937
-     * Deactivates a message type for a specific messenger as opposed to all messengers.
938
-     *
939
-     * @param string $message_type_name Name of message type being deactivated.
940
-     * @param string $messenger_name    Name of messenger the message type is being deactivated for.
941
-     */
942
-    public function deactivate_message_type_for_messenger($message_type_name, $messenger_name)
943
-    {
944
-        $this->_initialize_collections();
945
-        if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
946
-            unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
947
-        }
948
-        $this->_message_template_group_model->deactivate_message_template_groups_for(
949
-            array($messenger_name),
950
-            array($message_type_name)
951
-        );
952
-        $this->update_active_messengers_option();
953
-    }
954
-
955
-
956
-    /**
957
-     * Used to verify if a message can be sent for the given messenger and message type
958
-     * and that it is a generating messenger (used for generating message templates).
959
-     *
960
-     * @param EE_messenger    $messenger    messenger used in trigger
961
-     * @param EE_message_type $message_type message type used in trigger
962
-     * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
963
-     */
964
-    public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type)
965
-    {
966
-        // get the $messengers the message type says it can be used with.
967
-        foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) {
968
-            if ($messenger->name === $generating_messenger
969
-                && $this->is_message_type_active_for_messenger($messenger->name, $message_type->name)
970
-            ) {
971
-                return true;
972
-            }
973
-        }
974
-        return false;
975
-    }
976
-
977
-
978
-    /**
979
-     * This returns all the contexts that are registered by all message types.
980
-     * If $slugs_only is true,
981
-     * then just an array indexed by unique context slugs with the latest label representation for that slug.
982
-     * array(
983
-     *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
984
-     * );
985
-     * If $slugs_only is false, then the format is:
986
-     * array(
987
-     *      'message_type_name' => array(
988
-     *          'context_slug' => array(
989
-     *              'label' => 'localized label for context',
990
-     *              'description' => 'localized description for context'
991
-     *          )
992
-     *      )
993
-     * );
994
-     * Keep in mind that although different message types may share the same context slugs,
995
-     * it is possible that the context is described differently by the message type.
996
-     *
997
-     * @since 4.9.0
998
-     * @param   bool $slugs_only Whether to return an array of just slugs and labels (true)
999
-     *                           or all contexts indexed by message type.
1000
-     * @return array
1001
-     */
1002
-    public function get_all_contexts($slugs_only = true)
1003
-    {
1004
-        $key = $slugs_only ? 'slugs' : 'all';
1005
-        // check if contexts has been setup yet.
1006
-        if (empty($this->_contexts[ $key ])) {
1007
-            // So let's get all active message type objects and loop through to get all unique contexts
1008
-            foreach ($this->get_active_message_type_objects() as $message_type) {
1009
-                if ($message_type instanceof EE_message_type) {
1010
-                    $message_type_contexts = $message_type->get_contexts();
1011
-                    if ($slugs_only) {
1012
-                        foreach ($message_type_contexts as $context => $context_details) {
1013
-                            $this->_contexts[ $key ][ $context ] = $context_details['label'];
1014
-                        }
1015
-                    } else {
1016
-                        $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1017
-                    }
1018
-                }
1019
-            }
1020
-        }
1021
-        return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * This checks the internal record of what message types are considered "active" and verifies that
1027
-     * there is an installed class definition for that message type.  If the active message type does not have a
1028
-     * corresponding accessible message type class then it will be deactivated from all messengers it is active on and
1029
-     * any related message templates will be inactivated as well.
1030
-     *
1031
-     * @return bool   true means all active message types are valid, false means at least one message type was
1032
-     *                deactivated.
1033
-     */
1034
-    public function validate_active_message_types_are_installed()
1035
-    {
1036
-        $list_of_active_message_type_names = $this->list_of_active_message_types();
1037
-        $installed_message_types           = $this->installed_message_types();
1038
-        $all_message_types_valid           = true;
1039
-        // loop through list of active message types and verify they are installed.
1040
-        foreach ($list_of_active_message_type_names as $message_type_name) {
1041
-            if (! isset($installed_message_types[ $message_type_name ])) {
1042
-                $this->remove_message_type_has_been_activated_from_all_messengers(
1043
-                    $message_type_name,
1044
-                    true
1045
-                );
1046
-                $this->deactivate_message_type($message_type_name, false);
1047
-                $all_message_types_valid = false;
1048
-            }
1049
-        }
1050
-        return $all_message_types_valid;
1051
-    }
1052
-
1053
-
1054
-    /**
1055
-     * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been
1056
-     * activated for the given messenger.  This can be called by client code on plugin updates etc to determine whether
1057
-     * to attempt automatically reactivating message types that should be activated by default or not.
1058
-     *
1059
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1060
-     *
1061
-     * @param $message_type_name
1062
-     * @param $messenger_name
1063
-     * @return bool
1064
-     */
1065
-    public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1066
-    {
1067
-        $has_activated = $this->get_has_activated_messengers_option();
1068
-        return isset($has_activated[ $messenger_name ])
1069
-               && in_array($message_type_name, $has_activated[ $messenger_name ]);
1070
-    }
1071
-
1072
-
1073
-    /**
1074
-     * This method unsets a message type from the given messenger has activated option.
1075
-     *
1076
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1077
-     *
1078
-     * @param string $message_type_name
1079
-     * @param string $messenger_name
1080
-     * @param bool   $consider_current_state  Whether to consider whether the  message type is currently active or not.
1081
-     *                                        If it is currently active, then remove.  Otherwise leave it alone.
1082
-     */
1083
-    public function remove_message_type_has_been_activated_for_messenger(
1084
-        $message_type_name,
1085
-        $messenger_name,
1086
-        $consider_current_state = false
1087
-    ) {
1088
-        if ($consider_current_state
1089
-            && ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
1090
-        ) {
1091
-            // when consider current state is true, this means we don't want to change anything on the "has_activated"
1092
-            // record if the message type is currently active for this messenger.  This is used when we want to retain
1093
-            // the record for user initiated inactivations of the message type.
1094
-            return;
1095
-        }
1096
-        $has_activated = $this->get_has_activated_messengers_option();
1097
-        $key_for_message_type = isset($has_activated[ $messenger_name ])
1098
-            ? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1099
-            : false;
1100
-        if ($key_for_message_type !== false) {
1101
-            unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1102
-            $this->update_has_activated_messengers_option($has_activated);
1103
-            // reset the internal cached property
1104
-            $this->get_has_activated_messengers_option(true);
1105
-        }
1106
-    }
1107
-
1108
-
1109
-    /**
1110
-     * Removes a message type active record from all messengers it is attached to.
1111
-     *
1112
-     * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1113
-     *
1114
-     * @param      $message_type_name
1115
-     * @param bool $consider_current_state  Whether to consider whether the  message type is currently active or not.
1116
-     *                                      If it is currently active, then remove.  Otherwise leave it alone.
1117
-     */
1118
-    public function remove_message_type_has_been_activated_from_all_messengers(
1119
-        $message_type_name,
1120
-        $consider_current_state = false
1121
-    ) {
1122
-        foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) {
1123
-            $this->remove_message_type_has_been_activated_for_messenger(
1124
-                $message_type_name,
1125
-                $messenger_name,
1126
-                $consider_current_state
1127
-            );
1128
-        }
1129
-    }
15
+	/**
16
+	 * This option in the database is used to keep a record of message types that have been activated for a messenger
17
+	 * at some point in the history of the site.  It is utilized by the implementation of the 'force' flag in
18
+	 * EE_Register_Message_Type.  The force flag is an indication of whether a message type should be activated by
19
+	 * default when the message type is registered.  However, if a user has explicitly deactivated a message type, then
20
+	 * the force flag is ignored.  The method by which the code knows whether to ignore this flag is via this option.
21
+	 * Note, that this is NOT a historical record.  Its entirely possible for a message type to have been activated for
22
+	 * a messenger and yet not have a record in this option.  This occurs when a message type is inactivated through an
23
+	 * automated process (when an add-on registering the message type deactivates, or when some other code calls the
24
+	 * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to ensure
25
+	 * the "force" flag is respected if that message type is later re-registered.
26
+	 *
27
+	 * This option should NOT be used to determine the current "active" state of a message type for a given messenger.
28
+	 *
29
+	 * The name of this option (and related methods/properties) is due to matching the original intended purpose for the
30
+	 * option that got superseded by later behaviour requirements.
31
+	 */
32
+	const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger';
33
+
34
+	/**
35
+	 * @type boolean $_initialized
36
+	 */
37
+	protected $_initialized = false;
38
+
39
+	/**
40
+	 * @type EE_Messenger_Collection $_messenger_collection_loader
41
+	 */
42
+	protected $_messenger_collection_loader;
43
+
44
+	/**
45
+	 * @type EE_Message_Type_Collection $_message_type_collection_loader
46
+	 */
47
+	protected $_message_type_collection_loader;
48
+
49
+	/**
50
+	 * @type EEM_Message_Template_Group $_message_template_group_model
51
+	 */
52
+	protected $_message_template_group_model;
53
+
54
+	/**
55
+	 * @type EE_messenger[]
56
+	 */
57
+	protected $_installed_messengers = array();
58
+
59
+	/**
60
+	 * @type EE_message_type[]
61
+	 */
62
+	protected $_installed_message_types = array();
63
+
64
+	/**
65
+	 * Array of active messengers.
66
+	 * Format is this:
67
+	 * array(
68
+	 *      'messenger_name' => EE_messenger
69
+	 * )
70
+	 *
71
+	 * @type EE_messenger[]
72
+	 */
73
+	protected $_active_messengers = array();
74
+
75
+	/**
76
+	 * Formatted array of active message types grouped per messenger.
77
+	 * Format is this:
78
+	 * array(
79
+	 *      'messenger_name' => array(
80
+	 *          'settings' => array(
81
+	 *              '{messenger_name}-message_types' => array(
82
+	 *                  'message_type_name' => array() //variable array of settings corresponding to message type.
83
+	 *              )
84
+	 *          )
85
+	 *      )
86
+	 * )
87
+	 *
88
+	 * @type array
89
+	 */
90
+	protected $_active_message_types = array();
91
+
92
+
93
+	/**
94
+	 * This holds the array of messengers and their corresponding message types that have
95
+	 * been activated on a site at some point.  This is an important record that helps the messages system
96
+	 * not accidentally reactivate something that was intentionally deactivated by a user.
97
+	 *
98
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
99
+	 *
100
+	 * @type array
101
+	 */
102
+	protected $_has_activated_messengers_and_message_types = array();
103
+
104
+	/**
105
+	 * An array of unique message type contexts across all active message types.
106
+	 * The array will be indexed by either 'slugs' or 'all'.
107
+	 * The slugs index contains an array indexed by unique context slugs with the latest label representation for that
108
+	 * slug. array(
109
+	 *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
110
+	 * );
111
+	 * The all index returns an array in this format:
112
+	 * array(
113
+	 *      'message_type_name' => array(
114
+	 *          'context_slug' => array(
115
+	 *              'label' => 'localized label for context',
116
+	 *              'description' => 'localized description for context'
117
+	 *          )
118
+	 *      )
119
+	 * );
120
+	 *
121
+	 * @type array
122
+	 */
123
+	protected $_contexts = array();
124
+
125
+
126
+	/**
127
+	 * EE_Message_Resource_Manager constructor.
128
+	 *
129
+	 * @param \EE_Messenger_Collection_Loader    $Messenger_Collection_Loader
130
+	 * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader
131
+	 * @param \EEM_Message_Template_Group        $Message_Template_Group_Model
132
+	 */
133
+	public function __construct(
134
+		EE_Messenger_Collection_Loader $Messenger_Collection_Loader,
135
+		EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader,
136
+		EEM_Message_Template_Group $Message_Template_Group_Model
137
+	) {
138
+		$this->_messenger_collection_loader    = $Messenger_Collection_Loader;
139
+		$this->_message_type_collection_loader = $Message_Type_Collection_Loader;
140
+		$this->_message_template_group_model   = $Message_Template_Group_Model;
141
+	}
142
+
143
+
144
+	/**
145
+	 * @return void
146
+	 */
147
+	protected function _initialize_collections()
148
+	{
149
+		if ($this->_initialized) {
150
+			return;
151
+		}
152
+		$this->_initialized = true;
153
+		$this->_messenger_collection_loader->load_messengers_from_folder();
154
+		$this->_message_type_collection_loader->load_message_types_from_folder();
155
+		$this->get_has_activated_messengers_option(true);
156
+		$this->_set_active_messengers_and_message_types();
157
+	}
158
+
159
+
160
+	/**
161
+	 * @return EE_Messenger_Collection
162
+	 */
163
+	public function messenger_collection()
164
+	{
165
+		$this->_initialize_collections();
166
+		return $this->_messenger_collection_loader->messenger_collection();
167
+	}
168
+
169
+
170
+	/**
171
+	 * @return EE_messenger[]
172
+	 */
173
+	public function active_messengers()
174
+	{
175
+		$this->_initialize_collections();
176
+		return $this->_active_messengers;
177
+	}
178
+
179
+
180
+	/**
181
+	 * @param string $messenger_name
182
+	 * @return \EE_messenger
183
+	 */
184
+	public function get_messenger($messenger_name)
185
+	{
186
+		return $this->messenger_collection()->get_by_info($messenger_name);
187
+	}
188
+
189
+
190
+	/**
191
+	 * This returns the corresponding EE_messenger object for the given string if it is active.
192
+	 *
193
+	 * @param string $messenger
194
+	 * @return EE_messenger | null
195
+	 */
196
+	public function get_active_messenger($messenger)
197
+	{
198
+		$this->_initialize_collections();
199
+		return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
200
+	}
201
+
202
+
203
+	/**
204
+	 * @return \EE_messenger[]
205
+	 */
206
+	public function installed_messengers()
207
+	{
208
+		if (empty($this->_installed_messengers)) {
209
+			$this->_installed_messengers = array();
210
+			$this->messenger_collection()->rewind();
211
+			while ($this->messenger_collection()->valid()) {
212
+				$this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
213
+				$this->messenger_collection()->next();
214
+			}
215
+		}
216
+		return $this->_installed_messengers;
217
+	}
218
+
219
+
220
+	/**
221
+	 * @param string $messenger_name
222
+	 * @return \EE_messenger
223
+	 * @throws EE_Error
224
+	 */
225
+	public function valid_messenger($messenger_name)
226
+	{
227
+		$messenger = $this->get_messenger($messenger_name);
228
+		if ($messenger instanceof EE_messenger) {
229
+			return $messenger;
230
+		}
231
+		throw new EE_Error(
232
+			sprintf(
233
+				__('The "%1$s" messenger is either invalid or not installed', 'event_espresso'),
234
+				$messenger_name
235
+			)
236
+		);
237
+	}
238
+
239
+
240
+	/**
241
+	 * @return EE_Message_Type_Collection
242
+	 */
243
+	public function message_type_collection()
244
+	{
245
+		$this->_initialize_collections();
246
+		return $this->_message_type_collection_loader->message_type_collection();
247
+	}
248
+
249
+
250
+	/**
251
+	 * @return array
252
+	 */
253
+	public function active_message_types()
254
+	{
255
+		$this->_initialize_collections();
256
+		return $this->_active_message_types;
257
+	}
258
+
259
+
260
+	/**
261
+	 * @param string $message_type_name
262
+	 * @return \EE_message_type
263
+	 */
264
+	public function get_message_type($message_type_name)
265
+	{
266
+		return $this->message_type_collection()->get_by_info($message_type_name);
267
+	}
268
+
269
+
270
+	/**
271
+	 * This returns the EE_message_type from the active message types array ( if present );
272
+	 *
273
+	 * @param string $messenger_name
274
+	 * @param string $message_type_name
275
+	 * @return \EE_message_type|null
276
+	 */
277
+	public function get_active_message_type_for_messenger($messenger_name, $message_type_name)
278
+	{
279
+		return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
280
+			? $this->get_message_type($message_type_name)
281
+			: null;
282
+	}
283
+
284
+
285
+	/**
286
+	 * Returns whether the given message type is active for the given messenger.
287
+	 *
288
+	 * @param string $messenger_name
289
+	 * @param string $message_type_name
290
+	 * @return bool
291
+	 */
292
+	public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293
+	{
294
+		$this->_initialize_collections();
295
+		return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
296
+	}
297
+
298
+
299
+	/**
300
+	 * Returns whether the given messenger is active.
301
+	 *
302
+	 * @param string $messenger_name the name of the messenger to check if active.
303
+	 * @return bool
304
+	 */
305
+	public function is_messenger_active($messenger_name)
306
+	{
307
+		$this->_initialize_collections();
308
+		return ! empty($this->_active_message_types[ $messenger_name ]);
309
+	}
310
+
311
+
312
+	/**
313
+	 * This returns any settings that might be on a message type for a messenger
314
+	 *
315
+	 * @param string $messenger_name    The slug of the messenger
316
+	 * @param string $message_type_name The slug of the message type getting the settings for.
317
+	 * @return array
318
+	 */
319
+	public function get_message_type_settings_for_messenger($messenger_name, $message_type_name)
320
+	{
321
+		$settings = array();
322
+		if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
+			$settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
+				? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
325
+				: array();
326
+		}
327
+		return $settings;
328
+	}
329
+
330
+
331
+	/**
332
+	 * Returns whether the given messenger name has active message types on it.
333
+	 * Infers whether the messenger is active or not as well.
334
+	 *
335
+	 * @param string $messenger_name
336
+	 * @return bool
337
+	 */
338
+	public function messenger_has_active_message_types($messenger_name)
339
+	{
340
+		$this->_initialize_collections();
341
+		return
342
+			! empty($this->_active_message_types[ $messenger_name ])
343
+			&& ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
344
+	}
345
+
346
+
347
+	/**
348
+	 * This checks the _active_message_types property for any active message types
349
+	 * that are present for the given messenger and returns them.
350
+	 *
351
+	 * @since 4.9.0
352
+	 * @param string $messenger_name The messenger being checked
353
+	 * @return EE_message_type[]|array    (empty array if no active_message_types)
354
+	 */
355
+	public function get_active_message_types_for_messenger($messenger_name)
356
+	{
357
+		$message_types = array();
358
+		if (! $this->messenger_has_active_message_types($messenger_name)) {
359
+			return $message_types;
360
+		}
361
+		$installed_message_types = $this->installed_message_types();
362
+		foreach ($installed_message_types as $message_type_name => $message_type) {
363
+			if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
+				$message_types[ $message_type_name ] = $message_type;
365
+			}
366
+		}
367
+		return $message_types;
368
+	}
369
+
370
+
371
+	/**
372
+	 * This does NOT return the _active_message_types property but
373
+	 * simply returns an array of active message type names from that property.
374
+	 * (The _active_message_types property is indexed by messenger and active message_types per messenger).
375
+	 *
376
+	 * @return array message_type references (string)
377
+	 */
378
+	public function list_of_active_message_types()
379
+	{
380
+		$active_message_type_names = array();
381
+		$this->_initialize_collections();
382
+		foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
+			if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
384
+				continue;
385
+			}
386
+			foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
+				if (! in_array($message_type_name, $active_message_type_names)) {
388
+					$active_message_type_names[] = $message_type_name;
389
+				}
390
+			}
391
+		}
392
+		return $active_message_type_names;
393
+	}
394
+
395
+
396
+	/**
397
+	 * Same as list_of_active_message_types() except this returns actual EE_message_type objects
398
+	 *
399
+	 * @since 4.9.0
400
+	 * @return \EE_message_type[]
401
+	 */
402
+	public function get_active_message_type_objects()
403
+	{
404
+		$active_message_types      = array();
405
+		$installed_message_types   = $this->installed_message_types();
406
+		$active_message_type_names = $this->list_of_active_message_types();
407
+		foreach ($active_message_type_names as $active_message_type_name) {
408
+			if (isset($installed_message_types[ $active_message_type_name ])) {
409
+				$active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
410
+			}
411
+		}
412
+		return $active_message_types;
413
+	}
414
+
415
+
416
+	/**
417
+	 * @return \EE_message_type[]
418
+	 */
419
+	public function installed_message_types()
420
+	{
421
+		if (empty($this->_installed_message_types)) {
422
+			$this->message_type_collection()->rewind();
423
+			while ($this->message_type_collection()->valid()) {
424
+				$this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
425
+				$this->message_type_collection()->next();
426
+			}
427
+		}
428
+		return $this->_installed_message_types;
429
+	}
430
+
431
+
432
+	/**
433
+	 * @param string $message_type_name
434
+	 * @return \EE_message_type
435
+	 * @throws EE_Error
436
+	 */
437
+	public function valid_message_type($message_type_name)
438
+	{
439
+		$message_type = $this->get_message_type($message_type_name);
440
+		if ($message_type instanceof EE_message_type) {
441
+			return $message_type;
442
+		}
443
+		throw new EE_Error(
444
+			sprintf(
445
+				__('The "%1$s" message type is either invalid or not installed', 'event_espresso'),
446
+				$message_type_name
447
+			)
448
+		);
449
+	}
450
+
451
+
452
+	/**
453
+	 * valid_message_type_for_messenger
454
+	 *
455
+	 * @param EE_messenger $messenger
456
+	 * @param string       $message_type_name
457
+	 * @return boolean
458
+	 * @throws EE_Error
459
+	 */
460
+	public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461
+	{
462
+		$valid_message_types = $messenger->get_valid_message_types();
463
+		if (! in_array($message_type_name, $valid_message_types)) {
464
+			throw new EE_Error(
465
+				sprintf(
466
+					__(
467
+						'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger.  Double-check the spelling and verify that message type has been registered as a valid type with the messenger.',
468
+						'event_espresso'
469
+					),
470
+					$message_type_name,
471
+					__METHOD__,
472
+					$messenger->name
473
+				)
474
+			);
475
+		}
476
+		return true;
477
+	}
478
+
479
+
480
+	/**
481
+	 * Used to return active messengers array stored in the wp options table.
482
+	 * If no value is present in the option then an empty array is returned.
483
+	 *
484
+	 * @param   bool $reset     If true then we ignore whether the option is cached on the _active_message_types
485
+	 *                          property and pull directly from the db.  Otherwise whatever is currently on the
486
+	 *                          $_active_message_types property is pulled.
487
+	 * @return array
488
+	 */
489
+	public function get_active_messengers_option($reset = false)
490
+	{
491
+		if ($reset) {
492
+			$this->_active_message_types = get_option('ee_active_messengers', array());
493
+		}
494
+		return $this->_active_message_types;
495
+	}
496
+
497
+
498
+	/**
499
+	 * Used to update the active messengers array stored in the wp options table.
500
+	 *
501
+	 * @param array $active_messenger_settings Incoming data to save.  If empty, then the internal cached property
502
+	 *                                         representing this data is used.
503
+	 * @return bool FALSE if not updated, TRUE if updated.
504
+	 */
505
+	public function update_active_messengers_option($active_messenger_settings = array())
506
+	{
507
+		$active_messenger_settings = empty($active_messenger_settings) ? $this->_active_message_types : $active_messenger_settings;
508
+		// make sure _active_message_types is updated (this is the internal cache for the settings).
509
+		$this->_active_message_types = $active_messenger_settings;
510
+		return update_option('ee_active_messengers', $active_messenger_settings);
511
+	}
512
+
513
+
514
+	/**
515
+	 * Used to return has activated message types for messengers array stored in the wp options table.
516
+	 * If no value is present in the option then an empty array is returned.
517
+	 * The value is cached on the $_has_activated_messengers_and_message_types property for future calls.
518
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
519
+	 *
520
+	 * @param   bool $reset Used to indicate that any cached value should be ignored.
521
+	 * @return array
522
+	 */
523
+	public function get_has_activated_messengers_option($reset = false)
524
+	{
525
+		if ($reset || empty($this->_has_activated_messengers_and_message_types)) {
526
+			$this->_has_activated_messengers_and_message_types = get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, array());
527
+		}
528
+		return $this->_has_activated_messengers_and_message_types;
529
+	}
530
+
531
+
532
+	/**
533
+	 * Used to update the has activated option in the db.
534
+	 *
535
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
536
+	 *
537
+	 * @param array $has_activated_messengers Incoming data to save.  If empty, then the internal cached property
538
+	 *                                        representing this data is used.
539
+	 * @return bool FALSE if not updated, TRUE if updated.
540
+	 */
541
+	public function update_has_activated_messengers_option($has_activated_messengers = array())
542
+	{
543
+		// make sure the option has been retrieved from first so we don't overwrite it accidentally.
544
+		if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) {
545
+			$this->get_has_activated_messengers_option();
546
+		}
547
+		$has_activated_messengers = empty($has_activated_messengers)
548
+			? $this->_has_activated_messengers_and_message_types
549
+			: $has_activated_messengers;
550
+		return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers);
551
+	}
552
+
553
+
554
+	/**
555
+	 * wrapper for _set_active_messengers_and_message_types()
556
+	 */
557
+	public function reset_active_messengers_and_message_types()
558
+	{
559
+		$this->_set_active_messengers_and_message_types();
560
+	}
561
+
562
+
563
+	/**
564
+	 * Generate list of active messengers and message types from collection.
565
+	 * This sets up the active messengers from what is present in the database.
566
+	 */
567
+	protected function _set_active_messengers_and_message_types()
568
+	{
569
+		// echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n";
570
+		// list of activated messengers as set via the admin
571
+		// note calling `get_active_messengers_options` also initializes the _active_message_types property.
572
+		$this->get_active_messengers_option(true);
573
+		$this->ensure_messengers_are_active(array(), false, true);
574
+		$this->update_active_messengers_option();
575
+		$this->update_has_activated_messengers_option();
576
+	}
577
+
578
+
579
+	/**
580
+	 * Ensures that the specified messenger is currently active.
581
+	 * If not, activates it and its default message types.
582
+	 *
583
+	 * @param string $messenger_name
584
+	 * @param bool   $update_option Whether to update the option in the db or not.
585
+	 * @return boolean true if either already active or successfully activated.
586
+	 */
587
+	public function ensure_messenger_is_active($messenger_name, $update_option = true)
588
+	{
589
+		if (! isset($this->_active_messengers[ $messenger_name ])) {
590
+			try {
591
+				$this->activate_messenger($messenger_name, array(), $update_option);
592
+			} catch (EE_Error $e) {
593
+				EE_Error::add_error(
594
+					$e->getMessage(),
595
+					__FILE__,
596
+					__FUNCTION__,
597
+					__LINE__
598
+				);
599
+				return false;
600
+			}
601
+		}
602
+		return true;
603
+	}
604
+
605
+
606
+	/**
607
+	 * This ensures the given array of messenger names is active in the system.
608
+	 * Note, this method will not activate any NEW message types for the messenger when it is called. Instead,
609
+	 * it will automatically activate the default message types for the messenger if its not active.
610
+	 *
611
+	 * @param array $messenger_names  Array of messenger names for messengers to be activated.  If an empty array
612
+	 *                                (default) then will attempt to set the active messengers from the
613
+	 *                                activated_messengers option
614
+	 *                                (stored in $_active_message_types property).
615
+	 * @param bool  $update_option    Whether to update the related active messengers option.
616
+	 * @param bool  $verify           Whether to verify the messengers are installed before activating. Note if this is
617
+	 *                                set to true and a messenger is indicated as active, but is NOT installed, then it
618
+	 *                                will automatically be deactivated.
619
+	 */
620
+	public function ensure_messengers_are_active($messenger_names = array(), $update_option = true, $verify = false)
621
+	{
622
+		$messenger_names = empty($messenger_names) ? array_keys($this->_active_message_types) : $messenger_names;
623
+
624
+		$not_installed = array();
625
+		foreach ($messenger_names as $messenger_name) {
626
+			if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) {
627
+				$not_installed[] = $messenger_name;
628
+				$this->deactivate_messenger($messenger_name);
629
+				continue;
630
+			}
631
+			$this->ensure_messenger_is_active($messenger_name, $update_option);
632
+		}
633
+
634
+		if (! empty($not_installed)) {
635
+			EE_Error::add_error(
636
+				sprintf(
637
+					__('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
638
+					'<br />',
639
+					implode(', ', $not_installed)
640
+				),
641
+				__FILE__,
642
+				__FUNCTION__,
643
+				__LINE__
644
+			);
645
+		}
646
+	}
647
+
648
+
649
+	/**
650
+	 * Ensures that the specified message type for the given messenger is currently active, if not activates it.
651
+	 * This ALSO ensures that the given messenger is active as well!
652
+	 *
653
+	 * @param string $message_type_name message type name.
654
+	 * @param        $messenger_name
655
+	 * @param bool   $update_option     Whether to update the option in the db or not.
656
+	 * @return bool  Returns true if already is active or if was activated successfully.
657
+	 * @throws EE_Error
658
+	 */
659
+	public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true)
660
+	{
661
+		// grab the messenger to work with.
662
+		$messenger = $this->valid_messenger($messenger_name);
663
+		if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) {
664
+			// ensure messenger is active (that's an inherent coupling between active message types and the
665
+			// messenger they are being activated for.
666
+			try {
667
+				if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668
+					// all is good so let's just get it active
669
+					$this->activate_messenger($messenger, array($message_type_name), $update_option);
670
+				}
671
+			} catch (EE_Error $e) {
672
+				EE_Error::add_error(
673
+					$e->getMessage(),
674
+					__FILE__,
675
+					__FUNCTION__,
676
+					__LINE__
677
+				);
678
+				return false;
679
+			}
680
+		}
681
+		return true;
682
+	}
683
+
684
+
685
+	/**
686
+	 * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a
687
+	 * messenger are active in one go.
688
+	 *
689
+	 * @param array  $message_type_names Array of message type names to ensure are active.
690
+	 * @param string $messenger_name     The name of the messenger that the message types are to be activated on.
691
+	 * @param bool   $update_option      Whether to persist the activation to the database or not (default true).
692
+	 */
693
+	public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true)
694
+	{
695
+		$message_type_names = (array) $message_type_names;
696
+		foreach ($message_type_names as $message_type_name) {
697
+			// note, intentionally not updating option here because we're in a loop.
698
+			// We'll follow the instructions of the incoming $update_option argument after the loop.
699
+			$this->ensure_message_type_is_active($message_type_name, $messenger_name, false);
700
+		}
701
+		if ($update_option) {
702
+			$this->update_active_messengers_option();
703
+			$this->update_has_activated_messengers_option();
704
+		}
705
+	}
706
+
707
+
708
+	/**
709
+	 * Activates the specified messenger.
710
+	 *
711
+	 * @param EE_messenger|string $messenger    Instantiated EE_messenger OR messenger name if not already loaded!
712
+	 * @param array  $message_type_names        An array of message type names to activate with this messenger.
713
+	 *                                          If included we do NOT setup the default message types
714
+	 *                                          (assuming they are already setup.)
715
+	 * @param bool   $update_active_messengers_option
716
+	 * @return array of generated templates
717
+	 * @throws EE_Error
718
+	 */
719
+	public function activate_messenger(
720
+		$messenger,
721
+		$message_type_names = array(),
722
+		$update_active_messengers_option = true
723
+	) {
724
+		$templates = array();
725
+		// grab the messenger to work with.
726
+		$messenger = $messenger instanceof EE_messenger
727
+			? $messenger
728
+			: $this->messenger_collection()->get_by_info($messenger);
729
+		// it's inactive. Activate it.
730
+		if ($messenger instanceof EE_messenger) {
731
+			$this->_active_messengers[ $messenger->name ] = $messenger;
732
+			// activate incoming message types set to be activated with messenger.
733
+			$message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734
+			// setup any initial settings for the messenger if necessary.
735
+			$this->add_settings_for_messenger($messenger->name);
736
+			if ($update_active_messengers_option) {
737
+				$this->update_active_messengers_option();
738
+				$this->update_has_activated_messengers_option();
739
+			}
740
+			// generate new templates if necessary and ensure all related templates that are already in the database are
741
+			// marked active.  Note, this will also deactivate a message type for a messenger if the template
742
+			// cannot be successfully created during its attempt (only happens for global template attempts).
743
+			if (! empty($message_type_names)) {
744
+				$templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745
+				EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746
+			}
747
+		}
748
+		return $templates;
749
+	}
750
+
751
+
752
+	/**
753
+	 * Activates given message types for the given EE_messenger object.
754
+	 * Note: (very important) This method does not persist the activation to the database.
755
+	 * See code implementing this method in this class for examples of how to persist.
756
+	 *
757
+	 * @param \EE_messenger $messenger
758
+	 * @param  array        $message_type_names
759
+	 * @return array
760
+	 */
761
+	protected function _activate_message_types(EE_messenger $messenger, $message_type_names = array())
762
+	{
763
+		// If $message_type_names is empty, AND $this->_active_message_types is empty, then that means
764
+		// things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765
+		// So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766
+		// only override _active_message_types when an explicit array of $message_type_names has been provided.
767
+		$message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
768
+			? $messenger->get_default_message_types()
769
+			: (array) $message_type_names;
770
+
771
+		// now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
+		if (! isset($this->_active_message_types[ $messenger->name ])) {
773
+			$this->_active_message_types[ $messenger->name ]['settings'] = array();
774
+		}
775
+
776
+		if ($message_type_names) {
777
+			// cycle thru message types
778
+			foreach ($message_type_names as $message_type_name) {
779
+				// only register the message type as active IF it isn't already active
780
+				// and if its actually installed.
781
+				if (! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
782
+				) {
783
+					$this->add_settings_for_message_type($messenger->name, $message_type_name);
784
+					$this->_set_messenger_has_activated_message_type(
785
+						$messenger,
786
+						$message_type_name
787
+					);
788
+				}
789
+			}
790
+		}
791
+		return $message_type_names;
792
+	}
793
+
794
+
795
+	/**
796
+	 * add_settings_for_message_type
797
+	 * NOTE This does NOT automatically persist any settings to the db.  Client code should call
798
+	 * $this->update_active_messengers_option to persist.
799
+	 *
800
+	 * @param  string $messenger_name    The name of the messenger adding the settings for
801
+	 * @param  string $message_type_name The name of the message type adding the settings for
802
+	 * @param  array  $new_settings      Any new settings being set for the message type and messenger
803
+	 */
804
+	public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = array())
805
+	{
806
+		// get installed message type from collection
807
+		$message_type      = $this->message_type_collection()->get_by_info($message_type_name);
808
+		$existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name);
809
+		// we need to setup any initial settings for message types
810
+		if ($message_type instanceof EE_message_type) {
811
+			$default_settings = $message_type->get_admin_settings_fields();
812
+			foreach ($default_settings as $field => $values) {
813
+				if (isset($new_settings[ $field ])) {
814
+					$existing_settings[ $field ] = $new_settings[ $field ];
815
+					continue;
816
+				}
817
+				if (! isset($existing_settings[ $field ])) {
818
+					$existing_settings[ $field ] = $values['default'];
819
+				}
820
+			}
821
+		}
822
+		$this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
823
+	}
824
+
825
+
826
+	/**
827
+	 * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger
828
+	 * and message type.
829
+	 *
830
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
831
+	 *
832
+	 * @access protected
833
+	 * @param \EE_messenger $messenger
834
+	 * @param string        $message_type_name
835
+	 */
836
+	protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name)
837
+	{
838
+
839
+		// if _has_activated_messengers_and_message_types is empty then lets ensure its initialized
840
+		if (empty($this->_has_activated_messengers_and_message_types)) {
841
+			$this->get_has_activated_messengers_option();
842
+		}
843
+
844
+		// make sure this messenger has a record in the has_activated array
845
+		if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
846
+			$this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
847
+		}
848
+		// check if message type has already been added
849
+		if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
850
+			$this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
851
+		}
852
+	}
853
+
854
+
855
+	/**
856
+	 * add_settings_for_messenger
857
+	 * NOTE This does NOT automatically persist any settings to the db.  Client code should call
858
+	 * $this->update_active_messengers_option to persist.
859
+	 *
860
+	 * @param string $messenger_name The name of the messenger the settings is being added for.
861
+	 * @param array  $new_settings   An array of settings to update the existing settings.
862
+	 */
863
+	public function add_settings_for_messenger($messenger_name, $new_settings = array())
864
+	{
865
+		$messenger = $this->get_messenger($messenger_name);
866
+		if ($messenger instanceof EE_messenger) {
867
+			$msgr_settings = $messenger->get_admin_settings_fields();
868
+			if (! empty($msgr_settings)) {
869
+				foreach ($msgr_settings as $field => $value) {
870
+					// is there a new setting for this?
871
+					if (isset($new_settings[ $field ])) {
872
+						$this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
873
+						continue;
874
+					}
875
+					// only set the default if it isn't already set.
876
+					if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
877
+						$this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
878
+					}
879
+				}
880
+			}
881
+		}
882
+	}
883
+
884
+
885
+	/**
886
+	 * deactivate_messenger
887
+	 *
888
+	 * @param  string|EE_messenger $messenger_name name of messenger
889
+	 * @return void
890
+	 */
891
+	public function deactivate_messenger($messenger_name)
892
+	{
893
+		$this->_initialize_collections();
894
+		if ($messenger_name instanceof EE_messenger) {
895
+			$messenger_name = $messenger_name->name;
896
+		}
897
+		unset($this->_active_messengers[ $messenger_name ]);
898
+		unset($this->_active_message_types[ $messenger_name ]);
899
+		$this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
900
+		$this->update_active_messengers_option();
901
+	}
902
+
903
+
904
+	/**
905
+	 * Deactivates a message type (note this will deactivate across all messenger's it is active on.
906
+	 *
907
+	 * @param  string $message_type_name     name of message type being deactivated
908
+	 * @param bool    $set_has_active_record By default we always record the has_active record when deactivating a message
909
+	 *                                       type.  However, this can be overridden if we don't want this set (usually when
910
+	 *                                       this is called as a part of deregistration of a custom message type)
911
+	 */
912
+	public function deactivate_message_type($message_type_name, $set_has_active_record = true)
913
+	{
914
+		$this->_initialize_collections();
915
+		if ($message_type_name instanceof EE_message_type) {
916
+			$message_type_name = $message_type_name->name;
917
+		}
918
+		foreach ($this->_active_message_types as $messenger_name => $settings) {
919
+			unset(
920
+				$this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
921
+			);
922
+
923
+			// we always record (even on deactivation) that a message type has been activated because there should at
924
+			// least be a record in the "has_activated" option that it WAS active at one point.
925
+			if ($set_has_active_record) {
926
+				$messenger = $this->get_messenger($messenger_name);
927
+				$this->_set_messenger_has_activated_message_type($messenger, $message_type_name);
928
+			}
929
+		}
930
+		$this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name);
931
+		$this->update_active_messengers_option();
932
+		$this->update_has_activated_messengers_option();
933
+	}
934
+
935
+
936
+	/**
937
+	 * Deactivates a message type for a specific messenger as opposed to all messengers.
938
+	 *
939
+	 * @param string $message_type_name Name of message type being deactivated.
940
+	 * @param string $messenger_name    Name of messenger the message type is being deactivated for.
941
+	 */
942
+	public function deactivate_message_type_for_messenger($message_type_name, $messenger_name)
943
+	{
944
+		$this->_initialize_collections();
945
+		if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
946
+			unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
947
+		}
948
+		$this->_message_template_group_model->deactivate_message_template_groups_for(
949
+			array($messenger_name),
950
+			array($message_type_name)
951
+		);
952
+		$this->update_active_messengers_option();
953
+	}
954
+
955
+
956
+	/**
957
+	 * Used to verify if a message can be sent for the given messenger and message type
958
+	 * and that it is a generating messenger (used for generating message templates).
959
+	 *
960
+	 * @param EE_messenger    $messenger    messenger used in trigger
961
+	 * @param EE_message_type $message_type message type used in trigger
962
+	 * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send.
963
+	 */
964
+	public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type)
965
+	{
966
+		// get the $messengers the message type says it can be used with.
967
+		foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) {
968
+			if ($messenger->name === $generating_messenger
969
+				&& $this->is_message_type_active_for_messenger($messenger->name, $message_type->name)
970
+			) {
971
+				return true;
972
+			}
973
+		}
974
+		return false;
975
+	}
976
+
977
+
978
+	/**
979
+	 * This returns all the contexts that are registered by all message types.
980
+	 * If $slugs_only is true,
981
+	 * then just an array indexed by unique context slugs with the latest label representation for that slug.
982
+	 * array(
983
+	 *      'context_slug' => 'localized label for context obtained from latest message type in the loop'.
984
+	 * );
985
+	 * If $slugs_only is false, then the format is:
986
+	 * array(
987
+	 *      'message_type_name' => array(
988
+	 *          'context_slug' => array(
989
+	 *              'label' => 'localized label for context',
990
+	 *              'description' => 'localized description for context'
991
+	 *          )
992
+	 *      )
993
+	 * );
994
+	 * Keep in mind that although different message types may share the same context slugs,
995
+	 * it is possible that the context is described differently by the message type.
996
+	 *
997
+	 * @since 4.9.0
998
+	 * @param   bool $slugs_only Whether to return an array of just slugs and labels (true)
999
+	 *                           or all contexts indexed by message type.
1000
+	 * @return array
1001
+	 */
1002
+	public function get_all_contexts($slugs_only = true)
1003
+	{
1004
+		$key = $slugs_only ? 'slugs' : 'all';
1005
+		// check if contexts has been setup yet.
1006
+		if (empty($this->_contexts[ $key ])) {
1007
+			// So let's get all active message type objects and loop through to get all unique contexts
1008
+			foreach ($this->get_active_message_type_objects() as $message_type) {
1009
+				if ($message_type instanceof EE_message_type) {
1010
+					$message_type_contexts = $message_type->get_contexts();
1011
+					if ($slugs_only) {
1012
+						foreach ($message_type_contexts as $context => $context_details) {
1013
+							$this->_contexts[ $key ][ $context ] = $context_details['label'];
1014
+						}
1015
+					} else {
1016
+						$this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1017
+					}
1018
+				}
1019
+			}
1020
+		}
1021
+		return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * This checks the internal record of what message types are considered "active" and verifies that
1027
+	 * there is an installed class definition for that message type.  If the active message type does not have a
1028
+	 * corresponding accessible message type class then it will be deactivated from all messengers it is active on and
1029
+	 * any related message templates will be inactivated as well.
1030
+	 *
1031
+	 * @return bool   true means all active message types are valid, false means at least one message type was
1032
+	 *                deactivated.
1033
+	 */
1034
+	public function validate_active_message_types_are_installed()
1035
+	{
1036
+		$list_of_active_message_type_names = $this->list_of_active_message_types();
1037
+		$installed_message_types           = $this->installed_message_types();
1038
+		$all_message_types_valid           = true;
1039
+		// loop through list of active message types and verify they are installed.
1040
+		foreach ($list_of_active_message_type_names as $message_type_name) {
1041
+			if (! isset($installed_message_types[ $message_type_name ])) {
1042
+				$this->remove_message_type_has_been_activated_from_all_messengers(
1043
+					$message_type_name,
1044
+					true
1045
+				);
1046
+				$this->deactivate_message_type($message_type_name, false);
1047
+				$all_message_types_valid = false;
1048
+			}
1049
+		}
1050
+		return $all_message_types_valid;
1051
+	}
1052
+
1053
+
1054
+	/**
1055
+	 * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been
1056
+	 * activated for the given messenger.  This can be called by client code on plugin updates etc to determine whether
1057
+	 * to attempt automatically reactivating message types that should be activated by default or not.
1058
+	 *
1059
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1060
+	 *
1061
+	 * @param $message_type_name
1062
+	 * @param $messenger_name
1063
+	 * @return bool
1064
+	 */
1065
+	public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1066
+	{
1067
+		$has_activated = $this->get_has_activated_messengers_option();
1068
+		return isset($has_activated[ $messenger_name ])
1069
+			   && in_array($message_type_name, $has_activated[ $messenger_name ]);
1070
+	}
1071
+
1072
+
1073
+	/**
1074
+	 * This method unsets a message type from the given messenger has activated option.
1075
+	 *
1076
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1077
+	 *
1078
+	 * @param string $message_type_name
1079
+	 * @param string $messenger_name
1080
+	 * @param bool   $consider_current_state  Whether to consider whether the  message type is currently active or not.
1081
+	 *                                        If it is currently active, then remove.  Otherwise leave it alone.
1082
+	 */
1083
+	public function remove_message_type_has_been_activated_for_messenger(
1084
+		$message_type_name,
1085
+		$messenger_name,
1086
+		$consider_current_state = false
1087
+	) {
1088
+		if ($consider_current_state
1089
+			&& ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)
1090
+		) {
1091
+			// when consider current state is true, this means we don't want to change anything on the "has_activated"
1092
+			// record if the message type is currently active for this messenger.  This is used when we want to retain
1093
+			// the record for user initiated inactivations of the message type.
1094
+			return;
1095
+		}
1096
+		$has_activated = $this->get_has_activated_messengers_option();
1097
+		$key_for_message_type = isset($has_activated[ $messenger_name ])
1098
+			? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1099
+			: false;
1100
+		if ($key_for_message_type !== false) {
1101
+			unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1102
+			$this->update_has_activated_messengers_option($has_activated);
1103
+			// reset the internal cached property
1104
+			$this->get_has_activated_messengers_option(true);
1105
+		}
1106
+	}
1107
+
1108
+
1109
+	/**
1110
+	 * Removes a message type active record from all messengers it is attached to.
1111
+	 *
1112
+	 * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more details.
1113
+	 *
1114
+	 * @param      $message_type_name
1115
+	 * @param bool $consider_current_state  Whether to consider whether the  message type is currently active or not.
1116
+	 *                                      If it is currently active, then remove.  Otherwise leave it alone.
1117
+	 */
1118
+	public function remove_message_type_has_been_activated_from_all_messengers(
1119
+		$message_type_name,
1120
+		$consider_current_state = false
1121
+	) {
1122
+		foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) {
1123
+			$this->remove_message_type_has_been_activated_for_messenger(
1124
+				$message_type_name,
1125
+				$messenger_name,
1126
+				$consider_current_state
1127
+			);
1128
+		}
1129
+	}
1130 1130
 }
Please login to merge, or discard this patch.
Spacing   +54 added lines, -54 removed lines patch added patch discarded remove patch
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
     public function get_active_messenger($messenger)
197 197
     {
198 198
         $this->_initialize_collections();
199
-        return ! empty($this->_active_messengers[ $messenger ]) ? $this->_active_messengers[ $messenger ] : null;
199
+        return ! empty($this->_active_messengers[$messenger]) ? $this->_active_messengers[$messenger] : null;
200 200
     }
201 201
 
202 202
 
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
             $this->_installed_messengers = array();
210 210
             $this->messenger_collection()->rewind();
211 211
             while ($this->messenger_collection()->valid()) {
212
-                $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = $this->messenger_collection()->current();
212
+                $this->_installed_messengers[$this->messenger_collection()->current()->name] = $this->messenger_collection()->current();
213 213
                 $this->messenger_collection()->next();
214 214
             }
215 215
         }
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
     public function is_message_type_active_for_messenger($messenger_name, $message_type_name)
293 293
     {
294 294
         $this->_initialize_collections();
295
-        return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
295
+        return ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]);
296 296
     }
297 297
 
298 298
 
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
     public function is_messenger_active($messenger_name)
306 306
     {
307 307
         $this->_initialize_collections();
308
-        return ! empty($this->_active_message_types[ $messenger_name ]);
308
+        return ! empty($this->_active_message_types[$messenger_name]);
309 309
     }
310 310
 
311 311
 
@@ -320,8 +320,8 @@  discard block
 block discarded – undo
320 320
     {
321 321
         $settings = array();
322 322
         if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
323
-            $settings = isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'])
324
-                ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']
323
+            $settings = isset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'])
324
+                ? $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings']
325 325
                 : array();
326 326
         }
327 327
         return $settings;
@@ -339,8 +339,8 @@  discard block
 block discarded – undo
339 339
     {
340 340
         $this->_initialize_collections();
341 341
         return
342
-            ! empty($this->_active_message_types[ $messenger_name ])
343
-            && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]);
342
+            ! empty($this->_active_message_types[$messenger_name])
343
+            && ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types']);
344 344
     }
345 345
 
346 346
 
@@ -355,13 +355,13 @@  discard block
 block discarded – undo
355 355
     public function get_active_message_types_for_messenger($messenger_name)
356 356
     {
357 357
         $message_types = array();
358
-        if (! $this->messenger_has_active_message_types($messenger_name)) {
358
+        if ( ! $this->messenger_has_active_message_types($messenger_name)) {
359 359
             return $message_types;
360 360
         }
361 361
         $installed_message_types = $this->installed_message_types();
362 362
         foreach ($installed_message_types as $message_type_name => $message_type) {
363 363
             if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
364
-                $message_types[ $message_type_name ] = $message_type;
364
+                $message_types[$message_type_name] = $message_type;
365 365
             }
366 366
         }
367 367
         return $message_types;
@@ -380,11 +380,11 @@  discard block
 block discarded – undo
380 380
         $active_message_type_names = array();
381 381
         $this->_initialize_collections();
382 382
         foreach ($this->_active_message_types as $messenger => $messenger_settings) {
383
-            if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) {
383
+            if ( ! isset($messenger_settings['settings'][$messenger.'-message_types'])) {
384 384
                 continue;
385 385
             }
386
-            foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) {
387
-                if (! in_array($message_type_name, $active_message_type_names)) {
386
+            foreach ($messenger_settings['settings'][$messenger.'-message_types'] as $message_type_name => $message_type_config) {
387
+                if ( ! in_array($message_type_name, $active_message_type_names)) {
388 388
                     $active_message_type_names[] = $message_type_name;
389 389
                 }
390 390
             }
@@ -405,8 +405,8 @@  discard block
 block discarded – undo
405 405
         $installed_message_types   = $this->installed_message_types();
406 406
         $active_message_type_names = $this->list_of_active_message_types();
407 407
         foreach ($active_message_type_names as $active_message_type_name) {
408
-            if (isset($installed_message_types[ $active_message_type_name ])) {
409
-                $active_message_types[ $active_message_type_name ] = $installed_message_types[ $active_message_type_name ];
408
+            if (isset($installed_message_types[$active_message_type_name])) {
409
+                $active_message_types[$active_message_type_name] = $installed_message_types[$active_message_type_name];
410 410
             }
411 411
         }
412 412
         return $active_message_types;
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
         if (empty($this->_installed_message_types)) {
422 422
             $this->message_type_collection()->rewind();
423 423
             while ($this->message_type_collection()->valid()) {
424
-                $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = $this->message_type_collection()->current();
424
+                $this->_installed_message_types[$this->message_type_collection()->current()->name] = $this->message_type_collection()->current();
425 425
                 $this->message_type_collection()->next();
426 426
             }
427 427
         }
@@ -460,7 +460,7 @@  discard block
 block discarded – undo
460 460
     public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name)
461 461
     {
462 462
         $valid_message_types = $messenger->get_valid_message_types();
463
-        if (! in_array($message_type_name, $valid_message_types)) {
463
+        if ( ! in_array($message_type_name, $valid_message_types)) {
464 464
             throw new EE_Error(
465 465
                 sprintf(
466 466
                     __(
@@ -586,7 +586,7 @@  discard block
 block discarded – undo
586 586
      */
587 587
     public function ensure_messenger_is_active($messenger_name, $update_option = true)
588 588
     {
589
-        if (! isset($this->_active_messengers[ $messenger_name ])) {
589
+        if ( ! isset($this->_active_messengers[$messenger_name])) {
590 590
             try {
591 591
                 $this->activate_messenger($messenger_name, array(), $update_option);
592 592
             } catch (EE_Error $e) {
@@ -631,7 +631,7 @@  discard block
 block discarded – undo
631 631
             $this->ensure_messenger_is_active($messenger_name, $update_option);
632 632
         }
633 633
 
634
-        if (! empty($not_installed)) {
634
+        if ( ! empty($not_installed)) {
635 635
             EE_Error::add_error(
636 636
                 sprintf(
637 637
                     __('The following messengers are either not installed or are invalid:%1$s %2$s', 'event_espresso'),
@@ -664,7 +664,7 @@  discard block
 block discarded – undo
664 664
             // ensure messenger is active (that's an inherent coupling between active message types and the
665 665
             // messenger they are being activated for.
666 666
             try {
667
-                if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
667
+                if ( ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
668 668
                     // all is good so let's just get it active
669 669
                     $this->activate_messenger($messenger, array($message_type_name), $update_option);
670 670
                 }
@@ -728,7 +728,7 @@  discard block
 block discarded – undo
728 728
             : $this->messenger_collection()->get_by_info($messenger);
729 729
         // it's inactive. Activate it.
730 730
         if ($messenger instanceof EE_messenger) {
731
-            $this->_active_messengers[ $messenger->name ] = $messenger;
731
+            $this->_active_messengers[$messenger->name] = $messenger;
732 732
             // activate incoming message types set to be activated with messenger.
733 733
             $message_type_names = $this->_activate_message_types($messenger, $message_type_names);
734 734
             // setup any initial settings for the messenger if necessary.
@@ -740,7 +740,7 @@  discard block
 block discarded – undo
740 740
             // generate new templates if necessary and ensure all related templates that are already in the database are
741 741
             // marked active.  Note, this will also deactivate a message type for a messenger if the template
742 742
             // cannot be successfully created during its attempt (only happens for global template attempts).
743
-            if (! empty($message_type_names)) {
743
+            if ( ! empty($message_type_names)) {
744 744
                 $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true);
745 745
                 EEH_MSG_Template::update_to_active(array($messenger->name), $message_type_names);
746 746
             }
@@ -764,13 +764,13 @@  discard block
 block discarded – undo
764 764
         // things have never been initialized (which should happen on EEH_Activation::generate_message_templates).
765 765
         // So ONLY then do we need to actually grab defaults and cycle through them.  Otherwise we
766 766
         // only override _active_message_types when an explicit array of $message_type_names has been provided.
767
-        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ])
767
+        $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[$messenger->name])
768 768
             ? $messenger->get_default_message_types()
769 769
             : (array) $message_type_names;
770 770
 
771 771
         // now we ALWAYS need to make sure that the messenger is active for the message types we're activating!
772
-        if (! isset($this->_active_message_types[ $messenger->name ])) {
773
-            $this->_active_message_types[ $messenger->name ]['settings'] = array();
772
+        if ( ! isset($this->_active_message_types[$messenger->name])) {
773
+            $this->_active_message_types[$messenger->name]['settings'] = array();
774 774
         }
775 775
 
776 776
         if ($message_type_names) {
@@ -778,7 +778,7 @@  discard block
 block discarded – undo
778 778
             foreach ($message_type_names as $message_type_name) {
779 779
                 // only register the message type as active IF it isn't already active
780 780
                 // and if its actually installed.
781
-                if (! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
781
+                if ( ! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name)
782 782
                 ) {
783 783
                     $this->add_settings_for_message_type($messenger->name, $message_type_name);
784 784
                     $this->_set_messenger_has_activated_message_type(
@@ -810,16 +810,16 @@  discard block
 block discarded – undo
810 810
         if ($message_type instanceof EE_message_type) {
811 811
             $default_settings = $message_type->get_admin_settings_fields();
812 812
             foreach ($default_settings as $field => $values) {
813
-                if (isset($new_settings[ $field ])) {
814
-                    $existing_settings[ $field ] = $new_settings[ $field ];
813
+                if (isset($new_settings[$field])) {
814
+                    $existing_settings[$field] = $new_settings[$field];
815 815
                     continue;
816 816
                 }
817
-                if (! isset($existing_settings[ $field ])) {
818
-                    $existing_settings[ $field ] = $values['default'];
817
+                if ( ! isset($existing_settings[$field])) {
818
+                    $existing_settings[$field] = $values['default'];
819 819
                 }
820 820
             }
821 821
         }
822
-        $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = $existing_settings;
822
+        $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'] = $existing_settings;
823 823
     }
824 824
 
825 825
 
@@ -842,12 +842,12 @@  discard block
 block discarded – undo
842 842
         }
843 843
 
844 844
         // make sure this messenger has a record in the has_activated array
845
-        if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
846
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ] = array();
845
+        if ( ! isset($this->_has_activated_messengers_and_message_types[$messenger->name])) {
846
+            $this->_has_activated_messengers_and_message_types[$messenger->name] = array();
847 847
         }
848 848
         // check if message type has already been added
849
-        if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) {
850
-            $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name;
849
+        if ( ! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[$messenger->name])) {
850
+            $this->_has_activated_messengers_and_message_types[$messenger->name][] = $message_type_name;
851 851
         }
852 852
     }
853 853
 
@@ -865,16 +865,16 @@  discard block
 block discarded – undo
865 865
         $messenger = $this->get_messenger($messenger_name);
866 866
         if ($messenger instanceof EE_messenger) {
867 867
             $msgr_settings = $messenger->get_admin_settings_fields();
868
-            if (! empty($msgr_settings)) {
868
+            if ( ! empty($msgr_settings)) {
869 869
                 foreach ($msgr_settings as $field => $value) {
870 870
                     // is there a new setting for this?
871
-                    if (isset($new_settings[ $field ])) {
872
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $new_settings[ $field ];
871
+                    if (isset($new_settings[$field])) {
872
+                        $this->_active_message_types[$messenger->name]['settings'][$field] = $new_settings[$field];
873 873
                         continue;
874 874
                     }
875 875
                     // only set the default if it isn't already set.
876
-                    if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) {
877
-                        $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value;
876
+                    if ( ! isset($this->_active_message_types[$messenger->name]['settings'][$field])) {
877
+                        $this->_active_message_types[$messenger->name]['settings'][$field] = $value;
878 878
                     }
879 879
                 }
880 880
             }
@@ -894,8 +894,8 @@  discard block
 block discarded – undo
894 894
         if ($messenger_name instanceof EE_messenger) {
895 895
             $messenger_name = $messenger_name->name;
896 896
         }
897
-        unset($this->_active_messengers[ $messenger_name ]);
898
-        unset($this->_active_message_types[ $messenger_name ]);
897
+        unset($this->_active_messengers[$messenger_name]);
898
+        unset($this->_active_message_types[$messenger_name]);
899 899
         $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name);
900 900
         $this->update_active_messengers_option();
901 901
     }
@@ -917,7 +917,7 @@  discard block
 block discarded – undo
917 917
         }
918 918
         foreach ($this->_active_message_types as $messenger_name => $settings) {
919 919
             unset(
920
-                $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]
920
+                $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]
921 921
             );
922 922
 
923 923
             // we always record (even on deactivation) that a message type has been activated because there should at
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
     {
944 944
         $this->_initialize_collections();
945 945
         if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) {
946
-            unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]);
946
+            unset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]);
947 947
         }
948 948
         $this->_message_template_group_model->deactivate_message_template_groups_for(
949 949
             array($messenger_name),
@@ -1003,22 +1003,22 @@  discard block
 block discarded – undo
1003 1003
     {
1004 1004
         $key = $slugs_only ? 'slugs' : 'all';
1005 1005
         // check if contexts has been setup yet.
1006
-        if (empty($this->_contexts[ $key ])) {
1006
+        if (empty($this->_contexts[$key])) {
1007 1007
             // So let's get all active message type objects and loop through to get all unique contexts
1008 1008
             foreach ($this->get_active_message_type_objects() as $message_type) {
1009 1009
                 if ($message_type instanceof EE_message_type) {
1010 1010
                     $message_type_contexts = $message_type->get_contexts();
1011 1011
                     if ($slugs_only) {
1012 1012
                         foreach ($message_type_contexts as $context => $context_details) {
1013
-                            $this->_contexts[ $key ][ $context ] = $context_details['label'];
1013
+                            $this->_contexts[$key][$context] = $context_details['label'];
1014 1014
                         }
1015 1015
                     } else {
1016
-                        $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts;
1016
+                        $this->_contexts[$key][$message_type->name] = $message_type_contexts;
1017 1017
                     }
1018 1018
                 }
1019 1019
             }
1020 1020
         }
1021
-        return ! empty($this->_contexts[ $key ]) ? $this->_contexts[ $key ] : array();
1021
+        return ! empty($this->_contexts[$key]) ? $this->_contexts[$key] : array();
1022 1022
     }
1023 1023
 
1024 1024
 
@@ -1038,7 +1038,7 @@  discard block
 block discarded – undo
1038 1038
         $all_message_types_valid           = true;
1039 1039
         // loop through list of active message types and verify they are installed.
1040 1040
         foreach ($list_of_active_message_type_names as $message_type_name) {
1041
-            if (! isset($installed_message_types[ $message_type_name ])) {
1041
+            if ( ! isset($installed_message_types[$message_type_name])) {
1042 1042
                 $this->remove_message_type_has_been_activated_from_all_messengers(
1043 1043
                     $message_type_name,
1044 1044
                     true
@@ -1065,8 +1065,8 @@  discard block
 block discarded – undo
1065 1065
     public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name)
1066 1066
     {
1067 1067
         $has_activated = $this->get_has_activated_messengers_option();
1068
-        return isset($has_activated[ $messenger_name ])
1069
-               && in_array($message_type_name, $has_activated[ $messenger_name ]);
1068
+        return isset($has_activated[$messenger_name])
1069
+               && in_array($message_type_name, $has_activated[$messenger_name]);
1070 1070
     }
1071 1071
 
1072 1072
 
@@ -1094,11 +1094,11 @@  discard block
 block discarded – undo
1094 1094
             return;
1095 1095
         }
1096 1096
         $has_activated = $this->get_has_activated_messengers_option();
1097
-        $key_for_message_type = isset($has_activated[ $messenger_name ])
1098
-            ? array_search($message_type_name, $has_activated[ $messenger_name ], true)
1097
+        $key_for_message_type = isset($has_activated[$messenger_name])
1098
+            ? array_search($message_type_name, $has_activated[$messenger_name], true)
1099 1099
             : false;
1100 1100
         if ($key_for_message_type !== false) {
1101
-            unset($has_activated[ $messenger_name ][ $key_for_message_type ]);
1101
+            unset($has_activated[$messenger_name][$key_for_message_type]);
1102 1102
             $this->update_has_activated_messengers_option($has_activated);
1103 1103
             // reset the internal cached property
1104 1104
             $this->get_has_activated_messengers_option(true);
Please login to merge, or discard this patch.
core/domain/DomainFactory.php 2 patches
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -23,62 +23,62 @@
 block discarded – undo
23 23
 class DomainFactory
24 24
 {
25 25
 
26
-    /**
27
-     * @param FullyQualifiedName $domain_fqcn   [required] Fully Qualified Class Name for the Domain class
28
-     * @param array $arguments                  [required] array of arguments to be passed to the Domain class
29
-     *                                          constructor. Must at least include the following two value objects:
30
-     *                                          array(
31
-     *                                              EventEspresso\core\domain\values\FilePath $plugin_file
32
-     *                                              EventEspresso\core\domain\values\Version $version
33
-     *                                          )
34
-     * @return DomainInterface
35
-     * @throws DomainException
36
-     * @throws InvalidArgumentException
37
-     * @throws InvalidDataTypeException
38
-     * @throws InvalidInterfaceException
39
-     */
40
-    public static function getShared(FullyQualifiedName $domain_fqcn, array $arguments)
41
-    {
42
-        if (! isset($arguments[0], $arguments[1])) {
43
-            throw new InvalidArgumentException(
44
-                esc_html__(
45
-                    'You need to pass at least two arguments, representing the addon plugin file and version, in order to generate a Domain class',
46
-                    'event_espresso'
47
-                )
48
-            );
49
-        }
50
-        /** @var DomainInterface $domain */
51
-        $domain = LoaderFactory::getLoader()->getShared($domain_fqcn, $arguments);
52
-        if (! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
53
-            throw new DomainException(
54
-                sprintf(
55
-                    esc_html__(
56
-                        'The requested Domain class "%1$s" could not be loaded.',
57
-                        'event_espresso'
58
-                    ),
59
-                    $domain_fqcn
60
-                )
61
-            );
62
-        }
63
-        return $domain;
64
-    }
26
+	/**
27
+	 * @param FullyQualifiedName $domain_fqcn   [required] Fully Qualified Class Name for the Domain class
28
+	 * @param array $arguments                  [required] array of arguments to be passed to the Domain class
29
+	 *                                          constructor. Must at least include the following two value objects:
30
+	 *                                          array(
31
+	 *                                              EventEspresso\core\domain\values\FilePath $plugin_file
32
+	 *                                              EventEspresso\core\domain\values\Version $version
33
+	 *                                          )
34
+	 * @return DomainInterface
35
+	 * @throws DomainException
36
+	 * @throws InvalidArgumentException
37
+	 * @throws InvalidDataTypeException
38
+	 * @throws InvalidInterfaceException
39
+	 */
40
+	public static function getShared(FullyQualifiedName $domain_fqcn, array $arguments)
41
+	{
42
+		if (! isset($arguments[0], $arguments[1])) {
43
+			throw new InvalidArgumentException(
44
+				esc_html__(
45
+					'You need to pass at least two arguments, representing the addon plugin file and version, in order to generate a Domain class',
46
+					'event_espresso'
47
+				)
48
+			);
49
+		}
50
+		/** @var DomainInterface $domain */
51
+		$domain = LoaderFactory::getLoader()->getShared($domain_fqcn, $arguments);
52
+		if (! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
53
+			throw new DomainException(
54
+				sprintf(
55
+					esc_html__(
56
+						'The requested Domain class "%1$s" could not be loaded.',
57
+						'event_espresso'
58
+					),
59
+					$domain_fqcn
60
+				)
61
+			);
62
+		}
63
+		return $domain;
64
+	}
65 65
 
66 66
 
67
-    /**
68
-     * @return Domain
69
-     * @throws DomainException
70
-     * @throws InvalidArgumentException
71
-     * @throws InvalidDataTypeException
72
-     * @throws InvalidFilePathException
73
-     * @throws InvalidInterfaceException
74
-     */
75
-    public static function getEventEspressoCoreDomain()
76
-    {
77
-        $domain = new Domain(
78
-            new FilePath(EVENT_ESPRESSO_MAIN_FILE),
79
-            Version::fromString(espresso_version())
80
-        );
81
-        LoaderFactory::getLoader()->share('EventEspresso\core\domain\Domain', $domain);
82
-        return $domain;
83
-    }
67
+	/**
68
+	 * @return Domain
69
+	 * @throws DomainException
70
+	 * @throws InvalidArgumentException
71
+	 * @throws InvalidDataTypeException
72
+	 * @throws InvalidFilePathException
73
+	 * @throws InvalidInterfaceException
74
+	 */
75
+	public static function getEventEspressoCoreDomain()
76
+	{
77
+		$domain = new Domain(
78
+			new FilePath(EVENT_ESPRESSO_MAIN_FILE),
79
+			Version::fromString(espresso_version())
80
+		);
81
+		LoaderFactory::getLoader()->share('EventEspresso\core\domain\Domain', $domain);
82
+		return $domain;
83
+	}
84 84
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -39,7 +39,7 @@  discard block
 block discarded – undo
39 39
      */
40 40
     public static function getShared(FullyQualifiedName $domain_fqcn, array $arguments)
41 41
     {
42
-        if (! isset($arguments[0], $arguments[1])) {
42
+        if ( ! isset($arguments[0], $arguments[1])) {
43 43
             throw new InvalidArgumentException(
44 44
                 esc_html__(
45 45
                     'You need to pass at least two arguments, representing the addon plugin file and version, in order to generate a Domain class',
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
         }
50 50
         /** @var DomainInterface $domain */
51 51
         $domain = LoaderFactory::getLoader()->getShared($domain_fqcn, $arguments);
52
-        if (! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
52
+        if ( ! $domain instanceof $domain_fqcn && ! $domain instanceof DomainBase) {
53 53
             throw new DomainException(
54 54
                 sprintf(
55 55
                     esc_html__(
Please login to merge, or discard this patch.
core/EE_Addon.core.php 2 patches
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
     public function set_plugins_page_row($plugins_page_row = array())
299 299
     {
300 300
         // sigh.... check for example content that I stupidly merged to master and remove it if found
301
-        if (! is_array($plugins_page_row)
301
+        if ( ! is_array($plugins_page_row)
302 302
             && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303 303
         ) {
304 304
             $plugins_page_row = array();
@@ -575,7 +575,7 @@  discard block
 block discarded – undo
575 575
      */
576 576
     public function get_activation_indicator_option_name()
577 577
     {
578
-        return 'ee_activation_' . $this->name();
578
+        return 'ee_activation_'.$this->name();
579 579
     }
580 580
 
581 581
 
@@ -662,13 +662,13 @@  discard block
 block discarded – undo
662 662
      */
663 663
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
664 664
     {
665
-        if (! $version_history) {
665
+        if ( ! $version_history) {
666 666
             $version_history = $this->get_activation_history();
667 667
         }
668 668
         if ($current_version_to_add === null) {
669 669
             $current_version_to_add = $this->version();
670 670
         }
671
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
671
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
672 672
         // resave
673 673
         return update_option($this->get_activation_history_option_name(), $version_history);
674 674
     }
@@ -681,7 +681,7 @@  discard block
 block discarded – undo
681 681
      */
682 682
     public function get_activation_history_option_name()
683 683
     {
684
-        return self::ee_addon_version_history_option_prefix . $this->name();
684
+        return self::ee_addon_version_history_option_prefix.$this->name();
685 685
     }
686 686
 
687 687
 
@@ -756,7 +756,7 @@  discard block
 block discarded – undo
756 756
         // is admin and not in M-Mode ?
757 757
         if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
758 758
             add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
759
-            add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
759
+            add_filter('after_plugin_row_'.$this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
760 760
         }
761 761
     }
762 762
 
@@ -775,7 +775,7 @@  discard block
 block discarded – undo
775 775
             // before other links
776 776
             array_unshift(
777 777
                 $links,
778
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
778
+                '<a href="admin.php?page='.$this->plugin_action_slug().'">'
779 779
                 . esc_html__('Settings', 'event_espresso')
780 780
                 . '</a>'
781 781
             );
@@ -798,15 +798,15 @@  discard block
 block discarded – undo
798 798
     {
799 799
         $after_plugin_row = '';
800 800
         $plugins_page_row = $this->get_plugins_page_row();
801
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
801
+        if ( ! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
802 802
             $class = $status ? 'active' : 'inactive';
803 803
             $link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
804 804
             $link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
805 805
             $description = isset($plugins_page_row['description'])
806 806
                 ? $plugins_page_row['description']
807 807
                 : '';
808
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
808
+            if ( ! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
+                $after_plugin_row .= '<tr id="'.sanitize_title($plugin_file).'-ee-addon" class="'.$class.'">';
810 810
                 $after_plugin_row .= '<th class="check-column" scope="row"></th>';
811 811
                 $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
812 812
                 $after_plugin_row .= '<style>
@@ -848,7 +848,7 @@  discard block
 block discarded – undo
848 848
 </style>';
849 849
                 $after_plugin_row .= '
850 850
 <p class="ee-addon-upsell-info-dv">
851
-	<a class="ee-button" href="' . $link_url . '">'
851
+	<a class="ee-button" href="' . $link_url.'">'
852 852
                                      . $link_text
853 853
                                      . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
854 854
                                      . '</a>
Please login to merge, or discard this patch.
Indentation   +843 added lines, -843 removed lines patch added patch discarded remove patch
@@ -19,797 +19,797 @@  discard block
 block discarded – undo
19 19
 {
20 20
 
21 21
 
22
-    /**
23
-     * prefix to be added onto an addon's plugin slug to make a wp option name
24
-     * which will be used to store the plugin's activation history
25
-     */
26
-    const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
-
28
-    /**
29
-     * @var $_version
30
-     * @type string
31
-     */
32
-    protected $_version = '';
33
-
34
-    /**
35
-     * @var $_min_core_version
36
-     * @type string
37
-     */
38
-    protected $_min_core_version = '';
39
-
40
-    /**
41
-     * derived from plugin 'main_file_path using plugin_basename()
42
-     *
43
-     * @type string $_plugin_basename
44
-     */
45
-    protected $_plugin_basename = '';
46
-
47
-    /**
48
-     * A non-internationalized name to identify this addon for use in URLs, etc
49
-     *
50
-     * @type string $_plugin_slug
51
-     */
52
-    protected $_plugin_slug = '';
53
-
54
-    /**
55
-     * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
-     *
57
-     * @type string _addon_name
58
-     */
59
-    protected $_addon_name = '';
60
-
61
-    /**
62
-     * one of the EE_System::req_type_* constants
63
-     *
64
-     * @type int $_req_type
65
-     */
66
-    protected $_req_type;
67
-
68
-    /**
69
-     * page slug to be used when generating the "Settings" link on the WP plugin page
70
-     *
71
-     * @type string $_plugin_action_slug
72
-     */
73
-    protected $_plugin_action_slug = '';
74
-
75
-    /**
76
-     * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
-     * that can be used for adding upgrading/marketing info
78
-     *
79
-     * @type array $_plugins_page_row
80
-     */
81
-    protected $_plugins_page_row = array();
82
-
83
-
84
-    /**
85
-     *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
-     *
87
-     * @type string
88
-     */
89
-    protected $_main_plugin_file;
90
-
91
-    /**
92
-     *    This is the slug used to identify this add-on within the plugin update engine.
93
-     *
94
-     * @type string
95
-     */
96
-    protected $pue_slug;
97
-
98
-
99
-    /**
100
-     * @var EE_Dependency_Map $dependency_map
101
-     */
102
-    private $dependency_map;
103
-
104
-
105
-    /**
106
-     * @var DomainInterface $domain
107
-     */
108
-    private $domain;
109
-
110
-
111
-    /**
112
-     * @param EE_Dependency_Map $dependency_map [optional]
113
-     * @param DomainInterface   $domain         [optional]
114
-     */
115
-    public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
-    {
117
-        if ($dependency_map instanceof EE_Dependency_Map) {
118
-            $this->setDependencyMap($dependency_map);
119
-        }
120
-        if ($domain instanceof DomainInterface) {
121
-            $this->setDomain($domain);
122
-        }
123
-        add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init'));
124
-    }
125
-
126
-
127
-    /**
128
-     * @param EE_Dependency_Map $dependency_map
129
-     */
130
-    public function setDependencyMap($dependency_map)
131
-    {
132
-        $this->dependency_map = $dependency_map;
133
-    }
134
-
135
-
136
-    /**
137
-     * @return EE_Dependency_Map
138
-     */
139
-    public function dependencyMap()
140
-    {
141
-        return $this->dependency_map;
142
-    }
143
-
144
-
145
-    /**
146
-     * @param DomainInterface $domain
147
-     */
148
-    public function setDomain(DomainInterface $domain)
149
-    {
150
-        $this->domain = $domain;
151
-    }
152
-
153
-    /**
154
-     * @return DomainInterface
155
-     */
156
-    public function domain()
157
-    {
158
-        return $this->domain;
159
-    }
160
-
161
-
162
-    /**
163
-     * @param mixed $version
164
-     */
165
-    public function set_version($version = null)
166
-    {
167
-        $this->_version = $version;
168
-    }
169
-
170
-
171
-    /**
172
-     * get__version
173
-     *
174
-     * @return string
175
-     */
176
-    public function version()
177
-    {
178
-        return $this->_version;
179
-    }
180
-
181
-
182
-    /**
183
-     * @param mixed $min_core_version
184
-     */
185
-    public function set_min_core_version($min_core_version = null)
186
-    {
187
-        $this->_min_core_version = $min_core_version;
188
-    }
189
-
190
-
191
-    /**
192
-     * get__min_core_version
193
-     *
194
-     * @return string
195
-     */
196
-    public function min_core_version()
197
-    {
198
-        return $this->_min_core_version;
199
-    }
200
-
201
-
202
-    /**
203
-     * Sets addon_name
204
-     *
205
-     * @param string $addon_name
206
-     * @return boolean
207
-     */
208
-    public function set_name($addon_name)
209
-    {
210
-        return $this->_addon_name = $addon_name;
211
-    }
212
-
213
-
214
-    /**
215
-     * Gets addon_name
216
-     *
217
-     * @return string
218
-     */
219
-    public function name()
220
-    {
221
-        return $this->_addon_name;
222
-    }
223
-
224
-
225
-    /**
226
-     * @return string
227
-     */
228
-    public function plugin_basename()
229
-    {
230
-
231
-        return $this->_plugin_basename;
232
-    }
233
-
234
-
235
-    /**
236
-     * @param string $plugin_basename
237
-     */
238
-    public function set_plugin_basename($plugin_basename)
239
-    {
240
-
241
-        $this->_plugin_basename = $plugin_basename;
242
-    }
243
-
244
-
245
-    /**
246
-     * @return string
247
-     */
248
-    public function plugin_slug()
249
-    {
250
-
251
-        return $this->_plugin_slug;
252
-    }
253
-
254
-
255
-    /**
256
-     * @param string $plugin_slug
257
-     */
258
-    public function set_plugin_slug($plugin_slug)
259
-    {
260
-
261
-        $this->_plugin_slug = $plugin_slug;
262
-    }
263
-
264
-
265
-    /**
266
-     * @return string
267
-     */
268
-    public function plugin_action_slug()
269
-    {
270
-
271
-        return $this->_plugin_action_slug;
272
-    }
273
-
274
-
275
-    /**
276
-     * @param string $plugin_action_slug
277
-     */
278
-    public function set_plugin_action_slug($plugin_action_slug)
279
-    {
280
-
281
-        $this->_plugin_action_slug = $plugin_action_slug;
282
-    }
283
-
284
-
285
-    /**
286
-     * @return array
287
-     */
288
-    public function get_plugins_page_row()
289
-    {
290
-
291
-        return $this->_plugins_page_row;
292
-    }
293
-
294
-
295
-    /**
296
-     * @param array $plugins_page_row
297
-     */
298
-    public function set_plugins_page_row($plugins_page_row = array())
299
-    {
300
-        // sigh.... check for example content that I stupidly merged to master and remove it if found
301
-        if (! is_array($plugins_page_row)
302
-            && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303
-        ) {
304
-            $plugins_page_row = array();
305
-        }
306
-        $this->_plugins_page_row = (array) $plugins_page_row;
307
-    }
308
-
309
-
310
-    /**
311
-     * Called when EE core detects this addon has been activated for the first time.
312
-     * If the site isn't in maintenance mode, should setup the addon's database
313
-     *
314
-     * @return void
315
-     */
316
-    public function new_install()
317
-    {
318
-        $classname = get_class($this);
319
-        do_action("AHEE__{$classname}__new_install");
320
-        do_action('AHEE__EE_Addon__new_install', $this);
321
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
322
-        add_action(
323
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
324
-            array($this, 'initialize_db_if_no_migrations_required')
325
-        );
326
-    }
327
-
328
-
329
-    /**
330
-     * Called when EE core detects this addon has been reactivated. When this happens,
331
-     * it's good to just check that your data is still intact
332
-     *
333
-     * @return void
334
-     */
335
-    public function reactivation()
336
-    {
337
-        $classname = get_class($this);
338
-        do_action("AHEE__{$classname}__reactivation");
339
-        do_action('AHEE__EE_Addon__reactivation', $this);
340
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
341
-        add_action(
342
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
343
-            array($this, 'initialize_db_if_no_migrations_required')
344
-        );
345
-    }
346
-
347
-
348
-    /**
349
-     * Called when the registered deactivation hook for this addon fires.
350
-     *
351
-     * @throws EE_Error
352
-     */
353
-    public function deactivation()
354
-    {
355
-        $classname = get_class($this);
356
-        do_action("AHEE__{$classname}__deactivation");
357
-        do_action('AHEE__EE_Addon__deactivation', $this);
358
-        // check if the site no longer needs to be in maintenance mode
359
-        EE_Register_Addon::deregister($this->name());
360
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
361
-    }
362
-
363
-
364
-    /**
365
-     * Takes care of double-checking that we're not in maintenance mode, and then
366
-     * initializing this addon's necessary initial data. This is called by default on new activations
367
-     * and reactivations.
368
-     *
369
-     * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
370
-     *                               This is a resource-intensive job so we prefer to only do it when necessary
371
-     * @return void
372
-     * @throws \EE_Error
373
-     * @throws InvalidInterfaceException
374
-     * @throws InvalidDataTypeException
375
-     * @throws InvalidArgumentException
376
-     */
377
-    public function initialize_db_if_no_migrations_required($verify_schema = true)
378
-    {
379
-        if ($verify_schema === '') {
380
-            // wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
381
-            // (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
382
-            // calls them with an argument of an empty string (ie ""), which evaluates to false
383
-            // so we need to treat the empty string as if nothing had been passed, and should instead use the default
384
-            $verify_schema = true;
385
-        }
386
-        if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
387
-            if ($verify_schema) {
388
-                $this->initialize_db();
389
-            }
390
-            $this->initialize_default_data();
391
-            // @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
392
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to(
393
-                array(
394
-                    'slug'    => $this->name(),
395
-                    'version' => $this->version(),
396
-                )
397
-            );
398
-            /* make sure core's data is a-ok
22
+	/**
23
+	 * prefix to be added onto an addon's plugin slug to make a wp option name
24
+	 * which will be used to store the plugin's activation history
25
+	 */
26
+	const ee_addon_version_history_option_prefix = 'ee_version_history_';
27
+
28
+	/**
29
+	 * @var $_version
30
+	 * @type string
31
+	 */
32
+	protected $_version = '';
33
+
34
+	/**
35
+	 * @var $_min_core_version
36
+	 * @type string
37
+	 */
38
+	protected $_min_core_version = '';
39
+
40
+	/**
41
+	 * derived from plugin 'main_file_path using plugin_basename()
42
+	 *
43
+	 * @type string $_plugin_basename
44
+	 */
45
+	protected $_plugin_basename = '';
46
+
47
+	/**
48
+	 * A non-internationalized name to identify this addon for use in URLs, etc
49
+	 *
50
+	 * @type string $_plugin_slug
51
+	 */
52
+	protected $_plugin_slug = '';
53
+
54
+	/**
55
+	 * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
56
+	 *
57
+	 * @type string _addon_name
58
+	 */
59
+	protected $_addon_name = '';
60
+
61
+	/**
62
+	 * one of the EE_System::req_type_* constants
63
+	 *
64
+	 * @type int $_req_type
65
+	 */
66
+	protected $_req_type;
67
+
68
+	/**
69
+	 * page slug to be used when generating the "Settings" link on the WP plugin page
70
+	 *
71
+	 * @type string $_plugin_action_slug
72
+	 */
73
+	protected $_plugin_action_slug = '';
74
+
75
+	/**
76
+	 * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
77
+	 * that can be used for adding upgrading/marketing info
78
+	 *
79
+	 * @type array $_plugins_page_row
80
+	 */
81
+	protected $_plugins_page_row = array();
82
+
83
+
84
+	/**
85
+	 *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
+	 *
87
+	 * @type string
88
+	 */
89
+	protected $_main_plugin_file;
90
+
91
+	/**
92
+	 *    This is the slug used to identify this add-on within the plugin update engine.
93
+	 *
94
+	 * @type string
95
+	 */
96
+	protected $pue_slug;
97
+
98
+
99
+	/**
100
+	 * @var EE_Dependency_Map $dependency_map
101
+	 */
102
+	private $dependency_map;
103
+
104
+
105
+	/**
106
+	 * @var DomainInterface $domain
107
+	 */
108
+	private $domain;
109
+
110
+
111
+	/**
112
+	 * @param EE_Dependency_Map $dependency_map [optional]
113
+	 * @param DomainInterface   $domain         [optional]
114
+	 */
115
+	public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
116
+	{
117
+		if ($dependency_map instanceof EE_Dependency_Map) {
118
+			$this->setDependencyMap($dependency_map);
119
+		}
120
+		if ($domain instanceof DomainInterface) {
121
+			$this->setDomain($domain);
122
+		}
123
+		add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init'));
124
+	}
125
+
126
+
127
+	/**
128
+	 * @param EE_Dependency_Map $dependency_map
129
+	 */
130
+	public function setDependencyMap($dependency_map)
131
+	{
132
+		$this->dependency_map = $dependency_map;
133
+	}
134
+
135
+
136
+	/**
137
+	 * @return EE_Dependency_Map
138
+	 */
139
+	public function dependencyMap()
140
+	{
141
+		return $this->dependency_map;
142
+	}
143
+
144
+
145
+	/**
146
+	 * @param DomainInterface $domain
147
+	 */
148
+	public function setDomain(DomainInterface $domain)
149
+	{
150
+		$this->domain = $domain;
151
+	}
152
+
153
+	/**
154
+	 * @return DomainInterface
155
+	 */
156
+	public function domain()
157
+	{
158
+		return $this->domain;
159
+	}
160
+
161
+
162
+	/**
163
+	 * @param mixed $version
164
+	 */
165
+	public function set_version($version = null)
166
+	{
167
+		$this->_version = $version;
168
+	}
169
+
170
+
171
+	/**
172
+	 * get__version
173
+	 *
174
+	 * @return string
175
+	 */
176
+	public function version()
177
+	{
178
+		return $this->_version;
179
+	}
180
+
181
+
182
+	/**
183
+	 * @param mixed $min_core_version
184
+	 */
185
+	public function set_min_core_version($min_core_version = null)
186
+	{
187
+		$this->_min_core_version = $min_core_version;
188
+	}
189
+
190
+
191
+	/**
192
+	 * get__min_core_version
193
+	 *
194
+	 * @return string
195
+	 */
196
+	public function min_core_version()
197
+	{
198
+		return $this->_min_core_version;
199
+	}
200
+
201
+
202
+	/**
203
+	 * Sets addon_name
204
+	 *
205
+	 * @param string $addon_name
206
+	 * @return boolean
207
+	 */
208
+	public function set_name($addon_name)
209
+	{
210
+		return $this->_addon_name = $addon_name;
211
+	}
212
+
213
+
214
+	/**
215
+	 * Gets addon_name
216
+	 *
217
+	 * @return string
218
+	 */
219
+	public function name()
220
+	{
221
+		return $this->_addon_name;
222
+	}
223
+
224
+
225
+	/**
226
+	 * @return string
227
+	 */
228
+	public function plugin_basename()
229
+	{
230
+
231
+		return $this->_plugin_basename;
232
+	}
233
+
234
+
235
+	/**
236
+	 * @param string $plugin_basename
237
+	 */
238
+	public function set_plugin_basename($plugin_basename)
239
+	{
240
+
241
+		$this->_plugin_basename = $plugin_basename;
242
+	}
243
+
244
+
245
+	/**
246
+	 * @return string
247
+	 */
248
+	public function plugin_slug()
249
+	{
250
+
251
+		return $this->_plugin_slug;
252
+	}
253
+
254
+
255
+	/**
256
+	 * @param string $plugin_slug
257
+	 */
258
+	public function set_plugin_slug($plugin_slug)
259
+	{
260
+
261
+		$this->_plugin_slug = $plugin_slug;
262
+	}
263
+
264
+
265
+	/**
266
+	 * @return string
267
+	 */
268
+	public function plugin_action_slug()
269
+	{
270
+
271
+		return $this->_plugin_action_slug;
272
+	}
273
+
274
+
275
+	/**
276
+	 * @param string $plugin_action_slug
277
+	 */
278
+	public function set_plugin_action_slug($plugin_action_slug)
279
+	{
280
+
281
+		$this->_plugin_action_slug = $plugin_action_slug;
282
+	}
283
+
284
+
285
+	/**
286
+	 * @return array
287
+	 */
288
+	public function get_plugins_page_row()
289
+	{
290
+
291
+		return $this->_plugins_page_row;
292
+	}
293
+
294
+
295
+	/**
296
+	 * @param array $plugins_page_row
297
+	 */
298
+	public function set_plugins_page_row($plugins_page_row = array())
299
+	{
300
+		// sigh.... check for example content that I stupidly merged to master and remove it if found
301
+		if (! is_array($plugins_page_row)
302
+			&& strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
303
+		) {
304
+			$plugins_page_row = array();
305
+		}
306
+		$this->_plugins_page_row = (array) $plugins_page_row;
307
+	}
308
+
309
+
310
+	/**
311
+	 * Called when EE core detects this addon has been activated for the first time.
312
+	 * If the site isn't in maintenance mode, should setup the addon's database
313
+	 *
314
+	 * @return void
315
+	 */
316
+	public function new_install()
317
+	{
318
+		$classname = get_class($this);
319
+		do_action("AHEE__{$classname}__new_install");
320
+		do_action('AHEE__EE_Addon__new_install', $this);
321
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
322
+		add_action(
323
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
324
+			array($this, 'initialize_db_if_no_migrations_required')
325
+		);
326
+	}
327
+
328
+
329
+	/**
330
+	 * Called when EE core detects this addon has been reactivated. When this happens,
331
+	 * it's good to just check that your data is still intact
332
+	 *
333
+	 * @return void
334
+	 */
335
+	public function reactivation()
336
+	{
337
+		$classname = get_class($this);
338
+		do_action("AHEE__{$classname}__reactivation");
339
+		do_action('AHEE__EE_Addon__reactivation', $this);
340
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
341
+		add_action(
342
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
343
+			array($this, 'initialize_db_if_no_migrations_required')
344
+		);
345
+	}
346
+
347
+
348
+	/**
349
+	 * Called when the registered deactivation hook for this addon fires.
350
+	 *
351
+	 * @throws EE_Error
352
+	 */
353
+	public function deactivation()
354
+	{
355
+		$classname = get_class($this);
356
+		do_action("AHEE__{$classname}__deactivation");
357
+		do_action('AHEE__EE_Addon__deactivation', $this);
358
+		// check if the site no longer needs to be in maintenance mode
359
+		EE_Register_Addon::deregister($this->name());
360
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
361
+	}
362
+
363
+
364
+	/**
365
+	 * Takes care of double-checking that we're not in maintenance mode, and then
366
+	 * initializing this addon's necessary initial data. This is called by default on new activations
367
+	 * and reactivations.
368
+	 *
369
+	 * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
370
+	 *                               This is a resource-intensive job so we prefer to only do it when necessary
371
+	 * @return void
372
+	 * @throws \EE_Error
373
+	 * @throws InvalidInterfaceException
374
+	 * @throws InvalidDataTypeException
375
+	 * @throws InvalidArgumentException
376
+	 */
377
+	public function initialize_db_if_no_migrations_required($verify_schema = true)
378
+	{
379
+		if ($verify_schema === '') {
380
+			// wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
381
+			// (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
382
+			// calls them with an argument of an empty string (ie ""), which evaluates to false
383
+			// so we need to treat the empty string as if nothing had been passed, and should instead use the default
384
+			$verify_schema = true;
385
+		}
386
+		if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
387
+			if ($verify_schema) {
388
+				$this->initialize_db();
389
+			}
390
+			$this->initialize_default_data();
391
+			// @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
392
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to(
393
+				array(
394
+					'slug'    => $this->name(),
395
+					'version' => $this->version(),
396
+				)
397
+			);
398
+			/* make sure core's data is a-ok
399 399
              * (at the time of writing, we especially want to verify all the caps are present
400 400
              * because payment method type capabilities are added dynamically, and it's
401 401
              * possible this addon added a payment method. But it's also possible
402 402
              * other data needs to be verified)
403 403
              */
404
-            EEH_Activation::initialize_db_content();
405
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
406
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
407
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
408
-            );
409
-            $rewrite_rules->flushRewriteRules();
410
-            // in case there are lots of addons being activated at once, let's force garbage collection
411
-            // to help avoid memory limit errors
412
-            // EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
413
-            gc_collect_cycles();
414
-        } else {
415
-            // ask the data migration manager to init this addon's data
416
-            // when migrations are finished because we can't do it now
417
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
418
-        }
419
-    }
420
-
421
-
422
-    /**
423
-     * Used to setup this addon's database tables, but not necessarily any default
424
-     * data in them. The default is to actually use the most up-to-date data migration script
425
-     * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
426
-     * methods to setup the db.
427
-     */
428
-    public function initialize_db()
429
-    {
430
-        // find the migration script that sets the database to be compatible with the code
431
-        $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
432
-        if ($current_dms_name) {
433
-            $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
434
-            $current_data_migration_script->set_migrating(false);
435
-            $current_data_migration_script->schema_changes_before_migration();
436
-            $current_data_migration_script->schema_changes_after_migration();
437
-            if ($current_data_migration_script->get_errors()) {
438
-                foreach ($current_data_migration_script->get_errors() as $error) {
439
-                    EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
440
-                }
441
-            }
442
-        }
443
-        // if not DMS was found that should be ok. This addon just doesn't require any database changes
444
-        EE_Data_Migration_Manager::instance()->update_current_database_state_to(
445
-            array(
446
-                'slug'    => $this->name(),
447
-                'version' => $this->version(),
448
-            )
449
-        );
450
-    }
451
-
452
-
453
-    /**
454
-     * If you want to setup default data for the addon, override this method, and call
455
-     * parent::initialize_default_data() from within it. This is normally called
456
-     * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
457
-     * and should verify default data is present (but this is also called
458
-     * on reactivations and just after migrations, so please verify you actually want
459
-     * to ADD default data, because it may already be present).
460
-     * However, please call this parent (currently it just fires a hook which other
461
-     * addons may be depending on)
462
-     */
463
-    public function initialize_default_data()
464
-    {
465
-        /**
466
-         * Called when an addon is ensuring its default data is set (possibly called
467
-         * on a reactivation, so first check for the absence of other data before setting
468
-         * default data)
469
-         *
470
-         * @param EE_Addon $addon the addon that called this
471
-         */
472
-        do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
473
-        // override to insert default data. It is safe to use the models here
474
-        // because the site should not be in maintenance mode
475
-    }
476
-
477
-
478
-    /**
479
-     * EE Core detected that this addon has been upgraded. We should check if there
480
-     * are any new migration scripts, and if so put the site into maintenance mode until
481
-     * they're ran
482
-     *
483
-     * @return void
484
-     */
485
-    public function upgrade()
486
-    {
487
-        $classname = get_class($this);
488
-        do_action("AHEE__{$classname}__upgrade");
489
-        do_action('AHEE__EE_Addon__upgrade', $this);
490
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
491
-        // also it's possible there is new default data that needs to be added
492
-        add_action(
493
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
494
-            array($this, 'initialize_db_if_no_migrations_required')
495
-        );
496
-    }
497
-
498
-
499
-    /**
500
-     * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
501
-     */
502
-    public function downgrade()
503
-    {
504
-        $classname = get_class($this);
505
-        do_action("AHEE__{$classname}__downgrade");
506
-        do_action('AHEE__EE_Addon__downgrade', $this);
507
-        // it's possible there's old default data that needs to be double-checked
508
-        add_action(
509
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
510
-            array($this, 'initialize_db_if_no_migrations_required')
511
-        );
512
-    }
513
-
514
-
515
-    /**
516
-     * set_db_update_option_name
517
-     * Until we do something better, we'll just check for migration scripts upon
518
-     * plugin activation only. In the future, we'll want to do it on plugin updates too
519
-     *
520
-     * @return bool
521
-     */
522
-    public function set_db_update_option_name()
523
-    {
524
-        EE_Error::doing_it_wrong(
525
-            __FUNCTION__,
526
-            esc_html__(
527
-                'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
528
-                'event_espresso'
529
-            ),
530
-            '4.3.0.alpha.016'
531
-        );
532
-        // let's just handle this on the next request, ok? right now we're just not really ready
533
-        return $this->set_activation_indicator_option();
534
-    }
535
-
536
-
537
-    /**
538
-     * Returns the name of the activation indicator option
539
-     * (an option which is set temporarily to indicate that this addon was just activated)
540
-     *
541
-     * @deprecated since version 4.3.0.alpha.016
542
-     * @return string
543
-     */
544
-    public function get_db_update_option_name()
545
-    {
546
-        EE_Error::doing_it_wrong(
547
-            __FUNCTION__,
548
-            esc_html__(
549
-                'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
550
-                'event_espresso'
551
-            ),
552
-            '4.3.0.alpha.016'
553
-        );
554
-        return $this->get_activation_indicator_option_name();
555
-    }
556
-
557
-
558
-    /**
559
-     * When the addon is activated, this should be called to set a wordpress option that
560
-     * indicates it was activated. This is especially useful for detecting reactivations.
561
-     *
562
-     * @return bool
563
-     */
564
-    public function set_activation_indicator_option()
565
-    {
566
-        // let's just handle this on the next request, ok? right now we're just not really ready
567
-        return update_option($this->get_activation_indicator_option_name(), true);
568
-    }
569
-
570
-
571
-    /**
572
-     * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
573
-     *
574
-     * @return string
575
-     */
576
-    public function get_activation_indicator_option_name()
577
-    {
578
-        return 'ee_activation_' . $this->name();
579
-    }
580
-
581
-
582
-    /**
583
-     * Used by EE_System to set the request type of this addon. Should not be used by addon developers
584
-     *
585
-     * @param int $req_type
586
-     */
587
-    public function set_req_type($req_type)
588
-    {
589
-        $this->_req_type = $req_type;
590
-    }
591
-
592
-
593
-    /**
594
-     * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
595
-     * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
596
-     * EE_System when it is checking for new install or upgrades of addons
597
-     */
598
-    public function detect_req_type($redetect = false)
599
-    {
600
-        if ($this->_req_type === null || $redetect) {
601
-            $this->detect_activation_or_upgrade();
602
-        }
603
-        return $this->_req_type;
604
-    }
605
-
606
-
607
-    /**
608
-     * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
609
-     * Should only be called once per request
610
-     *
611
-     * @return void
612
-     */
613
-    public function detect_activation_or_upgrade()
614
-    {
615
-        $activation_history_for_addon = $this->get_activation_history();
616
-        $request_type = EE_System::detect_req_type_given_activation_history(
617
-            $activation_history_for_addon,
618
-            $this->get_activation_indicator_option_name(),
619
-            $this->version()
620
-        );
621
-        $this->set_req_type($request_type);
622
-        $classname = get_class($this);
623
-        switch ($request_type) {
624
-            case EE_System::req_type_new_activation:
625
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
626
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
627
-                $this->new_install();
628
-                $this->update_list_of_installed_versions($activation_history_for_addon);
629
-                break;
630
-            case EE_System::req_type_reactivation:
631
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
632
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
633
-                $this->reactivation();
634
-                $this->update_list_of_installed_versions($activation_history_for_addon);
635
-                break;
636
-            case EE_System::req_type_upgrade:
637
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
638
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
639
-                $this->upgrade();
640
-                $this->update_list_of_installed_versions($activation_history_for_addon);
641
-                break;
642
-            case EE_System::req_type_downgrade:
643
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
644
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
645
-                $this->downgrade();
646
-                $this->update_list_of_installed_versions($activation_history_for_addon);
647
-                break;
648
-            case EE_System::req_type_normal:
649
-            default:
650
-                break;
651
-        }
652
-
653
-        do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
654
-    }
655
-
656
-    /**
657
-     * Updates the version history for this addon
658
-     *
659
-     * @param array  $version_history
660
-     * @param string $current_version_to_add
661
-     * @return boolean success
662
-     */
663
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
664
-    {
665
-        if (! $version_history) {
666
-            $version_history = $this->get_activation_history();
667
-        }
668
-        if ($current_version_to_add === null) {
669
-            $current_version_to_add = $this->version();
670
-        }
671
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
672
-        // resave
673
-        return update_option($this->get_activation_history_option_name(), $version_history);
674
-    }
675
-
676
-    /**
677
-     * Gets the name of the wp option that stores the activation history
678
-     * of this addon
679
-     *
680
-     * @return string
681
-     */
682
-    public function get_activation_history_option_name()
683
-    {
684
-        return self::ee_addon_version_history_option_prefix . $this->name();
685
-    }
686
-
687
-
688
-    /**
689
-     * Gets the wp option which stores the activation history for this addon
690
-     *
691
-     * @return array
692
-     */
693
-    public function get_activation_history()
694
-    {
695
-        return get_option($this->get_activation_history_option_name(), null);
696
-    }
697
-
698
-
699
-    /**
700
-     * @param string $config_section
701
-     */
702
-    public function set_config_section($config_section = '')
703
-    {
704
-        $this->_config_section = ! empty($config_section) ? $config_section : 'addons';
705
-    }
706
-
707
-    /**
708
-     * Sets the filepath to the main plugin file
709
-     *
710
-     * @param string $filepath
711
-     */
712
-    public function set_main_plugin_file($filepath)
713
-    {
714
-        $this->_main_plugin_file = $filepath;
715
-    }
716
-
717
-    /**
718
-     * gets the filepath to teh main file
719
-     *
720
-     * @return string
721
-     */
722
-    public function get_main_plugin_file()
723
-    {
724
-        return $this->_main_plugin_file;
725
-    }
726
-
727
-    /**
728
-     * Gets the filename (no path) of the main file (the main file loaded
729
-     * by WP)
730
-     *
731
-     * @return string
732
-     */
733
-    public function get_main_plugin_file_basename()
734
-    {
735
-        return plugin_basename($this->get_main_plugin_file());
736
-    }
737
-
738
-    /**
739
-     * Gets the folder name which contains the main plugin file
740
-     *
741
-     * @return string
742
-     */
743
-    public function get_main_plugin_file_dirname()
744
-    {
745
-        return dirname($this->get_main_plugin_file());
746
-    }
747
-
748
-
749
-    /**
750
-     * sets hooks used in the admin
751
-     *
752
-     * @return void
753
-     */
754
-    public function admin_init()
755
-    {
756
-        // is admin and not in M-Mode ?
757
-        if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
758
-            add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
759
-            add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
760
-        }
761
-    }
762
-
763
-
764
-    /**
765
-     * plugin_actions
766
-     * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
767
-     *
768
-     * @param $links
769
-     * @param $file
770
-     * @return array
771
-     */
772
-    public function plugin_action_links($links, $file)
773
-    {
774
-        if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
775
-            // before other links
776
-            array_unshift(
777
-                $links,
778
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
779
-                . esc_html__('Settings', 'event_espresso')
780
-                . '</a>'
781
-            );
782
-        }
783
-        return $links;
784
-    }
785
-
786
-
787
-    /**
788
-     * after_plugin_row
789
-     * Add additional content to the plugins page plugin row
790
-     * Inserts another row
791
-     *
792
-     * @param $plugin_file
793
-     * @param $plugin_data
794
-     * @param $status
795
-     * @return void
796
-     */
797
-    public function after_plugin_row($plugin_file, $plugin_data, $status)
798
-    {
799
-        $after_plugin_row = '';
800
-        $plugins_page_row = $this->get_plugins_page_row();
801
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
802
-            $class = $status ? 'active' : 'inactive';
803
-            $link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
804
-            $link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
805
-            $description = isset($plugins_page_row['description'])
806
-                ? $plugins_page_row['description']
807
-                : '';
808
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
810
-                $after_plugin_row .= '<th class="check-column" scope="row"></th>';
811
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
812
-                $after_plugin_row .= '<style>
404
+			EEH_Activation::initialize_db_content();
405
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
406
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
407
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
408
+			);
409
+			$rewrite_rules->flushRewriteRules();
410
+			// in case there are lots of addons being activated at once, let's force garbage collection
411
+			// to help avoid memory limit errors
412
+			// EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
413
+			gc_collect_cycles();
414
+		} else {
415
+			// ask the data migration manager to init this addon's data
416
+			// when migrations are finished because we can't do it now
417
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
418
+		}
419
+	}
420
+
421
+
422
+	/**
423
+	 * Used to setup this addon's database tables, but not necessarily any default
424
+	 * data in them. The default is to actually use the most up-to-date data migration script
425
+	 * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
426
+	 * methods to setup the db.
427
+	 */
428
+	public function initialize_db()
429
+	{
430
+		// find the migration script that sets the database to be compatible with the code
431
+		$current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
432
+		if ($current_dms_name) {
433
+			$current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
434
+			$current_data_migration_script->set_migrating(false);
435
+			$current_data_migration_script->schema_changes_before_migration();
436
+			$current_data_migration_script->schema_changes_after_migration();
437
+			if ($current_data_migration_script->get_errors()) {
438
+				foreach ($current_data_migration_script->get_errors() as $error) {
439
+					EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
440
+				}
441
+			}
442
+		}
443
+		// if not DMS was found that should be ok. This addon just doesn't require any database changes
444
+		EE_Data_Migration_Manager::instance()->update_current_database_state_to(
445
+			array(
446
+				'slug'    => $this->name(),
447
+				'version' => $this->version(),
448
+			)
449
+		);
450
+	}
451
+
452
+
453
+	/**
454
+	 * If you want to setup default data for the addon, override this method, and call
455
+	 * parent::initialize_default_data() from within it. This is normally called
456
+	 * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
457
+	 * and should verify default data is present (but this is also called
458
+	 * on reactivations and just after migrations, so please verify you actually want
459
+	 * to ADD default data, because it may already be present).
460
+	 * However, please call this parent (currently it just fires a hook which other
461
+	 * addons may be depending on)
462
+	 */
463
+	public function initialize_default_data()
464
+	{
465
+		/**
466
+		 * Called when an addon is ensuring its default data is set (possibly called
467
+		 * on a reactivation, so first check for the absence of other data before setting
468
+		 * default data)
469
+		 *
470
+		 * @param EE_Addon $addon the addon that called this
471
+		 */
472
+		do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
473
+		// override to insert default data. It is safe to use the models here
474
+		// because the site should not be in maintenance mode
475
+	}
476
+
477
+
478
+	/**
479
+	 * EE Core detected that this addon has been upgraded. We should check if there
480
+	 * are any new migration scripts, and if so put the site into maintenance mode until
481
+	 * they're ran
482
+	 *
483
+	 * @return void
484
+	 */
485
+	public function upgrade()
486
+	{
487
+		$classname = get_class($this);
488
+		do_action("AHEE__{$classname}__upgrade");
489
+		do_action('AHEE__EE_Addon__upgrade', $this);
490
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
491
+		// also it's possible there is new default data that needs to be added
492
+		add_action(
493
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
494
+			array($this, 'initialize_db_if_no_migrations_required')
495
+		);
496
+	}
497
+
498
+
499
+	/**
500
+	 * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
501
+	 */
502
+	public function downgrade()
503
+	{
504
+		$classname = get_class($this);
505
+		do_action("AHEE__{$classname}__downgrade");
506
+		do_action('AHEE__EE_Addon__downgrade', $this);
507
+		// it's possible there's old default data that needs to be double-checked
508
+		add_action(
509
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
510
+			array($this, 'initialize_db_if_no_migrations_required')
511
+		);
512
+	}
513
+
514
+
515
+	/**
516
+	 * set_db_update_option_name
517
+	 * Until we do something better, we'll just check for migration scripts upon
518
+	 * plugin activation only. In the future, we'll want to do it on plugin updates too
519
+	 *
520
+	 * @return bool
521
+	 */
522
+	public function set_db_update_option_name()
523
+	{
524
+		EE_Error::doing_it_wrong(
525
+			__FUNCTION__,
526
+			esc_html__(
527
+				'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
528
+				'event_espresso'
529
+			),
530
+			'4.3.0.alpha.016'
531
+		);
532
+		// let's just handle this on the next request, ok? right now we're just not really ready
533
+		return $this->set_activation_indicator_option();
534
+	}
535
+
536
+
537
+	/**
538
+	 * Returns the name of the activation indicator option
539
+	 * (an option which is set temporarily to indicate that this addon was just activated)
540
+	 *
541
+	 * @deprecated since version 4.3.0.alpha.016
542
+	 * @return string
543
+	 */
544
+	public function get_db_update_option_name()
545
+	{
546
+		EE_Error::doing_it_wrong(
547
+			__FUNCTION__,
548
+			esc_html__(
549
+				'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
550
+				'event_espresso'
551
+			),
552
+			'4.3.0.alpha.016'
553
+		);
554
+		return $this->get_activation_indicator_option_name();
555
+	}
556
+
557
+
558
+	/**
559
+	 * When the addon is activated, this should be called to set a wordpress option that
560
+	 * indicates it was activated. This is especially useful for detecting reactivations.
561
+	 *
562
+	 * @return bool
563
+	 */
564
+	public function set_activation_indicator_option()
565
+	{
566
+		// let's just handle this on the next request, ok? right now we're just not really ready
567
+		return update_option($this->get_activation_indicator_option_name(), true);
568
+	}
569
+
570
+
571
+	/**
572
+	 * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
573
+	 *
574
+	 * @return string
575
+	 */
576
+	public function get_activation_indicator_option_name()
577
+	{
578
+		return 'ee_activation_' . $this->name();
579
+	}
580
+
581
+
582
+	/**
583
+	 * Used by EE_System to set the request type of this addon. Should not be used by addon developers
584
+	 *
585
+	 * @param int $req_type
586
+	 */
587
+	public function set_req_type($req_type)
588
+	{
589
+		$this->_req_type = $req_type;
590
+	}
591
+
592
+
593
+	/**
594
+	 * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
595
+	 * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
596
+	 * EE_System when it is checking for new install or upgrades of addons
597
+	 */
598
+	public function detect_req_type($redetect = false)
599
+	{
600
+		if ($this->_req_type === null || $redetect) {
601
+			$this->detect_activation_or_upgrade();
602
+		}
603
+		return $this->_req_type;
604
+	}
605
+
606
+
607
+	/**
608
+	 * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
609
+	 * Should only be called once per request
610
+	 *
611
+	 * @return void
612
+	 */
613
+	public function detect_activation_or_upgrade()
614
+	{
615
+		$activation_history_for_addon = $this->get_activation_history();
616
+		$request_type = EE_System::detect_req_type_given_activation_history(
617
+			$activation_history_for_addon,
618
+			$this->get_activation_indicator_option_name(),
619
+			$this->version()
620
+		);
621
+		$this->set_req_type($request_type);
622
+		$classname = get_class($this);
623
+		switch ($request_type) {
624
+			case EE_System::req_type_new_activation:
625
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
626
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
627
+				$this->new_install();
628
+				$this->update_list_of_installed_versions($activation_history_for_addon);
629
+				break;
630
+			case EE_System::req_type_reactivation:
631
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
632
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
633
+				$this->reactivation();
634
+				$this->update_list_of_installed_versions($activation_history_for_addon);
635
+				break;
636
+			case EE_System::req_type_upgrade:
637
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
638
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
639
+				$this->upgrade();
640
+				$this->update_list_of_installed_versions($activation_history_for_addon);
641
+				break;
642
+			case EE_System::req_type_downgrade:
643
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
644
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
645
+				$this->downgrade();
646
+				$this->update_list_of_installed_versions($activation_history_for_addon);
647
+				break;
648
+			case EE_System::req_type_normal:
649
+			default:
650
+				break;
651
+		}
652
+
653
+		do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
654
+	}
655
+
656
+	/**
657
+	 * Updates the version history for this addon
658
+	 *
659
+	 * @param array  $version_history
660
+	 * @param string $current_version_to_add
661
+	 * @return boolean success
662
+	 */
663
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
664
+	{
665
+		if (! $version_history) {
666
+			$version_history = $this->get_activation_history();
667
+		}
668
+		if ($current_version_to_add === null) {
669
+			$current_version_to_add = $this->version();
670
+		}
671
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
672
+		// resave
673
+		return update_option($this->get_activation_history_option_name(), $version_history);
674
+	}
675
+
676
+	/**
677
+	 * Gets the name of the wp option that stores the activation history
678
+	 * of this addon
679
+	 *
680
+	 * @return string
681
+	 */
682
+	public function get_activation_history_option_name()
683
+	{
684
+		return self::ee_addon_version_history_option_prefix . $this->name();
685
+	}
686
+
687
+
688
+	/**
689
+	 * Gets the wp option which stores the activation history for this addon
690
+	 *
691
+	 * @return array
692
+	 */
693
+	public function get_activation_history()
694
+	{
695
+		return get_option($this->get_activation_history_option_name(), null);
696
+	}
697
+
698
+
699
+	/**
700
+	 * @param string $config_section
701
+	 */
702
+	public function set_config_section($config_section = '')
703
+	{
704
+		$this->_config_section = ! empty($config_section) ? $config_section : 'addons';
705
+	}
706
+
707
+	/**
708
+	 * Sets the filepath to the main plugin file
709
+	 *
710
+	 * @param string $filepath
711
+	 */
712
+	public function set_main_plugin_file($filepath)
713
+	{
714
+		$this->_main_plugin_file = $filepath;
715
+	}
716
+
717
+	/**
718
+	 * gets the filepath to teh main file
719
+	 *
720
+	 * @return string
721
+	 */
722
+	public function get_main_plugin_file()
723
+	{
724
+		return $this->_main_plugin_file;
725
+	}
726
+
727
+	/**
728
+	 * Gets the filename (no path) of the main file (the main file loaded
729
+	 * by WP)
730
+	 *
731
+	 * @return string
732
+	 */
733
+	public function get_main_plugin_file_basename()
734
+	{
735
+		return plugin_basename($this->get_main_plugin_file());
736
+	}
737
+
738
+	/**
739
+	 * Gets the folder name which contains the main plugin file
740
+	 *
741
+	 * @return string
742
+	 */
743
+	public function get_main_plugin_file_dirname()
744
+	{
745
+		return dirname($this->get_main_plugin_file());
746
+	}
747
+
748
+
749
+	/**
750
+	 * sets hooks used in the admin
751
+	 *
752
+	 * @return void
753
+	 */
754
+	public function admin_init()
755
+	{
756
+		// is admin and not in M-Mode ?
757
+		if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
758
+			add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
759
+			add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
760
+		}
761
+	}
762
+
763
+
764
+	/**
765
+	 * plugin_actions
766
+	 * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
767
+	 *
768
+	 * @param $links
769
+	 * @param $file
770
+	 * @return array
771
+	 */
772
+	public function plugin_action_links($links, $file)
773
+	{
774
+		if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
775
+			// before other links
776
+			array_unshift(
777
+				$links,
778
+				'<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
779
+				. esc_html__('Settings', 'event_espresso')
780
+				. '</a>'
781
+			);
782
+		}
783
+		return $links;
784
+	}
785
+
786
+
787
+	/**
788
+	 * after_plugin_row
789
+	 * Add additional content to the plugins page plugin row
790
+	 * Inserts another row
791
+	 *
792
+	 * @param $plugin_file
793
+	 * @param $plugin_data
794
+	 * @param $status
795
+	 * @return void
796
+	 */
797
+	public function after_plugin_row($plugin_file, $plugin_data, $status)
798
+	{
799
+		$after_plugin_row = '';
800
+		$plugins_page_row = $this->get_plugins_page_row();
801
+		if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
802
+			$class = $status ? 'active' : 'inactive';
803
+			$link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
804
+			$link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
805
+			$description = isset($plugins_page_row['description'])
806
+				? $plugins_page_row['description']
807
+				: '';
808
+			if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
809
+				$after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
810
+				$after_plugin_row .= '<th class="check-column" scope="row"></th>';
811
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
812
+				$after_plugin_row .= '<style>
813 813
 .ee-button,
814 814
 .ee-button:active,
815 815
 .ee-button:visited {
@@ -846,64 +846,64 @@  discard block
 block discarded – undo
846 846
 }
847 847
 .ee-button:active { top:0; }
848 848
 </style>';
849
-                $after_plugin_row .= '
849
+				$after_plugin_row .= '
850 850
 <p class="ee-addon-upsell-info-dv">
851 851
 	<a class="ee-button" href="' . $link_url . '">'
852
-                                     . $link_text
853
-                                     . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
854
-                                     . '</a>
852
+									 . $link_text
853
+									 . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
854
+									 . '</a>
855 855
 </p>';
856
-                $after_plugin_row .= '</td>';
857
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
858
-                $after_plugin_row .= $description;
859
-                $after_plugin_row .= '</td>';
860
-                $after_plugin_row .= '</tr>';
861
-            } else {
862
-                $after_plugin_row .= $description;
863
-            }
864
-        }
865
-
866
-        echo $after_plugin_row;
867
-    }
868
-
869
-
870
-    /**
871
-     * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
872
-     * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
873
-     * for back compat reasons.
874
-     *
875
-     * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
876
-     *
877
-     * It is recommended, if client code is `de-registering` an add-on, then do it on the
878
-     * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
879
-     * callback does not get run/set in that request.
880
-     *
881
-     * Also, keep in mind that if a registered add-on happens to be deactivated via
882
-     * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
883
-     * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
884
-     * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
885
-     * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
886
-     * to call `parent::deactivation`.
887
-     *
888
-     * @since 4.9.26
889
-     */
890
-    public function after_registration()
891
-    {
892
-        // cricket chirp... cricket chirp...
893
-    }
894
-
895
-    /**
896
-     * @return string
897
-     */
898
-    public function getPueSlug()
899
-    {
900
-        return $this->pue_slug;
901
-    }
902
-    /**
903
-     * @param string $pue_slug
904
-     */
905
-    public function setPueSlug($pue_slug)
906
-    {
907
-        $this->pue_slug = $pue_slug;
908
-    }
856
+				$after_plugin_row .= '</td>';
857
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
858
+				$after_plugin_row .= $description;
859
+				$after_plugin_row .= '</td>';
860
+				$after_plugin_row .= '</tr>';
861
+			} else {
862
+				$after_plugin_row .= $description;
863
+			}
864
+		}
865
+
866
+		echo $after_plugin_row;
867
+	}
868
+
869
+
870
+	/**
871
+	 * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
872
+	 * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
873
+	 * for back compat reasons.
874
+	 *
875
+	 * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
876
+	 *
877
+	 * It is recommended, if client code is `de-registering` an add-on, then do it on the
878
+	 * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
879
+	 * callback does not get run/set in that request.
880
+	 *
881
+	 * Also, keep in mind that if a registered add-on happens to be deactivated via
882
+	 * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
883
+	 * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
884
+	 * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
885
+	 * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
886
+	 * to call `parent::deactivation`.
887
+	 *
888
+	 * @since 4.9.26
889
+	 */
890
+	public function after_registration()
891
+	{
892
+		// cricket chirp... cricket chirp...
893
+	}
894
+
895
+	/**
896
+	 * @return string
897
+	 */
898
+	public function getPueSlug()
899
+	{
900
+		return $this->pue_slug;
901
+	}
902
+	/**
903
+	 * @param string $pue_slug
904
+	 */
905
+	public function setPueSlug($pue_slug)
906
+	{
907
+		$this->pue_slug = $pue_slug;
908
+	}
909 909
 }
Please login to merge, or discard this patch.