Completed
Branch BUG/fix-table-exists-query (bbef99)
by
unknown
02:41 queued 26s
created
core/domain/services/custom_post_types/RewriteRules.php 2 patches
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -13,35 +13,35 @@
 block discarded – undo
13 13
 class RewriteRules
14 14
 {
15 15
 
16
-    const OPTION_KEY_FLUSH_REWRITE_RULES = 'ee_flush_rewrite_rules';
16
+	const OPTION_KEY_FLUSH_REWRITE_RULES = 'ee_flush_rewrite_rules';
17 17
 
18 18
 
19
-    /**
20
-     * This will flush rewrite rules on demand.  This actually gets called around wp init priority level 100.
21
-     *
22
-     * @return void
23
-     */
24
-    public function flush()
25
-    {
26
-        update_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, true);
27
-    }
19
+	/**
20
+	 * This will flush rewrite rules on demand.  This actually gets called around wp init priority level 100.
21
+	 *
22
+	 * @return void
23
+	 */
24
+	public function flush()
25
+	{
26
+		update_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, true);
27
+	}
28 28
 
29 29
 
30
-    /**
31
-     * This will flush rewrite rules on demand.  This actually gets called around wp init priority level 100.
32
-     *
33
-     * @return void
34
-     */
35
-    public function flushRewriteRules()
36
-    {
37
-        if (get_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, true)) {
38
-            add_action(
39
-                'shutdown',
40
-                static function () {
41
-                    flush_rewrite_rules();
42
-                    update_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, false);
43
-                }
44
-            );
45
-        }
46
-    }
30
+	/**
31
+	 * This will flush rewrite rules on demand.  This actually gets called around wp init priority level 100.
32
+	 *
33
+	 * @return void
34
+	 */
35
+	public function flushRewriteRules()
36
+	{
37
+		if (get_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, true)) {
38
+			add_action(
39
+				'shutdown',
40
+				static function () {
41
+					flush_rewrite_rules();
42
+					update_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, false);
43
+				}
44
+			);
45
+		}
46
+	}
47 47
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -37,7 +37,7 @@
 block discarded – undo
37 37
         if (get_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, true)) {
38 38
             add_action(
39 39
                 'shutdown',
40
-                static function () {
40
+                static function() {
41 41
                     flush_rewrite_rules();
42 42
                     update_option(RewriteRules::OPTION_KEY_FLUSH_REWRITE_RULES, false);
43 43
                 }
Please login to merge, or discard this patch.
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/libraries/plugin_api/EE_Register_Addon.lib.php 2 patches
Indentation   +1233 added lines, -1233 removed lines patch added patch discarded remove patch
@@ -22,1237 +22,1237 @@
 block discarded – undo
22 22
 class EE_Register_Addon implements EEI_Plugin_API
23 23
 {
24 24
 
25
-    /**
26
-     * possibly truncated version of the EE core version string
27
-     *
28
-     * @var string
29
-     */
30
-    protected static $_core_version = '';
31
-
32
-    /**
33
-     * Holds values for registered addons
34
-     *
35
-     * @var array
36
-     */
37
-    protected static $_settings = array();
38
-
39
-    /**
40
-     * @var  array $_incompatible_addons keys are addon SLUGS
41
-     * (first argument passed to EE_Register_Addon::register()), keys are
42
-     * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004).
43
-     * Generally this should be used sparingly, as we don't want to muddle up
44
-     * EE core with knowledge of ALL the addons out there.
45
-     * If you want NO versions of an addon to run with a certain version of core,
46
-     * it's usually best to define the addon's "min_core_version" as part of its call
47
-     * to EE_Register_Addon::register(), rather than using this array with a super high value for its
48
-     * minimum plugin version.
49
-     * @access    protected
50
-     */
51
-    protected static $_incompatible_addons = array(
52
-        'Multi_Event_Registration' => '2.0.11.rc.002',
53
-        'Promotions'               => '1.0.0.rc.084',
54
-    );
55
-
56
-
57
-    /**
58
-     * We should always be comparing core to a version like '4.3.0.rc.000',
59
-     * not just '4.3.0'.
60
-     * So if the addon developer doesn't provide that full version string,
61
-     * fill in the blanks for them
62
-     *
63
-     * @param string $min_core_version
64
-     * @return string always like '4.3.0.rc.000'
65
-     */
66
-    protected static function _effective_version($min_core_version)
67
-    {
68
-        // versions: 4 . 3 . 1 . p . 123
69
-        // offsets:    0 . 1 . 2 . 3 . 4
70
-        $version_parts = explode('.', $min_core_version);
71
-        // check they specified the micro version (after 2nd period)
72
-        if (! isset($version_parts[2])) {
73
-            $version_parts[2] = '0';
74
-        }
75
-        // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76
-        // soon we can assume that's 'rc', but this current version is 'alpha'
77
-        if (! isset($version_parts[3])) {
78
-            $version_parts[3] = 'dev';
79
-        }
80
-        if (! isset($version_parts[4])) {
81
-            $version_parts[4] = '000';
82
-        }
83
-        return implode('.', $version_parts);
84
-    }
85
-
86
-
87
-    /**
88
-     * Returns whether or not the min core version requirement of the addon is met
89
-     *
90
-     * @param string $min_core_version    the minimum core version required by the addon
91
-     * @param string $actual_core_version the actual core version, optional
92
-     * @return boolean
93
-     */
94
-    public static function _meets_min_core_version_requirement(
95
-        $min_core_version,
96
-        $actual_core_version = EVENT_ESPRESSO_VERSION
97
-    ) {
98
-        return version_compare(
99
-            self::_effective_version($actual_core_version),
100
-            self::_effective_version($min_core_version),
101
-            '>='
102
-        );
103
-    }
104
-
105
-
106
-    /**
107
-     * Method for registering new EE_Addons.
108
-     * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE
109
-     * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it
110
-     * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon
111
-     * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after
112
-     * 'activate_plugin', it registers the addon still, but its components are not registered
113
-     * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do
114
-     * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns
115
-     * (so that we can detect that the addon has activated on the subsequent request)
116
-     *
117
-     * @since    4.3.0
118
-     * @param string                  $addon_name                       [Required] the EE_Addon's name.
119
-     * @param  array                  $setup_args                       {
120
-     *                                                                  An array of arguments provided for registering
121
-     *                                                                  the message type.
122
-     * @type  string                  $class_name                       the addon's main file name.
123
-     *                                                                  If left blank, generated from the addon name,
124
-     *                                                                  changes something like "calendar" to
125
-     *                                                                  "EE_Calendar"
126
-     * @type string                   $min_core_version                 the minimum version of EE Core that the
127
-     *                                                                  addon will work with. eg "4.8.1.rc.084"
128
-     * @type string                   $version                          the "software" version for the addon. eg
129
-     *                                                                  "1.0.0.p" for a first stable release, or
130
-     *                                                                  "1.0.0.rc.043" for a version in progress
131
-     * @type string                   $main_file_path                   the full server path to the main file
132
-     *                                                                  loaded directly by WP
133
-     * @type DomainInterface $domain                                    child class of
134
-     *                                                                  EventEspresso\core\domain\DomainBase
135
-     * @type string                   $domain_fqcn                      Fully Qualified Class Name
136
-     *                                                                  for the addon's Domain class
137
-     *                                                                  (see EventEspresso\core\domain\Domain)
138
-     * @type string                   $admin_path                       full server path to the folder where the
139
-     *                                                                  addon\'s admin files reside
140
-     * @type string                   $admin_callback                   a method to be called when the EE Admin is
141
-     *                                                                  first invoked, can be used for hooking into
142
-     *                                                                  any admin page
143
-     * @type string                   $config_section                   the section name for this addon's
144
-     *                                                                  configuration settings section
145
-     *                                                                  (defaults to "addons")
146
-     * @type string                   $config_class                     the class name for this addon's
147
-     *                                                                  configuration settings object
148
-     * @type string                   $config_name                      the class name for this addon's
149
-     *                                                                  configuration settings object
150
-     * @type string                   $autoloader_paths                 [Required] an array of class names and the full
151
-     *                                                                  server paths to those files.
152
-     * @type string                   $autoloader_folders               an array of  "full server paths" for any
153
-     *                                                                  folders containing classes that might be
154
-     *                                                                  invoked by the addon
155
-     * @type string                   $dms_paths                        [Required] an array of full server paths to
156
-     *                                                                  folders that contain data migration scripts.
157
-     *                                                                  The key should be the EE_Addon class name that
158
-     *                                                                  this set of data migration scripts belongs to.
159
-     *                                                                  If the EE_Addon class is namespaced, then this
160
-     *                                                                  needs to be the Fully Qualified Class Name
161
-     * @type string                   $module_paths                     an array of full server paths to any
162
-     *                                                                  EED_Modules used by the addon
163
-     * @type string                   $shortcode_paths                  an array of full server paths to folders
164
-     *                                                                  that contain EES_Shortcodes
165
-     * @type string                   $widget_paths                     an array of full server paths to folders
166
-     *                                                                  that contain WP_Widgets
167
-     * @type string                   $pue_options
168
-     * @type array                    $capabilities                     an array indexed by role name
169
-     *                                                                  (i.e administrator,author ) and the values
170
-     *                                                                  are an array of caps to add to the role.
171
-     *                                                                  'administrator' => array(
172
-     *                                                                  'read_addon',
173
-     *                                                                  'edit_addon',
174
-     *                                                                  etc.
175
-     *                                                                  ).
176
-     * @type EE_Meta_Capability_Map[] $capability_maps                  an array of EE_Meta_Capability_Map object
177
-     *                                                                  for any addons that need to register any
178
-     *                                                                  special meta mapped capabilities.  Should
179
-     *                                                                  be indexed where the key is the
180
-     *                                                                  EE_Meta_Capability_Map class name and the
181
-     *                                                                  values are the arguments sent to the class.
182
-     * @type array                    $model_paths                      array of folders containing DB models
183
-     * @see      EE_Register_Model
184
-     * @type array                    $class_paths                      array of folders containing DB classes
185
-     * @see      EE_Register_Model
186
-     * @type array                    $model_extension_paths            array of folders containing DB model
187
-     *                                                                  extensions
188
-     * @see      EE_Register_Model_Extension
189
-     * @type array                    $class_extension_paths            array of folders containing DB class
190
-     *                                                                  extensions
191
-     * @see      EE_Register_Model_Extension
192
-     * @type array message_types {
193
-     *                                                                  An array of message types with the key as
194
-     *                                                                  the message type name and the values as
195
-     *                                                                  below:
196
-     * @type string                   $mtfilename                       [Required] The filename of the message type
197
-     *                                                                  being registered. This will be the main
198
-     *                                                                  EE_{Message Type Name}_message_type class.
199
-     *                                                                  for example:
200
-     *                                                                  EE_Declined_Registration_message_type.class.php
201
-     * @type array                    $autoloadpaths                    [Required] An array of paths to add to the
202
-     *                                                                  messages autoloader for the new message type.
203
-     * @type array                    $messengers_to_activate_with      An array of messengers that this message
204
-     *                                                                  type should activate with. Each value in
205
-     *                                                                  the
206
-     *                                                                  array
207
-     *                                                                  should match the name property of a
208
-     *                                                                  EE_messenger. Optional.
209
-     * @type array                    $messengers_to_validate_with      An array of messengers that this message
210
-     *                                                                  type should validate with. Each value in
211
-     *                                                                  the
212
-     *                                                                  array
213
-     *                                                                  should match the name property of an
214
-     *                                                                  EE_messenger.
215
-     *                                                                  Optional.
216
-     *                                                                  }
217
-     * @type array                    $custom_post_types
218
-     * @type array                    $custom_taxonomies
219
-     * @type array                    $payment_method_paths             each element is the folder containing the
220
-     *                                                                  EE_PMT_Base child class
221
-     *                                                                  (eg,
222
-     *                                                                  '/wp-content/plugins/my_plugin/Payomatic/'
223
-     *                                                                  which contains the files
224
-     *                                                                  EE_PMT_Payomatic.pm.php)
225
-     * @type array                    $default_terms
226
-     * @type array                    $namespace                        {
227
-     *                                                                  An array with two items for registering the
228
-     *                                                                  addon's namespace. (If, for some reason, you
229
-     *                                                                  require additional namespaces,
230
-     *                                                                  use
231
-     *                                                                  EventEspresso\core\Psr4Autoloader::addNamespace()
232
-     *                                                                  directly)
233
-     * @see      EventEspresso\core\Psr4Autoloader::addNamespace()
234
-     * @type string                   $FQNS                             the namespace prefix
235
-     * @type string                   $DIR                              a base directory for class files in the
236
-     *                                                                  namespace.
237
-     *                                                                  }
238
-     *                                                                  }
239
-     * @type string                   $privacy_policies                 FQNSs (namespaces, each of which contains only
240
-     *                                                                  privacy policy classes) or FQCNs (specific
241
-     *                                                                  classnames of privacy policy classes)
242
-     * @type string                   $personal_data_exporters          FQNSs (namespaces, each of which contains only
243
-     *                                                                  privacy policy classes) or FQCNs (specific
244
-     *                                                                  classnames of privacy policy classes)
245
-     * @type string                   $personal_data_erasers            FQNSs (namespaces, each of which contains only
246
-     *                                                                  privacy policy classes) or FQCNs (specific
247
-     *                                                                  classnames of privacy policy classes)
248
-     * @return void
249
-     * @throws DomainException
250
-     * @throws EE_Error
251
-     * @throws InvalidArgumentException
252
-     * @throws InvalidDataTypeException
253
-     * @throws InvalidInterfaceException
254
-     */
255
-    public static function register($addon_name = '', array $setup_args = array())
256
-    {
257
-        // required fields MUST be present, so let's make sure they are.
258
-        EE_Register_Addon::_verify_parameters($addon_name, $setup_args);
259
-        // get class name for addon
260
-        $class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args);
261
-        // setup $_settings array from incoming values.
262
-        $addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args);
263
-        // setup PUE
264
-        EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
265
-        // does this addon work with this version of core or WordPress ?
266
-        // does this addon work with this version of core or WordPress ?
267
-        if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268
-            return;
269
-        }
270
-        // register namespaces
271
-        EE_Register_Addon::_setup_namespaces($addon_settings);
272
-        // check if this is an activation request
273
-        if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) {
274
-            // dont bother setting up the rest of the addon atm
275
-            return;
276
-        }
277
-        // we need cars
278
-        EE_Register_Addon::_setup_autoloaders($addon_name);
279
-        // register new models and extensions
280
-        EE_Register_Addon::_register_models_and_extensions($addon_name);
281
-        // setup DMS
282
-        EE_Register_Addon::_register_data_migration_scripts($addon_name);
283
-        // if config_class is present let's register config.
284
-        EE_Register_Addon::_register_config($addon_name);
285
-        // register admin pages
286
-        EE_Register_Addon::_register_admin_pages($addon_name);
287
-        // add to list of modules to be registered
288
-        EE_Register_Addon::_register_modules($addon_name);
289
-        // add to list of shortcodes to be registered
290
-        EE_Register_Addon::_register_shortcodes($addon_name);
291
-        // add to list of widgets to be registered
292
-        EE_Register_Addon::_register_widgets($addon_name);
293
-        // register capability related stuff.
294
-        EE_Register_Addon::_register_capabilities($addon_name);
295
-        // any message type to register?
296
-        EE_Register_Addon::_register_message_types($addon_name);
297
-        // any custom post type/ custom capabilities or default terms to register
298
-        EE_Register_Addon::_register_custom_post_types($addon_name);
299
-        // and any payment methods
300
-        EE_Register_Addon::_register_payment_methods($addon_name);
301
-        // and privacy policy generators
302
-        EE_Register_Addon::registerPrivacyPolicies($addon_name);
303
-        // and privacy policy generators
304
-        EE_Register_Addon::registerPersonalDataExporters($addon_name);
305
-        // and privacy policy generators
306
-        EE_Register_Addon::registerPersonalDataErasers($addon_name);
307
-        // load and instantiate main addon class
308
-        $addon = EE_Register_Addon::_load_and_init_addon_class($addon_name);
309
-        // delay calling after_registration hook on each addon until after all add-ons have been registered.
310
-        add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999);
311
-    }
312
-
313
-
314
-    /**
315
-     * @param string $addon_name
316
-     * @param array  $setup_args
317
-     * @return void
318
-     * @throws EE_Error
319
-     */
320
-    private static function _verify_parameters($addon_name, array $setup_args)
321
-    {
322
-        // required fields MUST be present, so let's make sure they are.
323
-        if (empty($addon_name) || ! is_array($setup_args)) {
324
-            throw new EE_Error(
325
-                __(
326
-                    'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.',
327
-                    'event_espresso'
328
-                )
329
-            );
330
-        }
331
-        if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332
-            throw new EE_Error(
333
-                sprintf(
334
-                    __(
335
-                        'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s',
336
-                        'event_espresso'
337
-                    ),
338
-                    implode(',', array_keys($setup_args))
339
-                )
340
-            );
341
-        }
342
-        // check that addon has not already been registered with that name
343
-        if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
344
-            throw new EE_Error(
345
-                sprintf(
346
-                    __(
347
-                        'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.',
348
-                        'event_espresso'
349
-                    ),
350
-                    $addon_name
351
-                )
352
-            );
353
-        }
354
-    }
355
-
356
-
357
-    /**
358
-     * @param string $addon_name
359
-     * @param array  $setup_args
360
-     * @return string
361
-     */
362
-    private static function _parse_class_name($addon_name, array $setup_args)
363
-    {
364
-        if (empty($setup_args['class_name'])) {
365
-            // generate one by first separating name with spaces
366
-            $class_name = str_replace(array('-', '_'), ' ', trim($addon_name));
367
-            // capitalize, then replace spaces with underscores
368
-            $class_name = str_replace(' ', '_', ucwords($class_name));
369
-        } else {
370
-            $class_name = $setup_args['class_name'];
371
-        }
372
-        // check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373
-        return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374
-            ? $class_name
375
-            : 'EE_' . $class_name;
376
-    }
377
-
378
-
379
-    /**
380
-     * @param string $class_name
381
-     * @param array  $setup_args
382
-     * @return array
383
-     */
384
-    private static function _get_addon_settings($class_name, array $setup_args)
385
-    {
386
-        // setup $_settings array from incoming values.
387
-        $addon_settings = array(
388
-            // generated from the addon name, changes something like "calendar" to "EE_Calendar"
389
-            'class_name'            => $class_name,
390
-            // the addon slug for use in URLs, etc
391
-            'plugin_slug'           => isset($setup_args['plugin_slug'])
392
-                ? (string) $setup_args['plugin_slug']
393
-                : '',
394
-            // page slug to be used when generating the "Settings" link on the WP plugin page
395
-            'plugin_action_slug'    => isset($setup_args['plugin_action_slug'])
396
-                ? (string) $setup_args['plugin_action_slug']
397
-                : '',
398
-            // the "software" version for the addon
399
-            'version'               => isset($setup_args['version'])
400
-                ? (string) $setup_args['version']
401
-                : '',
402
-            // the minimum version of EE Core that the addon will work with
403
-            'min_core_version'      => isset($setup_args['min_core_version'])
404
-                ? (string) $setup_args['min_core_version']
405
-                : '',
406
-            // the minimum version of WordPress that the addon will work with
407
-            'min_wp_version'        => isset($setup_args['min_wp_version'])
408
-                ? (string) $setup_args['min_wp_version']
409
-                : EE_MIN_WP_VER_REQUIRED,
410
-            // full server path to main file (file loaded directly by WP)
411
-            'main_file_path'        => isset($setup_args['main_file_path'])
412
-                ? (string) $setup_args['main_file_path']
413
-                : '',
414
-            // instance of \EventEspresso\core\domain\DomainInterface
415
-            'domain'                => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface
416
-                ? $setup_args['domain']
417
-                : null,
418
-            // Fully Qualified Class Name for the addon's Domain class
419
-            'domain_fqcn'           => isset($setup_args['domain_fqcn'])
420
-                ? (string) $setup_args['domain_fqcn']
421
-                : '',
422
-            // path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages
423
-            'admin_path'            => isset($setup_args['admin_path'])
424
-                ? (string) $setup_args['admin_path'] : '',
425
-            // a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page
426
-            'admin_callback'        => isset($setup_args['admin_callback'])
427
-                ? (string) $setup_args['admin_callback']
428
-                : '',
429
-            // the section name for this addon's configuration settings section (defaults to "addons")
430
-            'config_section'        => isset($setup_args['config_section'])
431
-                ? (string) $setup_args['config_section']
432
-                : 'addons',
433
-            // the class name for this addon's configuration settings object
434
-            'config_class'          => isset($setup_args['config_class'])
435
-                ? (string) $setup_args['config_class'] : '',
436
-            // the name given to the config for this addons' configuration settings object (optional)
437
-            'config_name'           => isset($setup_args['config_name'])
438
-                ? (string) $setup_args['config_name'] : '',
439
-            // an array of "class names" => "full server paths" for any classes that might be invoked by the addon
440
-            'autoloader_paths'      => isset($setup_args['autoloader_paths'])
441
-                ? (array) $setup_args['autoloader_paths']
442
-                : array(),
443
-            // an array of  "full server paths" for any folders containing classes that might be invoked by the addon
444
-            'autoloader_folders'    => isset($setup_args['autoloader_folders'])
445
-                ? (array) $setup_args['autoloader_folders']
446
-                : array(),
447
-            // array of full server paths to any EE_DMS data migration scripts used by the addon.
448
-            // The key should be the EE_Addon class name that this set of data migration scripts belongs to.
449
-            // If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name
450
-            'dms_paths'             => isset($setup_args['dms_paths'])
451
-                ? (array) $setup_args['dms_paths']
452
-                : array(),
453
-            // array of full server paths to any EED_Modules used by the addon
454
-            'module_paths'          => isset($setup_args['module_paths'])
455
-                ? (array) $setup_args['module_paths']
456
-                : array(),
457
-            // array of full server paths to any EES_Shortcodes used by the addon
458
-            'shortcode_paths'       => isset($setup_args['shortcode_paths'])
459
-                ? (array) $setup_args['shortcode_paths']
460
-                : array(),
461
-            'shortcode_fqcns'       => isset($setup_args['shortcode_fqcns'])
462
-                ? (array) $setup_args['shortcode_fqcns']
463
-                : array(),
464
-            // array of full server paths to any WP_Widgets used by the addon
465
-            'widget_paths'          => isset($setup_args['widget_paths'])
466
-                ? (array) $setup_args['widget_paths']
467
-                : array(),
468
-            // array of PUE options used by the addon
469
-            'pue_options'           => isset($setup_args['pue_options'])
470
-                ? (array) $setup_args['pue_options']
471
-                : array(),
472
-            'message_types'         => isset($setup_args['message_types'])
473
-                ? (array) $setup_args['message_types']
474
-                : array(),
475
-            'capabilities'          => isset($setup_args['capabilities'])
476
-                ? (array) $setup_args['capabilities']
477
-                : array(),
478
-            'capability_maps'       => isset($setup_args['capability_maps'])
479
-                ? (array) $setup_args['capability_maps']
480
-                : array(),
481
-            'model_paths'           => isset($setup_args['model_paths'])
482
-                ? (array) $setup_args['model_paths']
483
-                : array(),
484
-            'class_paths'           => isset($setup_args['class_paths'])
485
-                ? (array) $setup_args['class_paths']
486
-                : array(),
487
-            'model_extension_paths' => isset($setup_args['model_extension_paths'])
488
-                ? (array) $setup_args['model_extension_paths']
489
-                : array(),
490
-            'class_extension_paths' => isset($setup_args['class_extension_paths'])
491
-                ? (array) $setup_args['class_extension_paths']
492
-                : array(),
493
-            'custom_post_types'     => isset($setup_args['custom_post_types'])
494
-                ? (array) $setup_args['custom_post_types']
495
-                : array(),
496
-            'custom_taxonomies'     => isset($setup_args['custom_taxonomies'])
497
-                ? (array) $setup_args['custom_taxonomies']
498
-                : array(),
499
-            'payment_method_paths'  => isset($setup_args['payment_method_paths'])
500
-                ? (array) $setup_args['payment_method_paths']
501
-                : array(),
502
-            'default_terms'         => isset($setup_args['default_terms'])
503
-                ? (array) $setup_args['default_terms']
504
-                : array(),
505
-            // if not empty, inserts a new table row after this plugin's row on the WP Plugins page
506
-            // that can be used for adding upgrading/marketing info
507
-            'plugins_page_row'      => isset($setup_args['plugins_page_row']) ? $setup_args['plugins_page_row'] : '',
508
-            'namespace'             => isset(
509
-                $setup_args['namespace']['FQNS'],
510
-                $setup_args['namespace']['DIR']
511
-            )
512
-                ? (array) $setup_args['namespace']
513
-                : array(),
514
-            'privacy_policies'      => isset($setup_args['privacy_policies'])
515
-                ? (array) $setup_args['privacy_policies']
516
-                : '',
517
-        );
518
-        // if plugin_action_slug is NOT set, but an admin page path IS set,
519
-        // then let's just use the plugin_slug since that will be used for linking to the admin page
520
-        $addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug'])
521
-                                                && ! empty($addon_settings['admin_path'])
522
-            ? $addon_settings['plugin_slug']
523
-            : $addon_settings['plugin_action_slug'];
524
-        // full server path to main file (file loaded directly by WP)
525
-        $addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']);
526
-        return $addon_settings;
527
-    }
528
-
529
-
530
-    /**
531
-     * @param string $addon_name
532
-     * @param array  $addon_settings
533
-     * @return boolean
534
-     */
535
-    private static function _addon_is_compatible($addon_name, array $addon_settings)
536
-    {
537
-        global $wp_version;
538
-        $incompatibility_message = '';
539
-        // check whether this addon version is compatible with EE core
540
-        if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
541
-            && ! self::_meets_min_core_version_requirement(
542
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
543
-                $addon_settings['version']
544
-            )
545
-        ) {
546
-            $incompatibility_message = sprintf(
547
-                __(
548
-                    '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.',
549
-                    'event_espresso'
550
-                ),
551
-                $addon_name,
552
-                '<br />',
553
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
554
-                '<span style="font-weight: bold; color: #D54E21;">',
555
-                '</span><br />'
556
-            );
557
-        } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
558
-        ) {
559
-            $incompatibility_message = sprintf(
560
-                __(
561
-                    '%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".',
562
-                    'event_espresso'
563
-                ),
564
-                $addon_name,
565
-                self::_effective_version($addon_settings['min_core_version']),
566
-                self::_effective_version(espresso_version()),
567
-                '<br />',
568
-                '<span style="font-weight: bold; color: #D54E21;">',
569
-                '</span><br />'
570
-            );
571
-        } elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) {
572
-            $incompatibility_message = sprintf(
573
-                __(
574
-                    '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.',
575
-                    'event_espresso'
576
-                ),
577
-                $addon_name,
578
-                $addon_settings['min_wp_version'],
579
-                '<br />',
580
-                '<span style="font-weight: bold; color: #D54E21;">',
581
-                '</span><br />'
582
-            );
583
-        }
584
-        if (! empty($incompatibility_message)) {
585
-            // remove 'activate' from the REQUEST
586
-            // so WP doesn't erroneously tell the user the plugin activated fine when it didn't
587
-            unset($_GET['activate'], $_REQUEST['activate']);
588
-            if (current_user_can('activate_plugins')) {
589
-                // show an error message indicating the plugin didn't activate properly
590
-                EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__);
591
-            }
592
-            // BAIL FROM THE ADDON REGISTRATION PROCESS
593
-            return false;
594
-        }
595
-        // addon IS compatible
596
-        return true;
597
-    }
598
-
599
-
600
-    /**
601
-     * if plugin update engine is being used for auto-updates,
602
-     * then let's set that up now before going any further so that ALL addons can be updated
603
-     * (not needed if PUE is not being used)
604
-     *
605
-     * @param string $addon_name
606
-     * @param string $class_name
607
-     * @param array  $setup_args
608
-     * @return void
609
-     */
610
-    private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
611
-    {
612
-        if (! empty($setup_args['pue_options'])) {
613
-            self::$_settings[ $addon_name ]['pue_options'] = array(
614
-                'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
615
-                    ? (string) $setup_args['pue_options']['pue_plugin_slug']
616
-                    : 'espresso_' . strtolower($class_name),
617
-                'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
618
-                    ? (string) $setup_args['pue_options']['plugin_basename']
619
-                    : plugin_basename($setup_args['main_file_path']),
620
-                'checkPeriod'     => isset($setup_args['pue_options']['checkPeriod'])
621
-                    ? (string) $setup_args['pue_options']['checkPeriod']
622
-                    : '24',
623
-                'use_wp_update'   => isset($setup_args['pue_options']['use_wp_update'])
624
-                    ? (string) $setup_args['pue_options']['use_wp_update']
625
-                    : false,
626
-            );
627
-            add_action(
628
-                'AHEE__EE_System__brew_espresso__after_pue_init',
629
-                array('EE_Register_Addon', 'load_pue_update')
630
-            );
631
-        }
632
-    }
633
-
634
-
635
-    /**
636
-     * register namespaces right away before any other files or classes get loaded, but AFTER the version checks
637
-     *
638
-     * @param array $addon_settings
639
-     * @return void
640
-     */
641
-    private static function _setup_namespaces(array $addon_settings)
642
-    {
643
-        //
644
-        if (isset(
645
-            $addon_settings['namespace']['FQNS'],
646
-            $addon_settings['namespace']['DIR']
647
-        )) {
648
-            EE_Psr4AutoloaderInit::psr4_loader()->addNamespace(
649
-                $addon_settings['namespace']['FQNS'],
650
-                $addon_settings['namespace']['DIR']
651
-            );
652
-        }
653
-    }
654
-
655
-
656
-    /**
657
-     * @param string $addon_name
658
-     * @param array  $addon_settings
659
-     * @return bool
660
-     * @throws InvalidArgumentException
661
-     * @throws InvalidDataTypeException
662
-     * @throws InvalidInterfaceException
663
-     */
664
-    private static function _addon_activation($addon_name, array $addon_settings)
665
-    {
666
-        // this is an activation request
667
-        if (did_action('activate_plugin')) {
668
-            // to find if THIS is the addon that was activated, just check if we have already registered it or not
669
-            // (as the newly-activated addon wasn't around the first time addons were registered).
670
-            // Note: the presence of pue_options in the addon registration options will initialize the $_settings
671
-            // property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
672
-            if (! isset(self::$_settings[ $addon_name ])
673
-                || (isset(self::$_settings[ $addon_name ]) && ! isset(self::$_settings[ $addon_name ]['class_name']))
674
-            ) {
675
-                self::$_settings[ $addon_name ] = $addon_settings;
676
-                $addon = self::_load_and_init_addon_class($addon_name);
677
-                $addon->set_activation_indicator_option();
678
-                // dont bother setting up the rest of the addon.
679
-                // we know it was just activated and the request will end soon
680
-            }
681
-            return true;
682
-        }
683
-        // make sure this was called in the right place!
684
-        if (! did_action('AHEE__EE_System__load_espresso_addons')
685
-            || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
686
-        ) {
687
-            EE_Error::doing_it_wrong(
688
-                __METHOD__,
689
-                sprintf(
690
-                    __(
691
-                        'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.',
692
-                        'event_espresso'
693
-                    ),
694
-                    $addon_name
695
-                ),
696
-                '4.3.0'
697
-            );
698
-        }
699
-        // make sure addon settings are set correctly without overwriting anything existing
700
-        if (isset(self::$_settings[ $addon_name ])) {
701
-            self::$_settings[ $addon_name ] += $addon_settings;
702
-        } else {
703
-            self::$_settings[ $addon_name ] = $addon_settings;
704
-        }
705
-        return false;
706
-    }
707
-
708
-
709
-    /**
710
-     * @param string $addon_name
711
-     * @return void
712
-     * @throws EE_Error
713
-     */
714
-    private static function _setup_autoloaders($addon_name)
715
-    {
716
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
717
-            // setup autoloader for single file
718
-            EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
719
-        }
720
-        // setup autoloaders for folders
721
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
722
-            foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
723
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
724
-            }
725
-        }
726
-    }
727
-
728
-
729
-    /**
730
-     * register new models and extensions
731
-     *
732
-     * @param string $addon_name
733
-     * @return void
734
-     * @throws EE_Error
735
-     */
736
-    private static function _register_models_and_extensions($addon_name)
737
-    {
738
-        // register new models
739
-        if (! empty(self::$_settings[ $addon_name ]['model_paths'])
740
-            || ! empty(self::$_settings[ $addon_name ]['class_paths'])
741
-        ) {
742
-            EE_Register_Model::register(
743
-                $addon_name,
744
-                array(
745
-                    'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
746
-                    'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
747
-                )
748
-            );
749
-        }
750
-        // register model extensions
751
-        if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
752
-            || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
753
-        ) {
754
-            EE_Register_Model_Extensions::register(
755
-                $addon_name,
756
-                array(
757
-                    'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
758
-                    'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
759
-                )
760
-            );
761
-        }
762
-    }
763
-
764
-
765
-    /**
766
-     * @param string $addon_name
767
-     * @return void
768
-     * @throws EE_Error
769
-     */
770
-    private static function _register_data_migration_scripts($addon_name)
771
-    {
772
-        // setup DMS
773
-        if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
774
-            EE_Register_Data_Migration_Scripts::register(
775
-                $addon_name,
776
-                array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
777
-            );
778
-        }
779
-    }
780
-
781
-
782
-    /**
783
-     * @param string $addon_name
784
-     * @return void
785
-     * @throws EE_Error
786
-     */
787
-    private static function _register_config($addon_name)
788
-    {
789
-        // if config_class is present let's register config.
790
-        if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
791
-            EE_Register_Config::register(
792
-                self::$_settings[ $addon_name ]['config_class'],
793
-                array(
794
-                    'config_section' => self::$_settings[ $addon_name ]['config_section'],
795
-                    'config_name'    => self::$_settings[ $addon_name ]['config_name'],
796
-                )
797
-            );
798
-        }
799
-    }
800
-
801
-
802
-    /**
803
-     * @param string $addon_name
804
-     * @return void
805
-     * @throws EE_Error
806
-     */
807
-    private static function _register_admin_pages($addon_name)
808
-    {
809
-        if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
810
-            EE_Register_Admin_Page::register(
811
-                $addon_name,
812
-                array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
813
-            );
814
-        }
815
-    }
816
-
817
-
818
-    /**
819
-     * @param string $addon_name
820
-     * @return void
821
-     * @throws EE_Error
822
-     */
823
-    private static function _register_modules($addon_name)
824
-    {
825
-        if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
826
-            EE_Register_Module::register(
827
-                $addon_name,
828
-                array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
829
-            );
830
-        }
831
-    }
832
-
833
-
834
-    /**
835
-     * @param string $addon_name
836
-     * @return void
837
-     * @throws EE_Error
838
-     */
839
-    private static function _register_shortcodes($addon_name)
840
-    {
841
-        if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
842
-            || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
843
-        ) {
844
-            EE_Register_Shortcode::register(
845
-                $addon_name,
846
-                array(
847
-                    'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
848
-                        ? self::$_settings[ $addon_name ]['shortcode_paths'] : array(),
849
-                    'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
850
-                        ? self::$_settings[ $addon_name ]['shortcode_fqcns'] : array(),
851
-                )
852
-            );
853
-        }
854
-    }
855
-
856
-
857
-    /**
858
-     * @param string $addon_name
859
-     * @return void
860
-     * @throws EE_Error
861
-     */
862
-    private static function _register_widgets($addon_name)
863
-    {
864
-        if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
865
-            EE_Register_Widget::register(
866
-                $addon_name,
867
-                array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
868
-            );
869
-        }
870
-    }
871
-
872
-
873
-    /**
874
-     * @param string $addon_name
875
-     * @return void
876
-     * @throws EE_Error
877
-     */
878
-    private static function _register_capabilities($addon_name)
879
-    {
880
-        if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
881
-            EE_Register_Capabilities::register(
882
-                $addon_name,
883
-                array(
884
-                    'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
885
-                    'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
886
-                )
887
-            );
888
-        }
889
-    }
890
-
891
-
892
-    /**
893
-     * @param string $addon_name
894
-     * @return void
895
-     */
896
-    private static function _register_message_types($addon_name)
897
-    {
898
-        if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
899
-            add_action(
900
-                'EE_Brewing_Regular___messages_caf',
901
-                array('EE_Register_Addon', 'register_message_types')
902
-            );
903
-        }
904
-    }
905
-
906
-
907
-    /**
908
-     * @param string $addon_name
909
-     * @return void
910
-     * @throws EE_Error
911
-     */
912
-    private static function _register_custom_post_types($addon_name)
913
-    {
914
-        if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
915
-            || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
916
-        ) {
917
-            EE_Register_CPT::register(
918
-                $addon_name,
919
-                array(
920
-                    'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
921
-                    'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
922
-                    'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
923
-                )
924
-            );
925
-        }
926
-    }
927
-
928
-
929
-    /**
930
-     * @param string $addon_name
931
-     * @return void
932
-     * @throws InvalidArgumentException
933
-     * @throws InvalidInterfaceException
934
-     * @throws InvalidDataTypeException
935
-     * @throws DomainException
936
-     * @throws EE_Error
937
-     */
938
-    private static function _register_payment_methods($addon_name)
939
-    {
940
-        if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
941
-            EE_Register_Payment_Method::register(
942
-                $addon_name,
943
-                array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
944
-            );
945
-        }
946
-    }
947
-
948
-
949
-    /**
950
-     * @param string $addon_name
951
-     * @return void
952
-     * @throws InvalidArgumentException
953
-     * @throws InvalidInterfaceException
954
-     * @throws InvalidDataTypeException
955
-     * @throws DomainException
956
-     */
957
-    private static function registerPrivacyPolicies($addon_name)
958
-    {
959
-        if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
960
-            EE_Register_Privacy_Policy::register(
961
-                $addon_name,
962
-                self::$_settings[ $addon_name ]['privacy_policies']
963
-            );
964
-        }
965
-    }
966
-
967
-
968
-    /**
969
-     * @param string $addon_name
970
-     * @return void
971
-     */
972
-    private static function registerPersonalDataExporters($addon_name)
973
-    {
974
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
975
-            EE_Register_Personal_Data_Eraser::register(
976
-                $addon_name,
977
-                self::$_settings[ $addon_name ]['personal_data_exporters']
978
-            );
979
-        }
980
-    }
981
-
982
-
983
-    /**
984
-     * @param string $addon_name
985
-     * @return void
986
-     */
987
-    private static function registerPersonalDataErasers($addon_name)
988
-    {
989
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
990
-            EE_Register_Personal_Data_Eraser::register(
991
-                $addon_name,
992
-                self::$_settings[ $addon_name ]['personal_data_erasers']
993
-            );
994
-        }
995
-    }
996
-
997
-
998
-    /**
999
-     * Loads and instantiates the EE_Addon class and adds it onto the registry
1000
-     *
1001
-     * @param string $addon_name
1002
-     * @return EE_Addon
1003
-     * @throws InvalidArgumentException
1004
-     * @throws InvalidInterfaceException
1005
-     * @throws InvalidDataTypeException
1006
-     * @throws DomainException
1007
-     */
1008
-    private static function _load_and_init_addon_class($addon_name)
1009
-    {
1010
-        $addon_class = self::$_settings[ $addon_name ]['class_name'];
1011
-        $addon = LoaderFactory::getLoader()->getShared($addon_class, ['EE_Registry::create(addon)' => true]);
1012
-        // verify addon has been instantiated correctly
1013
-        if (! $addon instanceof $addon_class) {
1014
-            throw new DomainException(
1015
-                sprintf(
1016
-                    __(
1017
-                        'An attempt to register an EE_Addon named "%1$s" has failed because the "%2$s" class is either missing or invalid. The following was created instead: %3$s',
1018
-                        'event_espresso'
1019
-                    ),
1020
-                    $addon_name,
1021
-                    $addon_class,
1022
-                    print_r($addon, true)
1023
-                )
1024
-            );
1025
-        }
1026
-        // setter inject dep map if required
1027
-        if ($addon->dependencyMap() === null) {
1028
-            $addon->setDependencyMap(LoaderFactory::getLoader()->getShared('EE_Dependency_Map'));
1029
-        }
1030
-        // setter inject domain if required
1031
-        EE_Register_Addon::injectAddonDomain($addon_name, $addon);
1032
-
1033
-        $addon->set_name($addon_name);
1034
-        $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1035
-        $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1036
-        $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1037
-        $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1038
-        $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1039
-        $addon->set_version(self::$_settings[ $addon_name ]['version']);
1040
-        $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1041
-        $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1042
-        $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1043
-        $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1044
-        // setup the add-on's pue_slug if we have one.
1045
-        if (! empty(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug'])) {
1046
-            $addon->setPueSlug(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug']);
1047
-        }
1048
-        // unfortunately this can't be hooked in upon construction,
1049
-        // because we don't have the plugin's mainfile path upon construction.
1050
-        register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1051
-        // call any additional admin_callback functions during load_admin_controller hook
1052
-        if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1053
-            add_action(
1054
-                'AHEE__EE_System__load_controllers__load_admin_controllers',
1055
-                array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1056
-            );
1057
-        }
1058
-        return $addon;
1059
-    }
1060
-
1061
-
1062
-    /**
1063
-     * @param string   $addon_name
1064
-     * @param EE_Addon $addon
1065
-     * @since   $VID:$
1066
-     */
1067
-    private static function injectAddonDomain($addon_name, EE_Addon $addon)
1068
-    {
1069
-        if ($addon instanceof RequiresDomainInterface && $addon->domain() === null) {
1070
-            // using supplied Domain object
1071
-            $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1072
-                ? self::$_settings[ $addon_name ]['domain']
1073
-                : null;
1074
-            // or construct one using Domain FQCN
1075
-            if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1076
-                $domain = LoaderFactory::getLoader()->getShared(
1077
-                    self::$_settings[ $addon_name ]['domain_fqcn'],
1078
-                    [
1079
-                        new EventEspresso\core\domain\values\FilePath(
1080
-                            self::$_settings[ $addon_name ]['main_file_path']
1081
-                        ),
1082
-                        EventEspresso\core\domain\values\Version::fromString(
1083
-                            self::$_settings[ $addon_name ]['version']
1084
-                        ),
1085
-                    ]
1086
-                );
1087
-            }
1088
-            if ($domain instanceof DomainInterface) {
1089
-                $addon->setDomain($domain);
1090
-            }
1091
-        }
1092
-    }
1093
-
1094
-
1095
-    /**
1096
-     *    load_pue_update - Update notifications
1097
-     *
1098
-     * @return void
1099
-     * @throws InvalidArgumentException
1100
-     * @throws InvalidDataTypeException
1101
-     * @throws InvalidInterfaceException
1102
-     */
1103
-    public static function load_pue_update()
1104
-    {
1105
-        // load PUE client
1106
-        require_once EE_THIRD_PARTY . 'pue/pue-client.php';
1107
-        $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1108
-        // cycle thru settings
1109
-        foreach (self::$_settings as $settings) {
1110
-            if (! empty($settings['pue_options'])) {
1111
-                // initiate the class and start the plugin update engine!
1112
-                new PluginUpdateEngineChecker(
1113
-                    // host file URL
1114
-                    $license_server,
1115
-                    // plugin slug(s)
1116
-                    array(
1117
-                        'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1118
-                        'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1119
-                    ),
1120
-                    // options
1121
-                    array(
1122
-                        'apikey'            => EE_Registry::instance()->NET_CFG->core->site_license_key,
1123
-                        'lang_domain'       => 'event_espresso',
1124
-                        'checkPeriod'       => $settings['pue_options']['checkPeriod'],
1125
-                        'option_key'        => 'ee_site_license_key',
1126
-                        'options_page_slug' => 'event_espresso',
1127
-                        'plugin_basename'   => $settings['pue_options']['plugin_basename'],
1128
-                        // if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP
1129
-                        'use_wp_update'     => $settings['pue_options']['use_wp_update'],
1130
-                    )
1131
-                );
1132
-            }
1133
-        }
1134
-    }
1135
-
1136
-
1137
-    /**
1138
-     * Callback for EE_Brewing_Regular__messages_caf hook used to register message types.
1139
-     *
1140
-     * @since 4.4.0
1141
-     * @return void
1142
-     * @throws EE_Error
1143
-     */
1144
-    public static function register_message_types()
1145
-    {
1146
-        foreach (self::$_settings as $settings) {
1147
-            if (! empty($settings['message_types'])) {
1148
-                foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1149
-                    EE_Register_Message_Type::register($message_type, $message_type_settings);
1150
-                }
1151
-            }
1152
-        }
1153
-    }
1154
-
1155
-
1156
-    /**
1157
-     * This deregisters an addon that was previously registered with a specific addon_name.
1158
-     *
1159
-     * @param string $addon_name the name for the addon that was previously registered
1160
-     * @throws DomainException
1161
-     * @throws InvalidArgumentException
1162
-     * @throws InvalidDataTypeException
1163
-     * @throws InvalidInterfaceException
1164
-     *@since    4.3.0
1165
-     */
1166
-    public static function deregister($addon_name = '')
1167
-    {
1168
-        if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1169
-            try {
1170
-                do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1171
-                $class_name = self::$_settings[ $addon_name ]['class_name'];
1172
-                if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1173
-                    // setup DMS
1174
-                    EE_Register_Data_Migration_Scripts::deregister($addon_name);
1175
-                }
1176
-                if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1177
-                    // register admin page
1178
-                    EE_Register_Admin_Page::deregister($addon_name);
1179
-                }
1180
-                if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1181
-                    // add to list of modules to be registered
1182
-                    EE_Register_Module::deregister($addon_name);
1183
-                }
1184
-                if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1185
-                    || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1186
-                ) {
1187
-                    // add to list of shortcodes to be registered
1188
-                    EE_Register_Shortcode::deregister($addon_name);
1189
-                }
1190
-                if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1191
-                    // if config_class present let's register config.
1192
-                    EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1193
-                }
1194
-                if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1195
-                    // add to list of widgets to be registered
1196
-                    EE_Register_Widget::deregister($addon_name);
1197
-                }
1198
-                if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1199
-                    || ! empty(self::$_settings[ $addon_name ]['class_paths'])
1200
-                ) {
1201
-                    // add to list of shortcodes to be registered
1202
-                    EE_Register_Model::deregister($addon_name);
1203
-                }
1204
-                if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1205
-                    || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1206
-                ) {
1207
-                    // add to list of shortcodes to be registered
1208
-                    EE_Register_Model_Extensions::deregister($addon_name);
1209
-                }
1210
-                if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1211
-                    foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1212
-                        EE_Register_Message_Type::deregister($message_type);
1213
-                    }
1214
-                }
1215
-                // deregister capabilities for addon
1216
-                if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1217
-                    || ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1218
-                ) {
1219
-                    EE_Register_Capabilities::deregister($addon_name);
1220
-                }
1221
-                // deregister custom_post_types for addon
1222
-                if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1223
-                    EE_Register_CPT::deregister($addon_name);
1224
-                }
1225
-                if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1226
-                    EE_Register_Payment_Method::deregister($addon_name);
1227
-                }
1228
-                $addon = EE_Registry::instance()->getAddon($class_name);
1229
-                if ($addon instanceof EE_Addon) {
1230
-                    remove_action(
1231
-                        'deactivate_' . $addon->get_main_plugin_file_basename(),
1232
-                        array($addon, 'deactivation')
1233
-                    );
1234
-                    remove_action(
1235
-                        'AHEE__EE_System__perform_activations_upgrades_and_migrations',
1236
-                        array($addon, 'initialize_db_if_no_migrations_required')
1237
-                    );
1238
-                    // remove `after_registration` call
1239
-                    remove_action(
1240
-                        'AHEE__EE_System__load_espresso_addons__complete',
1241
-                        array($addon, 'after_registration'),
1242
-                        999
1243
-                    );
1244
-                }
1245
-                EE_Registry::instance()->removeAddon($class_name);
1246
-            } catch (OutOfBoundsException $addon_not_yet_registered_exception) {
1247
-                // the add-on was not yet registered in the registry,
1248
-                // so RegistryContainer::__get() throws this exception.
1249
-                // also no need to worry about this or log it,
1250
-                // it's ok to deregister an add-on before its registered in the registry
1251
-            } catch (Exception $e) {
1252
-                new ExceptionLogger($e);
1253
-            }
1254
-            unset(self::$_settings[ $addon_name ]);
1255
-            do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1256
-        }
1257
-    }
25
+	/**
26
+	 * possibly truncated version of the EE core version string
27
+	 *
28
+	 * @var string
29
+	 */
30
+	protected static $_core_version = '';
31
+
32
+	/**
33
+	 * Holds values for registered addons
34
+	 *
35
+	 * @var array
36
+	 */
37
+	protected static $_settings = array();
38
+
39
+	/**
40
+	 * @var  array $_incompatible_addons keys are addon SLUGS
41
+	 * (first argument passed to EE_Register_Addon::register()), keys are
42
+	 * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004).
43
+	 * Generally this should be used sparingly, as we don't want to muddle up
44
+	 * EE core with knowledge of ALL the addons out there.
45
+	 * If you want NO versions of an addon to run with a certain version of core,
46
+	 * it's usually best to define the addon's "min_core_version" as part of its call
47
+	 * to EE_Register_Addon::register(), rather than using this array with a super high value for its
48
+	 * minimum plugin version.
49
+	 * @access    protected
50
+	 */
51
+	protected static $_incompatible_addons = array(
52
+		'Multi_Event_Registration' => '2.0.11.rc.002',
53
+		'Promotions'               => '1.0.0.rc.084',
54
+	);
55
+
56
+
57
+	/**
58
+	 * We should always be comparing core to a version like '4.3.0.rc.000',
59
+	 * not just '4.3.0'.
60
+	 * So if the addon developer doesn't provide that full version string,
61
+	 * fill in the blanks for them
62
+	 *
63
+	 * @param string $min_core_version
64
+	 * @return string always like '4.3.0.rc.000'
65
+	 */
66
+	protected static function _effective_version($min_core_version)
67
+	{
68
+		// versions: 4 . 3 . 1 . p . 123
69
+		// offsets:    0 . 1 . 2 . 3 . 4
70
+		$version_parts = explode('.', $min_core_version);
71
+		// check they specified the micro version (after 2nd period)
72
+		if (! isset($version_parts[2])) {
73
+			$version_parts[2] = '0';
74
+		}
75
+		// if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76
+		// soon we can assume that's 'rc', but this current version is 'alpha'
77
+		if (! isset($version_parts[3])) {
78
+			$version_parts[3] = 'dev';
79
+		}
80
+		if (! isset($version_parts[4])) {
81
+			$version_parts[4] = '000';
82
+		}
83
+		return implode('.', $version_parts);
84
+	}
85
+
86
+
87
+	/**
88
+	 * Returns whether or not the min core version requirement of the addon is met
89
+	 *
90
+	 * @param string $min_core_version    the minimum core version required by the addon
91
+	 * @param string $actual_core_version the actual core version, optional
92
+	 * @return boolean
93
+	 */
94
+	public static function _meets_min_core_version_requirement(
95
+		$min_core_version,
96
+		$actual_core_version = EVENT_ESPRESSO_VERSION
97
+	) {
98
+		return version_compare(
99
+			self::_effective_version($actual_core_version),
100
+			self::_effective_version($min_core_version),
101
+			'>='
102
+		);
103
+	}
104
+
105
+
106
+	/**
107
+	 * Method for registering new EE_Addons.
108
+	 * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE
109
+	 * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it
110
+	 * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon
111
+	 * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after
112
+	 * 'activate_plugin', it registers the addon still, but its components are not registered
113
+	 * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do
114
+	 * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns
115
+	 * (so that we can detect that the addon has activated on the subsequent request)
116
+	 *
117
+	 * @since    4.3.0
118
+	 * @param string                  $addon_name                       [Required] the EE_Addon's name.
119
+	 * @param  array                  $setup_args                       {
120
+	 *                                                                  An array of arguments provided for registering
121
+	 *                                                                  the message type.
122
+	 * @type  string                  $class_name                       the addon's main file name.
123
+	 *                                                                  If left blank, generated from the addon name,
124
+	 *                                                                  changes something like "calendar" to
125
+	 *                                                                  "EE_Calendar"
126
+	 * @type string                   $min_core_version                 the minimum version of EE Core that the
127
+	 *                                                                  addon will work with. eg "4.8.1.rc.084"
128
+	 * @type string                   $version                          the "software" version for the addon. eg
129
+	 *                                                                  "1.0.0.p" for a first stable release, or
130
+	 *                                                                  "1.0.0.rc.043" for a version in progress
131
+	 * @type string                   $main_file_path                   the full server path to the main file
132
+	 *                                                                  loaded directly by WP
133
+	 * @type DomainInterface $domain                                    child class of
134
+	 *                                                                  EventEspresso\core\domain\DomainBase
135
+	 * @type string                   $domain_fqcn                      Fully Qualified Class Name
136
+	 *                                                                  for the addon's Domain class
137
+	 *                                                                  (see EventEspresso\core\domain\Domain)
138
+	 * @type string                   $admin_path                       full server path to the folder where the
139
+	 *                                                                  addon\'s admin files reside
140
+	 * @type string                   $admin_callback                   a method to be called when the EE Admin is
141
+	 *                                                                  first invoked, can be used for hooking into
142
+	 *                                                                  any admin page
143
+	 * @type string                   $config_section                   the section name for this addon's
144
+	 *                                                                  configuration settings section
145
+	 *                                                                  (defaults to "addons")
146
+	 * @type string                   $config_class                     the class name for this addon's
147
+	 *                                                                  configuration settings object
148
+	 * @type string                   $config_name                      the class name for this addon's
149
+	 *                                                                  configuration settings object
150
+	 * @type string                   $autoloader_paths                 [Required] an array of class names and the full
151
+	 *                                                                  server paths to those files.
152
+	 * @type string                   $autoloader_folders               an array of  "full server paths" for any
153
+	 *                                                                  folders containing classes that might be
154
+	 *                                                                  invoked by the addon
155
+	 * @type string                   $dms_paths                        [Required] an array of full server paths to
156
+	 *                                                                  folders that contain data migration scripts.
157
+	 *                                                                  The key should be the EE_Addon class name that
158
+	 *                                                                  this set of data migration scripts belongs to.
159
+	 *                                                                  If the EE_Addon class is namespaced, then this
160
+	 *                                                                  needs to be the Fully Qualified Class Name
161
+	 * @type string                   $module_paths                     an array of full server paths to any
162
+	 *                                                                  EED_Modules used by the addon
163
+	 * @type string                   $shortcode_paths                  an array of full server paths to folders
164
+	 *                                                                  that contain EES_Shortcodes
165
+	 * @type string                   $widget_paths                     an array of full server paths to folders
166
+	 *                                                                  that contain WP_Widgets
167
+	 * @type string                   $pue_options
168
+	 * @type array                    $capabilities                     an array indexed by role name
169
+	 *                                                                  (i.e administrator,author ) and the values
170
+	 *                                                                  are an array of caps to add to the role.
171
+	 *                                                                  'administrator' => array(
172
+	 *                                                                  'read_addon',
173
+	 *                                                                  'edit_addon',
174
+	 *                                                                  etc.
175
+	 *                                                                  ).
176
+	 * @type EE_Meta_Capability_Map[] $capability_maps                  an array of EE_Meta_Capability_Map object
177
+	 *                                                                  for any addons that need to register any
178
+	 *                                                                  special meta mapped capabilities.  Should
179
+	 *                                                                  be indexed where the key is the
180
+	 *                                                                  EE_Meta_Capability_Map class name and the
181
+	 *                                                                  values are the arguments sent to the class.
182
+	 * @type array                    $model_paths                      array of folders containing DB models
183
+	 * @see      EE_Register_Model
184
+	 * @type array                    $class_paths                      array of folders containing DB classes
185
+	 * @see      EE_Register_Model
186
+	 * @type array                    $model_extension_paths            array of folders containing DB model
187
+	 *                                                                  extensions
188
+	 * @see      EE_Register_Model_Extension
189
+	 * @type array                    $class_extension_paths            array of folders containing DB class
190
+	 *                                                                  extensions
191
+	 * @see      EE_Register_Model_Extension
192
+	 * @type array message_types {
193
+	 *                                                                  An array of message types with the key as
194
+	 *                                                                  the message type name and the values as
195
+	 *                                                                  below:
196
+	 * @type string                   $mtfilename                       [Required] The filename of the message type
197
+	 *                                                                  being registered. This will be the main
198
+	 *                                                                  EE_{Message Type Name}_message_type class.
199
+	 *                                                                  for example:
200
+	 *                                                                  EE_Declined_Registration_message_type.class.php
201
+	 * @type array                    $autoloadpaths                    [Required] An array of paths to add to the
202
+	 *                                                                  messages autoloader for the new message type.
203
+	 * @type array                    $messengers_to_activate_with      An array of messengers that this message
204
+	 *                                                                  type should activate with. Each value in
205
+	 *                                                                  the
206
+	 *                                                                  array
207
+	 *                                                                  should match the name property of a
208
+	 *                                                                  EE_messenger. Optional.
209
+	 * @type array                    $messengers_to_validate_with      An array of messengers that this message
210
+	 *                                                                  type should validate with. Each value in
211
+	 *                                                                  the
212
+	 *                                                                  array
213
+	 *                                                                  should match the name property of an
214
+	 *                                                                  EE_messenger.
215
+	 *                                                                  Optional.
216
+	 *                                                                  }
217
+	 * @type array                    $custom_post_types
218
+	 * @type array                    $custom_taxonomies
219
+	 * @type array                    $payment_method_paths             each element is the folder containing the
220
+	 *                                                                  EE_PMT_Base child class
221
+	 *                                                                  (eg,
222
+	 *                                                                  '/wp-content/plugins/my_plugin/Payomatic/'
223
+	 *                                                                  which contains the files
224
+	 *                                                                  EE_PMT_Payomatic.pm.php)
225
+	 * @type array                    $default_terms
226
+	 * @type array                    $namespace                        {
227
+	 *                                                                  An array with two items for registering the
228
+	 *                                                                  addon's namespace. (If, for some reason, you
229
+	 *                                                                  require additional namespaces,
230
+	 *                                                                  use
231
+	 *                                                                  EventEspresso\core\Psr4Autoloader::addNamespace()
232
+	 *                                                                  directly)
233
+	 * @see      EventEspresso\core\Psr4Autoloader::addNamespace()
234
+	 * @type string                   $FQNS                             the namespace prefix
235
+	 * @type string                   $DIR                              a base directory for class files in the
236
+	 *                                                                  namespace.
237
+	 *                                                                  }
238
+	 *                                                                  }
239
+	 * @type string                   $privacy_policies                 FQNSs (namespaces, each of which contains only
240
+	 *                                                                  privacy policy classes) or FQCNs (specific
241
+	 *                                                                  classnames of privacy policy classes)
242
+	 * @type string                   $personal_data_exporters          FQNSs (namespaces, each of which contains only
243
+	 *                                                                  privacy policy classes) or FQCNs (specific
244
+	 *                                                                  classnames of privacy policy classes)
245
+	 * @type string                   $personal_data_erasers            FQNSs (namespaces, each of which contains only
246
+	 *                                                                  privacy policy classes) or FQCNs (specific
247
+	 *                                                                  classnames of privacy policy classes)
248
+	 * @return void
249
+	 * @throws DomainException
250
+	 * @throws EE_Error
251
+	 * @throws InvalidArgumentException
252
+	 * @throws InvalidDataTypeException
253
+	 * @throws InvalidInterfaceException
254
+	 */
255
+	public static function register($addon_name = '', array $setup_args = array())
256
+	{
257
+		// required fields MUST be present, so let's make sure they are.
258
+		EE_Register_Addon::_verify_parameters($addon_name, $setup_args);
259
+		// get class name for addon
260
+		$class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args);
261
+		// setup $_settings array from incoming values.
262
+		$addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args);
263
+		// setup PUE
264
+		EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
265
+		// does this addon work with this version of core or WordPress ?
266
+		// does this addon work with this version of core or WordPress ?
267
+		if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268
+			return;
269
+		}
270
+		// register namespaces
271
+		EE_Register_Addon::_setup_namespaces($addon_settings);
272
+		// check if this is an activation request
273
+		if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) {
274
+			// dont bother setting up the rest of the addon atm
275
+			return;
276
+		}
277
+		// we need cars
278
+		EE_Register_Addon::_setup_autoloaders($addon_name);
279
+		// register new models and extensions
280
+		EE_Register_Addon::_register_models_and_extensions($addon_name);
281
+		// setup DMS
282
+		EE_Register_Addon::_register_data_migration_scripts($addon_name);
283
+		// if config_class is present let's register config.
284
+		EE_Register_Addon::_register_config($addon_name);
285
+		// register admin pages
286
+		EE_Register_Addon::_register_admin_pages($addon_name);
287
+		// add to list of modules to be registered
288
+		EE_Register_Addon::_register_modules($addon_name);
289
+		// add to list of shortcodes to be registered
290
+		EE_Register_Addon::_register_shortcodes($addon_name);
291
+		// add to list of widgets to be registered
292
+		EE_Register_Addon::_register_widgets($addon_name);
293
+		// register capability related stuff.
294
+		EE_Register_Addon::_register_capabilities($addon_name);
295
+		// any message type to register?
296
+		EE_Register_Addon::_register_message_types($addon_name);
297
+		// any custom post type/ custom capabilities or default terms to register
298
+		EE_Register_Addon::_register_custom_post_types($addon_name);
299
+		// and any payment methods
300
+		EE_Register_Addon::_register_payment_methods($addon_name);
301
+		// and privacy policy generators
302
+		EE_Register_Addon::registerPrivacyPolicies($addon_name);
303
+		// and privacy policy generators
304
+		EE_Register_Addon::registerPersonalDataExporters($addon_name);
305
+		// and privacy policy generators
306
+		EE_Register_Addon::registerPersonalDataErasers($addon_name);
307
+		// load and instantiate main addon class
308
+		$addon = EE_Register_Addon::_load_and_init_addon_class($addon_name);
309
+		// delay calling after_registration hook on each addon until after all add-ons have been registered.
310
+		add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999);
311
+	}
312
+
313
+
314
+	/**
315
+	 * @param string $addon_name
316
+	 * @param array  $setup_args
317
+	 * @return void
318
+	 * @throws EE_Error
319
+	 */
320
+	private static function _verify_parameters($addon_name, array $setup_args)
321
+	{
322
+		// required fields MUST be present, so let's make sure they are.
323
+		if (empty($addon_name) || ! is_array($setup_args)) {
324
+			throw new EE_Error(
325
+				__(
326
+					'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.',
327
+					'event_espresso'
328
+				)
329
+			);
330
+		}
331
+		if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332
+			throw new EE_Error(
333
+				sprintf(
334
+					__(
335
+						'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s',
336
+						'event_espresso'
337
+					),
338
+					implode(',', array_keys($setup_args))
339
+				)
340
+			);
341
+		}
342
+		// check that addon has not already been registered with that name
343
+		if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
344
+			throw new EE_Error(
345
+				sprintf(
346
+					__(
347
+						'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.',
348
+						'event_espresso'
349
+					),
350
+					$addon_name
351
+				)
352
+			);
353
+		}
354
+	}
355
+
356
+
357
+	/**
358
+	 * @param string $addon_name
359
+	 * @param array  $setup_args
360
+	 * @return string
361
+	 */
362
+	private static function _parse_class_name($addon_name, array $setup_args)
363
+	{
364
+		if (empty($setup_args['class_name'])) {
365
+			// generate one by first separating name with spaces
366
+			$class_name = str_replace(array('-', '_'), ' ', trim($addon_name));
367
+			// capitalize, then replace spaces with underscores
368
+			$class_name = str_replace(' ', '_', ucwords($class_name));
369
+		} else {
370
+			$class_name = $setup_args['class_name'];
371
+		}
372
+		// check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373
+		return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374
+			? $class_name
375
+			: 'EE_' . $class_name;
376
+	}
377
+
378
+
379
+	/**
380
+	 * @param string $class_name
381
+	 * @param array  $setup_args
382
+	 * @return array
383
+	 */
384
+	private static function _get_addon_settings($class_name, array $setup_args)
385
+	{
386
+		// setup $_settings array from incoming values.
387
+		$addon_settings = array(
388
+			// generated from the addon name, changes something like "calendar" to "EE_Calendar"
389
+			'class_name'            => $class_name,
390
+			// the addon slug for use in URLs, etc
391
+			'plugin_slug'           => isset($setup_args['plugin_slug'])
392
+				? (string) $setup_args['plugin_slug']
393
+				: '',
394
+			// page slug to be used when generating the "Settings" link on the WP plugin page
395
+			'plugin_action_slug'    => isset($setup_args['plugin_action_slug'])
396
+				? (string) $setup_args['plugin_action_slug']
397
+				: '',
398
+			// the "software" version for the addon
399
+			'version'               => isset($setup_args['version'])
400
+				? (string) $setup_args['version']
401
+				: '',
402
+			// the minimum version of EE Core that the addon will work with
403
+			'min_core_version'      => isset($setup_args['min_core_version'])
404
+				? (string) $setup_args['min_core_version']
405
+				: '',
406
+			// the minimum version of WordPress that the addon will work with
407
+			'min_wp_version'        => isset($setup_args['min_wp_version'])
408
+				? (string) $setup_args['min_wp_version']
409
+				: EE_MIN_WP_VER_REQUIRED,
410
+			// full server path to main file (file loaded directly by WP)
411
+			'main_file_path'        => isset($setup_args['main_file_path'])
412
+				? (string) $setup_args['main_file_path']
413
+				: '',
414
+			// instance of \EventEspresso\core\domain\DomainInterface
415
+			'domain'                => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface
416
+				? $setup_args['domain']
417
+				: null,
418
+			// Fully Qualified Class Name for the addon's Domain class
419
+			'domain_fqcn'           => isset($setup_args['domain_fqcn'])
420
+				? (string) $setup_args['domain_fqcn']
421
+				: '',
422
+			// path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages
423
+			'admin_path'            => isset($setup_args['admin_path'])
424
+				? (string) $setup_args['admin_path'] : '',
425
+			// a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page
426
+			'admin_callback'        => isset($setup_args['admin_callback'])
427
+				? (string) $setup_args['admin_callback']
428
+				: '',
429
+			// the section name for this addon's configuration settings section (defaults to "addons")
430
+			'config_section'        => isset($setup_args['config_section'])
431
+				? (string) $setup_args['config_section']
432
+				: 'addons',
433
+			// the class name for this addon's configuration settings object
434
+			'config_class'          => isset($setup_args['config_class'])
435
+				? (string) $setup_args['config_class'] : '',
436
+			// the name given to the config for this addons' configuration settings object (optional)
437
+			'config_name'           => isset($setup_args['config_name'])
438
+				? (string) $setup_args['config_name'] : '',
439
+			// an array of "class names" => "full server paths" for any classes that might be invoked by the addon
440
+			'autoloader_paths'      => isset($setup_args['autoloader_paths'])
441
+				? (array) $setup_args['autoloader_paths']
442
+				: array(),
443
+			// an array of  "full server paths" for any folders containing classes that might be invoked by the addon
444
+			'autoloader_folders'    => isset($setup_args['autoloader_folders'])
445
+				? (array) $setup_args['autoloader_folders']
446
+				: array(),
447
+			// array of full server paths to any EE_DMS data migration scripts used by the addon.
448
+			// The key should be the EE_Addon class name that this set of data migration scripts belongs to.
449
+			// If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name
450
+			'dms_paths'             => isset($setup_args['dms_paths'])
451
+				? (array) $setup_args['dms_paths']
452
+				: array(),
453
+			// array of full server paths to any EED_Modules used by the addon
454
+			'module_paths'          => isset($setup_args['module_paths'])
455
+				? (array) $setup_args['module_paths']
456
+				: array(),
457
+			// array of full server paths to any EES_Shortcodes used by the addon
458
+			'shortcode_paths'       => isset($setup_args['shortcode_paths'])
459
+				? (array) $setup_args['shortcode_paths']
460
+				: array(),
461
+			'shortcode_fqcns'       => isset($setup_args['shortcode_fqcns'])
462
+				? (array) $setup_args['shortcode_fqcns']
463
+				: array(),
464
+			// array of full server paths to any WP_Widgets used by the addon
465
+			'widget_paths'          => isset($setup_args['widget_paths'])
466
+				? (array) $setup_args['widget_paths']
467
+				: array(),
468
+			// array of PUE options used by the addon
469
+			'pue_options'           => isset($setup_args['pue_options'])
470
+				? (array) $setup_args['pue_options']
471
+				: array(),
472
+			'message_types'         => isset($setup_args['message_types'])
473
+				? (array) $setup_args['message_types']
474
+				: array(),
475
+			'capabilities'          => isset($setup_args['capabilities'])
476
+				? (array) $setup_args['capabilities']
477
+				: array(),
478
+			'capability_maps'       => isset($setup_args['capability_maps'])
479
+				? (array) $setup_args['capability_maps']
480
+				: array(),
481
+			'model_paths'           => isset($setup_args['model_paths'])
482
+				? (array) $setup_args['model_paths']
483
+				: array(),
484
+			'class_paths'           => isset($setup_args['class_paths'])
485
+				? (array) $setup_args['class_paths']
486
+				: array(),
487
+			'model_extension_paths' => isset($setup_args['model_extension_paths'])
488
+				? (array) $setup_args['model_extension_paths']
489
+				: array(),
490
+			'class_extension_paths' => isset($setup_args['class_extension_paths'])
491
+				? (array) $setup_args['class_extension_paths']
492
+				: array(),
493
+			'custom_post_types'     => isset($setup_args['custom_post_types'])
494
+				? (array) $setup_args['custom_post_types']
495
+				: array(),
496
+			'custom_taxonomies'     => isset($setup_args['custom_taxonomies'])
497
+				? (array) $setup_args['custom_taxonomies']
498
+				: array(),
499
+			'payment_method_paths'  => isset($setup_args['payment_method_paths'])
500
+				? (array) $setup_args['payment_method_paths']
501
+				: array(),
502
+			'default_terms'         => isset($setup_args['default_terms'])
503
+				? (array) $setup_args['default_terms']
504
+				: array(),
505
+			// if not empty, inserts a new table row after this plugin's row on the WP Plugins page
506
+			// that can be used for adding upgrading/marketing info
507
+			'plugins_page_row'      => isset($setup_args['plugins_page_row']) ? $setup_args['plugins_page_row'] : '',
508
+			'namespace'             => isset(
509
+				$setup_args['namespace']['FQNS'],
510
+				$setup_args['namespace']['DIR']
511
+			)
512
+				? (array) $setup_args['namespace']
513
+				: array(),
514
+			'privacy_policies'      => isset($setup_args['privacy_policies'])
515
+				? (array) $setup_args['privacy_policies']
516
+				: '',
517
+		);
518
+		// if plugin_action_slug is NOT set, but an admin page path IS set,
519
+		// then let's just use the plugin_slug since that will be used for linking to the admin page
520
+		$addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug'])
521
+												&& ! empty($addon_settings['admin_path'])
522
+			? $addon_settings['plugin_slug']
523
+			: $addon_settings['plugin_action_slug'];
524
+		// full server path to main file (file loaded directly by WP)
525
+		$addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']);
526
+		return $addon_settings;
527
+	}
528
+
529
+
530
+	/**
531
+	 * @param string $addon_name
532
+	 * @param array  $addon_settings
533
+	 * @return boolean
534
+	 */
535
+	private static function _addon_is_compatible($addon_name, array $addon_settings)
536
+	{
537
+		global $wp_version;
538
+		$incompatibility_message = '';
539
+		// check whether this addon version is compatible with EE core
540
+		if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
541
+			&& ! self::_meets_min_core_version_requirement(
542
+				EE_Register_Addon::$_incompatible_addons[ $addon_name ],
543
+				$addon_settings['version']
544
+			)
545
+		) {
546
+			$incompatibility_message = sprintf(
547
+				__(
548
+					'%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.',
549
+					'event_espresso'
550
+				),
551
+				$addon_name,
552
+				'<br />',
553
+				EE_Register_Addon::$_incompatible_addons[ $addon_name ],
554
+				'<span style="font-weight: bold; color: #D54E21;">',
555
+				'</span><br />'
556
+			);
557
+		} elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
558
+		) {
559
+			$incompatibility_message = sprintf(
560
+				__(
561
+					'%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".',
562
+					'event_espresso'
563
+				),
564
+				$addon_name,
565
+				self::_effective_version($addon_settings['min_core_version']),
566
+				self::_effective_version(espresso_version()),
567
+				'<br />',
568
+				'<span style="font-weight: bold; color: #D54E21;">',
569
+				'</span><br />'
570
+			);
571
+		} elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) {
572
+			$incompatibility_message = sprintf(
573
+				__(
574
+					'%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.',
575
+					'event_espresso'
576
+				),
577
+				$addon_name,
578
+				$addon_settings['min_wp_version'],
579
+				'<br />',
580
+				'<span style="font-weight: bold; color: #D54E21;">',
581
+				'</span><br />'
582
+			);
583
+		}
584
+		if (! empty($incompatibility_message)) {
585
+			// remove 'activate' from the REQUEST
586
+			// so WP doesn't erroneously tell the user the plugin activated fine when it didn't
587
+			unset($_GET['activate'], $_REQUEST['activate']);
588
+			if (current_user_can('activate_plugins')) {
589
+				// show an error message indicating the plugin didn't activate properly
590
+				EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__);
591
+			}
592
+			// BAIL FROM THE ADDON REGISTRATION PROCESS
593
+			return false;
594
+		}
595
+		// addon IS compatible
596
+		return true;
597
+	}
598
+
599
+
600
+	/**
601
+	 * if plugin update engine is being used for auto-updates,
602
+	 * then let's set that up now before going any further so that ALL addons can be updated
603
+	 * (not needed if PUE is not being used)
604
+	 *
605
+	 * @param string $addon_name
606
+	 * @param string $class_name
607
+	 * @param array  $setup_args
608
+	 * @return void
609
+	 */
610
+	private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
611
+	{
612
+		if (! empty($setup_args['pue_options'])) {
613
+			self::$_settings[ $addon_name ]['pue_options'] = array(
614
+				'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
615
+					? (string) $setup_args['pue_options']['pue_plugin_slug']
616
+					: 'espresso_' . strtolower($class_name),
617
+				'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
618
+					? (string) $setup_args['pue_options']['plugin_basename']
619
+					: plugin_basename($setup_args['main_file_path']),
620
+				'checkPeriod'     => isset($setup_args['pue_options']['checkPeriod'])
621
+					? (string) $setup_args['pue_options']['checkPeriod']
622
+					: '24',
623
+				'use_wp_update'   => isset($setup_args['pue_options']['use_wp_update'])
624
+					? (string) $setup_args['pue_options']['use_wp_update']
625
+					: false,
626
+			);
627
+			add_action(
628
+				'AHEE__EE_System__brew_espresso__after_pue_init',
629
+				array('EE_Register_Addon', 'load_pue_update')
630
+			);
631
+		}
632
+	}
633
+
634
+
635
+	/**
636
+	 * register namespaces right away before any other files or classes get loaded, but AFTER the version checks
637
+	 *
638
+	 * @param array $addon_settings
639
+	 * @return void
640
+	 */
641
+	private static function _setup_namespaces(array $addon_settings)
642
+	{
643
+		//
644
+		if (isset(
645
+			$addon_settings['namespace']['FQNS'],
646
+			$addon_settings['namespace']['DIR']
647
+		)) {
648
+			EE_Psr4AutoloaderInit::psr4_loader()->addNamespace(
649
+				$addon_settings['namespace']['FQNS'],
650
+				$addon_settings['namespace']['DIR']
651
+			);
652
+		}
653
+	}
654
+
655
+
656
+	/**
657
+	 * @param string $addon_name
658
+	 * @param array  $addon_settings
659
+	 * @return bool
660
+	 * @throws InvalidArgumentException
661
+	 * @throws InvalidDataTypeException
662
+	 * @throws InvalidInterfaceException
663
+	 */
664
+	private static function _addon_activation($addon_name, array $addon_settings)
665
+	{
666
+		// this is an activation request
667
+		if (did_action('activate_plugin')) {
668
+			// to find if THIS is the addon that was activated, just check if we have already registered it or not
669
+			// (as the newly-activated addon wasn't around the first time addons were registered).
670
+			// Note: the presence of pue_options in the addon registration options will initialize the $_settings
671
+			// property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
672
+			if (! isset(self::$_settings[ $addon_name ])
673
+				|| (isset(self::$_settings[ $addon_name ]) && ! isset(self::$_settings[ $addon_name ]['class_name']))
674
+			) {
675
+				self::$_settings[ $addon_name ] = $addon_settings;
676
+				$addon = self::_load_and_init_addon_class($addon_name);
677
+				$addon->set_activation_indicator_option();
678
+				// dont bother setting up the rest of the addon.
679
+				// we know it was just activated and the request will end soon
680
+			}
681
+			return true;
682
+		}
683
+		// make sure this was called in the right place!
684
+		if (! did_action('AHEE__EE_System__load_espresso_addons')
685
+			|| did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
686
+		) {
687
+			EE_Error::doing_it_wrong(
688
+				__METHOD__,
689
+				sprintf(
690
+					__(
691
+						'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.',
692
+						'event_espresso'
693
+					),
694
+					$addon_name
695
+				),
696
+				'4.3.0'
697
+			);
698
+		}
699
+		// make sure addon settings are set correctly without overwriting anything existing
700
+		if (isset(self::$_settings[ $addon_name ])) {
701
+			self::$_settings[ $addon_name ] += $addon_settings;
702
+		} else {
703
+			self::$_settings[ $addon_name ] = $addon_settings;
704
+		}
705
+		return false;
706
+	}
707
+
708
+
709
+	/**
710
+	 * @param string $addon_name
711
+	 * @return void
712
+	 * @throws EE_Error
713
+	 */
714
+	private static function _setup_autoloaders($addon_name)
715
+	{
716
+		if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
717
+			// setup autoloader for single file
718
+			EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
719
+		}
720
+		// setup autoloaders for folders
721
+		if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
722
+			foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
723
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
724
+			}
725
+		}
726
+	}
727
+
728
+
729
+	/**
730
+	 * register new models and extensions
731
+	 *
732
+	 * @param string $addon_name
733
+	 * @return void
734
+	 * @throws EE_Error
735
+	 */
736
+	private static function _register_models_and_extensions($addon_name)
737
+	{
738
+		// register new models
739
+		if (! empty(self::$_settings[ $addon_name ]['model_paths'])
740
+			|| ! empty(self::$_settings[ $addon_name ]['class_paths'])
741
+		) {
742
+			EE_Register_Model::register(
743
+				$addon_name,
744
+				array(
745
+					'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
746
+					'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
747
+				)
748
+			);
749
+		}
750
+		// register model extensions
751
+		if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
752
+			|| ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
753
+		) {
754
+			EE_Register_Model_Extensions::register(
755
+				$addon_name,
756
+				array(
757
+					'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
758
+					'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
759
+				)
760
+			);
761
+		}
762
+	}
763
+
764
+
765
+	/**
766
+	 * @param string $addon_name
767
+	 * @return void
768
+	 * @throws EE_Error
769
+	 */
770
+	private static function _register_data_migration_scripts($addon_name)
771
+	{
772
+		// setup DMS
773
+		if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
774
+			EE_Register_Data_Migration_Scripts::register(
775
+				$addon_name,
776
+				array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
777
+			);
778
+		}
779
+	}
780
+
781
+
782
+	/**
783
+	 * @param string $addon_name
784
+	 * @return void
785
+	 * @throws EE_Error
786
+	 */
787
+	private static function _register_config($addon_name)
788
+	{
789
+		// if config_class is present let's register config.
790
+		if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
791
+			EE_Register_Config::register(
792
+				self::$_settings[ $addon_name ]['config_class'],
793
+				array(
794
+					'config_section' => self::$_settings[ $addon_name ]['config_section'],
795
+					'config_name'    => self::$_settings[ $addon_name ]['config_name'],
796
+				)
797
+			);
798
+		}
799
+	}
800
+
801
+
802
+	/**
803
+	 * @param string $addon_name
804
+	 * @return void
805
+	 * @throws EE_Error
806
+	 */
807
+	private static function _register_admin_pages($addon_name)
808
+	{
809
+		if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
810
+			EE_Register_Admin_Page::register(
811
+				$addon_name,
812
+				array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
813
+			);
814
+		}
815
+	}
816
+
817
+
818
+	/**
819
+	 * @param string $addon_name
820
+	 * @return void
821
+	 * @throws EE_Error
822
+	 */
823
+	private static function _register_modules($addon_name)
824
+	{
825
+		if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
826
+			EE_Register_Module::register(
827
+				$addon_name,
828
+				array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
829
+			);
830
+		}
831
+	}
832
+
833
+
834
+	/**
835
+	 * @param string $addon_name
836
+	 * @return void
837
+	 * @throws EE_Error
838
+	 */
839
+	private static function _register_shortcodes($addon_name)
840
+	{
841
+		if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
842
+			|| ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
843
+		) {
844
+			EE_Register_Shortcode::register(
845
+				$addon_name,
846
+				array(
847
+					'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
848
+						? self::$_settings[ $addon_name ]['shortcode_paths'] : array(),
849
+					'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
850
+						? self::$_settings[ $addon_name ]['shortcode_fqcns'] : array(),
851
+				)
852
+			);
853
+		}
854
+	}
855
+
856
+
857
+	/**
858
+	 * @param string $addon_name
859
+	 * @return void
860
+	 * @throws EE_Error
861
+	 */
862
+	private static function _register_widgets($addon_name)
863
+	{
864
+		if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
865
+			EE_Register_Widget::register(
866
+				$addon_name,
867
+				array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
868
+			);
869
+		}
870
+	}
871
+
872
+
873
+	/**
874
+	 * @param string $addon_name
875
+	 * @return void
876
+	 * @throws EE_Error
877
+	 */
878
+	private static function _register_capabilities($addon_name)
879
+	{
880
+		if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
881
+			EE_Register_Capabilities::register(
882
+				$addon_name,
883
+				array(
884
+					'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
885
+					'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
886
+				)
887
+			);
888
+		}
889
+	}
890
+
891
+
892
+	/**
893
+	 * @param string $addon_name
894
+	 * @return void
895
+	 */
896
+	private static function _register_message_types($addon_name)
897
+	{
898
+		if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
899
+			add_action(
900
+				'EE_Brewing_Regular___messages_caf',
901
+				array('EE_Register_Addon', 'register_message_types')
902
+			);
903
+		}
904
+	}
905
+
906
+
907
+	/**
908
+	 * @param string $addon_name
909
+	 * @return void
910
+	 * @throws EE_Error
911
+	 */
912
+	private static function _register_custom_post_types($addon_name)
913
+	{
914
+		if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
915
+			|| ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
916
+		) {
917
+			EE_Register_CPT::register(
918
+				$addon_name,
919
+				array(
920
+					'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
921
+					'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
922
+					'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
923
+				)
924
+			);
925
+		}
926
+	}
927
+
928
+
929
+	/**
930
+	 * @param string $addon_name
931
+	 * @return void
932
+	 * @throws InvalidArgumentException
933
+	 * @throws InvalidInterfaceException
934
+	 * @throws InvalidDataTypeException
935
+	 * @throws DomainException
936
+	 * @throws EE_Error
937
+	 */
938
+	private static function _register_payment_methods($addon_name)
939
+	{
940
+		if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
941
+			EE_Register_Payment_Method::register(
942
+				$addon_name,
943
+				array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
944
+			);
945
+		}
946
+	}
947
+
948
+
949
+	/**
950
+	 * @param string $addon_name
951
+	 * @return void
952
+	 * @throws InvalidArgumentException
953
+	 * @throws InvalidInterfaceException
954
+	 * @throws InvalidDataTypeException
955
+	 * @throws DomainException
956
+	 */
957
+	private static function registerPrivacyPolicies($addon_name)
958
+	{
959
+		if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
960
+			EE_Register_Privacy_Policy::register(
961
+				$addon_name,
962
+				self::$_settings[ $addon_name ]['privacy_policies']
963
+			);
964
+		}
965
+	}
966
+
967
+
968
+	/**
969
+	 * @param string $addon_name
970
+	 * @return void
971
+	 */
972
+	private static function registerPersonalDataExporters($addon_name)
973
+	{
974
+		if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
975
+			EE_Register_Personal_Data_Eraser::register(
976
+				$addon_name,
977
+				self::$_settings[ $addon_name ]['personal_data_exporters']
978
+			);
979
+		}
980
+	}
981
+
982
+
983
+	/**
984
+	 * @param string $addon_name
985
+	 * @return void
986
+	 */
987
+	private static function registerPersonalDataErasers($addon_name)
988
+	{
989
+		if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
990
+			EE_Register_Personal_Data_Eraser::register(
991
+				$addon_name,
992
+				self::$_settings[ $addon_name ]['personal_data_erasers']
993
+			);
994
+		}
995
+	}
996
+
997
+
998
+	/**
999
+	 * Loads and instantiates the EE_Addon class and adds it onto the registry
1000
+	 *
1001
+	 * @param string $addon_name
1002
+	 * @return EE_Addon
1003
+	 * @throws InvalidArgumentException
1004
+	 * @throws InvalidInterfaceException
1005
+	 * @throws InvalidDataTypeException
1006
+	 * @throws DomainException
1007
+	 */
1008
+	private static function _load_and_init_addon_class($addon_name)
1009
+	{
1010
+		$addon_class = self::$_settings[ $addon_name ]['class_name'];
1011
+		$addon = LoaderFactory::getLoader()->getShared($addon_class, ['EE_Registry::create(addon)' => true]);
1012
+		// verify addon has been instantiated correctly
1013
+		if (! $addon instanceof $addon_class) {
1014
+			throw new DomainException(
1015
+				sprintf(
1016
+					__(
1017
+						'An attempt to register an EE_Addon named "%1$s" has failed because the "%2$s" class is either missing or invalid. The following was created instead: %3$s',
1018
+						'event_espresso'
1019
+					),
1020
+					$addon_name,
1021
+					$addon_class,
1022
+					print_r($addon, true)
1023
+				)
1024
+			);
1025
+		}
1026
+		// setter inject dep map if required
1027
+		if ($addon->dependencyMap() === null) {
1028
+			$addon->setDependencyMap(LoaderFactory::getLoader()->getShared('EE_Dependency_Map'));
1029
+		}
1030
+		// setter inject domain if required
1031
+		EE_Register_Addon::injectAddonDomain($addon_name, $addon);
1032
+
1033
+		$addon->set_name($addon_name);
1034
+		$addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1035
+		$addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1036
+		$addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1037
+		$addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1038
+		$addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1039
+		$addon->set_version(self::$_settings[ $addon_name ]['version']);
1040
+		$addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1041
+		$addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1042
+		$addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1043
+		$addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1044
+		// setup the add-on's pue_slug if we have one.
1045
+		if (! empty(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug'])) {
1046
+			$addon->setPueSlug(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug']);
1047
+		}
1048
+		// unfortunately this can't be hooked in upon construction,
1049
+		// because we don't have the plugin's mainfile path upon construction.
1050
+		register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1051
+		// call any additional admin_callback functions during load_admin_controller hook
1052
+		if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1053
+			add_action(
1054
+				'AHEE__EE_System__load_controllers__load_admin_controllers',
1055
+				array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1056
+			);
1057
+		}
1058
+		return $addon;
1059
+	}
1060
+
1061
+
1062
+	/**
1063
+	 * @param string   $addon_name
1064
+	 * @param EE_Addon $addon
1065
+	 * @since   $VID:$
1066
+	 */
1067
+	private static function injectAddonDomain($addon_name, EE_Addon $addon)
1068
+	{
1069
+		if ($addon instanceof RequiresDomainInterface && $addon->domain() === null) {
1070
+			// using supplied Domain object
1071
+			$domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1072
+				? self::$_settings[ $addon_name ]['domain']
1073
+				: null;
1074
+			// or construct one using Domain FQCN
1075
+			if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1076
+				$domain = LoaderFactory::getLoader()->getShared(
1077
+					self::$_settings[ $addon_name ]['domain_fqcn'],
1078
+					[
1079
+						new EventEspresso\core\domain\values\FilePath(
1080
+							self::$_settings[ $addon_name ]['main_file_path']
1081
+						),
1082
+						EventEspresso\core\domain\values\Version::fromString(
1083
+							self::$_settings[ $addon_name ]['version']
1084
+						),
1085
+					]
1086
+				);
1087
+			}
1088
+			if ($domain instanceof DomainInterface) {
1089
+				$addon->setDomain($domain);
1090
+			}
1091
+		}
1092
+	}
1093
+
1094
+
1095
+	/**
1096
+	 *    load_pue_update - Update notifications
1097
+	 *
1098
+	 * @return void
1099
+	 * @throws InvalidArgumentException
1100
+	 * @throws InvalidDataTypeException
1101
+	 * @throws InvalidInterfaceException
1102
+	 */
1103
+	public static function load_pue_update()
1104
+	{
1105
+		// load PUE client
1106
+		require_once EE_THIRD_PARTY . 'pue/pue-client.php';
1107
+		$license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1108
+		// cycle thru settings
1109
+		foreach (self::$_settings as $settings) {
1110
+			if (! empty($settings['pue_options'])) {
1111
+				// initiate the class and start the plugin update engine!
1112
+				new PluginUpdateEngineChecker(
1113
+					// host file URL
1114
+					$license_server,
1115
+					// plugin slug(s)
1116
+					array(
1117
+						'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1118
+						'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1119
+					),
1120
+					// options
1121
+					array(
1122
+						'apikey'            => EE_Registry::instance()->NET_CFG->core->site_license_key,
1123
+						'lang_domain'       => 'event_espresso',
1124
+						'checkPeriod'       => $settings['pue_options']['checkPeriod'],
1125
+						'option_key'        => 'ee_site_license_key',
1126
+						'options_page_slug' => 'event_espresso',
1127
+						'plugin_basename'   => $settings['pue_options']['plugin_basename'],
1128
+						// if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP
1129
+						'use_wp_update'     => $settings['pue_options']['use_wp_update'],
1130
+					)
1131
+				);
1132
+			}
1133
+		}
1134
+	}
1135
+
1136
+
1137
+	/**
1138
+	 * Callback for EE_Brewing_Regular__messages_caf hook used to register message types.
1139
+	 *
1140
+	 * @since 4.4.0
1141
+	 * @return void
1142
+	 * @throws EE_Error
1143
+	 */
1144
+	public static function register_message_types()
1145
+	{
1146
+		foreach (self::$_settings as $settings) {
1147
+			if (! empty($settings['message_types'])) {
1148
+				foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1149
+					EE_Register_Message_Type::register($message_type, $message_type_settings);
1150
+				}
1151
+			}
1152
+		}
1153
+	}
1154
+
1155
+
1156
+	/**
1157
+	 * This deregisters an addon that was previously registered with a specific addon_name.
1158
+	 *
1159
+	 * @param string $addon_name the name for the addon that was previously registered
1160
+	 * @throws DomainException
1161
+	 * @throws InvalidArgumentException
1162
+	 * @throws InvalidDataTypeException
1163
+	 * @throws InvalidInterfaceException
1164
+	 *@since    4.3.0
1165
+	 */
1166
+	public static function deregister($addon_name = '')
1167
+	{
1168
+		if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1169
+			try {
1170
+				do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1171
+				$class_name = self::$_settings[ $addon_name ]['class_name'];
1172
+				if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1173
+					// setup DMS
1174
+					EE_Register_Data_Migration_Scripts::deregister($addon_name);
1175
+				}
1176
+				if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1177
+					// register admin page
1178
+					EE_Register_Admin_Page::deregister($addon_name);
1179
+				}
1180
+				if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1181
+					// add to list of modules to be registered
1182
+					EE_Register_Module::deregister($addon_name);
1183
+				}
1184
+				if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1185
+					|| ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1186
+				) {
1187
+					// add to list of shortcodes to be registered
1188
+					EE_Register_Shortcode::deregister($addon_name);
1189
+				}
1190
+				if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1191
+					// if config_class present let's register config.
1192
+					EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1193
+				}
1194
+				if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1195
+					// add to list of widgets to be registered
1196
+					EE_Register_Widget::deregister($addon_name);
1197
+				}
1198
+				if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1199
+					|| ! empty(self::$_settings[ $addon_name ]['class_paths'])
1200
+				) {
1201
+					// add to list of shortcodes to be registered
1202
+					EE_Register_Model::deregister($addon_name);
1203
+				}
1204
+				if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1205
+					|| ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1206
+				) {
1207
+					// add to list of shortcodes to be registered
1208
+					EE_Register_Model_Extensions::deregister($addon_name);
1209
+				}
1210
+				if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1211
+					foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1212
+						EE_Register_Message_Type::deregister($message_type);
1213
+					}
1214
+				}
1215
+				// deregister capabilities for addon
1216
+				if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1217
+					|| ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1218
+				) {
1219
+					EE_Register_Capabilities::deregister($addon_name);
1220
+				}
1221
+				// deregister custom_post_types for addon
1222
+				if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1223
+					EE_Register_CPT::deregister($addon_name);
1224
+				}
1225
+				if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1226
+					EE_Register_Payment_Method::deregister($addon_name);
1227
+				}
1228
+				$addon = EE_Registry::instance()->getAddon($class_name);
1229
+				if ($addon instanceof EE_Addon) {
1230
+					remove_action(
1231
+						'deactivate_' . $addon->get_main_plugin_file_basename(),
1232
+						array($addon, 'deactivation')
1233
+					);
1234
+					remove_action(
1235
+						'AHEE__EE_System__perform_activations_upgrades_and_migrations',
1236
+						array($addon, 'initialize_db_if_no_migrations_required')
1237
+					);
1238
+					// remove `after_registration` call
1239
+					remove_action(
1240
+						'AHEE__EE_System__load_espresso_addons__complete',
1241
+						array($addon, 'after_registration'),
1242
+						999
1243
+					);
1244
+				}
1245
+				EE_Registry::instance()->removeAddon($class_name);
1246
+			} catch (OutOfBoundsException $addon_not_yet_registered_exception) {
1247
+				// the add-on was not yet registered in the registry,
1248
+				// so RegistryContainer::__get() throws this exception.
1249
+				// also no need to worry about this or log it,
1250
+				// it's ok to deregister an add-on before its registered in the registry
1251
+			} catch (Exception $e) {
1252
+				new ExceptionLogger($e);
1253
+			}
1254
+			unset(self::$_settings[ $addon_name ]);
1255
+			do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1256
+		}
1257
+	}
1258 1258
 }
Please login to merge, or discard this patch.
Spacing   +117 added lines, -117 removed lines patch added patch discarded remove patch
@@ -69,15 +69,15 @@  discard block
 block discarded – undo
69 69
         // offsets:    0 . 1 . 2 . 3 . 4
70 70
         $version_parts = explode('.', $min_core_version);
71 71
         // check they specified the micro version (after 2nd period)
72
-        if (! isset($version_parts[2])) {
72
+        if ( ! isset($version_parts[2])) {
73 73
             $version_parts[2] = '0';
74 74
         }
75 75
         // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible
76 76
         // soon we can assume that's 'rc', but this current version is 'alpha'
77
-        if (! isset($version_parts[3])) {
77
+        if ( ! isset($version_parts[3])) {
78 78
             $version_parts[3] = 'dev';
79 79
         }
80
-        if (! isset($version_parts[4])) {
80
+        if ( ! isset($version_parts[4])) {
81 81
             $version_parts[4] = '000';
82 82
         }
83 83
         return implode('.', $version_parts);
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
         EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args);
265 265
         // does this addon work with this version of core or WordPress ?
266 266
         // does this addon work with this version of core or WordPress ?
267
-        if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
267
+        if ( ! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) {
268 268
             return;
269 269
         }
270 270
         // register namespaces
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
                 )
329 329
             );
330 330
         }
331
-        if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
331
+        if ( ! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) {
332 332
             throw new EE_Error(
333 333
                 sprintf(
334 334
                     __(
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
             );
341 341
         }
342 342
         // check that addon has not already been registered with that name
343
-        if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) {
343
+        if (isset(self::$_settings[$addon_name]) && ! did_action('activate_plugin')) {
344 344
             throw new EE_Error(
345 345
                 sprintf(
346 346
                     __(
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
         // check if classname is fully  qualified or is a legacy classname already prefixed with 'EE_'
373 373
         return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0
374 374
             ? $class_name
375
-            : 'EE_' . $class_name;
375
+            : 'EE_'.$class_name;
376 376
     }
377 377
 
378 378
 
@@ -537,9 +537,9 @@  discard block
 block discarded – undo
537 537
         global $wp_version;
538 538
         $incompatibility_message = '';
539 539
         // check whether this addon version is compatible with EE core
540
-        if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ])
540
+        if (isset(EE_Register_Addon::$_incompatible_addons[$addon_name])
541 541
             && ! self::_meets_min_core_version_requirement(
542
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
542
+                EE_Register_Addon::$_incompatible_addons[$addon_name],
543 543
                 $addon_settings['version']
544 544
             )
545 545
         ) {
@@ -550,11 +550,11 @@  discard block
 block discarded – undo
550 550
                 ),
551 551
                 $addon_name,
552 552
                 '<br />',
553
-                EE_Register_Addon::$_incompatible_addons[ $addon_name ],
553
+                EE_Register_Addon::$_incompatible_addons[$addon_name],
554 554
                 '<span style="font-weight: bold; color: #D54E21;">',
555 555
                 '</span><br />'
556 556
             );
557
-        } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
557
+        } elseif ( ! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version())
558 558
         ) {
559 559
             $incompatibility_message = sprintf(
560 560
                 __(
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
                 '</span><br />'
582 582
             );
583 583
         }
584
-        if (! empty($incompatibility_message)) {
584
+        if ( ! empty($incompatibility_message)) {
585 585
             // remove 'activate' from the REQUEST
586 586
             // so WP doesn't erroneously tell the user the plugin activated fine when it didn't
587 587
             unset($_GET['activate'], $_REQUEST['activate']);
@@ -609,11 +609,11 @@  discard block
 block discarded – undo
609 609
      */
610 610
     private static function _parse_pue_options($addon_name, $class_name, array $setup_args)
611 611
     {
612
-        if (! empty($setup_args['pue_options'])) {
613
-            self::$_settings[ $addon_name ]['pue_options'] = array(
612
+        if ( ! empty($setup_args['pue_options'])) {
613
+            self::$_settings[$addon_name]['pue_options'] = array(
614 614
                 'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug'])
615 615
                     ? (string) $setup_args['pue_options']['pue_plugin_slug']
616
-                    : 'espresso_' . strtolower($class_name),
616
+                    : 'espresso_'.strtolower($class_name),
617 617
                 'plugin_basename' => isset($setup_args['pue_options']['plugin_basename'])
618 618
                     ? (string) $setup_args['pue_options']['plugin_basename']
619 619
                     : plugin_basename($setup_args['main_file_path']),
@@ -669,10 +669,10 @@  discard block
 block discarded – undo
669 669
             // (as the newly-activated addon wasn't around the first time addons were registered).
670 670
             // Note: the presence of pue_options in the addon registration options will initialize the $_settings
671 671
             // property for the add-on, but the add-on is only partially initialized.  Hence, the additional check.
672
-            if (! isset(self::$_settings[ $addon_name ])
673
-                || (isset(self::$_settings[ $addon_name ]) && ! isset(self::$_settings[ $addon_name ]['class_name']))
672
+            if ( ! isset(self::$_settings[$addon_name])
673
+                || (isset(self::$_settings[$addon_name]) && ! isset(self::$_settings[$addon_name]['class_name']))
674 674
             ) {
675
-                self::$_settings[ $addon_name ] = $addon_settings;
675
+                self::$_settings[$addon_name] = $addon_settings;
676 676
                 $addon = self::_load_and_init_addon_class($addon_name);
677 677
                 $addon->set_activation_indicator_option();
678 678
                 // dont bother setting up the rest of the addon.
@@ -681,7 +681,7 @@  discard block
 block discarded – undo
681 681
             return true;
682 682
         }
683 683
         // make sure this was called in the right place!
684
-        if (! did_action('AHEE__EE_System__load_espresso_addons')
684
+        if ( ! did_action('AHEE__EE_System__load_espresso_addons')
685 685
             || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')
686 686
         ) {
687 687
             EE_Error::doing_it_wrong(
@@ -697,10 +697,10 @@  discard block
 block discarded – undo
697 697
             );
698 698
         }
699 699
         // make sure addon settings are set correctly without overwriting anything existing
700
-        if (isset(self::$_settings[ $addon_name ])) {
701
-            self::$_settings[ $addon_name ] += $addon_settings;
700
+        if (isset(self::$_settings[$addon_name])) {
701
+            self::$_settings[$addon_name] += $addon_settings;
702 702
         } else {
703
-            self::$_settings[ $addon_name ] = $addon_settings;
703
+            self::$_settings[$addon_name] = $addon_settings;
704 704
         }
705 705
         return false;
706 706
     }
@@ -713,13 +713,13 @@  discard block
 block discarded – undo
713 713
      */
714 714
     private static function _setup_autoloaders($addon_name)
715 715
     {
716
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) {
716
+        if ( ! empty(self::$_settings[$addon_name]['autoloader_paths'])) {
717 717
             // setup autoloader for single file
718
-            EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']);
718
+            EEH_Autoloader::instance()->register_autoloader(self::$_settings[$addon_name]['autoloader_paths']);
719 719
         }
720 720
         // setup autoloaders for folders
721
-        if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) {
722
-            foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) {
721
+        if ( ! empty(self::$_settings[$addon_name]['autoloader_folders'])) {
722
+            foreach ((array) self::$_settings[$addon_name]['autoloader_folders'] as $autoloader_folder) {
723 723
                 EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder);
724 724
             }
725 725
         }
@@ -736,26 +736,26 @@  discard block
 block discarded – undo
736 736
     private static function _register_models_and_extensions($addon_name)
737 737
     {
738 738
         // register new models
739
-        if (! empty(self::$_settings[ $addon_name ]['model_paths'])
740
-            || ! empty(self::$_settings[ $addon_name ]['class_paths'])
739
+        if ( ! empty(self::$_settings[$addon_name]['model_paths'])
740
+            || ! empty(self::$_settings[$addon_name]['class_paths'])
741 741
         ) {
742 742
             EE_Register_Model::register(
743 743
                 $addon_name,
744 744
                 array(
745
-                    'model_paths' => self::$_settings[ $addon_name ]['model_paths'],
746
-                    'class_paths' => self::$_settings[ $addon_name ]['class_paths'],
745
+                    'model_paths' => self::$_settings[$addon_name]['model_paths'],
746
+                    'class_paths' => self::$_settings[$addon_name]['class_paths'],
747 747
                 )
748 748
             );
749 749
         }
750 750
         // register model extensions
751
-        if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
752
-            || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
751
+        if ( ! empty(self::$_settings[$addon_name]['model_extension_paths'])
752
+            || ! empty(self::$_settings[$addon_name]['class_extension_paths'])
753 753
         ) {
754 754
             EE_Register_Model_Extensions::register(
755 755
                 $addon_name,
756 756
                 array(
757
-                    'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'],
758
-                    'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'],
757
+                    'model_extension_paths' => self::$_settings[$addon_name]['model_extension_paths'],
758
+                    'class_extension_paths' => self::$_settings[$addon_name]['class_extension_paths'],
759 759
                 )
760 760
             );
761 761
         }
@@ -770,10 +770,10 @@  discard block
 block discarded – undo
770 770
     private static function _register_data_migration_scripts($addon_name)
771 771
     {
772 772
         // setup DMS
773
-        if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
773
+        if ( ! empty(self::$_settings[$addon_name]['dms_paths'])) {
774 774
             EE_Register_Data_Migration_Scripts::register(
775 775
                 $addon_name,
776
-                array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths'])
776
+                array('dms_paths' => self::$_settings[$addon_name]['dms_paths'])
777 777
             );
778 778
         }
779 779
     }
@@ -787,12 +787,12 @@  discard block
 block discarded – undo
787 787
     private static function _register_config($addon_name)
788 788
     {
789 789
         // if config_class is present let's register config.
790
-        if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
790
+        if ( ! empty(self::$_settings[$addon_name]['config_class'])) {
791 791
             EE_Register_Config::register(
792
-                self::$_settings[ $addon_name ]['config_class'],
792
+                self::$_settings[$addon_name]['config_class'],
793 793
                 array(
794
-                    'config_section' => self::$_settings[ $addon_name ]['config_section'],
795
-                    'config_name'    => self::$_settings[ $addon_name ]['config_name'],
794
+                    'config_section' => self::$_settings[$addon_name]['config_section'],
795
+                    'config_name'    => self::$_settings[$addon_name]['config_name'],
796 796
                 )
797 797
             );
798 798
         }
@@ -806,10 +806,10 @@  discard block
 block discarded – undo
806 806
      */
807 807
     private static function _register_admin_pages($addon_name)
808 808
     {
809
-        if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
809
+        if ( ! empty(self::$_settings[$addon_name]['admin_path'])) {
810 810
             EE_Register_Admin_Page::register(
811 811
                 $addon_name,
812
-                array('page_path' => self::$_settings[ $addon_name ]['admin_path'])
812
+                array('page_path' => self::$_settings[$addon_name]['admin_path'])
813 813
             );
814 814
         }
815 815
     }
@@ -822,10 +822,10 @@  discard block
 block discarded – undo
822 822
      */
823 823
     private static function _register_modules($addon_name)
824 824
     {
825
-        if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
825
+        if ( ! empty(self::$_settings[$addon_name]['module_paths'])) {
826 826
             EE_Register_Module::register(
827 827
                 $addon_name,
828
-                array('module_paths' => self::$_settings[ $addon_name ]['module_paths'])
828
+                array('module_paths' => self::$_settings[$addon_name]['module_paths'])
829 829
             );
830 830
         }
831 831
     }
@@ -838,16 +838,16 @@  discard block
 block discarded – undo
838 838
      */
839 839
     private static function _register_shortcodes($addon_name)
840 840
     {
841
-        if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
842
-            || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
841
+        if ( ! empty(self::$_settings[$addon_name]['shortcode_paths'])
842
+            || ! empty(self::$_settings[$addon_name]['shortcode_fqcns'])
843 843
         ) {
844 844
             EE_Register_Shortcode::register(
845 845
                 $addon_name,
846 846
                 array(
847
-                    'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths'])
848
-                        ? self::$_settings[ $addon_name ]['shortcode_paths'] : array(),
849
-                    'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns'])
850
-                        ? self::$_settings[ $addon_name ]['shortcode_fqcns'] : array(),
847
+                    'shortcode_paths' => isset(self::$_settings[$addon_name]['shortcode_paths'])
848
+                        ? self::$_settings[$addon_name]['shortcode_paths'] : array(),
849
+                    'shortcode_fqcns' => isset(self::$_settings[$addon_name]['shortcode_fqcns'])
850
+                        ? self::$_settings[$addon_name]['shortcode_fqcns'] : array(),
851 851
                 )
852 852
             );
853 853
         }
@@ -861,10 +861,10 @@  discard block
 block discarded – undo
861 861
      */
862 862
     private static function _register_widgets($addon_name)
863 863
     {
864
-        if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
864
+        if ( ! empty(self::$_settings[$addon_name]['widget_paths'])) {
865 865
             EE_Register_Widget::register(
866 866
                 $addon_name,
867
-                array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths'])
867
+                array('widget_paths' => self::$_settings[$addon_name]['widget_paths'])
868 868
             );
869 869
         }
870 870
     }
@@ -877,12 +877,12 @@  discard block
 block discarded – undo
877 877
      */
878 878
     private static function _register_capabilities($addon_name)
879 879
     {
880
-        if (! empty(self::$_settings[ $addon_name ]['capabilities'])) {
880
+        if ( ! empty(self::$_settings[$addon_name]['capabilities'])) {
881 881
             EE_Register_Capabilities::register(
882 882
                 $addon_name,
883 883
                 array(
884
-                    'capabilities'    => self::$_settings[ $addon_name ]['capabilities'],
885
-                    'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'],
884
+                    'capabilities'    => self::$_settings[$addon_name]['capabilities'],
885
+                    'capability_maps' => self::$_settings[$addon_name]['capability_maps'],
886 886
                 )
887 887
             );
888 888
         }
@@ -895,7 +895,7 @@  discard block
 block discarded – undo
895 895
      */
896 896
     private static function _register_message_types($addon_name)
897 897
     {
898
-        if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
898
+        if ( ! empty(self::$_settings[$addon_name]['message_types'])) {
899 899
             add_action(
900 900
                 'EE_Brewing_Regular___messages_caf',
901 901
                 array('EE_Register_Addon', 'register_message_types')
@@ -911,15 +911,15 @@  discard block
 block discarded – undo
911 911
      */
912 912
     private static function _register_custom_post_types($addon_name)
913 913
     {
914
-        if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])
915
-            || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies'])
914
+        if ( ! empty(self::$_settings[$addon_name]['custom_post_types'])
915
+            || ! empty(self::$_settings[$addon_name]['custom_taxonomies'])
916 916
         ) {
917 917
             EE_Register_CPT::register(
918 918
                 $addon_name,
919 919
                 array(
920
-                    'cpts'          => self::$_settings[ $addon_name ]['custom_post_types'],
921
-                    'cts'           => self::$_settings[ $addon_name ]['custom_taxonomies'],
922
-                    'default_terms' => self::$_settings[ $addon_name ]['default_terms'],
920
+                    'cpts'          => self::$_settings[$addon_name]['custom_post_types'],
921
+                    'cts'           => self::$_settings[$addon_name]['custom_taxonomies'],
922
+                    'default_terms' => self::$_settings[$addon_name]['default_terms'],
923 923
                 )
924 924
             );
925 925
         }
@@ -937,10 +937,10 @@  discard block
 block discarded – undo
937 937
      */
938 938
     private static function _register_payment_methods($addon_name)
939 939
     {
940
-        if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
940
+        if ( ! empty(self::$_settings[$addon_name]['payment_method_paths'])) {
941 941
             EE_Register_Payment_Method::register(
942 942
                 $addon_name,
943
-                array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths'])
943
+                array('payment_method_paths' => self::$_settings[$addon_name]['payment_method_paths'])
944 944
             );
945 945
         }
946 946
     }
@@ -956,10 +956,10 @@  discard block
 block discarded – undo
956 956
      */
957 957
     private static function registerPrivacyPolicies($addon_name)
958 958
     {
959
-        if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) {
959
+        if ( ! empty(self::$_settings[$addon_name]['privacy_policies'])) {
960 960
             EE_Register_Privacy_Policy::register(
961 961
                 $addon_name,
962
-                self::$_settings[ $addon_name ]['privacy_policies']
962
+                self::$_settings[$addon_name]['privacy_policies']
963 963
             );
964 964
         }
965 965
     }
@@ -971,10 +971,10 @@  discard block
 block discarded – undo
971 971
      */
972 972
     private static function registerPersonalDataExporters($addon_name)
973 973
     {
974
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) {
974
+        if ( ! empty(self::$_settings[$addon_name]['personal_data_exporters'])) {
975 975
             EE_Register_Personal_Data_Eraser::register(
976 976
                 $addon_name,
977
-                self::$_settings[ $addon_name ]['personal_data_exporters']
977
+                self::$_settings[$addon_name]['personal_data_exporters']
978 978
             );
979 979
         }
980 980
     }
@@ -986,10 +986,10 @@  discard block
 block discarded – undo
986 986
      */
987 987
     private static function registerPersonalDataErasers($addon_name)
988 988
     {
989
-        if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) {
989
+        if ( ! empty(self::$_settings[$addon_name]['personal_data_erasers'])) {
990 990
             EE_Register_Personal_Data_Eraser::register(
991 991
                 $addon_name,
992
-                self::$_settings[ $addon_name ]['personal_data_erasers']
992
+                self::$_settings[$addon_name]['personal_data_erasers']
993 993
             );
994 994
         }
995 995
     }
@@ -1007,10 +1007,10 @@  discard block
 block discarded – undo
1007 1007
      */
1008 1008
     private static function _load_and_init_addon_class($addon_name)
1009 1009
     {
1010
-        $addon_class = self::$_settings[ $addon_name ]['class_name'];
1010
+        $addon_class = self::$_settings[$addon_name]['class_name'];
1011 1011
         $addon = LoaderFactory::getLoader()->getShared($addon_class, ['EE_Registry::create(addon)' => true]);
1012 1012
         // verify addon has been instantiated correctly
1013
-        if (! $addon instanceof $addon_class) {
1013
+        if ( ! $addon instanceof $addon_class) {
1014 1014
             throw new DomainException(
1015 1015
                 sprintf(
1016 1016
                     __(
@@ -1031,28 +1031,28 @@  discard block
 block discarded – undo
1031 1031
         EE_Register_Addon::injectAddonDomain($addon_name, $addon);
1032 1032
 
1033 1033
         $addon->set_name($addon_name);
1034
-        $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']);
1035
-        $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']);
1036
-        $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']);
1037
-        $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']);
1038
-        $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']);
1039
-        $addon->set_version(self::$_settings[ $addon_name ]['version']);
1040
-        $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version']));
1041
-        $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']);
1042
-        $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']);
1043
-        $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']);
1034
+        $addon->set_plugin_slug(self::$_settings[$addon_name]['plugin_slug']);
1035
+        $addon->set_plugin_basename(self::$_settings[$addon_name]['plugin_basename']);
1036
+        $addon->set_main_plugin_file(self::$_settings[$addon_name]['main_file_path']);
1037
+        $addon->set_plugin_action_slug(self::$_settings[$addon_name]['plugin_action_slug']);
1038
+        $addon->set_plugins_page_row(self::$_settings[$addon_name]['plugins_page_row']);
1039
+        $addon->set_version(self::$_settings[$addon_name]['version']);
1040
+        $addon->set_min_core_version(self::_effective_version(self::$_settings[$addon_name]['min_core_version']));
1041
+        $addon->set_config_section(self::$_settings[$addon_name]['config_section']);
1042
+        $addon->set_config_class(self::$_settings[$addon_name]['config_class']);
1043
+        $addon->set_config_name(self::$_settings[$addon_name]['config_name']);
1044 1044
         // setup the add-on's pue_slug if we have one.
1045
-        if (! empty(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug'])) {
1046
-            $addon->setPueSlug(self::$_settings[ $addon_name ]['pue_options']['pue_plugin_slug']);
1045
+        if ( ! empty(self::$_settings[$addon_name]['pue_options']['pue_plugin_slug'])) {
1046
+            $addon->setPueSlug(self::$_settings[$addon_name]['pue_options']['pue_plugin_slug']);
1047 1047
         }
1048 1048
         // unfortunately this can't be hooked in upon construction,
1049 1049
         // because we don't have the plugin's mainfile path upon construction.
1050 1050
         register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation'));
1051 1051
         // call any additional admin_callback functions during load_admin_controller hook
1052
-        if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) {
1052
+        if ( ! empty(self::$_settings[$addon_name]['admin_callback'])) {
1053 1053
             add_action(
1054 1054
                 'AHEE__EE_System__load_controllers__load_admin_controllers',
1055
-                array($addon, self::$_settings[ $addon_name ]['admin_callback'])
1055
+                array($addon, self::$_settings[$addon_name]['admin_callback'])
1056 1056
             );
1057 1057
         }
1058 1058
         return $addon;
@@ -1068,19 +1068,19 @@  discard block
 block discarded – undo
1068 1068
     {
1069 1069
         if ($addon instanceof RequiresDomainInterface && $addon->domain() === null) {
1070 1070
             // using supplied Domain object
1071
-            $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface
1072
-                ? self::$_settings[ $addon_name ]['domain']
1071
+            $domain = self::$_settings[$addon_name]['domain'] instanceof DomainInterface
1072
+                ? self::$_settings[$addon_name]['domain']
1073 1073
                 : null;
1074 1074
             // or construct one using Domain FQCN
1075
-            if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') {
1075
+            if ($domain === null && self::$_settings[$addon_name]['domain_fqcn'] !== '') {
1076 1076
                 $domain = LoaderFactory::getLoader()->getShared(
1077
-                    self::$_settings[ $addon_name ]['domain_fqcn'],
1077
+                    self::$_settings[$addon_name]['domain_fqcn'],
1078 1078
                     [
1079 1079
                         new EventEspresso\core\domain\values\FilePath(
1080
-                            self::$_settings[ $addon_name ]['main_file_path']
1080
+                            self::$_settings[$addon_name]['main_file_path']
1081 1081
                         ),
1082 1082
                         EventEspresso\core\domain\values\Version::fromString(
1083
-                            self::$_settings[ $addon_name ]['version']
1083
+                            self::$_settings[$addon_name]['version']
1084 1084
                         ),
1085 1085
                     ]
1086 1086
                 );
@@ -1103,11 +1103,11 @@  discard block
 block discarded – undo
1103 1103
     public static function load_pue_update()
1104 1104
     {
1105 1105
         // load PUE client
1106
-        require_once EE_THIRD_PARTY . 'pue/pue-client.php';
1106
+        require_once EE_THIRD_PARTY.'pue/pue-client.php';
1107 1107
         $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com';
1108 1108
         // cycle thru settings
1109 1109
         foreach (self::$_settings as $settings) {
1110
-            if (! empty($settings['pue_options'])) {
1110
+            if ( ! empty($settings['pue_options'])) {
1111 1111
                 // initiate the class and start the plugin update engine!
1112 1112
                 new PluginUpdateEngineChecker(
1113 1113
                     // host file URL
@@ -1115,7 +1115,7 @@  discard block
 block discarded – undo
1115 1115
                     // plugin slug(s)
1116 1116
                     array(
1117 1117
                         'premium'    => array('p' => $settings['pue_options']['pue_plugin_slug']),
1118
-                        'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'),
1118
+                        'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'].'-pr'),
1119 1119
                     ),
1120 1120
                     // options
1121 1121
                     array(
@@ -1144,7 +1144,7 @@  discard block
 block discarded – undo
1144 1144
     public static function register_message_types()
1145 1145
     {
1146 1146
         foreach (self::$_settings as $settings) {
1147
-            if (! empty($settings['message_types'])) {
1147
+            if ( ! empty($settings['message_types'])) {
1148 1148
                 foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) {
1149 1149
                     EE_Register_Message_Type::register($message_type, $message_type_settings);
1150 1150
                 }
@@ -1165,70 +1165,70 @@  discard block
 block discarded – undo
1165 1165
      */
1166 1166
     public static function deregister($addon_name = '')
1167 1167
     {
1168
-        if (isset(self::$_settings[ $addon_name ]['class_name'])) {
1168
+        if (isset(self::$_settings[$addon_name]['class_name'])) {
1169 1169
             try {
1170 1170
                 do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name);
1171
-                $class_name = self::$_settings[ $addon_name ]['class_name'];
1172
-                if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) {
1171
+                $class_name = self::$_settings[$addon_name]['class_name'];
1172
+                if ( ! empty(self::$_settings[$addon_name]['dms_paths'])) {
1173 1173
                     // setup DMS
1174 1174
                     EE_Register_Data_Migration_Scripts::deregister($addon_name);
1175 1175
                 }
1176
-                if (! empty(self::$_settings[ $addon_name ]['admin_path'])) {
1176
+                if ( ! empty(self::$_settings[$addon_name]['admin_path'])) {
1177 1177
                     // register admin page
1178 1178
                     EE_Register_Admin_Page::deregister($addon_name);
1179 1179
                 }
1180
-                if (! empty(self::$_settings[ $addon_name ]['module_paths'])) {
1180
+                if ( ! empty(self::$_settings[$addon_name]['module_paths'])) {
1181 1181
                     // add to list of modules to be registered
1182 1182
                     EE_Register_Module::deregister($addon_name);
1183 1183
                 }
1184
-                if (! empty(self::$_settings[ $addon_name ]['shortcode_paths'])
1185
-                    || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns'])
1184
+                if ( ! empty(self::$_settings[$addon_name]['shortcode_paths'])
1185
+                    || ! empty(self::$_settings[$addon_name]['shortcode_fqcns'])
1186 1186
                 ) {
1187 1187
                     // add to list of shortcodes to be registered
1188 1188
                     EE_Register_Shortcode::deregister($addon_name);
1189 1189
                 }
1190
-                if (! empty(self::$_settings[ $addon_name ]['config_class'])) {
1190
+                if ( ! empty(self::$_settings[$addon_name]['config_class'])) {
1191 1191
                     // if config_class present let's register config.
1192
-                    EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']);
1192
+                    EE_Register_Config::deregister(self::$_settings[$addon_name]['config_class']);
1193 1193
                 }
1194
-                if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) {
1194
+                if ( ! empty(self::$_settings[$addon_name]['widget_paths'])) {
1195 1195
                     // add to list of widgets to be registered
1196 1196
                     EE_Register_Widget::deregister($addon_name);
1197 1197
                 }
1198
-                if (! empty(self::$_settings[ $addon_name ]['model_paths'])
1199
-                    || ! empty(self::$_settings[ $addon_name ]['class_paths'])
1198
+                if ( ! empty(self::$_settings[$addon_name]['model_paths'])
1199
+                    || ! empty(self::$_settings[$addon_name]['class_paths'])
1200 1200
                 ) {
1201 1201
                     // add to list of shortcodes to be registered
1202 1202
                     EE_Register_Model::deregister($addon_name);
1203 1203
                 }
1204
-                if (! empty(self::$_settings[ $addon_name ]['model_extension_paths'])
1205
-                    || ! empty(self::$_settings[ $addon_name ]['class_extension_paths'])
1204
+                if ( ! empty(self::$_settings[$addon_name]['model_extension_paths'])
1205
+                    || ! empty(self::$_settings[$addon_name]['class_extension_paths'])
1206 1206
                 ) {
1207 1207
                     // add to list of shortcodes to be registered
1208 1208
                     EE_Register_Model_Extensions::deregister($addon_name);
1209 1209
                 }
1210
-                if (! empty(self::$_settings[ $addon_name ]['message_types'])) {
1211
-                    foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) {
1210
+                if ( ! empty(self::$_settings[$addon_name]['message_types'])) {
1211
+                    foreach ((array) self::$_settings[$addon_name]['message_types'] as $message_type => $message_type_settings) {
1212 1212
                         EE_Register_Message_Type::deregister($message_type);
1213 1213
                     }
1214 1214
                 }
1215 1215
                 // deregister capabilities for addon
1216
-                if (! empty(self::$_settings[ $addon_name ]['capabilities'])
1217
-                    || ! empty(self::$_settings[ $addon_name ]['capability_maps'])
1216
+                if ( ! empty(self::$_settings[$addon_name]['capabilities'])
1217
+                    || ! empty(self::$_settings[$addon_name]['capability_maps'])
1218 1218
                 ) {
1219 1219
                     EE_Register_Capabilities::deregister($addon_name);
1220 1220
                 }
1221 1221
                 // deregister custom_post_types for addon
1222
-                if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) {
1222
+                if ( ! empty(self::$_settings[$addon_name]['custom_post_types'])) {
1223 1223
                     EE_Register_CPT::deregister($addon_name);
1224 1224
                 }
1225
-                if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) {
1225
+                if ( ! empty(self::$_settings[$addon_name]['payment_method_paths'])) {
1226 1226
                     EE_Register_Payment_Method::deregister($addon_name);
1227 1227
                 }
1228 1228
                 $addon = EE_Registry::instance()->getAddon($class_name);
1229 1229
                 if ($addon instanceof EE_Addon) {
1230 1230
                     remove_action(
1231
-                        'deactivate_' . $addon->get_main_plugin_file_basename(),
1231
+                        'deactivate_'.$addon->get_main_plugin_file_basename(),
1232 1232
                         array($addon, 'deactivation')
1233 1233
                     );
1234 1234
                     remove_action(
@@ -1251,7 +1251,7 @@  discard block
 block discarded – undo
1251 1251
             } catch (Exception $e) {
1252 1252
                 new ExceptionLogger($e);
1253 1253
             }
1254
-            unset(self::$_settings[ $addon_name ]);
1254
+            unset(self::$_settings[$addon_name]);
1255 1255
             do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name);
1256 1256
         }
1257 1257
     }
Please login to merge, or discard this patch.
core/EE_System.core.php 1 patch
Indentation   +1308 added lines, -1308 removed lines patch added patch discarded remove patch
@@ -27,1312 +27,1312 @@
 block discarded – undo
27 27
 final class EE_System implements ResettableInterface
28 28
 {
29 29
 
30
-    /**
31
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
-     */
34
-    const req_type_normal = 0;
35
-
36
-    /**
37
-     * Indicates this is a brand new installation of EE so we should install
38
-     * tables and default data etc
39
-     */
40
-    const req_type_new_activation = 1;
41
-
42
-    /**
43
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
-     * and we just exited maintenance mode). We MUST check the database is setup properly
45
-     * and that default data is setup too
46
-     */
47
-    const req_type_reactivation = 2;
48
-
49
-    /**
50
-     * indicates that EE has been upgraded since its previous request.
51
-     * We may have data migration scripts to call and will want to trigger maintenance mode
52
-     */
53
-    const req_type_upgrade = 3;
54
-
55
-    /**
56
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
-     */
58
-    const req_type_downgrade = 4;
59
-
60
-    /**
61
-     * @deprecated since version 4.6.0.dev.006
62
-     * Now whenever a new_activation is detected the request type is still just
63
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
-     * (Specifically, when the migration manager indicates migrations are finished
67
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
-     */
69
-    const req_type_activation_but_not_installed = 5;
70
-
71
-    /**
72
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
-     */
74
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
-
76
-    /**
77
-     * @var EE_System $_instance
78
-     */
79
-    private static $_instance;
80
-
81
-    /**
82
-     * @var EE_Registry $registry
83
-     */
84
-    private $registry;
85
-
86
-    /**
87
-     * @var LoaderInterface $loader
88
-     */
89
-    private $loader;
90
-
91
-    /**
92
-     * @var EE_Capabilities $capabilities
93
-     */
94
-    private $capabilities;
95
-
96
-    /**
97
-     * @var RequestInterface $request
98
-     */
99
-    private $request;
100
-
101
-    /**
102
-     * @var EE_Maintenance_Mode $maintenance_mode
103
-     */
104
-    private $maintenance_mode;
105
-
106
-    /**
107
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
-     *
110
-     * @var int $_req_type
111
-     */
112
-    private $_req_type;
113
-
114
-    /**
115
-     * Whether or not there was a non-micro version change in EE core version during this request
116
-     *
117
-     * @var boolean $_major_version_change
118
-     */
119
-    private $_major_version_change = false;
120
-
121
-    /**
122
-     * A Context DTO dedicated solely to identifying the current request type.
123
-     *
124
-     * @var RequestTypeContextCheckerInterface $request_type
125
-     */
126
-    private $request_type;
127
-
128
-
129
-    /**
130
-     * @singleton method used to instantiate class object
131
-     * @param EE_Registry|null         $registry
132
-     * @param LoaderInterface|null     $loader
133
-     * @param RequestInterface|null    $request
134
-     * @param EE_Maintenance_Mode|null $maintenance_mode
135
-     * @return EE_System
136
-     */
137
-    public static function instance(
138
-        EE_Registry $registry = null,
139
-        LoaderInterface $loader = null,
140
-        RequestInterface $request = null,
141
-        EE_Maintenance_Mode $maintenance_mode = null
142
-    ) {
143
-        // check if class object is instantiated
144
-        if (! self::$_instance instanceof EE_System) {
145
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
-        }
147
-        return self::$_instance;
148
-    }
149
-
150
-
151
-    /**
152
-     * resets the instance and returns it
153
-     *
154
-     * @return EE_System
155
-     */
156
-    public static function reset()
157
-    {
158
-        self::$_instance->_req_type = null;
159
-        // make sure none of the old hooks are left hanging around
160
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
-        // we need to reset the migration manager in order for it to detect DMSs properly
162
-        EE_Data_Migration_Manager::reset();
163
-        self::instance()->detect_activations_or_upgrades();
164
-        self::instance()->perform_activations_upgrades_and_migrations();
165
-        return self::instance();
166
-    }
167
-
168
-
169
-    /**
170
-     * sets hooks for running rest of system
171
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
-     * starting EE Addons from any other point may lead to problems
173
-     *
174
-     * @param EE_Registry         $registry
175
-     * @param LoaderInterface     $loader
176
-     * @param RequestInterface    $request
177
-     * @param EE_Maintenance_Mode $maintenance_mode
178
-     */
179
-    private function __construct(
180
-        EE_Registry $registry,
181
-        LoaderInterface $loader,
182
-        RequestInterface $request,
183
-        EE_Maintenance_Mode $maintenance_mode
184
-    ) {
185
-        $this->registry = $registry;
186
-        $this->loader = $loader;
187
-        $this->request = $request;
188
-        $this->maintenance_mode = $maintenance_mode;
189
-        do_action('AHEE__EE_System__construct__begin', $this);
190
-        add_action(
191
-            'AHEE__EE_Bootstrap__load_espresso_addons',
192
-            array($this, 'loadCapabilities'),
193
-            5
194
-        );
195
-        add_action(
196
-            'AHEE__EE_Bootstrap__load_espresso_addons',
197
-            array($this, 'loadCommandBus'),
198
-            7
199
-        );
200
-        add_action(
201
-            'AHEE__EE_Bootstrap__load_espresso_addons',
202
-            array($this, 'loadPluginApi'),
203
-            9
204
-        );
205
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
-        add_action(
207
-            'AHEE__EE_Bootstrap__load_espresso_addons',
208
-            array($this, 'load_espresso_addons')
209
-        );
210
-        // when an ee addon is activated, we want to call the core hook(s) again
211
-        // because the newly-activated addon didn't get a chance to run at all
212
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
-        // detect whether install or upgrade
214
-        add_action(
215
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
-            array($this, 'detect_activations_or_upgrades'),
217
-            3
218
-        );
219
-        // load EE_Config, EE_Textdomain, etc
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_core_configuration',
222
-            array($this, 'load_core_configuration'),
223
-            5
224
-        );
225
-        // load specifications for matching routes to current request
226
-        add_action(
227
-            'AHEE__EE_Bootstrap__load_core_configuration',
228
-            array($this, 'loadRouteMatchSpecifications')
229
-        );
230
-        // load EE_Config, EE_Textdomain, etc
231
-        add_action(
232
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
-            array($this, 'register_shortcodes_modules_and_widgets'),
234
-            7
235
-        );
236
-        // you wanna get going? I wanna get going... let's get going!
237
-        add_action(
238
-            'AHEE__EE_Bootstrap__brew_espresso',
239
-            array($this, 'brew_espresso'),
240
-            9
241
-        );
242
-        // other housekeeping
243
-        // exclude EE critical pages from wp_list_pages
244
-        add_filter(
245
-            'wp_list_pages_excludes',
246
-            array($this, 'remove_pages_from_wp_list_pages'),
247
-            10
248
-        );
249
-        // ALL EE Addons should use the following hook point to attach their initial setup too
250
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
-        do_action('AHEE__EE_System__construct__complete', $this);
252
-    }
253
-
254
-
255
-    /**
256
-     * load and setup EE_Capabilities
257
-     *
258
-     * @return void
259
-     * @throws EE_Error
260
-     */
261
-    public function loadCapabilities()
262
-    {
263
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
264
-        add_action(
265
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
266
-            function () {
267
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
-            }
269
-        );
270
-    }
271
-
272
-
273
-    /**
274
-     * create and cache the CommandBus, and also add middleware
275
-     * The CapChecker middleware requires the use of EE_Capabilities
276
-     * which is why we need to load the CommandBus after Caps are set up
277
-     *
278
-     * @return void
279
-     * @throws EE_Error
280
-     */
281
-    public function loadCommandBus()
282
-    {
283
-        $this->loader->getShared(
284
-            'CommandBusInterface',
285
-            array(
286
-                null,
287
-                apply_filters(
288
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
-                    array(
290
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
-                    )
293
-                ),
294
-            )
295
-        );
296
-    }
297
-
298
-
299
-    /**
300
-     * @return void
301
-     * @throws EE_Error
302
-     */
303
-    public function loadPluginApi()
304
-    {
305
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
306
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
307
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
-        $this->loader->getShared('EE_Request_Handler');
309
-    }
310
-
311
-
312
-    /**
313
-     * @param string $addon_name
314
-     * @param string $version_constant
315
-     * @param string $min_version_required
316
-     * @param string $load_callback
317
-     * @param string $plugin_file_constant
318
-     * @return void
319
-     */
320
-    private function deactivateIncompatibleAddon(
321
-        $addon_name,
322
-        $version_constant,
323
-        $min_version_required,
324
-        $load_callback,
325
-        $plugin_file_constant
326
-    ) {
327
-        if (! defined($version_constant)) {
328
-            return;
329
-        }
330
-        $addon_version = constant($version_constant);
331
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
-            if (! function_exists('deactivate_plugins')) {
334
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
-            }
336
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
-            unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
-            EE_Error::add_error(
339
-                sprintf(
340
-                    esc_html__(
341
-                        'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
342
-                        'event_espresso'
343
-                    ),
344
-                    $addon_name,
345
-                    $min_version_required
346
-                ),
347
-                __FILE__,
348
-                __FUNCTION__ . "({$addon_name})",
349
-                __LINE__
350
-            );
351
-            EE_Error::get_notices(false, true);
352
-        }
353
-    }
354
-
355
-
356
-    /**
357
-     * load_espresso_addons
358
-     * allow addons to load first so that they can set hooks for running DMS's, etc
359
-     * this is hooked into both:
360
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
361
-     *        which runs during the WP 'plugins_loaded' action at priority 5
362
-     *    and the WP 'activate_plugin' hook point
363
-     *
364
-     * @access public
365
-     * @return void
366
-     */
367
-    public function load_espresso_addons()
368
-    {
369
-        $this->deactivateIncompatibleAddon(
370
-            'Wait Lists',
371
-            'EE_WAIT_LISTS_VERSION',
372
-            '1.0.0.beta.074',
373
-            'load_espresso_wait_lists',
374
-            'EE_WAIT_LISTS_PLUGIN_FILE'
375
-        );
376
-        $this->deactivateIncompatibleAddon(
377
-            'Automated Upcoming Event Notifications',
378
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
-            '1.0.0.beta.091',
380
-            'load_espresso_automated_upcoming_event_notification',
381
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
-        );
383
-        do_action('AHEE__EE_System__load_espresso_addons');
384
-        // if the WP API basic auth plugin isn't already loaded, load it now.
385
-        // We want it for mobile apps. Just include the entire plugin
386
-        // also, don't load the basic auth when a plugin is getting activated, because
387
-        // it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
-        // and causes a fatal error
389
-        if (($this->request->isWordPressApi() || $this->request->isApi())
390
-            && $this->request->getRequestParam('activate') !== 'true'
391
-            && ! function_exists('json_basic_auth_handler')
392
-            && ! function_exists('json_basic_auth_error')
393
-            && ! in_array(
394
-                $this->request->getRequestParam('action'),
395
-                array('activate', 'activate-selected'),
396
-                true
397
-            )
398
-        ) {
399
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
400
-        }
401
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
402
-    }
403
-
404
-
405
-    /**
406
-     * detect_activations_or_upgrades
407
-     * Checks for activation or upgrade of core first;
408
-     * then also checks if any registered addons have been activated or upgraded
409
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
410
-     * which runs during the WP 'plugins_loaded' action at priority 3
411
-     *
412
-     * @access public
413
-     * @return void
414
-     */
415
-    public function detect_activations_or_upgrades()
416
-    {
417
-        // first off: let's make sure to handle core
418
-        $this->detect_if_activation_or_upgrade();
419
-        foreach ($this->registry->addons as $addon) {
420
-            if ($addon instanceof EE_Addon) {
421
-                // detect teh request type for that addon
422
-                $addon->detect_req_type();
423
-            }
424
-        }
425
-    }
426
-
427
-
428
-    /**
429
-     * detect_if_activation_or_upgrade
430
-     * Takes care of detecting whether this is a brand new install or code upgrade,
431
-     * and either setting up the DB or setting up maintenance mode etc.
432
-     *
433
-     * @access public
434
-     * @return void
435
-     */
436
-    public function detect_if_activation_or_upgrade()
437
-    {
438
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
439
-        // check if db has been updated, or if its a brand-new installation
440
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
441
-        $request_type = $this->detect_req_type($espresso_db_update);
442
-        switch ($request_type) {
443
-            case EE_System::req_type_new_activation:
444
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
445
-                $this->_handle_core_version_change($espresso_db_update);
446
-                break;
447
-            case EE_System::req_type_reactivation:
448
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
449
-                $this->_handle_core_version_change($espresso_db_update);
450
-                break;
451
-            case EE_System::req_type_upgrade:
452
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
453
-                // migrations may be required now that we've upgraded
454
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
455
-                $this->_handle_core_version_change($espresso_db_update);
456
-                break;
457
-            case EE_System::req_type_downgrade:
458
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
459
-                // its possible migrations are no longer required
460
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
461
-                $this->_handle_core_version_change($espresso_db_update);
462
-                break;
463
-            case EE_System::req_type_normal:
464
-            default:
465
-                break;
466
-        }
467
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
468
-    }
469
-
470
-
471
-    /**
472
-     * Updates the list of installed versions and sets hooks for
473
-     * initializing the database later during the request
474
-     *
475
-     * @param array $espresso_db_update
476
-     */
477
-    private function _handle_core_version_change($espresso_db_update)
478
-    {
479
-        $this->update_list_of_installed_versions($espresso_db_update);
480
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
481
-        add_action(
482
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
483
-            array($this, 'initialize_db_if_no_migrations_required')
484
-        );
485
-    }
486
-
487
-
488
-    /**
489
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
490
-     * information about what versions of EE have been installed and activated,
491
-     * NOT necessarily the state of the database
492
-     *
493
-     * @param mixed $espresso_db_update           the value of the WordPress option.
494
-     *                                            If not supplied, fetches it from the options table
495
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
496
-     */
497
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
498
-    {
499
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
500
-        if (! $espresso_db_update) {
501
-            $espresso_db_update = get_option('espresso_db_update');
502
-        }
503
-        // check that option is an array
504
-        if (! is_array($espresso_db_update)) {
505
-            // if option is FALSE, then it never existed
506
-            if ($espresso_db_update === false) {
507
-                // make $espresso_db_update an array and save option with autoload OFF
508
-                $espresso_db_update = array();
509
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
510
-            } else {
511
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
512
-                $espresso_db_update = array($espresso_db_update => array());
513
-                update_option('espresso_db_update', $espresso_db_update);
514
-            }
515
-        } else {
516
-            $corrected_db_update = array();
517
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
518
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
519
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
520
-                    // the key is an int, and the value IS NOT an array
521
-                    // so it must be numerically-indexed, where values are versions installed...
522
-                    // fix it!
523
-                    $version_string = $should_be_array;
524
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
525
-                } else {
526
-                    // ok it checks out
527
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
528
-                }
529
-            }
530
-            $espresso_db_update = $corrected_db_update;
531
-            update_option('espresso_db_update', $espresso_db_update);
532
-        }
533
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
534
-        return $espresso_db_update;
535
-    }
536
-
537
-
538
-    /**
539
-     * Does the traditional work of setting up the plugin's database and adding default data.
540
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
541
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
542
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
543
-     * so that it will be done when migrations are finished
544
-     *
545
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
546
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
547
-     *                                       This is a resource-intensive job
548
-     *                                       so we prefer to only do it when necessary
549
-     * @return void
550
-     * @throws EE_Error
551
-     */
552
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
553
-    {
554
-        $request_type = $this->detect_req_type();
555
-        // only initialize system if we're not in maintenance mode.
556
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
557
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
558
-            $rewrite_rules = $this->loader->getShared(
559
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
560
-            );
561
-            $rewrite_rules->flush();
562
-            if ($verify_schema) {
563
-                EEH_Activation::initialize_db_and_folders();
564
-            }
565
-            EEH_Activation::initialize_db_content();
566
-            EEH_Activation::system_initialization();
567
-            if ($initialize_addons_too) {
568
-                $this->initialize_addons();
569
-            }
570
-        } else {
571
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
572
-        }
573
-        if ($request_type === EE_System::req_type_new_activation
574
-            || $request_type === EE_System::req_type_reactivation
575
-            || (
576
-                $request_type === EE_System::req_type_upgrade
577
-                && $this->is_major_version_change()
578
-            )
579
-        ) {
580
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
581
-        }
582
-    }
583
-
584
-
585
-    /**
586
-     * Initializes the db for all registered addons
587
-     *
588
-     * @throws EE_Error
589
-     */
590
-    public function initialize_addons()
591
-    {
592
-        // foreach registered addon, make sure its db is up-to-date too
593
-        foreach ($this->registry->addons as $addon) {
594
-            if ($addon instanceof EE_Addon) {
595
-                $addon->initialize_db_if_no_migrations_required();
596
-            }
597
-        }
598
-    }
599
-
600
-
601
-    /**
602
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
603
-     *
604
-     * @param    array  $version_history
605
-     * @param    string $current_version_to_add version to be added to the version history
606
-     * @return    boolean success as to whether or not this option was changed
607
-     */
608
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
609
-    {
610
-        if (! $version_history) {
611
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
612
-        }
613
-        if ($current_version_to_add === null) {
614
-            $current_version_to_add = espresso_version();
615
-        }
616
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
617
-        // re-save
618
-        return update_option('espresso_db_update', $version_history);
619
-    }
620
-
621
-
622
-    /**
623
-     * Detects if the current version indicated in the has existed in the list of
624
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
625
-     *
626
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
627
-     *                                  If not supplied, fetches it from the options table.
628
-     *                                  Also, caches its result so later parts of the code can also know whether
629
-     *                                  there's been an update or not. This way we can add the current version to
630
-     *                                  espresso_db_update, but still know if this is a new install or not
631
-     * @return int one of the constants on EE_System::req_type_
632
-     */
633
-    public function detect_req_type($espresso_db_update = null)
634
-    {
635
-        if ($this->_req_type === null) {
636
-            $espresso_db_update = ! empty($espresso_db_update)
637
-                ? $espresso_db_update
638
-                : $this->fix_espresso_db_upgrade_option();
639
-            $this->_req_type = EE_System::detect_req_type_given_activation_history(
640
-                $espresso_db_update,
641
-                'ee_espresso_activation',
642
-                espresso_version()
643
-            );
644
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
645
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
646
-        }
647
-        return $this->_req_type;
648
-    }
649
-
650
-
651
-    /**
652
-     * Returns whether or not there was a non-micro version change (ie, change in either
653
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
654
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
655
-     *
656
-     * @param $activation_history
657
-     * @return bool
658
-     */
659
-    private function _detect_major_version_change($activation_history)
660
-    {
661
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
662
-        $previous_version_parts = explode('.', $previous_version);
663
-        $current_version_parts = explode('.', espresso_version());
664
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
665
-               && ($previous_version_parts[0] !== $current_version_parts[0]
666
-                   || $previous_version_parts[1] !== $current_version_parts[1]
667
-               );
668
-    }
669
-
670
-
671
-    /**
672
-     * Returns true if either the major or minor version of EE changed during this request.
673
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
674
-     *
675
-     * @return bool
676
-     */
677
-    public function is_major_version_change()
678
-    {
679
-        return $this->_major_version_change;
680
-    }
681
-
682
-
683
-    /**
684
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
685
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
686
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
687
-     * just activated to (for core that will always be espresso_version())
688
-     *
689
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
690
-     *                                                 ee plugin. for core that's 'espresso_db_update'
691
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
692
-     *                                                 indicate that this plugin was just activated
693
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
694
-     *                                                 espresso_version())
695
-     * @return int one of the constants on EE_System::req_type_*
696
-     */
697
-    public static function detect_req_type_given_activation_history(
698
-        $activation_history_for_addon,
699
-        $activation_indicator_option_name,
700
-        $version_to_upgrade_to
701
-    ) {
702
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
703
-        if ($activation_history_for_addon) {
704
-            // it exists, so this isn't a completely new install
705
-            // check if this version already in that list of previously installed versions
706
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
707
-                // it a version we haven't seen before
708
-                if ($version_is_higher === 1) {
709
-                    $req_type = EE_System::req_type_upgrade;
710
-                } else {
711
-                    $req_type = EE_System::req_type_downgrade;
712
-                }
713
-                delete_option($activation_indicator_option_name);
714
-            } else {
715
-                // its not an update. maybe a reactivation?
716
-                if (get_option($activation_indicator_option_name, false)) {
717
-                    if ($version_is_higher === -1) {
718
-                        $req_type = EE_System::req_type_downgrade;
719
-                    } elseif ($version_is_higher === 0) {
720
-                        // we've seen this version before, but it's an activation. must be a reactivation
721
-                        $req_type = EE_System::req_type_reactivation;
722
-                    } else {// $version_is_higher === 1
723
-                        $req_type = EE_System::req_type_upgrade;
724
-                    }
725
-                    delete_option($activation_indicator_option_name);
726
-                } else {
727
-                    // we've seen this version before and the activation indicate doesn't show it was just activated
728
-                    if ($version_is_higher === -1) {
729
-                        $req_type = EE_System::req_type_downgrade;
730
-                    } elseif ($version_is_higher === 0) {
731
-                        // we've seen this version before and it's not an activation. its normal request
732
-                        $req_type = EE_System::req_type_normal;
733
-                    } else {// $version_is_higher === 1
734
-                        $req_type = EE_System::req_type_upgrade;
735
-                    }
736
-                }
737
-            }
738
-        } else {
739
-            // brand new install
740
-            $req_type = EE_System::req_type_new_activation;
741
-            delete_option($activation_indicator_option_name);
742
-        }
743
-        return $req_type;
744
-    }
745
-
746
-
747
-    /**
748
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
749
-     * the $activation_history_for_addon
750
-     *
751
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
752
-     *                                             sometimes containing 'unknown-date'
753
-     * @param string $version_to_upgrade_to        (current version)
754
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
755
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
756
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
757
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
758
-     */
759
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
760
-    {
761
-        // find the most recently-activated version
762
-        $most_recently_active_version =
763
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
764
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
765
-    }
766
-
767
-
768
-    /**
769
-     * Gets the most recently active version listed in the activation history,
770
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
771
-     *
772
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
773
-     *                                   sometimes containing 'unknown-date'
774
-     * @return string
775
-     */
776
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
777
-    {
778
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
779
-        $most_recently_active_version = '0.0.0.dev.000';
780
-        if (is_array($activation_history)) {
781
-            foreach ($activation_history as $version => $times_activated) {
782
-                // check there is a record of when this version was activated. Otherwise,
783
-                // mark it as unknown
784
-                if (! $times_activated) {
785
-                    $times_activated = array('unknown-date');
786
-                }
787
-                if (is_string($times_activated)) {
788
-                    $times_activated = array($times_activated);
789
-                }
790
-                foreach ($times_activated as $an_activation) {
791
-                    if ($an_activation !== 'unknown-date'
792
-                        && $an_activation
793
-                           > $most_recently_active_version_activation) {
794
-                        $most_recently_active_version = $version;
795
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
796
-                            ? '1970-01-01 00:00:00'
797
-                            : $an_activation;
798
-                    }
799
-                }
800
-            }
801
-        }
802
-        return $most_recently_active_version;
803
-    }
804
-
805
-
806
-    /**
807
-     * This redirects to the about EE page after activation
808
-     *
809
-     * @return void
810
-     */
811
-    public function redirect_to_about_ee()
812
-    {
813
-        $notices = EE_Error::get_notices(false);
814
-        // if current user is an admin and it's not an ajax or rest request
815
-        if (! isset($notices['errors'])
816
-            && $this->request->isAdmin()
817
-            && apply_filters(
818
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
819
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
820
-            )
821
-        ) {
822
-            $query_params = array('page' => 'espresso_about');
823
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
824
-                $query_params['new_activation'] = true;
825
-            }
826
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
827
-                $query_params['reactivation'] = true;
828
-            }
829
-            $url = add_query_arg($query_params, admin_url('admin.php'));
830
-            wp_safe_redirect($url);
831
-            exit();
832
-        }
833
-    }
834
-
835
-
836
-    /**
837
-     * load_core_configuration
838
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
839
-     * which runs during the WP 'plugins_loaded' action at priority 5
840
-     *
841
-     * @return void
842
-     * @throws ReflectionException
843
-     * @throws Exception
844
-     */
845
-    public function load_core_configuration()
846
-    {
847
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
848
-        $this->loader->getShared('EE_Load_Textdomain');
849
-        // load textdomain
850
-        EE_Load_Textdomain::load_textdomain();
851
-        // load caf stuff a chance to play during the activation process too.
852
-        $this->_maybe_brew_regular();
853
-        // load and setup EE_Config and EE_Network_Config
854
-        $config = $this->loader->getShared('EE_Config');
855
-        $this->loader->getShared('EE_Network_Config');
856
-        // setup autoloaders
857
-        // enable logging?
858
-        if ($config->admin->use_remote_logging) {
859
-            $this->loader->getShared('EE_Log');
860
-        }
861
-        // check for activation errors
862
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
863
-        if ($activation_errors) {
864
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
865
-            update_option('ee_plugin_activation_errors', false);
866
-        }
867
-        // get model names
868
-        $this->_parse_model_names();
869
-        // configure custom post type definitions
870
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
871
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
872
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
873
-    }
874
-
875
-
876
-    /**
877
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
878
-     *
879
-     * @return void
880
-     * @throws ReflectionException
881
-     */
882
-    private function _parse_model_names()
883
-    {
884
-        // get all the files in the EE_MODELS folder that end in .model.php
885
-        $models = glob(EE_MODELS . '*.model.php');
886
-        $model_names = array();
887
-        $non_abstract_db_models = array();
888
-        foreach ($models as $model) {
889
-            // get model classname
890
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
891
-            $short_name = str_replace('EEM_', '', $classname);
892
-            $reflectionClass = new ReflectionClass($classname);
893
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
894
-                $non_abstract_db_models[ $short_name ] = $classname;
895
-            }
896
-            $model_names[ $short_name ] = $classname;
897
-        }
898
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
899
-        $this->registry->non_abstract_db_models = apply_filters(
900
-            'FHEE__EE_System__parse_implemented_model_names',
901
-            $non_abstract_db_models
902
-        );
903
-    }
904
-
905
-
906
-    /**
907
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
908
-     * that need to be setup before our EE_System launches.
909
-     *
910
-     * @return void
911
-     * @throws DomainException
912
-     * @throws InvalidArgumentException
913
-     * @throws InvalidDataTypeException
914
-     * @throws InvalidInterfaceException
915
-     * @throws InvalidClassException
916
-     * @throws InvalidFilePathException
917
-     */
918
-    private function _maybe_brew_regular()
919
-    {
920
-        /** @var Domain $domain */
921
-        $domain = DomainFactory::getShared(
922
-            new FullyQualifiedName(
923
-                'EventEspresso\core\domain\Domain'
924
-            ),
925
-            array(
926
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
927
-                Version::fromString(espresso_version()),
928
-            )
929
-        );
930
-        if ($domain->isCaffeinated()) {
931
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
932
-        }
933
-    }
934
-
935
-
936
-    /**
937
-     * @since 4.9.71.p
938
-     * @throws Exception
939
-     */
940
-    public function loadRouteMatchSpecifications()
941
-    {
942
-        try {
943
-            $this->loader->getShared(
944
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
945
-            );
946
-        } catch (Exception $exception) {
947
-            new ExceptionStackTraceDisplay($exception);
948
-        }
949
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
950
-    }
951
-
952
-
953
-    /**
954
-     * register_shortcodes_modules_and_widgets
955
-     * generate lists of shortcodes and modules, then verify paths and classes
956
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
957
-     * which runs during the WP 'plugins_loaded' action at priority 7
958
-     *
959
-     * @access public
960
-     * @return void
961
-     * @throws Exception
962
-     */
963
-    public function register_shortcodes_modules_and_widgets()
964
-    {
965
-        if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
966
-            try {
967
-                // load, register, and add shortcodes the new way
968
-                $this->loader->getShared(
969
-                    'EventEspresso\core\services\shortcodes\ShortcodesManager',
970
-                    array(
971
-                        // and the old way, but we'll put it under control of the new system
972
-                        EE_Config::getLegacyShortcodesManager(),
973
-                    )
974
-                );
975
-            } catch (Exception $exception) {
976
-                new ExceptionStackTraceDisplay($exception);
977
-            }
978
-        }
979
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
980
-        // check for addons using old hook point
981
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
982
-            $this->_incompatible_addon_error();
983
-        }
984
-    }
985
-
986
-
987
-    /**
988
-     * _incompatible_addon_error
989
-     *
990
-     * @access public
991
-     * @return void
992
-     */
993
-    private function _incompatible_addon_error()
994
-    {
995
-        // get array of classes hooking into here
996
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
997
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
998
-        );
999
-        if (! empty($class_names)) {
1000
-            $msg = __(
1001
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1002
-                'event_espresso'
1003
-            );
1004
-            $msg .= '<ul>';
1005
-            foreach ($class_names as $class_name) {
1006
-                $msg .= '<li><b>Event Espresso - '
1007
-                        . str_replace(
1008
-                            array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1009
-                            '',
1010
-                            $class_name
1011
-                        ) . '</b></li>';
1012
-            }
1013
-            $msg .= '</ul>';
1014
-            $msg .= __(
1015
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1016
-                'event_espresso'
1017
-            );
1018
-            // save list of incompatible addons to wp-options for later use
1019
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1020
-            if (is_admin()) {
1021
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1022
-            }
1023
-        }
1024
-    }
1025
-
1026
-
1027
-    /**
1028
-     * brew_espresso
1029
-     * begins the process of setting hooks for initializing EE in the correct order
1030
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1031
-     * which runs during the WP 'plugins_loaded' action at priority 9
1032
-     *
1033
-     * @return void
1034
-     */
1035
-    public function brew_espresso()
1036
-    {
1037
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1038
-        // load some final core systems
1039
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1040
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1041
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1042
-        add_action('init', array($this, 'load_controllers'), 7);
1043
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1044
-        add_action('init', array($this, 'initialize'), 10);
1045
-        add_action('init', array($this, 'initialize_last'), 100);
1046
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1047
-            // pew pew pew
1048
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1049
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1050
-        }
1051
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1052
-    }
1053
-
1054
-
1055
-    /**
1056
-     *    set_hooks_for_core
1057
-     *
1058
-     * @access public
1059
-     * @return    void
1060
-     * @throws EE_Error
1061
-     */
1062
-    public function set_hooks_for_core()
1063
-    {
1064
-        $this->_deactivate_incompatible_addons();
1065
-        do_action('AHEE__EE_System__set_hooks_for_core');
1066
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1067
-        // caps need to be initialized on every request so that capability maps are set.
1068
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1069
-        $this->registry->CAP->init_caps();
1070
-    }
1071
-
1072
-
1073
-    /**
1074
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1075
-     * deactivates any addons considered incompatible with the current version of EE
1076
-     */
1077
-    private function _deactivate_incompatible_addons()
1078
-    {
1079
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1080
-        if (! empty($incompatible_addons)) {
1081
-            $active_plugins = get_option('active_plugins', array());
1082
-            foreach ($active_plugins as $active_plugin) {
1083
-                foreach ($incompatible_addons as $incompatible_addon) {
1084
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1085
-                        unset($_GET['activate']);
1086
-                        espresso_deactivate_plugin($active_plugin);
1087
-                    }
1088
-                }
1089
-            }
1090
-        }
1091
-    }
1092
-
1093
-
1094
-    /**
1095
-     *    perform_activations_upgrades_and_migrations
1096
-     *
1097
-     * @access public
1098
-     * @return    void
1099
-     */
1100
-    public function perform_activations_upgrades_and_migrations()
1101
-    {
1102
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1103
-    }
1104
-
1105
-
1106
-    /**
1107
-     * @return void
1108
-     * @throws DomainException
1109
-     */
1110
-    public function load_CPTs_and_session()
1111
-    {
1112
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1113
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1114
-        $register_custom_taxonomies = $this->loader->getShared(
1115
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1116
-        );
1117
-        $register_custom_taxonomies->registerCustomTaxonomies();
1118
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1119
-        $register_custom_post_types = $this->loader->getShared(
1120
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1121
-        );
1122
-        $register_custom_post_types->registerCustomPostTypes();
1123
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1124
-        $register_custom_taxonomy_terms = $this->loader->getShared(
1125
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1126
-        );
1127
-        $register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1128
-        // load legacy Custom Post Types and Taxonomies
1129
-        $this->loader->getShared('EE_Register_CPTs');
1130
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1131
-    }
1132
-
1133
-
1134
-    /**
1135
-     * load_controllers
1136
-     * this is the best place to load any additional controllers that needs access to EE core.
1137
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1138
-     * time
1139
-     *
1140
-     * @access public
1141
-     * @return void
1142
-     */
1143
-    public function load_controllers()
1144
-    {
1145
-        do_action('AHEE__EE_System__load_controllers__start');
1146
-        // let's get it started
1147
-        if (! $this->maintenance_mode->level()
1148
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1149
-        ) {
1150
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1151
-            $this->loader->getShared('EE_Front_Controller');
1152
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1153
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1154
-            $this->loader->getShared('EE_Admin');
1155
-        } elseif ($this->request->isWordPressHeartbeat()) {
1156
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1157
-        }
1158
-        do_action('AHEE__EE_System__load_controllers__complete');
1159
-    }
1160
-
1161
-
1162
-    /**
1163
-     * core_loaded_and_ready
1164
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1165
-     *
1166
-     * @access public
1167
-     * @return void
1168
-     * @throws Exception
1169
-     */
1170
-    public function core_loaded_and_ready()
1171
-    {
1172
-        if ($this->request->isAdmin()
1173
-            || $this->request->isFrontend()
1174
-            || $this->request->isIframe()
1175
-            || $this->request->isWordPressApi()
1176
-        ) {
1177
-            try {
1178
-                $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1179
-                $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1180
-                if ($this->canLoadBlocks()) {
1181
-                    $this->loader->getShared(
1182
-                        'EventEspresso\core\services\editor\BlockRegistrationManager'
1183
-                    );
1184
-                }
1185
-            } catch (Exception $exception) {
1186
-                new ExceptionStackTraceDisplay($exception);
1187
-            }
1188
-        }
1189
-        if ($this->request->isAdmin()
1190
-            || $this->request->isEeAjax()
1191
-            || $this->request->isFrontend()
1192
-        ) {
1193
-            $this->loader->getShared('EE_Session');
1194
-        }
1195
-        // integrate WP_Query with the EE models
1196
-        $this->loader->getShared('EE_CPT_Strategy');
1197
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1198
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1199
-        // builders require these even on the front-end
1200
-        require_once EE_PUBLIC . 'template_tags.php';
1201
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1202
-    }
1203
-
1204
-
1205
-    /**
1206
-     * initialize
1207
-     * this is the best place to begin initializing client code
1208
-     *
1209
-     * @access public
1210
-     * @return void
1211
-     */
1212
-    public function initialize()
1213
-    {
1214
-        do_action('AHEE__EE_System__initialize');
1215
-    }
1216
-
1217
-
1218
-    /**
1219
-     * initialize_last
1220
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1221
-     * initialize has done so
1222
-     *
1223
-     * @access public
1224
-     * @return void
1225
-     */
1226
-    public function initialize_last()
1227
-    {
1228
-        do_action('AHEE__EE_System__initialize_last');
1229
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1230
-        $rewrite_rules = $this->loader->getShared(
1231
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1232
-        );
1233
-        $rewrite_rules->flushRewriteRules();
1234
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1235
-        if (($this->request->isAjax() || $this->request->isAdmin())
1236
-            && $this->maintenance_mode->models_can_query()) {
1237
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1238
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1239
-        }
1240
-    }
1241
-
1242
-
1243
-    /**
1244
-     * @return void
1245
-     * @throws EE_Error
1246
-     */
1247
-    public function addEspressoToolbar()
1248
-    {
1249
-        $this->loader->getShared(
1250
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1251
-            array($this->registry->CAP)
1252
-        );
1253
-    }
1254
-
1255
-
1256
-    /**
1257
-     * do_not_cache
1258
-     * sets no cache headers and defines no cache constants for WP plugins
1259
-     *
1260
-     * @access public
1261
-     * @return void
1262
-     */
1263
-    public static function do_not_cache()
1264
-    {
1265
-        // set no cache constants
1266
-        if (! defined('DONOTCACHEPAGE')) {
1267
-            define('DONOTCACHEPAGE', true);
1268
-        }
1269
-        if (! defined('DONOTCACHCEOBJECT')) {
1270
-            define('DONOTCACHCEOBJECT', true);
1271
-        }
1272
-        if (! defined('DONOTCACHEDB')) {
1273
-            define('DONOTCACHEDB', true);
1274
-        }
1275
-        // add no cache headers
1276
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1277
-        // plus a little extra for nginx and Google Chrome
1278
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1279
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1280
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1281
-    }
1282
-
1283
-
1284
-    /**
1285
-     *    extra_nocache_headers
1286
-     *
1287
-     * @access    public
1288
-     * @param $headers
1289
-     * @return    array
1290
-     */
1291
-    public static function extra_nocache_headers($headers)
1292
-    {
1293
-        // for NGINX
1294
-        $headers['X-Accel-Expires'] = 0;
1295
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1296
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1297
-        return $headers;
1298
-    }
1299
-
1300
-
1301
-    /**
1302
-     *    nocache_headers
1303
-     *
1304
-     * @access    public
1305
-     * @return    void
1306
-     */
1307
-    public static function nocache_headers()
1308
-    {
1309
-        nocache_headers();
1310
-    }
1311
-
1312
-
1313
-    /**
1314
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1315
-     * never returned with the function.
1316
-     *
1317
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1318
-     * @return array
1319
-     */
1320
-    public function remove_pages_from_wp_list_pages($exclude_array)
1321
-    {
1322
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1323
-    }
1324
-
1325
-
1326
-    /**
1327
-     * Return whether blocks can be registered/loaded or not.
1328
-     * @return bool
1329
-     */
1330
-    private function canLoadBlocks()
1331
-    {
1332
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1333
-               && function_exists('register_block_type')
1334
-               // don't load blocks if in the Divi page builder editor context
1335
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
1336
-               && ! $this->request->getRequestParam('et_fb', false);
1337
-    }
30
+	/**
31
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
+	 */
34
+	const req_type_normal = 0;
35
+
36
+	/**
37
+	 * Indicates this is a brand new installation of EE so we should install
38
+	 * tables and default data etc
39
+	 */
40
+	const req_type_new_activation = 1;
41
+
42
+	/**
43
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
45
+	 * and that default data is setup too
46
+	 */
47
+	const req_type_reactivation = 2;
48
+
49
+	/**
50
+	 * indicates that EE has been upgraded since its previous request.
51
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
52
+	 */
53
+	const req_type_upgrade = 3;
54
+
55
+	/**
56
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
+	 */
58
+	const req_type_downgrade = 4;
59
+
60
+	/**
61
+	 * @deprecated since version 4.6.0.dev.006
62
+	 * Now whenever a new_activation is detected the request type is still just
63
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
+	 * (Specifically, when the migration manager indicates migrations are finished
67
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
+	 */
69
+	const req_type_activation_but_not_installed = 5;
70
+
71
+	/**
72
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
+	 */
74
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
+
76
+	/**
77
+	 * @var EE_System $_instance
78
+	 */
79
+	private static $_instance;
80
+
81
+	/**
82
+	 * @var EE_Registry $registry
83
+	 */
84
+	private $registry;
85
+
86
+	/**
87
+	 * @var LoaderInterface $loader
88
+	 */
89
+	private $loader;
90
+
91
+	/**
92
+	 * @var EE_Capabilities $capabilities
93
+	 */
94
+	private $capabilities;
95
+
96
+	/**
97
+	 * @var RequestInterface $request
98
+	 */
99
+	private $request;
100
+
101
+	/**
102
+	 * @var EE_Maintenance_Mode $maintenance_mode
103
+	 */
104
+	private $maintenance_mode;
105
+
106
+	/**
107
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
+	 *
110
+	 * @var int $_req_type
111
+	 */
112
+	private $_req_type;
113
+
114
+	/**
115
+	 * Whether or not there was a non-micro version change in EE core version during this request
116
+	 *
117
+	 * @var boolean $_major_version_change
118
+	 */
119
+	private $_major_version_change = false;
120
+
121
+	/**
122
+	 * A Context DTO dedicated solely to identifying the current request type.
123
+	 *
124
+	 * @var RequestTypeContextCheckerInterface $request_type
125
+	 */
126
+	private $request_type;
127
+
128
+
129
+	/**
130
+	 * @singleton method used to instantiate class object
131
+	 * @param EE_Registry|null         $registry
132
+	 * @param LoaderInterface|null     $loader
133
+	 * @param RequestInterface|null    $request
134
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
135
+	 * @return EE_System
136
+	 */
137
+	public static function instance(
138
+		EE_Registry $registry = null,
139
+		LoaderInterface $loader = null,
140
+		RequestInterface $request = null,
141
+		EE_Maintenance_Mode $maintenance_mode = null
142
+	) {
143
+		// check if class object is instantiated
144
+		if (! self::$_instance instanceof EE_System) {
145
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
+		}
147
+		return self::$_instance;
148
+	}
149
+
150
+
151
+	/**
152
+	 * resets the instance and returns it
153
+	 *
154
+	 * @return EE_System
155
+	 */
156
+	public static function reset()
157
+	{
158
+		self::$_instance->_req_type = null;
159
+		// make sure none of the old hooks are left hanging around
160
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
+		// we need to reset the migration manager in order for it to detect DMSs properly
162
+		EE_Data_Migration_Manager::reset();
163
+		self::instance()->detect_activations_or_upgrades();
164
+		self::instance()->perform_activations_upgrades_and_migrations();
165
+		return self::instance();
166
+	}
167
+
168
+
169
+	/**
170
+	 * sets hooks for running rest of system
171
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
+	 * starting EE Addons from any other point may lead to problems
173
+	 *
174
+	 * @param EE_Registry         $registry
175
+	 * @param LoaderInterface     $loader
176
+	 * @param RequestInterface    $request
177
+	 * @param EE_Maintenance_Mode $maintenance_mode
178
+	 */
179
+	private function __construct(
180
+		EE_Registry $registry,
181
+		LoaderInterface $loader,
182
+		RequestInterface $request,
183
+		EE_Maintenance_Mode $maintenance_mode
184
+	) {
185
+		$this->registry = $registry;
186
+		$this->loader = $loader;
187
+		$this->request = $request;
188
+		$this->maintenance_mode = $maintenance_mode;
189
+		do_action('AHEE__EE_System__construct__begin', $this);
190
+		add_action(
191
+			'AHEE__EE_Bootstrap__load_espresso_addons',
192
+			array($this, 'loadCapabilities'),
193
+			5
194
+		);
195
+		add_action(
196
+			'AHEE__EE_Bootstrap__load_espresso_addons',
197
+			array($this, 'loadCommandBus'),
198
+			7
199
+		);
200
+		add_action(
201
+			'AHEE__EE_Bootstrap__load_espresso_addons',
202
+			array($this, 'loadPluginApi'),
203
+			9
204
+		);
205
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
+		add_action(
207
+			'AHEE__EE_Bootstrap__load_espresso_addons',
208
+			array($this, 'load_espresso_addons')
209
+		);
210
+		// when an ee addon is activated, we want to call the core hook(s) again
211
+		// because the newly-activated addon didn't get a chance to run at all
212
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
+		// detect whether install or upgrade
214
+		add_action(
215
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
+			array($this, 'detect_activations_or_upgrades'),
217
+			3
218
+		);
219
+		// load EE_Config, EE_Textdomain, etc
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_core_configuration',
222
+			array($this, 'load_core_configuration'),
223
+			5
224
+		);
225
+		// load specifications for matching routes to current request
226
+		add_action(
227
+			'AHEE__EE_Bootstrap__load_core_configuration',
228
+			array($this, 'loadRouteMatchSpecifications')
229
+		);
230
+		// load EE_Config, EE_Textdomain, etc
231
+		add_action(
232
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
+			array($this, 'register_shortcodes_modules_and_widgets'),
234
+			7
235
+		);
236
+		// you wanna get going? I wanna get going... let's get going!
237
+		add_action(
238
+			'AHEE__EE_Bootstrap__brew_espresso',
239
+			array($this, 'brew_espresso'),
240
+			9
241
+		);
242
+		// other housekeeping
243
+		// exclude EE critical pages from wp_list_pages
244
+		add_filter(
245
+			'wp_list_pages_excludes',
246
+			array($this, 'remove_pages_from_wp_list_pages'),
247
+			10
248
+		);
249
+		// ALL EE Addons should use the following hook point to attach their initial setup too
250
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
+		do_action('AHEE__EE_System__construct__complete', $this);
252
+	}
253
+
254
+
255
+	/**
256
+	 * load and setup EE_Capabilities
257
+	 *
258
+	 * @return void
259
+	 * @throws EE_Error
260
+	 */
261
+	public function loadCapabilities()
262
+	{
263
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
264
+		add_action(
265
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
266
+			function () {
267
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
+			}
269
+		);
270
+	}
271
+
272
+
273
+	/**
274
+	 * create and cache the CommandBus, and also add middleware
275
+	 * The CapChecker middleware requires the use of EE_Capabilities
276
+	 * which is why we need to load the CommandBus after Caps are set up
277
+	 *
278
+	 * @return void
279
+	 * @throws EE_Error
280
+	 */
281
+	public function loadCommandBus()
282
+	{
283
+		$this->loader->getShared(
284
+			'CommandBusInterface',
285
+			array(
286
+				null,
287
+				apply_filters(
288
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
+					array(
290
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
+					)
293
+				),
294
+			)
295
+		);
296
+	}
297
+
298
+
299
+	/**
300
+	 * @return void
301
+	 * @throws EE_Error
302
+	 */
303
+	public function loadPluginApi()
304
+	{
305
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
306
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
307
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
+		$this->loader->getShared('EE_Request_Handler');
309
+	}
310
+
311
+
312
+	/**
313
+	 * @param string $addon_name
314
+	 * @param string $version_constant
315
+	 * @param string $min_version_required
316
+	 * @param string $load_callback
317
+	 * @param string $plugin_file_constant
318
+	 * @return void
319
+	 */
320
+	private function deactivateIncompatibleAddon(
321
+		$addon_name,
322
+		$version_constant,
323
+		$min_version_required,
324
+		$load_callback,
325
+		$plugin_file_constant
326
+	) {
327
+		if (! defined($version_constant)) {
328
+			return;
329
+		}
330
+		$addon_version = constant($version_constant);
331
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
+			if (! function_exists('deactivate_plugins')) {
334
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
+			}
336
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
+			unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
+			EE_Error::add_error(
339
+				sprintf(
340
+					esc_html__(
341
+						'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
342
+						'event_espresso'
343
+					),
344
+					$addon_name,
345
+					$min_version_required
346
+				),
347
+				__FILE__,
348
+				__FUNCTION__ . "({$addon_name})",
349
+				__LINE__
350
+			);
351
+			EE_Error::get_notices(false, true);
352
+		}
353
+	}
354
+
355
+
356
+	/**
357
+	 * load_espresso_addons
358
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
359
+	 * this is hooked into both:
360
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
361
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
362
+	 *    and the WP 'activate_plugin' hook point
363
+	 *
364
+	 * @access public
365
+	 * @return void
366
+	 */
367
+	public function load_espresso_addons()
368
+	{
369
+		$this->deactivateIncompatibleAddon(
370
+			'Wait Lists',
371
+			'EE_WAIT_LISTS_VERSION',
372
+			'1.0.0.beta.074',
373
+			'load_espresso_wait_lists',
374
+			'EE_WAIT_LISTS_PLUGIN_FILE'
375
+		);
376
+		$this->deactivateIncompatibleAddon(
377
+			'Automated Upcoming Event Notifications',
378
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
+			'1.0.0.beta.091',
380
+			'load_espresso_automated_upcoming_event_notification',
381
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
+		);
383
+		do_action('AHEE__EE_System__load_espresso_addons');
384
+		// if the WP API basic auth plugin isn't already loaded, load it now.
385
+		// We want it for mobile apps. Just include the entire plugin
386
+		// also, don't load the basic auth when a plugin is getting activated, because
387
+		// it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
+		// and causes a fatal error
389
+		if (($this->request->isWordPressApi() || $this->request->isApi())
390
+			&& $this->request->getRequestParam('activate') !== 'true'
391
+			&& ! function_exists('json_basic_auth_handler')
392
+			&& ! function_exists('json_basic_auth_error')
393
+			&& ! in_array(
394
+				$this->request->getRequestParam('action'),
395
+				array('activate', 'activate-selected'),
396
+				true
397
+			)
398
+		) {
399
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
400
+		}
401
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
402
+	}
403
+
404
+
405
+	/**
406
+	 * detect_activations_or_upgrades
407
+	 * Checks for activation or upgrade of core first;
408
+	 * then also checks if any registered addons have been activated or upgraded
409
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
410
+	 * which runs during the WP 'plugins_loaded' action at priority 3
411
+	 *
412
+	 * @access public
413
+	 * @return void
414
+	 */
415
+	public function detect_activations_or_upgrades()
416
+	{
417
+		// first off: let's make sure to handle core
418
+		$this->detect_if_activation_or_upgrade();
419
+		foreach ($this->registry->addons as $addon) {
420
+			if ($addon instanceof EE_Addon) {
421
+				// detect teh request type for that addon
422
+				$addon->detect_req_type();
423
+			}
424
+		}
425
+	}
426
+
427
+
428
+	/**
429
+	 * detect_if_activation_or_upgrade
430
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
431
+	 * and either setting up the DB or setting up maintenance mode etc.
432
+	 *
433
+	 * @access public
434
+	 * @return void
435
+	 */
436
+	public function detect_if_activation_or_upgrade()
437
+	{
438
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
439
+		// check if db has been updated, or if its a brand-new installation
440
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
441
+		$request_type = $this->detect_req_type($espresso_db_update);
442
+		switch ($request_type) {
443
+			case EE_System::req_type_new_activation:
444
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
445
+				$this->_handle_core_version_change($espresso_db_update);
446
+				break;
447
+			case EE_System::req_type_reactivation:
448
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
449
+				$this->_handle_core_version_change($espresso_db_update);
450
+				break;
451
+			case EE_System::req_type_upgrade:
452
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
453
+				// migrations may be required now that we've upgraded
454
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
455
+				$this->_handle_core_version_change($espresso_db_update);
456
+				break;
457
+			case EE_System::req_type_downgrade:
458
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
459
+				// its possible migrations are no longer required
460
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
461
+				$this->_handle_core_version_change($espresso_db_update);
462
+				break;
463
+			case EE_System::req_type_normal:
464
+			default:
465
+				break;
466
+		}
467
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
468
+	}
469
+
470
+
471
+	/**
472
+	 * Updates the list of installed versions and sets hooks for
473
+	 * initializing the database later during the request
474
+	 *
475
+	 * @param array $espresso_db_update
476
+	 */
477
+	private function _handle_core_version_change($espresso_db_update)
478
+	{
479
+		$this->update_list_of_installed_versions($espresso_db_update);
480
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
481
+		add_action(
482
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
483
+			array($this, 'initialize_db_if_no_migrations_required')
484
+		);
485
+	}
486
+
487
+
488
+	/**
489
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
490
+	 * information about what versions of EE have been installed and activated,
491
+	 * NOT necessarily the state of the database
492
+	 *
493
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
494
+	 *                                            If not supplied, fetches it from the options table
495
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
496
+	 */
497
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
498
+	{
499
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
500
+		if (! $espresso_db_update) {
501
+			$espresso_db_update = get_option('espresso_db_update');
502
+		}
503
+		// check that option is an array
504
+		if (! is_array($espresso_db_update)) {
505
+			// if option is FALSE, then it never existed
506
+			if ($espresso_db_update === false) {
507
+				// make $espresso_db_update an array and save option with autoload OFF
508
+				$espresso_db_update = array();
509
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
510
+			} else {
511
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
512
+				$espresso_db_update = array($espresso_db_update => array());
513
+				update_option('espresso_db_update', $espresso_db_update);
514
+			}
515
+		} else {
516
+			$corrected_db_update = array();
517
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
518
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
519
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
520
+					// the key is an int, and the value IS NOT an array
521
+					// so it must be numerically-indexed, where values are versions installed...
522
+					// fix it!
523
+					$version_string = $should_be_array;
524
+					$corrected_db_update[ $version_string ] = array('unknown-date');
525
+				} else {
526
+					// ok it checks out
527
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
528
+				}
529
+			}
530
+			$espresso_db_update = $corrected_db_update;
531
+			update_option('espresso_db_update', $espresso_db_update);
532
+		}
533
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
534
+		return $espresso_db_update;
535
+	}
536
+
537
+
538
+	/**
539
+	 * Does the traditional work of setting up the plugin's database and adding default data.
540
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
541
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
542
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
543
+	 * so that it will be done when migrations are finished
544
+	 *
545
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
546
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
547
+	 *                                       This is a resource-intensive job
548
+	 *                                       so we prefer to only do it when necessary
549
+	 * @return void
550
+	 * @throws EE_Error
551
+	 */
552
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
553
+	{
554
+		$request_type = $this->detect_req_type();
555
+		// only initialize system if we're not in maintenance mode.
556
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
557
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
558
+			$rewrite_rules = $this->loader->getShared(
559
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
560
+			);
561
+			$rewrite_rules->flush();
562
+			if ($verify_schema) {
563
+				EEH_Activation::initialize_db_and_folders();
564
+			}
565
+			EEH_Activation::initialize_db_content();
566
+			EEH_Activation::system_initialization();
567
+			if ($initialize_addons_too) {
568
+				$this->initialize_addons();
569
+			}
570
+		} else {
571
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
572
+		}
573
+		if ($request_type === EE_System::req_type_new_activation
574
+			|| $request_type === EE_System::req_type_reactivation
575
+			|| (
576
+				$request_type === EE_System::req_type_upgrade
577
+				&& $this->is_major_version_change()
578
+			)
579
+		) {
580
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
581
+		}
582
+	}
583
+
584
+
585
+	/**
586
+	 * Initializes the db for all registered addons
587
+	 *
588
+	 * @throws EE_Error
589
+	 */
590
+	public function initialize_addons()
591
+	{
592
+		// foreach registered addon, make sure its db is up-to-date too
593
+		foreach ($this->registry->addons as $addon) {
594
+			if ($addon instanceof EE_Addon) {
595
+				$addon->initialize_db_if_no_migrations_required();
596
+			}
597
+		}
598
+	}
599
+
600
+
601
+	/**
602
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
603
+	 *
604
+	 * @param    array  $version_history
605
+	 * @param    string $current_version_to_add version to be added to the version history
606
+	 * @return    boolean success as to whether or not this option was changed
607
+	 */
608
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
609
+	{
610
+		if (! $version_history) {
611
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
612
+		}
613
+		if ($current_version_to_add === null) {
614
+			$current_version_to_add = espresso_version();
615
+		}
616
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
617
+		// re-save
618
+		return update_option('espresso_db_update', $version_history);
619
+	}
620
+
621
+
622
+	/**
623
+	 * Detects if the current version indicated in the has existed in the list of
624
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
625
+	 *
626
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
627
+	 *                                  If not supplied, fetches it from the options table.
628
+	 *                                  Also, caches its result so later parts of the code can also know whether
629
+	 *                                  there's been an update or not. This way we can add the current version to
630
+	 *                                  espresso_db_update, but still know if this is a new install or not
631
+	 * @return int one of the constants on EE_System::req_type_
632
+	 */
633
+	public function detect_req_type($espresso_db_update = null)
634
+	{
635
+		if ($this->_req_type === null) {
636
+			$espresso_db_update = ! empty($espresso_db_update)
637
+				? $espresso_db_update
638
+				: $this->fix_espresso_db_upgrade_option();
639
+			$this->_req_type = EE_System::detect_req_type_given_activation_history(
640
+				$espresso_db_update,
641
+				'ee_espresso_activation',
642
+				espresso_version()
643
+			);
644
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
645
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
646
+		}
647
+		return $this->_req_type;
648
+	}
649
+
650
+
651
+	/**
652
+	 * Returns whether or not there was a non-micro version change (ie, change in either
653
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
654
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
655
+	 *
656
+	 * @param $activation_history
657
+	 * @return bool
658
+	 */
659
+	private function _detect_major_version_change($activation_history)
660
+	{
661
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
662
+		$previous_version_parts = explode('.', $previous_version);
663
+		$current_version_parts = explode('.', espresso_version());
664
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
665
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
666
+				   || $previous_version_parts[1] !== $current_version_parts[1]
667
+			   );
668
+	}
669
+
670
+
671
+	/**
672
+	 * Returns true if either the major or minor version of EE changed during this request.
673
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
674
+	 *
675
+	 * @return bool
676
+	 */
677
+	public function is_major_version_change()
678
+	{
679
+		return $this->_major_version_change;
680
+	}
681
+
682
+
683
+	/**
684
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
685
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
686
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
687
+	 * just activated to (for core that will always be espresso_version())
688
+	 *
689
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
690
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
691
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
692
+	 *                                                 indicate that this plugin was just activated
693
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
694
+	 *                                                 espresso_version())
695
+	 * @return int one of the constants on EE_System::req_type_*
696
+	 */
697
+	public static function detect_req_type_given_activation_history(
698
+		$activation_history_for_addon,
699
+		$activation_indicator_option_name,
700
+		$version_to_upgrade_to
701
+	) {
702
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
703
+		if ($activation_history_for_addon) {
704
+			// it exists, so this isn't a completely new install
705
+			// check if this version already in that list of previously installed versions
706
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
707
+				// it a version we haven't seen before
708
+				if ($version_is_higher === 1) {
709
+					$req_type = EE_System::req_type_upgrade;
710
+				} else {
711
+					$req_type = EE_System::req_type_downgrade;
712
+				}
713
+				delete_option($activation_indicator_option_name);
714
+			} else {
715
+				// its not an update. maybe a reactivation?
716
+				if (get_option($activation_indicator_option_name, false)) {
717
+					if ($version_is_higher === -1) {
718
+						$req_type = EE_System::req_type_downgrade;
719
+					} elseif ($version_is_higher === 0) {
720
+						// we've seen this version before, but it's an activation. must be a reactivation
721
+						$req_type = EE_System::req_type_reactivation;
722
+					} else {// $version_is_higher === 1
723
+						$req_type = EE_System::req_type_upgrade;
724
+					}
725
+					delete_option($activation_indicator_option_name);
726
+				} else {
727
+					// we've seen this version before and the activation indicate doesn't show it was just activated
728
+					if ($version_is_higher === -1) {
729
+						$req_type = EE_System::req_type_downgrade;
730
+					} elseif ($version_is_higher === 0) {
731
+						// we've seen this version before and it's not an activation. its normal request
732
+						$req_type = EE_System::req_type_normal;
733
+					} else {// $version_is_higher === 1
734
+						$req_type = EE_System::req_type_upgrade;
735
+					}
736
+				}
737
+			}
738
+		} else {
739
+			// brand new install
740
+			$req_type = EE_System::req_type_new_activation;
741
+			delete_option($activation_indicator_option_name);
742
+		}
743
+		return $req_type;
744
+	}
745
+
746
+
747
+	/**
748
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
749
+	 * the $activation_history_for_addon
750
+	 *
751
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
752
+	 *                                             sometimes containing 'unknown-date'
753
+	 * @param string $version_to_upgrade_to        (current version)
754
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
755
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
756
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
757
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
758
+	 */
759
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
760
+	{
761
+		// find the most recently-activated version
762
+		$most_recently_active_version =
763
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
764
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
765
+	}
766
+
767
+
768
+	/**
769
+	 * Gets the most recently active version listed in the activation history,
770
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
771
+	 *
772
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
773
+	 *                                   sometimes containing 'unknown-date'
774
+	 * @return string
775
+	 */
776
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
777
+	{
778
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
779
+		$most_recently_active_version = '0.0.0.dev.000';
780
+		if (is_array($activation_history)) {
781
+			foreach ($activation_history as $version => $times_activated) {
782
+				// check there is a record of when this version was activated. Otherwise,
783
+				// mark it as unknown
784
+				if (! $times_activated) {
785
+					$times_activated = array('unknown-date');
786
+				}
787
+				if (is_string($times_activated)) {
788
+					$times_activated = array($times_activated);
789
+				}
790
+				foreach ($times_activated as $an_activation) {
791
+					if ($an_activation !== 'unknown-date'
792
+						&& $an_activation
793
+						   > $most_recently_active_version_activation) {
794
+						$most_recently_active_version = $version;
795
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
796
+							? '1970-01-01 00:00:00'
797
+							: $an_activation;
798
+					}
799
+				}
800
+			}
801
+		}
802
+		return $most_recently_active_version;
803
+	}
804
+
805
+
806
+	/**
807
+	 * This redirects to the about EE page after activation
808
+	 *
809
+	 * @return void
810
+	 */
811
+	public function redirect_to_about_ee()
812
+	{
813
+		$notices = EE_Error::get_notices(false);
814
+		// if current user is an admin and it's not an ajax or rest request
815
+		if (! isset($notices['errors'])
816
+			&& $this->request->isAdmin()
817
+			&& apply_filters(
818
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
819
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
820
+			)
821
+		) {
822
+			$query_params = array('page' => 'espresso_about');
823
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
824
+				$query_params['new_activation'] = true;
825
+			}
826
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
827
+				$query_params['reactivation'] = true;
828
+			}
829
+			$url = add_query_arg($query_params, admin_url('admin.php'));
830
+			wp_safe_redirect($url);
831
+			exit();
832
+		}
833
+	}
834
+
835
+
836
+	/**
837
+	 * load_core_configuration
838
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
839
+	 * which runs during the WP 'plugins_loaded' action at priority 5
840
+	 *
841
+	 * @return void
842
+	 * @throws ReflectionException
843
+	 * @throws Exception
844
+	 */
845
+	public function load_core_configuration()
846
+	{
847
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
848
+		$this->loader->getShared('EE_Load_Textdomain');
849
+		// load textdomain
850
+		EE_Load_Textdomain::load_textdomain();
851
+		// load caf stuff a chance to play during the activation process too.
852
+		$this->_maybe_brew_regular();
853
+		// load and setup EE_Config and EE_Network_Config
854
+		$config = $this->loader->getShared('EE_Config');
855
+		$this->loader->getShared('EE_Network_Config');
856
+		// setup autoloaders
857
+		// enable logging?
858
+		if ($config->admin->use_remote_logging) {
859
+			$this->loader->getShared('EE_Log');
860
+		}
861
+		// check for activation errors
862
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
863
+		if ($activation_errors) {
864
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
865
+			update_option('ee_plugin_activation_errors', false);
866
+		}
867
+		// get model names
868
+		$this->_parse_model_names();
869
+		// configure custom post type definitions
870
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
871
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
872
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
873
+	}
874
+
875
+
876
+	/**
877
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
878
+	 *
879
+	 * @return void
880
+	 * @throws ReflectionException
881
+	 */
882
+	private function _parse_model_names()
883
+	{
884
+		// get all the files in the EE_MODELS folder that end in .model.php
885
+		$models = glob(EE_MODELS . '*.model.php');
886
+		$model_names = array();
887
+		$non_abstract_db_models = array();
888
+		foreach ($models as $model) {
889
+			// get model classname
890
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
891
+			$short_name = str_replace('EEM_', '', $classname);
892
+			$reflectionClass = new ReflectionClass($classname);
893
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
894
+				$non_abstract_db_models[ $short_name ] = $classname;
895
+			}
896
+			$model_names[ $short_name ] = $classname;
897
+		}
898
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
899
+		$this->registry->non_abstract_db_models = apply_filters(
900
+			'FHEE__EE_System__parse_implemented_model_names',
901
+			$non_abstract_db_models
902
+		);
903
+	}
904
+
905
+
906
+	/**
907
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
908
+	 * that need to be setup before our EE_System launches.
909
+	 *
910
+	 * @return void
911
+	 * @throws DomainException
912
+	 * @throws InvalidArgumentException
913
+	 * @throws InvalidDataTypeException
914
+	 * @throws InvalidInterfaceException
915
+	 * @throws InvalidClassException
916
+	 * @throws InvalidFilePathException
917
+	 */
918
+	private function _maybe_brew_regular()
919
+	{
920
+		/** @var Domain $domain */
921
+		$domain = DomainFactory::getShared(
922
+			new FullyQualifiedName(
923
+				'EventEspresso\core\domain\Domain'
924
+			),
925
+			array(
926
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
927
+				Version::fromString(espresso_version()),
928
+			)
929
+		);
930
+		if ($domain->isCaffeinated()) {
931
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
932
+		}
933
+	}
934
+
935
+
936
+	/**
937
+	 * @since 4.9.71.p
938
+	 * @throws Exception
939
+	 */
940
+	public function loadRouteMatchSpecifications()
941
+	{
942
+		try {
943
+			$this->loader->getShared(
944
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
945
+			);
946
+		} catch (Exception $exception) {
947
+			new ExceptionStackTraceDisplay($exception);
948
+		}
949
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
950
+	}
951
+
952
+
953
+	/**
954
+	 * register_shortcodes_modules_and_widgets
955
+	 * generate lists of shortcodes and modules, then verify paths and classes
956
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
957
+	 * which runs during the WP 'plugins_loaded' action at priority 7
958
+	 *
959
+	 * @access public
960
+	 * @return void
961
+	 * @throws Exception
962
+	 */
963
+	public function register_shortcodes_modules_and_widgets()
964
+	{
965
+		if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
966
+			try {
967
+				// load, register, and add shortcodes the new way
968
+				$this->loader->getShared(
969
+					'EventEspresso\core\services\shortcodes\ShortcodesManager',
970
+					array(
971
+						// and the old way, but we'll put it under control of the new system
972
+						EE_Config::getLegacyShortcodesManager(),
973
+					)
974
+				);
975
+			} catch (Exception $exception) {
976
+				new ExceptionStackTraceDisplay($exception);
977
+			}
978
+		}
979
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
980
+		// check for addons using old hook point
981
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
982
+			$this->_incompatible_addon_error();
983
+		}
984
+	}
985
+
986
+
987
+	/**
988
+	 * _incompatible_addon_error
989
+	 *
990
+	 * @access public
991
+	 * @return void
992
+	 */
993
+	private function _incompatible_addon_error()
994
+	{
995
+		// get array of classes hooking into here
996
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
997
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
998
+		);
999
+		if (! empty($class_names)) {
1000
+			$msg = __(
1001
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1002
+				'event_espresso'
1003
+			);
1004
+			$msg .= '<ul>';
1005
+			foreach ($class_names as $class_name) {
1006
+				$msg .= '<li><b>Event Espresso - '
1007
+						. str_replace(
1008
+							array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1009
+							'',
1010
+							$class_name
1011
+						) . '</b></li>';
1012
+			}
1013
+			$msg .= '</ul>';
1014
+			$msg .= __(
1015
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1016
+				'event_espresso'
1017
+			);
1018
+			// save list of incompatible addons to wp-options for later use
1019
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1020
+			if (is_admin()) {
1021
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1022
+			}
1023
+		}
1024
+	}
1025
+
1026
+
1027
+	/**
1028
+	 * brew_espresso
1029
+	 * begins the process of setting hooks for initializing EE in the correct order
1030
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1031
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1032
+	 *
1033
+	 * @return void
1034
+	 */
1035
+	public function brew_espresso()
1036
+	{
1037
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1038
+		// load some final core systems
1039
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1040
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1041
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1042
+		add_action('init', array($this, 'load_controllers'), 7);
1043
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1044
+		add_action('init', array($this, 'initialize'), 10);
1045
+		add_action('init', array($this, 'initialize_last'), 100);
1046
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1047
+			// pew pew pew
1048
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1049
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1050
+		}
1051
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1052
+	}
1053
+
1054
+
1055
+	/**
1056
+	 *    set_hooks_for_core
1057
+	 *
1058
+	 * @access public
1059
+	 * @return    void
1060
+	 * @throws EE_Error
1061
+	 */
1062
+	public function set_hooks_for_core()
1063
+	{
1064
+		$this->_deactivate_incompatible_addons();
1065
+		do_action('AHEE__EE_System__set_hooks_for_core');
1066
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1067
+		// caps need to be initialized on every request so that capability maps are set.
1068
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1069
+		$this->registry->CAP->init_caps();
1070
+	}
1071
+
1072
+
1073
+	/**
1074
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1075
+	 * deactivates any addons considered incompatible with the current version of EE
1076
+	 */
1077
+	private function _deactivate_incompatible_addons()
1078
+	{
1079
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1080
+		if (! empty($incompatible_addons)) {
1081
+			$active_plugins = get_option('active_plugins', array());
1082
+			foreach ($active_plugins as $active_plugin) {
1083
+				foreach ($incompatible_addons as $incompatible_addon) {
1084
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1085
+						unset($_GET['activate']);
1086
+						espresso_deactivate_plugin($active_plugin);
1087
+					}
1088
+				}
1089
+			}
1090
+		}
1091
+	}
1092
+
1093
+
1094
+	/**
1095
+	 *    perform_activations_upgrades_and_migrations
1096
+	 *
1097
+	 * @access public
1098
+	 * @return    void
1099
+	 */
1100
+	public function perform_activations_upgrades_and_migrations()
1101
+	{
1102
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1103
+	}
1104
+
1105
+
1106
+	/**
1107
+	 * @return void
1108
+	 * @throws DomainException
1109
+	 */
1110
+	public function load_CPTs_and_session()
1111
+	{
1112
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1113
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1114
+		$register_custom_taxonomies = $this->loader->getShared(
1115
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1116
+		);
1117
+		$register_custom_taxonomies->registerCustomTaxonomies();
1118
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1119
+		$register_custom_post_types = $this->loader->getShared(
1120
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1121
+		);
1122
+		$register_custom_post_types->registerCustomPostTypes();
1123
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1124
+		$register_custom_taxonomy_terms = $this->loader->getShared(
1125
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1126
+		);
1127
+		$register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1128
+		// load legacy Custom Post Types and Taxonomies
1129
+		$this->loader->getShared('EE_Register_CPTs');
1130
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1131
+	}
1132
+
1133
+
1134
+	/**
1135
+	 * load_controllers
1136
+	 * this is the best place to load any additional controllers that needs access to EE core.
1137
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1138
+	 * time
1139
+	 *
1140
+	 * @access public
1141
+	 * @return void
1142
+	 */
1143
+	public function load_controllers()
1144
+	{
1145
+		do_action('AHEE__EE_System__load_controllers__start');
1146
+		// let's get it started
1147
+		if (! $this->maintenance_mode->level()
1148
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1149
+		) {
1150
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1151
+			$this->loader->getShared('EE_Front_Controller');
1152
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1153
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1154
+			$this->loader->getShared('EE_Admin');
1155
+		} elseif ($this->request->isWordPressHeartbeat()) {
1156
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1157
+		}
1158
+		do_action('AHEE__EE_System__load_controllers__complete');
1159
+	}
1160
+
1161
+
1162
+	/**
1163
+	 * core_loaded_and_ready
1164
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1165
+	 *
1166
+	 * @access public
1167
+	 * @return void
1168
+	 * @throws Exception
1169
+	 */
1170
+	public function core_loaded_and_ready()
1171
+	{
1172
+		if ($this->request->isAdmin()
1173
+			|| $this->request->isFrontend()
1174
+			|| $this->request->isIframe()
1175
+			|| $this->request->isWordPressApi()
1176
+		) {
1177
+			try {
1178
+				$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1179
+				$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1180
+				if ($this->canLoadBlocks()) {
1181
+					$this->loader->getShared(
1182
+						'EventEspresso\core\services\editor\BlockRegistrationManager'
1183
+					);
1184
+				}
1185
+			} catch (Exception $exception) {
1186
+				new ExceptionStackTraceDisplay($exception);
1187
+			}
1188
+		}
1189
+		if ($this->request->isAdmin()
1190
+			|| $this->request->isEeAjax()
1191
+			|| $this->request->isFrontend()
1192
+		) {
1193
+			$this->loader->getShared('EE_Session');
1194
+		}
1195
+		// integrate WP_Query with the EE models
1196
+		$this->loader->getShared('EE_CPT_Strategy');
1197
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1198
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1199
+		// builders require these even on the front-end
1200
+		require_once EE_PUBLIC . 'template_tags.php';
1201
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1202
+	}
1203
+
1204
+
1205
+	/**
1206
+	 * initialize
1207
+	 * this is the best place to begin initializing client code
1208
+	 *
1209
+	 * @access public
1210
+	 * @return void
1211
+	 */
1212
+	public function initialize()
1213
+	{
1214
+		do_action('AHEE__EE_System__initialize');
1215
+	}
1216
+
1217
+
1218
+	/**
1219
+	 * initialize_last
1220
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1221
+	 * initialize has done so
1222
+	 *
1223
+	 * @access public
1224
+	 * @return void
1225
+	 */
1226
+	public function initialize_last()
1227
+	{
1228
+		do_action('AHEE__EE_System__initialize_last');
1229
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1230
+		$rewrite_rules = $this->loader->getShared(
1231
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1232
+		);
1233
+		$rewrite_rules->flushRewriteRules();
1234
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1235
+		if (($this->request->isAjax() || $this->request->isAdmin())
1236
+			&& $this->maintenance_mode->models_can_query()) {
1237
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1238
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1239
+		}
1240
+	}
1241
+
1242
+
1243
+	/**
1244
+	 * @return void
1245
+	 * @throws EE_Error
1246
+	 */
1247
+	public function addEspressoToolbar()
1248
+	{
1249
+		$this->loader->getShared(
1250
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1251
+			array($this->registry->CAP)
1252
+		);
1253
+	}
1254
+
1255
+
1256
+	/**
1257
+	 * do_not_cache
1258
+	 * sets no cache headers and defines no cache constants for WP plugins
1259
+	 *
1260
+	 * @access public
1261
+	 * @return void
1262
+	 */
1263
+	public static function do_not_cache()
1264
+	{
1265
+		// set no cache constants
1266
+		if (! defined('DONOTCACHEPAGE')) {
1267
+			define('DONOTCACHEPAGE', true);
1268
+		}
1269
+		if (! defined('DONOTCACHCEOBJECT')) {
1270
+			define('DONOTCACHCEOBJECT', true);
1271
+		}
1272
+		if (! defined('DONOTCACHEDB')) {
1273
+			define('DONOTCACHEDB', true);
1274
+		}
1275
+		// add no cache headers
1276
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1277
+		// plus a little extra for nginx and Google Chrome
1278
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1279
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1280
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1281
+	}
1282
+
1283
+
1284
+	/**
1285
+	 *    extra_nocache_headers
1286
+	 *
1287
+	 * @access    public
1288
+	 * @param $headers
1289
+	 * @return    array
1290
+	 */
1291
+	public static function extra_nocache_headers($headers)
1292
+	{
1293
+		// for NGINX
1294
+		$headers['X-Accel-Expires'] = 0;
1295
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1296
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1297
+		return $headers;
1298
+	}
1299
+
1300
+
1301
+	/**
1302
+	 *    nocache_headers
1303
+	 *
1304
+	 * @access    public
1305
+	 * @return    void
1306
+	 */
1307
+	public static function nocache_headers()
1308
+	{
1309
+		nocache_headers();
1310
+	}
1311
+
1312
+
1313
+	/**
1314
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1315
+	 * never returned with the function.
1316
+	 *
1317
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1318
+	 * @return array
1319
+	 */
1320
+	public function remove_pages_from_wp_list_pages($exclude_array)
1321
+	{
1322
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1323
+	}
1324
+
1325
+
1326
+	/**
1327
+	 * Return whether blocks can be registered/loaded or not.
1328
+	 * @return bool
1329
+	 */
1330
+	private function canLoadBlocks()
1331
+	{
1332
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1333
+			   && function_exists('register_block_type')
1334
+			   // don't load blocks if in the Divi page builder editor context
1335
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
1336
+			   && ! $this->request->getRequestParam('et_fb', false);
1337
+	}
1338 1338
 }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.13.rc.006');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.13.rc.006');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.