Completed
Branch BUG-10236-FIX-RESET-CAPABILITI... (9be734)
by
unknown
23:08 queued 11:28
created
espresso.php 1 patch
Indentation   +219 added lines, -219 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('ABSPATH')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 /*
5 5
   Plugin Name:		Event Espresso
@@ -40,243 +40,243 @@  discard block
 block discarded – undo
40 40
  * @since            4.0
41 41
  */
42 42
 if (function_exists('espresso_version')) {
43
-    /**
44
-     *    espresso_duplicate_plugin_error
45
-     *    displays if more than one version of EE is activated at the same time
46
-     */
47
-    function espresso_duplicate_plugin_error()
48
-    {
49
-        ?>
43
+	/**
44
+	 *    espresso_duplicate_plugin_error
45
+	 *    displays if more than one version of EE is activated at the same time
46
+	 */
47
+	function espresso_duplicate_plugin_error()
48
+	{
49
+		?>
50 50
         <div class="error">
51 51
             <p>
52 52
                 <?php 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
-                ); ?>
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
-    }
59
+		espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+	}
61 61
 
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
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.3.9');
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
-        /**
97
-         * espresso_version
98
-         * Returns the plugin version
99
-         *
100
-         * @return string
101
-         */
102
-        function espresso_version()
103
-        {
104
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.39.rc.054');
105
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		/**
97
+		 * espresso_version
98
+		 * Returns the plugin version
99
+		 *
100
+		 * @return string
101
+		 */
102
+		function espresso_version()
103
+		{
104
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.39.rc.054');
105
+		}
106 106
 
107
-        // define versions
108
-        define('EVENT_ESPRESSO_VERSION', espresso_version());
109
-        define('EE_MIN_WP_VER_REQUIRED', '4.1');
110
-        define('EE_MIN_WP_VER_RECOMMENDED', '4.4.2');
111
-        define('EE_MIN_PHP_VER_RECOMMENDED', '5.4.44');
112
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
113
-        //used to be DIRECTORY_SEPARATOR, but that caused issues on windows
114
-        if ( ! defined('DS')) {
115
-            define('DS', '/');
116
-        }
117
-        if ( ! defined('PS')) {
118
-            define('PS', PATH_SEPARATOR);
119
-        }
120
-        if ( ! defined('SP')) {
121
-            define('SP', ' ');
122
-        }
123
-        if ( ! defined('EENL')) {
124
-            define('EENL', "\n");
125
-        }
126
-        define('EE_SUPPORT_EMAIL', '[email protected]');
127
-        // define the plugin directory and URL
128
-        define('EE_PLUGIN_BASENAME', plugin_basename(EVENT_ESPRESSO_MAIN_FILE));
129
-        define('EE_PLUGIN_DIR_PATH', plugin_dir_path(EVENT_ESPRESSO_MAIN_FILE));
130
-        define('EE_PLUGIN_DIR_URL', plugin_dir_url(EVENT_ESPRESSO_MAIN_FILE));
131
-        // main root folder paths
132
-        define('EE_ADMIN_PAGES', EE_PLUGIN_DIR_PATH . 'admin_pages' . DS);
133
-        define('EE_CORE', EE_PLUGIN_DIR_PATH . 'core' . DS);
134
-        define('EE_MODULES', EE_PLUGIN_DIR_PATH . 'modules' . DS);
135
-        define('EE_PUBLIC', EE_PLUGIN_DIR_PATH . 'public' . DS);
136
-        define('EE_SHORTCODES', EE_PLUGIN_DIR_PATH . 'shortcodes' . DS);
137
-        define('EE_WIDGETS', EE_PLUGIN_DIR_PATH . 'widgets' . DS);
138
-        define('EE_PAYMENT_METHODS', EE_PLUGIN_DIR_PATH . 'payment_methods' . DS);
139
-        define('EE_CAFF_PATH', EE_PLUGIN_DIR_PATH . 'caffeinated' . DS);
140
-        // core system paths
141
-        define('EE_ADMIN', EE_CORE . 'admin' . DS);
142
-        define('EE_CPTS', EE_CORE . 'CPTs' . DS);
143
-        define('EE_CLASSES', EE_CORE . 'db_classes' . DS);
144
-        define('EE_INTERFACES', EE_CORE . 'interfaces' . DS);
145
-        define('EE_BUSINESS', EE_CORE . 'business' . DS);
146
-        define('EE_MODELS', EE_CORE . 'db_models' . DS);
147
-        define('EE_HELPERS', EE_CORE . 'helpers' . DS);
148
-        define('EE_LIBRARIES', EE_CORE . 'libraries' . DS);
149
-        define('EE_TEMPLATES', EE_CORE . 'templates' . DS);
150
-        define('EE_THIRD_PARTY', EE_CORE . 'third_party_libs' . DS);
151
-        define('EE_GLOBAL_ASSETS', EE_TEMPLATES . 'global_assets' . DS);
152
-        define('EE_FORM_SECTIONS', EE_LIBRARIES . 'form_sections' . DS);
153
-        // gateways
154
-        define('EE_GATEWAYS', EE_MODULES . 'gateways' . DS);
155
-        define('EE_GATEWAYS_URL', EE_PLUGIN_DIR_URL . 'modules' . DS . 'gateways' . DS);
156
-        // asset URL paths
157
-        define('EE_TEMPLATES_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'templates' . DS);
158
-        define('EE_GLOBAL_ASSETS_URL', EE_TEMPLATES_URL . 'global_assets' . DS);
159
-        define('EE_IMAGES_URL', EE_GLOBAL_ASSETS_URL . 'images' . DS);
160
-        define('EE_THIRD_PARTY_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'third_party_libs' . DS);
161
-        define('EE_HELPERS_ASSETS', EE_PLUGIN_DIR_URL . 'core/helpers/assets/');
162
-        define('EE_LIBRARIES_URL', EE_PLUGIN_DIR_URL . 'core/libraries/');
163
-        // define upload paths
164
-        $uploads = wp_upload_dir();
165
-        // define the uploads directory and URL
166
-        define('EVENT_ESPRESSO_UPLOAD_DIR', $uploads['basedir'] . DS . 'espresso' . DS);
167
-        define('EVENT_ESPRESSO_UPLOAD_URL', $uploads['baseurl'] . DS . 'espresso' . DS);
168
-        // define the templates directory and URL
169
-        define('EVENT_ESPRESSO_TEMPLATE_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'templates' . DS);
170
-        define('EVENT_ESPRESSO_TEMPLATE_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'templates' . DS);
171
-        // define the gateway directory and URL
172
-        define('EVENT_ESPRESSO_GATEWAY_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'gateways' . DS);
173
-        define('EVENT_ESPRESSO_GATEWAY_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'gateways' . DS);
174
-        // languages folder/path
175
-        define('EE_LANGUAGES_SAFE_LOC', '..' . DS . 'uploads' . DS . 'espresso' . DS . 'languages' . DS);
176
-        define('EE_LANGUAGES_SAFE_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'languages' . DS);
177
-        //check for dompdf fonts in uploads
178
-        if (file_exists(EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS)) {
179
-            define('DOMPDF_FONT_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS);
180
-        }
181
-        //ajax constants
182
-        define(
183
-                'EE_FRONT_AJAX',
184
-                isset($_REQUEST['ee_front_ajax']) || isset($_REQUEST['data']['ee_front_ajax']) ? true : false
185
-        );
186
-        define(
187
-                'EE_ADMIN_AJAX',
188
-                isset($_REQUEST['ee_admin_ajax']) || isset($_REQUEST['data']['ee_admin_ajax']) ? true : false
189
-        );
190
-        //just a handy constant occasionally needed for finding values representing infinity in the DB
191
-        //you're better to use this than its straight value (currently -1) in case you ever
192
-        //want to change its default value! or find when -1 means infinity
193
-        define('EE_INF_IN_DB', -1);
194
-        define('EE_INF', INF > (float)PHP_INT_MAX ? INF : PHP_INT_MAX);
195
-        define('EE_DEBUG', false);
196
-        // for older WP versions
197
-        if ( ! defined('MONTH_IN_SECONDS')) {
198
-            define('MONTH_IN_SECONDS', DAY_IN_SECONDS * 30);
199
-        }
200
-        /**
201
-         *    espresso_plugin_activation
202
-         *    adds a wp-option to indicate that EE has been activated via the WP admin plugins page
203
-         */
204
-        function espresso_plugin_activation()
205
-        {
206
-            update_option('ee_espresso_activation', true);
207
-        }
107
+		// define versions
108
+		define('EVENT_ESPRESSO_VERSION', espresso_version());
109
+		define('EE_MIN_WP_VER_REQUIRED', '4.1');
110
+		define('EE_MIN_WP_VER_RECOMMENDED', '4.4.2');
111
+		define('EE_MIN_PHP_VER_RECOMMENDED', '5.4.44');
112
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
113
+		//used to be DIRECTORY_SEPARATOR, but that caused issues on windows
114
+		if ( ! defined('DS')) {
115
+			define('DS', '/');
116
+		}
117
+		if ( ! defined('PS')) {
118
+			define('PS', PATH_SEPARATOR);
119
+		}
120
+		if ( ! defined('SP')) {
121
+			define('SP', ' ');
122
+		}
123
+		if ( ! defined('EENL')) {
124
+			define('EENL', "\n");
125
+		}
126
+		define('EE_SUPPORT_EMAIL', '[email protected]');
127
+		// define the plugin directory and URL
128
+		define('EE_PLUGIN_BASENAME', plugin_basename(EVENT_ESPRESSO_MAIN_FILE));
129
+		define('EE_PLUGIN_DIR_PATH', plugin_dir_path(EVENT_ESPRESSO_MAIN_FILE));
130
+		define('EE_PLUGIN_DIR_URL', plugin_dir_url(EVENT_ESPRESSO_MAIN_FILE));
131
+		// main root folder paths
132
+		define('EE_ADMIN_PAGES', EE_PLUGIN_DIR_PATH . 'admin_pages' . DS);
133
+		define('EE_CORE', EE_PLUGIN_DIR_PATH . 'core' . DS);
134
+		define('EE_MODULES', EE_PLUGIN_DIR_PATH . 'modules' . DS);
135
+		define('EE_PUBLIC', EE_PLUGIN_DIR_PATH . 'public' . DS);
136
+		define('EE_SHORTCODES', EE_PLUGIN_DIR_PATH . 'shortcodes' . DS);
137
+		define('EE_WIDGETS', EE_PLUGIN_DIR_PATH . 'widgets' . DS);
138
+		define('EE_PAYMENT_METHODS', EE_PLUGIN_DIR_PATH . 'payment_methods' . DS);
139
+		define('EE_CAFF_PATH', EE_PLUGIN_DIR_PATH . 'caffeinated' . DS);
140
+		// core system paths
141
+		define('EE_ADMIN', EE_CORE . 'admin' . DS);
142
+		define('EE_CPTS', EE_CORE . 'CPTs' . DS);
143
+		define('EE_CLASSES', EE_CORE . 'db_classes' . DS);
144
+		define('EE_INTERFACES', EE_CORE . 'interfaces' . DS);
145
+		define('EE_BUSINESS', EE_CORE . 'business' . DS);
146
+		define('EE_MODELS', EE_CORE . 'db_models' . DS);
147
+		define('EE_HELPERS', EE_CORE . 'helpers' . DS);
148
+		define('EE_LIBRARIES', EE_CORE . 'libraries' . DS);
149
+		define('EE_TEMPLATES', EE_CORE . 'templates' . DS);
150
+		define('EE_THIRD_PARTY', EE_CORE . 'third_party_libs' . DS);
151
+		define('EE_GLOBAL_ASSETS', EE_TEMPLATES . 'global_assets' . DS);
152
+		define('EE_FORM_SECTIONS', EE_LIBRARIES . 'form_sections' . DS);
153
+		// gateways
154
+		define('EE_GATEWAYS', EE_MODULES . 'gateways' . DS);
155
+		define('EE_GATEWAYS_URL', EE_PLUGIN_DIR_URL . 'modules' . DS . 'gateways' . DS);
156
+		// asset URL paths
157
+		define('EE_TEMPLATES_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'templates' . DS);
158
+		define('EE_GLOBAL_ASSETS_URL', EE_TEMPLATES_URL . 'global_assets' . DS);
159
+		define('EE_IMAGES_URL', EE_GLOBAL_ASSETS_URL . 'images' . DS);
160
+		define('EE_THIRD_PARTY_URL', EE_PLUGIN_DIR_URL . 'core' . DS . 'third_party_libs' . DS);
161
+		define('EE_HELPERS_ASSETS', EE_PLUGIN_DIR_URL . 'core/helpers/assets/');
162
+		define('EE_LIBRARIES_URL', EE_PLUGIN_DIR_URL . 'core/libraries/');
163
+		// define upload paths
164
+		$uploads = wp_upload_dir();
165
+		// define the uploads directory and URL
166
+		define('EVENT_ESPRESSO_UPLOAD_DIR', $uploads['basedir'] . DS . 'espresso' . DS);
167
+		define('EVENT_ESPRESSO_UPLOAD_URL', $uploads['baseurl'] . DS . 'espresso' . DS);
168
+		// define the templates directory and URL
169
+		define('EVENT_ESPRESSO_TEMPLATE_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'templates' . DS);
170
+		define('EVENT_ESPRESSO_TEMPLATE_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'templates' . DS);
171
+		// define the gateway directory and URL
172
+		define('EVENT_ESPRESSO_GATEWAY_DIR', $uploads['basedir'] . DS . 'espresso' . DS . 'gateways' . DS);
173
+		define('EVENT_ESPRESSO_GATEWAY_URL', $uploads['baseurl'] . DS . 'espresso' . DS . 'gateways' . DS);
174
+		// languages folder/path
175
+		define('EE_LANGUAGES_SAFE_LOC', '..' . DS . 'uploads' . DS . 'espresso' . DS . 'languages' . DS);
176
+		define('EE_LANGUAGES_SAFE_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'languages' . DS);
177
+		//check for dompdf fonts in uploads
178
+		if (file_exists(EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS)) {
179
+			define('DOMPDF_FONT_DIR', EVENT_ESPRESSO_UPLOAD_DIR . 'fonts' . DS);
180
+		}
181
+		//ajax constants
182
+		define(
183
+				'EE_FRONT_AJAX',
184
+				isset($_REQUEST['ee_front_ajax']) || isset($_REQUEST['data']['ee_front_ajax']) ? true : false
185
+		);
186
+		define(
187
+				'EE_ADMIN_AJAX',
188
+				isset($_REQUEST['ee_admin_ajax']) || isset($_REQUEST['data']['ee_admin_ajax']) ? true : false
189
+		);
190
+		//just a handy constant occasionally needed for finding values representing infinity in the DB
191
+		//you're better to use this than its straight value (currently -1) in case you ever
192
+		//want to change its default value! or find when -1 means infinity
193
+		define('EE_INF_IN_DB', -1);
194
+		define('EE_INF', INF > (float)PHP_INT_MAX ? INF : PHP_INT_MAX);
195
+		define('EE_DEBUG', false);
196
+		// for older WP versions
197
+		if ( ! defined('MONTH_IN_SECONDS')) {
198
+			define('MONTH_IN_SECONDS', DAY_IN_SECONDS * 30);
199
+		}
200
+		/**
201
+		 *    espresso_plugin_activation
202
+		 *    adds a wp-option to indicate that EE has been activated via the WP admin plugins page
203
+		 */
204
+		function espresso_plugin_activation()
205
+		{
206
+			update_option('ee_espresso_activation', true);
207
+		}
208 208
 
209
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
210
-        /**
211
-         *    espresso_load_error_handling
212
-         *    this function loads EE's class for handling exceptions and errors
213
-         */
214
-        function espresso_load_error_handling()
215
-        {
216
-            // load debugging tools
217
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
218
-                require_once(EE_HELPERS . 'EEH_Debug_Tools.helper.php');
219
-                EEH_Debug_Tools::instance();
220
-            }
221
-            // load error handling
222
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
223
-                require_once(EE_CORE . 'EE_Error.core.php');
224
-            } else {
225
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
226
-            }
227
-        }
209
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
210
+		/**
211
+		 *    espresso_load_error_handling
212
+		 *    this function loads EE's class for handling exceptions and errors
213
+		 */
214
+		function espresso_load_error_handling()
215
+		{
216
+			// load debugging tools
217
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
218
+				require_once(EE_HELPERS . 'EEH_Debug_Tools.helper.php');
219
+				EEH_Debug_Tools::instance();
220
+			}
221
+			// load error handling
222
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
223
+				require_once(EE_CORE . 'EE_Error.core.php');
224
+			} else {
225
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
226
+			}
227
+		}
228 228
 
229
-        /**
230
-         *    espresso_load_required
231
-         *    given a class name and path, this function will load that file or throw an exception
232
-         *
233
-         * @param    string $classname
234
-         * @param    string $full_path_to_file
235
-         * @throws    EE_Error
236
-         */
237
-        function espresso_load_required($classname, $full_path_to_file)
238
-        {
239
-            static $error_handling_loaded = false;
240
-            if ( ! $error_handling_loaded) {
241
-                espresso_load_error_handling();
242
-                $error_handling_loaded = true;
243
-            }
244
-            if (is_readable($full_path_to_file)) {
245
-                require_once($full_path_to_file);
246
-            } else {
247
-                throw new EE_Error (
248
-                        sprintf(
249
-                                esc_html__(
250
-                                        'The %s class file could not be located or is not readable due to file permissions.',
251
-                                        'event_espresso'
252
-                                ),
253
-                                $classname
254
-                        )
255
-                );
256
-            }
257
-        }
229
+		/**
230
+		 *    espresso_load_required
231
+		 *    given a class name and path, this function will load that file or throw an exception
232
+		 *
233
+		 * @param    string $classname
234
+		 * @param    string $full_path_to_file
235
+		 * @throws    EE_Error
236
+		 */
237
+		function espresso_load_required($classname, $full_path_to_file)
238
+		{
239
+			static $error_handling_loaded = false;
240
+			if ( ! $error_handling_loaded) {
241
+				espresso_load_error_handling();
242
+				$error_handling_loaded = true;
243
+			}
244
+			if (is_readable($full_path_to_file)) {
245
+				require_once($full_path_to_file);
246
+			} else {
247
+				throw new EE_Error (
248
+						sprintf(
249
+								esc_html__(
250
+										'The %s class file could not be located or is not readable due to file permissions.',
251
+										'event_espresso'
252
+								),
253
+								$classname
254
+						)
255
+				);
256
+			}
257
+		}
258 258
 
259
-        espresso_load_required('EEH_Base', EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php');
260
-        espresso_load_required('EEH_File', EE_CORE . 'helpers' . DS . 'EEH_File.helper.php');
261
-        espresso_load_required('EE_Bootstrap', EE_CORE . 'EE_Bootstrap.core.php');
262
-        new EE_Bootstrap();
263
-    }
259
+		espresso_load_required('EEH_Base', EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php');
260
+		espresso_load_required('EEH_File', EE_CORE . 'helpers' . DS . 'EEH_File.helper.php');
261
+		espresso_load_required('EE_Bootstrap', EE_CORE . 'EE_Bootstrap.core.php');
262
+		new EE_Bootstrap();
263
+	}
264 264
 }
265 265
 if ( ! function_exists('espresso_deactivate_plugin')) {
266
-    /**
267
-     *    deactivate_plugin
268
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
269
-     *
270
-     * @access public
271
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
272
-     * @return    void
273
-     */
274
-    function espresso_deactivate_plugin($plugin_basename = '')
275
-    {
276
-        if ( ! function_exists('deactivate_plugins')) {
277
-            require_once(ABSPATH . 'wp-admin/includes/plugin.php');
278
-        }
279
-        unset($_GET['activate'], $_REQUEST['activate']);
280
-        deactivate_plugins($plugin_basename);
281
-    }
266
+	/**
267
+	 *    deactivate_plugin
268
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
269
+	 *
270
+	 * @access public
271
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
272
+	 * @return    void
273
+	 */
274
+	function espresso_deactivate_plugin($plugin_basename = '')
275
+	{
276
+		if ( ! function_exists('deactivate_plugins')) {
277
+			require_once(ABSPATH . 'wp-admin/includes/plugin.php');
278
+		}
279
+		unset($_GET['activate'], $_REQUEST['activate']);
280
+		deactivate_plugins($plugin_basename);
281
+	}
282 282
 }
283 283
\ No newline at end of file
Please login to merge, or discard this patch.
core/EE_Registry.core.php 3 patches
Doc Comments   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -309,6 +309,7 @@  discard block
 block discarded – undo
309 309
 
310 310
     /**
311 311
      * @param mixed string | EED_Module $module
312
+     * @param string $module
312 313
      */
313 314
     public function add_module($module)
314 315
     {
@@ -1394,7 +1395,7 @@  discard block
 block discarded – undo
1394 1395
      * Gets the names of all the "models", including abstract and "non-database" models.
1395 1396
      * Mainly all the classes from core/db_models.
1396 1397
      * You may want to use EE_Registry::non_abstract_db_models instead
1397
-     * @return array keys are model names (eg "Event") and values are their classnames (eg "EEM_Event")
1398
+     * @return EEM_Base[] keys are model names (eg "Event") and values are their classnames (eg "EEM_Event")
1398 1399
      */
1399 1400
     public function models()
1400 1401
     {
Please login to merge, or discard this patch.
Indentation   +1391 added lines, -1391 removed lines patch added patch discarded remove patch
@@ -16,1433 +16,1433 @@
 block discarded – undo
16 16
 class EE_Registry
17 17
 {
18 18
 
19
-    /**
20
-     *    EE_Registry Object
21
-     *
22
-     * @var EE_Registry $_instance
23
-     * @access    private
24
-     */
25
-    private static $_instance = null;
26
-
27
-    /**
28
-     * @var EE_Dependency_Map $_dependency_map
29
-     * @access    protected
30
-     */
31
-    protected $_dependency_map = null;
32
-
33
-    /**
34
-     * @var array $_class_abbreviations
35
-     * @access    protected
36
-     */
37
-    protected $_class_abbreviations = array();
38
-
39
-    /**
40
-     * @access public
41
-     * @var \EventEspresso\core\services\commands\CommandBusInterface $BUS
42
-     */
43
-    public $BUS;
44
-
45
-    /**
46
-     *    EE_Cart Object
47
-     *
48
-     * @access    public
49
-     * @var    EE_Cart $CART
50
-     */
51
-    public $CART = null;
52
-
53
-    /**
54
-     *    EE_Config Object
55
-     *
56
-     * @access    public
57
-     * @var    EE_Config $CFG
58
-     */
59
-    public $CFG = null;
60
-
61
-    /**
62
-     * EE_Network_Config Object
63
-     *
64
-     * @access public
65
-     * @var EE_Network_Config $NET_CFG
66
-     */
67
-    public $NET_CFG = null;
68
-
69
-    /**
70
-     *    StdClass object for storing library classes in
71
-     *
72
-     * @public LIB
73
-     * @var StdClass $LIB
74
-     */
75
-    public $LIB = null;
76
-
77
-    /**
78
-     *    EE_Request_Handler Object
79
-     *
80
-     * @access    public
81
-     * @var    EE_Request_Handler $REQ
82
-     */
83
-    public $REQ = null;
84
-
85
-    /**
86
-     *    EE_Session Object
87
-     *
88
-     * @access    public
89
-     * @var    EE_Session $SSN
90
-     */
91
-    public $SSN = null;
92
-
93
-    /**
94
-     * holds the ee capabilities object.
95
-     *
96
-     * @since 4.5.0
97
-     * @var EE_Capabilities
98
-     */
99
-    public $CAP = null;
100
-
101
-    /**
102
-     * holds the EE_Message_Resource_Manager object.
103
-     *
104
-     * @since 4.9.0
105
-     * @var EE_Message_Resource_Manager
106
-     */
107
-    public $MRM = null;
108
-
109
-
110
-    /**
111
-     * Holds the Assets Registry instance
112
-     * @var Registry
113
-     */
114
-    public $AssetsRegistry = null;
115
-
116
-    /**
117
-     *    $addons - StdClass object for holding addons which have registered themselves to work with EE core
118
-     *
119
-     * @access    public
120
-     * @var    EE_Addon[]
121
-     */
122
-    public $addons = null;
123
-
124
-    /**
125
-     *    $models
126
-     * @access    public
127
-     * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
128
-     */
129
-    public $models = array();
130
-
131
-    /**
132
-     *    $modules
133
-     * @access    public
134
-     * @var    EED_Module[] $modules
135
-     */
136
-    public $modules = null;
137
-
138
-    /**
139
-     *    $shortcodes
140
-     * @access    public
141
-     * @var    EES_Shortcode[] $shortcodes
142
-     */
143
-    public $shortcodes = null;
144
-
145
-    /**
146
-     *    $widgets
147
-     * @access    public
148
-     * @var    WP_Widget[] $widgets
149
-     */
150
-    public $widgets = null;
151
-
152
-    /**
153
-     * $non_abstract_db_models
154
-     * @access public but its better to use EE_Registry::non_abstract_db_models() as it verifies we've set this property before returning it
155
-     * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
156
-     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
157
-     * Keys are model "short names" (eg "Event") as used in model relations, and values are
158
-     * classnames (eg "EEM_Event")
159
-     */
160
-    public $non_abstract_db_models = array();
161
-
162
-
163
-    /**
164
-     *    $i18n_js_strings - internationalization for JS strings
165
-     *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
166
-     *    in js file:  var translatedString = eei18n.string_key;
167
-     *
168
-     * @access    public
169
-     * @var    array
170
-     */
171
-    public static $i18n_js_strings = array();
172
-
173
-
174
-    /**
175
-     *    $main_file - path to espresso.php
176
-     *
177
-     * @access    public
178
-     * @var    array
179
-     */
180
-    public $main_file;
181
-
182
-    /**
183
-     * array of ReflectionClass objects where the key is the class name
184
-     *
185
-     * @access    public
186
-     * @var ReflectionClass[]
187
-     */
188
-    public $_reflectors;
189
-
190
-    /**
191
-     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
192
-     *
193
-     * @access    protected
194
-     * @var boolean $_cache_on
195
-     */
196
-    protected $_cache_on = true;
197
-
198
-
199
-
200
-    /**
201
-     * @singleton method used to instantiate class object
202
-     * @access    public
203
-     * @param  \EE_Dependency_Map $dependency_map
204
-     * @return \EE_Registry instance
205
-     */
206
-    public static function instance(\EE_Dependency_Map $dependency_map = null)
207
-    {
208
-        // check if class object is instantiated
209
-        if ( ! self::$_instance instanceof EE_Registry) {
210
-            self::$_instance = new EE_Registry($dependency_map);
211
-        }
212
-        return self::$_instance;
213
-    }
214
-
215
-
216
-
217
-    /**
218
-     *protected constructor to prevent direct creation
219
-     *
220
-     * @Constructor
221
-     * @access protected
222
-     * @param  \EE_Dependency_Map $dependency_map
223
-     * @return \EE_Registry
224
-     */
225
-    protected function __construct(\EE_Dependency_Map $dependency_map)
226
-    {
227
-        $this->_dependency_map = $dependency_map;
228
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
229
-    }
230
-
231
-
232
-
233
-    /**
234
-     * initialize
235
-     */
236
-    public function initialize()
237
-    {
238
-        $this->_class_abbreviations = apply_filters(
239
-            'FHEE__EE_Registry____construct___class_abbreviations',
240
-            array(
241
-                'EE_Config'                                       => 'CFG',
242
-                'EE_Session'                                      => 'SSN',
243
-                'EE_Capabilities'                                 => 'CAP',
244
-                'EE_Cart'                                         => 'CART',
245
-                'EE_Network_Config'                               => 'NET_CFG',
246
-                'EE_Request_Handler'                              => 'REQ',
247
-                'EE_Message_Resource_Manager'                     => 'MRM',
248
-                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
249
-            )
250
-        );
251
-        // class library
252
-        $this->LIB = new stdClass();
253
-        $this->addons = new stdClass();
254
-        $this->modules = new stdClass();
255
-        $this->shortcodes = new stdClass();
256
-        $this->widgets = new stdClass();
257
-        $this->load_core('Base', array(), true);
258
-        // add our request and response objects to the cache
259
-        $request_loader = $this->_dependency_map->class_loader('EE_Request');
260
-        $this->_set_cached_class(
261
-            $request_loader(),
262
-            'EE_Request'
263
-        );
264
-        $response_loader = $this->_dependency_map->class_loader('EE_Response');
265
-        $this->_set_cached_class(
266
-            $response_loader(),
267
-            'EE_Response'
268
-        );
269
-        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
270
-    }
271
-
272
-
273
-
274
-    /**
275
-     *    init
276
-     *
277
-     * @access    public
278
-     * @return    void
279
-     */
280
-    public function init()
281
-    {
282
-        $this->AssetsRegistry = new Registry();
283
-        // Get current page protocol
284
-        $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
285
-        // Output admin-ajax.php URL with same protocol as current page
286
-        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
287
-        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
288
-    }
289
-
290
-
291
-
292
-    /**
293
-     * localize_i18n_js_strings
294
-     *
295
-     * @return string
296
-     */
297
-    public static function localize_i18n_js_strings()
298
-    {
299
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
300
-        foreach ($i18n_js_strings as $key => $value) {
301
-            if (is_scalar($value)) {
302
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
303
-            }
304
-        }
305
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
306
-    }
307
-
308
-
309
-
310
-    /**
311
-     * @param mixed string | EED_Module $module
312
-     */
313
-    public function add_module($module)
314
-    {
315
-        if ($module instanceof EED_Module) {
316
-            $module_class = get_class($module);
317
-            $this->modules->{$module_class} = $module;
318
-        } else {
319
-            if ( ! class_exists('EE_Module_Request_Router')) {
320
-                $this->load_core('Module_Request_Router');
321
-            }
322
-            $this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
323
-        }
324
-    }
325
-
326
-
327
-
328
-    /**
329
-     * @param string $module_name
330
-     * @return mixed EED_Module | NULL
331
-     */
332
-    public function get_module($module_name = '')
333
-    {
334
-        return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
335
-    }
336
-
337
-
338
-
339
-    /**
340
-     *    loads core classes - must be singletons
341
-     *
342
-     * @access    public
343
-     * @param string $class_name - simple class name ie: session
344
-     * @param mixed  $arguments
345
-     * @param bool   $load_only
346
-     * @return mixed
347
-     */
348
-    public function load_core($class_name, $arguments = array(), $load_only = false)
349
-    {
350
-        $core_paths = apply_filters(
351
-            'FHEE__EE_Registry__load_core__core_paths',
352
-            array(
353
-                EE_CORE,
354
-                EE_ADMIN,
355
-                EE_CPTS,
356
-                EE_CORE . 'data_migration_scripts' . DS,
357
-                EE_CORE . 'request_stack' . DS,
358
-                EE_CORE . 'middleware' . DS,
359
-            )
360
-        );
361
-        // retrieve instantiated class
362
-        return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     *    loads service classes
369
-     *
370
-     * @access    public
371
-     * @param string $class_name - simple class name ie: session
372
-     * @param mixed  $arguments
373
-     * @param bool   $load_only
374
-     * @return mixed
375
-     */
376
-    public function load_service($class_name, $arguments = array(), $load_only = false)
377
-    {
378
-        $service_paths = apply_filters(
379
-            'FHEE__EE_Registry__load_service__service_paths',
380
-            array(
381
-                EE_CORE . 'services' . DS,
382
-            )
383
-        );
384
-        // retrieve instantiated class
385
-        return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
386
-    }
387
-
388
-
389
-
390
-    /**
391
-     *    loads data_migration_scripts
392
-     *
393
-     * @access    public
394
-     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
395
-     * @param mixed  $arguments
396
-     * @return EE_Data_Migration_Script_Base|mixed
397
-     */
398
-    public function load_dms($class_name, $arguments = array())
399
-    {
400
-        // retrieve instantiated class
401
-        return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
402
-    }
403
-
404
-
405
-
406
-    /**
407
-     *    loads object creating classes - must be singletons
408
-     *
409
-     * @param string $class_name - simple class name ie: attendee
410
-     * @param mixed  $arguments  - an array of arguments to pass to the class
411
-     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
412
-     * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then set this to FALSE (ie. when instantiating model objects from client in a loop)
413
-     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
414
-     * @return EE_Base_Class | bool
415
-     */
416
-    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
417
-    {
418
-        $paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
419
-            EE_CORE,
420
-            EE_CLASSES,
421
-            EE_BUSINESS,
422
-        ));
423
-        // retrieve instantiated class
424
-        return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
425
-    }
426
-
427
-
428
-
429
-    /**
430
-     *    loads helper classes - must be singletons
431
-     *
432
-     * @param string $class_name - simple class name ie: price
433
-     * @param mixed  $arguments
434
-     * @param bool   $load_only
435
-     * @return EEH_Base | bool
436
-     */
437
-    public function load_helper($class_name, $arguments = array(), $load_only = true)
438
-    {
439
-        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
440
-        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
441
-        // retrieve instantiated class
442
-        return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     *    loads core classes - must be singletons
449
-     *
450
-     * @access    public
451
-     * @param string $class_name - simple class name ie: session
452
-     * @param mixed  $arguments
453
-     * @param bool   $load_only
454
-     * @param bool   $cache      whether to cache the object or not.
455
-     * @return mixed
456
-     */
457
-    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
458
-    {
459
-        $paths = array(
460
-            EE_LIBRARIES,
461
-            EE_LIBRARIES . 'messages' . DS,
462
-            EE_LIBRARIES . 'shortcodes' . DS,
463
-            EE_LIBRARIES . 'qtips' . DS,
464
-            EE_LIBRARIES . 'payment_methods' . DS,
465
-        );
466
-        // retrieve instantiated class
467
-        return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
468
-    }
469
-
470
-
471
-
472
-    /**
473
-     *    loads model classes - must be singletons
474
-     *
475
-     * @param string $class_name - simple class name ie: price
476
-     * @param mixed  $arguments
477
-     * @param bool   $load_only
478
-     * @return EEM_Base | bool
479
-     */
480
-    public function load_model($class_name, $arguments = array(), $load_only = false)
481
-    {
482
-        $paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
483
-            EE_MODELS,
484
-            EE_CORE,
485
-        ));
486
-        // retrieve instantiated class
487
-        return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
488
-    }
489
-
490
-
491
-
492
-    /**
493
-     *    loads model classes - must be singletons
494
-     *
495
-     * @param string $class_name - simple class name ie: price
496
-     * @param mixed  $arguments
497
-     * @param bool   $load_only
498
-     * @return mixed | bool
499
-     */
500
-    public function load_model_class($class_name, $arguments = array(), $load_only = true)
501
-    {
502
-        $paths = array(
503
-            EE_MODELS . 'fields' . DS,
504
-            EE_MODELS . 'helpers' . DS,
505
-            EE_MODELS . 'relations' . DS,
506
-            EE_MODELS . 'strategies' . DS,
507
-        );
508
-        // retrieve instantiated class
509
-        return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
510
-    }
511
-
512
-
513
-
514
-    /**
515
-     * Determines if $model_name is the name of an actual EE model.
516
-     *
517
-     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
518
-     * @return boolean
519
-     */
520
-    public function is_model_name($model_name)
521
-    {
522
-        $this->_verify_models_discovered();
523
-        return isset($this->models[$model_name]) ? true : false;
524
-    }
525
-
526
-
527
-
528
-    /**
529
-     *    generic class loader
530
-     *
531
-     * @param string $path_to_file - directory path to file location, not including filename
532
-     * @param string $file_name    - file name  ie:  my_file.php, including extension
533
-     * @param string $type         - file type - core? class? helper? model?
534
-     * @param mixed  $arguments
535
-     * @param bool   $load_only
536
-     * @return mixed
537
-     */
538
-    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
539
-    {
540
-        // retrieve instantiated class
541
-        return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
542
-    }
543
-
544
-
545
-
546
-    /**
547
-     *    load_addon
548
-     *
549
-     * @param string $path_to_file - directory path to file location, not including filename
550
-     * @param string $class_name   - full class name  ie:  My_Class
551
-     * @param string $type         - file type - core? class? helper? model?
552
-     * @param mixed  $arguments
553
-     * @param bool   $load_only
554
-     * @return EE_Addon
555
-     */
556
-    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
557
-    {
558
-        // retrieve instantiated class
559
-        return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
560
-    }
561
-
562
-
563
-
564
-    /**
565
-     * instantiates, caches, and automatically resolves dependencies
566
-     * for classes that use a Fully Qualified Class Name.
567
-     * if the class is not capable of being loaded using PSR-4 autoloading,
568
-     * then you need to use one of the existing load_*() methods
569
-     * which can resolve the classname and filepath from the passed arguments
570
-     *
571
-     * @param bool|string $class_name   Fully Qualified Class Name
572
-     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
573
-     * @param bool        $cache        whether to cache the instantiated object for reuse
574
-     * @param bool        $from_db      some classes are instantiated from the db
575
-     *                                  and thus call a different method to instantiate
576
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
577
-     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
578
-     * @return mixed                    null = failure to load or instantiate class object.
579
-     *                                  object = class loaded and instantiated successfully.
580
-     *                                  bool = fail or success when $load_only is true
581
-     */
582
-    public function create(
583
-        $class_name = false,
584
-        $arguments = array(),
585
-        $cache = false,
586
-        $from_db = false,
587
-        $load_only = false,
588
-        $addon = false
589
-    ) {
590
-        $class_name = ltrim($class_name, '\\');
591
-        $class_name = $this->_dependency_map->get_alias($class_name);
592
-        if ( ! class_exists($class_name)) {
593
-            // maybe the class is registered with a preceding \
594
-            $class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
595
-            // still doesn't exist ?
596
-            if ( ! class_exists($class_name)) {
597
-                return null;
598
-            }
599
-        }
600
-        // if we're only loading the class and it already exists, then let's just return true immediately
601
-        if ($load_only) {
602
-            return true;
603
-        }
604
-        $addon = $addon ? 'addon' : '';
605
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
606
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
607
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
608
-        if ($this->_cache_on && $cache && ! $load_only) {
609
-            // return object if it's already cached
610
-            $cached_class = $this->_get_cached_class($class_name, $addon);
611
-            if ($cached_class !== null) {
612
-                return $cached_class;
613
-            }
614
-        }
615
-        // instantiate the requested object
616
-        $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
617
-        if ($this->_cache_on && $cache) {
618
-            // save it for later... kinda like gum  { : $
619
-            $this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
620
-        }
621
-        $this->_cache_on = true;
622
-        return $class_obj;
623
-    }
624
-
625
-
626
-
627
-    /**
628
-     * instantiates, caches, and injects dependencies for classes
629
-     *
630
-     * @param array       $file_paths   an array of paths to folders to look in
631
-     * @param string      $class_prefix EE  or EEM or... ???
632
-     * @param bool|string $class_name   $class name
633
-     * @param string      $type         file type - core? class? helper? model?
634
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
635
-     * @param bool        $from_db      some classes are instantiated from the db
636
-     *                                  and thus call a different method to instantiate
637
-     * @param bool        $cache        whether to cache the instantiated object for reuse
638
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
639
-     * @return null|object|bool         null = failure to load or instantiate class object.
640
-     *                                  object = class loaded and instantiated successfully.
641
-     *                                  bool = fail or success when $load_only is true
642
-     */
643
-    protected function _load(
644
-        $file_paths = array(),
645
-        $class_prefix = 'EE_',
646
-        $class_name = false,
647
-        $type = 'class',
648
-        $arguments = array(),
649
-        $from_db = false,
650
-        $cache = true,
651
-        $load_only = false
652
-    ) {
653
-        $class_name = ltrim($class_name, '\\');
654
-        // strip php file extension
655
-        $class_name = str_replace('.php', '', trim($class_name));
656
-        // does the class have a prefix ?
657
-        if ( ! empty($class_prefix) && $class_prefix != 'addon') {
658
-            // make sure $class_prefix is uppercase
659
-            $class_prefix = strtoupper(trim($class_prefix));
660
-            // add class prefix ONCE!!!
661
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
662
-        }
663
-        $class_name = $this->_dependency_map->get_alias($class_name);
664
-        $class_exists = class_exists($class_name);
665
-        // if we're only loading the class and it already exists, then let's just return true immediately
666
-        if ($load_only && $class_exists) {
667
-            return true;
668
-        }
669
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
670
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
671
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
672
-        if ($this->_cache_on && $cache && ! $load_only) {
673
-            // return object if it's already cached
674
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix);
675
-            if ($cached_class !== null) {
676
-                return $cached_class;
677
-            }
678
-        }
679
-        // if the class doesn't already exist.. then we need to try and find the file and load it
680
-        if ( ! $class_exists) {
681
-            // get full path to file
682
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
683
-            // load the file
684
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
685
-            // if loading failed, or we are only loading a file but NOT instantiating an object
686
-            if ( ! $loaded || $load_only) {
687
-                // return boolean if only loading, or null if an object was expected
688
-                return $load_only ? $loaded : null;
689
-            }
690
-        }
691
-        // instantiate the requested object
692
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
693
-        if ($this->_cache_on && $cache) {
694
-            // save it for later... kinda like gum  { : $
695
-            $this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
696
-        }
697
-        $this->_cache_on = true;
698
-        return $class_obj;
699
-    }
700
-
701
-
702
-
703
-    /**
704
-     * _get_cached_class
705
-     * attempts to find a cached version of the requested class
706
-     * by looking in the following places:
707
-     *        $this->{$class_abbreviation}            ie:    $this->CART
708
-     *        $this->{$class_name}                        ie:    $this->Some_Class
709
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
710
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
711
-     *
712
-     * @access protected
713
-     * @param string $class_name
714
-     * @param string $class_prefix
715
-     * @return mixed
716
-     */
717
-    protected function _get_cached_class($class_name, $class_prefix = '')
718
-    {
719
-        if (isset($this->_class_abbreviations[$class_name])) {
720
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
721
-        } else {
722
-            // have to specify something, but not anything that will conflict
723
-            $class_abbreviation = 'FANCY_BATMAN_PANTS';
724
-        }
725
-        // check if class has already been loaded, and return it if it has been
726
-        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
727
-            return $this->{$class_abbreviation};
728
-        } else if (isset ($this->{$class_name})) {
729
-            return $this->{$class_name};
730
-        } else if (isset ($this->LIB->{$class_name})) {
731
-            return $this->LIB->{$class_name};
732
-        } else if ($class_prefix == 'addon' && isset ($this->addons->{$class_name})) {
733
-            return $this->addons->{$class_name};
734
-        }
735
-        return null;
736
-    }
737
-
738
-
739
-
740
-    /**
741
-     * _resolve_path
742
-     * attempts to find a full valid filepath for the requested class.
743
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
744
-     * then returns that path if the target file has been found and is readable
745
-     *
746
-     * @access protected
747
-     * @param string $class_name
748
-     * @param string $type
749
-     * @param array  $file_paths
750
-     * @return string | bool
751
-     */
752
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
753
-    {
754
-        // make sure $file_paths is an array
755
-        $file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
756
-        // cycle thru paths
757
-        foreach ($file_paths as $key => $file_path) {
758
-            // convert all separators to proper DS, if no filepath, then use EE_CLASSES
759
-            $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
760
-            // prep file type
761
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
762
-            // build full file path
763
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
764
-            //does the file exist and can be read ?
765
-            if (is_readable($file_paths[$key])) {
766
-                return $file_paths[$key];
767
-            }
768
-        }
769
-        return false;
770
-    }
771
-
772
-
773
-
774
-    /**
775
-     * _require_file
776
-     * basically just performs a require_once()
777
-     * but with some error handling
778
-     *
779
-     * @access protected
780
-     * @param  string $path
781
-     * @param  string $class_name
782
-     * @param  string $type
783
-     * @param  array  $file_paths
784
-     * @return boolean
785
-     * @throws \EE_Error
786
-     */
787
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
788
-    {
789
-        // don't give up! you gotta...
790
-        try {
791
-            //does the file exist and can it be read ?
792
-            if ( ! $path) {
793
-                // so sorry, can't find the file
794
-                throw new EE_Error (
795
-                    sprintf(
796
-                        __('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
797
-                        trim($type, '.'),
798
-                        $class_name,
799
-                        '<br />' . implode(',<br />', $file_paths)
800
-                    )
801
-                );
802
-            }
803
-            // get the file
804
-            require_once($path);
805
-            // if the class isn't already declared somewhere
806
-            if (class_exists($class_name, false) === false) {
807
-                // so sorry, not a class
808
-                throw new EE_Error(
809
-                    sprintf(
810
-                        __('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
811
-                        $type,
812
-                        $path,
813
-                        $class_name
814
-                    )
815
-                );
816
-            }
817
-        } catch (EE_Error $e) {
818
-            $e->get_error();
819
-            return false;
820
-        }
821
-        return true;
822
-    }
823
-
824
-
825
-
826
-    /**
827
-     * _create_object
828
-     * Attempts to instantiate the requested class via any of the
829
-     * commonly used instantiation methods employed throughout EE.
830
-     * The priority for instantiation is as follows:
831
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
832
-     *        - model objects via their 'new_instance_from_db' method
833
-     *        - model objects via their 'new_instance' method
834
-     *        - "singleton" classes" via their 'instance' method
835
-     *    - standard instantiable classes via their __constructor
836
-     * Prior to instantiation, if the classname exists in the dependency_map,
837
-     * then the constructor for the requested class will be examined to determine
838
-     * if any dependencies exist, and if they can be injected.
839
-     * If so, then those classes will be added to the array of arguments passed to the constructor
840
-     *
841
-     * @access protected
842
-     * @param string $class_name
843
-     * @param array  $arguments
844
-     * @param string $type
845
-     * @param bool   $from_db
846
-     * @return null | object
847
-     * @throws \EE_Error
848
-     */
849
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
850
-    {
851
-        $class_obj = null;
852
-        $instantiation_mode = '0) none';
853
-        // don't give up! you gotta...
854
-        try {
855
-            // create reflection
856
-            $reflector = $this->get_ReflectionClass($class_name);
857
-            // make sure arguments are an array
858
-            $arguments = is_array($arguments) ? $arguments : array($arguments);
859
-            // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
860
-            // else wrap it in an additional array so that it doesn't get split into multiple parameters
861
-            $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
862
-                ? $arguments
863
-                : array($arguments);
864
-            // attempt to inject dependencies ?
865
-            if ($this->_dependency_map->has($class_name)) {
866
-                $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
867
-            }
868
-            // instantiate the class if possible
869
-            if ($reflector->isAbstract()) {
870
-                // nothing to instantiate, loading file was enough
871
-                // does not throw an exception so $instantiation_mode is unused
872
-                // $instantiation_mode = "1) no constructor abstract class";
873
-                $class_obj = true;
874
-            } else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
875
-                // no constructor = static methods only... nothing to instantiate, loading file was enough
876
-                $instantiation_mode = "2) no constructor but instantiable";
877
-                $class_obj = $reflector->newInstance();
878
-            } else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
879
-                $instantiation_mode = "3) new_instance_from_db()";
880
-                $class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
881
-            } else if (method_exists($class_name, 'new_instance')) {
882
-                $instantiation_mode = "4) new_instance()";
883
-                $class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
884
-            } else if (method_exists($class_name, 'instance')) {
885
-                $instantiation_mode = "5) instance()";
886
-                $class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
887
-            } else if ($reflector->isInstantiable()) {
888
-                $instantiation_mode = "6) constructor";
889
-                $class_obj = $reflector->newInstanceArgs($arguments);
890
-            } else {
891
-                // heh ? something's not right !
892
-                throw new EE_Error(
893
-                    sprintf(
894
-                        __('The %s file %s could not be instantiated.', 'event_espresso'),
895
-                        $type,
896
-                        $class_name
897
-                    )
898
-                );
899
-            }
900
-        } catch (Exception $e) {
901
-            if ( ! $e instanceof EE_Error) {
902
-                $e = new EE_Error(
903
-                    sprintf(
904
-                        __('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
905
-                        $class_name,
906
-                        '<br />',
907
-                        $e->getMessage(),
908
-                        $instantiation_mode
909
-                    )
910
-                );
911
-            }
912
-            $e->get_error();
913
-        }
914
-        return $class_obj;
915
-    }
916
-
917
-
918
-
919
-    /**
920
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
921
-     * @param array $array
922
-     * @return bool
923
-     */
924
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
925
-    {
926
-        return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
927
-    }
928
-
929
-
930
-
931
-    /**
932
-     * getReflectionClass
933
-     * checks if a ReflectionClass object has already been generated for a class
934
-     * and returns that instead of creating a new one
935
-     *
936
-     * @access public
937
-     * @param string $class_name
938
-     * @return ReflectionClass
939
-     */
940
-    public function get_ReflectionClass($class_name)
941
-    {
942
-        if (
943
-            ! isset($this->_reflectors[$class_name])
944
-            || ! $this->_reflectors[$class_name] instanceof ReflectionClass
945
-        ) {
946
-            $this->_reflectors[$class_name] = new ReflectionClass($class_name);
947
-        }
948
-        return $this->_reflectors[$class_name];
949
-    }
950
-
951
-
952
-
953
-    /**
954
-     * _resolve_dependencies
955
-     * examines the constructor for the requested class to determine
956
-     * if any dependencies exist, and if they can be injected.
957
-     * If so, then those classes will be added to the array of arguments passed to the constructor
958
-     * PLZ NOTE: this is achieved by type hinting the constructor params
959
-     * For example:
960
-     *        if attempting to load a class "Foo" with the following constructor:
961
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
962
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
963
-     *        but only IF they are NOT already present in the incoming arguments array,
964
-     *        and the correct classes can be loaded
965
-     *
966
-     * @access protected
967
-     * @param ReflectionClass $reflector
968
-     * @param string          $class_name
969
-     * @param array           $arguments
970
-     * @return array
971
-     * @throws \ReflectionException
972
-     */
973
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
974
-    {
975
-        // let's examine the constructor
976
-        $constructor = $reflector->getConstructor();
977
-        // whu? huh? nothing?
978
-        if ( ! $constructor) {
979
-            return $arguments;
980
-        }
981
-        // get constructor parameters
982
-        $params = $constructor->getParameters();
983
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
984
-        $argument_keys = array_keys($arguments);
985
-        // now loop thru all of the constructors expected parameters
986
-        foreach ($params as $index => $param) {
987
-            // is this a dependency for a specific class ?
988
-            $param_class = $param->getClass() ? $param->getClass()->name : null;
989
-            if (
990
-                // param is not even a class
991
-                empty($param_class)
992
-                // and something already exists in the incoming arguments for this param
993
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
994
-            ) {
995
-                // so let's skip this argument and move on to the next
996
-                continue;
997
-            } else if (
998
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
999
-                ! empty($param_class)
1000
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1001
-                && $arguments[$argument_keys[$index]] instanceof $param_class
1002
-            ) {
1003
-                // skip this argument and move on to the next
1004
-                continue;
1005
-            } else if (
1006
-                // parameter is type hinted as a class, and should be injected
1007
-                ! empty($param_class)
1008
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1009
-            ) {
1010
-                $arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1011
-            } else {
1012
-                try {
1013
-                    $arguments[$index] = $param->getDefaultValue();
1014
-                } catch (ReflectionException $e) {
1015
-                    throw new ReflectionException(
1016
-                        sprintf(
1017
-                            __('%1$s for parameter "$%2$s"', 'event_espresso'),
1018
-                            $e->getMessage(),
1019
-                            $param->getName()
1020
-                        )
1021
-                    );
1022
-                }
1023
-            }
1024
-        }
1025
-        return $arguments;
1026
-    }
1027
-
1028
-
1029
-
1030
-    /**
1031
-     * @access protected
1032
-     * @param string $class_name
1033
-     * @param string $param_class
1034
-     * @param array  $arguments
1035
-     * @param mixed  $index
1036
-     * @return array
1037
-     */
1038
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1039
-    {
1040
-        $dependency = null;
1041
-        // should dependency be loaded from cache ?
1042
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1043
-                    !== EE_Dependency_Map::load_new_object
1044
-            ? true
1045
-            : false;
1046
-        // we might have a dependency...
1047
-        // let's MAYBE try and find it in our cache if that's what's been requested
1048
-        $cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1049
-        // and grab it if it exists
1050
-        if ($cached_class instanceof $param_class) {
1051
-            $dependency = $cached_class;
1052
-        } else if ($param_class != $class_name) {
1053
-            // obtain the loader method from the dependency map
1054
-            $loader = $this->_dependency_map->class_loader($param_class);
1055
-            // is loader a custom closure ?
1056
-            if ($loader instanceof Closure) {
1057
-                $dependency = $loader();
1058
-            } else {
1059
-                // set the cache on property for the recursive loading call
1060
-                $this->_cache_on = $cache_on;
1061
-                // if not, then let's try and load it via the registry
1062
-                if (method_exists($this, $loader)) {
1063
-                    $dependency = $this->{$loader}($param_class);
1064
-                } else {
1065
-                    $dependency = $this->create($param_class, array(), $cache_on);
1066
-                }
1067
-            }
1068
-        }
1069
-        // did we successfully find the correct dependency ?
1070
-        if ($dependency instanceof $param_class) {
1071
-            // then let's inject it into the incoming array of arguments at the correct location
1072
-            if (isset($argument_keys[$index])) {
1073
-                $arguments[$argument_keys[$index]] = $dependency;
1074
-            } else {
1075
-                $arguments[$index] = $dependency;
1076
-            }
1077
-        }
1078
-        return $arguments;
1079
-    }
1080
-
1081
-
1082
-
1083
-    /**
1084
-     * _set_cached_class
1085
-     * attempts to cache the instantiated class locally
1086
-     * in one of the following places, in the following order:
1087
-     *        $this->{class_abbreviation}   ie:    $this->CART
1088
-     *        $this->{$class_name}          ie:    $this->Some_Class
1089
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1090
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1091
-     *
1092
-     * @access protected
1093
-     * @param object $class_obj
1094
-     * @param string $class_name
1095
-     * @param string $class_prefix
1096
-     * @param bool   $from_db
1097
-     * @return void
1098
-     */
1099
-    protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1100
-    {
1101
-        if (empty($class_obj)) {
1102
-            return;
1103
-        }
1104
-        // return newly instantiated class
1105
-        if (isset($this->_class_abbreviations[$class_name])) {
1106
-            $class_abbreviation = $this->_class_abbreviations[$class_name];
1107
-            $this->{$class_abbreviation} = $class_obj;
1108
-        } else if (property_exists($this, $class_name)) {
1109
-            $this->{$class_name} = $class_obj;
1110
-        } else if ($class_prefix == 'addon') {
1111
-            $this->addons->{$class_name} = $class_obj;
1112
-        } else if ( ! $from_db) {
1113
-            $this->LIB->{$class_name} = $class_obj;
1114
-        }
1115
-    }
1116
-
1117
-
1118
-
1119
-    /**
1120
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1121
-     *
1122
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1123
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1124
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1125
-     * @param array  $arguments
1126
-     * @return object
1127
-     */
1128
-    public static function factory($classname, $arguments = array())
1129
-    {
1130
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1131
-        if ($loader instanceof Closure) {
1132
-            return $loader($arguments);
1133
-        } else if (method_exists(EE_Registry::instance(), $loader)) {
1134
-            return EE_Registry::instance()->{$loader}($classname, $arguments);
1135
-        }
1136
-        return null;
1137
-    }
1138
-
1139
-
1140
-
1141
-    /**
1142
-     * Gets the addon by its name/slug (not classname. For that, just
1143
-     * use the classname as the property name on EE_Config::instance()->addons)
1144
-     *
1145
-     * @param string $name
1146
-     * @return EE_Addon
1147
-     */
1148
-    public function get_addon_by_name($name)
1149
-    {
1150
-        foreach ($this->addons as $addon) {
1151
-            if ($addon->name() == $name) {
1152
-                return $addon;
1153
-            }
1154
-        }
1155
-        return null;
1156
-    }
1157
-
1158
-
1159
-
1160
-    /**
1161
-     * Gets an array of all the registered addons, where the keys are their names. (ie, what each returns for their name() function) They're already available on EE_Config::instance()->addons as properties, where each property's name is
1162
-     * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1163
-     *
1164
-     * @return EE_Addon[] where the KEYS are the addon's name()
1165
-     */
1166
-    public function get_addons_by_name()
1167
-    {
1168
-        $addons = array();
1169
-        foreach ($this->addons as $addon) {
1170
-            $addons[$addon->name()] = $addon;
1171
-        }
1172
-        return $addons;
1173
-    }
1174
-
1175
-
1176
-
1177
-    /**
1178
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1179
-     * a stale copy of it around
1180
-     *
1181
-     * @param string $model_name
1182
-     * @return \EEM_Base
1183
-     * @throws \EE_Error
1184
-     */
1185
-    public function reset_model($model_name)
1186
-    {
1187
-        $model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1188
-        if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1189
-            return null;
1190
-        }
1191
-        //get that model reset it and make sure we nuke the old reference to it
1192
-        if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1193
-            $this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1194
-        } else {
1195
-            throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1196
-        }
1197
-        return $this->LIB->{$model_class_name};
1198
-    }
1199
-
1200
-
1201
-
1202
-    /**
1203
-     * Resets the registry.
1204
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1205
-     * is used in a multisite install.  Here is a list of things that are NOT reset.
1206
-     * - $_dependency_map
1207
-     * - $_class_abbreviations
1208
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1209
-     * - $REQ:  Still on the same request so no need to change.
1210
-     * - $CAP: There is no site specific state in the EE_Capability class.
1211
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1212
-     *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1213
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1214
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1215
-     *             switch or on the restore.
1216
-     * - $modules
1217
-     * - $shortcodes
1218
-     * - $widgets
1219
-     *
1220
-     * @param boolean $hard             whether to reset data in the database too, or just refresh
1221
-     *                                  the Registry to its state at the beginning of the request
1222
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1223
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1224
-     *                                  currently reinstantiate the singletons at the moment)
1225
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1226
-     *                                  code instead can just change the model context to a different blog id if necessary
1227
-     * @return EE_Registry
1228
-     */
1229
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1230
-    {
1231
-        $instance = self::instance();
1232
-        EEH_Activation::reset();
1233
-        //properties that get reset
1234
-        $instance->_cache_on = true;
1235
-        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1236
-        $instance->CART = null;
1237
-        $instance->MRM = null;
1238
-        $instance->AssetsRegistry = new Registry();
1239
-        //messages reset
1240
-        EED_Messages::reset();
1241
-        if ($reset_models) {
1242
-            foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1243
-                $instance->reset_model($model_name);
1244
-            }
1245
-        }
1246
-        $instance->LIB = new stdClass();
1247
-        return $instance;
1248
-    }
1249
-
1250
-
1251
-
1252
-    /**
1253
-     * @override magic methods
1254
-     * @return void
1255
-     */
1256
-    final function __destruct()
1257
-    {
1258
-    }
1259
-
1260
-
1261
-
1262
-    /**
1263
-     * @param $a
1264
-     * @param $b
1265
-     */
1266
-    final function __call($a, $b)
1267
-    {
1268
-    }
1269
-
1270
-
1271
-
1272
-    /**
1273
-     * @param $a
1274
-     */
1275
-    final function __get($a)
1276
-    {
1277
-    }
1278
-
1279
-
1280
-
1281
-    /**
1282
-     * @param $a
1283
-     * @param $b
1284
-     */
1285
-    final function __set($a, $b)
1286
-    {
1287
-    }
1288
-
1289
-
1290
-
1291
-    /**
1292
-     * @param $a
1293
-     */
1294
-    final function __isset($a)
1295
-    {
1296
-    }
19
+	/**
20
+	 *    EE_Registry Object
21
+	 *
22
+	 * @var EE_Registry $_instance
23
+	 * @access    private
24
+	 */
25
+	private static $_instance = null;
26
+
27
+	/**
28
+	 * @var EE_Dependency_Map $_dependency_map
29
+	 * @access    protected
30
+	 */
31
+	protected $_dependency_map = null;
32
+
33
+	/**
34
+	 * @var array $_class_abbreviations
35
+	 * @access    protected
36
+	 */
37
+	protected $_class_abbreviations = array();
38
+
39
+	/**
40
+	 * @access public
41
+	 * @var \EventEspresso\core\services\commands\CommandBusInterface $BUS
42
+	 */
43
+	public $BUS;
44
+
45
+	/**
46
+	 *    EE_Cart Object
47
+	 *
48
+	 * @access    public
49
+	 * @var    EE_Cart $CART
50
+	 */
51
+	public $CART = null;
52
+
53
+	/**
54
+	 *    EE_Config Object
55
+	 *
56
+	 * @access    public
57
+	 * @var    EE_Config $CFG
58
+	 */
59
+	public $CFG = null;
60
+
61
+	/**
62
+	 * EE_Network_Config Object
63
+	 *
64
+	 * @access public
65
+	 * @var EE_Network_Config $NET_CFG
66
+	 */
67
+	public $NET_CFG = null;
68
+
69
+	/**
70
+	 *    StdClass object for storing library classes in
71
+	 *
72
+	 * @public LIB
73
+	 * @var StdClass $LIB
74
+	 */
75
+	public $LIB = null;
76
+
77
+	/**
78
+	 *    EE_Request_Handler Object
79
+	 *
80
+	 * @access    public
81
+	 * @var    EE_Request_Handler $REQ
82
+	 */
83
+	public $REQ = null;
84
+
85
+	/**
86
+	 *    EE_Session Object
87
+	 *
88
+	 * @access    public
89
+	 * @var    EE_Session $SSN
90
+	 */
91
+	public $SSN = null;
92
+
93
+	/**
94
+	 * holds the ee capabilities object.
95
+	 *
96
+	 * @since 4.5.0
97
+	 * @var EE_Capabilities
98
+	 */
99
+	public $CAP = null;
100
+
101
+	/**
102
+	 * holds the EE_Message_Resource_Manager object.
103
+	 *
104
+	 * @since 4.9.0
105
+	 * @var EE_Message_Resource_Manager
106
+	 */
107
+	public $MRM = null;
108
+
109
+
110
+	/**
111
+	 * Holds the Assets Registry instance
112
+	 * @var Registry
113
+	 */
114
+	public $AssetsRegistry = null;
115
+
116
+	/**
117
+	 *    $addons - StdClass object for holding addons which have registered themselves to work with EE core
118
+	 *
119
+	 * @access    public
120
+	 * @var    EE_Addon[]
121
+	 */
122
+	public $addons = null;
123
+
124
+	/**
125
+	 *    $models
126
+	 * @access    public
127
+	 * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
128
+	 */
129
+	public $models = array();
130
+
131
+	/**
132
+	 *    $modules
133
+	 * @access    public
134
+	 * @var    EED_Module[] $modules
135
+	 */
136
+	public $modules = null;
137
+
138
+	/**
139
+	 *    $shortcodes
140
+	 * @access    public
141
+	 * @var    EES_Shortcode[] $shortcodes
142
+	 */
143
+	public $shortcodes = null;
144
+
145
+	/**
146
+	 *    $widgets
147
+	 * @access    public
148
+	 * @var    WP_Widget[] $widgets
149
+	 */
150
+	public $widgets = null;
151
+
152
+	/**
153
+	 * $non_abstract_db_models
154
+	 * @access public but its better to use EE_Registry::non_abstract_db_models() as it verifies we've set this property before returning it
155
+	 * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
156
+	 * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
157
+	 * Keys are model "short names" (eg "Event") as used in model relations, and values are
158
+	 * classnames (eg "EEM_Event")
159
+	 */
160
+	public $non_abstract_db_models = array();
161
+
162
+
163
+	/**
164
+	 *    $i18n_js_strings - internationalization for JS strings
165
+	 *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
166
+	 *    in js file:  var translatedString = eei18n.string_key;
167
+	 *
168
+	 * @access    public
169
+	 * @var    array
170
+	 */
171
+	public static $i18n_js_strings = array();
172
+
173
+
174
+	/**
175
+	 *    $main_file - path to espresso.php
176
+	 *
177
+	 * @access    public
178
+	 * @var    array
179
+	 */
180
+	public $main_file;
181
+
182
+	/**
183
+	 * array of ReflectionClass objects where the key is the class name
184
+	 *
185
+	 * @access    public
186
+	 * @var ReflectionClass[]
187
+	 */
188
+	public $_reflectors;
189
+
190
+	/**
191
+	 * boolean flag to indicate whether or not to load/save dependencies from/to the cache
192
+	 *
193
+	 * @access    protected
194
+	 * @var boolean $_cache_on
195
+	 */
196
+	protected $_cache_on = true;
197
+
198
+
199
+
200
+	/**
201
+	 * @singleton method used to instantiate class object
202
+	 * @access    public
203
+	 * @param  \EE_Dependency_Map $dependency_map
204
+	 * @return \EE_Registry instance
205
+	 */
206
+	public static function instance(\EE_Dependency_Map $dependency_map = null)
207
+	{
208
+		// check if class object is instantiated
209
+		if ( ! self::$_instance instanceof EE_Registry) {
210
+			self::$_instance = new EE_Registry($dependency_map);
211
+		}
212
+		return self::$_instance;
213
+	}
214
+
215
+
216
+
217
+	/**
218
+	 *protected constructor to prevent direct creation
219
+	 *
220
+	 * @Constructor
221
+	 * @access protected
222
+	 * @param  \EE_Dependency_Map $dependency_map
223
+	 * @return \EE_Registry
224
+	 */
225
+	protected function __construct(\EE_Dependency_Map $dependency_map)
226
+	{
227
+		$this->_dependency_map = $dependency_map;
228
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
229
+	}
230
+
231
+
232
+
233
+	/**
234
+	 * initialize
235
+	 */
236
+	public function initialize()
237
+	{
238
+		$this->_class_abbreviations = apply_filters(
239
+			'FHEE__EE_Registry____construct___class_abbreviations',
240
+			array(
241
+				'EE_Config'                                       => 'CFG',
242
+				'EE_Session'                                      => 'SSN',
243
+				'EE_Capabilities'                                 => 'CAP',
244
+				'EE_Cart'                                         => 'CART',
245
+				'EE_Network_Config'                               => 'NET_CFG',
246
+				'EE_Request_Handler'                              => 'REQ',
247
+				'EE_Message_Resource_Manager'                     => 'MRM',
248
+				'EventEspresso\core\services\commands\CommandBus' => 'BUS',
249
+			)
250
+		);
251
+		// class library
252
+		$this->LIB = new stdClass();
253
+		$this->addons = new stdClass();
254
+		$this->modules = new stdClass();
255
+		$this->shortcodes = new stdClass();
256
+		$this->widgets = new stdClass();
257
+		$this->load_core('Base', array(), true);
258
+		// add our request and response objects to the cache
259
+		$request_loader = $this->_dependency_map->class_loader('EE_Request');
260
+		$this->_set_cached_class(
261
+			$request_loader(),
262
+			'EE_Request'
263
+		);
264
+		$response_loader = $this->_dependency_map->class_loader('EE_Response');
265
+		$this->_set_cached_class(
266
+			$response_loader(),
267
+			'EE_Response'
268
+		);
269
+		add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
270
+	}
271
+
272
+
273
+
274
+	/**
275
+	 *    init
276
+	 *
277
+	 * @access    public
278
+	 * @return    void
279
+	 */
280
+	public function init()
281
+	{
282
+		$this->AssetsRegistry = new Registry();
283
+		// Get current page protocol
284
+		$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
285
+		// Output admin-ajax.php URL with same protocol as current page
286
+		self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
287
+		self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
288
+	}
289
+
290
+
291
+
292
+	/**
293
+	 * localize_i18n_js_strings
294
+	 *
295
+	 * @return string
296
+	 */
297
+	public static function localize_i18n_js_strings()
298
+	{
299
+		$i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
300
+		foreach ($i18n_js_strings as $key => $value) {
301
+			if (is_scalar($value)) {
302
+				$i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
303
+			}
304
+		}
305
+		return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
306
+	}
307
+
308
+
309
+
310
+	/**
311
+	 * @param mixed string | EED_Module $module
312
+	 */
313
+	public function add_module($module)
314
+	{
315
+		if ($module instanceof EED_Module) {
316
+			$module_class = get_class($module);
317
+			$this->modules->{$module_class} = $module;
318
+		} else {
319
+			if ( ! class_exists('EE_Module_Request_Router')) {
320
+				$this->load_core('Module_Request_Router');
321
+			}
322
+			$this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
323
+		}
324
+	}
325
+
326
+
327
+
328
+	/**
329
+	 * @param string $module_name
330
+	 * @return mixed EED_Module | NULL
331
+	 */
332
+	public function get_module($module_name = '')
333
+	{
334
+		return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
335
+	}
336
+
337
+
338
+
339
+	/**
340
+	 *    loads core classes - must be singletons
341
+	 *
342
+	 * @access    public
343
+	 * @param string $class_name - simple class name ie: session
344
+	 * @param mixed  $arguments
345
+	 * @param bool   $load_only
346
+	 * @return mixed
347
+	 */
348
+	public function load_core($class_name, $arguments = array(), $load_only = false)
349
+	{
350
+		$core_paths = apply_filters(
351
+			'FHEE__EE_Registry__load_core__core_paths',
352
+			array(
353
+				EE_CORE,
354
+				EE_ADMIN,
355
+				EE_CPTS,
356
+				EE_CORE . 'data_migration_scripts' . DS,
357
+				EE_CORE . 'request_stack' . DS,
358
+				EE_CORE . 'middleware' . DS,
359
+			)
360
+		);
361
+		// retrieve instantiated class
362
+		return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 *    loads service classes
369
+	 *
370
+	 * @access    public
371
+	 * @param string $class_name - simple class name ie: session
372
+	 * @param mixed  $arguments
373
+	 * @param bool   $load_only
374
+	 * @return mixed
375
+	 */
376
+	public function load_service($class_name, $arguments = array(), $load_only = false)
377
+	{
378
+		$service_paths = apply_filters(
379
+			'FHEE__EE_Registry__load_service__service_paths',
380
+			array(
381
+				EE_CORE . 'services' . DS,
382
+			)
383
+		);
384
+		// retrieve instantiated class
385
+		return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
386
+	}
387
+
388
+
389
+
390
+	/**
391
+	 *    loads data_migration_scripts
392
+	 *
393
+	 * @access    public
394
+	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
395
+	 * @param mixed  $arguments
396
+	 * @return EE_Data_Migration_Script_Base|mixed
397
+	 */
398
+	public function load_dms($class_name, $arguments = array())
399
+	{
400
+		// retrieve instantiated class
401
+		return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
402
+	}
403
+
404
+
405
+
406
+	/**
407
+	 *    loads object creating classes - must be singletons
408
+	 *
409
+	 * @param string $class_name - simple class name ie: attendee
410
+	 * @param mixed  $arguments  - an array of arguments to pass to the class
411
+	 * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
412
+	 * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then set this to FALSE (ie. when instantiating model objects from client in a loop)
413
+	 * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
414
+	 * @return EE_Base_Class | bool
415
+	 */
416
+	public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
417
+	{
418
+		$paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
419
+			EE_CORE,
420
+			EE_CLASSES,
421
+			EE_BUSINESS,
422
+		));
423
+		// retrieve instantiated class
424
+		return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
425
+	}
426
+
427
+
428
+
429
+	/**
430
+	 *    loads helper classes - must be singletons
431
+	 *
432
+	 * @param string $class_name - simple class name ie: price
433
+	 * @param mixed  $arguments
434
+	 * @param bool   $load_only
435
+	 * @return EEH_Base | bool
436
+	 */
437
+	public function load_helper($class_name, $arguments = array(), $load_only = true)
438
+	{
439
+		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
440
+		$helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
441
+		// retrieve instantiated class
442
+		return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 *    loads core classes - must be singletons
449
+	 *
450
+	 * @access    public
451
+	 * @param string $class_name - simple class name ie: session
452
+	 * @param mixed  $arguments
453
+	 * @param bool   $load_only
454
+	 * @param bool   $cache      whether to cache the object or not.
455
+	 * @return mixed
456
+	 */
457
+	public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
458
+	{
459
+		$paths = array(
460
+			EE_LIBRARIES,
461
+			EE_LIBRARIES . 'messages' . DS,
462
+			EE_LIBRARIES . 'shortcodes' . DS,
463
+			EE_LIBRARIES . 'qtips' . DS,
464
+			EE_LIBRARIES . 'payment_methods' . DS,
465
+		);
466
+		// retrieve instantiated class
467
+		return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
468
+	}
469
+
470
+
471
+
472
+	/**
473
+	 *    loads model classes - must be singletons
474
+	 *
475
+	 * @param string $class_name - simple class name ie: price
476
+	 * @param mixed  $arguments
477
+	 * @param bool   $load_only
478
+	 * @return EEM_Base | bool
479
+	 */
480
+	public function load_model($class_name, $arguments = array(), $load_only = false)
481
+	{
482
+		$paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
483
+			EE_MODELS,
484
+			EE_CORE,
485
+		));
486
+		// retrieve instantiated class
487
+		return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
488
+	}
489
+
490
+
491
+
492
+	/**
493
+	 *    loads model classes - must be singletons
494
+	 *
495
+	 * @param string $class_name - simple class name ie: price
496
+	 * @param mixed  $arguments
497
+	 * @param bool   $load_only
498
+	 * @return mixed | bool
499
+	 */
500
+	public function load_model_class($class_name, $arguments = array(), $load_only = true)
501
+	{
502
+		$paths = array(
503
+			EE_MODELS . 'fields' . DS,
504
+			EE_MODELS . 'helpers' . DS,
505
+			EE_MODELS . 'relations' . DS,
506
+			EE_MODELS . 'strategies' . DS,
507
+		);
508
+		// retrieve instantiated class
509
+		return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
510
+	}
511
+
512
+
513
+
514
+	/**
515
+	 * Determines if $model_name is the name of an actual EE model.
516
+	 *
517
+	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
518
+	 * @return boolean
519
+	 */
520
+	public function is_model_name($model_name)
521
+	{
522
+		$this->_verify_models_discovered();
523
+		return isset($this->models[$model_name]) ? true : false;
524
+	}
525
+
526
+
527
+
528
+	/**
529
+	 *    generic class loader
530
+	 *
531
+	 * @param string $path_to_file - directory path to file location, not including filename
532
+	 * @param string $file_name    - file name  ie:  my_file.php, including extension
533
+	 * @param string $type         - file type - core? class? helper? model?
534
+	 * @param mixed  $arguments
535
+	 * @param bool   $load_only
536
+	 * @return mixed
537
+	 */
538
+	public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
539
+	{
540
+		// retrieve instantiated class
541
+		return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
542
+	}
543
+
544
+
545
+
546
+	/**
547
+	 *    load_addon
548
+	 *
549
+	 * @param string $path_to_file - directory path to file location, not including filename
550
+	 * @param string $class_name   - full class name  ie:  My_Class
551
+	 * @param string $type         - file type - core? class? helper? model?
552
+	 * @param mixed  $arguments
553
+	 * @param bool   $load_only
554
+	 * @return EE_Addon
555
+	 */
556
+	public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
557
+	{
558
+		// retrieve instantiated class
559
+		return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
560
+	}
561
+
562
+
563
+
564
+	/**
565
+	 * instantiates, caches, and automatically resolves dependencies
566
+	 * for classes that use a Fully Qualified Class Name.
567
+	 * if the class is not capable of being loaded using PSR-4 autoloading,
568
+	 * then you need to use one of the existing load_*() methods
569
+	 * which can resolve the classname and filepath from the passed arguments
570
+	 *
571
+	 * @param bool|string $class_name   Fully Qualified Class Name
572
+	 * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
573
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
574
+	 * @param bool        $from_db      some classes are instantiated from the db
575
+	 *                                  and thus call a different method to instantiate
576
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
577
+	 * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
578
+	 * @return mixed                    null = failure to load or instantiate class object.
579
+	 *                                  object = class loaded and instantiated successfully.
580
+	 *                                  bool = fail or success when $load_only is true
581
+	 */
582
+	public function create(
583
+		$class_name = false,
584
+		$arguments = array(),
585
+		$cache = false,
586
+		$from_db = false,
587
+		$load_only = false,
588
+		$addon = false
589
+	) {
590
+		$class_name = ltrim($class_name, '\\');
591
+		$class_name = $this->_dependency_map->get_alias($class_name);
592
+		if ( ! class_exists($class_name)) {
593
+			// maybe the class is registered with a preceding \
594
+			$class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
595
+			// still doesn't exist ?
596
+			if ( ! class_exists($class_name)) {
597
+				return null;
598
+			}
599
+		}
600
+		// if we're only loading the class and it already exists, then let's just return true immediately
601
+		if ($load_only) {
602
+			return true;
603
+		}
604
+		$addon = $addon ? 'addon' : '';
605
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
606
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
607
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
608
+		if ($this->_cache_on && $cache && ! $load_only) {
609
+			// return object if it's already cached
610
+			$cached_class = $this->_get_cached_class($class_name, $addon);
611
+			if ($cached_class !== null) {
612
+				return $cached_class;
613
+			}
614
+		}
615
+		// instantiate the requested object
616
+		$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
617
+		if ($this->_cache_on && $cache) {
618
+			// save it for later... kinda like gum  { : $
619
+			$this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
620
+		}
621
+		$this->_cache_on = true;
622
+		return $class_obj;
623
+	}
624
+
625
+
626
+
627
+	/**
628
+	 * instantiates, caches, and injects dependencies for classes
629
+	 *
630
+	 * @param array       $file_paths   an array of paths to folders to look in
631
+	 * @param string      $class_prefix EE  or EEM or... ???
632
+	 * @param bool|string $class_name   $class name
633
+	 * @param string      $type         file type - core? class? helper? model?
634
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
635
+	 * @param bool        $from_db      some classes are instantiated from the db
636
+	 *                                  and thus call a different method to instantiate
637
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
638
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
639
+	 * @return null|object|bool         null = failure to load or instantiate class object.
640
+	 *                                  object = class loaded and instantiated successfully.
641
+	 *                                  bool = fail or success when $load_only is true
642
+	 */
643
+	protected function _load(
644
+		$file_paths = array(),
645
+		$class_prefix = 'EE_',
646
+		$class_name = false,
647
+		$type = 'class',
648
+		$arguments = array(),
649
+		$from_db = false,
650
+		$cache = true,
651
+		$load_only = false
652
+	) {
653
+		$class_name = ltrim($class_name, '\\');
654
+		// strip php file extension
655
+		$class_name = str_replace('.php', '', trim($class_name));
656
+		// does the class have a prefix ?
657
+		if ( ! empty($class_prefix) && $class_prefix != 'addon') {
658
+			// make sure $class_prefix is uppercase
659
+			$class_prefix = strtoupper(trim($class_prefix));
660
+			// add class prefix ONCE!!!
661
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
662
+		}
663
+		$class_name = $this->_dependency_map->get_alias($class_name);
664
+		$class_exists = class_exists($class_name);
665
+		// if we're only loading the class and it already exists, then let's just return true immediately
666
+		if ($load_only && $class_exists) {
667
+			return true;
668
+		}
669
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
670
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
671
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
672
+		if ($this->_cache_on && $cache && ! $load_only) {
673
+			// return object if it's already cached
674
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix);
675
+			if ($cached_class !== null) {
676
+				return $cached_class;
677
+			}
678
+		}
679
+		// if the class doesn't already exist.. then we need to try and find the file and load it
680
+		if ( ! $class_exists) {
681
+			// get full path to file
682
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
683
+			// load the file
684
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
685
+			// if loading failed, or we are only loading a file but NOT instantiating an object
686
+			if ( ! $loaded || $load_only) {
687
+				// return boolean if only loading, or null if an object was expected
688
+				return $load_only ? $loaded : null;
689
+			}
690
+		}
691
+		// instantiate the requested object
692
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
693
+		if ($this->_cache_on && $cache) {
694
+			// save it for later... kinda like gum  { : $
695
+			$this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
696
+		}
697
+		$this->_cache_on = true;
698
+		return $class_obj;
699
+	}
700
+
701
+
702
+
703
+	/**
704
+	 * _get_cached_class
705
+	 * attempts to find a cached version of the requested class
706
+	 * by looking in the following places:
707
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
708
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
709
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
710
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
711
+	 *
712
+	 * @access protected
713
+	 * @param string $class_name
714
+	 * @param string $class_prefix
715
+	 * @return mixed
716
+	 */
717
+	protected function _get_cached_class($class_name, $class_prefix = '')
718
+	{
719
+		if (isset($this->_class_abbreviations[$class_name])) {
720
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
721
+		} else {
722
+			// have to specify something, but not anything that will conflict
723
+			$class_abbreviation = 'FANCY_BATMAN_PANTS';
724
+		}
725
+		// check if class has already been loaded, and return it if it has been
726
+		if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
727
+			return $this->{$class_abbreviation};
728
+		} else if (isset ($this->{$class_name})) {
729
+			return $this->{$class_name};
730
+		} else if (isset ($this->LIB->{$class_name})) {
731
+			return $this->LIB->{$class_name};
732
+		} else if ($class_prefix == 'addon' && isset ($this->addons->{$class_name})) {
733
+			return $this->addons->{$class_name};
734
+		}
735
+		return null;
736
+	}
737
+
738
+
739
+
740
+	/**
741
+	 * _resolve_path
742
+	 * attempts to find a full valid filepath for the requested class.
743
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
744
+	 * then returns that path if the target file has been found and is readable
745
+	 *
746
+	 * @access protected
747
+	 * @param string $class_name
748
+	 * @param string $type
749
+	 * @param array  $file_paths
750
+	 * @return string | bool
751
+	 */
752
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
753
+	{
754
+		// make sure $file_paths is an array
755
+		$file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
756
+		// cycle thru paths
757
+		foreach ($file_paths as $key => $file_path) {
758
+			// convert all separators to proper DS, if no filepath, then use EE_CLASSES
759
+			$file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
760
+			// prep file type
761
+			$type = ! empty($type) ? trim($type, '.') . '.' : '';
762
+			// build full file path
763
+			$file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
764
+			//does the file exist and can be read ?
765
+			if (is_readable($file_paths[$key])) {
766
+				return $file_paths[$key];
767
+			}
768
+		}
769
+		return false;
770
+	}
771
+
772
+
773
+
774
+	/**
775
+	 * _require_file
776
+	 * basically just performs a require_once()
777
+	 * but with some error handling
778
+	 *
779
+	 * @access protected
780
+	 * @param  string $path
781
+	 * @param  string $class_name
782
+	 * @param  string $type
783
+	 * @param  array  $file_paths
784
+	 * @return boolean
785
+	 * @throws \EE_Error
786
+	 */
787
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
788
+	{
789
+		// don't give up! you gotta...
790
+		try {
791
+			//does the file exist and can it be read ?
792
+			if ( ! $path) {
793
+				// so sorry, can't find the file
794
+				throw new EE_Error (
795
+					sprintf(
796
+						__('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
797
+						trim($type, '.'),
798
+						$class_name,
799
+						'<br />' . implode(',<br />', $file_paths)
800
+					)
801
+				);
802
+			}
803
+			// get the file
804
+			require_once($path);
805
+			// if the class isn't already declared somewhere
806
+			if (class_exists($class_name, false) === false) {
807
+				// so sorry, not a class
808
+				throw new EE_Error(
809
+					sprintf(
810
+						__('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
811
+						$type,
812
+						$path,
813
+						$class_name
814
+					)
815
+				);
816
+			}
817
+		} catch (EE_Error $e) {
818
+			$e->get_error();
819
+			return false;
820
+		}
821
+		return true;
822
+	}
823
+
824
+
825
+
826
+	/**
827
+	 * _create_object
828
+	 * Attempts to instantiate the requested class via any of the
829
+	 * commonly used instantiation methods employed throughout EE.
830
+	 * The priority for instantiation is as follows:
831
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
832
+	 *        - model objects via their 'new_instance_from_db' method
833
+	 *        - model objects via their 'new_instance' method
834
+	 *        - "singleton" classes" via their 'instance' method
835
+	 *    - standard instantiable classes via their __constructor
836
+	 * Prior to instantiation, if the classname exists in the dependency_map,
837
+	 * then the constructor for the requested class will be examined to determine
838
+	 * if any dependencies exist, and if they can be injected.
839
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
840
+	 *
841
+	 * @access protected
842
+	 * @param string $class_name
843
+	 * @param array  $arguments
844
+	 * @param string $type
845
+	 * @param bool   $from_db
846
+	 * @return null | object
847
+	 * @throws \EE_Error
848
+	 */
849
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
850
+	{
851
+		$class_obj = null;
852
+		$instantiation_mode = '0) none';
853
+		// don't give up! you gotta...
854
+		try {
855
+			// create reflection
856
+			$reflector = $this->get_ReflectionClass($class_name);
857
+			// make sure arguments are an array
858
+			$arguments = is_array($arguments) ? $arguments : array($arguments);
859
+			// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
860
+			// else wrap it in an additional array so that it doesn't get split into multiple parameters
861
+			$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
862
+				? $arguments
863
+				: array($arguments);
864
+			// attempt to inject dependencies ?
865
+			if ($this->_dependency_map->has($class_name)) {
866
+				$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
867
+			}
868
+			// instantiate the class if possible
869
+			if ($reflector->isAbstract()) {
870
+				// nothing to instantiate, loading file was enough
871
+				// does not throw an exception so $instantiation_mode is unused
872
+				// $instantiation_mode = "1) no constructor abstract class";
873
+				$class_obj = true;
874
+			} else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
875
+				// no constructor = static methods only... nothing to instantiate, loading file was enough
876
+				$instantiation_mode = "2) no constructor but instantiable";
877
+				$class_obj = $reflector->newInstance();
878
+			} else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
879
+				$instantiation_mode = "3) new_instance_from_db()";
880
+				$class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
881
+			} else if (method_exists($class_name, 'new_instance')) {
882
+				$instantiation_mode = "4) new_instance()";
883
+				$class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
884
+			} else if (method_exists($class_name, 'instance')) {
885
+				$instantiation_mode = "5) instance()";
886
+				$class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
887
+			} else if ($reflector->isInstantiable()) {
888
+				$instantiation_mode = "6) constructor";
889
+				$class_obj = $reflector->newInstanceArgs($arguments);
890
+			} else {
891
+				// heh ? something's not right !
892
+				throw new EE_Error(
893
+					sprintf(
894
+						__('The %s file %s could not be instantiated.', 'event_espresso'),
895
+						$type,
896
+						$class_name
897
+					)
898
+				);
899
+			}
900
+		} catch (Exception $e) {
901
+			if ( ! $e instanceof EE_Error) {
902
+				$e = new EE_Error(
903
+					sprintf(
904
+						__('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
905
+						$class_name,
906
+						'<br />',
907
+						$e->getMessage(),
908
+						$instantiation_mode
909
+					)
910
+				);
911
+			}
912
+			$e->get_error();
913
+		}
914
+		return $class_obj;
915
+	}
916
+
917
+
918
+
919
+	/**
920
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
921
+	 * @param array $array
922
+	 * @return bool
923
+	 */
924
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
925
+	{
926
+		return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
927
+	}
928
+
929
+
930
+
931
+	/**
932
+	 * getReflectionClass
933
+	 * checks if a ReflectionClass object has already been generated for a class
934
+	 * and returns that instead of creating a new one
935
+	 *
936
+	 * @access public
937
+	 * @param string $class_name
938
+	 * @return ReflectionClass
939
+	 */
940
+	public function get_ReflectionClass($class_name)
941
+	{
942
+		if (
943
+			! isset($this->_reflectors[$class_name])
944
+			|| ! $this->_reflectors[$class_name] instanceof ReflectionClass
945
+		) {
946
+			$this->_reflectors[$class_name] = new ReflectionClass($class_name);
947
+		}
948
+		return $this->_reflectors[$class_name];
949
+	}
950
+
951
+
952
+
953
+	/**
954
+	 * _resolve_dependencies
955
+	 * examines the constructor for the requested class to determine
956
+	 * if any dependencies exist, and if they can be injected.
957
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
958
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
959
+	 * For example:
960
+	 *        if attempting to load a class "Foo" with the following constructor:
961
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
962
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
963
+	 *        but only IF they are NOT already present in the incoming arguments array,
964
+	 *        and the correct classes can be loaded
965
+	 *
966
+	 * @access protected
967
+	 * @param ReflectionClass $reflector
968
+	 * @param string          $class_name
969
+	 * @param array           $arguments
970
+	 * @return array
971
+	 * @throws \ReflectionException
972
+	 */
973
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
974
+	{
975
+		// let's examine the constructor
976
+		$constructor = $reflector->getConstructor();
977
+		// whu? huh? nothing?
978
+		if ( ! $constructor) {
979
+			return $arguments;
980
+		}
981
+		// get constructor parameters
982
+		$params = $constructor->getParameters();
983
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
984
+		$argument_keys = array_keys($arguments);
985
+		// now loop thru all of the constructors expected parameters
986
+		foreach ($params as $index => $param) {
987
+			// is this a dependency for a specific class ?
988
+			$param_class = $param->getClass() ? $param->getClass()->name : null;
989
+			if (
990
+				// param is not even a class
991
+				empty($param_class)
992
+				// and something already exists in the incoming arguments for this param
993
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
994
+			) {
995
+				// so let's skip this argument and move on to the next
996
+				continue;
997
+			} else if (
998
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
999
+				! empty($param_class)
1000
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1001
+				&& $arguments[$argument_keys[$index]] instanceof $param_class
1002
+			) {
1003
+				// skip this argument and move on to the next
1004
+				continue;
1005
+			} else if (
1006
+				// parameter is type hinted as a class, and should be injected
1007
+				! empty($param_class)
1008
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1009
+			) {
1010
+				$arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1011
+			} else {
1012
+				try {
1013
+					$arguments[$index] = $param->getDefaultValue();
1014
+				} catch (ReflectionException $e) {
1015
+					throw new ReflectionException(
1016
+						sprintf(
1017
+							__('%1$s for parameter "$%2$s"', 'event_espresso'),
1018
+							$e->getMessage(),
1019
+							$param->getName()
1020
+						)
1021
+					);
1022
+				}
1023
+			}
1024
+		}
1025
+		return $arguments;
1026
+	}
1027
+
1028
+
1029
+
1030
+	/**
1031
+	 * @access protected
1032
+	 * @param string $class_name
1033
+	 * @param string $param_class
1034
+	 * @param array  $arguments
1035
+	 * @param mixed  $index
1036
+	 * @return array
1037
+	 */
1038
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1039
+	{
1040
+		$dependency = null;
1041
+		// should dependency be loaded from cache ?
1042
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1043
+					!== EE_Dependency_Map::load_new_object
1044
+			? true
1045
+			: false;
1046
+		// we might have a dependency...
1047
+		// let's MAYBE try and find it in our cache if that's what's been requested
1048
+		$cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1049
+		// and grab it if it exists
1050
+		if ($cached_class instanceof $param_class) {
1051
+			$dependency = $cached_class;
1052
+		} else if ($param_class != $class_name) {
1053
+			// obtain the loader method from the dependency map
1054
+			$loader = $this->_dependency_map->class_loader($param_class);
1055
+			// is loader a custom closure ?
1056
+			if ($loader instanceof Closure) {
1057
+				$dependency = $loader();
1058
+			} else {
1059
+				// set the cache on property for the recursive loading call
1060
+				$this->_cache_on = $cache_on;
1061
+				// if not, then let's try and load it via the registry
1062
+				if (method_exists($this, $loader)) {
1063
+					$dependency = $this->{$loader}($param_class);
1064
+				} else {
1065
+					$dependency = $this->create($param_class, array(), $cache_on);
1066
+				}
1067
+			}
1068
+		}
1069
+		// did we successfully find the correct dependency ?
1070
+		if ($dependency instanceof $param_class) {
1071
+			// then let's inject it into the incoming array of arguments at the correct location
1072
+			if (isset($argument_keys[$index])) {
1073
+				$arguments[$argument_keys[$index]] = $dependency;
1074
+			} else {
1075
+				$arguments[$index] = $dependency;
1076
+			}
1077
+		}
1078
+		return $arguments;
1079
+	}
1080
+
1081
+
1082
+
1083
+	/**
1084
+	 * _set_cached_class
1085
+	 * attempts to cache the instantiated class locally
1086
+	 * in one of the following places, in the following order:
1087
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1088
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1089
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1090
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1091
+	 *
1092
+	 * @access protected
1093
+	 * @param object $class_obj
1094
+	 * @param string $class_name
1095
+	 * @param string $class_prefix
1096
+	 * @param bool   $from_db
1097
+	 * @return void
1098
+	 */
1099
+	protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1100
+	{
1101
+		if (empty($class_obj)) {
1102
+			return;
1103
+		}
1104
+		// return newly instantiated class
1105
+		if (isset($this->_class_abbreviations[$class_name])) {
1106
+			$class_abbreviation = $this->_class_abbreviations[$class_name];
1107
+			$this->{$class_abbreviation} = $class_obj;
1108
+		} else if (property_exists($this, $class_name)) {
1109
+			$this->{$class_name} = $class_obj;
1110
+		} else if ($class_prefix == 'addon') {
1111
+			$this->addons->{$class_name} = $class_obj;
1112
+		} else if ( ! $from_db) {
1113
+			$this->LIB->{$class_name} = $class_obj;
1114
+		}
1115
+	}
1116
+
1117
+
1118
+
1119
+	/**
1120
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1121
+	 *
1122
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1123
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1124
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1125
+	 * @param array  $arguments
1126
+	 * @return object
1127
+	 */
1128
+	public static function factory($classname, $arguments = array())
1129
+	{
1130
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1131
+		if ($loader instanceof Closure) {
1132
+			return $loader($arguments);
1133
+		} else if (method_exists(EE_Registry::instance(), $loader)) {
1134
+			return EE_Registry::instance()->{$loader}($classname, $arguments);
1135
+		}
1136
+		return null;
1137
+	}
1138
+
1139
+
1140
+
1141
+	/**
1142
+	 * Gets the addon by its name/slug (not classname. For that, just
1143
+	 * use the classname as the property name on EE_Config::instance()->addons)
1144
+	 *
1145
+	 * @param string $name
1146
+	 * @return EE_Addon
1147
+	 */
1148
+	public function get_addon_by_name($name)
1149
+	{
1150
+		foreach ($this->addons as $addon) {
1151
+			if ($addon->name() == $name) {
1152
+				return $addon;
1153
+			}
1154
+		}
1155
+		return null;
1156
+	}
1157
+
1158
+
1159
+
1160
+	/**
1161
+	 * Gets an array of all the registered addons, where the keys are their names. (ie, what each returns for their name() function) They're already available on EE_Config::instance()->addons as properties, where each property's name is
1162
+	 * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1163
+	 *
1164
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1165
+	 */
1166
+	public function get_addons_by_name()
1167
+	{
1168
+		$addons = array();
1169
+		foreach ($this->addons as $addon) {
1170
+			$addons[$addon->name()] = $addon;
1171
+		}
1172
+		return $addons;
1173
+	}
1174
+
1175
+
1176
+
1177
+	/**
1178
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1179
+	 * a stale copy of it around
1180
+	 *
1181
+	 * @param string $model_name
1182
+	 * @return \EEM_Base
1183
+	 * @throws \EE_Error
1184
+	 */
1185
+	public function reset_model($model_name)
1186
+	{
1187
+		$model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1188
+		if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1189
+			return null;
1190
+		}
1191
+		//get that model reset it and make sure we nuke the old reference to it
1192
+		if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1193
+			$this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1194
+		} else {
1195
+			throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1196
+		}
1197
+		return $this->LIB->{$model_class_name};
1198
+	}
1199
+
1200
+
1201
+
1202
+	/**
1203
+	 * Resets the registry.
1204
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1205
+	 * is used in a multisite install.  Here is a list of things that are NOT reset.
1206
+	 * - $_dependency_map
1207
+	 * - $_class_abbreviations
1208
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1209
+	 * - $REQ:  Still on the same request so no need to change.
1210
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1211
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1212
+	 *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1213
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1214
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1215
+	 *             switch or on the restore.
1216
+	 * - $modules
1217
+	 * - $shortcodes
1218
+	 * - $widgets
1219
+	 *
1220
+	 * @param boolean $hard             whether to reset data in the database too, or just refresh
1221
+	 *                                  the Registry to its state at the beginning of the request
1222
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1223
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1224
+	 *                                  currently reinstantiate the singletons at the moment)
1225
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1226
+	 *                                  code instead can just change the model context to a different blog id if necessary
1227
+	 * @return EE_Registry
1228
+	 */
1229
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1230
+	{
1231
+		$instance = self::instance();
1232
+		EEH_Activation::reset();
1233
+		//properties that get reset
1234
+		$instance->_cache_on = true;
1235
+		$instance->CFG = EE_Config::reset($hard, $reinstantiate);
1236
+		$instance->CART = null;
1237
+		$instance->MRM = null;
1238
+		$instance->AssetsRegistry = new Registry();
1239
+		//messages reset
1240
+		EED_Messages::reset();
1241
+		if ($reset_models) {
1242
+			foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1243
+				$instance->reset_model($model_name);
1244
+			}
1245
+		}
1246
+		$instance->LIB = new stdClass();
1247
+		return $instance;
1248
+	}
1249
+
1250
+
1251
+
1252
+	/**
1253
+	 * @override magic methods
1254
+	 * @return void
1255
+	 */
1256
+	final function __destruct()
1257
+	{
1258
+	}
1259
+
1260
+
1261
+
1262
+	/**
1263
+	 * @param $a
1264
+	 * @param $b
1265
+	 */
1266
+	final function __call($a, $b)
1267
+	{
1268
+	}
1269
+
1270
+
1271
+
1272
+	/**
1273
+	 * @param $a
1274
+	 */
1275
+	final function __get($a)
1276
+	{
1277
+	}
1278
+
1279
+
1280
+
1281
+	/**
1282
+	 * @param $a
1283
+	 * @param $b
1284
+	 */
1285
+	final function __set($a, $b)
1286
+	{
1287
+	}
1288
+
1289
+
1290
+
1291
+	/**
1292
+	 * @param $a
1293
+	 */
1294
+	final function __isset($a)
1295
+	{
1296
+	}
1297 1297
 
1298 1298
 
1299 1299
 
1300
-    /**
1301
-     * @param $a
1302
-     */
1303
-    final function __unset($a)
1304
-    {
1305
-    }
1300
+	/**
1301
+	 * @param $a
1302
+	 */
1303
+	final function __unset($a)
1304
+	{
1305
+	}
1306 1306
 
1307 1307
 
1308 1308
 
1309
-    /**
1310
-     * @return array
1311
-     */
1312
-    final function __sleep()
1313
-    {
1314
-        return array();
1315
-    }
1309
+	/**
1310
+	 * @return array
1311
+	 */
1312
+	final function __sleep()
1313
+	{
1314
+		return array();
1315
+	}
1316 1316
 
1317 1317
 
1318 1318
 
1319
-    final function __wakeup()
1320
-    {
1321
-    }
1319
+	final function __wakeup()
1320
+	{
1321
+	}
1322 1322
 
1323 1323
 
1324 1324
 
1325
-    /**
1326
-     * @return string
1327
-     */
1328
-    final function __toString()
1329
-    {
1330
-        return '';
1331
-    }
1325
+	/**
1326
+	 * @return string
1327
+	 */
1328
+	final function __toString()
1329
+	{
1330
+		return '';
1331
+	}
1332 1332
 
1333 1333
 
1334 1334
 
1335
-    final function __invoke()
1336
-    {
1337
-    }
1335
+	final function __invoke()
1336
+	{
1337
+	}
1338 1338
 
1339 1339
 
1340 1340
 
1341
-    final static function __set_state()
1342
-    {
1343
-    }
1341
+	final static function __set_state()
1342
+	{
1343
+	}
1344 1344
 
1345 1345
 
1346 1346
 
1347
-    final function __clone()
1348
-    {
1349
-    }
1347
+	final function __clone()
1348
+	{
1349
+	}
1350 1350
 
1351 1351
 
1352 1352
 
1353
-    /**
1354
-     * @param $a
1355
-     * @param $b
1356
-     */
1357
-    final static function __callStatic($a, $b)
1358
-    {
1359
-    }
1353
+	/**
1354
+	 * @param $a
1355
+	 * @param $b
1356
+	 */
1357
+	final static function __callStatic($a, $b)
1358
+	{
1359
+	}
1360 1360
 
1361 1361
 
1362 1362
 
1363
-    /**
1364
-     * Gets all the custom post type models defined
1365
-     *
1366
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1367
-     */
1368
-    public function cpt_models()
1369
-    {
1370
-        $cpt_models = array();
1371
-        foreach ($this->non_abstract_db_models() as $short_name => $classname) {
1372
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1373
-                $cpt_models[$short_name] = $classname;
1374
-            }
1375
-        }
1376
-        return $cpt_models;
1377
-    }
1363
+	/**
1364
+	 * Gets all the custom post type models defined
1365
+	 *
1366
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1367
+	 */
1368
+	public function cpt_models()
1369
+	{
1370
+		$cpt_models = array();
1371
+		foreach ($this->non_abstract_db_models() as $short_name => $classname) {
1372
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1373
+				$cpt_models[$short_name] = $classname;
1374
+			}
1375
+		}
1376
+		return $cpt_models;
1377
+	}
1378 1378
 
1379 1379
 
1380 1380
 
1381
-    /**
1382
-     * Gets all the non-abstract database model names. If we haven't yet discovered what they are, does that
1383
-     * @return array keys are model names (eg "Event") and values are their classnames (eg "EEM_Event")
1384
-     */
1385
-    public function non_abstract_db_models()
1386
-    {
1387
-        $this->_verify_models_discovered();
1388
-        return $this->non_abstract_db_models;
1389
-    }
1381
+	/**
1382
+	 * Gets all the non-abstract database model names. If we haven't yet discovered what they are, does that
1383
+	 * @return array keys are model names (eg "Event") and values are their classnames (eg "EEM_Event")
1384
+	 */
1385
+	public function non_abstract_db_models()
1386
+	{
1387
+		$this->_verify_models_discovered();
1388
+		return $this->non_abstract_db_models;
1389
+	}
1390 1390
 
1391 1391
 
1392 1392
 
1393
-    /**
1394
-     * Gets the names of all the "models", including abstract and "non-database" models.
1395
-     * Mainly all the classes from core/db_models.
1396
-     * You may want to use EE_Registry::non_abstract_db_models instead
1397
-     * @return array keys are model names (eg "Event") and values are their classnames (eg "EEM_Event")
1398
-     */
1399
-    public function models()
1400
-    {
1401
-        $this->_verify_models_discovered();
1402
-        return $this->models;
1403
-    }
1393
+	/**
1394
+	 * Gets the names of all the "models", including abstract and "non-database" models.
1395
+	 * Mainly all the classes from core/db_models.
1396
+	 * You may want to use EE_Registry::non_abstract_db_models instead
1397
+	 * @return array keys are model names (eg "Event") and values are their classnames (eg "EEM_Event")
1398
+	 */
1399
+	public function models()
1400
+	{
1401
+		$this->_verify_models_discovered();
1402
+		return $this->models;
1403
+	}
1404 1404
 
1405 1405
 
1406 1406
 
1407
-    /**
1408
-     * Discovers all the models in core/db_models and remembers them on properties
1409
-     * models and non_abstract_db_models
1410
-     * @return void
1411
-     */
1412
-    private function _verify_models_discovered()
1413
-    {
1414
-        if( ! $this->non_abstract_db_models
1415
-            || ! $this->models){
1416
-            //get all the files in the EE_MODELS folder that end in .model.php
1417
-            $models = glob(EE_MODELS . '*.model.php');
1418
-            $model_names = array();
1419
-            $non_abstract_db_models = array();
1420
-            foreach ($models as $model) {
1421
-                // get model classname
1422
-                $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
1423
-                $short_name = str_replace('EEM_', '', $classname);
1424
-                $reflectionClass = new ReflectionClass($classname);
1425
-                if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
1426
-                    $non_abstract_db_models[$short_name] = $classname;
1427
-                }
1428
-                $model_names[$short_name] = $classname;
1429
-            }
1430
-            //continue using legacy filter names (originally this logic was contained elsewhere)
1431
-            $this->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
1432
-            $this->non_abstract_db_models = apply_filters('FHEE__EE_System__parse_implemented_model_names',
1433
-                $non_abstract_db_models);
1434
-        }
1435
-    }
1436
-
1437
-
1438
-
1439
-    /**
1440
-     * @return \EE_Config
1441
-     */
1442
-    public static function CFG()
1443
-    {
1444
-        return self::instance()->CFG;
1445
-    }
1407
+	/**
1408
+	 * Discovers all the models in core/db_models and remembers them on properties
1409
+	 * models and non_abstract_db_models
1410
+	 * @return void
1411
+	 */
1412
+	private function _verify_models_discovered()
1413
+	{
1414
+		if( ! $this->non_abstract_db_models
1415
+			|| ! $this->models){
1416
+			//get all the files in the EE_MODELS folder that end in .model.php
1417
+			$models = glob(EE_MODELS . '*.model.php');
1418
+			$model_names = array();
1419
+			$non_abstract_db_models = array();
1420
+			foreach ($models as $model) {
1421
+				// get model classname
1422
+				$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
1423
+				$short_name = str_replace('EEM_', '', $classname);
1424
+				$reflectionClass = new ReflectionClass($classname);
1425
+				if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
1426
+					$non_abstract_db_models[$short_name] = $classname;
1427
+				}
1428
+				$model_names[$short_name] = $classname;
1429
+			}
1430
+			//continue using legacy filter names (originally this logic was contained elsewhere)
1431
+			$this->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
1432
+			$this->non_abstract_db_models = apply_filters('FHEE__EE_System__parse_implemented_model_names',
1433
+				$non_abstract_db_models);
1434
+		}
1435
+	}
1436
+
1437
+
1438
+
1439
+	/**
1440
+	 * @return \EE_Config
1441
+	 */
1442
+	public static function CFG()
1443
+	{
1444
+		return self::instance()->CFG;
1445
+	}
1446 1446
 
1447 1447
 
1448 1448
 }
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -296,13 +296,13 @@  discard block
 block discarded – undo
296 296
      */
297 297
     public static function localize_i18n_js_strings()
298 298
     {
299
-        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
299
+        $i18n_js_strings = (array) EE_Registry::$i18n_js_strings;
300 300
         foreach ($i18n_js_strings as $key => $value) {
301 301
             if (is_scalar($value)) {
302
-                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
302
+                $i18n_js_strings[$key] = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
303 303
             }
304 304
         }
305
-        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
305
+        return "/* <![CDATA[ */ var eei18n = ".wp_json_encode($i18n_js_strings).'; /* ]]> */';
306 306
     }
307 307
 
308 308
 
@@ -353,9 +353,9 @@  discard block
 block discarded – undo
353 353
                 EE_CORE,
354 354
                 EE_ADMIN,
355 355
                 EE_CPTS,
356
-                EE_CORE . 'data_migration_scripts' . DS,
357
-                EE_CORE . 'request_stack' . DS,
358
-                EE_CORE . 'middleware' . DS,
356
+                EE_CORE.'data_migration_scripts'.DS,
357
+                EE_CORE.'request_stack'.DS,
358
+                EE_CORE.'middleware'.DS,
359 359
             )
360 360
         );
361 361
         // retrieve instantiated class
@@ -378,7 +378,7 @@  discard block
 block discarded – undo
378 378
         $service_paths = apply_filters(
379 379
             'FHEE__EE_Registry__load_service__service_paths',
380 380
             array(
381
-                EE_CORE . 'services' . DS,
381
+                EE_CORE.'services'.DS,
382 382
             )
383 383
         );
384 384
         // retrieve instantiated class
@@ -458,10 +458,10 @@  discard block
 block discarded – undo
458 458
     {
459 459
         $paths = array(
460 460
             EE_LIBRARIES,
461
-            EE_LIBRARIES . 'messages' . DS,
462
-            EE_LIBRARIES . 'shortcodes' . DS,
463
-            EE_LIBRARIES . 'qtips' . DS,
464
-            EE_LIBRARIES . 'payment_methods' . DS,
461
+            EE_LIBRARIES.'messages'.DS,
462
+            EE_LIBRARIES.'shortcodes'.DS,
463
+            EE_LIBRARIES.'qtips'.DS,
464
+            EE_LIBRARIES.'payment_methods'.DS,
465 465
         );
466 466
         // retrieve instantiated class
467 467
         return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
@@ -500,10 +500,10 @@  discard block
 block discarded – undo
500 500
     public function load_model_class($class_name, $arguments = array(), $load_only = true)
501 501
     {
502 502
         $paths = array(
503
-            EE_MODELS . 'fields' . DS,
504
-            EE_MODELS . 'helpers' . DS,
505
-            EE_MODELS . 'relations' . DS,
506
-            EE_MODELS . 'strategies' . DS,
503
+            EE_MODELS.'fields'.DS,
504
+            EE_MODELS.'helpers'.DS,
505
+            EE_MODELS.'relations'.DS,
506
+            EE_MODELS.'strategies'.DS,
507 507
         );
508 508
         // retrieve instantiated class
509 509
         return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
@@ -591,7 +591,7 @@  discard block
 block discarded – undo
591 591
         $class_name = $this->_dependency_map->get_alias($class_name);
592 592
         if ( ! class_exists($class_name)) {
593 593
             // maybe the class is registered with a preceding \
594
-            $class_name = strpos($class_name, '\\') !== 0 ? '\\' . $class_name : $class_name;
594
+            $class_name = strpos($class_name, '\\') !== 0 ? '\\'.$class_name : $class_name;
595 595
             // still doesn't exist ?
596 596
             if ( ! class_exists($class_name)) {
597 597
                 return null;
@@ -658,7 +658,7 @@  discard block
 block discarded – undo
658 658
             // make sure $class_prefix is uppercase
659 659
             $class_prefix = strtoupper(trim($class_prefix));
660 660
             // add class prefix ONCE!!!
661
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
661
+            $class_name = $class_prefix.str_replace($class_prefix, '', $class_name);
662 662
         }
663 663
         $class_name = $this->_dependency_map->get_alias($class_name);
664 664
         $class_exists = class_exists($class_name);
@@ -758,9 +758,9 @@  discard block
 block discarded – undo
758 758
             // convert all separators to proper DS, if no filepath, then use EE_CLASSES
759 759
             $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
760 760
             // prep file type
761
-            $type = ! empty($type) ? trim($type, '.') . '.' : '';
761
+            $type = ! empty($type) ? trim($type, '.').'.' : '';
762 762
             // build full file path
763
-            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
763
+            $file_paths[$key] = rtrim($file_path, DS).DS.$class_name.'.'.$type.'php';
764 764
             //does the file exist and can be read ?
765 765
             if (is_readable($file_paths[$key])) {
766 766
                 return $file_paths[$key];
@@ -791,12 +791,12 @@  discard block
 block discarded – undo
791 791
             //does the file exist and can it be read ?
792 792
             if ( ! $path) {
793 793
                 // so sorry, can't find the file
794
-                throw new EE_Error (
794
+                throw new EE_Error(
795 795
                     sprintf(
796 796
                         __('The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s', 'event_espresso'),
797 797
                         trim($type, '.'),
798 798
                         $class_name,
799
-                        '<br />' . implode(',<br />', $file_paths)
799
+                        '<br />'.implode(',<br />', $file_paths)
800 800
                     )
801 801
                 );
802 802
             }
@@ -1411,10 +1411,10 @@  discard block
 block discarded – undo
1411 1411
      */
1412 1412
     private function _verify_models_discovered()
1413 1413
     {
1414
-        if( ! $this->non_abstract_db_models
1415
-            || ! $this->models){
1414
+        if ( ! $this->non_abstract_db_models
1415
+            || ! $this->models) {
1416 1416
             //get all the files in the EE_MODELS folder that end in .model.php
1417
-            $models = glob(EE_MODELS . '*.model.php');
1417
+            $models = glob(EE_MODELS.'*.model.php');
1418 1418
             $model_names = array();
1419 1419
             $non_abstract_db_models = array();
1420 1420
             foreach ($models as $model) {
Please login to merge, or discard this patch.
core/helpers/EEH_Activation.helper.php 1 patch
Indentation   +1652 added lines, -1652 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -14,243 +14,243 @@  discard block
 block discarded – undo
14 14
 class EEH_Activation
15 15
 {
16 16
 
17
-    /**
18
-     * constant used to indicate a cron task is no longer in use
19
-     */
20
-    const cron_task_no_longer_in_use = 'no_longer_in_use';
21
-
22
-    /**
23
-     * option name that will indicate whether or not we still
24
-     * need to create EE's folders in the uploads directory
25
-     * (because if EE was installed without file system access,
26
-     * we need to request credentials before we can create them)
27
-     */
28
-    const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
29
-
30
-    /**
31
-     * WP_User->ID
32
-     *
33
-     * @var int
34
-     */
35
-    private static $_default_creator_id;
36
-
37
-    /**
38
-     * indicates whether or not we've already verified core's default data during this request,
39
-     * because after migrations are done, any addons activated while in maintenance mode
40
-     * will want to setup their own default data, and they might hook into core's default data
41
-     * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
42
-     * This prevents doing that for EVERY single addon.
43
-     *
44
-     * @var boolean
45
-     */
46
-    protected static $_initialized_db_content_already_in_this_request = false;
47
-
48
-    /**
49
-     * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
50
-     */
51
-    private static $table_analysis;
52
-
53
-    /**
54
-     * @var \EventEspresso\core\services\database\TableManager $table_manager
55
-     */
56
-    private static $table_manager;
57
-
58
-
59
-    /**
60
-     * @return \EventEspresso\core\services\database\TableAnalysis
61
-     */
62
-    public static function getTableAnalysis()
63
-    {
64
-        if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
65
-            self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
66
-        }
67
-        return self::$table_analysis;
68
-    }
69
-
70
-
71
-    /**
72
-     * @return \EventEspresso\core\services\database\TableManager
73
-     */
74
-    public static function getTableManager()
75
-    {
76
-        if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
77
-            self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
78
-        }
79
-        return self::$table_manager;
80
-    }
81
-
82
-
83
-    /**
84
-     *    _ensure_table_name_has_prefix
85
-     *
86
-     * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
-     * @access     public
88
-     * @static
89
-     * @param $table_name
90
-     * @return string
91
-     */
92
-    public static function ensure_table_name_has_prefix($table_name)
93
-    {
94
-        return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
95
-    }
96
-
97
-
98
-    /**
99
-     *    system_initialization
100
-     *    ensures the EE configuration settings are loaded with at least default options set
101
-     *    and that all critical EE pages have been generated with the appropriate shortcodes in place
102
-     *
103
-     * @access public
104
-     * @static
105
-     * @return void
106
-     */
107
-    public static function system_initialization()
108
-    {
109
-        EEH_Activation::reset_and_update_config();
110
-        //which is fired BEFORE activation of plugin anyways
111
-        EEH_Activation::verify_default_pages_exist();
112
-    }
113
-
114
-
115
-    /**
116
-     * Sets the database schema and creates folders. This should
117
-     * be called on plugin activation and reactivation
118
-     *
119
-     * @return boolean success, whether the database and folders are setup properly
120
-     * @throws \EE_Error
121
-     */
122
-    public static function initialize_db_and_folders()
123
-    {
124
-        $good_filesystem = EEH_Activation::create_upload_directories();
125
-        $good_db         = EEH_Activation::create_database_tables();
126
-        return $good_filesystem && $good_db;
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
-     */
138
-    public static function initialize_db_content()
139
-    {
140
-        //let's avoid doing all this logic repeatedly, especially when addons are requesting it
141
-        if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
142
-            return;
143
-        }
144
-        EEH_Activation::$_initialized_db_content_already_in_this_request = true;
145
-
146
-        EEH_Activation::initialize_system_questions();
147
-        EEH_Activation::insert_default_status_codes();
148
-        EEH_Activation::generate_default_message_templates();
149
-        EEH_Activation::create_no_ticket_prices_array();
150
-        EEH_Activation::validate_messages_system();
151
-        EEH_Activation::insert_default_payment_methods();
152
-        //in case we've
153
-        EEH_Activation::remove_cron_tasks();
154
-        EEH_Activation::create_cron_tasks();
155
-        // remove all TXN locks since that is being done via extra meta now
156
-        delete_option('ee_locked_transactions');
157
-        //also, check for CAF default db content
158
-        do_action('AHEE__EEH_Activation__initialize_db_content');
159
-        //also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
160
-        //which users really won't care about on initial activation
161
-        EE_Error::overwrite_success();
162
-    }
163
-
164
-
165
-    /**
166
-     * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
167
-     * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
168
-     * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
169
-     * (null)
170
-     *
171
-     * @param string $which_to_include can be 'current' (ones that are currently in use),
172
-     *                                 'old' (only returns ones that should no longer be used),or 'all',
173
-     * @return array
174
-     * @throws \EE_Error
175
-     */
176
-    public static function get_cron_tasks($which_to_include)
177
-    {
178
-        $cron_tasks = apply_filters(
179
-            'FHEE__EEH_Activation__get_cron_tasks',
180
-            array(
181
-                'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
17
+	/**
18
+	 * constant used to indicate a cron task is no longer in use
19
+	 */
20
+	const cron_task_no_longer_in_use = 'no_longer_in_use';
21
+
22
+	/**
23
+	 * option name that will indicate whether or not we still
24
+	 * need to create EE's folders in the uploads directory
25
+	 * (because if EE was installed without file system access,
26
+	 * we need to request credentials before we can create them)
27
+	 */
28
+	const upload_directories_incomplete_option_name = 'ee_upload_directories_incomplete';
29
+
30
+	/**
31
+	 * WP_User->ID
32
+	 *
33
+	 * @var int
34
+	 */
35
+	private static $_default_creator_id;
36
+
37
+	/**
38
+	 * indicates whether or not we've already verified core's default data during this request,
39
+	 * because after migrations are done, any addons activated while in maintenance mode
40
+	 * will want to setup their own default data, and they might hook into core's default data
41
+	 * and trigger core to setup its default data. In which case they might all ask for core to init its default data.
42
+	 * This prevents doing that for EVERY single addon.
43
+	 *
44
+	 * @var boolean
45
+	 */
46
+	protected static $_initialized_db_content_already_in_this_request = false;
47
+
48
+	/**
49
+	 * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
50
+	 */
51
+	private static $table_analysis;
52
+
53
+	/**
54
+	 * @var \EventEspresso\core\services\database\TableManager $table_manager
55
+	 */
56
+	private static $table_manager;
57
+
58
+
59
+	/**
60
+	 * @return \EventEspresso\core\services\database\TableAnalysis
61
+	 */
62
+	public static function getTableAnalysis()
63
+	{
64
+		if (! self::$table_analysis instanceof \EventEspresso\core\services\database\TableAnalysis) {
65
+			self::$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
66
+		}
67
+		return self::$table_analysis;
68
+	}
69
+
70
+
71
+	/**
72
+	 * @return \EventEspresso\core\services\database\TableManager
73
+	 */
74
+	public static function getTableManager()
75
+	{
76
+		if (! self::$table_manager instanceof \EventEspresso\core\services\database\TableManager) {
77
+			self::$table_manager = EE_Registry::instance()->create('TableManager', array(), true);
78
+		}
79
+		return self::$table_manager;
80
+	}
81
+
82
+
83
+	/**
84
+	 *    _ensure_table_name_has_prefix
85
+	 *
86
+	 * @deprecated instead use TableAnalysis::ensureTableNameHasPrefix()
87
+	 * @access     public
88
+	 * @static
89
+	 * @param $table_name
90
+	 * @return string
91
+	 */
92
+	public static function ensure_table_name_has_prefix($table_name)
93
+	{
94
+		return \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix($table_name);
95
+	}
96
+
97
+
98
+	/**
99
+	 *    system_initialization
100
+	 *    ensures the EE configuration settings are loaded with at least default options set
101
+	 *    and that all critical EE pages have been generated with the appropriate shortcodes in place
102
+	 *
103
+	 * @access public
104
+	 * @static
105
+	 * @return void
106
+	 */
107
+	public static function system_initialization()
108
+	{
109
+		EEH_Activation::reset_and_update_config();
110
+		//which is fired BEFORE activation of plugin anyways
111
+		EEH_Activation::verify_default_pages_exist();
112
+	}
113
+
114
+
115
+	/**
116
+	 * Sets the database schema and creates folders. This should
117
+	 * be called on plugin activation and reactivation
118
+	 *
119
+	 * @return boolean success, whether the database and folders are setup properly
120
+	 * @throws \EE_Error
121
+	 */
122
+	public static function initialize_db_and_folders()
123
+	{
124
+		$good_filesystem = EEH_Activation::create_upload_directories();
125
+		$good_db         = EEH_Activation::create_database_tables();
126
+		return $good_filesystem && $good_db;
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
+	 */
138
+	public static function initialize_db_content()
139
+	{
140
+		//let's avoid doing all this logic repeatedly, especially when addons are requesting it
141
+		if (EEH_Activation::$_initialized_db_content_already_in_this_request) {
142
+			return;
143
+		}
144
+		EEH_Activation::$_initialized_db_content_already_in_this_request = true;
145
+
146
+		EEH_Activation::initialize_system_questions();
147
+		EEH_Activation::insert_default_status_codes();
148
+		EEH_Activation::generate_default_message_templates();
149
+		EEH_Activation::create_no_ticket_prices_array();
150
+		EEH_Activation::validate_messages_system();
151
+		EEH_Activation::insert_default_payment_methods();
152
+		//in case we've
153
+		EEH_Activation::remove_cron_tasks();
154
+		EEH_Activation::create_cron_tasks();
155
+		// remove all TXN locks since that is being done via extra meta now
156
+		delete_option('ee_locked_transactions');
157
+		//also, check for CAF default db content
158
+		do_action('AHEE__EEH_Activation__initialize_db_content');
159
+		//also: EEM_Gateways::load_all_gateways() outputs a lot of success messages
160
+		//which users really won't care about on initial activation
161
+		EE_Error::overwrite_success();
162
+	}
163
+
164
+
165
+	/**
166
+	 * Returns an array of cron tasks. Array values are the actions fired by the cron tasks (the "hooks"),
167
+	 * values are the frequency (the "recurrence"). See http://codex.wordpress.org/Function_Reference/wp_schedule_event
168
+	 * If the cron task should NO longer be used, it should have a value of EEH_Activation::cron_task_no_longer_in_use
169
+	 * (null)
170
+	 *
171
+	 * @param string $which_to_include can be 'current' (ones that are currently in use),
172
+	 *                                 'old' (only returns ones that should no longer be used),or 'all',
173
+	 * @return array
174
+	 * @throws \EE_Error
175
+	 */
176
+	public static function get_cron_tasks($which_to_include)
177
+	{
178
+		$cron_tasks = apply_filters(
179
+			'FHEE__EEH_Activation__get_cron_tasks',
180
+			array(
181
+				'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'      => 'hourly',
182 182
 //				'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions' => EEH_Activation::cron_task_no_longer_in_use, actually this is still in use
183
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
184
-                //there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
185
-                'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
186
-            )
187
-        );
188
-        if ($which_to_include === 'old') {
189
-            $cron_tasks = array_filter(
190
-                $cron_tasks,
191
-                function ($value) {
192
-                    return $value === EEH_Activation::cron_task_no_longer_in_use;
193
-                }
194
-            );
195
-        } elseif ($which_to_include === 'current') {
196
-            $cron_tasks = array_filter($cron_tasks);
197
-        } elseif (WP_DEBUG && $which_to_include !== 'all') {
198
-            throw new EE_Error(
199
-                sprintf(
200
-                    __(
201
-                        'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
202
-                        'event_espresso'
203
-                    ),
204
-                    $which_to_include
205
-                )
206
-            );
207
-        }
208
-        return $cron_tasks;
209
-    }
210
-
211
-
212
-    /**
213
-     * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
214
-     *
215
-     * @throws \EE_Error
216
-     */
217
-    public static function create_cron_tasks()
218
-    {
219
-
220
-        foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
221
-            if (! wp_next_scheduled($hook_name)) {
222
-                /**
223
-                 * This allows client code to define the initial start timestamp for this schedule.
224
-                 */
225
-                if (is_array($frequency)
226
-                    && count($frequency) === 2
227
-                    && isset($frequency[0], $frequency[1])
228
-                ) {
229
-                    $start_timestamp = $frequency[0];
230
-                    $frequency = $frequency[1];
231
-                } else {
232
-                    $start_timestamp = time();
233
-                }
234
-                wp_schedule_event($start_timestamp, $frequency, $hook_name);
235
-            }
236
-        }
237
-
238
-    }
239
-
240
-
241
-
242
-    /**
243
-     * Remove the currently-existing and now-removed cron tasks.
244
-     *
245
-     * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
246
-     * @throws \EE_Error
247
-     */
248
-    public static function remove_cron_tasks($remove_all = true)
249
-    {
250
-        $cron_tasks_to_remove = $remove_all ? 'all' : 'old';
251
-        $crons                = _get_cron_array();
252
-        $crons                = is_array($crons) ? $crons : array();
253
-        /* reminder of what $crons look like:
183
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment' => EEH_Activation::cron_task_no_longer_in_use,
184
+				//there may have been a bug which prevented from these cron tasks from getting unscheduled, so we might want to remove these for a few updates
185
+				'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs'       => 'daily',
186
+			)
187
+		);
188
+		if ($which_to_include === 'old') {
189
+			$cron_tasks = array_filter(
190
+				$cron_tasks,
191
+				function ($value) {
192
+					return $value === EEH_Activation::cron_task_no_longer_in_use;
193
+				}
194
+			);
195
+		} elseif ($which_to_include === 'current') {
196
+			$cron_tasks = array_filter($cron_tasks);
197
+		} elseif (WP_DEBUG && $which_to_include !== 'all') {
198
+			throw new EE_Error(
199
+				sprintf(
200
+					__(
201
+						'Invalid argument of "%1$s" passed to EEH_Activation::get_cron_tasks. Valid values are "all", "old" and "current".',
202
+						'event_espresso'
203
+					),
204
+					$which_to_include
205
+				)
206
+			);
207
+		}
208
+		return $cron_tasks;
209
+	}
210
+
211
+
212
+	/**
213
+	 * Ensure cron tasks are setup (the removal of crons should be done by remove_crons())
214
+	 *
215
+	 * @throws \EE_Error
216
+	 */
217
+	public static function create_cron_tasks()
218
+	{
219
+
220
+		foreach (EEH_Activation::get_cron_tasks('current') as $hook_name => $frequency) {
221
+			if (! wp_next_scheduled($hook_name)) {
222
+				/**
223
+				 * This allows client code to define the initial start timestamp for this schedule.
224
+				 */
225
+				if (is_array($frequency)
226
+					&& count($frequency) === 2
227
+					&& isset($frequency[0], $frequency[1])
228
+				) {
229
+					$start_timestamp = $frequency[0];
230
+					$frequency = $frequency[1];
231
+				} else {
232
+					$start_timestamp = time();
233
+				}
234
+				wp_schedule_event($start_timestamp, $frequency, $hook_name);
235
+			}
236
+		}
237
+
238
+	}
239
+
240
+
241
+
242
+	/**
243
+	 * Remove the currently-existing and now-removed cron tasks.
244
+	 *
245
+	 * @param boolean $remove_all whether to only remove the old ones, or remove absolutely ALL the EE ones
246
+	 * @throws \EE_Error
247
+	 */
248
+	public static function remove_cron_tasks($remove_all = true)
249
+	{
250
+		$cron_tasks_to_remove = $remove_all ? 'all' : 'old';
251
+		$crons                = _get_cron_array();
252
+		$crons                = is_array($crons) ? $crons : array();
253
+		/* reminder of what $crons look like:
254 254
          * Top-level keys are timestamps, and their values are arrays.
255 255
          * The 2nd level arrays have keys with each of the cron task hook names to run at that time
256 256
          * and their values are arrays.
@@ -267,912 +267,912 @@  discard block
 block discarded – undo
267 267
          *					...
268 268
          *      ...
269 269
          */
270
-        $ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
271
-        foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
272
-            if (is_array($hooks_to_fire_at_time)) {
273
-                foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
274
-                    if (isset($ee_cron_tasks_to_remove[$hook_name])
275
-                        && is_array($ee_cron_tasks_to_remove[$hook_name])
276
-                    ) {
277
-                        unset($crons[$timestamp][$hook_name]);
278
-                    }
279
-                }
280
-                //also take care of any empty cron timestamps.
281
-                if (empty($hooks_to_fire_at_time)) {
282
-                    unset($crons[$timestamp]);
283
-                }
284
-            }
285
-        }
286
-        _set_cron_array($crons);
287
-    }
288
-
289
-
290
-    /**
291
-     *    CPT_initialization
292
-     *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
293
-     *
294
-     * @access public
295
-     * @static
296
-     * @return void
297
-     */
298
-    public static function CPT_initialization()
299
-    {
300
-        // register Custom Post Types
301
-        EE_Registry::instance()->load_core('Register_CPTs');
302
-        flush_rewrite_rules();
303
-    }
304
-
305
-
306
-
307
-    /**
308
-     *    reset_and_update_config
309
-     * The following code was moved over from EE_Config so that it will no longer run on every request.
310
-     * If there is old calendar config data saved, then it will get converted on activation.
311
-     * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
312
-     *
313
-     * @access public
314
-     * @static
315
-     * @return void
316
-     */
317
-    public static function reset_and_update_config()
318
-    {
319
-        do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
320
-        add_filter(
321
-            'FHEE__EE_Config___load_core_config__config_settings',
322
-            array('EEH_Activation', 'migrate_old_config_data'),
323
-            10,
324
-            3
325
-        );
326
-        //EE_Config::reset();
327
-        if (! EE_Config::logging_enabled()) {
328
-            delete_option(EE_Config::LOG_NAME);
329
-        }
330
-    }
331
-
332
-
333
-    /**
334
-     *    load_calendar_config
335
-     *
336
-     * @access    public
337
-     * @return    void
338
-     */
339
-    public static function load_calendar_config()
340
-    {
341
-        // grab array of all plugin folders and loop thru it
342
-        $plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
343
-        if (empty($plugins)) {
344
-            return;
345
-        }
346
-        foreach ($plugins as $plugin_path) {
347
-            // grab plugin folder name from path
348
-            $plugin = basename($plugin_path);
349
-            // drill down to Espresso plugins
350
-            // then to calendar related plugins
351
-            if (
352
-                strpos($plugin, 'espresso') !== false
353
-                || strpos($plugin, 'Espresso') !== false
354
-                || strpos($plugin, 'ee4') !== false
355
-                || strpos($plugin, 'EE4') !== false
356
-                || strpos($plugin, 'calendar') !== false
357
-            ) {
358
-                // this is what we are looking for
359
-                $calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
360
-                // does it exist in this folder ?
361
-                if (is_readable($calendar_config)) {
362
-                    // YEAH! let's load it
363
-                    require_once($calendar_config);
364
-                }
365
-            }
366
-        }
367
-    }
368
-
369
-
370
-
371
-    /**
372
-     *    _migrate_old_config_data
373
-     *
374
-     * @access    public
375
-     * @param array|stdClass $settings
376
-     * @param string         $config
377
-     * @param \EE_Config     $EE_Config
378
-     * @return \stdClass
379
-     */
380
-    public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
381
-    {
382
-        $convert_from_array = array('addons');
383
-        // in case old settings were saved as an array
384
-        if (is_array($settings) && in_array($config, $convert_from_array)) {
385
-            // convert existing settings to an object
386
-            $config_array = $settings;
387
-            $settings = new stdClass();
388
-            foreach ($config_array as $key => $value) {
389
-                if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
390
-                    $EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
391
-                } else {
392
-                    $settings->{$key} = $value;
393
-                }
394
-            }
395
-            add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
396
-        }
397
-        return $settings;
398
-    }
399
-
400
-
401
-    /**
402
-     * deactivate_event_espresso
403
-     *
404
-     * @access public
405
-     * @static
406
-     * @return void
407
-     */
408
-    public static function deactivate_event_espresso()
409
-    {
410
-        // check permissions
411
-        if (current_user_can('activate_plugins')) {
412
-            deactivate_plugins(EE_PLUGIN_BASENAME, true);
413
-        }
414
-    }
415
-
416
-
417
-
418
-
419
-    /**
420
-     * verify_default_pages_exist
421
-     *
422
-     * @access public
423
-     * @static
424
-     * @return void
425
-     */
426
-    public static function verify_default_pages_exist()
427
-    {
428
-        $critical_page_problem = false;
429
-        $critical_pages = array(
430
-            array(
431
-                'id'   => 'reg_page_id',
432
-                'name' => __('Registration Checkout', 'event_espresso'),
433
-                'post' => null,
434
-                'code' => 'ESPRESSO_CHECKOUT',
435
-            ),
436
-            array(
437
-                'id'   => 'txn_page_id',
438
-                'name' => __('Transactions', 'event_espresso'),
439
-                'post' => null,
440
-                'code' => 'ESPRESSO_TXN_PAGE',
441
-            ),
442
-            array(
443
-                'id'   => 'thank_you_page_id',
444
-                'name' => __('Thank You', 'event_espresso'),
445
-                'post' => null,
446
-                'code' => 'ESPRESSO_THANK_YOU',
447
-            ),
448
-            array(
449
-                'id'   => 'cancel_page_id',
450
-                'name' => __('Registration Cancelled', 'event_espresso'),
451
-                'post' => null,
452
-                'code' => 'ESPRESSO_CANCELLED',
453
-            ),
454
-        );
455
-        $EE_Core_Config = EE_Registry::instance()->CFG->core;
456
-        foreach ($critical_pages as $critical_page) {
457
-            // is critical page ID set in config ?
458
-            if ($EE_Core_Config->{$critical_page['id']} !== false) {
459
-                // attempt to find post by ID
460
-                $critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
461
-            }
462
-            // no dice?
463
-            if ($critical_page['post'] === null) {
464
-                // attempt to find post by title
465
-                $critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
466
-                // still nothing?
467
-                if ($critical_page['post'] === null) {
468
-                    $critical_page = EEH_Activation::create_critical_page($critical_page);
469
-                    // REALLY? Still nothing ??!?!?
470
-                    if ($critical_page['post'] === null) {
471
-                        $msg = __(
472
-                            'The Event Espresso critical page configuration settings could not be updated.',
473
-                            'event_espresso'
474
-                        );
475
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
476
-                        break;
477
-                    }
478
-                }
479
-            }
480
-            // check that Post ID matches critical page ID in config
481
-            if (
482
-                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
-            $msg = sprintf(
504
-                __(
505
-                    'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
506
-                    'event_espresso'
507
-                ),
508
-                '<a href="'
509
-                . admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
510
-                . '">'
511
-                . __('Event Espresso Critical Pages Settings', 'event_espresso')
512
-                . '</a>'
513
-            );
514
-            EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
515
-        }
516
-        if (EE_Error::has_notices()) {
517
-            EE_Error::get_notices(false, true, true);
518
-        }
519
-    }
520
-
521
-
522
-
523
-    /**
524
-     * Returns the first post which uses the specified shortcode
525
-     *
526
-     * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
527
-     *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
528
-     *                             "[ESPRESSO_THANK_YOU"
529
-     *                             (we don't search for the closing shortcode bracket because they might have added
530
-     *                             parameter to the shortcode
531
-     * @return WP_Post or NULl
532
-     */
533
-    public static function get_page_by_ee_shortcode($ee_shortcode)
534
-    {
535
-        global $wpdb;
536
-        $shortcode_and_opening_bracket = '[' . $ee_shortcode;
537
-        $post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
538
-        if ($post_id) {
539
-            return get_post($post_id);
540
-        } else {
541
-            return null;
542
-        }
543
-    }
544
-
545
-
546
-
547
-    /**
548
-     *    This function generates a post for critical espresso pages
549
-     *
550
-     * @access public
551
-     * @static
552
-     * @param array $critical_page
553
-     * @return array
554
-     */
555
-    public static function create_critical_page($critical_page)
556
-    {
557
-
558
-        $post_args = array(
559
-            'post_title'     => $critical_page['name'],
560
-            'post_status'    => 'publish',
561
-            'post_type'      => 'page',
562
-            'comment_status' => 'closed',
563
-            'post_content'   => '[' . $critical_page['code'] . ']',
564
-        );
565
-
566
-        $post_id = wp_insert_post($post_args);
567
-        if (! $post_id) {
568
-            $msg = sprintf(
569
-                __('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
570
-                $critical_page['name']
571
-            );
572
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
573
-            return $critical_page;
574
-        }
575
-        // get newly created post's details
576
-        if (! $critical_page['post'] = get_post($post_id)) {
577
-            $msg = sprintf(
578
-                __('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
579
-                $critical_page['name']
580
-            );
581
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
582
-        }
583
-
584
-        return $critical_page;
585
-
586
-    }
587
-
588
-
589
-
590
-
591
-    /**
592
-     * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
593
-     * The role being used to check is filterable.
594
-     *
595
-     * @since  4.6.0
596
-     * @global WPDB $wpdb
597
-     * @return mixed null|int WP_user ID or NULL
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
-    /**
633
-     * used by EE and EE addons during plugin activation to create tables.
634
-     * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
635
-     * but includes extra logic regarding activations.
636
-     *
637
-     * @access public
638
-     * @static
639
-     * @param string  $table_name              without the $wpdb->prefix
640
-     * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
641
-     *                                         table query)
642
-     * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
643
-     * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
644
-     *                                         and new once this function is done (ie, you really do want to CREATE a
645
-     *                                         table, and expect it to be empty once you're done) leave as FALSE when
646
-     *                                         you just want to verify the table exists and matches this definition
647
-     *                                         (and if it HAS data in it you want to leave it be)
648
-     * @return void
649
-     * @throws EE_Error if there are database errors
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
-            } else if ( ! $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
-    /**
691
-     *    add_column_if_it_doesn't_exist
692
-     *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
693
-     *
694
-     * @access     public
695
-     * @static
696
-     * @deprecated instead use TableManager::addColumn()
697
-     * @param string $table_name  (without "wp_", eg "esp_attendee"
698
-     * @param string $column_name
699
-     * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
700
-     *                            'VARCHAR(10)'
701
-     * @return bool|int
702
-     */
703
-    public static function add_column_if_it_doesnt_exist(
704
-        $table_name,
705
-        $column_name,
706
-        $column_info = 'INT UNSIGNED NOT NULL'
707
-    ) {
708
-        return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
709
-    }
710
-
711
-
712
-    /**
713
-     * get_fields_on_table
714
-     * Gets all the fields on the database table.
715
-     *
716
-     * @access     public
717
-     * @deprecated instead use TableManager::getTableColumns()
718
-     * @static
719
-     * @param string $table_name , without prefixed $wpdb->prefix
720
-     * @return array of database column names
721
-     */
722
-    public static function get_fields_on_table($table_name = null)
723
-    {
724
-        return \EEH_Activation::getTableManager()->getTableColumns($table_name);
725
-    }
726
-
727
-
728
-    /**
729
-     * db_table_is_empty
730
-     *
731
-     * @access     public\
732
-     * @deprecated instead use TableAnalysis::tableIsEmpty()
733
-     * @static
734
-     * @param string $table_name
735
-     * @return bool
736
-     */
737
-    public static function db_table_is_empty($table_name)
738
-    {
739
-        return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
740
-    }
741
-
742
-
743
-    /**
744
-     * delete_db_table_if_empty
745
-     *
746
-     * @access public
747
-     * @static
748
-     * @param string $table_name
749
-     * @return bool | int
750
-     */
751
-    public static function delete_db_table_if_empty($table_name)
752
-    {
753
-        if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
754
-            return \EEH_Activation::getTableManager()->dropTable($table_name);
755
-        }
756
-        return false;
757
-    }
758
-
759
-
760
-    /**
761
-     * delete_unused_db_table
762
-     *
763
-     * @access     public
764
-     * @static
765
-     * @deprecated instead use TableManager::dropTable()
766
-     * @param string $table_name
767
-     * @return bool | int
768
-     */
769
-    public static function delete_unused_db_table($table_name)
770
-    {
771
-        return \EEH_Activation::getTableManager()->dropTable($table_name);
772
-    }
773
-
774
-
775
-    /**
776
-     * drop_index
777
-     *
778
-     * @access     public
779
-     * @static
780
-     * @deprecated instead use TableManager::dropIndex()
781
-     * @param string $table_name
782
-     * @param string $index_name
783
-     * @return bool | int
784
-     */
785
-    public static function drop_index($table_name, $index_name)
786
-    {
787
-        return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
788
-    }
789
-
790
-
791
-
792
-    /**
793
-     * create_database_tables
794
-     *
795
-     * @access public
796
-     * @static
797
-     * @throws EE_Error
798
-     * @return boolean success (whether database is setup properly or not)
799
-     */
800
-    public static function create_database_tables()
801
-    {
802
-        EE_Registry::instance()->load_core('Data_Migration_Manager');
803
-        //find the migration script that sets the database to be compatible with the code
804
-        $dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
805
-        if ($dms_name) {
806
-            $current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
807
-            $current_data_migration_script->set_migrating(false);
808
-            $current_data_migration_script->schema_changes_before_migration();
809
-            $current_data_migration_script->schema_changes_after_migration();
810
-            if ($current_data_migration_script->get_errors()) {
811
-                if (WP_DEBUG) {
812
-                    foreach ($current_data_migration_script->get_errors() as $error) {
813
-                        EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
814
-                    }
815
-                } else {
816
-                    EE_Error::add_error(
817
-                        __(
818
-                            'There were errors creating the Event Espresso database tables and Event Espresso has been 
270
+		$ee_cron_tasks_to_remove = EEH_Activation::get_cron_tasks($cron_tasks_to_remove);
271
+		foreach ($crons as $timestamp => $hooks_to_fire_at_time) {
272
+			if (is_array($hooks_to_fire_at_time)) {
273
+				foreach ($hooks_to_fire_at_time as $hook_name => $hook_actions) {
274
+					if (isset($ee_cron_tasks_to_remove[$hook_name])
275
+						&& is_array($ee_cron_tasks_to_remove[$hook_name])
276
+					) {
277
+						unset($crons[$timestamp][$hook_name]);
278
+					}
279
+				}
280
+				//also take care of any empty cron timestamps.
281
+				if (empty($hooks_to_fire_at_time)) {
282
+					unset($crons[$timestamp]);
283
+				}
284
+			}
285
+		}
286
+		_set_cron_array($crons);
287
+	}
288
+
289
+
290
+	/**
291
+	 *    CPT_initialization
292
+	 *    registers all EE CPTs ( Custom Post Types ) then flushes rewrite rules so that all endpoints exist
293
+	 *
294
+	 * @access public
295
+	 * @static
296
+	 * @return void
297
+	 */
298
+	public static function CPT_initialization()
299
+	{
300
+		// register Custom Post Types
301
+		EE_Registry::instance()->load_core('Register_CPTs');
302
+		flush_rewrite_rules();
303
+	}
304
+
305
+
306
+
307
+	/**
308
+	 *    reset_and_update_config
309
+	 * The following code was moved over from EE_Config so that it will no longer run on every request.
310
+	 * If there is old calendar config data saved, then it will get converted on activation.
311
+	 * This was basically a DMS before we had DMS's, and will get removed after a few more versions.
312
+	 *
313
+	 * @access public
314
+	 * @static
315
+	 * @return void
316
+	 */
317
+	public static function reset_and_update_config()
318
+	{
319
+		do_action('AHEE__EE_Config___load_core_config__start', array('EEH_Activation', 'load_calendar_config'));
320
+		add_filter(
321
+			'FHEE__EE_Config___load_core_config__config_settings',
322
+			array('EEH_Activation', 'migrate_old_config_data'),
323
+			10,
324
+			3
325
+		);
326
+		//EE_Config::reset();
327
+		if (! EE_Config::logging_enabled()) {
328
+			delete_option(EE_Config::LOG_NAME);
329
+		}
330
+	}
331
+
332
+
333
+	/**
334
+	 *    load_calendar_config
335
+	 *
336
+	 * @access    public
337
+	 * @return    void
338
+	 */
339
+	public static function load_calendar_config()
340
+	{
341
+		// grab array of all plugin folders and loop thru it
342
+		$plugins = glob(WP_PLUGIN_DIR . DS . '*', GLOB_ONLYDIR);
343
+		if (empty($plugins)) {
344
+			return;
345
+		}
346
+		foreach ($plugins as $plugin_path) {
347
+			// grab plugin folder name from path
348
+			$plugin = basename($plugin_path);
349
+			// drill down to Espresso plugins
350
+			// then to calendar related plugins
351
+			if (
352
+				strpos($plugin, 'espresso') !== false
353
+				|| strpos($plugin, 'Espresso') !== false
354
+				|| strpos($plugin, 'ee4') !== false
355
+				|| strpos($plugin, 'EE4') !== false
356
+				|| strpos($plugin, 'calendar') !== false
357
+			) {
358
+				// this is what we are looking for
359
+				$calendar_config = $plugin_path . DS . 'EE_Calendar_Config.php';
360
+				// does it exist in this folder ?
361
+				if (is_readable($calendar_config)) {
362
+					// YEAH! let's load it
363
+					require_once($calendar_config);
364
+				}
365
+			}
366
+		}
367
+	}
368
+
369
+
370
+
371
+	/**
372
+	 *    _migrate_old_config_data
373
+	 *
374
+	 * @access    public
375
+	 * @param array|stdClass $settings
376
+	 * @param string         $config
377
+	 * @param \EE_Config     $EE_Config
378
+	 * @return \stdClass
379
+	 */
380
+	public static function migrate_old_config_data($settings = array(), $config = '', EE_Config $EE_Config)
381
+	{
382
+		$convert_from_array = array('addons');
383
+		// in case old settings were saved as an array
384
+		if (is_array($settings) && in_array($config, $convert_from_array)) {
385
+			// convert existing settings to an object
386
+			$config_array = $settings;
387
+			$settings = new stdClass();
388
+			foreach ($config_array as $key => $value) {
389
+				if ($key === 'calendar' && class_exists('EE_Calendar_Config')) {
390
+					$EE_Config->set_config('addons', 'EE_Calendar', 'EE_Calendar_Config', $value);
391
+				} else {
392
+					$settings->{$key} = $value;
393
+				}
394
+			}
395
+			add_filter('FHEE__EE_Config___load_core_config__update_espresso_config', '__return_true');
396
+		}
397
+		return $settings;
398
+	}
399
+
400
+
401
+	/**
402
+	 * deactivate_event_espresso
403
+	 *
404
+	 * @access public
405
+	 * @static
406
+	 * @return void
407
+	 */
408
+	public static function deactivate_event_espresso()
409
+	{
410
+		// check permissions
411
+		if (current_user_can('activate_plugins')) {
412
+			deactivate_plugins(EE_PLUGIN_BASENAME, true);
413
+		}
414
+	}
415
+
416
+
417
+
418
+
419
+	/**
420
+	 * verify_default_pages_exist
421
+	 *
422
+	 * @access public
423
+	 * @static
424
+	 * @return void
425
+	 */
426
+	public static function verify_default_pages_exist()
427
+	{
428
+		$critical_page_problem = false;
429
+		$critical_pages = array(
430
+			array(
431
+				'id'   => 'reg_page_id',
432
+				'name' => __('Registration Checkout', 'event_espresso'),
433
+				'post' => null,
434
+				'code' => 'ESPRESSO_CHECKOUT',
435
+			),
436
+			array(
437
+				'id'   => 'txn_page_id',
438
+				'name' => __('Transactions', 'event_espresso'),
439
+				'post' => null,
440
+				'code' => 'ESPRESSO_TXN_PAGE',
441
+			),
442
+			array(
443
+				'id'   => 'thank_you_page_id',
444
+				'name' => __('Thank You', 'event_espresso'),
445
+				'post' => null,
446
+				'code' => 'ESPRESSO_THANK_YOU',
447
+			),
448
+			array(
449
+				'id'   => 'cancel_page_id',
450
+				'name' => __('Registration Cancelled', 'event_espresso'),
451
+				'post' => null,
452
+				'code' => 'ESPRESSO_CANCELLED',
453
+			),
454
+		);
455
+		$EE_Core_Config = EE_Registry::instance()->CFG->core;
456
+		foreach ($critical_pages as $critical_page) {
457
+			// is critical page ID set in config ?
458
+			if ($EE_Core_Config->{$critical_page['id']} !== false) {
459
+				// attempt to find post by ID
460
+				$critical_page['post'] = get_post($EE_Core_Config->{$critical_page['id']});
461
+			}
462
+			// no dice?
463
+			if ($critical_page['post'] === null) {
464
+				// attempt to find post by title
465
+				$critical_page['post'] = self::get_page_by_ee_shortcode($critical_page['code']);
466
+				// still nothing?
467
+				if ($critical_page['post'] === null) {
468
+					$critical_page = EEH_Activation::create_critical_page($critical_page);
469
+					// REALLY? Still nothing ??!?!?
470
+					if ($critical_page['post'] === null) {
471
+						$msg = __(
472
+							'The Event Espresso critical page configuration settings could not be updated.',
473
+							'event_espresso'
474
+						);
475
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
476
+						break;
477
+					}
478
+				}
479
+			}
480
+			// check that Post ID matches critical page ID in config
481
+			if (
482
+				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
+			$msg = sprintf(
504
+				__(
505
+					'A potential issue has been detected with one or more of your Event Espresso pages. Go to %s to view your Event Espresso pages.',
506
+					'event_espresso'
507
+				),
508
+				'<a href="'
509
+				. admin_url('admin.php?page=espresso_general_settings&action=critical_pages')
510
+				. '">'
511
+				. __('Event Espresso Critical Pages Settings', 'event_espresso')
512
+				. '</a>'
513
+			);
514
+			EE_Error::add_persistent_admin_notice('critical_page_problem', $msg);
515
+		}
516
+		if (EE_Error::has_notices()) {
517
+			EE_Error::get_notices(false, true, true);
518
+		}
519
+	}
520
+
521
+
522
+
523
+	/**
524
+	 * Returns the first post which uses the specified shortcode
525
+	 *
526
+	 * @param string $ee_shortcode usually one of the critical pages shortcodes, eg
527
+	 *                             ESPRESSO_THANK_YOU. So we will search fora post with the content
528
+	 *                             "[ESPRESSO_THANK_YOU"
529
+	 *                             (we don't search for the closing shortcode bracket because they might have added
530
+	 *                             parameter to the shortcode
531
+	 * @return WP_Post or NULl
532
+	 */
533
+	public static function get_page_by_ee_shortcode($ee_shortcode)
534
+	{
535
+		global $wpdb;
536
+		$shortcode_and_opening_bracket = '[' . $ee_shortcode;
537
+		$post_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%$shortcode_and_opening_bracket%' LIMIT 1");
538
+		if ($post_id) {
539
+			return get_post($post_id);
540
+		} else {
541
+			return null;
542
+		}
543
+	}
544
+
545
+
546
+
547
+	/**
548
+	 *    This function generates a post for critical espresso pages
549
+	 *
550
+	 * @access public
551
+	 * @static
552
+	 * @param array $critical_page
553
+	 * @return array
554
+	 */
555
+	public static function create_critical_page($critical_page)
556
+	{
557
+
558
+		$post_args = array(
559
+			'post_title'     => $critical_page['name'],
560
+			'post_status'    => 'publish',
561
+			'post_type'      => 'page',
562
+			'comment_status' => 'closed',
563
+			'post_content'   => '[' . $critical_page['code'] . ']',
564
+		);
565
+
566
+		$post_id = wp_insert_post($post_args);
567
+		if (! $post_id) {
568
+			$msg = sprintf(
569
+				__('The Event Espresso  critical page entitled "%s" could not be created.', 'event_espresso'),
570
+				$critical_page['name']
571
+			);
572
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
573
+			return $critical_page;
574
+		}
575
+		// get newly created post's details
576
+		if (! $critical_page['post'] = get_post($post_id)) {
577
+			$msg = sprintf(
578
+				__('The Event Espresso critical page entitled "%s" could not be retrieved.', 'event_espresso'),
579
+				$critical_page['name']
580
+			);
581
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
582
+		}
583
+
584
+		return $critical_page;
585
+
586
+	}
587
+
588
+
589
+
590
+
591
+	/**
592
+	 * Tries to find the oldest admin for this site.  If there are no admins for this site then return NULL.
593
+	 * The role being used to check is filterable.
594
+	 *
595
+	 * @since  4.6.0
596
+	 * @global WPDB $wpdb
597
+	 * @return mixed null|int WP_user ID or NULL
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
+	/**
633
+	 * used by EE and EE addons during plugin activation to create tables.
634
+	 * Its a wrapper for EventEspresso\core\services\database\TableManager::createTable,
635
+	 * but includes extra logic regarding activations.
636
+	 *
637
+	 * @access public
638
+	 * @static
639
+	 * @param string  $table_name              without the $wpdb->prefix
640
+	 * @param string  $sql                     SQL for creating the table (contents between brackets in an SQL create
641
+	 *                                         table query)
642
+	 * @param string  $engine                  like 'ENGINE=MyISAM' or 'ENGINE=InnoDB'
643
+	 * @param boolean $drop_pre_existing_table set to TRUE when you want to make SURE the table is completely empty
644
+	 *                                         and new once this function is done (ie, you really do want to CREATE a
645
+	 *                                         table, and expect it to be empty once you're done) leave as FALSE when
646
+	 *                                         you just want to verify the table exists and matches this definition
647
+	 *                                         (and if it HAS data in it you want to leave it be)
648
+	 * @return void
649
+	 * @throws EE_Error if there are database errors
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
+			} else if ( ! $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
+	/**
691
+	 *    add_column_if_it_doesn't_exist
692
+	 *    Checks if this column already exists on the specified table. Handy for addons which want to add a column
693
+	 *
694
+	 * @access     public
695
+	 * @static
696
+	 * @deprecated instead use TableManager::addColumn()
697
+	 * @param string $table_name  (without "wp_", eg "esp_attendee"
698
+	 * @param string $column_name
699
+	 * @param string $column_info if your SQL were 'ALTER TABLE table_name ADD price VARCHAR(10)', this would be
700
+	 *                            'VARCHAR(10)'
701
+	 * @return bool|int
702
+	 */
703
+	public static function add_column_if_it_doesnt_exist(
704
+		$table_name,
705
+		$column_name,
706
+		$column_info = 'INT UNSIGNED NOT NULL'
707
+	) {
708
+		return \EEH_Activation::getTableManager()->addColumn($table_name, $column_name, $column_info);
709
+	}
710
+
711
+
712
+	/**
713
+	 * get_fields_on_table
714
+	 * Gets all the fields on the database table.
715
+	 *
716
+	 * @access     public
717
+	 * @deprecated instead use TableManager::getTableColumns()
718
+	 * @static
719
+	 * @param string $table_name , without prefixed $wpdb->prefix
720
+	 * @return array of database column names
721
+	 */
722
+	public static function get_fields_on_table($table_name = null)
723
+	{
724
+		return \EEH_Activation::getTableManager()->getTableColumns($table_name);
725
+	}
726
+
727
+
728
+	/**
729
+	 * db_table_is_empty
730
+	 *
731
+	 * @access     public\
732
+	 * @deprecated instead use TableAnalysis::tableIsEmpty()
733
+	 * @static
734
+	 * @param string $table_name
735
+	 * @return bool
736
+	 */
737
+	public static function db_table_is_empty($table_name)
738
+	{
739
+		return \EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name);
740
+	}
741
+
742
+
743
+	/**
744
+	 * delete_db_table_if_empty
745
+	 *
746
+	 * @access public
747
+	 * @static
748
+	 * @param string $table_name
749
+	 * @return bool | int
750
+	 */
751
+	public static function delete_db_table_if_empty($table_name)
752
+	{
753
+		if (\EEH_Activation::getTableAnalysis()->tableIsEmpty($table_name)) {
754
+			return \EEH_Activation::getTableManager()->dropTable($table_name);
755
+		}
756
+		return false;
757
+	}
758
+
759
+
760
+	/**
761
+	 * delete_unused_db_table
762
+	 *
763
+	 * @access     public
764
+	 * @static
765
+	 * @deprecated instead use TableManager::dropTable()
766
+	 * @param string $table_name
767
+	 * @return bool | int
768
+	 */
769
+	public static function delete_unused_db_table($table_name)
770
+	{
771
+		return \EEH_Activation::getTableManager()->dropTable($table_name);
772
+	}
773
+
774
+
775
+	/**
776
+	 * drop_index
777
+	 *
778
+	 * @access     public
779
+	 * @static
780
+	 * @deprecated instead use TableManager::dropIndex()
781
+	 * @param string $table_name
782
+	 * @param string $index_name
783
+	 * @return bool | int
784
+	 */
785
+	public static function drop_index($table_name, $index_name)
786
+	{
787
+		return \EEH_Activation::getTableManager()->dropIndex($table_name, $index_name);
788
+	}
789
+
790
+
791
+
792
+	/**
793
+	 * create_database_tables
794
+	 *
795
+	 * @access public
796
+	 * @static
797
+	 * @throws EE_Error
798
+	 * @return boolean success (whether database is setup properly or not)
799
+	 */
800
+	public static function create_database_tables()
801
+	{
802
+		EE_Registry::instance()->load_core('Data_Migration_Manager');
803
+		//find the migration script that sets the database to be compatible with the code
804
+		$dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms();
805
+		if ($dms_name) {
806
+			$current_data_migration_script = EE_Registry::instance()->load_dms($dms_name);
807
+			$current_data_migration_script->set_migrating(false);
808
+			$current_data_migration_script->schema_changes_before_migration();
809
+			$current_data_migration_script->schema_changes_after_migration();
810
+			if ($current_data_migration_script->get_errors()) {
811
+				if (WP_DEBUG) {
812
+					foreach ($current_data_migration_script->get_errors() as $error) {
813
+						EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
814
+					}
815
+				} else {
816
+					EE_Error::add_error(
817
+						__(
818
+							'There were errors creating the Event Espresso database tables and Event Espresso has been 
819 819
                             deactivated. To view the errors, please enable WP_DEBUG in your wp-config.php file.',
820
-                            'event_espresso'
821
-                        )
822
-                    );
823
-                }
824
-                return false;
825
-            }
826
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to();
827
-        } else {
828
-            EE_Error::add_error(
829
-                __(
830
-                    'Could not determine most up-to-date data migration script from which to pull database schema
820
+							'event_espresso'
821
+						)
822
+					);
823
+				}
824
+				return false;
825
+			}
826
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to();
827
+		} else {
828
+			EE_Error::add_error(
829
+				__(
830
+					'Could not determine most up-to-date data migration script from which to pull database schema
831 831
                      structure. So database is probably not setup properly',
832
-                    'event_espresso'
833
-                ),
834
-                __FILE__,
835
-                __FUNCTION__,
836
-                __LINE__
837
-            );
838
-            return false;
839
-        }
840
-        return true;
841
-    }
842
-
843
-
844
-
845
-    /**
846
-     * initialize_system_questions
847
-     *
848
-     * @access public
849
-     * @static
850
-     * @return void
851
-     */
852
-    public static function initialize_system_questions()
853
-    {
854
-        // QUESTION GROUPS
855
-        global $wpdb;
856
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
857
-        $SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
858
-        // what we have
859
-        $question_groups = $wpdb->get_col($SQL);
860
-        // check the response
861
-        $question_groups = is_array($question_groups) ? $question_groups : array();
862
-        // what we should have
863
-        $QSG_systems = array(1, 2);
864
-        // loop thru what we should have and compare to what we have
865
-        foreach ($QSG_systems as $QSG_system) {
866
-            // reset values array
867
-            $QSG_values = array();
868
-            // 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)
869
-            if (! in_array("$QSG_system", $question_groups)) {
870
-                // add it
871
-                switch ($QSG_system) {
872
-                    case 1:
873
-                        $QSG_values = array(
874
-                            'QSG_name'            => __('Personal Information', 'event_espresso'),
875
-                            'QSG_identifier'      => 'personal-information-' . time(),
876
-                            'QSG_desc'            => '',
877
-                            'QSG_order'           => 1,
878
-                            'QSG_show_group_name' => 1,
879
-                            'QSG_show_group_desc' => 1,
880
-                            'QSG_system'          => EEM_Question_Group::system_personal,
881
-                            'QSG_deleted'         => 0,
882
-                        );
883
-                        break;
884
-                    case 2:
885
-                        $QSG_values = array(
886
-                            'QSG_name'            => __('Address Information', 'event_espresso'),
887
-                            'QSG_identifier'      => 'address-information-' . time(),
888
-                            'QSG_desc'            => '',
889
-                            'QSG_order'           => 2,
890
-                            'QSG_show_group_name' => 1,
891
-                            'QSG_show_group_desc' => 1,
892
-                            'QSG_system'          => EEM_Question_Group::system_address,
893
-                            'QSG_deleted'         => 0,
894
-                        );
895
-                        break;
896
-                }
897
-                // make sure we have some values before inserting them
898
-                if (! empty($QSG_values)) {
899
-                    // insert system question
900
-                    $wpdb->insert(
901
-                        $table_name,
902
-                        $QSG_values,
903
-                        array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
904
-                    );
905
-                    $QSG_IDs[$QSG_system] = $wpdb->insert_id;
906
-                }
907
-            }
908
-        }
909
-        // QUESTIONS
910
-        global $wpdb;
911
-        $table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
912
-        $SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
913
-        // what we have
914
-        $questions = $wpdb->get_col($SQL);
915
-        // what we should have
916
-        $QST_systems = array(
917
-            'fname',
918
-            'lname',
919
-            'email',
920
-            'address',
921
-            'address2',
922
-            'city',
923
-            'country',
924
-            'state',
925
-            'zip',
926
-            'phone',
927
-        );
928
-        $order_for_group_1 = 1;
929
-        $order_for_group_2 = 1;
930
-        // loop thru what we should have and compare to what we have
931
-        foreach ($QST_systems as $QST_system) {
932
-            // reset values array
933
-            $QST_values = array();
934
-            // if we don't have what we should have
935
-            if (! in_array($QST_system, $questions)) {
936
-                // add it
937
-                switch ($QST_system) {
938
-                    case 'fname':
939
-                        $QST_values = array(
940
-                            'QST_display_text'  => __('First Name', 'event_espresso'),
941
-                            'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
942
-                            'QST_system'        => 'fname',
943
-                            'QST_type'          => 'TEXT',
944
-                            'QST_required'      => 1,
945
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
946
-                            'QST_order'         => 1,
947
-                            'QST_admin_only'    => 0,
948
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
949
-                            'QST_wp_user'       => self::get_default_creator_id(),
950
-                            'QST_deleted'       => 0,
951
-                        );
952
-                        break;
953
-                    case 'lname':
954
-                        $QST_values = array(
955
-                            'QST_display_text'  => __('Last Name', 'event_espresso'),
956
-                            'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
957
-                            'QST_system'        => 'lname',
958
-                            'QST_type'          => 'TEXT',
959
-                            'QST_required'      => 1,
960
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
961
-                            'QST_order'         => 2,
962
-                            'QST_admin_only'    => 0,
963
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
964
-                            'QST_wp_user'       => self::get_default_creator_id(),
965
-                            'QST_deleted'       => 0,
966
-                        );
967
-                        break;
968
-                    case 'email':
969
-                        $QST_values = array(
970
-                            'QST_display_text'  => __('Email Address', 'event_espresso'),
971
-                            'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
972
-                            'QST_system'        => 'email',
973
-                            'QST_type'          => 'EMAIL',
974
-                            'QST_required'      => 1,
975
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
976
-                            'QST_order'         => 3,
977
-                            'QST_admin_only'    => 0,
978
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
979
-                            'QST_wp_user'       => self::get_default_creator_id(),
980
-                            'QST_deleted'       => 0,
981
-                        );
982
-                        break;
983
-                    case 'address':
984
-                        $QST_values = array(
985
-                            'QST_display_text'  => __('Address', 'event_espresso'),
986
-                            'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
987
-                            'QST_system'        => 'address',
988
-                            'QST_type'          => 'TEXT',
989
-                            'QST_required'      => 0,
990
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
991
-                            'QST_order'         => 4,
992
-                            'QST_admin_only'    => 0,
993
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
994
-                            'QST_wp_user'       => self::get_default_creator_id(),
995
-                            'QST_deleted'       => 0,
996
-                        );
997
-                        break;
998
-                    case 'address2':
999
-                        $QST_values = array(
1000
-                            'QST_display_text'  => __('Address2', 'event_espresso'),
1001
-                            'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1002
-                            'QST_system'        => 'address2',
1003
-                            'QST_type'          => 'TEXT',
1004
-                            'QST_required'      => 0,
1005
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1006
-                            'QST_order'         => 5,
1007
-                            'QST_admin_only'    => 0,
1008
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1009
-                            'QST_wp_user'       => self::get_default_creator_id(),
1010
-                            'QST_deleted'       => 0,
1011
-                        );
1012
-                        break;
1013
-                    case 'city':
1014
-                        $QST_values = array(
1015
-                            'QST_display_text'  => __('City', 'event_espresso'),
1016
-                            'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1017
-                            'QST_system'        => 'city',
1018
-                            'QST_type'          => 'TEXT',
1019
-                            'QST_required'      => 0,
1020
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1021
-                            'QST_order'         => 6,
1022
-                            'QST_admin_only'    => 0,
1023
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1024
-                            'QST_wp_user'       => self::get_default_creator_id(),
1025
-                            'QST_deleted'       => 0,
1026
-                        );
1027
-                        break;
1028
-                    case 'country':
1029
-                        $QST_values = array(
1030
-                            'QST_display_text'  => __('Country', 'event_espresso'),
1031
-                            'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1032
-                            'QST_system'        => 'country',
1033
-                            'QST_type'          => 'COUNTRY',
1034
-                            'QST_required'      => 0,
1035
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1036
-                            'QST_order'         => 7,
1037
-                            'QST_admin_only'    => 0,
1038
-                            'QST_wp_user'       => self::get_default_creator_id(),
1039
-                            'QST_deleted'       => 0,
1040
-                        );
1041
-                        break;
1042
-                    case 'state':
1043
-                        $QST_values = array(
1044
-                            'QST_display_text'  => __('State/Province', 'event_espresso'),
1045
-                            'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1046
-                            'QST_system'        => 'state',
1047
-                            'QST_type'          => 'STATE',
1048
-                            'QST_required'      => 0,
1049
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1050
-                            'QST_order'         => 8,
1051
-                            'QST_admin_only'    => 0,
1052
-                            'QST_wp_user'       => self::get_default_creator_id(),
1053
-                            'QST_deleted'       => 0,
1054
-                        );
1055
-                        break;
1056
-                    case 'zip':
1057
-                        $QST_values = array(
1058
-                            'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1059
-                            'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1060
-                            'QST_system'        => 'zip',
1061
-                            'QST_type'          => 'TEXT',
1062
-                            'QST_required'      => 0,
1063
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1064
-                            'QST_order'         => 9,
1065
-                            'QST_admin_only'    => 0,
1066
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1067
-                            'QST_wp_user'       => self::get_default_creator_id(),
1068
-                            'QST_deleted'       => 0,
1069
-                        );
1070
-                        break;
1071
-                    case 'phone':
1072
-                        $QST_values = array(
1073
-                            'QST_display_text'  => __('Phone Number', 'event_espresso'),
1074
-                            'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1075
-                            'QST_system'        => 'phone',
1076
-                            'QST_type'          => 'TEXT',
1077
-                            'QST_required'      => 0,
1078
-                            'QST_required_text' => __('This field is required', 'event_espresso'),
1079
-                            'QST_order'         => 10,
1080
-                            'QST_admin_only'    => 0,
1081
-                            'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1082
-                            'QST_wp_user'       => self::get_default_creator_id(),
1083
-                            'QST_deleted'       => 0,
1084
-                        );
1085
-                        break;
1086
-                }
1087
-                if (! empty($QST_values)) {
1088
-                    // insert system question
1089
-                    $wpdb->insert(
1090
-                        $table_name,
1091
-                        $QST_values,
1092
-                        array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1093
-                    );
1094
-                    $QST_ID = $wpdb->insert_id;
1095
-                    // QUESTION GROUP QUESTIONS
1096
-                    if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1097
-                        $system_question_we_want = EEM_Question_Group::system_personal;
1098
-                    } else {
1099
-                        $system_question_we_want = EEM_Question_Group::system_address;
1100
-                    }
1101
-                    if (isset($QSG_IDs[$system_question_we_want])) {
1102
-                        $QSG_ID = $QSG_IDs[$system_question_we_want];
1103
-                    } else {
1104
-                        $id_col = EEM_Question_Group::instance()
1105
-                                                    ->get_col(array(array('QSG_system' => $system_question_we_want)));
1106
-                        if (is_array($id_col)) {
1107
-                            $QSG_ID = reset($id_col);
1108
-                        } else {
1109
-                            //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
1110
-                            EE_Log::instance()->log(
1111
-                                __FILE__,
1112
-                                __FUNCTION__,
1113
-                                sprintf(
1114
-                                    __(
1115
-                                        'Could not associate question %1$s to a question group because no system question
832
+					'event_espresso'
833
+				),
834
+				__FILE__,
835
+				__FUNCTION__,
836
+				__LINE__
837
+			);
838
+			return false;
839
+		}
840
+		return true;
841
+	}
842
+
843
+
844
+
845
+	/**
846
+	 * initialize_system_questions
847
+	 *
848
+	 * @access public
849
+	 * @static
850
+	 * @return void
851
+	 */
852
+	public static function initialize_system_questions()
853
+	{
854
+		// QUESTION GROUPS
855
+		global $wpdb;
856
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group');
857
+		$SQL = "SELECT QSG_system FROM $table_name WHERE QSG_system != 0";
858
+		// what we have
859
+		$question_groups = $wpdb->get_col($SQL);
860
+		// check the response
861
+		$question_groups = is_array($question_groups) ? $question_groups : array();
862
+		// what we should have
863
+		$QSG_systems = array(1, 2);
864
+		// loop thru what we should have and compare to what we have
865
+		foreach ($QSG_systems as $QSG_system) {
866
+			// reset values array
867
+			$QSG_values = array();
868
+			// 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)
869
+			if (! in_array("$QSG_system", $question_groups)) {
870
+				// add it
871
+				switch ($QSG_system) {
872
+					case 1:
873
+						$QSG_values = array(
874
+							'QSG_name'            => __('Personal Information', 'event_espresso'),
875
+							'QSG_identifier'      => 'personal-information-' . time(),
876
+							'QSG_desc'            => '',
877
+							'QSG_order'           => 1,
878
+							'QSG_show_group_name' => 1,
879
+							'QSG_show_group_desc' => 1,
880
+							'QSG_system'          => EEM_Question_Group::system_personal,
881
+							'QSG_deleted'         => 0,
882
+						);
883
+						break;
884
+					case 2:
885
+						$QSG_values = array(
886
+							'QSG_name'            => __('Address Information', 'event_espresso'),
887
+							'QSG_identifier'      => 'address-information-' . time(),
888
+							'QSG_desc'            => '',
889
+							'QSG_order'           => 2,
890
+							'QSG_show_group_name' => 1,
891
+							'QSG_show_group_desc' => 1,
892
+							'QSG_system'          => EEM_Question_Group::system_address,
893
+							'QSG_deleted'         => 0,
894
+						);
895
+						break;
896
+				}
897
+				// make sure we have some values before inserting them
898
+				if (! empty($QSG_values)) {
899
+					// insert system question
900
+					$wpdb->insert(
901
+						$table_name,
902
+						$QSG_values,
903
+						array('%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')
904
+					);
905
+					$QSG_IDs[$QSG_system] = $wpdb->insert_id;
906
+				}
907
+			}
908
+		}
909
+		// QUESTIONS
910
+		global $wpdb;
911
+		$table_name = \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question');
912
+		$SQL = "SELECT QST_system FROM $table_name WHERE QST_system != ''";
913
+		// what we have
914
+		$questions = $wpdb->get_col($SQL);
915
+		// what we should have
916
+		$QST_systems = array(
917
+			'fname',
918
+			'lname',
919
+			'email',
920
+			'address',
921
+			'address2',
922
+			'city',
923
+			'country',
924
+			'state',
925
+			'zip',
926
+			'phone',
927
+		);
928
+		$order_for_group_1 = 1;
929
+		$order_for_group_2 = 1;
930
+		// loop thru what we should have and compare to what we have
931
+		foreach ($QST_systems as $QST_system) {
932
+			// reset values array
933
+			$QST_values = array();
934
+			// if we don't have what we should have
935
+			if (! in_array($QST_system, $questions)) {
936
+				// add it
937
+				switch ($QST_system) {
938
+					case 'fname':
939
+						$QST_values = array(
940
+							'QST_display_text'  => __('First Name', 'event_espresso'),
941
+							'QST_admin_label'   => __('First Name - System Question', 'event_espresso'),
942
+							'QST_system'        => 'fname',
943
+							'QST_type'          => 'TEXT',
944
+							'QST_required'      => 1,
945
+							'QST_required_text' => __('This field is required', 'event_espresso'),
946
+							'QST_order'         => 1,
947
+							'QST_admin_only'    => 0,
948
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
949
+							'QST_wp_user'       => self::get_default_creator_id(),
950
+							'QST_deleted'       => 0,
951
+						);
952
+						break;
953
+					case 'lname':
954
+						$QST_values = array(
955
+							'QST_display_text'  => __('Last Name', 'event_espresso'),
956
+							'QST_admin_label'   => __('Last Name - System Question', 'event_espresso'),
957
+							'QST_system'        => 'lname',
958
+							'QST_type'          => 'TEXT',
959
+							'QST_required'      => 1,
960
+							'QST_required_text' => __('This field is required', 'event_espresso'),
961
+							'QST_order'         => 2,
962
+							'QST_admin_only'    => 0,
963
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
964
+							'QST_wp_user'       => self::get_default_creator_id(),
965
+							'QST_deleted'       => 0,
966
+						);
967
+						break;
968
+					case 'email':
969
+						$QST_values = array(
970
+							'QST_display_text'  => __('Email Address', 'event_espresso'),
971
+							'QST_admin_label'   => __('Email Address - System Question', 'event_espresso'),
972
+							'QST_system'        => 'email',
973
+							'QST_type'          => 'EMAIL',
974
+							'QST_required'      => 1,
975
+							'QST_required_text' => __('This field is required', 'event_espresso'),
976
+							'QST_order'         => 3,
977
+							'QST_admin_only'    => 0,
978
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
979
+							'QST_wp_user'       => self::get_default_creator_id(),
980
+							'QST_deleted'       => 0,
981
+						);
982
+						break;
983
+					case 'address':
984
+						$QST_values = array(
985
+							'QST_display_text'  => __('Address', 'event_espresso'),
986
+							'QST_admin_label'   => __('Address - System Question', 'event_espresso'),
987
+							'QST_system'        => 'address',
988
+							'QST_type'          => 'TEXT',
989
+							'QST_required'      => 0,
990
+							'QST_required_text' => __('This field is required', 'event_espresso'),
991
+							'QST_order'         => 4,
992
+							'QST_admin_only'    => 0,
993
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
994
+							'QST_wp_user'       => self::get_default_creator_id(),
995
+							'QST_deleted'       => 0,
996
+						);
997
+						break;
998
+					case 'address2':
999
+						$QST_values = array(
1000
+							'QST_display_text'  => __('Address2', 'event_espresso'),
1001
+							'QST_admin_label'   => __('Address2 - System Question', 'event_espresso'),
1002
+							'QST_system'        => 'address2',
1003
+							'QST_type'          => 'TEXT',
1004
+							'QST_required'      => 0,
1005
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1006
+							'QST_order'         => 5,
1007
+							'QST_admin_only'    => 0,
1008
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1009
+							'QST_wp_user'       => self::get_default_creator_id(),
1010
+							'QST_deleted'       => 0,
1011
+						);
1012
+						break;
1013
+					case 'city':
1014
+						$QST_values = array(
1015
+							'QST_display_text'  => __('City', 'event_espresso'),
1016
+							'QST_admin_label'   => __('City - System Question', 'event_espresso'),
1017
+							'QST_system'        => 'city',
1018
+							'QST_type'          => 'TEXT',
1019
+							'QST_required'      => 0,
1020
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1021
+							'QST_order'         => 6,
1022
+							'QST_admin_only'    => 0,
1023
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1024
+							'QST_wp_user'       => self::get_default_creator_id(),
1025
+							'QST_deleted'       => 0,
1026
+						);
1027
+						break;
1028
+					case 'country':
1029
+						$QST_values = array(
1030
+							'QST_display_text'  => __('Country', 'event_espresso'),
1031
+							'QST_admin_label'   => __('Country - System Question', 'event_espresso'),
1032
+							'QST_system'        => 'country',
1033
+							'QST_type'          => 'COUNTRY',
1034
+							'QST_required'      => 0,
1035
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1036
+							'QST_order'         => 7,
1037
+							'QST_admin_only'    => 0,
1038
+							'QST_wp_user'       => self::get_default_creator_id(),
1039
+							'QST_deleted'       => 0,
1040
+						);
1041
+						break;
1042
+					case 'state':
1043
+						$QST_values = array(
1044
+							'QST_display_text'  => __('State/Province', 'event_espresso'),
1045
+							'QST_admin_label'   => __('State/Province - System Question', 'event_espresso'),
1046
+							'QST_system'        => 'state',
1047
+							'QST_type'          => 'STATE',
1048
+							'QST_required'      => 0,
1049
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1050
+							'QST_order'         => 8,
1051
+							'QST_admin_only'    => 0,
1052
+							'QST_wp_user'       => self::get_default_creator_id(),
1053
+							'QST_deleted'       => 0,
1054
+						);
1055
+						break;
1056
+					case 'zip':
1057
+						$QST_values = array(
1058
+							'QST_display_text'  => __('Zip/Postal Code', 'event_espresso'),
1059
+							'QST_admin_label'   => __('Zip/Postal Code - System Question', 'event_espresso'),
1060
+							'QST_system'        => 'zip',
1061
+							'QST_type'          => 'TEXT',
1062
+							'QST_required'      => 0,
1063
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1064
+							'QST_order'         => 9,
1065
+							'QST_admin_only'    => 0,
1066
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1067
+							'QST_wp_user'       => self::get_default_creator_id(),
1068
+							'QST_deleted'       => 0,
1069
+						);
1070
+						break;
1071
+					case 'phone':
1072
+						$QST_values = array(
1073
+							'QST_display_text'  => __('Phone Number', 'event_espresso'),
1074
+							'QST_admin_label'   => __('Phone Number - System Question', 'event_espresso'),
1075
+							'QST_system'        => 'phone',
1076
+							'QST_type'          => 'TEXT',
1077
+							'QST_required'      => 0,
1078
+							'QST_required_text' => __('This field is required', 'event_espresso'),
1079
+							'QST_order'         => 10,
1080
+							'QST_admin_only'    => 0,
1081
+							'QST_max'           => EEM_Question::instance()->absolute_max_for_system_question($QST_system),
1082
+							'QST_wp_user'       => self::get_default_creator_id(),
1083
+							'QST_deleted'       => 0,
1084
+						);
1085
+						break;
1086
+				}
1087
+				if (! empty($QST_values)) {
1088
+					// insert system question
1089
+					$wpdb->insert(
1090
+						$table_name,
1091
+						$QST_values,
1092
+						array('%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%d', '%d')
1093
+					);
1094
+					$QST_ID = $wpdb->insert_id;
1095
+					// QUESTION GROUP QUESTIONS
1096
+					if (in_array($QST_system, array('fname', 'lname', 'email'))) {
1097
+						$system_question_we_want = EEM_Question_Group::system_personal;
1098
+					} else {
1099
+						$system_question_we_want = EEM_Question_Group::system_address;
1100
+					}
1101
+					if (isset($QSG_IDs[$system_question_we_want])) {
1102
+						$QSG_ID = $QSG_IDs[$system_question_we_want];
1103
+					} else {
1104
+						$id_col = EEM_Question_Group::instance()
1105
+													->get_col(array(array('QSG_system' => $system_question_we_want)));
1106
+						if (is_array($id_col)) {
1107
+							$QSG_ID = reset($id_col);
1108
+						} else {
1109
+							//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
1110
+							EE_Log::instance()->log(
1111
+								__FILE__,
1112
+								__FUNCTION__,
1113
+								sprintf(
1114
+									__(
1115
+										'Could not associate question %1$s to a question group because no system question
1116 1116
                                          group existed',
1117
-                                        'event_espresso'
1118
-                                    ),
1119
-                                    $QST_ID),
1120
-                                'error');
1121
-                            continue;
1122
-                        }
1123
-                    }
1124
-                    // add system questions to groups
1125
-                    $wpdb->insert(
1126
-                        \EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1127
-                        array(
1128
-                            'QSG_ID'    => $QSG_ID,
1129
-                            'QST_ID'    => $QST_ID,
1130
-                            'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1131
-                        ),
1132
-                        array('%d', '%d', '%d')
1133
-                    );
1134
-                }
1135
-            }
1136
-        }
1137
-    }
1138
-
1139
-
1140
-    /**
1141
-     * Makes sure the default payment method (Invoice) is active.
1142
-     * This used to be done automatically as part of constructing the old gateways config
1143
-     *
1144
-     * @throws \EE_Error
1145
-     */
1146
-    public static function insert_default_payment_methods()
1147
-    {
1148
-        if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1149
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
1150
-            EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1151
-        } else {
1152
-            EEM_Payment_Method::instance()->verify_button_urls();
1153
-        }
1154
-    }
1155
-
1156
-    /**
1157
-     * insert_default_status_codes
1158
-     *
1159
-     * @access public
1160
-     * @static
1161
-     * @return void
1162
-     */
1163
-    public static function insert_default_status_codes()
1164
-    {
1165
-
1166
-        global $wpdb;
1167
-
1168
-        if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1169
-
1170
-            $table_name = EEM_Status::instance()->table();
1171
-
1172
-            $SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1173
-            $wpdb->query($SQL);
1174
-
1175
-            $SQL = "INSERT INTO $table_name
1117
+										'event_espresso'
1118
+									),
1119
+									$QST_ID),
1120
+								'error');
1121
+							continue;
1122
+						}
1123
+					}
1124
+					// add system questions to groups
1125
+					$wpdb->insert(
1126
+						\EEH_Activation::getTableAnalysis()->ensureTableNameHasPrefix('esp_question_group_question'),
1127
+						array(
1128
+							'QSG_ID'    => $QSG_ID,
1129
+							'QST_ID'    => $QST_ID,
1130
+							'QGQ_order' => ($QSG_ID === 1) ? $order_for_group_1++ : $order_for_group_2++,
1131
+						),
1132
+						array('%d', '%d', '%d')
1133
+					);
1134
+				}
1135
+			}
1136
+		}
1137
+	}
1138
+
1139
+
1140
+	/**
1141
+	 * Makes sure the default payment method (Invoice) is active.
1142
+	 * This used to be done automatically as part of constructing the old gateways config
1143
+	 *
1144
+	 * @throws \EE_Error
1145
+	 */
1146
+	public static function insert_default_payment_methods()
1147
+	{
1148
+		if (! EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart)) {
1149
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
1150
+			EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
1151
+		} else {
1152
+			EEM_Payment_Method::instance()->verify_button_urls();
1153
+		}
1154
+	}
1155
+
1156
+	/**
1157
+	 * insert_default_status_codes
1158
+	 *
1159
+	 * @access public
1160
+	 * @static
1161
+	 * @return void
1162
+	 */
1163
+	public static function insert_default_status_codes()
1164
+	{
1165
+
1166
+		global $wpdb;
1167
+
1168
+		if (\EEH_Activation::getTableAnalysis()->tableExists(EEM_Status::instance()->table())) {
1169
+
1170
+			$table_name = EEM_Status::instance()->table();
1171
+
1172
+			$SQL = "DELETE FROM $table_name WHERE STS_ID IN ( 'ACT', 'NAC', 'NOP', 'OPN', 'CLS', 'PND', 'ONG', 'SEC', 'DRF', 'DEL', 'DEN', 'EXP', 'RPP', 'RCN', 'RDC', 'RAP', 'RNA', 'RWL', 'TAB', 'TIN', 'TFL', 'TCM', 'TOP', 'PAP', 'PCN', 'PFL', 'PDC', 'EDR', 'ESN', 'PPN', 'RIC', 'MSN', 'MFL', 'MID', 'MRS', 'MIC', 'MDO', 'MEX' );";
1173
+			$wpdb->query($SQL);
1174
+
1175
+			$SQL = "INSERT INTO $table_name
1176 1176
 					(STS_ID, STS_code, STS_type, STS_can_edit, STS_desc, STS_open) VALUES
1177 1177
 					('ACT', 'ACTIVE', 'event', 0, NULL, 1),
1178 1178
 					('NAC', 'NOT_ACTIVE', 'event', 0, NULL, 0),
@@ -1212,521 +1212,521 @@  discard block
 block discarded – undo
1212 1212
 					('MID', 'IDLE', 'message', 0, NULL, 1),
1213 1213
 					('MRS', 'RESEND', 'message', 0, NULL, 1),
1214 1214
 					('MIC', 'INCOMPLETE', 'message', 0, NULL, 0);";
1215
-            $wpdb->query($SQL);
1216
-
1217
-        }
1218
-
1219
-    }
1220
-
1221
-
1222
-    /**
1223
-     * create_upload_directories
1224
-     * Creates folders in the uploads directory to facilitate addons and templates
1225
-     *
1226
-     * @access public
1227
-     * @static
1228
-     * @return boolean success of verifying upload directories exist
1229
-     */
1230
-    public static function create_upload_directories()
1231
-    {
1232
-        // Create the required folders
1233
-        $folders = array(
1234
-            EVENT_ESPRESSO_TEMPLATE_DIR,
1235
-            EVENT_ESPRESSO_GATEWAY_DIR,
1236
-            EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1237
-            EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1238
-            EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1239
-        );
1240
-        foreach ($folders as $folder) {
1241
-            try {
1242
-                EEH_File::ensure_folder_exists_and_is_writable($folder);
1243
-                @ chmod($folder, 0755);
1244
-            } catch (EE_Error $e) {
1245
-                EE_Error::add_error(
1246
-                    sprintf(
1247
-                        __('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1248
-                        $folder,
1249
-                        '<br />' . $e->getMessage()
1250
-                    ),
1251
-                    __FILE__, __FUNCTION__, __LINE__
1252
-                );
1253
-                //indicate we'll need to fix this later
1254
-                update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1255
-                return false;
1256
-            }
1257
-        }
1258
-        //just add the .htaccess file to the logs directory to begin with. Even if logging
1259
-        //is disabled, there might be activation errors recorded in there
1260
-        EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1261
-        //remember EE's folders are all good
1262
-        delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1263
-        return true;
1264
-    }
1265
-
1266
-    /**
1267
-     * Whether the upload directories need to be fixed or not.
1268
-     * If EE is installed but filesystem access isn't initially available,
1269
-     * we need to get the user's filesystem credentials and THEN create them,
1270
-     * so there might be period of time when EE is installed but its
1271
-     * upload directories aren't available. This indicates such a state
1272
-     *
1273
-     * @return boolean
1274
-     */
1275
-    public static function upload_directories_incomplete()
1276
-    {
1277
-        return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1278
-    }
1279
-
1280
-
1281
-    /**
1282
-     * generate_default_message_templates
1283
-     *
1284
-     * @static
1285
-     * @throws EE_Error
1286
-     * @return bool     true means new templates were created.
1287
-     *                  false means no templates were created.
1288
-     *                  This is NOT an error flag. To check for errors you will want
1289
-     *                  to use either EE_Error or a try catch for an EE_Error exception.
1290
-     */
1291
-    public static function generate_default_message_templates()
1292
-    {
1293
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1294
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1295
-        /*
1215
+			$wpdb->query($SQL);
1216
+
1217
+		}
1218
+
1219
+	}
1220
+
1221
+
1222
+	/**
1223
+	 * create_upload_directories
1224
+	 * Creates folders in the uploads directory to facilitate addons and templates
1225
+	 *
1226
+	 * @access public
1227
+	 * @static
1228
+	 * @return boolean success of verifying upload directories exist
1229
+	 */
1230
+	public static function create_upload_directories()
1231
+	{
1232
+		// Create the required folders
1233
+		$folders = array(
1234
+			EVENT_ESPRESSO_TEMPLATE_DIR,
1235
+			EVENT_ESPRESSO_GATEWAY_DIR,
1236
+			EVENT_ESPRESSO_UPLOAD_DIR . 'logs/',
1237
+			EVENT_ESPRESSO_UPLOAD_DIR . 'css/',
1238
+			EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/',
1239
+		);
1240
+		foreach ($folders as $folder) {
1241
+			try {
1242
+				EEH_File::ensure_folder_exists_and_is_writable($folder);
1243
+				@ chmod($folder, 0755);
1244
+			} catch (EE_Error $e) {
1245
+				EE_Error::add_error(
1246
+					sprintf(
1247
+						__('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'),
1248
+						$folder,
1249
+						'<br />' . $e->getMessage()
1250
+					),
1251
+					__FILE__, __FUNCTION__, __LINE__
1252
+				);
1253
+				//indicate we'll need to fix this later
1254
+				update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
1255
+				return false;
1256
+			}
1257
+		}
1258
+		//just add the .htaccess file to the logs directory to begin with. Even if logging
1259
+		//is disabled, there might be activation errors recorded in there
1260
+		EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
1261
+		//remember EE's folders are all good
1262
+		delete_option(EEH_Activation::upload_directories_incomplete_option_name);
1263
+		return true;
1264
+	}
1265
+
1266
+	/**
1267
+	 * Whether the upload directories need to be fixed or not.
1268
+	 * If EE is installed but filesystem access isn't initially available,
1269
+	 * we need to get the user's filesystem credentials and THEN create them,
1270
+	 * so there might be period of time when EE is installed but its
1271
+	 * upload directories aren't available. This indicates such a state
1272
+	 *
1273
+	 * @return boolean
1274
+	 */
1275
+	public static function upload_directories_incomplete()
1276
+	{
1277
+		return get_option(EEH_Activation::upload_directories_incomplete_option_name, false);
1278
+	}
1279
+
1280
+
1281
+	/**
1282
+	 * generate_default_message_templates
1283
+	 *
1284
+	 * @static
1285
+	 * @throws EE_Error
1286
+	 * @return bool     true means new templates were created.
1287
+	 *                  false means no templates were created.
1288
+	 *                  This is NOT an error flag. To check for errors you will want
1289
+	 *                  to use either EE_Error or a try catch for an EE_Error exception.
1290
+	 */
1291
+	public static function generate_default_message_templates()
1292
+	{
1293
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1294
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1295
+		/*
1296 1296
          * This first method is taking care of ensuring any default messengers
1297 1297
          * that should be made active and have templates generated are done.
1298 1298
          */
1299
-        $new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1300
-            $message_resource_manager
1301
-        );
1302
-        /**
1303
-         * This method is verifying there are no NEW default message types
1304
-         * for ACTIVE messengers that need activated (and corresponding templates setup).
1305
-         */
1306
-        $new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1307
-            $message_resource_manager
1308
-        );
1309
-        //after all is done, let's persist these changes to the db.
1310
-        $message_resource_manager->update_has_activated_messengers_option();
1311
-        $message_resource_manager->update_active_messengers_option();
1312
-        // will return true if either of these are true.  Otherwise will return false.
1313
-        return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1314
-    }
1315
-
1316
-
1317
-
1318
-    /**
1319
-     * @param \EE_Message_Resource_Manager $message_resource_manager
1320
-     * @return array|bool
1321
-     * @throws \EE_Error
1322
-     */
1323
-    protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1324
-        EE_Message_Resource_Manager $message_resource_manager
1325
-    ) {
1326
-        /** @type EE_messenger[] $active_messengers */
1327
-        $active_messengers = $message_resource_manager->active_messengers();
1328
-        $installed_message_types = $message_resource_manager->installed_message_types();
1329
-        $templates_created = false;
1330
-        foreach ($active_messengers as $active_messenger) {
1331
-            $default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1332
-            $default_message_type_names_to_activate = array();
1333
-            // looping through each default message type reported by the messenger
1334
-            // and setup the actual message types to activate.
1335
-            foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1336
-                // if already active or has already been activated before we skip
1337
-                // (otherwise we might reactivate something user's intentionally deactivated.)
1338
-                // we also skip if the message type is not installed.
1339
-                if (
1340
-                    $message_resource_manager->has_message_type_been_activated_for_messenger(
1341
-                        $default_message_type_name_for_messenger,
1342
-                        $active_messenger->name
1343
-                    )
1344
-                    || $message_resource_manager->is_message_type_active_for_messenger(
1345
-                        $active_messenger->name,
1346
-                        $default_message_type_name_for_messenger
1347
-                    )
1348
-                    || ! isset($installed_message_types[$default_message_type_name_for_messenger])
1349
-                ) {
1350
-                    continue;
1351
-                }
1352
-                $default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1353
-            }
1354
-            //let's activate!
1355
-            $message_resource_manager->ensure_message_types_are_active(
1356
-                $default_message_type_names_to_activate,
1357
-                $active_messenger->name,
1358
-                false
1359
-            );
1360
-            //activate the templates for these message types
1361
-            if ( ! empty($default_message_type_names_to_activate)) {
1362
-                $templates_created = EEH_MSG_Template::generate_new_templates(
1363
-                    $active_messenger->name,
1364
-                    $default_message_type_names_for_messenger,
1365
-                    '',
1366
-                    true
1367
-                );
1368
-            }
1369
-        }
1370
-        return $templates_created;
1371
-    }
1372
-
1373
-
1374
-
1375
-    /**
1376
-     * This will activate and generate default messengers and default message types for those messengers.
1377
-     *
1378
-     * @param EE_message_Resource_Manager $message_resource_manager
1379
-     * @return array|bool  True means there were default messengers and message type templates generated.
1380
-     *                     False means that there were no templates generated
1381
-     *                     (which could simply mean there are no default message types for a messenger).
1382
-     * @throws EE_Error
1383
-     */
1384
-    protected static function _activate_and_generate_default_messengers_and_message_templates(
1385
-        EE_Message_Resource_Manager $message_resource_manager
1386
-    ) {
1387
-        /** @type EE_messenger[] $messengers_to_generate */
1388
-        $messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1389
-        $installed_message_types = $message_resource_manager->installed_message_types();
1390
-        $templates_generated = false;
1391
-        foreach ($messengers_to_generate as $messenger_to_generate) {
1392
-            $default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1393
-            //verify the default message types match an installed message type.
1394
-            foreach ($default_message_type_names_for_messenger as $key => $name) {
1395
-                if (
1396
-                    ! isset($installed_message_types[$name])
1397
-                    || $message_resource_manager->has_message_type_been_activated_for_messenger(
1398
-                        $name,
1399
-                        $messenger_to_generate->name
1400
-                    )
1401
-                ) {
1402
-                    unset($default_message_type_names_for_messenger[$key]);
1403
-                }
1404
-            }
1405
-            // in previous iterations, the active_messengers option in the db
1406
-            // needed updated before calling create templates. however with the changes this may not be necessary.
1407
-            // This comment is left here just in case we discover that we _do_ need to update before
1408
-            // passing off to create templates (after the refactor is done).
1409
-            // @todo remove this comment when determined not necessary.
1410
-            $message_resource_manager->activate_messenger(
1411
-                $messenger_to_generate->name,
1412
-                $default_message_type_names_for_messenger,
1413
-                false
1414
-            );
1415
-            //create any templates needing created (or will reactivate templates already generated as necessary).
1416
-            if ( ! empty($default_message_type_names_for_messenger)) {
1417
-                $templates_generated = EEH_MSG_Template::generate_new_templates(
1418
-                    $messenger_to_generate->name,
1419
-                    $default_message_type_names_for_messenger,
1420
-                    '',
1421
-                    true
1422
-                );
1423
-            }
1424
-        }
1425
-        return $templates_generated;
1426
-    }
1427
-
1428
-
1429
-    /**
1430
-     * This returns the default messengers to generate templates for on activation of EE.
1431
-     * It considers:
1432
-     * - whether a messenger is already active in the db.
1433
-     * - whether a messenger has been made active at any time in the past.
1434
-     *
1435
-     * @static
1436
-     * @param  EE_Message_Resource_Manager $message_resource_manager
1437
-     * @return EE_messenger[]
1438
-     */
1439
-    protected static function _get_default_messengers_to_generate_on_activation(
1440
-        EE_Message_Resource_Manager $message_resource_manager
1441
-    ) {
1442
-        $active_messengers    = $message_resource_manager->active_messengers();
1443
-        $installed_messengers = $message_resource_manager->installed_messengers();
1444
-        $has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1445
-
1446
-        $messengers_to_generate = array();
1447
-        foreach ($installed_messengers as $installed_messenger) {
1448
-            //if installed messenger is a messenger that should be activated on install
1449
-            //and is not already active
1450
-            //and has never been activated
1451
-            if (
1452
-                ! $installed_messenger->activate_on_install
1453
-                || isset($active_messengers[$installed_messenger->name])
1454
-                || isset($has_activated[$installed_messenger->name])
1455
-            ) {
1456
-                continue;
1457
-            }
1458
-            $messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1459
-        }
1460
-        return $messengers_to_generate;
1461
-    }
1462
-
1463
-
1464
-    /**
1465
-     * This simply validates active message types to ensure they actually match installed
1466
-     * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1467
-     * rows are set inactive.
1468
-     * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1469
-     * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1470
-     * are still handled in here.
1471
-     *
1472
-     * @since 4.3.1
1473
-     * @return void
1474
-     */
1475
-    public static function validate_messages_system()
1476
-    {
1477
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
1478
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1479
-        $message_resource_manager->validate_active_message_types_are_installed();
1480
-        do_action('AHEE__EEH_Activation__validate_messages_system');
1481
-    }
1482
-
1483
-
1484
-    /**
1485
-     * create_no_ticket_prices_array
1486
-     *
1487
-     * @access public
1488
-     * @static
1489
-     * @return void
1490
-     */
1491
-    public static function create_no_ticket_prices_array()
1492
-    {
1493
-        // this creates an array for tracking events that have no active ticket prices created
1494
-        // this allows us to warn admins of the situation so that it can be corrected
1495
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1496
-        if (! $espresso_no_ticket_prices) {
1497
-            add_option('ee_no_ticket_prices', array(), '', false);
1498
-        }
1499
-    }
1500
-
1501
-
1502
-    /**
1503
-     * plugin_deactivation
1504
-     *
1505
-     * @access public
1506
-     * @static
1507
-     * @return void
1508
-     */
1509
-    public static function plugin_deactivation()
1510
-    {
1511
-    }
1512
-
1513
-
1514
-    /**
1515
-     * Finds all our EE4 custom post types, and deletes them and their associated data
1516
-     * (like post meta or term relations)
1517
-     *
1518
-     * @global wpdb $wpdb
1519
-     * @throws \EE_Error
1520
-     */
1521
-    public static function delete_all_espresso_cpt_data()
1522
-    {
1523
-        global $wpdb;
1524
-        //get all the CPT post_types
1525
-        $ee_post_types = array();
1526
-        foreach (EE_Registry::instance()->non_abstract_db_models() as $model_name) {
1527
-            if (method_exists($model_name, 'instance')) {
1528
-                $model_obj = call_user_func(array($model_name, 'instance'));
1529
-                if ($model_obj instanceof EEM_CPT_Base) {
1530
-                    $ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1531
-                }
1532
-            }
1533
-        }
1534
-        //get all our CPTs
1535
-        $query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1536
-        $cpt_ids = $wpdb->get_col($query);
1537
-        //delete each post meta and term relations too
1538
-        foreach ($cpt_ids as $post_id) {
1539
-            wp_delete_post($post_id, true);
1540
-        }
1541
-    }
1542
-
1543
-    /**
1544
-     * Deletes all EE custom tables
1545
-     *
1546
-     * @return array
1547
-     */
1548
-    public static function drop_espresso_tables()
1549
-    {
1550
-        $tables = array();
1551
-        // load registry
1552
-        foreach (EE_Registry::instance()->non_abstract_db_models() as $model_name) {
1553
-            if (method_exists($model_name, 'instance')) {
1554
-                $model_obj = call_user_func(array($model_name, 'instance'));
1555
-                if ($model_obj instanceof EEM_Base) {
1556
-                    foreach ($model_obj->get_tables() as $table) {
1557
-                        if (strpos($table->get_table_name(), 'esp_')
1558
-                            &&
1559
-                            (
1560
-                                is_main_site()//main site? nuke them all
1561
-                                || ! $table->is_global()//not main site,but not global either. nuke it
1562
-                            )
1563
-                        ) {
1564
-                            $tables[] = $table->get_table_name();
1565
-                        }
1566
-                    }
1567
-                }
1568
-            }
1569
-        }
1570
-
1571
-        //there are some tables whose models were removed.
1572
-        //they should be removed when removing all EE core's data
1573
-        $tables_without_models = array(
1574
-            'esp_promotion',
1575
-            'esp_promotion_applied',
1576
-            'esp_promotion_object',
1577
-            'esp_promotion_rule',
1578
-            'esp_rule',
1579
-        );
1580
-        foreach ($tables_without_models as $table) {
1581
-            $tables[] = $table;
1582
-        }
1583
-        return \EEH_Activation::getTableManager()->dropTables($tables);
1584
-    }
1585
-
1586
-
1587
-
1588
-    /**
1589
-     * Drops all the tables mentioned in a single MYSQL query. Double-checks
1590
-     * each table name provided has a wpdb prefix attached, and that it exists.
1591
-     * Returns the list actually deleted
1592
-     *
1593
-     * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1594
-     * @global WPDB $wpdb
1595
-     * @param array $table_names
1596
-     * @return array of table names which we deleted
1597
-     */
1598
-    public static function drop_tables($table_names)
1599
-    {
1600
-        return \EEH_Activation::getTableManager()->dropTables($table_names);
1601
-    }
1602
-
1603
-
1604
-
1605
-    /**
1606
-     * plugin_uninstall
1607
-     *
1608
-     * @access public
1609
-     * @static
1610
-     * @param bool $remove_all
1611
-     * @return void
1612
-     */
1613
-    public static function delete_all_espresso_tables_and_data($remove_all = true)
1614
-    {
1615
-        global $wpdb;
1616
-        self::drop_espresso_tables();
1617
-        $wp_options_to_delete = array(
1618
-            'ee_no_ticket_prices'                => true,
1619
-            'ee_active_messengers'               => true,
1620
-            'ee_has_activated_messenger'         => true,
1621
-            'ee_flush_rewrite_rules'             => true,
1622
-            'ee_config'                          => false,
1623
-            'ee_data_migration_current_db_state' => true,
1624
-            'ee_data_migration_mapping_'         => false,
1625
-            'ee_data_migration_script_'          => false,
1626
-            'ee_data_migrations'                 => true,
1627
-            'ee_dms_map'                         => false,
1628
-            'ee_notices'                         => true,
1629
-            'lang_file_check_'                   => false,
1630
-            'ee_maintenance_mode'                => true,
1631
-            'ee_ueip_optin'                      => true,
1632
-            'ee_ueip_has_notified'               => true,
1633
-            'ee_plugin_activation_errors'        => true,
1634
-            'ee_id_mapping_from'                 => false,
1635
-            'espresso_persistent_admin_notices'  => true,
1636
-            'ee_encryption_key'                  => true,
1637
-            'pue_force_upgrade_'                 => false,
1638
-            'pue_json_error_'                    => false,
1639
-            'pue_install_key_'                   => false,
1640
-            'pue_verification_error_'            => false,
1641
-            'pu_dismissed_upgrade_'              => false,
1642
-            'external_updates-'                  => false,
1643
-            'ee_extra_data'                      => true,
1644
-            'ee_ssn_'                            => false,
1645
-            'ee_rss_'                            => false,
1646
-            'ee_rte_n_tx_'                       => false,
1647
-            'ee_pers_admin_notices'              => true,
1648
-            'ee_job_parameters_'                 => false,
1649
-            'ee_upload_directories_incomplete'   => true,
1650
-            'ee_verified_db_collations'          => true,
1651
-        );
1652
-        if (is_main_site()) {
1653
-            $wp_options_to_delete['ee_network_config'] = true;
1654
-        }
1655
-        $undeleted_options = array();
1656
-        foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1657
-            if ($no_wildcard) {
1658
-                if ( ! delete_option($option_name)) {
1659
-                    $undeleted_options[] = $option_name;
1660
-                }
1661
-            } else {
1662
-                $option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1663
-                foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1664
-                    if ( ! delete_option($option_name_from_wildcard)) {
1665
-                        $undeleted_options[] = $option_name_from_wildcard;
1666
-                    }
1667
-                }
1668
-            }
1669
-        }
1670
-        //also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1671
-        remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1672
-        if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1673
-            $db_update_sans_ee4 = array();
1674
-            foreach ($espresso_db_update as $version => $times_activated) {
1675
-                if ((string)$version[0] === '3') {//if its NON EE4
1676
-                    $db_update_sans_ee4[$version] = $times_activated;
1677
-                }
1678
-            }
1679
-            update_option('espresso_db_update', $db_update_sans_ee4);
1680
-        }
1681
-        $errors = '';
1682
-        if ( ! empty($undeleted_options)) {
1683
-            $errors .= sprintf(
1684
-                __('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1685
-                '<br/>',
1686
-                implode(',<br/>', $undeleted_options)
1687
-            );
1688
-        }
1689
-        if ( ! empty($errors)) {
1690
-            EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1691
-        }
1692
-    }
1693
-
1694
-    /**
1695
-     * Gets the mysql error code from the last used query by wpdb
1696
-     *
1697
-     * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1698
-     */
1699
-    public static function last_wpdb_error_code()
1700
-    {
1701
-        global $wpdb;
1702
-        if ($wpdb->use_mysqli) {
1703
-            return mysqli_errno($wpdb->dbh);
1704
-        } else {
1705
-            return mysql_errno($wpdb->dbh);
1706
-        }
1707
-    }
1708
-
1709
-    /**
1710
-     * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1711
-     *
1712
-     * @global wpdb  $wpdb
1713
-     * @deprecated instead use TableAnalysis::tableExists()
1714
-     * @param string $table_name with or without $wpdb->prefix
1715
-     * @return boolean
1716
-     */
1717
-    public static function table_exists($table_name)
1718
-    {
1719
-        return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1720
-    }
1721
-
1722
-    /**
1723
-     * Resets the cache on EEH_Activation
1724
-     */
1725
-    public static function reset()
1726
-    {
1727
-        self::$_default_creator_id                             = null;
1728
-        self::$_initialized_db_content_already_in_this_request = false;
1729
-    }
1299
+		$new_templates_created_for_messenger = self::_activate_and_generate_default_messengers_and_message_templates(
1300
+			$message_resource_manager
1301
+		);
1302
+		/**
1303
+		 * This method is verifying there are no NEW default message types
1304
+		 * for ACTIVE messengers that need activated (and corresponding templates setup).
1305
+		 */
1306
+		$new_templates_created_for_message_type = self::_activate_new_message_types_for_active_messengers_and_generate_default_templates(
1307
+			$message_resource_manager
1308
+		);
1309
+		//after all is done, let's persist these changes to the db.
1310
+		$message_resource_manager->update_has_activated_messengers_option();
1311
+		$message_resource_manager->update_active_messengers_option();
1312
+		// will return true if either of these are true.  Otherwise will return false.
1313
+		return $new_templates_created_for_message_type || $new_templates_created_for_messenger;
1314
+	}
1315
+
1316
+
1317
+
1318
+	/**
1319
+	 * @param \EE_Message_Resource_Manager $message_resource_manager
1320
+	 * @return array|bool
1321
+	 * @throws \EE_Error
1322
+	 */
1323
+	protected static function _activate_new_message_types_for_active_messengers_and_generate_default_templates(
1324
+		EE_Message_Resource_Manager $message_resource_manager
1325
+	) {
1326
+		/** @type EE_messenger[] $active_messengers */
1327
+		$active_messengers = $message_resource_manager->active_messengers();
1328
+		$installed_message_types = $message_resource_manager->installed_message_types();
1329
+		$templates_created = false;
1330
+		foreach ($active_messengers as $active_messenger) {
1331
+			$default_message_type_names_for_messenger = $active_messenger->get_default_message_types();
1332
+			$default_message_type_names_to_activate = array();
1333
+			// looping through each default message type reported by the messenger
1334
+			// and setup the actual message types to activate.
1335
+			foreach ($default_message_type_names_for_messenger as $default_message_type_name_for_messenger) {
1336
+				// if already active or has already been activated before we skip
1337
+				// (otherwise we might reactivate something user's intentionally deactivated.)
1338
+				// we also skip if the message type is not installed.
1339
+				if (
1340
+					$message_resource_manager->has_message_type_been_activated_for_messenger(
1341
+						$default_message_type_name_for_messenger,
1342
+						$active_messenger->name
1343
+					)
1344
+					|| $message_resource_manager->is_message_type_active_for_messenger(
1345
+						$active_messenger->name,
1346
+						$default_message_type_name_for_messenger
1347
+					)
1348
+					|| ! isset($installed_message_types[$default_message_type_name_for_messenger])
1349
+				) {
1350
+					continue;
1351
+				}
1352
+				$default_message_type_names_to_activate[] = $default_message_type_name_for_messenger;
1353
+			}
1354
+			//let's activate!
1355
+			$message_resource_manager->ensure_message_types_are_active(
1356
+				$default_message_type_names_to_activate,
1357
+				$active_messenger->name,
1358
+				false
1359
+			);
1360
+			//activate the templates for these message types
1361
+			if ( ! empty($default_message_type_names_to_activate)) {
1362
+				$templates_created = EEH_MSG_Template::generate_new_templates(
1363
+					$active_messenger->name,
1364
+					$default_message_type_names_for_messenger,
1365
+					'',
1366
+					true
1367
+				);
1368
+			}
1369
+		}
1370
+		return $templates_created;
1371
+	}
1372
+
1373
+
1374
+
1375
+	/**
1376
+	 * This will activate and generate default messengers and default message types for those messengers.
1377
+	 *
1378
+	 * @param EE_message_Resource_Manager $message_resource_manager
1379
+	 * @return array|bool  True means there were default messengers and message type templates generated.
1380
+	 *                     False means that there were no templates generated
1381
+	 *                     (which could simply mean there are no default message types for a messenger).
1382
+	 * @throws EE_Error
1383
+	 */
1384
+	protected static function _activate_and_generate_default_messengers_and_message_templates(
1385
+		EE_Message_Resource_Manager $message_resource_manager
1386
+	) {
1387
+		/** @type EE_messenger[] $messengers_to_generate */
1388
+		$messengers_to_generate = self::_get_default_messengers_to_generate_on_activation($message_resource_manager);
1389
+		$installed_message_types = $message_resource_manager->installed_message_types();
1390
+		$templates_generated = false;
1391
+		foreach ($messengers_to_generate as $messenger_to_generate) {
1392
+			$default_message_type_names_for_messenger = $messenger_to_generate->get_default_message_types();
1393
+			//verify the default message types match an installed message type.
1394
+			foreach ($default_message_type_names_for_messenger as $key => $name) {
1395
+				if (
1396
+					! isset($installed_message_types[$name])
1397
+					|| $message_resource_manager->has_message_type_been_activated_for_messenger(
1398
+						$name,
1399
+						$messenger_to_generate->name
1400
+					)
1401
+				) {
1402
+					unset($default_message_type_names_for_messenger[$key]);
1403
+				}
1404
+			}
1405
+			// in previous iterations, the active_messengers option in the db
1406
+			// needed updated before calling create templates. however with the changes this may not be necessary.
1407
+			// This comment is left here just in case we discover that we _do_ need to update before
1408
+			// passing off to create templates (after the refactor is done).
1409
+			// @todo remove this comment when determined not necessary.
1410
+			$message_resource_manager->activate_messenger(
1411
+				$messenger_to_generate->name,
1412
+				$default_message_type_names_for_messenger,
1413
+				false
1414
+			);
1415
+			//create any templates needing created (or will reactivate templates already generated as necessary).
1416
+			if ( ! empty($default_message_type_names_for_messenger)) {
1417
+				$templates_generated = EEH_MSG_Template::generate_new_templates(
1418
+					$messenger_to_generate->name,
1419
+					$default_message_type_names_for_messenger,
1420
+					'',
1421
+					true
1422
+				);
1423
+			}
1424
+		}
1425
+		return $templates_generated;
1426
+	}
1427
+
1428
+
1429
+	/**
1430
+	 * This returns the default messengers to generate templates for on activation of EE.
1431
+	 * It considers:
1432
+	 * - whether a messenger is already active in the db.
1433
+	 * - whether a messenger has been made active at any time in the past.
1434
+	 *
1435
+	 * @static
1436
+	 * @param  EE_Message_Resource_Manager $message_resource_manager
1437
+	 * @return EE_messenger[]
1438
+	 */
1439
+	protected static function _get_default_messengers_to_generate_on_activation(
1440
+		EE_Message_Resource_Manager $message_resource_manager
1441
+	) {
1442
+		$active_messengers    = $message_resource_manager->active_messengers();
1443
+		$installed_messengers = $message_resource_manager->installed_messengers();
1444
+		$has_activated        = $message_resource_manager->get_has_activated_messengers_option();
1445
+
1446
+		$messengers_to_generate = array();
1447
+		foreach ($installed_messengers as $installed_messenger) {
1448
+			//if installed messenger is a messenger that should be activated on install
1449
+			//and is not already active
1450
+			//and has never been activated
1451
+			if (
1452
+				! $installed_messenger->activate_on_install
1453
+				|| isset($active_messengers[$installed_messenger->name])
1454
+				|| isset($has_activated[$installed_messenger->name])
1455
+			) {
1456
+				continue;
1457
+			}
1458
+			$messengers_to_generate[$installed_messenger->name] = $installed_messenger;
1459
+		}
1460
+		return $messengers_to_generate;
1461
+	}
1462
+
1463
+
1464
+	/**
1465
+	 * This simply validates active message types to ensure they actually match installed
1466
+	 * message types.  If there's a mismatch then we deactivate the message type and ensure all related db
1467
+	 * rows are set inactive.
1468
+	 * Note: Messengers are no longer validated here as of 4.9.0 because they get validated automatically whenever
1469
+	 * EE_Messenger_Resource_Manager is constructed.  Message Types are a bit more resource heavy for validation so they
1470
+	 * are still handled in here.
1471
+	 *
1472
+	 * @since 4.3.1
1473
+	 * @return void
1474
+	 */
1475
+	public static function validate_messages_system()
1476
+	{
1477
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
1478
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
1479
+		$message_resource_manager->validate_active_message_types_are_installed();
1480
+		do_action('AHEE__EEH_Activation__validate_messages_system');
1481
+	}
1482
+
1483
+
1484
+	/**
1485
+	 * create_no_ticket_prices_array
1486
+	 *
1487
+	 * @access public
1488
+	 * @static
1489
+	 * @return void
1490
+	 */
1491
+	public static function create_no_ticket_prices_array()
1492
+	{
1493
+		// this creates an array for tracking events that have no active ticket prices created
1494
+		// this allows us to warn admins of the situation so that it can be corrected
1495
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', false);
1496
+		if (! $espresso_no_ticket_prices) {
1497
+			add_option('ee_no_ticket_prices', array(), '', false);
1498
+		}
1499
+	}
1500
+
1501
+
1502
+	/**
1503
+	 * plugin_deactivation
1504
+	 *
1505
+	 * @access public
1506
+	 * @static
1507
+	 * @return void
1508
+	 */
1509
+	public static function plugin_deactivation()
1510
+	{
1511
+	}
1512
+
1513
+
1514
+	/**
1515
+	 * Finds all our EE4 custom post types, and deletes them and their associated data
1516
+	 * (like post meta or term relations)
1517
+	 *
1518
+	 * @global wpdb $wpdb
1519
+	 * @throws \EE_Error
1520
+	 */
1521
+	public static function delete_all_espresso_cpt_data()
1522
+	{
1523
+		global $wpdb;
1524
+		//get all the CPT post_types
1525
+		$ee_post_types = array();
1526
+		foreach (EE_Registry::instance()->non_abstract_db_models() as $model_name) {
1527
+			if (method_exists($model_name, 'instance')) {
1528
+				$model_obj = call_user_func(array($model_name, 'instance'));
1529
+				if ($model_obj instanceof EEM_CPT_Base) {
1530
+					$ee_post_types[] = $wpdb->prepare("%s", $model_obj->post_type());
1531
+				}
1532
+			}
1533
+		}
1534
+		//get all our CPTs
1535
+		$query   = "SELECT ID FROM {$wpdb->posts} WHERE post_type IN (" . implode(",", $ee_post_types) . ")";
1536
+		$cpt_ids = $wpdb->get_col($query);
1537
+		//delete each post meta and term relations too
1538
+		foreach ($cpt_ids as $post_id) {
1539
+			wp_delete_post($post_id, true);
1540
+		}
1541
+	}
1542
+
1543
+	/**
1544
+	 * Deletes all EE custom tables
1545
+	 *
1546
+	 * @return array
1547
+	 */
1548
+	public static function drop_espresso_tables()
1549
+	{
1550
+		$tables = array();
1551
+		// load registry
1552
+		foreach (EE_Registry::instance()->non_abstract_db_models() as $model_name) {
1553
+			if (method_exists($model_name, 'instance')) {
1554
+				$model_obj = call_user_func(array($model_name, 'instance'));
1555
+				if ($model_obj instanceof EEM_Base) {
1556
+					foreach ($model_obj->get_tables() as $table) {
1557
+						if (strpos($table->get_table_name(), 'esp_')
1558
+							&&
1559
+							(
1560
+								is_main_site()//main site? nuke them all
1561
+								|| ! $table->is_global()//not main site,but not global either. nuke it
1562
+							)
1563
+						) {
1564
+							$tables[] = $table->get_table_name();
1565
+						}
1566
+					}
1567
+				}
1568
+			}
1569
+		}
1570
+
1571
+		//there are some tables whose models were removed.
1572
+		//they should be removed when removing all EE core's data
1573
+		$tables_without_models = array(
1574
+			'esp_promotion',
1575
+			'esp_promotion_applied',
1576
+			'esp_promotion_object',
1577
+			'esp_promotion_rule',
1578
+			'esp_rule',
1579
+		);
1580
+		foreach ($tables_without_models as $table) {
1581
+			$tables[] = $table;
1582
+		}
1583
+		return \EEH_Activation::getTableManager()->dropTables($tables);
1584
+	}
1585
+
1586
+
1587
+
1588
+	/**
1589
+	 * Drops all the tables mentioned in a single MYSQL query. Double-checks
1590
+	 * each table name provided has a wpdb prefix attached, and that it exists.
1591
+	 * Returns the list actually deleted
1592
+	 *
1593
+	 * @deprecated in 4.9.13. Instead use TableManager::dropTables()
1594
+	 * @global WPDB $wpdb
1595
+	 * @param array $table_names
1596
+	 * @return array of table names which we deleted
1597
+	 */
1598
+	public static function drop_tables($table_names)
1599
+	{
1600
+		return \EEH_Activation::getTableManager()->dropTables($table_names);
1601
+	}
1602
+
1603
+
1604
+
1605
+	/**
1606
+	 * plugin_uninstall
1607
+	 *
1608
+	 * @access public
1609
+	 * @static
1610
+	 * @param bool $remove_all
1611
+	 * @return void
1612
+	 */
1613
+	public static function delete_all_espresso_tables_and_data($remove_all = true)
1614
+	{
1615
+		global $wpdb;
1616
+		self::drop_espresso_tables();
1617
+		$wp_options_to_delete = array(
1618
+			'ee_no_ticket_prices'                => true,
1619
+			'ee_active_messengers'               => true,
1620
+			'ee_has_activated_messenger'         => true,
1621
+			'ee_flush_rewrite_rules'             => true,
1622
+			'ee_config'                          => false,
1623
+			'ee_data_migration_current_db_state' => true,
1624
+			'ee_data_migration_mapping_'         => false,
1625
+			'ee_data_migration_script_'          => false,
1626
+			'ee_data_migrations'                 => true,
1627
+			'ee_dms_map'                         => false,
1628
+			'ee_notices'                         => true,
1629
+			'lang_file_check_'                   => false,
1630
+			'ee_maintenance_mode'                => true,
1631
+			'ee_ueip_optin'                      => true,
1632
+			'ee_ueip_has_notified'               => true,
1633
+			'ee_plugin_activation_errors'        => true,
1634
+			'ee_id_mapping_from'                 => false,
1635
+			'espresso_persistent_admin_notices'  => true,
1636
+			'ee_encryption_key'                  => true,
1637
+			'pue_force_upgrade_'                 => false,
1638
+			'pue_json_error_'                    => false,
1639
+			'pue_install_key_'                   => false,
1640
+			'pue_verification_error_'            => false,
1641
+			'pu_dismissed_upgrade_'              => false,
1642
+			'external_updates-'                  => false,
1643
+			'ee_extra_data'                      => true,
1644
+			'ee_ssn_'                            => false,
1645
+			'ee_rss_'                            => false,
1646
+			'ee_rte_n_tx_'                       => false,
1647
+			'ee_pers_admin_notices'              => true,
1648
+			'ee_job_parameters_'                 => false,
1649
+			'ee_upload_directories_incomplete'   => true,
1650
+			'ee_verified_db_collations'          => true,
1651
+		);
1652
+		if (is_main_site()) {
1653
+			$wp_options_to_delete['ee_network_config'] = true;
1654
+		}
1655
+		$undeleted_options = array();
1656
+		foreach ($wp_options_to_delete as $option_name => $no_wildcard) {
1657
+			if ($no_wildcard) {
1658
+				if ( ! delete_option($option_name)) {
1659
+					$undeleted_options[] = $option_name;
1660
+				}
1661
+			} else {
1662
+				$option_names_to_delete_from_wildcard = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%$option_name%'");
1663
+				foreach ($option_names_to_delete_from_wildcard as $option_name_from_wildcard) {
1664
+					if ( ! delete_option($option_name_from_wildcard)) {
1665
+						$undeleted_options[] = $option_name_from_wildcard;
1666
+					}
1667
+				}
1668
+			}
1669
+		}
1670
+		//also, let's make sure the "ee_config_option_names" wp option stays out by removing the action that adds it
1671
+		remove_action('shutdown', array(EE_Config::instance(), 'shutdown'), 10);
1672
+		if ($remove_all && $espresso_db_update = get_option('espresso_db_update')) {
1673
+			$db_update_sans_ee4 = array();
1674
+			foreach ($espresso_db_update as $version => $times_activated) {
1675
+				if ((string)$version[0] === '3') {//if its NON EE4
1676
+					$db_update_sans_ee4[$version] = $times_activated;
1677
+				}
1678
+			}
1679
+			update_option('espresso_db_update', $db_update_sans_ee4);
1680
+		}
1681
+		$errors = '';
1682
+		if ( ! empty($undeleted_options)) {
1683
+			$errors .= sprintf(
1684
+				__('The following wp-options could not be deleted: %s%s', 'event_espresso'),
1685
+				'<br/>',
1686
+				implode(',<br/>', $undeleted_options)
1687
+			);
1688
+		}
1689
+		if ( ! empty($errors)) {
1690
+			EE_Error::add_attention($errors, __FILE__, __FUNCTION__, __LINE__);
1691
+		}
1692
+	}
1693
+
1694
+	/**
1695
+	 * Gets the mysql error code from the last used query by wpdb
1696
+	 *
1697
+	 * @return int mysql error code, see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
1698
+	 */
1699
+	public static function last_wpdb_error_code()
1700
+	{
1701
+		global $wpdb;
1702
+		if ($wpdb->use_mysqli) {
1703
+			return mysqli_errno($wpdb->dbh);
1704
+		} else {
1705
+			return mysql_errno($wpdb->dbh);
1706
+		}
1707
+	}
1708
+
1709
+	/**
1710
+	 * Checks that the database table exists. Also works on temporary tables (for unit tests mostly).
1711
+	 *
1712
+	 * @global wpdb  $wpdb
1713
+	 * @deprecated instead use TableAnalysis::tableExists()
1714
+	 * @param string $table_name with or without $wpdb->prefix
1715
+	 * @return boolean
1716
+	 */
1717
+	public static function table_exists($table_name)
1718
+	{
1719
+		return \EEH_Activation::getTableAnalysis()->tableExists($table_name);
1720
+	}
1721
+
1722
+	/**
1723
+	 * Resets the cache on EEH_Activation
1724
+	 */
1725
+	public static function reset()
1726
+	{
1727
+		self::$_default_creator_id                             = null;
1728
+		self::$_initialized_db_content_already_in_this_request = false;
1729
+	}
1730 1730
 }
1731 1731
 // End of file EEH_Activation.helper.php
1732 1732
 // Location: /helpers/EEH_Activation.core.php
Please login to merge, or discard this patch.
core/data_migration_scripts/EE_DMS_Core_4_9_0.dms.php 1 patch
Indentation   +278 added lines, -278 removed lines patch added patch discarded remove patch
@@ -12,9 +12,9 @@  discard block
 block discarded – undo
12 12
 $stages = glob(EE_CORE . 'data_migration_scripts/4_9_0_stages/*');
13 13
 $class_to_filepath = array();
14 14
 foreach ($stages as $filepath) {
15
-    $matches = array();
16
-    preg_match('~4_9_0_stages/(.*).dmsstage.php~', $filepath, $matches);
17
-    $class_to_filepath[$matches[1]] = $filepath;
15
+	$matches = array();
16
+	preg_match('~4_9_0_stages/(.*).dmsstage.php~', $filepath, $matches);
17
+	$class_to_filepath[$matches[1]] = $filepath;
18 18
 }
19 19
 //give addons a chance to autoload their stages too
20 20
 $class_to_filepath = apply_filters('FHEE__EE_DMS_4_9_0__autoloaded_stages', $class_to_filepath);
@@ -33,68 +33,68 @@  discard block
 block discarded – undo
33 33
 class EE_DMS_Core_4_9_0 extends EE_Data_Migration_Script_Base
34 34
 {
35 35
 
36
-    /**
37
-     * return EE_DMS_Core_4_9_0
38
-     *
39
-     * @param TableManager  $table_manager
40
-     * @param TableAnalysis $table_analysis
41
-     */
42
-    public function __construct(TableManager $table_manager = null, TableAnalysis $table_analysis = null)
43
-    {
44
-        $this->_pretty_name = esc_html__("Data Update to Event Espresso 4.9.0", "event_espresso");
45
-        $this->_priority = 10;
46
-        $this->_migration_stages = array(
47
-            new EE_DMS_4_9_0_Email_System_Question(),
48
-            new EE_DMS_4_9_0_Answers_With_No_Registration(),
49
-        );
50
-        parent::__construct($table_manager, $table_analysis);
51
-    }
36
+	/**
37
+	 * return EE_DMS_Core_4_9_0
38
+	 *
39
+	 * @param TableManager  $table_manager
40
+	 * @param TableAnalysis $table_analysis
41
+	 */
42
+	public function __construct(TableManager $table_manager = null, TableAnalysis $table_analysis = null)
43
+	{
44
+		$this->_pretty_name = esc_html__("Data Update to Event Espresso 4.9.0", "event_espresso");
45
+		$this->_priority = 10;
46
+		$this->_migration_stages = array(
47
+			new EE_DMS_4_9_0_Email_System_Question(),
48
+			new EE_DMS_4_9_0_Answers_With_No_Registration(),
49
+		);
50
+		parent::__construct($table_manager, $table_analysis);
51
+	}
52 52
 
53 53
 
54 54
 
55
-    /**
56
-     * Whether to migrate or not.
57
-     *
58
-     * @param array $version_array
59
-     * @return bool
60
-     */
61
-    public function can_migrate_from_version($version_array)
62
-    {
63
-        $version_string = $version_array['Core'];
64
-        if (version_compare($version_string, '4.9.0', '<=') && version_compare($version_string, '4.8.0', '>=')) {
65
-            //			echo "$version_string can be migrated from";
66
-            return true;
67
-        } elseif ( ! $version_string) {
68
-            //			echo "no version string provided: $version_string";
69
-            //no version string provided... this must be pre 4.3
70
-            return false;//changed mind. dont want people thinking they should migrate yet because they cant
71
-        } else {
72
-            //			echo "$version_string doesnt apply";
73
-            return false;
74
-        }
75
-    }
55
+	/**
56
+	 * Whether to migrate or not.
57
+	 *
58
+	 * @param array $version_array
59
+	 * @return bool
60
+	 */
61
+	public function can_migrate_from_version($version_array)
62
+	{
63
+		$version_string = $version_array['Core'];
64
+		if (version_compare($version_string, '4.9.0', '<=') && version_compare($version_string, '4.8.0', '>=')) {
65
+			//			echo "$version_string can be migrated from";
66
+			return true;
67
+		} elseif ( ! $version_string) {
68
+			//			echo "no version string provided: $version_string";
69
+			//no version string provided... this must be pre 4.3
70
+			return false;//changed mind. dont want people thinking they should migrate yet because they cant
71
+		} else {
72
+			//			echo "$version_string doesnt apply";
73
+			return false;
74
+		}
75
+	}
76 76
 
77 77
 
78 78
 
79
-    /**
80
-     * @return bool
81
-     */
82
-    public function schema_changes_before_migration()
83
-    {
84
-        require_once(EE_HELPERS . 'EEH_Activation.helper.php');
85
-        $now_in_mysql = current_time('mysql', true);
86
-        $table_name = 'esp_answer';
87
-        $sql = " ANS_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
79
+	/**
80
+	 * @return bool
81
+	 */
82
+	public function schema_changes_before_migration()
83
+	{
84
+		require_once(EE_HELPERS . 'EEH_Activation.helper.php');
85
+		$now_in_mysql = current_time('mysql', true);
86
+		$table_name = 'esp_answer';
87
+		$sql = " ANS_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
88 88
 					REG_ID int(10) unsigned NOT NULL,
89 89
 					QST_ID int(10) unsigned NOT NULL,
90 90
 					ANS_value text NOT NULL,
91 91
 					PRIMARY KEY  (ANS_ID),
92 92
 					KEY REG_ID (REG_ID),
93 93
 					KEY QST_ID (QST_ID)";
94
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
95
-        $table_name = 'esp_attendee_meta';
96
-        $this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'ATT_email');
97
-        $sql = "ATTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
94
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
95
+		$table_name = 'esp_attendee_meta';
96
+		$this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'ATT_email');
97
+		$sql = "ATTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
98 98
 				ATT_ID bigint(20) unsigned NOT NULL,
99 99
 				ATT_fname varchar(45) NOT NULL,
100 100
 				ATT_lname varchar(45) NOT NULL,
@@ -111,9 +111,9 @@  discard block
 block discarded – undo
111 111
 				KEY ATT_email (ATT_email(191)),
112 112
 				KEY ATT_lname (ATT_lname),
113 113
 				KEY ATT_fname (ATT_fname)";
114
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
115
-        $table_name = 'esp_checkin';
116
-        $sql = "CHK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
114
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
115
+		$table_name = 'esp_checkin';
116
+		$sql = "CHK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
117 117
 				REG_ID int(10) unsigned NOT NULL,
118 118
 				DTT_ID int(10) unsigned NOT NULL,
119 119
 				CHK_in tinyint(1) unsigned NOT NULL DEFAULT 1,
@@ -121,9 +121,9 @@  discard block
 block discarded – undo
121 121
 				PRIMARY KEY  (CHK_ID),
122 122
 				KEY REG_ID (REG_ID),
123 123
 				KEY DTT_ID (DTT_ID)";
124
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
125
-        $table_name = 'esp_country';
126
-        $sql = "CNT_ISO varchar(2) NOT NULL,
124
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
125
+		$table_name = 'esp_country';
126
+		$sql = "CNT_ISO varchar(2) NOT NULL,
127 127
 				CNT_ISO3 varchar(3) NOT NULL,
128 128
 				RGN_ID tinyint(3) unsigned DEFAULT NULL,
129 129
 				CNT_name varchar(45) NOT NULL,
@@ -139,25 +139,25 @@  discard block
 block discarded – undo
139 139
 				CNT_is_EU tinyint(1) DEFAULT '0',
140 140
 				CNT_active tinyint(1) DEFAULT '0',
141 141
 				PRIMARY KEY  (CNT_ISO)";
142
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
143
-        $table_name = 'esp_currency';
144
-        $sql = "CUR_code varchar(6) NOT NULL,
142
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
143
+		$table_name = 'esp_currency';
144
+		$sql = "CUR_code varchar(6) NOT NULL,
145 145
 				CUR_single varchar(45) DEFAULT 'dollar',
146 146
 				CUR_plural varchar(45) DEFAULT 'dollars',
147 147
 				CUR_sign varchar(45) DEFAULT '$',
148 148
 				CUR_dec_plc varchar(1) NOT NULL DEFAULT '2',
149 149
 				CUR_active tinyint(1) DEFAULT '0',
150 150
 				PRIMARY KEY  (CUR_code)";
151
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
152
-        $table_name = 'esp_currency_payment_method';
153
-        $sql = "CPM_ID int(11) NOT NULL AUTO_INCREMENT,
151
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
152
+		$table_name = 'esp_currency_payment_method';
153
+		$sql = "CPM_ID int(11) NOT NULL AUTO_INCREMENT,
154 154
 				CUR_code varchar(6) NOT NULL,
155 155
 				PMD_ID int(11) NOT NULL,
156 156
 				PRIMARY KEY  (CPM_ID),
157 157
 				KEY PMD_ID (PMD_ID)";
158
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
159
-        $table_name = 'esp_datetime';
160
-        $sql = "DTT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
158
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
159
+		$table_name = 'esp_datetime';
160
+		$sql = "DTT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
161 161
 				EVT_ID bigint(20) unsigned NOT NULL,
162 162
 				DTT_name varchar(255) NOT NULL DEFAULT '',
163 163
 				DTT_description text NOT NULL,
@@ -174,25 +174,25 @@  discard block
 block discarded – undo
174 174
 				KEY DTT_EVT_start (DTT_EVT_start),
175 175
 				KEY EVT_ID (EVT_ID),
176 176
 				KEY DTT_is_primary (DTT_is_primary)";
177
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
178
-        $table_name = "esp_datetime_ticket";
179
-        $sql = "DTK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
177
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
178
+		$table_name = "esp_datetime_ticket";
179
+		$sql = "DTK_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
180 180
 				DTT_ID int(10) unsigned NOT NULL,
181 181
 				TKT_ID int(10) unsigned NOT NULL,
182 182
 				PRIMARY KEY  (DTK_ID),
183 183
 				KEY DTT_ID (DTT_ID),
184 184
 				KEY TKT_ID (TKT_ID)";
185
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
186
-        $table_name = 'esp_event_message_template';
187
-        $sql = "EMT_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
185
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
186
+		$table_name = 'esp_event_message_template';
187
+		$sql = "EMT_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
188 188
 				EVT_ID bigint(20) unsigned NOT NULL DEFAULT 0,
189 189
 				GRP_ID int(10) unsigned NOT NULL DEFAULT 0,
190 190
 				PRIMARY KEY  (EMT_ID),
191 191
 				KEY EVT_ID (EVT_ID),
192 192
 				KEY GRP_ID (GRP_ID)";
193
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
194
-        $table_name = 'esp_event_meta';
195
-        $sql = "EVTM_ID int(10) NOT NULL AUTO_INCREMENT,
193
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
194
+		$table_name = 'esp_event_meta';
195
+		$sql = "EVTM_ID int(10) NOT NULL AUTO_INCREMENT,
196 196
 				EVT_ID bigint(20) unsigned NOT NULL,
197 197
 				EVT_display_desc tinyint(1) unsigned NOT NULL DEFAULT 1,
198 198
 				EVT_display_ticket_selector tinyint(1) unsigned NOT NULL DEFAULT 1,
@@ -207,34 +207,34 @@  discard block
 block discarded – undo
207 207
 				EVT_donations tinyint(1) NULL,
208 208
 				PRIMARY KEY  (EVTM_ID),
209 209
 				KEY EVT_ID (EVT_ID)";
210
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
211
-        $table_name = 'esp_event_question_group';
212
-        $sql = "EQG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
210
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
211
+		$table_name = 'esp_event_question_group';
212
+		$sql = "EQG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
213 213
 				EVT_ID bigint(20) unsigned NOT NULL,
214 214
 				QSG_ID int(10) unsigned NOT NULL,
215 215
 				EQG_primary tinyint(1) unsigned NOT NULL DEFAULT 0,
216 216
 				PRIMARY KEY  (EQG_ID),
217 217
 				KEY EVT_ID (EVT_ID),
218 218
 				KEY QSG_ID (QSG_ID)";
219
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
220
-        $table_name = 'esp_event_venue';
221
-        $sql = "EVV_ID int(11) NOT NULL AUTO_INCREMENT,
219
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
220
+		$table_name = 'esp_event_venue';
221
+		$sql = "EVV_ID int(11) NOT NULL AUTO_INCREMENT,
222 222
 				EVT_ID bigint(20) unsigned NOT NULL,
223 223
 				VNU_ID bigint(20) unsigned NOT NULL,
224 224
 				EVV_primary tinyint(1) unsigned NOT NULL DEFAULT 0,
225 225
 				PRIMARY KEY  (EVV_ID)";
226
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
227
-        $table_name = 'esp_extra_meta';
228
-        $sql = "EXM_ID int(11) NOT NULL AUTO_INCREMENT,
226
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
227
+		$table_name = 'esp_extra_meta';
228
+		$sql = "EXM_ID int(11) NOT NULL AUTO_INCREMENT,
229 229
 				OBJ_ID int(11) DEFAULT NULL,
230 230
 				EXM_type varchar(45) DEFAULT NULL,
231 231
 				EXM_key varchar(45) DEFAULT NULL,
232 232
 				EXM_value text,
233 233
 				PRIMARY KEY  (EXM_ID),
234 234
 				KEY EXM_type (EXM_type,OBJ_ID,EXM_key)";
235
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
236
-        $table_name = 'esp_extra_join';
237
-        $sql = "EXJ_ID int(11) NOT NULL AUTO_INCREMENT,
235
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
236
+		$table_name = 'esp_extra_join';
237
+		$sql = "EXJ_ID int(11) NOT NULL AUTO_INCREMENT,
238 238
 				EXJ_first_model_id varchar(6) NOT NULL,
239 239
 				EXJ_first_model_name varchar(20) NOT NULL,
240 240
 				EXJ_second_model_id varchar(6) NOT NULL,
@@ -242,9 +242,9 @@  discard block
 block discarded – undo
242 242
 				PRIMARY KEY  (EXJ_ID),
243 243
 				KEY first_model (EXJ_first_model_name,EXJ_first_model_id),
244 244
 				KEY second_model (EXJ_second_model_name,EXJ_second_model_id)";
245
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
246
-        $table_name = 'esp_line_item';
247
-        $sql = "LIN_ID int(11) NOT NULL AUTO_INCREMENT,
245
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
246
+		$table_name = 'esp_line_item';
247
+		$sql = "LIN_ID int(11) NOT NULL AUTO_INCREMENT,
248 248
 				LIN_code varchar(245) NOT NULL DEFAULT '',
249 249
 				TXN_ID int(11) DEFAULT NULL,
250 250
 				LIN_name varchar(245) NOT NULL DEFAULT '',
@@ -263,9 +263,9 @@  discard block
 block discarded – undo
263 263
 				PRIMARY KEY  (LIN_ID),
264 264
 				KEY LIN_code (LIN_code(191)),
265 265
 				KEY TXN_ID (TXN_ID)";
266
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
267
-        $table_name = 'esp_log';
268
-        $sql = "LOG_ID int(11) NOT NULL AUTO_INCREMENT,
266
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
267
+		$table_name = 'esp_log';
268
+		$sql = "LOG_ID int(11) NOT NULL AUTO_INCREMENT,
269 269
 				LOG_time datetime DEFAULT NULL,
270 270
 				OBJ_ID varchar(45) DEFAULT NULL,
271 271
 				OBJ_type varchar(45) DEFAULT NULL,
@@ -276,12 +276,12 @@  discard block
 block discarded – undo
276 276
 				KEY LOG_time (LOG_time),
277 277
 				KEY OBJ (OBJ_type,OBJ_ID),
278 278
 				KEY LOG_type (LOG_type)";
279
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
280
-        $table_name = 'esp_message';
281
-        $this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'MSG_to');
282
-        $this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'MSG_from');
283
-        $this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'MSG_subject');
284
-        $sql = "MSG_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
279
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
280
+		$table_name = 'esp_message';
281
+		$this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'MSG_to');
282
+		$this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'MSG_from');
283
+		$this->_get_table_manager()->dropIndexIfSizeNot($table_name, 'MSG_subject');
284
+		$sql = "MSG_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
285 285
 				GRP_ID int(10) unsigned NULL,
286 286
 				MSG_token varchar(255) NULL,
287 287
 				TXN_ID int(10) unsigned NULL,
@@ -313,18 +313,18 @@  discard block
 block discarded – undo
313 313
 				KEY STS_ID (STS_ID),
314 314
 				KEY MSG_created (MSG_created),
315 315
 				KEY MSG_modified (MSG_modified)";
316
-        $this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
317
-        $table_name = 'esp_message_template';
318
-        $sql = "MTP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
316
+		$this->_table_is_new_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
317
+		$table_name = 'esp_message_template';
318
+		$sql = "MTP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
319 319
 				GRP_ID int(10) unsigned NOT NULL,
320 320
 				MTP_context varchar(50) NOT NULL,
321 321
 				MTP_template_field varchar(30) NOT NULL,
322 322
 				MTP_content text NOT NULL,
323 323
 				PRIMARY KEY  (MTP_ID),
324 324
 				KEY GRP_ID (GRP_ID)";
325
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
326
-        $table_name = 'esp_message_template_group';
327
-        $sql = "GRP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
325
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
326
+		$table_name = 'esp_message_template_group';
327
+		$sql = "GRP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
328 328
 				MTP_user_id int(10) NOT NULL DEFAULT '1',
329 329
 				MTP_name varchar(245) NOT NULL DEFAULT '',
330 330
 				MTP_description varchar(245) NOT NULL DEFAULT '',
@@ -336,9 +336,9 @@  discard block
 block discarded – undo
336 336
 				MTP_is_active tinyint(1) NOT NULL DEFAULT '1',
337 337
 				PRIMARY KEY  (GRP_ID),
338 338
 				KEY MTP_user_id (MTP_user_id)";
339
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
340
-        $table_name = 'esp_payment';
341
-        $sql = "PAY_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
339
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
340
+		$table_name = 'esp_payment';
341
+		$sql = "PAY_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
342 342
 				TXN_ID int(10) unsigned DEFAULT NULL,
343 343
 				STS_ID varchar(3) DEFAULT NULL,
344 344
 				PAY_timestamp datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
@@ -355,9 +355,9 @@  discard block
 block discarded – undo
355 355
 				PRIMARY KEY  (PAY_ID),
356 356
 				KEY PAY_timestamp (PAY_timestamp),
357 357
 				KEY TXN_ID (TXN_ID)";
358
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
359
-        $table_name = 'esp_payment_method';
360
-        $sql = "PMD_ID int(11) NOT NULL AUTO_INCREMENT,
358
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
359
+		$table_name = 'esp_payment_method';
360
+		$sql = "PMD_ID int(11) NOT NULL AUTO_INCREMENT,
361 361
 				PMD_type varchar(124) DEFAULT NULL,
362 362
 				PMD_name varchar(255) DEFAULT NULL,
363 363
 				PMD_desc text,
@@ -373,24 +373,24 @@  discard block
 block discarded – undo
373 373
 				PRIMARY KEY  (PMD_ID),
374 374
 				UNIQUE KEY PMD_slug_UNIQUE (PMD_slug),
375 375
 				KEY PMD_type (PMD_type)";
376
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
377
-        $table_name = "esp_ticket_price";
378
-        $sql = "TKP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
376
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
377
+		$table_name = "esp_ticket_price";
378
+		$sql = "TKP_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
379 379
 				TKT_ID int(10) unsigned NOT NULL,
380 380
 				PRC_ID int(10) unsigned NOT NULL,
381 381
 				PRIMARY KEY  (TKP_ID),
382 382
 				KEY TKT_ID (TKT_ID),
383 383
 				KEY PRC_ID (PRC_ID)";
384
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
385
-        $table_name = "esp_ticket_template";
386
-        $sql = "TTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
384
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
385
+		$table_name = "esp_ticket_template";
386
+		$sql = "TTM_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
387 387
 				TTM_name varchar(45) NOT NULL,
388 388
 				TTM_description text,
389 389
 				TTM_file varchar(45),
390 390
 				PRIMARY KEY  (TTM_ID)";
391
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
392
-        $table_name = 'esp_question';
393
-        $sql = 'QST_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
391
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
392
+		$table_name = 'esp_question';
393
+		$sql = 'QST_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
394 394
 				QST_display_text text NOT NULL,
395 395
 				QST_admin_label varchar(255) NOT NULL,
396 396
 				QST_system varchar(25) DEFAULT NULL,
@@ -404,18 +404,18 @@  discard block
 block discarded – undo
404 404
 				QST_deleted tinyint(2) unsigned NOT NULL DEFAULT 0,
405 405
 				PRIMARY KEY  (QST_ID),
406 406
 				KEY QST_order (QST_order)';
407
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
408
-        $table_name = 'esp_question_group_question';
409
-        $sql = "QGQ_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
407
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
408
+		$table_name = 'esp_question_group_question';
409
+		$sql = "QGQ_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
410 410
 				QSG_ID int(10) unsigned NOT NULL,
411 411
 				QST_ID int(10) unsigned NOT NULL,
412 412
 				QGQ_order int(10) unsigned NOT NULL DEFAULT 0,
413 413
 				PRIMARY KEY  (QGQ_ID),
414 414
 				KEY QST_ID (QST_ID),
415 415
 				KEY QSG_ID_order (QSG_ID,QGQ_order)";
416
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
417
-        $table_name = 'esp_question_option';
418
-        $sql = "QSO_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
416
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
417
+		$table_name = 'esp_question_option';
418
+		$sql = "QSO_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
419 419
 				QSO_value varchar(255) NOT NULL,
420 420
 				QSO_desc text NOT NULL,
421 421
 				QST_ID int(10) unsigned NOT NULL,
@@ -425,9 +425,9 @@  discard block
 block discarded – undo
425 425
 				PRIMARY KEY  (QSO_ID),
426 426
 				KEY QST_ID (QST_ID),
427 427
 				KEY QSO_order (QSO_order)";
428
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
429
-        $table_name = 'esp_registration';
430
-        $sql = "REG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
428
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
429
+		$table_name = 'esp_registration';
430
+		$sql = "REG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
431 431
 				EVT_ID bigint(20) unsigned NOT NULL,
432 432
 				ATT_ID bigint(20) unsigned NOT NULL,
433 433
 				TXN_ID int(10) unsigned NOT NULL,
@@ -451,18 +451,18 @@  discard block
 block discarded – undo
451 451
 				KEY TKT_ID (TKT_ID),
452 452
 				KEY EVT_ID (EVT_ID),
453 453
 				KEY STS_ID (STS_ID)";
454
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
455
-        $table_name = 'esp_registration_payment';
456
-        $sql = "RPY_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
454
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
455
+		$table_name = 'esp_registration_payment';
456
+		$sql = "RPY_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
457 457
 					  REG_ID int(10) unsigned NOT NULL,
458 458
 					  PAY_ID int(10) unsigned NULL,
459 459
 					  RPY_amount decimal(12,3) NOT NULL DEFAULT '0.00',
460 460
 					  PRIMARY KEY  (RPY_ID),
461 461
 					  KEY REG_ID (REG_ID),
462 462
 					  KEY PAY_ID (PAY_ID)";
463
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
464
-        $table_name = 'esp_state';
465
-        $sql = "STA_ID smallint(5) unsigned NOT NULL AUTO_INCREMENT,
463
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB ');
464
+		$table_name = 'esp_state';
465
+		$sql = "STA_ID smallint(5) unsigned NOT NULL AUTO_INCREMENT,
466 466
 				CNT_ISO varchar(2) NOT NULL,
467 467
 				STA_abbrev varchar(24) NOT NULL,
468 468
 				STA_name varchar(100) NOT NULL,
@@ -470,9 +470,9 @@  discard block
 block discarded – undo
470 470
 				PRIMARY KEY  (STA_ID),
471 471
 				KEY STA_abbrev (STA_abbrev),
472 472
 				KEY CNT_ISO (CNT_ISO)";
473
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
474
-        $table_name = 'esp_status';
475
-        $sql = "STS_ID varchar(3) NOT NULL,
473
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
474
+		$table_name = 'esp_status';
475
+		$sql = "STS_ID varchar(3) NOT NULL,
476 476
 				STS_code varchar(45) NOT NULL,
477 477
 				STS_type varchar(45) NOT NULL,
478 478
 				STS_can_edit tinyint(1) NOT NULL DEFAULT 0,
@@ -480,9 +480,9 @@  discard block
 block discarded – undo
480 480
 				STS_open tinyint(1) NOT NULL DEFAULT 1,
481 481
 				UNIQUE KEY STS_ID_UNIQUE (STS_ID),
482 482
 				KEY STS_type (STS_type)";
483
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
484
-        $table_name = 'esp_transaction';
485
-        $sql = "TXN_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
483
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
484
+		$table_name = 'esp_transaction';
485
+		$sql = "TXN_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
486 486
 				TXN_timestamp datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
487 487
 				TXN_total decimal(12,3) DEFAULT '0.00',
488 488
 				TXN_paid decimal(12,3) NOT NULL DEFAULT '0.00',
@@ -494,9 +494,9 @@  discard block
 block discarded – undo
494 494
 				PRIMARY KEY  (TXN_ID),
495 495
 				KEY TXN_timestamp (TXN_timestamp),
496 496
 				KEY STS_ID (STS_ID)";
497
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
498
-        $table_name = 'esp_venue_meta';
499
-        $sql = "VNUM_ID int(11) NOT NULL AUTO_INCREMENT,
497
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
498
+		$table_name = 'esp_venue_meta';
499
+		$sql = "VNUM_ID int(11) NOT NULL AUTO_INCREMENT,
500 500
 			VNU_ID bigint(20) unsigned NOT NULL DEFAULT 0,
501 501
 			VNU_address varchar(255) DEFAULT NULL,
502 502
 			VNU_address2 varchar(255) DEFAULT NULL,
@@ -515,10 +515,10 @@  discard block
 block discarded – undo
515 515
 			KEY VNU_ID (VNU_ID),
516 516
 			KEY STA_ID (STA_ID),
517 517
 			KEY CNT_ISO (CNT_ISO)";
518
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
519
-        //modified tables
520
-        $table_name = "esp_price";
521
-        $sql = "PRC_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
518
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
519
+		//modified tables
520
+		$table_name = "esp_price";
521
+		$sql = "PRC_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
522 522
 				PRT_ID tinyint(3) unsigned NOT NULL,
523 523
 				PRC_amount decimal(12,3) NOT NULL DEFAULT '0.00',
524 524
 				PRC_name varchar(245) NOT NULL,
@@ -531,9 +531,9 @@  discard block
 block discarded – undo
531 531
 				PRC_parent int(10) unsigned DEFAULT 0,
532 532
 				PRIMARY KEY  (PRC_ID),
533 533
 				KEY PRT_ID (PRT_ID)";
534
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
535
-        $table_name = "esp_price_type";
536
-        $sql = "PRT_ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
534
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
535
+		$table_name = "esp_price_type";
536
+		$sql = "PRT_ID tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
537 537
 				PRT_name varchar(45) NOT NULL,
538 538
 				PBT_ID tinyint(3) unsigned NOT NULL DEFAULT '1',
539 539
 				PRT_is_percent tinyint(1) NOT NULL DEFAULT '0',
@@ -542,9 +542,9 @@  discard block
 block discarded – undo
542 542
 				PRT_deleted tinyint(1) NOT NULL DEFAULT '0',
543 543
 				UNIQUE KEY PRT_name_UNIQUE (PRT_name),
544 544
 				PRIMARY KEY  (PRT_ID)";
545
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
546
-        $table_name = "esp_ticket";
547
-        $sql = "TKT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
545
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB ');
546
+		$table_name = "esp_ticket";
547
+		$sql = "TKT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
548 548
 				TTM_ID int(10) unsigned NOT NULL,
549 549
 				TKT_name varchar(245) NOT NULL DEFAULT '',
550 550
 				TKT_description text NOT NULL,
@@ -567,9 +567,9 @@  discard block
 block discarded – undo
567 567
 				TKT_deleted tinyint(1) NOT NULL DEFAULT '0',
568 568
 				PRIMARY KEY  (TKT_ID),
569 569
 				KEY TKT_start_date (TKT_start_date)";
570
-        $this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
571
-        $table_name = 'esp_question_group';
572
-        $sql = 'QSG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
570
+		$this->_table_is_changed_in_this_version($table_name, $sql, 'ENGINE=InnoDB');
571
+		$table_name = 'esp_question_group';
572
+		$sql = 'QSG_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
573 573
 				QSG_name varchar(255) NOT NULL,
574 574
 				QSG_identifier varchar(100) NOT NULL,
575 575
 				QSG_desc text NULL,
@@ -582,138 +582,138 @@  discard block
 block discarded – undo
582 582
 				PRIMARY KEY  (QSG_ID),
583 583
 				UNIQUE KEY QSG_identifier_UNIQUE (QSG_identifier),
584 584
 				KEY QSG_order (QSG_order)';
585
-        $this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
586
-        /** @var EE_DMS_Core_4_1_0 $script_4_1_defaults */
587
-        $script_4_1_defaults = EE_Registry::instance()->load_dms('Core_4_1_0');
588
-        //(because many need to convert old string states to foreign keys into the states table)
589
-        $script_4_1_defaults->insert_default_states();
590
-        $script_4_1_defaults->insert_default_countries();
591
-        /** @var EE_DMS_Core_4_5_0 $script_4_5_defaults */
592
-        $script_4_5_defaults = EE_Registry::instance()->load_dms('Core_4_5_0');
593
-        $script_4_5_defaults->insert_default_price_types();
594
-        $script_4_5_defaults->insert_default_prices();
595
-        $script_4_5_defaults->insert_default_tickets();
596
-        /** @var EE_DMS_Core_4_6_0 $script_4_6_defaults */
597
-        $script_4_6_defaults = EE_Registry::instance()->load_dms('Core_4_6_0');
598
-        $script_4_6_defaults->add_default_admin_only_payments();
599
-        $script_4_6_defaults->insert_default_currencies();
600
-        /** @var EE_DMS_Core_4_8_0 $script_4_8_defaults */
601
-        $script_4_8_defaults = EE_Registry::instance()->load_dms('Core_4_8_0');
602
-        $script_4_8_defaults->verify_new_countries();
603
-        $script_4_8_defaults->verify_new_currencies();
604
-        $this->verify_db_collations();
605
-        $this->verify_db_collations_again();
606
-        return true;
607
-    }
585
+		$this->_table_has_not_changed_since_previous($table_name, $sql, 'ENGINE=InnoDB');
586
+		/** @var EE_DMS_Core_4_1_0 $script_4_1_defaults */
587
+		$script_4_1_defaults = EE_Registry::instance()->load_dms('Core_4_1_0');
588
+		//(because many need to convert old string states to foreign keys into the states table)
589
+		$script_4_1_defaults->insert_default_states();
590
+		$script_4_1_defaults->insert_default_countries();
591
+		/** @var EE_DMS_Core_4_5_0 $script_4_5_defaults */
592
+		$script_4_5_defaults = EE_Registry::instance()->load_dms('Core_4_5_0');
593
+		$script_4_5_defaults->insert_default_price_types();
594
+		$script_4_5_defaults->insert_default_prices();
595
+		$script_4_5_defaults->insert_default_tickets();
596
+		/** @var EE_DMS_Core_4_6_0 $script_4_6_defaults */
597
+		$script_4_6_defaults = EE_Registry::instance()->load_dms('Core_4_6_0');
598
+		$script_4_6_defaults->add_default_admin_only_payments();
599
+		$script_4_6_defaults->insert_default_currencies();
600
+		/** @var EE_DMS_Core_4_8_0 $script_4_8_defaults */
601
+		$script_4_8_defaults = EE_Registry::instance()->load_dms('Core_4_8_0');
602
+		$script_4_8_defaults->verify_new_countries();
603
+		$script_4_8_defaults->verify_new_currencies();
604
+		$this->verify_db_collations();
605
+		$this->verify_db_collations_again();
606
+		return true;
607
+	}
608 608
 
609 609
 
610 610
 
611
-    /**
612
-     * @return boolean
613
-     */
614
-    public function schema_changes_after_migration()
615
-    {
616
-        return true;
617
-    }
611
+	/**
612
+	 * @return boolean
613
+	 */
614
+	public function schema_changes_after_migration()
615
+	{
616
+		return true;
617
+	}
618 618
 
619 619
 
620 620
 
621
-    public function migration_page_hooks()
622
-    {
623
-    }
621
+	public function migration_page_hooks()
622
+	{
623
+	}
624 624
 
625 625
 
626 626
 
627
-    /**
628
-     * Verify all EE4 models' tables use utf8mb4 collation
629
-     *
630
-     * @return void
631
-     */
632
-    public function verify_db_collations()
633
-    {
634
-        if (get_option('ee_verified_db_collations', false)) {
635
-            return;
636
-        }
637
-        // grab tables from each model
638
-        $tables_to_check = array();
639
-        foreach (EE_Registry::instance()->non_abstract_db_models() as $model_name) {
640
-            if (method_exists($model_name, 'instance')) {
641
-                $model_obj = call_user_func(array($model_name, 'instance'));
642
-                if ($model_obj instanceof EEM_Base) {
643
-                    foreach ($model_obj->get_tables() as $table) {
644
-                        if (
645
-                            strpos($table->get_table_name(), 'esp_')
646
-                            && (is_main_site()//for main tables, verify global tables
647
-                                || ! $table->is_global()//if not the main site, then only verify non-global tables (avoid doubling up)
648
-                            )
649
-                            && function_exists('maybe_convert_table_to_utf8mb4')
650
-                        ) {
651
-                            $tables_to_check[] = $table->get_table_name();
652
-                        }
653
-                    }
654
-                }
655
-            }
656
-        }
657
-        //and let's just be sure these addons' tables get migrated too. They already get handled if their addons are active
658
-        //when this code is run, but not otherwise. Once we record what tables EE added, we'll be able to use that instead
659
-        //of hard-coding this
660
-        $addon_tables = array(
661
-            //mailchimp
662
-            'esp_event_mailchimp_list_group',
663
-            'esp_event_question_mailchimp_field',
664
-            //multisite
665
-            'esp_blog_meta',
666
-            //people
667
-            'esp_people_to_post',
668
-            //promotions
669
-            'esp_promotion',
670
-            'esp_promotion_object',
671
-        );
672
-        foreach ($addon_tables as $table_name) {
673
-                $tables_to_check[] = $table_name;
674
-        }
675
-        $this->_verify_db_collations_for_tables(array_unique($tables_to_check));
676
-        //ok and now let's remember this was done (without needing to check the db schemas all over again)
677
-        add_option('ee_verified_db_collations', true, null, 'no');
678
-        //seeing how this ran with the fix from 10435, no need to check again
679
-        add_option('ee_verified_db_collations_again',true,null,'no');
680
-    }
627
+	/**
628
+	 * Verify all EE4 models' tables use utf8mb4 collation
629
+	 *
630
+	 * @return void
631
+	 */
632
+	public function verify_db_collations()
633
+	{
634
+		if (get_option('ee_verified_db_collations', false)) {
635
+			return;
636
+		}
637
+		// grab tables from each model
638
+		$tables_to_check = array();
639
+		foreach (EE_Registry::instance()->non_abstract_db_models() as $model_name) {
640
+			if (method_exists($model_name, 'instance')) {
641
+				$model_obj = call_user_func(array($model_name, 'instance'));
642
+				if ($model_obj instanceof EEM_Base) {
643
+					foreach ($model_obj->get_tables() as $table) {
644
+						if (
645
+							strpos($table->get_table_name(), 'esp_')
646
+							&& (is_main_site()//for main tables, verify global tables
647
+								|| ! $table->is_global()//if not the main site, then only verify non-global tables (avoid doubling up)
648
+							)
649
+							&& function_exists('maybe_convert_table_to_utf8mb4')
650
+						) {
651
+							$tables_to_check[] = $table->get_table_name();
652
+						}
653
+					}
654
+				}
655
+			}
656
+		}
657
+		//and let's just be sure these addons' tables get migrated too. They already get handled if their addons are active
658
+		//when this code is run, but not otherwise. Once we record what tables EE added, we'll be able to use that instead
659
+		//of hard-coding this
660
+		$addon_tables = array(
661
+			//mailchimp
662
+			'esp_event_mailchimp_list_group',
663
+			'esp_event_question_mailchimp_field',
664
+			//multisite
665
+			'esp_blog_meta',
666
+			//people
667
+			'esp_people_to_post',
668
+			//promotions
669
+			'esp_promotion',
670
+			'esp_promotion_object',
671
+		);
672
+		foreach ($addon_tables as $table_name) {
673
+				$tables_to_check[] = $table_name;
674
+		}
675
+		$this->_verify_db_collations_for_tables(array_unique($tables_to_check));
676
+		//ok and now let's remember this was done (without needing to check the db schemas all over again)
677
+		add_option('ee_verified_db_collations', true, null, 'no');
678
+		//seeing how this ran with the fix from 10435, no need to check again
679
+		add_option('ee_verified_db_collations_again',true,null,'no');
680
+	}
681 681
 
682 682
 
683 683
 
684
-    /**
685
-     * Verifies DB collations because a bug was discovered on https://events.codebasehq.com/projects/event-espresso/tickets/10435
686
-     * which meant some DB collations might not have been updated
687
-     * @return void
688
-     */
689
-    public function verify_db_collations_again(){
690
-        if (get_option('ee_verified_db_collations_again', false)) {
691
-            return;
692
-        }
693
-        $tables_to_check = array(
694
-            'esp_attendee_meta',
695
-            'esp_message'
696
-        );
697
-        $this->_verify_db_collations_for_tables(array_unique($tables_to_check));
698
-        add_option('ee_verified_db_collations_again',true,null,'no');
699
-    }
684
+	/**
685
+	 * Verifies DB collations because a bug was discovered on https://events.codebasehq.com/projects/event-espresso/tickets/10435
686
+	 * which meant some DB collations might not have been updated
687
+	 * @return void
688
+	 */
689
+	public function verify_db_collations_again(){
690
+		if (get_option('ee_verified_db_collations_again', false)) {
691
+			return;
692
+		}
693
+		$tables_to_check = array(
694
+			'esp_attendee_meta',
695
+			'esp_message'
696
+		);
697
+		$this->_verify_db_collations_for_tables(array_unique($tables_to_check));
698
+		add_option('ee_verified_db_collations_again',true,null,'no');
699
+	}
700 700
 
701 701
 
702 702
 
703
-    /**
704
-     * Runs maybe_convert_table_to_utf8mb4 on the specified tables
705
-     * @param $tables_to_check
706
-     * @return boolean true if logic ran, false if it didn't
707
-     */
708
-    protected function _verify_db_collations_for_tables($tables_to_check)
709
-    {
710
-        foreach ($tables_to_check as $table_name) {
711
-            $table_name = $this->_table_analysis->ensureTableNameHasPrefix($table_name);
712
-            if ( ! apply_filters('FHEE__EE_DMS_Core_4_9_0__verify_db_collations__check_overridden', false, $table_name )
713
-                && $this->_get_table_analysis()->tableExists($table_name)
714
-            ) {
715
-                maybe_convert_table_to_utf8mb4($table_name);
716
-            }
717
-        }
718
-    }
703
+	/**
704
+	 * Runs maybe_convert_table_to_utf8mb4 on the specified tables
705
+	 * @param $tables_to_check
706
+	 * @return boolean true if logic ran, false if it didn't
707
+	 */
708
+	protected function _verify_db_collations_for_tables($tables_to_check)
709
+	{
710
+		foreach ($tables_to_check as $table_name) {
711
+			$table_name = $this->_table_analysis->ensureTableNameHasPrefix($table_name);
712
+			if ( ! apply_filters('FHEE__EE_DMS_Core_4_9_0__verify_db_collations__check_overridden', false, $table_name )
713
+				&& $this->_get_table_analysis()->tableExists($table_name)
714
+			) {
715
+				maybe_convert_table_to_utf8mb4($table_name);
716
+			}
717
+		}
718
+	}
719 719
 }
720 720
\ No newline at end of file
Please login to merge, or discard this patch.
core/db_models/EEM_Extra_Join.model.php 1 patch
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -21,26 +21,26 @@
 block discarded – undo
21 21
  * @since		 	   $VID:$
22 22
  *
23 23
  */
24
-if (!defined('EVENT_ESPRESSO_VERSION')) {
24
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
25 25
 	exit('No direct script access allowed');
26 26
 }
27 27
 
28
-class EEM_Extra_Join extends EEM_Base{
28
+class EEM_Extra_Join extends EEM_Base {
29 29
 	// private instance of the Extra Join object
30 30
 	protected static $_instance = NULL;
31 31
 	
32 32
 	public function __construct($timezone = NULL) {
33
-		$models_this_can_join = array_keys( EE_Registry::instance()->non_abstract_db_models() );
33
+		$models_this_can_join = array_keys(EE_Registry::instance()->non_abstract_db_models());
34 34
 		$this->_tables = array(
35
-			'Extra_Join' => new EE_Primary_Table( 'esp_extra_join', 'EXJ_ID' ),
35
+			'Extra_Join' => new EE_Primary_Table('esp_extra_join', 'EXJ_ID'),
36 36
 		);
37 37
 		$this->_fields = array(
38 38
 			'Extra_Join' => array(
39
-				'EXJ_ID' => new EE_Primary_Key_Int_Field( 'EXJ_ID', __( 'Extra Join ID', 'event_espresso' ) ),
40
-				'EXJ_first_model_ID' => new EE_Foreign_Key_String_Field( 'EXJ_first_model_ID', __( 'First Model ID', 'event_espresso' ), true, 0, $models_this_can_join ),
41
-				'EXJ_first_model_name' => new EE_Any_Foreign_Model_Name_Field( 'EXJ_first_model_name', __( 'First Model Name', 'event_espresso'), true, '', $models_this_can_join ),
42
-				'EXJ_second_model_ID' => new EE_Foreign_Key_String_Field( 'EXJ_second_model_ID', __( 'Second Model ID', 'event_espresso' ), true, 0, $models_this_can_join ),
43
-				'EXJ_second_model_name' => new EE_Any_Foreign_Model_Name_Field( 'EXJ_second_model_name', __( 'Second Model Name', 'event_espresso'), true, '', $models_this_can_join ),
39
+				'EXJ_ID' => new EE_Primary_Key_Int_Field('EXJ_ID', __('Extra Join ID', 'event_espresso')),
40
+				'EXJ_first_model_ID' => new EE_Foreign_Key_String_Field('EXJ_first_model_ID', __('First Model ID', 'event_espresso'), true, 0, $models_this_can_join),
41
+				'EXJ_first_model_name' => new EE_Any_Foreign_Model_Name_Field('EXJ_first_model_name', __('First Model Name', 'event_espresso'), true, '', $models_this_can_join),
42
+				'EXJ_second_model_ID' => new EE_Foreign_Key_String_Field('EXJ_second_model_ID', __('Second Model ID', 'event_espresso'), true, 0, $models_this_can_join),
43
+				'EXJ_second_model_name' => new EE_Any_Foreign_Model_Name_Field('EXJ_second_model_name', __('Second Model Name', 'event_espresso'), true, '', $models_this_can_join),
44 44
 				
45 45
 			)
46 46
 		);
Please login to merge, or discard this patch.
core/db_models/EEM_Change_Log.model.php 1 patch
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-if (!defined('EVENT_ESPRESSO_VERSION'))
3
+if ( ! defined('EVENT_ESPRESSO_VERSION'))
4 4
 	exit('No direct script access allowed');
5 5
 
6 6
 /**
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
  *
26 26
  * ------------------------------------------------------------------------
27 27
  */
28
-class EEM_Change_Log extends EEM_Base{
28
+class EEM_Change_Log extends EEM_Base {
29 29
 
30 30
 	/**
31 31
 	 * the related object was created log type
@@ -68,19 +68,19 @@  discard block
 block discarded – undo
68 68
 	 *	@access protected
69 69
 	 *	@return EEM_Change_Log
70 70
 	 */
71
-	protected function __construct( $timezone = null ){
71
+	protected function __construct($timezone = null) {
72 72
 		global $current_user;
73
-		$this->singular_item = __('Log','event_espresso');
74
-		$this->plural_item = __('Logs','event_espresso');
73
+		$this->singular_item = __('Log', 'event_espresso');
74
+		$this->plural_item = __('Logs', 'event_espresso');
75 75
 		$this->_tables = array(
76 76
 			'Log'=> new EE_Primary_Table('esp_log', 'LOG_ID')
77 77
 		);
78 78
 		$models_this_can_attach_to = array_keys(EE_Registry::instance()->non_abstract_db_models());
79 79
 		$this->_fields = array(
80 80
 			'Log'=>array(
81
-				'LOG_ID'=> new EE_Primary_Key_Int_Field('LOG_ID', __('Log ID','event_espresso')),
82
-				'LOG_time'=>new EE_Datetime_Field('LOG_time', __("Log Time", 'event_espresso'), false, EE_Datetime_Field::now ),
83
-				'OBJ_ID'=>new EE_Foreign_Key_String_Field('OBJ_ID', __("Object ID (int or string)", 'event_espresso'), true, NULL,$models_this_can_attach_to),
81
+				'LOG_ID'=> new EE_Primary_Key_Int_Field('LOG_ID', __('Log ID', 'event_espresso')),
82
+				'LOG_time'=>new EE_Datetime_Field('LOG_time', __("Log Time", 'event_espresso'), false, EE_Datetime_Field::now),
83
+				'OBJ_ID'=>new EE_Foreign_Key_String_Field('OBJ_ID', __("Object ID (int or string)", 'event_espresso'), true, NULL, $models_this_can_attach_to),
84 84
 				'OBJ_type'=>new EE_Any_Foreign_Model_Name_Field('OBJ_type', __("Object Type", 'event_espresso'), true, NULL, $models_this_can_attach_to),
85 85
 				'LOG_type'=>new EE_Enum_Text_Field('LOG_type', __("Type of log entry", "event_espresso"), false, self::type_debug,
86 86
 						array(
@@ -92,24 +92,24 @@  discard block
 block discarded – undo
92 92
 							self::type_gateway=> __("Gateway Interaction (IPN or Direct Payment)", 'event_espresso'),
93 93
 							)),
94 94
 				'LOG_message'=>new EE_Maybe_Serialized_Text_Field('LOG_message', __("Log Message (body)", 'event_espresso'), true),
95
-				'LOG_wp_user' => new EE_WP_User_Field('LOG_wp_user', __("User who was logged in while this occurred", 'event_espresso'), true ),
95
+				'LOG_wp_user' => new EE_WP_User_Field('LOG_wp_user', __("User who was logged in while this occurred", 'event_espresso'), true),
96 96
 
97 97
 			));
98 98
 		$this->_model_relations = array();
99
-		foreach($models_this_can_attach_to as $model){
100
-			if( $model == 'WP_User' ){
101
-				$this->_model_relations[ $model ] = new EE_Belongs_To_Relation();
102
-			}elseif( $model != 'Change_Log' ) {
99
+		foreach ($models_this_can_attach_to as $model) {
100
+			if ($model == 'WP_User') {
101
+				$this->_model_relations[$model] = new EE_Belongs_To_Relation();
102
+			}elseif ($model != 'Change_Log') {
103 103
 				$this->_model_relations[$model] = new EE_Belongs_To_Any_Relation();
104 104
 			}
105 105
 		}
106 106
 		//use completely custom caps for this
107 107
 		$this->_cap_restriction_generators = false;
108 108
 		//caps-wise this is all-or-nothing: if you have the default role you can access anything, otherwise nothing
109
-		foreach( $this->_cap_contexts_to_cap_action_map as $cap_context => $action ) {
110
-			$this->_cap_restrictions[ $cap_context ][ EE_Restriction_Generator_Base::get_default_restrictions_cap() ] = new EE_Return_None_Where_Conditions();
109
+		foreach ($this->_cap_contexts_to_cap_action_map as $cap_context => $action) {
110
+			$this->_cap_restrictions[$cap_context][EE_Restriction_Generator_Base::get_default_restrictions_cap()] = new EE_Return_None_Where_Conditions();
111 111
 		}
112
-		parent::__construct( $timezone );
112
+		parent::__construct($timezone);
113 113
 	}
114 114
 
115 115
 	/**
@@ -119,11 +119,11 @@  discard block
 block discarded – undo
119 119
 	 * @param EE_Base_Class $related_model_obj
120 120
 	 * @return EE_Change_Log
121 121
 	 */
122
-	public function log($log_type,$message,$related_model_obj){
123
-		if($related_model_obj instanceof EE_Base_Class){
122
+	public function log($log_type, $message, $related_model_obj) {
123
+		if ($related_model_obj instanceof EE_Base_Class) {
124 124
 			$obj_id = $related_model_obj->ID();
125 125
 			$obj_type = $related_model_obj->get_model()->get_this_model_name();
126
-		}else{
126
+		} else {
127 127
 			$obj_id = NULL;
128 128
 			$obj_type = NULL;
129 129
 		}
@@ -147,9 +147,9 @@  discard block
 block discarded – undo
147 147
 	 * @throws EE_Error
148 148
 	 * @return EE_Change_Log
149 149
 	 */
150
-	public function gateway_log( $message, $related_obj_id, $related_obj_type ){
151
-		if( ! EE_Registry::instance()->is_model_name($related_obj_type)){
152
-			throw new EE_Error(sprintf(__("'%s' is not a model name. A model name must be provided when making a gateway log. Eg, 'Payment', 'Payment_Method', etc", "event_espresso"),$related_obj_type));
150
+	public function gateway_log($message, $related_obj_id, $related_obj_type) {
151
+		if ( ! EE_Registry::instance()->is_model_name($related_obj_type)) {
152
+			throw new EE_Error(sprintf(__("'%s' is not a model name. A model name must be provided when making a gateway log. Eg, 'Payment', 'Payment_Method', etc", "event_espresso"), $related_obj_type));
153 153
 		}
154 154
 		$log = EE_Change_Log::new_instance(array(
155 155
 				'LOG_type'=>EEM_Change_Log::type_gateway,
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
 	 * @param array $query_params @see EEM_Base::get_all
169 169
 	 * @return array of arrays
170 170
 	 */
171
-	public function get_all_efficiently($query_params){
171
+	public function get_all_efficiently($query_params) {
172 172
 		return $this->_get_all_wpdb_results($query_params);
173 173
 	}
174 174
 
@@ -180,11 +180,11 @@  discard block
 block discarded – undo
180 180
      * @param DateTime $datetime
181 181
      * @return false|int
182 182
      */
183
-	public function delete_gateway_logs_older_than(DateTime $datetime ) {
183
+	public function delete_gateway_logs_older_than(DateTime $datetime) {
184 184
 	    global $wpdb;
185 185
         return $wpdb->query(
186 186
             $wpdb->prepare(
187
-                'DELETE FROM ' . $this->table() . ' WHERE LOG_type = %s AND LOG_time < %s',
187
+                'DELETE FROM '.$this->table().' WHERE LOG_type = %s AND LOG_time < %s',
188 188
                 EEM_Change_Log::type_gateway,
189 189
                 $datetime->format(EE_Datetime_Field::mysql_timestamp_format)
190 190
             )
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Indentation   +1423 added lines, -1423 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 use EventEspresso\core\services\shortcodes\ShortcodesManager;
3 3
 
4 4
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -19,1428 +19,1428 @@  discard block
 block discarded – undo
19 19
 {
20 20
 
21 21
 
22
-    /**
23
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
24
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
25
-     */
26
-    const req_type_normal = 0;
27
-
28
-    /**
29
-     * Indicates this is a brand new installation of EE so we should install
30
-     * tables and default data etc
31
-     */
32
-    const req_type_new_activation = 1;
33
-
34
-    /**
35
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
36
-     * and we just exited maintenance mode). We MUST check the database is setup properly
37
-     * and that default data is setup too
38
-     */
39
-    const req_type_reactivation = 2;
40
-
41
-    /**
42
-     * indicates that EE has been upgraded since its previous request.
43
-     * We may have data migration scripts to call and will want to trigger maintenance mode
44
-     */
45
-    const req_type_upgrade = 3;
46
-
47
-    /**
48
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
49
-     */
50
-    const req_type_downgrade = 4;
51
-
52
-    /**
53
-     * @deprecated since version 4.6.0.dev.006
54
-     * Now whenever a new_activation is detected the request type is still just
55
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
56
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
57
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
58
-     * (Specifically, when the migration manager indicates migrations are finished
59
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
60
-     */
61
-    const req_type_activation_but_not_installed = 5;
62
-
63
-    /**
64
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
65
-     */
66
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
67
-
68
-
69
-    /**
70
-     *    instance of the EE_System object
71
-     *
72
-     * @var    $_instance
73
-     * @access    private
74
-     */
75
-    private static $_instance = null;
76
-
77
-    /**
78
-     * @type  EE_Registry $Registry
79
-     * @access    protected
80
-     */
81
-    protected $registry;
82
-
83
-    /**
84
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
85
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
86
-     *
87
-     * @var int
88
-     */
89
-    private $_req_type;
90
-
91
-    /**
92
-     * Whether or not there was a non-micro version change in EE core version during this request
93
-     *
94
-     * @var boolean
95
-     */
96
-    private $_major_version_change = false;
97
-
98
-
99
-
100
-    /**
101
-     * @singleton method used to instantiate class object
102
-     * @access    public
103
-     * @param  \EE_Registry $Registry
104
-     * @return \EE_System
105
-     */
106
-    public static function instance(EE_Registry $Registry = null)
107
-    {
108
-        // check if class object is instantiated
109
-        if ( ! self::$_instance instanceof EE_System) {
110
-            self::$_instance = new self($Registry);
111
-        }
112
-        return self::$_instance;
113
-    }
114
-
115
-
116
-
117
-    /**
118
-     * resets the instance and returns it
119
-     *
120
-     * @return EE_System
121
-     */
122
-    public static function reset()
123
-    {
124
-        self::$_instance->_req_type = null;
125
-        //make sure none of the old hooks are left hanging around
126
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
127
-        //we need to reset the migration manager in order for it to detect DMSs properly
128
-        EE_Data_Migration_Manager::reset();
129
-        self::instance()->detect_activations_or_upgrades();
130
-        self::instance()->perform_activations_upgrades_and_migrations();
131
-        return self::instance();
132
-    }
133
-
134
-
135
-
136
-    /**
137
-     *    sets hooks for running rest of system
138
-     *    provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
139
-     *    starting EE Addons from any other point may lead to problems
140
-     *
141
-     * @access private
142
-     * @param  \EE_Registry $Registry
143
-     */
144
-    private function __construct(EE_Registry $Registry)
145
-    {
146
-        $this->registry = $Registry;
147
-        do_action('AHEE__EE_System__construct__begin', $this);
148
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
149
-        add_action('AHEE__EE_Bootstrap__load_espresso_addons', array($this, 'load_espresso_addons'));
150
-        // when an ee addon is activated, we want to call the core hook(s) again
151
-        // because the newly-activated addon didn't get a chance to run at all
152
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
153
-        // detect whether install or upgrade
154
-        add_action('AHEE__EE_Bootstrap__detect_activations_or_upgrades', array($this, 'detect_activations_or_upgrades'),
155
-            3);
156
-        // load EE_Config, EE_Textdomain, etc
157
-        add_action('AHEE__EE_Bootstrap__load_core_configuration', array($this, 'load_core_configuration'), 5);
158
-        // load EE_Config, EE_Textdomain, etc
159
-        add_action('AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
160
-            array($this, 'register_shortcodes_modules_and_widgets'), 7);
161
-        // you wanna get going? I wanna get going... let's get going!
162
-        add_action('AHEE__EE_Bootstrap__brew_espresso', array($this, 'brew_espresso'), 9);
163
-        //other housekeeping
164
-        //exclude EE critical pages from wp_list_pages
165
-        add_filter('wp_list_pages_excludes', array($this, 'remove_pages_from_wp_list_pages'), 10);
166
-        // ALL EE Addons should use the following hook point to attach their initial setup too
167
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
168
-        do_action('AHEE__EE_System__construct__complete', $this);
169
-    }
170
-
171
-
172
-
173
-    /**
174
-     * load_espresso_addons
175
-     * allow addons to load first so that they can set hooks for running DMS's, etc
176
-     * this is hooked into both:
177
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
178
-     *        which runs during the WP 'plugins_loaded' action at priority 5
179
-     *    and the WP 'activate_plugin' hookpoint
180
-     *
181
-     * @access public
182
-     * @return void
183
-     */
184
-    public function load_espresso_addons()
185
-    {
186
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
187
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
188
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
189
-        //load and setup EE_Capabilities
190
-        $this->registry->load_core('Capabilities');
191
-        do_action('AHEE__EE_System__load_espresso_addons');
192
-        //if the WP API basic auth plugin isn't already loaded, load it now.
193
-        //We want it for mobile apps. Just include the entire plugin
194
-        //also, don't load the basic auth when a plugin is getting activated, because
195
-        //it could be the basic auth plugin, and it doesn't check if its methods are already defined
196
-        //and causes a fatal error
197
-        if ( ! function_exists('json_basic_auth_handler')
198
-             && ! function_exists('json_basic_auth_error')
199
-             && ! (
200
-                isset($_GET['action'])
201
-                && in_array($_GET['action'], array('activate', 'activate-selected'))
202
-            )
203
-             && ! (
204
-                isset($_GET['activate'])
205
-                && $_GET['activate'] === 'true'
206
-            )
207
-        ) {
208
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
209
-        }
210
-        $this->_maybe_brew_regular();
211
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
212
-
213
-        //caps need to be initialized on every request so that capability maps are set.
214
-        //@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
215
-        $this->registry->CAP->init_caps();
216
-    }
217
-
218
-
219
-
220
-    /**
221
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
222
-     * that need to be setup before our EE_System launches.
223
-     *
224
-     * @return void
225
-     */
226
-    private function _maybe_brew_regular()
227
-    {
228
-        if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
229
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
230
-        }
231
-    }
232
-
233
-
234
-
235
-    /**
236
-     * detect_activations_or_upgrades
237
-     * Checks for activation or upgrade of core first;
238
-     * then also checks if any registered addons have been activated or upgraded
239
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
240
-     * which runs during the WP 'plugins_loaded' action at priority 3
241
-     *
242
-     * @access public
243
-     * @return void
244
-     */
245
-    public function detect_activations_or_upgrades()
246
-    {
247
-        //first off: let's make sure to handle core
248
-        $this->detect_if_activation_or_upgrade();
249
-        foreach ($this->registry->addons as $addon) {
250
-            //detect teh request type for that addon
251
-            $addon->detect_activation_or_upgrade();
252
-        }
253
-    }
254
-
255
-
256
-
257
-    /**
258
-     * detect_if_activation_or_upgrade
259
-     * Takes care of detecting whether this is a brand new install or code upgrade,
260
-     * and either setting up the DB or setting up maintenance mode etc.
261
-     *
262
-     * @access public
263
-     * @return void
264
-     */
265
-    public function detect_if_activation_or_upgrade()
266
-    {
267
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
268
-        // load M-Mode class
269
-        $this->registry->load_core('Maintenance_Mode');
270
-        // check if db has been updated, or if its a brand-new installation
271
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
272
-        $request_type = $this->detect_req_type($espresso_db_update);
273
-        //EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
274
-        switch ($request_type) {
275
-            case EE_System::req_type_new_activation:
276
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
277
-                $this->_handle_core_version_change($espresso_db_update);
278
-                break;
279
-            case EE_System::req_type_reactivation:
280
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
281
-                $this->_handle_core_version_change($espresso_db_update);
282
-                break;
283
-            case EE_System::req_type_upgrade:
284
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
285
-                //migrations may be required now that we've upgraded
286
-                EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
287
-                $this->_handle_core_version_change($espresso_db_update);
288
-                //				echo "done upgrade";die;
289
-                break;
290
-            case EE_System::req_type_downgrade:
291
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
292
-                //its possible migrations are no longer required
293
-                EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
294
-                $this->_handle_core_version_change($espresso_db_update);
295
-                break;
296
-            case EE_System::req_type_normal:
297
-            default:
298
-                //				$this->_maybe_redirect_to_ee_about();
299
-                break;
300
-        }
301
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
302
-    }
303
-
304
-
305
-
306
-    /**
307
-     * Updates the list of installed versions and sets hooks for
308
-     * initializing the database later during the request
309
-     *
310
-     * @param array $espresso_db_update
311
-     */
312
-    protected function _handle_core_version_change($espresso_db_update)
313
-    {
314
-        $this->update_list_of_installed_versions($espresso_db_update);
315
-        //get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
316
-        add_action('AHEE__EE_System__perform_activations_upgrades_and_migrations',
317
-            array($this, 'initialize_db_if_no_migrations_required'));
318
-    }
319
-
320
-
321
-
322
-    /**
323
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
324
-     * information about what versions of EE have been installed and activated,
325
-     * NOT necessarily the state of the database
326
-     *
327
-     * @param null $espresso_db_update
328
-     * @internal param array $espresso_db_update_value the value of the WordPress option. If not supplied, fetches it
329
-     *           from the options table
330
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
331
-     */
332
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
333
-    {
334
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
335
-        if ( ! $espresso_db_update) {
336
-            $espresso_db_update = get_option('espresso_db_update');
337
-        }
338
-        // check that option is an array
339
-        if ( ! is_array($espresso_db_update)) {
340
-            // if option is FALSE, then it never existed
341
-            if ($espresso_db_update === false) {
342
-                // make $espresso_db_update an array and save option with autoload OFF
343
-                $espresso_db_update = array();
344
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
345
-            } else {
346
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
347
-                $espresso_db_update = array($espresso_db_update => array());
348
-                update_option('espresso_db_update', $espresso_db_update);
349
-            }
350
-        } else {
351
-            $corrected_db_update = array();
352
-            //if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
353
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
354
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
355
-                    //the key is an int, and the value IS NOT an array
356
-                    //so it must be numerically-indexed, where values are versions installed...
357
-                    //fix it!
358
-                    $version_string = $should_be_array;
359
-                    $corrected_db_update[$version_string] = array('unknown-date');
360
-                } else {
361
-                    //ok it checks out
362
-                    $corrected_db_update[$should_be_version_string] = $should_be_array;
363
-                }
364
-            }
365
-            $espresso_db_update = $corrected_db_update;
366
-            update_option('espresso_db_update', $espresso_db_update);
367
-        }
368
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
369
-        return $espresso_db_update;
370
-    }
371
-
372
-
373
-
374
-    /**
375
-     * Does the traditional work of setting up the plugin's database and adding default data.
376
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
377
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
378
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
379
-     * so that it will be done when migrations are finished
380
-     *
381
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
382
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
383
-     *                                       This is a resource-intensive job
384
-     *                                       so we prefer to only do it when necessary
385
-     * @return void
386
-     */
387
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
388
-    {
389
-        $request_type = $this->detect_req_type();
390
-        //only initialize system if we're not in maintenance mode.
391
-        if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
392
-            update_option('ee_flush_rewrite_rules', true);
393
-            if ($verify_schema) {
394
-                EEH_Activation::initialize_db_and_folders();
395
-            }
396
-            EEH_Activation::initialize_db_content();
397
-            EEH_Activation::system_initialization();
398
-            if ($initialize_addons_too) {
399
-                $this->initialize_addons();
400
-            }
401
-        } else {
402
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
403
-        }
404
-        if ($request_type === EE_System::req_type_new_activation
405
-            || $request_type === EE_System::req_type_reactivation
406
-            || (
407
-                $request_type === EE_System::req_type_upgrade
408
-                && $this->is_major_version_change()
409
-            )
410
-        ) {
411
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
412
-        }
413
-    }
414
-
415
-
416
-
417
-    /**
418
-     * Initializes the db for all registered addons
419
-     */
420
-    public function initialize_addons()
421
-    {
422
-        //foreach registered addon, make sure its db is up-to-date too
423
-        foreach ($this->registry->addons as $addon) {
424
-            $addon->initialize_db_if_no_migrations_required();
425
-        }
426
-    }
427
-
428
-
429
-
430
-    /**
431
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
432
-     *
433
-     * @param    array  $version_history
434
-     * @param    string $current_version_to_add version to be added to the version history
435
-     * @return    boolean success as to whether or not this option was changed
436
-     */
437
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
438
-    {
439
-        if ( ! $version_history) {
440
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
441
-        }
442
-        if ($current_version_to_add == null) {
443
-            $current_version_to_add = espresso_version();
444
-        }
445
-        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
446
-        // re-save
447
-        return update_option('espresso_db_update', $version_history);
448
-    }
449
-
450
-
451
-
452
-    /**
453
-     * Detects if the current version indicated in the has existed in the list of
454
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
455
-     *
456
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
457
-     *                                  If not supplied, fetches it from the options table.
458
-     *                                  Also, caches its result so later parts of the code can also know whether
459
-     *                                  there's been an update or not. This way we can add the current version to
460
-     *                                  espresso_db_update, but still know if this is a new install or not
461
-     * @return int one of the constants on EE_System::req_type_
462
-     */
463
-    public function detect_req_type($espresso_db_update = null)
464
-    {
465
-        if ($this->_req_type === null) {
466
-            $espresso_db_update = ! empty($espresso_db_update) ? $espresso_db_update
467
-                : $this->fix_espresso_db_upgrade_option();
468
-            $this->_req_type = $this->detect_req_type_given_activation_history($espresso_db_update,
469
-                'ee_espresso_activation', espresso_version());
470
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
471
-        }
472
-        return $this->_req_type;
473
-    }
474
-
475
-
476
-
477
-    /**
478
-     * Returns whether or not there was a non-micro version change (ie, change in either
479
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
480
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
481
-     *
482
-     * @param $activation_history
483
-     * @return bool
484
-     */
485
-    protected function _detect_major_version_change($activation_history)
486
-    {
487
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
488
-        $previous_version_parts = explode('.', $previous_version);
489
-        $current_version_parts = explode('.', espresso_version());
490
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
491
-               && ($previous_version_parts[0] !== $current_version_parts[0]
492
-                   || $previous_version_parts[1] !== $current_version_parts[1]
493
-               );
494
-    }
495
-
496
-
497
-
498
-    /**
499
-     * Returns true if either the major or minor version of EE changed during this request.
500
-     * 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
501
-     *
502
-     * @return bool
503
-     */
504
-    public function is_major_version_change()
505
-    {
506
-        return $this->_major_version_change;
507
-    }
508
-
509
-
510
-
511
-    /**
512
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
513
-     * histories (for core that' 'espresso_db_update' wp option); the name of the wordpress option which is temporarily
514
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
515
-     * just activated to (for core that will always be espresso_version())
516
-     *
517
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
518
-     *                                                 ee plugin. for core that's 'espresso_db_update'
519
-     * @param string $activation_indicator_option_name the name of the wordpress option that is temporarily set to
520
-     *                                                 indicate that this plugin was just activated
521
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
522
-     *                                                 espresso_version())
523
-     * @return int one of the constants on EE_System::req_type_*
524
-     */
525
-    public static function detect_req_type_given_activation_history(
526
-        $activation_history_for_addon,
527
-        $activation_indicator_option_name,
528
-        $version_to_upgrade_to
529
-    ) {
530
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
531
-        if ($activation_history_for_addon) {
532
-            //it exists, so this isn't a completely new install
533
-            //check if this version already in that list of previously installed versions
534
-            if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
535
-                //it a version we haven't seen before
536
-                if ($version_is_higher === 1) {
537
-                    $req_type = EE_System::req_type_upgrade;
538
-                } else {
539
-                    $req_type = EE_System::req_type_downgrade;
540
-                }
541
-                delete_option($activation_indicator_option_name);
542
-            } else {
543
-                // its not an update. maybe a reactivation?
544
-                if (get_option($activation_indicator_option_name, false)) {
545
-                    if ($version_is_higher === -1) {
546
-                        $req_type = EE_System::req_type_downgrade;
547
-                    } elseif ($version_is_higher === 0) {
548
-                        //we've seen this version before, but it's an activation. must be a reactivation
549
-                        $req_type = EE_System::req_type_reactivation;
550
-                    } else {//$version_is_higher === 1
551
-                        $req_type = EE_System::req_type_upgrade;
552
-                    }
553
-                    delete_option($activation_indicator_option_name);
554
-                } else {
555
-                    //we've seen this version before and the activation indicate doesn't show it was just activated
556
-                    if ($version_is_higher === -1) {
557
-                        $req_type = EE_System::req_type_downgrade;
558
-                    } elseif ($version_is_higher === 0) {
559
-                        //we've seen this version before and it's not an activation. its normal request
560
-                        $req_type = EE_System::req_type_normal;
561
-                    } else {//$version_is_higher === 1
562
-                        $req_type = EE_System::req_type_upgrade;
563
-                    }
564
-                }
565
-            }
566
-        } else {
567
-            //brand new install
568
-            $req_type = EE_System::req_type_new_activation;
569
-            delete_option($activation_indicator_option_name);
570
-        }
571
-        return $req_type;
572
-    }
573
-
574
-
575
-
576
-    /**
577
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
578
-     * the $activation_history_for_addon
579
-     *
580
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
581
-     *                                             sometimes containing 'unknown-date'
582
-     * @param string $version_to_upgrade_to        (current version)
583
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
584
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
585
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
586
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
587
-     */
588
-    protected static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
589
-    {
590
-        //find the most recently-activated version
591
-        $most_recently_active_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
592
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
593
-    }
594
-
595
-
596
-
597
-    /**
598
-     * Gets the most recently active version listed in the activation history,
599
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
600
-     *
601
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
602
-     *                                   sometimes containing 'unknown-date'
603
-     * @return string
604
-     */
605
-    protected static function _get_most_recently_active_version_from_activation_history($activation_history)
606
-    {
607
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
608
-        $most_recently_active_version = '0.0.0.dev.000';
609
-        if (is_array($activation_history)) {
610
-            foreach ($activation_history as $version => $times_activated) {
611
-                //check there is a record of when this version was activated. Otherwise,
612
-                //mark it as unknown
613
-                if ( ! $times_activated) {
614
-                    $times_activated = array('unknown-date');
615
-                }
616
-                if (is_string($times_activated)) {
617
-                    $times_activated = array($times_activated);
618
-                }
619
-                foreach ($times_activated as $an_activation) {
620
-                    if ($an_activation != 'unknown-date' && $an_activation > $most_recently_active_version_activation) {
621
-                        $most_recently_active_version = $version;
622
-                        $most_recently_active_version_activation = $an_activation == 'unknown-date'
623
-                            ? '1970-01-01 00:00:00' : $an_activation;
624
-                    }
625
-                }
626
-            }
627
-        }
628
-        return $most_recently_active_version;
629
-    }
630
-
631
-
632
-
633
-    /**
634
-     * This redirects to the about EE page after activation
635
-     *
636
-     * @return void
637
-     */
638
-    public function redirect_to_about_ee()
639
-    {
640
-        $notices = EE_Error::get_notices(false);
641
-        //if current user is an admin and it's not an ajax or rest request
642
-        if (
643
-            ! (defined('DOING_AJAX') && DOING_AJAX)
644
-            && ! (defined('REST_REQUEST') && REST_REQUEST)
645
-            && ! isset($notices['errors'])
646
-            && apply_filters(
647
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
648
-                $this->registry->CAP->current_user_can('manage_options', 'espresso_about_default')
649
-            )
650
-        ) {
651
-            $query_params = array('page' => 'espresso_about');
652
-            if (EE_System::instance()->detect_req_type() == EE_System::req_type_new_activation) {
653
-                $query_params['new_activation'] = true;
654
-            }
655
-            if (EE_System::instance()->detect_req_type() == EE_System::req_type_reactivation) {
656
-                $query_params['reactivation'] = true;
657
-            }
658
-            $url = add_query_arg($query_params, admin_url('admin.php'));
659
-            wp_safe_redirect($url);
660
-            exit();
661
-        }
662
-    }
663
-
664
-
665
-
666
-    /**
667
-     * load_core_configuration
668
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
669
-     * which runs during the WP 'plugins_loaded' action at priority 5
670
-     *
671
-     * @return void
672
-     */
673
-    public function load_core_configuration()
674
-    {
675
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
676
-        $this->registry->load_core('EE_Load_Textdomain');
677
-        //load textdomain
678
-        EE_Load_Textdomain::load_textdomain();
679
-        // load and setup EE_Config and EE_Network_Config
680
-        $this->registry->load_core('Config');
681
-        $this->registry->load_core('Network_Config');
682
-        // setup autoloaders
683
-        // enable logging?
684
-        if ($this->registry->CFG->admin->use_full_logging) {
685
-            $this->registry->load_core('Log');
686
-        }
687
-        // check for activation errors
688
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
689
-        if ($activation_errors) {
690
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
691
-            update_option('ee_plugin_activation_errors', false);
692
-        }
693
-        // get model names
694
-        $this->_parse_model_names();
695
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
696
-    }
697
-
698
-
699
-
700
-    /**
701
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
702
-     *
703
-     * @return void
704
-     */
705
-    private function _parse_model_names()
706
-    {
707
-        //call the non-abstract db models method, which verifies the model names have been discovered
708
-        //for the sake of unit tests, always re-discover the models. We could probably make this more
709
-        //efficient though (e.g., have unit tests reset the registered models in a different way)
710
-        $this->registry->non_abstract_db_models = array();
711
-        $this->registry->non_abstract_db_models();
712
-    }
713
-
714
-
715
-
716
-    /**
717
-     * register_shortcodes_modules_and_widgets
718
-     * generate lists of shortcodes and modules, then verify paths and classes
719
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
720
-     * which runs during the WP 'plugins_loaded' action at priority 7
721
-     *
722
-     * @access public
723
-     * @return void
724
-     */
725
-    public function register_shortcodes_modules_and_widgets()
726
-    {
727
-        try {
728
-            // load, register, and add shortcodes the new way
729
-            new ShortcodesManager(
730
-            // and the old way, but we'll put it under control of the new system
731
-                EE_Config::getLegacyShortcodesManager()
732
-            );
733
-        } catch (Exception $exception) {
734
-            new ExceptionStackTraceDisplay($exception);
735
-        }
736
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
737
-        // check for addons using old hookpoint
738
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
739
-            $this->_incompatible_addon_error();
740
-        }
741
-    }
742
-
743
-
744
-
745
-    /**
746
-     * _incompatible_addon_error
747
-     *
748
-     * @access public
749
-     * @return void
750
-     */
751
-    private function _incompatible_addon_error()
752
-    {
753
-        // get array of classes hooking into here
754
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook('AHEE__EE_System__register_shortcodes_modules_and_addons');
755
-        if ( ! empty($class_names)) {
756
-            $msg = __('The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
757
-                'event_espresso');
758
-            $msg .= '<ul>';
759
-            foreach ($class_names as $class_name) {
760
-                $msg .= '<li><b>Event Espresso - ' . str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
761
-                        $class_name) . '</b></li>';
762
-            }
763
-            $msg .= '</ul>';
764
-            $msg .= __('Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
765
-                'event_espresso');
766
-            // save list of incompatible addons to wp-options for later use
767
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
768
-            if (is_admin()) {
769
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
770
-            }
771
-        }
772
-    }
773
-
774
-
775
-
776
-    /**
777
-     * brew_espresso
778
-     * begins the process of setting hooks for initializing EE in the correct order
779
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hookpoint
780
-     * which runs during the WP 'plugins_loaded' action at priority 9
781
-     *
782
-     * @return void
783
-     */
784
-    public function brew_espresso()
785
-    {
786
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
787
-        // load some final core systems
788
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
789
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
790
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
791
-        add_action('init', array($this, 'load_controllers'), 7);
792
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
793
-        add_action('init', array($this, 'initialize'), 10);
794
-        add_action('init', array($this, 'initialize_last'), 100);
795
-        add_action('wp_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 100);
796
-        add_action('admin_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 100);
797
-        add_action('admin_bar_menu', array($this, 'espresso_toolbar_items'), 100);
798
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
799
-            // pew pew pew
800
-            $this->registry->load_core('PUE');
801
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
802
-        }
803
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
804
-    }
805
-
806
-
807
-
808
-    /**
809
-     *    set_hooks_for_core
810
-     *
811
-     * @access public
812
-     * @return    void
813
-     */
814
-    public function set_hooks_for_core()
815
-    {
816
-        $this->_deactivate_incompatible_addons();
817
-        do_action('AHEE__EE_System__set_hooks_for_core');
818
-    }
819
-
820
-
821
-
822
-    /**
823
-     * Using the information gathered in EE_System::_incompatible_addon_error,
824
-     * deactivates any addons considered incompatible with the current version of EE
825
-     */
826
-    private function _deactivate_incompatible_addons()
827
-    {
828
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
829
-        if ( ! empty($incompatible_addons)) {
830
-            $active_plugins = get_option('active_plugins', array());
831
-            foreach ($active_plugins as $active_plugin) {
832
-                foreach ($incompatible_addons as $incompatible_addon) {
833
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
834
-                        unset($_GET['activate']);
835
-                        espresso_deactivate_plugin($active_plugin);
836
-                    }
837
-                }
838
-            }
839
-        }
840
-    }
841
-
842
-
843
-
844
-    /**
845
-     *    perform_activations_upgrades_and_migrations
846
-     *
847
-     * @access public
848
-     * @return    void
849
-     */
850
-    public function perform_activations_upgrades_and_migrations()
851
-    {
852
-        //first check if we had previously attempted to setup EE's directories but failed
853
-        if (EEH_Activation::upload_directories_incomplete()) {
854
-            EEH_Activation::create_upload_directories();
855
-        }
856
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
857
-    }
858
-
859
-
860
-
861
-    /**
862
-     *    load_CPTs_and_session
863
-     *
864
-     * @access public
865
-     * @return    void
866
-     */
867
-    public function load_CPTs_and_session()
868
-    {
869
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
870
-        // register Custom Post Types
871
-        $this->registry->load_core('Register_CPTs');
872
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
873
-    }
874
-
875
-
876
-
877
-    /**
878
-     * load_controllers
879
-     * this is the best place to load any additional controllers that needs access to EE core.
880
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
881
-     * time
882
-     *
883
-     * @access public
884
-     * @return void
885
-     */
886
-    public function load_controllers()
887
-    {
888
-        do_action('AHEE__EE_System__load_controllers__start');
889
-        // let's get it started
890
-        if ( ! is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
891
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
892
-            $this->registry->load_core('Front_Controller');
893
-        } else if ( ! EE_FRONT_AJAX) {
894
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
895
-            EE_Registry::instance()->load_core('Admin');
896
-        }
897
-        do_action('AHEE__EE_System__load_controllers__complete');
898
-    }
899
-
900
-
901
-
902
-    /**
903
-     * core_loaded_and_ready
904
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
905
-     *
906
-     * @access public
907
-     * @return void
908
-     */
909
-    public function core_loaded_and_ready()
910
-    {
911
-        do_action('AHEE__EE_System__core_loaded_and_ready');
912
-        // load_espresso_template_tags
913
-        if (is_readable(EE_PUBLIC . 'template_tags.php')) {
914
-            require_once(EE_PUBLIC . 'template_tags.php');
915
-        }
916
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
917
-        $this->registry->load_core('Session');
918
-    }
919
-
920
-
921
-
922
-    /**
923
-     * initialize
924
-     * this is the best place to begin initializing client code
925
-     *
926
-     * @access public
927
-     * @return void
928
-     */
929
-    public function initialize()
930
-    {
931
-        do_action('AHEE__EE_System__initialize');
932
-    }
933
-
934
-
935
-
936
-    /**
937
-     * initialize_last
938
-     * this is run really late during the WP init hookpoint, and ensures that mostly everything else that needs to
939
-     * initialize has done so
940
-     *
941
-     * @access public
942
-     * @return void
943
-     */
944
-    public function initialize_last()
945
-    {
946
-        do_action('AHEE__EE_System__initialize_last');
947
-    }
948
-
949
-
950
-
951
-    /**
952
-     * set_hooks_for_shortcodes_modules_and_addons
953
-     * this is the best place for other systems to set callbacks for hooking into other parts of EE
954
-     * this happens at the very beginning of the wp_loaded hookpoint
955
-     *
956
-     * @access public
957
-     * @return void
958
-     */
959
-    public function set_hooks_for_shortcodes_modules_and_addons()
960
-    {
961
-        //		do_action( 'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons' );
962
-    }
963
-
964
-
965
-
966
-    /**
967
-     * do_not_cache
968
-     * sets no cache headers and defines no cache constants for WP plugins
969
-     *
970
-     * @access public
971
-     * @return void
972
-     */
973
-    public static function do_not_cache()
974
-    {
975
-        // set no cache constants
976
-        if ( ! defined('DONOTCACHEPAGE')) {
977
-            define('DONOTCACHEPAGE', true);
978
-        }
979
-        if ( ! defined('DONOTCACHCEOBJECT')) {
980
-            define('DONOTCACHCEOBJECT', true);
981
-        }
982
-        if ( ! defined('DONOTCACHEDB')) {
983
-            define('DONOTCACHEDB', true);
984
-        }
985
-        // add no cache headers
986
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
987
-        // plus a little extra for nginx and Google Chrome
988
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
989
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
990
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
991
-    }
992
-
993
-
994
-
995
-    /**
996
-     *    extra_nocache_headers
997
-     *
998
-     * @access    public
999
-     * @param $headers
1000
-     * @return    array
1001
-     */
1002
-    public static function extra_nocache_headers($headers)
1003
-    {
1004
-        // for NGINX
1005
-        $headers['X-Accel-Expires'] = 0;
1006
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1007
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1008
-        return $headers;
1009
-    }
1010
-
1011
-
1012
-
1013
-    /**
1014
-     *    nocache_headers
1015
-     *
1016
-     * @access    public
1017
-     * @return    void
1018
-     */
1019
-    public static function nocache_headers()
1020
-    {
1021
-        nocache_headers();
1022
-    }
1023
-
1024
-
1025
-
1026
-    /**
1027
-     *    espresso_toolbar_items
1028
-     *
1029
-     * @access public
1030
-     * @param  WP_Admin_Bar $admin_bar
1031
-     * @return void
1032
-     */
1033
-    public function espresso_toolbar_items(WP_Admin_Bar $admin_bar)
1034
-    {
1035
-        // if in full M-Mode, or its an AJAX request, or user is NOT an admin
1036
-        if (EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance
1037
-            || defined('DOING_AJAX')
1038
-            || ! $this->registry->CAP->current_user_can('ee_read_ee', 'ee_admin_bar_menu_top_level')
1039
-        ) {
1040
-            return;
1041
-        }
1042
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1043
-        $menu_class = 'espresso_menu_item_class';
1044
-        //we don't use the constants EVENTS_ADMIN_URL or REG_ADMIN_URL
1045
-        //because they're only defined in each of their respective constructors
1046
-        //and this might be a frontend request, in which case they aren't available
1047
-        $events_admin_url = admin_url("admin.php?page=espresso_events");
1048
-        $reg_admin_url = admin_url("admin.php?page=espresso_registrations");
1049
-        $extensions_admin_url = admin_url("admin.php?page=espresso_packages");
1050
-        //Top Level
1051
-        $admin_bar->add_menu(array(
1052
-            'id'    => 'espresso-toolbar',
1053
-            'title' => '<span class="ee-icon ee-icon-ee-cup-thick ee-icon-size-20"></span><span class="ab-label">'
1054
-                       . _x('Event Espresso', 'admin bar menu group label', 'event_espresso')
1055
-                       . '</span>',
1056
-            'href'  => $events_admin_url,
1057
-            'meta'  => array(
1058
-                'title' => __('Event Espresso', 'event_espresso'),
1059
-                'class' => $menu_class . 'first',
1060
-            ),
1061
-        ));
1062
-        //Events
1063
-        if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events')) {
1064
-            $admin_bar->add_menu(array(
1065
-                'id'     => 'espresso-toolbar-events',
1066
-                'parent' => 'espresso-toolbar',
1067
-                'title'  => __('Events', 'event_espresso'),
1068
-                'href'   => $events_admin_url,
1069
-                'meta'   => array(
1070
-                    'title'  => __('Events', 'event_espresso'),
1071
-                    'target' => '',
1072
-                    'class'  => $menu_class,
1073
-                ),
1074
-            ));
1075
-        }
1076
-        if ($this->registry->CAP->current_user_can('ee_edit_events', 'ee_admin_bar_menu_espresso-toolbar-events-new')) {
1077
-            //Events Add New
1078
-            $admin_bar->add_menu(array(
1079
-                'id'     => 'espresso-toolbar-events-new',
1080
-                'parent' => 'espresso-toolbar-events',
1081
-                'title'  => __('Add New', 'event_espresso'),
1082
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'create_new'), $events_admin_url),
1083
-                'meta'   => array(
1084
-                    'title'  => __('Add New', 'event_espresso'),
1085
-                    'target' => '',
1086
-                    'class'  => $menu_class,
1087
-                ),
1088
-            ));
1089
-        }
1090
-        if (is_single() && (get_post_type() == 'espresso_events')) {
1091
-            //Current post
1092
-            global $post;
1093
-            if ($this->registry->CAP->current_user_can('ee_edit_event',
1094
-                'ee_admin_bar_menu_espresso-toolbar-events-edit', $post->ID)
1095
-            ) {
1096
-                //Events Edit Current Event
1097
-                $admin_bar->add_menu(array(
1098
-                    'id'     => 'espresso-toolbar-events-edit',
1099
-                    'parent' => 'espresso-toolbar-events',
1100
-                    'title'  => __('Edit Event', 'event_espresso'),
1101
-                    'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'edit', 'post' => $post->ID),
1102
-                        $events_admin_url),
1103
-                    'meta'   => array(
1104
-                        'title'  => __('Edit Event', 'event_espresso'),
1105
-                        'target' => '',
1106
-                        'class'  => $menu_class,
1107
-                    ),
1108
-                ));
1109
-            }
1110
-        }
1111
-        //Events View
1112
-        if ($this->registry->CAP->current_user_can('ee_read_events',
1113
-            'ee_admin_bar_menu_espresso-toolbar-events-view')
1114
-        ) {
1115
-            $admin_bar->add_menu(array(
1116
-                'id'     => 'espresso-toolbar-events-view',
1117
-                'parent' => 'espresso-toolbar-events',
1118
-                'title'  => __('View', 'event_espresso'),
1119
-                'href'   => $events_admin_url,
1120
-                'meta'   => array(
1121
-                    'title'  => __('View', 'event_espresso'),
1122
-                    'target' => '',
1123
-                    'class'  => $menu_class,
1124
-                ),
1125
-            ));
1126
-        }
1127
-        if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-all')) {
1128
-            //Events View All
1129
-            $admin_bar->add_menu(array(
1130
-                'id'     => 'espresso-toolbar-events-all',
1131
-                'parent' => 'espresso-toolbar-events-view',
1132
-                'title'  => __('All', 'event_espresso'),
1133
-                'href'   => $events_admin_url,
1134
-                'meta'   => array(
1135
-                    'title'  => __('All', 'event_espresso'),
1136
-                    'target' => '',
1137
-                    'class'  => $menu_class,
1138
-                ),
1139
-            ));
1140
-        }
1141
-        if ($this->registry->CAP->current_user_can('ee_read_events',
1142
-            'ee_admin_bar_menu_espresso-toolbar-events-today')
1143
-        ) {
1144
-            //Events View Today
1145
-            $admin_bar->add_menu(array(
1146
-                'id'     => 'espresso-toolbar-events-today',
1147
-                'parent' => 'espresso-toolbar-events-view',
1148
-                'title'  => __('Today', 'event_espresso'),
1149
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1150
-                    $events_admin_url),
1151
-                'meta'   => array(
1152
-                    'title'  => __('Today', 'event_espresso'),
1153
-                    'target' => '',
1154
-                    'class'  => $menu_class,
1155
-                ),
1156
-            ));
1157
-        }
1158
-        if ($this->registry->CAP->current_user_can('ee_read_events',
1159
-            'ee_admin_bar_menu_espresso-toolbar-events-month')
1160
-        ) {
1161
-            //Events View This Month
1162
-            $admin_bar->add_menu(array(
1163
-                'id'     => 'espresso-toolbar-events-month',
1164
-                'parent' => 'espresso-toolbar-events-view',
1165
-                'title'  => __('This Month', 'event_espresso'),
1166
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1167
-                    $events_admin_url),
1168
-                'meta'   => array(
1169
-                    'title'  => __('This Month', 'event_espresso'),
1170
-                    'target' => '',
1171
-                    'class'  => $menu_class,
1172
-                ),
1173
-            ));
1174
-        }
1175
-        //Registration Overview
1176
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1177
-            'ee_admin_bar_menu_espresso-toolbar-registrations')
1178
-        ) {
1179
-            $admin_bar->add_menu(array(
1180
-                'id'     => 'espresso-toolbar-registrations',
1181
-                'parent' => 'espresso-toolbar',
1182
-                'title'  => __('Registrations', 'event_espresso'),
1183
-                'href'   => $reg_admin_url,
1184
-                'meta'   => array(
1185
-                    'title'  => __('Registrations', 'event_espresso'),
1186
-                    'target' => '',
1187
-                    'class'  => $menu_class,
1188
-                ),
1189
-            ));
1190
-        }
1191
-        //Registration Overview Today
1192
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1193
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today')
1194
-        ) {
1195
-            $admin_bar->add_menu(array(
1196
-                'id'     => 'espresso-toolbar-registrations-today',
1197
-                'parent' => 'espresso-toolbar-registrations',
1198
-                'title'  => __('Today', 'event_espresso'),
1199
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1200
-                    $reg_admin_url),
1201
-                'meta'   => array(
1202
-                    'title'  => __('Today', 'event_espresso'),
1203
-                    'target' => '',
1204
-                    'class'  => $menu_class,
1205
-                ),
1206
-            ));
1207
-        }
1208
-        //Registration Overview Today Completed
1209
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1210
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-approved')
1211
-        ) {
1212
-            $admin_bar->add_menu(array(
1213
-                'id'     => 'espresso-toolbar-registrations-today-approved',
1214
-                'parent' => 'espresso-toolbar-registrations-today',
1215
-                'title'  => __('Approved', 'event_espresso'),
1216
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1217
-                    'action'      => 'default',
1218
-                    'status'      => 'today',
1219
-                    '_reg_status' => EEM_Registration::status_id_approved,
1220
-                ), $reg_admin_url),
1221
-                'meta'   => array(
1222
-                    'title'  => __('Approved', 'event_espresso'),
1223
-                    'target' => '',
1224
-                    'class'  => $menu_class,
1225
-                ),
1226
-            ));
1227
-        }
1228
-        //Registration Overview Today Pending\
1229
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1230
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-pending')
1231
-        ) {
1232
-            $admin_bar->add_menu(array(
1233
-                'id'     => 'espresso-toolbar-registrations-today-pending',
1234
-                'parent' => 'espresso-toolbar-registrations-today',
1235
-                'title'  => __('Pending', 'event_espresso'),
1236
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1237
-                    'action'     => 'default',
1238
-                    'status'     => 'today',
1239
-                    'reg_status' => EEM_Registration::status_id_pending_payment,
1240
-                ), $reg_admin_url),
1241
-                'meta'   => array(
1242
-                    'title'  => __('Pending Payment', 'event_espresso'),
1243
-                    'target' => '',
1244
-                    'class'  => $menu_class,
1245
-                ),
1246
-            ));
1247
-        }
1248
-        //Registration Overview Today Incomplete
1249
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1250
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-not-approved')
1251
-        ) {
1252
-            $admin_bar->add_menu(array(
1253
-                'id'     => 'espresso-toolbar-registrations-today-not-approved',
1254
-                'parent' => 'espresso-toolbar-registrations-today',
1255
-                'title'  => __('Not Approved', 'event_espresso'),
1256
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1257
-                    'action'      => 'default',
1258
-                    'status'      => 'today',
1259
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1260
-                ), $reg_admin_url),
1261
-                'meta'   => array(
1262
-                    'title'  => __('Not Approved', 'event_espresso'),
1263
-                    'target' => '',
1264
-                    'class'  => $menu_class,
1265
-                ),
1266
-            ));
1267
-        }
1268
-        //Registration Overview Today Incomplete
1269
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1270
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-cancelled')
1271
-        ) {
1272
-            $admin_bar->add_menu(array(
1273
-                'id'     => 'espresso-toolbar-registrations-today-cancelled',
1274
-                'parent' => 'espresso-toolbar-registrations-today',
1275
-                'title'  => __('Cancelled', 'event_espresso'),
1276
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1277
-                    'action'      => 'default',
1278
-                    'status'      => 'today',
1279
-                    '_reg_status' => EEM_Registration::status_id_cancelled,
1280
-                ), $reg_admin_url),
1281
-                'meta'   => array(
1282
-                    'title'  => __('Cancelled', 'event_espresso'),
1283
-                    'target' => '',
1284
-                    'class'  => $menu_class,
1285
-                ),
1286
-            ));
1287
-        }
1288
-        //Registration Overview This Month
1289
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1290
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month')
1291
-        ) {
1292
-            $admin_bar->add_menu(array(
1293
-                'id'     => 'espresso-toolbar-registrations-month',
1294
-                'parent' => 'espresso-toolbar-registrations',
1295
-                'title'  => __('This Month', 'event_espresso'),
1296
-                'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1297
-                    $reg_admin_url),
1298
-                'meta'   => array(
1299
-                    'title'  => __('This Month', 'event_espresso'),
1300
-                    'target' => '',
1301
-                    'class'  => $menu_class,
1302
-                ),
1303
-            ));
1304
-        }
1305
-        //Registration Overview This Month Approved
1306
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1307
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-approved')
1308
-        ) {
1309
-            $admin_bar->add_menu(array(
1310
-                'id'     => 'espresso-toolbar-registrations-month-approved',
1311
-                'parent' => 'espresso-toolbar-registrations-month',
1312
-                'title'  => __('Approved', 'event_espresso'),
1313
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1314
-                    'action'      => 'default',
1315
-                    'status'      => 'month',
1316
-                    '_reg_status' => EEM_Registration::status_id_approved,
1317
-                ), $reg_admin_url),
1318
-                'meta'   => array(
1319
-                    'title'  => __('Approved', 'event_espresso'),
1320
-                    'target' => '',
1321
-                    'class'  => $menu_class,
1322
-                ),
1323
-            ));
1324
-        }
1325
-        //Registration Overview This Month Pending
1326
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1327
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-pending')
1328
-        ) {
1329
-            $admin_bar->add_menu(array(
1330
-                'id'     => 'espresso-toolbar-registrations-month-pending',
1331
-                'parent' => 'espresso-toolbar-registrations-month',
1332
-                'title'  => __('Pending', 'event_espresso'),
1333
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1334
-                    'action'      => 'default',
1335
-                    'status'      => 'month',
1336
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1337
-                ), $reg_admin_url),
1338
-                'meta'   => array(
1339
-                    'title'  => __('Pending', 'event_espresso'),
1340
-                    'target' => '',
1341
-                    'class'  => $menu_class,
1342
-                ),
1343
-            ));
1344
-        }
1345
-        //Registration Overview This Month Not Approved
1346
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1347
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-not-approved')
1348
-        ) {
1349
-            $admin_bar->add_menu(array(
1350
-                'id'     => 'espresso-toolbar-registrations-month-not-approved',
1351
-                'parent' => 'espresso-toolbar-registrations-month',
1352
-                'title'  => __('Not Approved', 'event_espresso'),
1353
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1354
-                    'action'      => 'default',
1355
-                    'status'      => 'month',
1356
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1357
-                ), $reg_admin_url),
1358
-                'meta'   => array(
1359
-                    'title'  => __('Not Approved', 'event_espresso'),
1360
-                    'target' => '',
1361
-                    'class'  => $menu_class,
1362
-                ),
1363
-            ));
1364
-        }
1365
-        //Registration Overview This Month Cancelled
1366
-        if ($this->registry->CAP->current_user_can('ee_read_registrations',
1367
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-cancelled')
1368
-        ) {
1369
-            $admin_bar->add_menu(array(
1370
-                'id'     => 'espresso-toolbar-registrations-month-cancelled',
1371
-                'parent' => 'espresso-toolbar-registrations-month',
1372
-                'title'  => __('Cancelled', 'event_espresso'),
1373
-                'href'   => EEH_URL::add_query_args_and_nonce(array(
1374
-                    'action'      => 'default',
1375
-                    'status'      => 'month',
1376
-                    '_reg_status' => EEM_Registration::status_id_cancelled,
1377
-                ), $reg_admin_url),
1378
-                'meta'   => array(
1379
-                    'title'  => __('Cancelled', 'event_espresso'),
1380
-                    'target' => '',
1381
-                    'class'  => $menu_class,
1382
-                ),
1383
-            ));
1384
-        }
1385
-        //Extensions & Services
1386
-        if ($this->registry->CAP->current_user_can('ee_read_ee',
1387
-            'ee_admin_bar_menu_espresso-toolbar-extensions-and-services')
1388
-        ) {
1389
-            $admin_bar->add_menu(array(
1390
-                'id'     => 'espresso-toolbar-extensions-and-services',
1391
-                'parent' => 'espresso-toolbar',
1392
-                'title'  => __('Extensions & Services', 'event_espresso'),
1393
-                'href'   => $extensions_admin_url,
1394
-                'meta'   => array(
1395
-                    'title'  => __('Extensions & Services', 'event_espresso'),
1396
-                    'target' => '',
1397
-                    'class'  => $menu_class,
1398
-                ),
1399
-            ));
1400
-        }
1401
-    }
1402
-
1403
-
1404
-
1405
-    /**
1406
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1407
-     * never returned with the function.
1408
-     *
1409
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1410
-     * @return array
1411
-     */
1412
-    public function remove_pages_from_wp_list_pages($exclude_array)
1413
-    {
1414
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1415
-    }
1416
-
1417
-
1418
-
1419
-
1420
-
1421
-
1422
-    /***********************************************        WP_ENQUEUE_SCRIPTS HOOK         ***********************************************/
1423
-    /**
1424
-     *    wp_enqueue_scripts
1425
-     *
1426
-     * @access    public
1427
-     * @return    void
1428
-     */
1429
-    public function wp_enqueue_scripts()
1430
-    {
1431
-        // unlike other systems, EE_System_scripts loading is turned ON by default, but prior to the init hook, can be turned off via: add_filter( 'FHEE_load_EE_System_scripts', '__return_false' );
1432
-        if (apply_filters('FHEE_load_EE_System_scripts', true)) {
1433
-            // jquery_validate loading is turned OFF by default, but prior to the wp_enqueue_scripts hook, can be turned back on again via:  add_filter( 'FHEE_load_jquery_validate', '__return_true' );
1434
-            if (apply_filters('FHEE_load_jquery_validate', false)) {
1435
-                // register jQuery Validate and additional methods
1436
-                wp_register_script('jquery-validate', EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
1437
-                    array('jquery'), '1.15.0', true);
1438
-                wp_register_script('jquery-validate-extra-methods',
1439
-                    EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
1440
-                    array('jquery', 'jquery-validate'), '1.15.0', true);
1441
-            }
1442
-        }
1443
-    }
22
+	/**
23
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
24
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
25
+	 */
26
+	const req_type_normal = 0;
27
+
28
+	/**
29
+	 * Indicates this is a brand new installation of EE so we should install
30
+	 * tables and default data etc
31
+	 */
32
+	const req_type_new_activation = 1;
33
+
34
+	/**
35
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
36
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
37
+	 * and that default data is setup too
38
+	 */
39
+	const req_type_reactivation = 2;
40
+
41
+	/**
42
+	 * indicates that EE has been upgraded since its previous request.
43
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
44
+	 */
45
+	const req_type_upgrade = 3;
46
+
47
+	/**
48
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
49
+	 */
50
+	const req_type_downgrade = 4;
51
+
52
+	/**
53
+	 * @deprecated since version 4.6.0.dev.006
54
+	 * Now whenever a new_activation is detected the request type is still just
55
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
56
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
57
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
58
+	 * (Specifically, when the migration manager indicates migrations are finished
59
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
60
+	 */
61
+	const req_type_activation_but_not_installed = 5;
62
+
63
+	/**
64
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
65
+	 */
66
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
67
+
68
+
69
+	/**
70
+	 *    instance of the EE_System object
71
+	 *
72
+	 * @var    $_instance
73
+	 * @access    private
74
+	 */
75
+	private static $_instance = null;
76
+
77
+	/**
78
+	 * @type  EE_Registry $Registry
79
+	 * @access    protected
80
+	 */
81
+	protected $registry;
82
+
83
+	/**
84
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
85
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
86
+	 *
87
+	 * @var int
88
+	 */
89
+	private $_req_type;
90
+
91
+	/**
92
+	 * Whether or not there was a non-micro version change in EE core version during this request
93
+	 *
94
+	 * @var boolean
95
+	 */
96
+	private $_major_version_change = false;
97
+
98
+
99
+
100
+	/**
101
+	 * @singleton method used to instantiate class object
102
+	 * @access    public
103
+	 * @param  \EE_Registry $Registry
104
+	 * @return \EE_System
105
+	 */
106
+	public static function instance(EE_Registry $Registry = null)
107
+	{
108
+		// check if class object is instantiated
109
+		if ( ! self::$_instance instanceof EE_System) {
110
+			self::$_instance = new self($Registry);
111
+		}
112
+		return self::$_instance;
113
+	}
114
+
115
+
116
+
117
+	/**
118
+	 * resets the instance and returns it
119
+	 *
120
+	 * @return EE_System
121
+	 */
122
+	public static function reset()
123
+	{
124
+		self::$_instance->_req_type = null;
125
+		//make sure none of the old hooks are left hanging around
126
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
127
+		//we need to reset the migration manager in order for it to detect DMSs properly
128
+		EE_Data_Migration_Manager::reset();
129
+		self::instance()->detect_activations_or_upgrades();
130
+		self::instance()->perform_activations_upgrades_and_migrations();
131
+		return self::instance();
132
+	}
133
+
134
+
135
+
136
+	/**
137
+	 *    sets hooks for running rest of system
138
+	 *    provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
139
+	 *    starting EE Addons from any other point may lead to problems
140
+	 *
141
+	 * @access private
142
+	 * @param  \EE_Registry $Registry
143
+	 */
144
+	private function __construct(EE_Registry $Registry)
145
+	{
146
+		$this->registry = $Registry;
147
+		do_action('AHEE__EE_System__construct__begin', $this);
148
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
149
+		add_action('AHEE__EE_Bootstrap__load_espresso_addons', array($this, 'load_espresso_addons'));
150
+		// when an ee addon is activated, we want to call the core hook(s) again
151
+		// because the newly-activated addon didn't get a chance to run at all
152
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
153
+		// detect whether install or upgrade
154
+		add_action('AHEE__EE_Bootstrap__detect_activations_or_upgrades', array($this, 'detect_activations_or_upgrades'),
155
+			3);
156
+		// load EE_Config, EE_Textdomain, etc
157
+		add_action('AHEE__EE_Bootstrap__load_core_configuration', array($this, 'load_core_configuration'), 5);
158
+		// load EE_Config, EE_Textdomain, etc
159
+		add_action('AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
160
+			array($this, 'register_shortcodes_modules_and_widgets'), 7);
161
+		// you wanna get going? I wanna get going... let's get going!
162
+		add_action('AHEE__EE_Bootstrap__brew_espresso', array($this, 'brew_espresso'), 9);
163
+		//other housekeeping
164
+		//exclude EE critical pages from wp_list_pages
165
+		add_filter('wp_list_pages_excludes', array($this, 'remove_pages_from_wp_list_pages'), 10);
166
+		// ALL EE Addons should use the following hook point to attach their initial setup too
167
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
168
+		do_action('AHEE__EE_System__construct__complete', $this);
169
+	}
170
+
171
+
172
+
173
+	/**
174
+	 * load_espresso_addons
175
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
176
+	 * this is hooked into both:
177
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
178
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
179
+	 *    and the WP 'activate_plugin' hookpoint
180
+	 *
181
+	 * @access public
182
+	 * @return void
183
+	 */
184
+	public function load_espresso_addons()
185
+	{
186
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
187
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
188
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
189
+		//load and setup EE_Capabilities
190
+		$this->registry->load_core('Capabilities');
191
+		do_action('AHEE__EE_System__load_espresso_addons');
192
+		//if the WP API basic auth plugin isn't already loaded, load it now.
193
+		//We want it for mobile apps. Just include the entire plugin
194
+		//also, don't load the basic auth when a plugin is getting activated, because
195
+		//it could be the basic auth plugin, and it doesn't check if its methods are already defined
196
+		//and causes a fatal error
197
+		if ( ! function_exists('json_basic_auth_handler')
198
+			 && ! function_exists('json_basic_auth_error')
199
+			 && ! (
200
+				isset($_GET['action'])
201
+				&& in_array($_GET['action'], array('activate', 'activate-selected'))
202
+			)
203
+			 && ! (
204
+				isset($_GET['activate'])
205
+				&& $_GET['activate'] === 'true'
206
+			)
207
+		) {
208
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
209
+		}
210
+		$this->_maybe_brew_regular();
211
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
212
+
213
+		//caps need to be initialized on every request so that capability maps are set.
214
+		//@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
215
+		$this->registry->CAP->init_caps();
216
+	}
217
+
218
+
219
+
220
+	/**
221
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
222
+	 * that need to be setup before our EE_System launches.
223
+	 *
224
+	 * @return void
225
+	 */
226
+	private function _maybe_brew_regular()
227
+	{
228
+		if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
229
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
230
+		}
231
+	}
232
+
233
+
234
+
235
+	/**
236
+	 * detect_activations_or_upgrades
237
+	 * Checks for activation or upgrade of core first;
238
+	 * then also checks if any registered addons have been activated or upgraded
239
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
240
+	 * which runs during the WP 'plugins_loaded' action at priority 3
241
+	 *
242
+	 * @access public
243
+	 * @return void
244
+	 */
245
+	public function detect_activations_or_upgrades()
246
+	{
247
+		//first off: let's make sure to handle core
248
+		$this->detect_if_activation_or_upgrade();
249
+		foreach ($this->registry->addons as $addon) {
250
+			//detect teh request type for that addon
251
+			$addon->detect_activation_or_upgrade();
252
+		}
253
+	}
254
+
255
+
256
+
257
+	/**
258
+	 * detect_if_activation_or_upgrade
259
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
260
+	 * and either setting up the DB or setting up maintenance mode etc.
261
+	 *
262
+	 * @access public
263
+	 * @return void
264
+	 */
265
+	public function detect_if_activation_or_upgrade()
266
+	{
267
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
268
+		// load M-Mode class
269
+		$this->registry->load_core('Maintenance_Mode');
270
+		// check if db has been updated, or if its a brand-new installation
271
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
272
+		$request_type = $this->detect_req_type($espresso_db_update);
273
+		//EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
274
+		switch ($request_type) {
275
+			case EE_System::req_type_new_activation:
276
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
277
+				$this->_handle_core_version_change($espresso_db_update);
278
+				break;
279
+			case EE_System::req_type_reactivation:
280
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
281
+				$this->_handle_core_version_change($espresso_db_update);
282
+				break;
283
+			case EE_System::req_type_upgrade:
284
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
285
+				//migrations may be required now that we've upgraded
286
+				EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
287
+				$this->_handle_core_version_change($espresso_db_update);
288
+				//				echo "done upgrade";die;
289
+				break;
290
+			case EE_System::req_type_downgrade:
291
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
292
+				//its possible migrations are no longer required
293
+				EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
294
+				$this->_handle_core_version_change($espresso_db_update);
295
+				break;
296
+			case EE_System::req_type_normal:
297
+			default:
298
+				//				$this->_maybe_redirect_to_ee_about();
299
+				break;
300
+		}
301
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
302
+	}
303
+
304
+
305
+
306
+	/**
307
+	 * Updates the list of installed versions and sets hooks for
308
+	 * initializing the database later during the request
309
+	 *
310
+	 * @param array $espresso_db_update
311
+	 */
312
+	protected function _handle_core_version_change($espresso_db_update)
313
+	{
314
+		$this->update_list_of_installed_versions($espresso_db_update);
315
+		//get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
316
+		add_action('AHEE__EE_System__perform_activations_upgrades_and_migrations',
317
+			array($this, 'initialize_db_if_no_migrations_required'));
318
+	}
319
+
320
+
321
+
322
+	/**
323
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
324
+	 * information about what versions of EE have been installed and activated,
325
+	 * NOT necessarily the state of the database
326
+	 *
327
+	 * @param null $espresso_db_update
328
+	 * @internal param array $espresso_db_update_value the value of the WordPress option. If not supplied, fetches it
329
+	 *           from the options table
330
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
331
+	 */
332
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
333
+	{
334
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
335
+		if ( ! $espresso_db_update) {
336
+			$espresso_db_update = get_option('espresso_db_update');
337
+		}
338
+		// check that option is an array
339
+		if ( ! is_array($espresso_db_update)) {
340
+			// if option is FALSE, then it never existed
341
+			if ($espresso_db_update === false) {
342
+				// make $espresso_db_update an array and save option with autoload OFF
343
+				$espresso_db_update = array();
344
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
345
+			} else {
346
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
347
+				$espresso_db_update = array($espresso_db_update => array());
348
+				update_option('espresso_db_update', $espresso_db_update);
349
+			}
350
+		} else {
351
+			$corrected_db_update = array();
352
+			//if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
353
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
354
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
355
+					//the key is an int, and the value IS NOT an array
356
+					//so it must be numerically-indexed, where values are versions installed...
357
+					//fix it!
358
+					$version_string = $should_be_array;
359
+					$corrected_db_update[$version_string] = array('unknown-date');
360
+				} else {
361
+					//ok it checks out
362
+					$corrected_db_update[$should_be_version_string] = $should_be_array;
363
+				}
364
+			}
365
+			$espresso_db_update = $corrected_db_update;
366
+			update_option('espresso_db_update', $espresso_db_update);
367
+		}
368
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
369
+		return $espresso_db_update;
370
+	}
371
+
372
+
373
+
374
+	/**
375
+	 * Does the traditional work of setting up the plugin's database and adding default data.
376
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
377
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
378
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
379
+	 * so that it will be done when migrations are finished
380
+	 *
381
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
382
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
383
+	 *                                       This is a resource-intensive job
384
+	 *                                       so we prefer to only do it when necessary
385
+	 * @return void
386
+	 */
387
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
388
+	{
389
+		$request_type = $this->detect_req_type();
390
+		//only initialize system if we're not in maintenance mode.
391
+		if (EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::level_2_complete_maintenance) {
392
+			update_option('ee_flush_rewrite_rules', true);
393
+			if ($verify_schema) {
394
+				EEH_Activation::initialize_db_and_folders();
395
+			}
396
+			EEH_Activation::initialize_db_content();
397
+			EEH_Activation::system_initialization();
398
+			if ($initialize_addons_too) {
399
+				$this->initialize_addons();
400
+			}
401
+		} else {
402
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
403
+		}
404
+		if ($request_type === EE_System::req_type_new_activation
405
+			|| $request_type === EE_System::req_type_reactivation
406
+			|| (
407
+				$request_type === EE_System::req_type_upgrade
408
+				&& $this->is_major_version_change()
409
+			)
410
+		) {
411
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
412
+		}
413
+	}
414
+
415
+
416
+
417
+	/**
418
+	 * Initializes the db for all registered addons
419
+	 */
420
+	public function initialize_addons()
421
+	{
422
+		//foreach registered addon, make sure its db is up-to-date too
423
+		foreach ($this->registry->addons as $addon) {
424
+			$addon->initialize_db_if_no_migrations_required();
425
+		}
426
+	}
427
+
428
+
429
+
430
+	/**
431
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
432
+	 *
433
+	 * @param    array  $version_history
434
+	 * @param    string $current_version_to_add version to be added to the version history
435
+	 * @return    boolean success as to whether or not this option was changed
436
+	 */
437
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
438
+	{
439
+		if ( ! $version_history) {
440
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
441
+		}
442
+		if ($current_version_to_add == null) {
443
+			$current_version_to_add = espresso_version();
444
+		}
445
+		$version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
446
+		// re-save
447
+		return update_option('espresso_db_update', $version_history);
448
+	}
449
+
450
+
451
+
452
+	/**
453
+	 * Detects if the current version indicated in the has existed in the list of
454
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
455
+	 *
456
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
457
+	 *                                  If not supplied, fetches it from the options table.
458
+	 *                                  Also, caches its result so later parts of the code can also know whether
459
+	 *                                  there's been an update or not. This way we can add the current version to
460
+	 *                                  espresso_db_update, but still know if this is a new install or not
461
+	 * @return int one of the constants on EE_System::req_type_
462
+	 */
463
+	public function detect_req_type($espresso_db_update = null)
464
+	{
465
+		if ($this->_req_type === null) {
466
+			$espresso_db_update = ! empty($espresso_db_update) ? $espresso_db_update
467
+				: $this->fix_espresso_db_upgrade_option();
468
+			$this->_req_type = $this->detect_req_type_given_activation_history($espresso_db_update,
469
+				'ee_espresso_activation', espresso_version());
470
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
471
+		}
472
+		return $this->_req_type;
473
+	}
474
+
475
+
476
+
477
+	/**
478
+	 * Returns whether or not there was a non-micro version change (ie, change in either
479
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
480
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
481
+	 *
482
+	 * @param $activation_history
483
+	 * @return bool
484
+	 */
485
+	protected function _detect_major_version_change($activation_history)
486
+	{
487
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
488
+		$previous_version_parts = explode('.', $previous_version);
489
+		$current_version_parts = explode('.', espresso_version());
490
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
491
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
492
+				   || $previous_version_parts[1] !== $current_version_parts[1]
493
+			   );
494
+	}
495
+
496
+
497
+
498
+	/**
499
+	 * Returns true if either the major or minor version of EE changed during this request.
500
+	 * 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
501
+	 *
502
+	 * @return bool
503
+	 */
504
+	public function is_major_version_change()
505
+	{
506
+		return $this->_major_version_change;
507
+	}
508
+
509
+
510
+
511
+	/**
512
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
513
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the wordpress option which is temporarily
514
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
515
+	 * just activated to (for core that will always be espresso_version())
516
+	 *
517
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
518
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
519
+	 * @param string $activation_indicator_option_name the name of the wordpress option that is temporarily set to
520
+	 *                                                 indicate that this plugin was just activated
521
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
522
+	 *                                                 espresso_version())
523
+	 * @return int one of the constants on EE_System::req_type_*
524
+	 */
525
+	public static function detect_req_type_given_activation_history(
526
+		$activation_history_for_addon,
527
+		$activation_indicator_option_name,
528
+		$version_to_upgrade_to
529
+	) {
530
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
531
+		if ($activation_history_for_addon) {
532
+			//it exists, so this isn't a completely new install
533
+			//check if this version already in that list of previously installed versions
534
+			if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
535
+				//it a version we haven't seen before
536
+				if ($version_is_higher === 1) {
537
+					$req_type = EE_System::req_type_upgrade;
538
+				} else {
539
+					$req_type = EE_System::req_type_downgrade;
540
+				}
541
+				delete_option($activation_indicator_option_name);
542
+			} else {
543
+				// its not an update. maybe a reactivation?
544
+				if (get_option($activation_indicator_option_name, false)) {
545
+					if ($version_is_higher === -1) {
546
+						$req_type = EE_System::req_type_downgrade;
547
+					} elseif ($version_is_higher === 0) {
548
+						//we've seen this version before, but it's an activation. must be a reactivation
549
+						$req_type = EE_System::req_type_reactivation;
550
+					} else {//$version_is_higher === 1
551
+						$req_type = EE_System::req_type_upgrade;
552
+					}
553
+					delete_option($activation_indicator_option_name);
554
+				} else {
555
+					//we've seen this version before and the activation indicate doesn't show it was just activated
556
+					if ($version_is_higher === -1) {
557
+						$req_type = EE_System::req_type_downgrade;
558
+					} elseif ($version_is_higher === 0) {
559
+						//we've seen this version before and it's not an activation. its normal request
560
+						$req_type = EE_System::req_type_normal;
561
+					} else {//$version_is_higher === 1
562
+						$req_type = EE_System::req_type_upgrade;
563
+					}
564
+				}
565
+			}
566
+		} else {
567
+			//brand new install
568
+			$req_type = EE_System::req_type_new_activation;
569
+			delete_option($activation_indicator_option_name);
570
+		}
571
+		return $req_type;
572
+	}
573
+
574
+
575
+
576
+	/**
577
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
578
+	 * the $activation_history_for_addon
579
+	 *
580
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
581
+	 *                                             sometimes containing 'unknown-date'
582
+	 * @param string $version_to_upgrade_to        (current version)
583
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
584
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
585
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
586
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
587
+	 */
588
+	protected static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
589
+	{
590
+		//find the most recently-activated version
591
+		$most_recently_active_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
592
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
593
+	}
594
+
595
+
596
+
597
+	/**
598
+	 * Gets the most recently active version listed in the activation history,
599
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
600
+	 *
601
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
602
+	 *                                   sometimes containing 'unknown-date'
603
+	 * @return string
604
+	 */
605
+	protected static function _get_most_recently_active_version_from_activation_history($activation_history)
606
+	{
607
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
608
+		$most_recently_active_version = '0.0.0.dev.000';
609
+		if (is_array($activation_history)) {
610
+			foreach ($activation_history as $version => $times_activated) {
611
+				//check there is a record of when this version was activated. Otherwise,
612
+				//mark it as unknown
613
+				if ( ! $times_activated) {
614
+					$times_activated = array('unknown-date');
615
+				}
616
+				if (is_string($times_activated)) {
617
+					$times_activated = array($times_activated);
618
+				}
619
+				foreach ($times_activated as $an_activation) {
620
+					if ($an_activation != 'unknown-date' && $an_activation > $most_recently_active_version_activation) {
621
+						$most_recently_active_version = $version;
622
+						$most_recently_active_version_activation = $an_activation == 'unknown-date'
623
+							? '1970-01-01 00:00:00' : $an_activation;
624
+					}
625
+				}
626
+			}
627
+		}
628
+		return $most_recently_active_version;
629
+	}
630
+
631
+
632
+
633
+	/**
634
+	 * This redirects to the about EE page after activation
635
+	 *
636
+	 * @return void
637
+	 */
638
+	public function redirect_to_about_ee()
639
+	{
640
+		$notices = EE_Error::get_notices(false);
641
+		//if current user is an admin and it's not an ajax or rest request
642
+		if (
643
+			! (defined('DOING_AJAX') && DOING_AJAX)
644
+			&& ! (defined('REST_REQUEST') && REST_REQUEST)
645
+			&& ! isset($notices['errors'])
646
+			&& apply_filters(
647
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
648
+				$this->registry->CAP->current_user_can('manage_options', 'espresso_about_default')
649
+			)
650
+		) {
651
+			$query_params = array('page' => 'espresso_about');
652
+			if (EE_System::instance()->detect_req_type() == EE_System::req_type_new_activation) {
653
+				$query_params['new_activation'] = true;
654
+			}
655
+			if (EE_System::instance()->detect_req_type() == EE_System::req_type_reactivation) {
656
+				$query_params['reactivation'] = true;
657
+			}
658
+			$url = add_query_arg($query_params, admin_url('admin.php'));
659
+			wp_safe_redirect($url);
660
+			exit();
661
+		}
662
+	}
663
+
664
+
665
+
666
+	/**
667
+	 * load_core_configuration
668
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
669
+	 * which runs during the WP 'plugins_loaded' action at priority 5
670
+	 *
671
+	 * @return void
672
+	 */
673
+	public function load_core_configuration()
674
+	{
675
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
676
+		$this->registry->load_core('EE_Load_Textdomain');
677
+		//load textdomain
678
+		EE_Load_Textdomain::load_textdomain();
679
+		// load and setup EE_Config and EE_Network_Config
680
+		$this->registry->load_core('Config');
681
+		$this->registry->load_core('Network_Config');
682
+		// setup autoloaders
683
+		// enable logging?
684
+		if ($this->registry->CFG->admin->use_full_logging) {
685
+			$this->registry->load_core('Log');
686
+		}
687
+		// check for activation errors
688
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
689
+		if ($activation_errors) {
690
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
691
+			update_option('ee_plugin_activation_errors', false);
692
+		}
693
+		// get model names
694
+		$this->_parse_model_names();
695
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
696
+	}
697
+
698
+
699
+
700
+	/**
701
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
702
+	 *
703
+	 * @return void
704
+	 */
705
+	private function _parse_model_names()
706
+	{
707
+		//call the non-abstract db models method, which verifies the model names have been discovered
708
+		//for the sake of unit tests, always re-discover the models. We could probably make this more
709
+		//efficient though (e.g., have unit tests reset the registered models in a different way)
710
+		$this->registry->non_abstract_db_models = array();
711
+		$this->registry->non_abstract_db_models();
712
+	}
713
+
714
+
715
+
716
+	/**
717
+	 * register_shortcodes_modules_and_widgets
718
+	 * generate lists of shortcodes and modules, then verify paths and classes
719
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
720
+	 * which runs during the WP 'plugins_loaded' action at priority 7
721
+	 *
722
+	 * @access public
723
+	 * @return void
724
+	 */
725
+	public function register_shortcodes_modules_and_widgets()
726
+	{
727
+		try {
728
+			// load, register, and add shortcodes the new way
729
+			new ShortcodesManager(
730
+			// and the old way, but we'll put it under control of the new system
731
+				EE_Config::getLegacyShortcodesManager()
732
+			);
733
+		} catch (Exception $exception) {
734
+			new ExceptionStackTraceDisplay($exception);
735
+		}
736
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
737
+		// check for addons using old hookpoint
738
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
739
+			$this->_incompatible_addon_error();
740
+		}
741
+	}
742
+
743
+
744
+
745
+	/**
746
+	 * _incompatible_addon_error
747
+	 *
748
+	 * @access public
749
+	 * @return void
750
+	 */
751
+	private function _incompatible_addon_error()
752
+	{
753
+		// get array of classes hooking into here
754
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook('AHEE__EE_System__register_shortcodes_modules_and_addons');
755
+		if ( ! empty($class_names)) {
756
+			$msg = __('The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
757
+				'event_espresso');
758
+			$msg .= '<ul>';
759
+			foreach ($class_names as $class_name) {
760
+				$msg .= '<li><b>Event Espresso - ' . str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
761
+						$class_name) . '</b></li>';
762
+			}
763
+			$msg .= '</ul>';
764
+			$msg .= __('Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
765
+				'event_espresso');
766
+			// save list of incompatible addons to wp-options for later use
767
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
768
+			if (is_admin()) {
769
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
770
+			}
771
+		}
772
+	}
773
+
774
+
775
+
776
+	/**
777
+	 * brew_espresso
778
+	 * begins the process of setting hooks for initializing EE in the correct order
779
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hookpoint
780
+	 * which runs during the WP 'plugins_loaded' action at priority 9
781
+	 *
782
+	 * @return void
783
+	 */
784
+	public function brew_espresso()
785
+	{
786
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
787
+		// load some final core systems
788
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
789
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
790
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
791
+		add_action('init', array($this, 'load_controllers'), 7);
792
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
793
+		add_action('init', array($this, 'initialize'), 10);
794
+		add_action('init', array($this, 'initialize_last'), 100);
795
+		add_action('wp_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 100);
796
+		add_action('admin_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 100);
797
+		add_action('admin_bar_menu', array($this, 'espresso_toolbar_items'), 100);
798
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
799
+			// pew pew pew
800
+			$this->registry->load_core('PUE');
801
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
802
+		}
803
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
804
+	}
805
+
806
+
807
+
808
+	/**
809
+	 *    set_hooks_for_core
810
+	 *
811
+	 * @access public
812
+	 * @return    void
813
+	 */
814
+	public function set_hooks_for_core()
815
+	{
816
+		$this->_deactivate_incompatible_addons();
817
+		do_action('AHEE__EE_System__set_hooks_for_core');
818
+	}
819
+
820
+
821
+
822
+	/**
823
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
824
+	 * deactivates any addons considered incompatible with the current version of EE
825
+	 */
826
+	private function _deactivate_incompatible_addons()
827
+	{
828
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
829
+		if ( ! empty($incompatible_addons)) {
830
+			$active_plugins = get_option('active_plugins', array());
831
+			foreach ($active_plugins as $active_plugin) {
832
+				foreach ($incompatible_addons as $incompatible_addon) {
833
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
834
+						unset($_GET['activate']);
835
+						espresso_deactivate_plugin($active_plugin);
836
+					}
837
+				}
838
+			}
839
+		}
840
+	}
841
+
842
+
843
+
844
+	/**
845
+	 *    perform_activations_upgrades_and_migrations
846
+	 *
847
+	 * @access public
848
+	 * @return    void
849
+	 */
850
+	public function perform_activations_upgrades_and_migrations()
851
+	{
852
+		//first check if we had previously attempted to setup EE's directories but failed
853
+		if (EEH_Activation::upload_directories_incomplete()) {
854
+			EEH_Activation::create_upload_directories();
855
+		}
856
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
857
+	}
858
+
859
+
860
+
861
+	/**
862
+	 *    load_CPTs_and_session
863
+	 *
864
+	 * @access public
865
+	 * @return    void
866
+	 */
867
+	public function load_CPTs_and_session()
868
+	{
869
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
870
+		// register Custom Post Types
871
+		$this->registry->load_core('Register_CPTs');
872
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
873
+	}
874
+
875
+
876
+
877
+	/**
878
+	 * load_controllers
879
+	 * this is the best place to load any additional controllers that needs access to EE core.
880
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
881
+	 * time
882
+	 *
883
+	 * @access public
884
+	 * @return void
885
+	 */
886
+	public function load_controllers()
887
+	{
888
+		do_action('AHEE__EE_System__load_controllers__start');
889
+		// let's get it started
890
+		if ( ! is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
891
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
892
+			$this->registry->load_core('Front_Controller');
893
+		} else if ( ! EE_FRONT_AJAX) {
894
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
895
+			EE_Registry::instance()->load_core('Admin');
896
+		}
897
+		do_action('AHEE__EE_System__load_controllers__complete');
898
+	}
899
+
900
+
901
+
902
+	/**
903
+	 * core_loaded_and_ready
904
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
905
+	 *
906
+	 * @access public
907
+	 * @return void
908
+	 */
909
+	public function core_loaded_and_ready()
910
+	{
911
+		do_action('AHEE__EE_System__core_loaded_and_ready');
912
+		// load_espresso_template_tags
913
+		if (is_readable(EE_PUBLIC . 'template_tags.php')) {
914
+			require_once(EE_PUBLIC . 'template_tags.php');
915
+		}
916
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
917
+		$this->registry->load_core('Session');
918
+	}
919
+
920
+
921
+
922
+	/**
923
+	 * initialize
924
+	 * this is the best place to begin initializing client code
925
+	 *
926
+	 * @access public
927
+	 * @return void
928
+	 */
929
+	public function initialize()
930
+	{
931
+		do_action('AHEE__EE_System__initialize');
932
+	}
933
+
934
+
935
+
936
+	/**
937
+	 * initialize_last
938
+	 * this is run really late during the WP init hookpoint, and ensures that mostly everything else that needs to
939
+	 * initialize has done so
940
+	 *
941
+	 * @access public
942
+	 * @return void
943
+	 */
944
+	public function initialize_last()
945
+	{
946
+		do_action('AHEE__EE_System__initialize_last');
947
+	}
948
+
949
+
950
+
951
+	/**
952
+	 * set_hooks_for_shortcodes_modules_and_addons
953
+	 * this is the best place for other systems to set callbacks for hooking into other parts of EE
954
+	 * this happens at the very beginning of the wp_loaded hookpoint
955
+	 *
956
+	 * @access public
957
+	 * @return void
958
+	 */
959
+	public function set_hooks_for_shortcodes_modules_and_addons()
960
+	{
961
+		//		do_action( 'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons' );
962
+	}
963
+
964
+
965
+
966
+	/**
967
+	 * do_not_cache
968
+	 * sets no cache headers and defines no cache constants for WP plugins
969
+	 *
970
+	 * @access public
971
+	 * @return void
972
+	 */
973
+	public static function do_not_cache()
974
+	{
975
+		// set no cache constants
976
+		if ( ! defined('DONOTCACHEPAGE')) {
977
+			define('DONOTCACHEPAGE', true);
978
+		}
979
+		if ( ! defined('DONOTCACHCEOBJECT')) {
980
+			define('DONOTCACHCEOBJECT', true);
981
+		}
982
+		if ( ! defined('DONOTCACHEDB')) {
983
+			define('DONOTCACHEDB', true);
984
+		}
985
+		// add no cache headers
986
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
987
+		// plus a little extra for nginx and Google Chrome
988
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
989
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
990
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
991
+	}
992
+
993
+
994
+
995
+	/**
996
+	 *    extra_nocache_headers
997
+	 *
998
+	 * @access    public
999
+	 * @param $headers
1000
+	 * @return    array
1001
+	 */
1002
+	public static function extra_nocache_headers($headers)
1003
+	{
1004
+		// for NGINX
1005
+		$headers['X-Accel-Expires'] = 0;
1006
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1007
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1008
+		return $headers;
1009
+	}
1010
+
1011
+
1012
+
1013
+	/**
1014
+	 *    nocache_headers
1015
+	 *
1016
+	 * @access    public
1017
+	 * @return    void
1018
+	 */
1019
+	public static function nocache_headers()
1020
+	{
1021
+		nocache_headers();
1022
+	}
1023
+
1024
+
1025
+
1026
+	/**
1027
+	 *    espresso_toolbar_items
1028
+	 *
1029
+	 * @access public
1030
+	 * @param  WP_Admin_Bar $admin_bar
1031
+	 * @return void
1032
+	 */
1033
+	public function espresso_toolbar_items(WP_Admin_Bar $admin_bar)
1034
+	{
1035
+		// if in full M-Mode, or its an AJAX request, or user is NOT an admin
1036
+		if (EE_Maintenance_Mode::instance()->level() == EE_Maintenance_Mode::level_2_complete_maintenance
1037
+			|| defined('DOING_AJAX')
1038
+			|| ! $this->registry->CAP->current_user_can('ee_read_ee', 'ee_admin_bar_menu_top_level')
1039
+		) {
1040
+			return;
1041
+		}
1042
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1043
+		$menu_class = 'espresso_menu_item_class';
1044
+		//we don't use the constants EVENTS_ADMIN_URL or REG_ADMIN_URL
1045
+		//because they're only defined in each of their respective constructors
1046
+		//and this might be a frontend request, in which case they aren't available
1047
+		$events_admin_url = admin_url("admin.php?page=espresso_events");
1048
+		$reg_admin_url = admin_url("admin.php?page=espresso_registrations");
1049
+		$extensions_admin_url = admin_url("admin.php?page=espresso_packages");
1050
+		//Top Level
1051
+		$admin_bar->add_menu(array(
1052
+			'id'    => 'espresso-toolbar',
1053
+			'title' => '<span class="ee-icon ee-icon-ee-cup-thick ee-icon-size-20"></span><span class="ab-label">'
1054
+					   . _x('Event Espresso', 'admin bar menu group label', 'event_espresso')
1055
+					   . '</span>',
1056
+			'href'  => $events_admin_url,
1057
+			'meta'  => array(
1058
+				'title' => __('Event Espresso', 'event_espresso'),
1059
+				'class' => $menu_class . 'first',
1060
+			),
1061
+		));
1062
+		//Events
1063
+		if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events')) {
1064
+			$admin_bar->add_menu(array(
1065
+				'id'     => 'espresso-toolbar-events',
1066
+				'parent' => 'espresso-toolbar',
1067
+				'title'  => __('Events', 'event_espresso'),
1068
+				'href'   => $events_admin_url,
1069
+				'meta'   => array(
1070
+					'title'  => __('Events', 'event_espresso'),
1071
+					'target' => '',
1072
+					'class'  => $menu_class,
1073
+				),
1074
+			));
1075
+		}
1076
+		if ($this->registry->CAP->current_user_can('ee_edit_events', 'ee_admin_bar_menu_espresso-toolbar-events-new')) {
1077
+			//Events Add New
1078
+			$admin_bar->add_menu(array(
1079
+				'id'     => 'espresso-toolbar-events-new',
1080
+				'parent' => 'espresso-toolbar-events',
1081
+				'title'  => __('Add New', 'event_espresso'),
1082
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'create_new'), $events_admin_url),
1083
+				'meta'   => array(
1084
+					'title'  => __('Add New', 'event_espresso'),
1085
+					'target' => '',
1086
+					'class'  => $menu_class,
1087
+				),
1088
+			));
1089
+		}
1090
+		if (is_single() && (get_post_type() == 'espresso_events')) {
1091
+			//Current post
1092
+			global $post;
1093
+			if ($this->registry->CAP->current_user_can('ee_edit_event',
1094
+				'ee_admin_bar_menu_espresso-toolbar-events-edit', $post->ID)
1095
+			) {
1096
+				//Events Edit Current Event
1097
+				$admin_bar->add_menu(array(
1098
+					'id'     => 'espresso-toolbar-events-edit',
1099
+					'parent' => 'espresso-toolbar-events',
1100
+					'title'  => __('Edit Event', 'event_espresso'),
1101
+					'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'edit', 'post' => $post->ID),
1102
+						$events_admin_url),
1103
+					'meta'   => array(
1104
+						'title'  => __('Edit Event', 'event_espresso'),
1105
+						'target' => '',
1106
+						'class'  => $menu_class,
1107
+					),
1108
+				));
1109
+			}
1110
+		}
1111
+		//Events View
1112
+		if ($this->registry->CAP->current_user_can('ee_read_events',
1113
+			'ee_admin_bar_menu_espresso-toolbar-events-view')
1114
+		) {
1115
+			$admin_bar->add_menu(array(
1116
+				'id'     => 'espresso-toolbar-events-view',
1117
+				'parent' => 'espresso-toolbar-events',
1118
+				'title'  => __('View', 'event_espresso'),
1119
+				'href'   => $events_admin_url,
1120
+				'meta'   => array(
1121
+					'title'  => __('View', 'event_espresso'),
1122
+					'target' => '',
1123
+					'class'  => $menu_class,
1124
+				),
1125
+			));
1126
+		}
1127
+		if ($this->registry->CAP->current_user_can('ee_read_events', 'ee_admin_bar_menu_espresso-toolbar-events-all')) {
1128
+			//Events View All
1129
+			$admin_bar->add_menu(array(
1130
+				'id'     => 'espresso-toolbar-events-all',
1131
+				'parent' => 'espresso-toolbar-events-view',
1132
+				'title'  => __('All', 'event_espresso'),
1133
+				'href'   => $events_admin_url,
1134
+				'meta'   => array(
1135
+					'title'  => __('All', 'event_espresso'),
1136
+					'target' => '',
1137
+					'class'  => $menu_class,
1138
+				),
1139
+			));
1140
+		}
1141
+		if ($this->registry->CAP->current_user_can('ee_read_events',
1142
+			'ee_admin_bar_menu_espresso-toolbar-events-today')
1143
+		) {
1144
+			//Events View Today
1145
+			$admin_bar->add_menu(array(
1146
+				'id'     => 'espresso-toolbar-events-today',
1147
+				'parent' => 'espresso-toolbar-events-view',
1148
+				'title'  => __('Today', 'event_espresso'),
1149
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1150
+					$events_admin_url),
1151
+				'meta'   => array(
1152
+					'title'  => __('Today', 'event_espresso'),
1153
+					'target' => '',
1154
+					'class'  => $menu_class,
1155
+				),
1156
+			));
1157
+		}
1158
+		if ($this->registry->CAP->current_user_can('ee_read_events',
1159
+			'ee_admin_bar_menu_espresso-toolbar-events-month')
1160
+		) {
1161
+			//Events View This Month
1162
+			$admin_bar->add_menu(array(
1163
+				'id'     => 'espresso-toolbar-events-month',
1164
+				'parent' => 'espresso-toolbar-events-view',
1165
+				'title'  => __('This Month', 'event_espresso'),
1166
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1167
+					$events_admin_url),
1168
+				'meta'   => array(
1169
+					'title'  => __('This Month', 'event_espresso'),
1170
+					'target' => '',
1171
+					'class'  => $menu_class,
1172
+				),
1173
+			));
1174
+		}
1175
+		//Registration Overview
1176
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1177
+			'ee_admin_bar_menu_espresso-toolbar-registrations')
1178
+		) {
1179
+			$admin_bar->add_menu(array(
1180
+				'id'     => 'espresso-toolbar-registrations',
1181
+				'parent' => 'espresso-toolbar',
1182
+				'title'  => __('Registrations', 'event_espresso'),
1183
+				'href'   => $reg_admin_url,
1184
+				'meta'   => array(
1185
+					'title'  => __('Registrations', 'event_espresso'),
1186
+					'target' => '',
1187
+					'class'  => $menu_class,
1188
+				),
1189
+			));
1190
+		}
1191
+		//Registration Overview Today
1192
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1193
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today')
1194
+		) {
1195
+			$admin_bar->add_menu(array(
1196
+				'id'     => 'espresso-toolbar-registrations-today',
1197
+				'parent' => 'espresso-toolbar-registrations',
1198
+				'title'  => __('Today', 'event_espresso'),
1199
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'today'),
1200
+					$reg_admin_url),
1201
+				'meta'   => array(
1202
+					'title'  => __('Today', 'event_espresso'),
1203
+					'target' => '',
1204
+					'class'  => $menu_class,
1205
+				),
1206
+			));
1207
+		}
1208
+		//Registration Overview Today Completed
1209
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1210
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-approved')
1211
+		) {
1212
+			$admin_bar->add_menu(array(
1213
+				'id'     => 'espresso-toolbar-registrations-today-approved',
1214
+				'parent' => 'espresso-toolbar-registrations-today',
1215
+				'title'  => __('Approved', 'event_espresso'),
1216
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1217
+					'action'      => 'default',
1218
+					'status'      => 'today',
1219
+					'_reg_status' => EEM_Registration::status_id_approved,
1220
+				), $reg_admin_url),
1221
+				'meta'   => array(
1222
+					'title'  => __('Approved', 'event_espresso'),
1223
+					'target' => '',
1224
+					'class'  => $menu_class,
1225
+				),
1226
+			));
1227
+		}
1228
+		//Registration Overview Today Pending\
1229
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1230
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-pending')
1231
+		) {
1232
+			$admin_bar->add_menu(array(
1233
+				'id'     => 'espresso-toolbar-registrations-today-pending',
1234
+				'parent' => 'espresso-toolbar-registrations-today',
1235
+				'title'  => __('Pending', 'event_espresso'),
1236
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1237
+					'action'     => 'default',
1238
+					'status'     => 'today',
1239
+					'reg_status' => EEM_Registration::status_id_pending_payment,
1240
+				), $reg_admin_url),
1241
+				'meta'   => array(
1242
+					'title'  => __('Pending Payment', 'event_espresso'),
1243
+					'target' => '',
1244
+					'class'  => $menu_class,
1245
+				),
1246
+			));
1247
+		}
1248
+		//Registration Overview Today Incomplete
1249
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1250
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-not-approved')
1251
+		) {
1252
+			$admin_bar->add_menu(array(
1253
+				'id'     => 'espresso-toolbar-registrations-today-not-approved',
1254
+				'parent' => 'espresso-toolbar-registrations-today',
1255
+				'title'  => __('Not Approved', 'event_espresso'),
1256
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1257
+					'action'      => 'default',
1258
+					'status'      => 'today',
1259
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1260
+				), $reg_admin_url),
1261
+				'meta'   => array(
1262
+					'title'  => __('Not Approved', 'event_espresso'),
1263
+					'target' => '',
1264
+					'class'  => $menu_class,
1265
+				),
1266
+			));
1267
+		}
1268
+		//Registration Overview Today Incomplete
1269
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1270
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-cancelled')
1271
+		) {
1272
+			$admin_bar->add_menu(array(
1273
+				'id'     => 'espresso-toolbar-registrations-today-cancelled',
1274
+				'parent' => 'espresso-toolbar-registrations-today',
1275
+				'title'  => __('Cancelled', 'event_espresso'),
1276
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1277
+					'action'      => 'default',
1278
+					'status'      => 'today',
1279
+					'_reg_status' => EEM_Registration::status_id_cancelled,
1280
+				), $reg_admin_url),
1281
+				'meta'   => array(
1282
+					'title'  => __('Cancelled', 'event_espresso'),
1283
+					'target' => '',
1284
+					'class'  => $menu_class,
1285
+				),
1286
+			));
1287
+		}
1288
+		//Registration Overview This Month
1289
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1290
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month')
1291
+		) {
1292
+			$admin_bar->add_menu(array(
1293
+				'id'     => 'espresso-toolbar-registrations-month',
1294
+				'parent' => 'espresso-toolbar-registrations',
1295
+				'title'  => __('This Month', 'event_espresso'),
1296
+				'href'   => EEH_URL::add_query_args_and_nonce(array('action' => 'default', 'status' => 'month'),
1297
+					$reg_admin_url),
1298
+				'meta'   => array(
1299
+					'title'  => __('This Month', 'event_espresso'),
1300
+					'target' => '',
1301
+					'class'  => $menu_class,
1302
+				),
1303
+			));
1304
+		}
1305
+		//Registration Overview This Month Approved
1306
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1307
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-approved')
1308
+		) {
1309
+			$admin_bar->add_menu(array(
1310
+				'id'     => 'espresso-toolbar-registrations-month-approved',
1311
+				'parent' => 'espresso-toolbar-registrations-month',
1312
+				'title'  => __('Approved', 'event_espresso'),
1313
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1314
+					'action'      => 'default',
1315
+					'status'      => 'month',
1316
+					'_reg_status' => EEM_Registration::status_id_approved,
1317
+				), $reg_admin_url),
1318
+				'meta'   => array(
1319
+					'title'  => __('Approved', 'event_espresso'),
1320
+					'target' => '',
1321
+					'class'  => $menu_class,
1322
+				),
1323
+			));
1324
+		}
1325
+		//Registration Overview This Month Pending
1326
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1327
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-pending')
1328
+		) {
1329
+			$admin_bar->add_menu(array(
1330
+				'id'     => 'espresso-toolbar-registrations-month-pending',
1331
+				'parent' => 'espresso-toolbar-registrations-month',
1332
+				'title'  => __('Pending', 'event_espresso'),
1333
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1334
+					'action'      => 'default',
1335
+					'status'      => 'month',
1336
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1337
+				), $reg_admin_url),
1338
+				'meta'   => array(
1339
+					'title'  => __('Pending', 'event_espresso'),
1340
+					'target' => '',
1341
+					'class'  => $menu_class,
1342
+				),
1343
+			));
1344
+		}
1345
+		//Registration Overview This Month Not Approved
1346
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1347
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-not-approved')
1348
+		) {
1349
+			$admin_bar->add_menu(array(
1350
+				'id'     => 'espresso-toolbar-registrations-month-not-approved',
1351
+				'parent' => 'espresso-toolbar-registrations-month',
1352
+				'title'  => __('Not Approved', 'event_espresso'),
1353
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1354
+					'action'      => 'default',
1355
+					'status'      => 'month',
1356
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1357
+				), $reg_admin_url),
1358
+				'meta'   => array(
1359
+					'title'  => __('Not Approved', 'event_espresso'),
1360
+					'target' => '',
1361
+					'class'  => $menu_class,
1362
+				),
1363
+			));
1364
+		}
1365
+		//Registration Overview This Month Cancelled
1366
+		if ($this->registry->CAP->current_user_can('ee_read_registrations',
1367
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-cancelled')
1368
+		) {
1369
+			$admin_bar->add_menu(array(
1370
+				'id'     => 'espresso-toolbar-registrations-month-cancelled',
1371
+				'parent' => 'espresso-toolbar-registrations-month',
1372
+				'title'  => __('Cancelled', 'event_espresso'),
1373
+				'href'   => EEH_URL::add_query_args_and_nonce(array(
1374
+					'action'      => 'default',
1375
+					'status'      => 'month',
1376
+					'_reg_status' => EEM_Registration::status_id_cancelled,
1377
+				), $reg_admin_url),
1378
+				'meta'   => array(
1379
+					'title'  => __('Cancelled', 'event_espresso'),
1380
+					'target' => '',
1381
+					'class'  => $menu_class,
1382
+				),
1383
+			));
1384
+		}
1385
+		//Extensions & Services
1386
+		if ($this->registry->CAP->current_user_can('ee_read_ee',
1387
+			'ee_admin_bar_menu_espresso-toolbar-extensions-and-services')
1388
+		) {
1389
+			$admin_bar->add_menu(array(
1390
+				'id'     => 'espresso-toolbar-extensions-and-services',
1391
+				'parent' => 'espresso-toolbar',
1392
+				'title'  => __('Extensions & Services', 'event_espresso'),
1393
+				'href'   => $extensions_admin_url,
1394
+				'meta'   => array(
1395
+					'title'  => __('Extensions & Services', 'event_espresso'),
1396
+					'target' => '',
1397
+					'class'  => $menu_class,
1398
+				),
1399
+			));
1400
+		}
1401
+	}
1402
+
1403
+
1404
+
1405
+	/**
1406
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1407
+	 * never returned with the function.
1408
+	 *
1409
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1410
+	 * @return array
1411
+	 */
1412
+	public function remove_pages_from_wp_list_pages($exclude_array)
1413
+	{
1414
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1415
+	}
1416
+
1417
+
1418
+
1419
+
1420
+
1421
+
1422
+	/***********************************************        WP_ENQUEUE_SCRIPTS HOOK         ***********************************************/
1423
+	/**
1424
+	 *    wp_enqueue_scripts
1425
+	 *
1426
+	 * @access    public
1427
+	 * @return    void
1428
+	 */
1429
+	public function wp_enqueue_scripts()
1430
+	{
1431
+		// unlike other systems, EE_System_scripts loading is turned ON by default, but prior to the init hook, can be turned off via: add_filter( 'FHEE_load_EE_System_scripts', '__return_false' );
1432
+		if (apply_filters('FHEE_load_EE_System_scripts', true)) {
1433
+			// jquery_validate loading is turned OFF by default, but prior to the wp_enqueue_scripts hook, can be turned back on again via:  add_filter( 'FHEE_load_jquery_validate', '__return_true' );
1434
+			if (apply_filters('FHEE_load_jquery_validate', false)) {
1435
+				// register jQuery Validate and additional methods
1436
+				wp_register_script('jquery-validate', EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
1437
+					array('jquery'), '1.15.0', true);
1438
+				wp_register_script('jquery-validate-extra-methods',
1439
+					EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
1440
+					array('jquery', 'jquery-validate'), '1.15.0', true);
1441
+			}
1442
+		}
1443
+	}
1444 1444
 
1445 1445
 
1446 1446
 
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -185,7 +185,7 @@  discard block
 block discarded – undo
185 185
     {
186 186
         // set autoloaders for all of the classes implementing EEI_Plugin_API
187 187
         // which provide helpers for EE plugin authors to more easily register certain components with EE.
188
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
188
+        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'plugin_api');
189 189
         //load and setup EE_Capabilities
190 190
         $this->registry->load_core('Capabilities');
191 191
         do_action('AHEE__EE_System__load_espresso_addons');
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
                 && $_GET['activate'] === 'true'
206 206
             )
207 207
         ) {
208
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
208
+            include_once EE_THIRD_PARTY.'wp-api-basic-auth'.DS.'basic-auth.php';
209 209
         }
210 210
         $this->_maybe_brew_regular();
211 211
         do_action('AHEE__EE_System__load_espresso_addons__complete');
@@ -225,8 +225,8 @@  discard block
 block discarded – undo
225 225
      */
226 226
     private function _maybe_brew_regular()
227 227
     {
228
-        if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
229
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
228
+        if (( ! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH.'brewing_regular.php')) {
229
+            require_once EE_CAFF_PATH.'brewing_regular.php';
230 230
         }
231 231
     }
232 232
 
@@ -757,8 +757,8 @@  discard block
 block discarded – undo
757 757
                 'event_espresso');
758 758
             $msg .= '<ul>';
759 759
             foreach ($class_names as $class_name) {
760
-                $msg .= '<li><b>Event Espresso - ' . str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
761
-                        $class_name) . '</b></li>';
760
+                $msg .= '<li><b>Event Espresso - '.str_replace(array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
761
+                        $class_name).'</b></li>';
762 762
             }
763 763
             $msg .= '</ul>';
764 764
             $msg .= __('Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
@@ -910,8 +910,8 @@  discard block
 block discarded – undo
910 910
     {
911 911
         do_action('AHEE__EE_System__core_loaded_and_ready');
912 912
         // load_espresso_template_tags
913
-        if (is_readable(EE_PUBLIC . 'template_tags.php')) {
914
-            require_once(EE_PUBLIC . 'template_tags.php');
913
+        if (is_readable(EE_PUBLIC.'template_tags.php')) {
914
+            require_once(EE_PUBLIC.'template_tags.php');
915 915
         }
916 916
         do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
917 917
         $this->registry->load_core('Session');
@@ -1056,7 +1056,7 @@  discard block
 block discarded – undo
1056 1056
             'href'  => $events_admin_url,
1057 1057
             'meta'  => array(
1058 1058
                 'title' => __('Event Espresso', 'event_espresso'),
1059
-                'class' => $menu_class . 'first',
1059
+                'class' => $menu_class.'first',
1060 1060
             ),
1061 1061
         ));
1062 1062
         //Events
@@ -1433,10 +1433,10 @@  discard block
 block discarded – undo
1433 1433
             // jquery_validate loading is turned OFF by default, but prior to the wp_enqueue_scripts hook, can be turned back on again via:  add_filter( 'FHEE_load_jquery_validate', '__return_true' );
1434 1434
             if (apply_filters('FHEE_load_jquery_validate', false)) {
1435 1435
                 // register jQuery Validate and additional methods
1436
-                wp_register_script('jquery-validate', EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
1436
+                wp_register_script('jquery-validate', EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.min.js',
1437 1437
                     array('jquery'), '1.15.0', true);
1438 1438
                 wp_register_script('jquery-validate-extra-methods',
1439
-                    EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
1439
+                    EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.additional-methods.min.js',
1440 1440
                     array('jquery', 'jquery-validate'), '1.15.0', true);
1441 1441
             }
1442 1442
         }
Please login to merge, or discard this patch.
core/libraries/rest_api/controllers/model/Read.php 1 patch
Indentation   +1240 added lines, -1240 removed lines patch added patch discarded remove patch
@@ -9,7 +9,7 @@  discard block
 block discarded – undo
9 9
 use EE_Datetime_Field;
10 10
 
11 11
 if (! defined('EVENT_ESPRESSO_VERSION')) {
12
-    exit('No direct script access allowed');
12
+	exit('No direct script access allowed');
13 13
 }
14 14
 
15 15
 
@@ -27,1245 +27,1245 @@  discard block
 block discarded – undo
27 27
 
28 28
 
29 29
 
30
-    /**
31
-     * @var Calculated_Model_Fields
32
-     */
33
-    protected $_fields_calculator;
34
-
35
-
36
-
37
-    /**
38
-     * Read constructor.
39
-     */
40
-    public function __construct()
41
-    {
42
-        parent::__construct();
43
-        $this->_fields_calculator = new Calculated_Model_Fields();
44
-    }
45
-
46
-
47
-
48
-    /**
49
-     * Handles requests to get all (or a filtered subset) of entities for a particular model
50
-     *
51
-     * @param \WP_REST_Request $request
52
-     * @return \WP_REST_Response|\WP_Error
53
-     */
54
-    public static function handle_request_get_all(\WP_REST_Request $request)
55
-    {
56
-        $controller = new Read();
57
-        try {
58
-            $matches = $controller->parse_route(
59
-                $request->get_route(),
60
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~',
61
-                array('version', 'model')
62
-            );
63
-            $controller->set_requested_version($matches['version']);
64
-            $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
65
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
66
-                return $controller->send_response(
67
-                    new \WP_Error(
68
-                        'endpoint_parsing_error',
69
-                        sprintf(
70
-                            __('There is no model for endpoint %s. Please contact event espresso support',
71
-                                'event_espresso'),
72
-                            $model_name_singular
73
-                        )
74
-                    )
75
-                );
76
-            }
77
-            return $controller->send_response(
78
-                $controller->get_entities_from_model(
79
-                    $controller->get_model_version_info()->load_model($model_name_singular),
80
-                    $request
81
-                )
82
-            );
83
-        } catch (\Exception $e) {
84
-            return $controller->send_response($e);
85
-        }
86
-    }
87
-
88
-
89
-
90
-    /**
91
-     * Prepares and returns schema for any OPTIONS request.
92
-     *
93
-     * @param string $model_name Something like `Event` or `Registration`
94
-     * @param string $version    The API endpoint version being used.
95
-     * @return array
96
-     */
97
-    public static function handle_schema_request($model_name, $version)
98
-    {
99
-        $controller = new Read();
100
-        try {
101
-            $controller->set_requested_version($version);
102
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name)) {
103
-                return array();
104
-            }
105
-            //get the model for this version
106
-            $model = $controller->get_model_version_info()->load_model($model_name);
107
-            $model_schema = new JsonModelSchema($model);
108
-            return $model_schema->getModelSchemaForRelations(
109
-                $controller->get_model_version_info()->relation_settings($model),
110
-                $controller->_customize_schema_for_rest_response(
111
-                    $model,
112
-                    $model_schema->getModelSchemaForFields(
113
-                        $controller->get_model_version_info()->fields_on_model_in_this_version($model),
114
-                        $model_schema->getInitialSchemaStructure()
115
-                    )
116
-                )
117
-            );
118
-        } catch (\Exception $e) {
119
-            return array();
120
-        }
121
-    }
122
-
123
-
124
-
125
-    /**
126
-     * This loops through each field in the given schema for the model and does the following:
127
-     * - add any extra fields that are REST API specific and related to existing fields.
128
-     * - transform default values into the correct format for a REST API response.
129
-     *
130
-     * @param \EEM_Base $model
131
-     * @param array     $schema
132
-     * @return array  The final schema.
133
-     */
134
-    protected function _customize_schema_for_rest_response(\EEM_Base $model, array $schema)
135
-    {
136
-        foreach ($this->get_model_version_info()->fields_on_model_in_this_version($model) as $field_name => $field) {
137
-            $schema = $this->_translate_defaults_for_rest_response(
138
-                $field_name,
139
-                $field,
140
-                $this->_maybe_add_extra_fields_to_schema($field_name, $field, $schema)
141
-            );
142
-        }
143
-        return $schema;
144
-    }
145
-
146
-
147
-
148
-    /**
149
-     * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
150
-     * response.
151
-     *
152
-     * @param                      $field_name
153
-     * @param \EE_Model_Field_Base $field
154
-     * @param array                $schema
155
-     * @return array
156
-     */
157
-    protected function _translate_defaults_for_rest_response($field_name, \EE_Model_Field_Base $field, array $schema)
158
-    {
159
-        if (isset($schema['properties'][$field_name]['default'])) {
160
-            if (is_array($schema['properties'][$field_name]['default'])) {
161
-                foreach ($schema['properties'][$field_name]['default'] as $default_key => $default_value) {
162
-                    if ($default_key === 'raw') {
163
-                        $schema['properties'][$field_name]['default'][$default_key] = Model_Data_Translator::prepare_field_value_for_json(
164
-                            $field,
165
-                            $default_value,
166
-                            $this->get_model_version_info()->requested_version()
167
-                        );
168
-                    }
169
-                }
170
-            } else {
171
-                $schema['properties'][$field_name]['default'] = Model_Data_Translator::prepare_field_value_for_json(
172
-                    $field,
173
-                    $schema['properties'][$field_name]['default'],
174
-                    $this->get_model_version_info()->requested_version()
175
-                );
176
-            }
177
-        }
178
-        return $schema;
179
-    }
180
-
181
-
182
-
183
-    /**
184
-     * Adds additional fields to the schema
185
-     * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
186
-     * needs to be added to the schema.
187
-     *
188
-     * @param                      $field_name
189
-     * @param \EE_Model_Field_Base $field
190
-     * @param array                $schema
191
-     * @return array
192
-     */
193
-    protected function _maybe_add_extra_fields_to_schema($field_name, \EE_Model_Field_Base $field, array $schema)
194
-    {
195
-        if ($field instanceof EE_Datetime_Field) {
196
-            $schema['properties'][$field_name . '_gmt'] = $field->getSchema();
197
-            //modify the description
198
-            $schema['properties'][$field_name . '_gmt']['description'] = sprintf(
199
-                esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
200
-                $field->get_nicename()
201
-            );
202
-        }
203
-        return $schema;
204
-    }
205
-
206
-
207
-
208
-    /**
209
-     * Used to figure out the route from the request when a `WP_REST_Request` object is not available
210
-     *
211
-     * @return string
212
-     */
213
-    protected function get_route_from_request()
214
-    {
215
-        if (isset($GLOBALS['wp'])
216
-            && $GLOBALS['wp'] instanceof \WP
217
-            && isset($GLOBALS['wp']->query_vars['rest_route'])
218
-        ) {
219
-            return $GLOBALS['wp']->query_vars['rest_route'];
220
-        } else {
221
-            return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
222
-        }
223
-    }
224
-
225
-
226
-
227
-    /**
228
-     * Gets a single entity related to the model indicated in the path and its id
229
-     *
230
-     * @param \WP_REST_Request $request
231
-     * @return \WP_REST_Response|\WP_Error
232
-     */
233
-    public static function handle_request_get_one(\WP_REST_Request $request)
234
-    {
235
-        $controller = new Read();
236
-        try {
237
-            $matches = $controller->parse_route(
238
-                $request->get_route(),
239
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~',
240
-                array('version', 'model', 'id'));
241
-            $controller->set_requested_version($matches['version']);
242
-            $model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
243
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
244
-                return $controller->send_response(
245
-                    new \WP_Error(
246
-                        'endpoint_parsing_error',
247
-                        sprintf(
248
-                            __('There is no model for endpoint %s. Please contact event espresso support',
249
-                                'event_espresso'),
250
-                            $model_name_singular
251
-                        )
252
-                    )
253
-                );
254
-            }
255
-            return $controller->send_response(
256
-                $controller->get_entity_from_model(
257
-                    $controller->get_model_version_info()->load_model($model_name_singular),
258
-                    $request
259
-                )
260
-            );
261
-        } catch (\Exception $e) {
262
-            return $controller->send_response($e);
263
-        }
264
-    }
265
-
266
-
267
-
268
-    /**
269
-     * Gets all the related entities (or if its a belongs-to relation just the one)
270
-     * to the item with the given id
271
-     *
272
-     * @param \WP_REST_Request $request
273
-     * @return \WP_REST_Response|\WP_Error
274
-     */
275
-    public static function handle_request_get_related(\WP_REST_Request $request)
276
-    {
277
-        $controller = new Read();
278
-        try {
279
-            $matches = $controller->parse_route(
280
-                $request->get_route(),
281
-                '~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~',
282
-                array('version', 'model', 'id', 'related_model')
283
-            );
284
-            $controller->set_requested_version($matches['version']);
285
-            $main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
286
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
287
-                return $controller->send_response(
288
-                    new \WP_Error(
289
-                        'endpoint_parsing_error',
290
-                        sprintf(
291
-                            __('There is no model for endpoint %s. Please contact event espresso support',
292
-                                'event_espresso'),
293
-                            $main_model_name_singular
294
-                        )
295
-                    )
296
-                );
297
-            }
298
-            $main_model = $controller->get_model_version_info()->load_model($main_model_name_singular);
299
-            //assume the related model name is plural and try to find the model's name
300
-            $related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']);
301
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
302
-                //so the word didn't singularize well. Maybe that's just because it's a singular word?
303
-                $related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']);
304
-            }
305
-            if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
306
-                return $controller->send_response(
307
-                    new \WP_Error(
308
-                        'endpoint_parsing_error',
309
-                        sprintf(
310
-                            __('There is no model for endpoint %s. Please contact event espresso support',
311
-                                'event_espresso'),
312
-                            $related_model_name_singular
313
-                        )
314
-                    )
315
-                );
316
-            }
317
-            return $controller->send_response(
318
-                $controller->get_entities_from_relation(
319
-                    $request->get_param('id'),
320
-                    $main_model->related_settings_for($related_model_name_singular),
321
-                    $request
322
-                )
323
-            );
324
-        } catch (\Exception $e) {
325
-            return $controller->send_response($e);
326
-        }
327
-    }
328
-
329
-
330
-
331
-    /**
332
-     * Gets a collection for the given model and filters
333
-     *
334
-     * @param \EEM_Base        $model
335
-     * @param \WP_REST_Request $request
336
-     * @return array|\WP_Error
337
-     */
338
-    public function get_entities_from_model($model, $request)
339
-    {
340
-        $query_params = $this->create_model_query_params($model, $request->get_params());
341
-        if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
342
-            $model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
343
-            return new \WP_Error(
344
-                sprintf('rest_%s_cannot_list', $model_name_plural),
345
-                sprintf(
346
-                    __('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
347
-                    $model_name_plural,
348
-                    Capabilities::get_missing_permissions_string($model, $query_params['caps'])
349
-                ),
350
-                array('status' => 403)
351
-            );
352
-        }
353
-        if (! $request->get_header('no_rest_headers')) {
354
-            $this->_set_headers_from_query_params($model, $query_params);
355
-        }
356
-        /** @type array $results */
357
-        $results = $model->get_all_wpdb_results($query_params);
358
-        $nice_results = array();
359
-        foreach ($results as $result) {
360
-            $nice_results[] = $this->create_entity_from_wpdb_result(
361
-                $model,
362
-                $result,
363
-                $request
364
-            );
365
-        }
366
-        return $nice_results;
367
-    }
368
-
369
-
370
-
371
-    /**
372
-     * @param array                   $primary_model_query_params query params for finding the item from which
373
-     *                                                            relations will be based
374
-     * @param \EE_Model_Relation_Base $relation
375
-     * @param \WP_REST_Request        $request
376
-     * @return \WP_Error|array
377
-     */
378
-    protected function _get_entities_from_relation($primary_model_query_params, $relation, $request)
379
-    {
380
-        $context = $this->validate_context($request->get_param('caps'));
381
-        $model = $relation->get_this_model();
382
-        $related_model = $relation->get_other_model();
383
-        if (! isset($primary_model_query_params[0])) {
384
-            $primary_model_query_params[0] = array();
385
-        }
386
-        //check if they can access the 1st model object
387
-        $primary_model_query_params = array(
388
-            0       => $primary_model_query_params[0],
389
-            'limit' => 1,
390
-        );
391
-        if ($model instanceof \EEM_Soft_Delete_Base) {
392
-            $primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params);
393
-        }
394
-        $restricted_query_params = $primary_model_query_params;
395
-        $restricted_query_params['caps'] = $context;
396
-        $this->_set_debug_info('main model query params', $restricted_query_params);
397
-        $this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context));
398
-        if (
399
-        ! (
400
-            Capabilities::current_user_has_partial_access_to($related_model, $context)
401
-            && $model->exists($restricted_query_params)
402
-        )
403
-        ) {
404
-            if ($relation instanceof \EE_Belongs_To_Relation) {
405
-                $related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
406
-            } else {
407
-                $related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name());
408
-            }
409
-            return new \WP_Error(
410
-                sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
411
-                sprintf(
412
-                    __('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
413
-                        'event_espresso'),
414
-                    $related_model_name_maybe_plural,
415
-                    $relation->get_this_model()->get_this_model_name(),
416
-                    implode(
417
-                        ',',
418
-                        array_keys(
419
-                            Capabilities::get_missing_permissions($related_model, $context)
420
-                        )
421
-                    )
422
-                ),
423
-                array('status' => 403)
424
-            );
425
-        }
426
-        $query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params());
427
-        foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
428
-            $query_params[0][$relation->get_this_model()->get_this_model_name()
429
-                             . '.'
430
-                             . $where_condition_key] = $where_condition_value;
431
-        }
432
-        $query_params['default_where_conditions'] = 'none';
433
-        $query_params['caps'] = $context;
434
-        if (! $request->get_header('no_rest_headers')) {
435
-            $this->_set_headers_from_query_params($relation->get_other_model(), $query_params);
436
-        }
437
-        /** @type array $results */
438
-        $results = $relation->get_other_model()->get_all_wpdb_results($query_params);
439
-        $nice_results = array();
440
-        foreach ($results as $result) {
441
-            $nice_result = $this->create_entity_from_wpdb_result(
442
-                $relation->get_other_model(),
443
-                $result,
444
-                $request
445
-            );
446
-            if ($relation instanceof \EE_HABTM_Relation) {
447
-                //put the unusual stuff (properties from the HABTM relation) first, and make sure
448
-                //if there are conflicts we prefer the properties from the main model
449
-                $join_model_result = $this->create_entity_from_wpdb_result(
450
-                    $relation->get_join_model(),
451
-                    $result,
452
-                    $request
453
-                );
454
-                $joined_result = array_merge($nice_result, $join_model_result);
455
-                //but keep the meta stuff from the main model
456
-                if (isset($nice_result['meta'])) {
457
-                    $joined_result['meta'] = $nice_result['meta'];
458
-                }
459
-                $nice_result = $joined_result;
460
-            }
461
-            $nice_results[] = $nice_result;
462
-        }
463
-        if ($relation instanceof \EE_Belongs_To_Relation) {
464
-            return array_shift($nice_results);
465
-        } else {
466
-            return $nice_results;
467
-        }
468
-    }
469
-
470
-
471
-
472
-    /**
473
-     * Gets the collection for given relation object
474
-     * The same as Read::get_entities_from_model(), except if the relation
475
-     * is a HABTM relation, in which case it merges any non-foreign-key fields from
476
-     * the join-model-object into the results
477
-     *
478
-     * @param string                  $id the ID of the thing we are fetching related stuff from
479
-     * @param \EE_Model_Relation_Base $relation
480
-     * @param \WP_REST_Request        $request
481
-     * @return array|\WP_Error
482
-     * @throws \EE_Error
483
-     */
484
-    public function get_entities_from_relation($id, $relation, $request)
485
-    {
486
-        if (! $relation->get_this_model()->has_primary_key_field()) {
487
-            throw new \EE_Error(
488
-                sprintf(
489
-                    __('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
490
-                        'event_espresso'),
491
-                    $relation->get_this_model()->get_this_model_name()
492
-                )
493
-            );
494
-        }
495
-        return $this->_get_entities_from_relation(
496
-            array(
497
-                array(
498
-                    $relation->get_this_model()->primary_key_name() => $id,
499
-                ),
500
-            ),
501
-            $relation,
502
-            $request
503
-        );
504
-    }
505
-
506
-
507
-
508
-    /**
509
-     * Sets the headers that are based on the model and query params,
510
-     * like the total records. This should only be called on the original request
511
-     * from the client, not on subsequent internal
512
-     *
513
-     * @param \EEM_Base $model
514
-     * @param array     $query_params
515
-     * @return void
516
-     */
517
-    protected function _set_headers_from_query_params($model, $query_params)
518
-    {
519
-        $this->_set_debug_info('model query params', $query_params);
520
-        $this->_set_debug_info('missing caps',
521
-            Capabilities::get_missing_permissions_string($model, $query_params['caps']));
522
-        //normally the limit to a 2-part array, where the 2nd item is the limit
523
-        if (! isset($query_params['limit'])) {
524
-            $query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
525
-        }
526
-        if (is_array($query_params['limit'])) {
527
-            $limit_parts = $query_params['limit'];
528
-        } else {
529
-            $limit_parts = explode(',', $query_params['limit']);
530
-            if (count($limit_parts) == 1) {
531
-                $limit_parts = array(0, $limit_parts[0]);
532
-            }
533
-        }
534
-        //remove the group by and having parts of the query, as those will
535
-        //make the sql query return an array of values, instead of just a single value
536
-        unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
537
-        $count = $model->count($query_params, null, true);
538
-        $pages = $count / $limit_parts[1];
539
-        $this->_set_response_header('Total', $count, false);
540
-        $this->_set_response_header('PageSize', $limit_parts[1], false);
541
-        $this->_set_response_header('TotalPages', ceil($pages), false);
542
-    }
543
-
544
-
545
-
546
-    /**
547
-     * Changes database results into REST API entities
548
-     *
549
-     * @param \EEM_Base        $model
550
-     * @param array            $db_row     like results from $wpdb->get_results()
551
-     * @param \WP_REST_Request $rest_request
552
-     * @param string           $deprecated no longer used
553
-     * @return array ready for being converted into json for sending to client
554
-     */
555
-    public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null)
556
-    {
557
-        if (! $rest_request instanceof \WP_REST_Request) {
558
-            //ok so this was called in the old style, where the 3rd arg was
559
-            //$include, and the 4th arg was $context
560
-            //now setup the request just to avoid fatal errors, although we won't be able
561
-            //to truly make use of it because it's kinda devoid of info
562
-            $rest_request = new \WP_REST_Request();
563
-            $rest_request->set_param('include', $rest_request);
564
-            $rest_request->set_param('caps', $deprecated);
565
-        }
566
-        if ($rest_request->get_param('caps') == null) {
567
-            $rest_request->set_param('caps', \EEM_Base::caps_read);
568
-        }
569
-        $entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row);
570
-        $entity_array = $this->_add_extra_fields($model, $db_row, $entity_array);
571
-        $entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array);
572
-        $entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request);
573
-        $entity_array = apply_filters('FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
574
-            $entity_array, $model, $rest_request->get_param('caps'), $rest_request, $this);
575
-        $entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row);
576
-        $entity_array = apply_filters(
577
-            'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
578
-            $entity_array,
579
-            $model,
580
-            $rest_request->get_param('caps'),
581
-            $rest_request,
582
-            $this
583
-        );
584
-        $result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields(
585
-            $entity_array,
586
-            $model,
587
-            $rest_request->get_param('caps'),
588
-            $this->get_model_version_info(),
589
-            $model->get_index_primary_key_string(
590
-                $model->deduce_fields_n_values_from_cols_n_values($db_row)
591
-            )
592
-        );
593
-        $this->_set_debug_info(
594
-            'inaccessible fields',
595
-            array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields))
596
-        );
597
-        return apply_filters(
598
-            'FHEE__Read__create_entity_from_wpdb_results__entity_return',
599
-            $result_without_inaccessible_fields,
600
-            $model,
601
-            $rest_request->get_param('caps')
602
-        );
603
-    }
604
-
605
-
606
-
607
-    /**
608
-     * Creates a REST entity array (JSON object we're going to return in the response, but
609
-     * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
610
-     * from $wpdb->get_row( $sql, ARRAY_A)
611
-     *
612
-     * @param \EEM_Base $model
613
-     * @param array     $db_row
614
-     * @return array entity mostly ready for converting to JSON and sending in the response
615
-     */
616
-    protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row)
617
-    {
618
-        $result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
619
-        $result = array_intersect_key($result,
620
-            $this->get_model_version_info()->fields_on_model_in_this_version($model));
621
-        foreach ($result as $field_name => $raw_field_value) {
622
-            $field_obj = $model->field_settings_for($field_name);
623
-            $field_value = $field_obj->prepare_for_set_from_db($raw_field_value);
624
-            if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) {
625
-                unset($result[$field_name]);
626
-            } elseif (
627
-            $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())
628
-            ) {
629
-                $result[$field_name] = array(
630
-                    'raw'      => $field_obj->prepare_for_get($field_value),
631
-                    'rendered' => $field_obj->prepare_for_pretty_echoing($field_value),
632
-                );
633
-            } elseif (
634
-            $this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())
635
-            ) {
636
-                $result[$field_name] = array(
637
-                    'raw'    => $field_obj->prepare_for_get($field_value),
638
-                    'pretty' => $field_obj->prepare_for_pretty_echoing($field_value),
639
-                );
640
-            } elseif ($field_obj instanceof \EE_Datetime_Field) {
641
-                if ($field_value instanceof \DateTime) {
642
-                    $timezone = $field_value->getTimezone();
643
-                    $field_value->setTimezone(new \DateTimeZone('UTC'));
644
-                    $result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
645
-                        $field_obj,
646
-                        $field_value,
647
-                        $this->get_model_version_info()->requested_version()
648
-                    );
649
-                    $field_value->setTimezone($timezone);
650
-                    $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
651
-                        $field_obj,
652
-                        $field_value,
653
-                        $this->get_model_version_info()->requested_version()
654
-                    );
655
-                }
656
-            } else {
657
-                $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
658
-                    $field_obj,
659
-                    $field_obj->prepare_for_get($field_value),
660
-                    $this->get_model_version_info()->requested_version()
661
-                );
662
-            }
663
-        }
664
-        return $result;
665
-    }
666
-
667
-
668
-
669
-    /**
670
-     * Adds a few extra fields to the entity response
671
-     *
672
-     * @param \EEM_Base $model
673
-     * @param array     $db_row
674
-     * @param array     $entity_array
675
-     * @return array modified entity
676
-     */
677
-    protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array)
678
-    {
679
-        if ($model instanceof \EEM_CPT_Base) {
680
-            $entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
681
-        }
682
-        return $entity_array;
683
-    }
684
-
685
-
686
-
687
-    /**
688
-     * Gets links we want to add to the response
689
-     *
690
-     * @global \WP_REST_Server $wp_rest_server
691
-     * @param \EEM_Base        $model
692
-     * @param array            $db_row
693
-     * @param array            $entity_array
694
-     * @return array the _links item in the entity
695
-     */
696
-    protected function _get_entity_links($model, $db_row, $entity_array)
697
-    {
698
-        //add basic links
699
-        $links = array();
700
-        if ($model->has_primary_key_field()) {
701
-            $links['self'] = array(
702
-                array(
703
-                    'href' => $this->get_versioned_link_to(
704
-                        \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
705
-                        . '/'
706
-                        . $entity_array[$model->primary_key_name()]
707
-                    ),
708
-                ),
709
-            );
710
-        }
711
-        $links['collection'] = array(
712
-            array(
713
-                'href' => $this->get_versioned_link_to(
714
-                    \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
715
-                ),
716
-            ),
717
-        );
718
-        //add links to related models
719
-        if ($model->has_primary_key_field()) {
720
-            foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) {
721
-                $related_model_part = Read::get_related_entity_name($relation_name, $relation_obj);
722
-                $links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(
723
-                    array(
724
-                        'href'   => $this->get_versioned_link_to(
725
-                            \EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
726
-                            . '/'
727
-                            . $entity_array[$model->primary_key_name()]
728
-                            . '/'
729
-                            . $related_model_part
730
-                        ),
731
-                        'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false,
732
-                    ),
733
-                );
734
-            }
735
-        }
736
-        return $links;
737
-    }
738
-
739
-
740
-
741
-    /**
742
-     * Adds the included models indicated in the request to the entity provided
743
-     *
744
-     * @param \EEM_Base        $model
745
-     * @param \WP_REST_Request $rest_request
746
-     * @param array            $entity_array
747
-     * @param array            $db_row
748
-     * @return array the modified entity
749
-     */
750
-    protected function _include_requested_models(
751
-        \EEM_Base $model,
752
-        \WP_REST_Request $rest_request,
753
-        $entity_array,
754
-        $db_row = array()
755
-    ) {
756
-        //if $db_row not included, hope the entity array has what we need
757
-        if (! $db_row) {
758
-            $db_row = $entity_array;
759
-        }
760
-        $includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), '');
761
-        $includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model);
762
-        //if they passed in * or didn't specify any includes, return everything
763
-        if (! in_array('*', $includes_for_this_model)
764
-            && ! empty($includes_for_this_model)
765
-        ) {
766
-            if ($model->has_primary_key_field()) {
767
-                //always include the primary key. ya just gotta know that at least
768
-                $includes_for_this_model[] = $model->primary_key_name();
769
-            }
770
-            if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) {
771
-                $includes_for_this_model[] = '_calculated_fields';
772
-            }
773
-            $entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
774
-        }
775
-        $relation_settings = $this->get_model_version_info()->relation_settings($model);
776
-        foreach ($relation_settings as $relation_name => $relation_obj) {
777
-            $related_fields_to_include = $this->explode_and_get_items_prefixed_with(
778
-                $rest_request->get_param('include'),
779
-                $relation_name
780
-            );
781
-            $related_fields_to_calculate = $this->explode_and_get_items_prefixed_with(
782
-                $rest_request->get_param('calculate'),
783
-                $relation_name
784
-            );
785
-            //did they specify they wanted to include a related model, or
786
-            //specific fields from a related model?
787
-            //or did they specify to calculate a field from a related model?
788
-            if ($related_fields_to_include || $related_fields_to_calculate) {
789
-                //if so, we should include at least some part of the related model
790
-                $pretend_related_request = new \WP_REST_Request();
791
-                $pretend_related_request->set_query_params(
792
-                    array(
793
-                        'caps'      => $rest_request->get_param('caps'),
794
-                        'include'   => $related_fields_to_include,
795
-                        'calculate' => $related_fields_to_calculate,
796
-                    )
797
-                );
798
-                $pretend_related_request->add_header('no_rest_headers', true);
799
-                $primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
800
-                    $model->get_index_primary_key_string(
801
-                        $model->deduce_fields_n_values_from_cols_n_values($db_row)
802
-                    )
803
-                );
804
-                $related_results = $this->_get_entities_from_relation(
805
-                    $primary_model_query_params,
806
-                    $relation_obj,
807
-                    $pretend_related_request
808
-                );
809
-                $entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results
810
-                                                                                              instanceof
811
-                                                                                              \WP_Error
812
-                    ? null
813
-                    : $related_results;
814
-            }
815
-        }
816
-        return $entity_array;
817
-    }
818
-
819
-
820
-
821
-    /**
822
-     * Returns a new array with all the names of models removed. Eg
823
-     * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
824
-     *
825
-     * @param array $arr
826
-     * @return array
827
-     */
828
-    private function _remove_model_names_from_array($arr)
829
-    {
830
-        return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models()));
831
-    }
832
-
833
-
834
-
835
-    /**
836
-     * Gets the calculated fields for the response
837
-     *
838
-     * @param \EEM_Base        $model
839
-     * @param array            $wpdb_row
840
-     * @param \WP_REST_Request $rest_request
841
-     * @return \stdClass the _calculations item in the entity
842
-     */
843
-    protected function _get_entity_calculations($model, $wpdb_row, $rest_request)
844
-    {
845
-        $calculated_fields = $this->explode_and_get_items_prefixed_with(
846
-            $rest_request->get_param('calculate'),
847
-            ''
848
-        );
849
-        //note: setting calculate=* doesn't do anything
850
-        $calculated_fields_to_return = new \stdClass();
851
-        foreach ($calculated_fields as $field_to_calculate) {
852
-            try {
853
-                $calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json(
854
-                    null,
855
-                    $this->_fields_calculator->retrieve_calculated_field_value(
856
-                        $model,
857
-                        $field_to_calculate,
858
-                        $wpdb_row,
859
-                        $rest_request,
860
-                        $this
861
-                    ),
862
-                    $this->get_model_version_info()->requested_version()
863
-                );
864
-            } catch (Rest_Exception $e) {
865
-                //if we don't have permission to read it, just leave it out. but let devs know about the problem
866
-                $this->_set_response_header(
867
-                    'Notices-Field-Calculation-Errors['
868
-                    . $e->get_string_code()
869
-                    . ']['
870
-                    . $model->get_this_model_name()
871
-                    . ']['
872
-                    . $field_to_calculate
873
-                    . ']',
874
-                    $e->getMessage(),
875
-                    true
876
-                );
877
-            }
878
-        }
879
-        return $calculated_fields_to_return;
880
-    }
881
-
882
-
883
-
884
-    /**
885
-     * Gets the full URL to the resource, taking the requested version into account
886
-     *
887
-     * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
888
-     * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
889
-     */
890
-    public function get_versioned_link_to($link_part_after_version_and_slash)
891
-    {
892
-        return rest_url(
893
-            \EED_Core_Rest_Api::ee_api_namespace
894
-            . $this->get_model_version_info()->requested_version()
895
-            . '/'
896
-            . $link_part_after_version_and_slash
897
-        );
898
-    }
899
-
900
-
901
-
902
-    /**
903
-     * Gets the correct lowercase name for the relation in the API according
904
-     * to the relation's type
905
-     *
906
-     * @param string                  $relation_name
907
-     * @param \EE_Model_Relation_Base $relation_obj
908
-     * @return string
909
-     */
910
-    public static function get_related_entity_name($relation_name, $relation_obj)
911
-    {
912
-        if ($relation_obj instanceof \EE_Belongs_To_Relation) {
913
-            return strtolower($relation_name);
914
-        } else {
915
-            return \EEH_Inflector::pluralize_and_lower($relation_name);
916
-        }
917
-    }
918
-
919
-
920
-
921
-    /**
922
-     * Gets the one model object with the specified id for the specified model
923
-     *
924
-     * @param \EEM_Base        $model
925
-     * @param \WP_REST_Request $request
926
-     * @return array|\WP_Error
927
-     */
928
-    public function get_entity_from_model($model, $request)
929
-    {
930
-        $query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
931
-        if ($model instanceof \EEM_Soft_Delete_Base) {
932
-            $query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
933
-        }
934
-        $restricted_query_params = $query_params;
935
-        $restricted_query_params['caps'] = $this->validate_context($request->get_param('caps'));
936
-        $this->_set_debug_info('model query params', $restricted_query_params);
937
-        $model_rows = $model->get_all_wpdb_results($restricted_query_params);
938
-        if (! empty ($model_rows)) {
939
-            return $this->create_entity_from_wpdb_result(
940
-                $model,
941
-                array_shift($model_rows),
942
-                $request);
943
-        } else {
944
-            //ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
945
-            $lowercase_model_name = strtolower($model->get_this_model_name());
946
-            $model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params);
947
-            if (! empty($model_rows_found_sans_restrictions)) {
948
-                //you got shafted- it existed but we didn't want to tell you!
949
-                return new \WP_Error(
950
-                    'rest_user_cannot_read',
951
-                    sprintf(
952
-                        __('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'),
953
-                        strtolower($model->get_this_model_name()),
954
-                        Capabilities::get_missing_permissions_string(
955
-                            $model,
956
-                            $this->validate_context($request->get_param('caps')))
957
-                    ),
958
-                    array('status' => 403)
959
-                );
960
-            } else {
961
-                //it's not you. It just doesn't exist
962
-                return new \WP_Error(
963
-                    sprintf('rest_%s_invalid_id', $lowercase_model_name),
964
-                    sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
965
-                    array('status' => 404)
966
-                );
967
-            }
968
-        }
969
-    }
970
-
971
-
972
-
973
-    /**
974
-     * If a context is provided which isn't valid, maybe it was added in a future
975
-     * version so just treat it as a default read
976
-     *
977
-     * @param string $context
978
-     * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
979
-     */
980
-    public function validate_context($context)
981
-    {
982
-        if (! $context) {
983
-            $context = \EEM_Base::caps_read;
984
-        }
985
-        $valid_contexts = \EEM_Base::valid_cap_contexts();
986
-        if (in_array($context, $valid_contexts)) {
987
-            return $context;
988
-        } else {
989
-            return \EEM_Base::caps_read;
990
-        }
991
-    }
992
-
993
-
994
-
995
-    /**
996
-     * Verifies the passed in value is an allowable default where conditions value.
997
-     *
998
-     * @param $default_query_params
999
-     * @return string
1000
-     */
1001
-    public function validate_default_query_params($default_query_params)
1002
-    {
1003
-        $valid_default_where_conditions_for_api_calls = array(
1004
-            \EEM_Base::default_where_conditions_all,
1005
-            \EEM_Base::default_where_conditions_minimum_all,
1006
-            \EEM_Base::default_where_conditions_minimum_others,
1007
-        );
1008
-        if (! $default_query_params) {
1009
-            $default_query_params = \EEM_Base::default_where_conditions_all;
1010
-        }
1011
-        if (
1012
-        in_array(
1013
-            $default_query_params,
1014
-            $valid_default_where_conditions_for_api_calls,
1015
-            true
1016
-        )
1017
-        ) {
1018
-            return $default_query_params;
1019
-        } else {
1020
-            return \EEM_Base::default_where_conditions_all;
1021
-        }
1022
-    }
1023
-
1024
-
1025
-
1026
-    /**
1027
-     * Translates API filter get parameter into $query_params array used by EEM_Base::get_all().
1028
-     * Note: right now the query parameter keys for fields (and related fields)
1029
-     * can be left as-is, but it's quite possible this will change someday.
1030
-     * Also, this method's contents might be candidate for moving to Model_Data_Translator
1031
-     *
1032
-     * @param \EEM_Base $model
1033
-     * @param array     $query_parameters from $_GET parameter @see Read:handle_request_get_all
1034
-     * @return array like what EEM_Base::get_all() expects or FALSE to indicate
1035
-     *                                    that absolutely no results should be returned
1036
-     * @throws \EE_Error
1037
-     */
1038
-    public function create_model_query_params($model, $query_parameters)
1039
-    {
1040
-        $model_query_params = array();
1041
-        if (isset($query_parameters['where'])) {
1042
-            $model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1043
-                $query_parameters['where'],
1044
-                $model,
1045
-                $this->get_model_version_info()->requested_version()
1046
-            );
1047
-        }
1048
-        if (isset($query_parameters['order_by'])) {
1049
-            $order_by = $query_parameters['order_by'];
1050
-        } elseif (isset($query_parameters['orderby'])) {
1051
-            $order_by = $query_parameters['orderby'];
1052
-        } else {
1053
-            $order_by = null;
1054
-        }
1055
-        if ($order_by !== null) {
1056
-            if (is_array($order_by)) {
1057
-                $order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by);
1058
-            } else {
1059
-                //it's a single item
1060
-                $order_by = Model_Data_Translator::prepare_field_name_from_json($order_by);
1061
-            }
1062
-            $model_query_params['order_by'] = $order_by;
1063
-        }
1064
-        if (isset($query_parameters['group_by'])) {
1065
-            $group_by = $query_parameters['group_by'];
1066
-        } elseif (isset($query_parameters['groupby'])) {
1067
-            $group_by = $query_parameters['groupby'];
1068
-        } else {
1069
-            $group_by = array_keys($model->get_combined_primary_key_fields());
1070
-        }
1071
-        //make sure they're all real names
1072
-        if (is_array($group_by)) {
1073
-            $group_by = Model_Data_Translator::prepare_field_names_from_json($group_by);
1074
-        }
1075
-        if ($group_by !== null) {
1076
-            $model_query_params['group_by'] = $group_by;
1077
-        }
1078
-        if (isset($query_parameters['having'])) {
1079
-            $model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1080
-                $query_parameters['having'],
1081
-                $model,
1082
-                $this->get_model_version_info()->requested_version()
1083
-            );
1084
-        }
1085
-        if (isset($query_parameters['order'])) {
1086
-            $model_query_params['order'] = $query_parameters['order'];
1087
-        }
1088
-        if (isset($query_parameters['mine'])) {
1089
-            $model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1090
-        }
1091
-        if (isset($query_parameters['limit'])) {
1092
-            //limit should be either a string like '23' or '23,43', or an array with two items in it
1093
-            if (! is_array($query_parameters['limit'])) {
1094
-                $limit_array = explode(',', (string)$query_parameters['limit']);
1095
-            } else {
1096
-                $limit_array = $query_parameters['limit'];
1097
-            }
1098
-            $sanitized_limit = array();
1099
-            foreach ($limit_array as $key => $limit_part) {
1100
-                if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1101
-                    throw new \EE_Error(
1102
-                        sprintf(
1103
-                            __('An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.',
1104
-                                'event_espresso'),
1105
-                            wp_json_encode($query_parameters['limit'])
1106
-                        )
1107
-                    );
1108
-                }
1109
-                $sanitized_limit[] = (int)$limit_part;
1110
-            }
1111
-            $model_query_params['limit'] = implode(',', $sanitized_limit);
1112
-        } else {
1113
-            $model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
1114
-        }
1115
-        if (isset($query_parameters['caps'])) {
1116
-            $model_query_params['caps'] = $this->validate_context($query_parameters['caps']);
1117
-        } else {
1118
-            $model_query_params['caps'] = \EEM_Base::caps_read;
1119
-        }
1120
-        if (isset($query_parameters['default_where_conditions'])) {
1121
-            $model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']);
1122
-        }
1123
-        return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model);
1124
-    }
1125
-
1126
-
1127
-
1128
-    /**
1129
-     * Changes the REST-style query params for use in the models
1130
-     *
1131
-     * @deprecated
1132
-     * @param \EEM_Base $model
1133
-     * @param array     $query_params sub-array from @see EEM_Base::get_all()
1134
-     * @return array
1135
-     */
1136
-    public function prepare_rest_query_params_key_for_models($model, $query_params)
1137
-    {
1138
-        $model_ready_query_params = array();
1139
-        foreach ($query_params as $key => $value) {
1140
-            if (is_array($value)) {
1141
-                $model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value);
1142
-            } else {
1143
-                $model_ready_query_params[$key] = $value;
1144
-            }
1145
-        }
1146
-        return $model_ready_query_params;
1147
-    }
1148
-
1149
-
1150
-
1151
-    /**
1152
-     * @deprecated
1153
-     * @param $model
1154
-     * @param $query_params
1155
-     * @return array
1156
-     */
1157
-    public function prepare_rest_query_params_values_for_models($model, $query_params)
1158
-    {
1159
-        $model_ready_query_params = array();
1160
-        foreach ($query_params as $key => $value) {
1161
-            if (is_array($value)) {
1162
-                $model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value);
1163
-            } else {
1164
-                $model_ready_query_params[$key] = $value;
1165
-            }
1166
-        }
1167
-        return $model_ready_query_params;
1168
-    }
1169
-
1170
-
1171
-
1172
-    /**
1173
-     * Explodes the string on commas, and only returns items with $prefix followed by a period.
1174
-     * If no prefix is specified, returns items with no period.
1175
-     *
1176
-     * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' )
1177
-     * @param string       $prefix            "Event" or "foobar"
1178
-     * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1179
-     *                                        we only return strings starting with that and a period; if no prefix was
1180
-     *                                        specified we return all items containing NO periods
1181
-     */
1182
-    public function explode_and_get_items_prefixed_with($string_to_explode, $prefix)
1183
-    {
1184
-        if (is_string($string_to_explode)) {
1185
-            $exploded_contents = explode(',', $string_to_explode);
1186
-        } else if (is_array($string_to_explode)) {
1187
-            $exploded_contents = $string_to_explode;
1188
-        } else {
1189
-            $exploded_contents = array();
1190
-        }
1191
-        //if the string was empty, we want an empty array
1192
-        $exploded_contents = array_filter($exploded_contents);
1193
-        $contents_with_prefix = array();
1194
-        foreach ($exploded_contents as $item) {
1195
-            $item = trim($item);
1196
-            //if no prefix was provided, so we look for items with no "." in them
1197
-            if (! $prefix) {
1198
-                //does this item have a period?
1199
-                if (strpos($item, '.') === false) {
1200
-                    //if not, then its what we're looking for
1201
-                    $contents_with_prefix[] = $item;
1202
-                }
1203
-            } else if (strpos($item, $prefix . '.') === 0) {
1204
-                //this item has the prefix and a period, grab it
1205
-                $contents_with_prefix[] = substr(
1206
-                    $item,
1207
-                    strpos($item, $prefix . '.') + strlen($prefix . '.')
1208
-                );
1209
-            } else if ($item === $prefix) {
1210
-                //this item is JUST the prefix
1211
-                //so let's grab everything after, which is a blank string
1212
-                $contents_with_prefix[] = '';
1213
-            }
1214
-        }
1215
-        return $contents_with_prefix;
1216
-    }
1217
-
1218
-
1219
-
1220
-    /**
1221
-     * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1222
-     * Deprecated because its return values were really quite confusing- sometimes it returned
1223
-     * an empty array (when the include string was blank or '*') or sometimes it returned
1224
-     * array('*') (when you provided a model and a model of that kind was found).
1225
-     * Parses the $include_string so we fetch all the field names relating to THIS model
1226
-     * (ie have NO period in them), or for the provided model (ie start with the model
1227
-     * name and then a period).
1228
-     * @param string $include_string @see Read:handle_request_get_all
1229
-     * @param string $model_name
1230
-     * @return array of fields for this model. If $model_name is provided, then
1231
-     *                               the fields for that model, with the model's name removed from each.
1232
-     *                               If $include_string was blank or '*' returns an empty array
1233
-     */
1234
-    public function extract_includes_for_this_model($include_string, $model_name = null)
1235
-    {
1236
-        if (is_array($include_string)) {
1237
-            $include_string = implode(',', $include_string);
1238
-        }
1239
-        if ($include_string === '*' || $include_string === '') {
1240
-            return array();
1241
-        }
1242
-        $includes = explode(',', $include_string);
1243
-        $extracted_fields_to_include = array();
1244
-        if ($model_name) {
1245
-            foreach ($includes as $field_to_include) {
1246
-                $field_to_include = trim($field_to_include);
1247
-                if (strpos($field_to_include, $model_name . '.') === 0) {
1248
-                    //found the model name at the exact start
1249
-                    $field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1250
-                    $extracted_fields_to_include[] = $field_sans_model_name;
1251
-                } elseif ($field_to_include == $model_name) {
1252
-                    $extracted_fields_to_include[] = '*';
1253
-                }
1254
-            }
1255
-        } else {
1256
-            //look for ones with no period
1257
-            foreach ($includes as $field_to_include) {
1258
-                $field_to_include = trim($field_to_include);
1259
-                if (
1260
-                    strpos($field_to_include, '.') === false
1261
-                    && ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include)
1262
-                ) {
1263
-                    $extracted_fields_to_include[] = $field_to_include;
1264
-                }
1265
-            }
1266
-        }
1267
-        return $extracted_fields_to_include;
1268
-    }
30
+	/**
31
+	 * @var Calculated_Model_Fields
32
+	 */
33
+	protected $_fields_calculator;
34
+
35
+
36
+
37
+	/**
38
+	 * Read constructor.
39
+	 */
40
+	public function __construct()
41
+	{
42
+		parent::__construct();
43
+		$this->_fields_calculator = new Calculated_Model_Fields();
44
+	}
45
+
46
+
47
+
48
+	/**
49
+	 * Handles requests to get all (or a filtered subset) of entities for a particular model
50
+	 *
51
+	 * @param \WP_REST_Request $request
52
+	 * @return \WP_REST_Response|\WP_Error
53
+	 */
54
+	public static function handle_request_get_all(\WP_REST_Request $request)
55
+	{
56
+		$controller = new Read();
57
+		try {
58
+			$matches = $controller->parse_route(
59
+				$request->get_route(),
60
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)~',
61
+				array('version', 'model')
62
+			);
63
+			$controller->set_requested_version($matches['version']);
64
+			$model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
65
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
66
+				return $controller->send_response(
67
+					new \WP_Error(
68
+						'endpoint_parsing_error',
69
+						sprintf(
70
+							__('There is no model for endpoint %s. Please contact event espresso support',
71
+								'event_espresso'),
72
+							$model_name_singular
73
+						)
74
+					)
75
+				);
76
+			}
77
+			return $controller->send_response(
78
+				$controller->get_entities_from_model(
79
+					$controller->get_model_version_info()->load_model($model_name_singular),
80
+					$request
81
+				)
82
+			);
83
+		} catch (\Exception $e) {
84
+			return $controller->send_response($e);
85
+		}
86
+	}
87
+
88
+
89
+
90
+	/**
91
+	 * Prepares and returns schema for any OPTIONS request.
92
+	 *
93
+	 * @param string $model_name Something like `Event` or `Registration`
94
+	 * @param string $version    The API endpoint version being used.
95
+	 * @return array
96
+	 */
97
+	public static function handle_schema_request($model_name, $version)
98
+	{
99
+		$controller = new Read();
100
+		try {
101
+			$controller->set_requested_version($version);
102
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name)) {
103
+				return array();
104
+			}
105
+			//get the model for this version
106
+			$model = $controller->get_model_version_info()->load_model($model_name);
107
+			$model_schema = new JsonModelSchema($model);
108
+			return $model_schema->getModelSchemaForRelations(
109
+				$controller->get_model_version_info()->relation_settings($model),
110
+				$controller->_customize_schema_for_rest_response(
111
+					$model,
112
+					$model_schema->getModelSchemaForFields(
113
+						$controller->get_model_version_info()->fields_on_model_in_this_version($model),
114
+						$model_schema->getInitialSchemaStructure()
115
+					)
116
+				)
117
+			);
118
+		} catch (\Exception $e) {
119
+			return array();
120
+		}
121
+	}
122
+
123
+
124
+
125
+	/**
126
+	 * This loops through each field in the given schema for the model and does the following:
127
+	 * - add any extra fields that are REST API specific and related to existing fields.
128
+	 * - transform default values into the correct format for a REST API response.
129
+	 *
130
+	 * @param \EEM_Base $model
131
+	 * @param array     $schema
132
+	 * @return array  The final schema.
133
+	 */
134
+	protected function _customize_schema_for_rest_response(\EEM_Base $model, array $schema)
135
+	{
136
+		foreach ($this->get_model_version_info()->fields_on_model_in_this_version($model) as $field_name => $field) {
137
+			$schema = $this->_translate_defaults_for_rest_response(
138
+				$field_name,
139
+				$field,
140
+				$this->_maybe_add_extra_fields_to_schema($field_name, $field, $schema)
141
+			);
142
+		}
143
+		return $schema;
144
+	}
145
+
146
+
147
+
148
+	/**
149
+	 * This is used to ensure that the 'default' value set in the schema response is formatted correctly for the REST
150
+	 * response.
151
+	 *
152
+	 * @param                      $field_name
153
+	 * @param \EE_Model_Field_Base $field
154
+	 * @param array                $schema
155
+	 * @return array
156
+	 */
157
+	protected function _translate_defaults_for_rest_response($field_name, \EE_Model_Field_Base $field, array $schema)
158
+	{
159
+		if (isset($schema['properties'][$field_name]['default'])) {
160
+			if (is_array($schema['properties'][$field_name]['default'])) {
161
+				foreach ($schema['properties'][$field_name]['default'] as $default_key => $default_value) {
162
+					if ($default_key === 'raw') {
163
+						$schema['properties'][$field_name]['default'][$default_key] = Model_Data_Translator::prepare_field_value_for_json(
164
+							$field,
165
+							$default_value,
166
+							$this->get_model_version_info()->requested_version()
167
+						);
168
+					}
169
+				}
170
+			} else {
171
+				$schema['properties'][$field_name]['default'] = Model_Data_Translator::prepare_field_value_for_json(
172
+					$field,
173
+					$schema['properties'][$field_name]['default'],
174
+					$this->get_model_version_info()->requested_version()
175
+				);
176
+			}
177
+		}
178
+		return $schema;
179
+	}
180
+
181
+
182
+
183
+	/**
184
+	 * Adds additional fields to the schema
185
+	 * The REST API returns a GMT value field for each datetime field in the resource.  Thus the description about this
186
+	 * needs to be added to the schema.
187
+	 *
188
+	 * @param                      $field_name
189
+	 * @param \EE_Model_Field_Base $field
190
+	 * @param array                $schema
191
+	 * @return array
192
+	 */
193
+	protected function _maybe_add_extra_fields_to_schema($field_name, \EE_Model_Field_Base $field, array $schema)
194
+	{
195
+		if ($field instanceof EE_Datetime_Field) {
196
+			$schema['properties'][$field_name . '_gmt'] = $field->getSchema();
197
+			//modify the description
198
+			$schema['properties'][$field_name . '_gmt']['description'] = sprintf(
199
+				esc_html__('%s - the value for this field is in GMT.', 'event_espresso'),
200
+				$field->get_nicename()
201
+			);
202
+		}
203
+		return $schema;
204
+	}
205
+
206
+
207
+
208
+	/**
209
+	 * Used to figure out the route from the request when a `WP_REST_Request` object is not available
210
+	 *
211
+	 * @return string
212
+	 */
213
+	protected function get_route_from_request()
214
+	{
215
+		if (isset($GLOBALS['wp'])
216
+			&& $GLOBALS['wp'] instanceof \WP
217
+			&& isset($GLOBALS['wp']->query_vars['rest_route'])
218
+		) {
219
+			return $GLOBALS['wp']->query_vars['rest_route'];
220
+		} else {
221
+			return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
222
+		}
223
+	}
224
+
225
+
226
+
227
+	/**
228
+	 * Gets a single entity related to the model indicated in the path and its id
229
+	 *
230
+	 * @param \WP_REST_Request $request
231
+	 * @return \WP_REST_Response|\WP_Error
232
+	 */
233
+	public static function handle_request_get_one(\WP_REST_Request $request)
234
+	{
235
+		$controller = new Read();
236
+		try {
237
+			$matches = $controller->parse_route(
238
+				$request->get_route(),
239
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)~',
240
+				array('version', 'model', 'id'));
241
+			$controller->set_requested_version($matches['version']);
242
+			$model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
243
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($model_name_singular)) {
244
+				return $controller->send_response(
245
+					new \WP_Error(
246
+						'endpoint_parsing_error',
247
+						sprintf(
248
+							__('There is no model for endpoint %s. Please contact event espresso support',
249
+								'event_espresso'),
250
+							$model_name_singular
251
+						)
252
+					)
253
+				);
254
+			}
255
+			return $controller->send_response(
256
+				$controller->get_entity_from_model(
257
+					$controller->get_model_version_info()->load_model($model_name_singular),
258
+					$request
259
+				)
260
+			);
261
+		} catch (\Exception $e) {
262
+			return $controller->send_response($e);
263
+		}
264
+	}
265
+
266
+
267
+
268
+	/**
269
+	 * Gets all the related entities (or if its a belongs-to relation just the one)
270
+	 * to the item with the given id
271
+	 *
272
+	 * @param \WP_REST_Request $request
273
+	 * @return \WP_REST_Response|\WP_Error
274
+	 */
275
+	public static function handle_request_get_related(\WP_REST_Request $request)
276
+	{
277
+		$controller = new Read();
278
+		try {
279
+			$matches = $controller->parse_route(
280
+				$request->get_route(),
281
+				'~' . \EED_Core_Rest_Api::ee_api_namespace_for_regex . '(.*)/(.*)/(.*)~',
282
+				array('version', 'model', 'id', 'related_model')
283
+			);
284
+			$controller->set_requested_version($matches['version']);
285
+			$main_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['model']);
286
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($main_model_name_singular)) {
287
+				return $controller->send_response(
288
+					new \WP_Error(
289
+						'endpoint_parsing_error',
290
+						sprintf(
291
+							__('There is no model for endpoint %s. Please contact event espresso support',
292
+								'event_espresso'),
293
+							$main_model_name_singular
294
+						)
295
+					)
296
+				);
297
+			}
298
+			$main_model = $controller->get_model_version_info()->load_model($main_model_name_singular);
299
+			//assume the related model name is plural and try to find the model's name
300
+			$related_model_name_singular = \EEH_Inflector::singularize_and_upper($matches['related_model']);
301
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
302
+				//so the word didn't singularize well. Maybe that's just because it's a singular word?
303
+				$related_model_name_singular = \EEH_Inflector::humanize($matches['related_model']);
304
+			}
305
+			if (! $controller->get_model_version_info()->is_model_name_in_this_version($related_model_name_singular)) {
306
+				return $controller->send_response(
307
+					new \WP_Error(
308
+						'endpoint_parsing_error',
309
+						sprintf(
310
+							__('There is no model for endpoint %s. Please contact event espresso support',
311
+								'event_espresso'),
312
+							$related_model_name_singular
313
+						)
314
+					)
315
+				);
316
+			}
317
+			return $controller->send_response(
318
+				$controller->get_entities_from_relation(
319
+					$request->get_param('id'),
320
+					$main_model->related_settings_for($related_model_name_singular),
321
+					$request
322
+				)
323
+			);
324
+		} catch (\Exception $e) {
325
+			return $controller->send_response($e);
326
+		}
327
+	}
328
+
329
+
330
+
331
+	/**
332
+	 * Gets a collection for the given model and filters
333
+	 *
334
+	 * @param \EEM_Base        $model
335
+	 * @param \WP_REST_Request $request
336
+	 * @return array|\WP_Error
337
+	 */
338
+	public function get_entities_from_model($model, $request)
339
+	{
340
+		$query_params = $this->create_model_query_params($model, $request->get_params());
341
+		if (! Capabilities::current_user_has_partial_access_to($model, $query_params['caps'])) {
342
+			$model_name_plural = \EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
343
+			return new \WP_Error(
344
+				sprintf('rest_%s_cannot_list', $model_name_plural),
345
+				sprintf(
346
+					__('Sorry, you are not allowed to list %1$s. Missing permissions: %2$s', 'event_espresso'),
347
+					$model_name_plural,
348
+					Capabilities::get_missing_permissions_string($model, $query_params['caps'])
349
+				),
350
+				array('status' => 403)
351
+			);
352
+		}
353
+		if (! $request->get_header('no_rest_headers')) {
354
+			$this->_set_headers_from_query_params($model, $query_params);
355
+		}
356
+		/** @type array $results */
357
+		$results = $model->get_all_wpdb_results($query_params);
358
+		$nice_results = array();
359
+		foreach ($results as $result) {
360
+			$nice_results[] = $this->create_entity_from_wpdb_result(
361
+				$model,
362
+				$result,
363
+				$request
364
+			);
365
+		}
366
+		return $nice_results;
367
+	}
368
+
369
+
370
+
371
+	/**
372
+	 * @param array                   $primary_model_query_params query params for finding the item from which
373
+	 *                                                            relations will be based
374
+	 * @param \EE_Model_Relation_Base $relation
375
+	 * @param \WP_REST_Request        $request
376
+	 * @return \WP_Error|array
377
+	 */
378
+	protected function _get_entities_from_relation($primary_model_query_params, $relation, $request)
379
+	{
380
+		$context = $this->validate_context($request->get_param('caps'));
381
+		$model = $relation->get_this_model();
382
+		$related_model = $relation->get_other_model();
383
+		if (! isset($primary_model_query_params[0])) {
384
+			$primary_model_query_params[0] = array();
385
+		}
386
+		//check if they can access the 1st model object
387
+		$primary_model_query_params = array(
388
+			0       => $primary_model_query_params[0],
389
+			'limit' => 1,
390
+		);
391
+		if ($model instanceof \EEM_Soft_Delete_Base) {
392
+			$primary_model_query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($primary_model_query_params);
393
+		}
394
+		$restricted_query_params = $primary_model_query_params;
395
+		$restricted_query_params['caps'] = $context;
396
+		$this->_set_debug_info('main model query params', $restricted_query_params);
397
+		$this->_set_debug_info('missing caps', Capabilities::get_missing_permissions_string($related_model, $context));
398
+		if (
399
+		! (
400
+			Capabilities::current_user_has_partial_access_to($related_model, $context)
401
+			&& $model->exists($restricted_query_params)
402
+		)
403
+		) {
404
+			if ($relation instanceof \EE_Belongs_To_Relation) {
405
+				$related_model_name_maybe_plural = strtolower($related_model->get_this_model_name());
406
+			} else {
407
+				$related_model_name_maybe_plural = \EEH_Inflector::pluralize_and_lower($related_model->get_this_model_name());
408
+			}
409
+			return new \WP_Error(
410
+				sprintf('rest_%s_cannot_list', $related_model_name_maybe_plural),
411
+				sprintf(
412
+					__('Sorry, you are not allowed to list %1$s related to %2$s. Missing permissions: %3$s',
413
+						'event_espresso'),
414
+					$related_model_name_maybe_plural,
415
+					$relation->get_this_model()->get_this_model_name(),
416
+					implode(
417
+						',',
418
+						array_keys(
419
+							Capabilities::get_missing_permissions($related_model, $context)
420
+						)
421
+					)
422
+				),
423
+				array('status' => 403)
424
+			);
425
+		}
426
+		$query_params = $this->create_model_query_params($relation->get_other_model(), $request->get_params());
427
+		foreach ($primary_model_query_params[0] as $where_condition_key => $where_condition_value) {
428
+			$query_params[0][$relation->get_this_model()->get_this_model_name()
429
+							 . '.'
430
+							 . $where_condition_key] = $where_condition_value;
431
+		}
432
+		$query_params['default_where_conditions'] = 'none';
433
+		$query_params['caps'] = $context;
434
+		if (! $request->get_header('no_rest_headers')) {
435
+			$this->_set_headers_from_query_params($relation->get_other_model(), $query_params);
436
+		}
437
+		/** @type array $results */
438
+		$results = $relation->get_other_model()->get_all_wpdb_results($query_params);
439
+		$nice_results = array();
440
+		foreach ($results as $result) {
441
+			$nice_result = $this->create_entity_from_wpdb_result(
442
+				$relation->get_other_model(),
443
+				$result,
444
+				$request
445
+			);
446
+			if ($relation instanceof \EE_HABTM_Relation) {
447
+				//put the unusual stuff (properties from the HABTM relation) first, and make sure
448
+				//if there are conflicts we prefer the properties from the main model
449
+				$join_model_result = $this->create_entity_from_wpdb_result(
450
+					$relation->get_join_model(),
451
+					$result,
452
+					$request
453
+				);
454
+				$joined_result = array_merge($nice_result, $join_model_result);
455
+				//but keep the meta stuff from the main model
456
+				if (isset($nice_result['meta'])) {
457
+					$joined_result['meta'] = $nice_result['meta'];
458
+				}
459
+				$nice_result = $joined_result;
460
+			}
461
+			$nice_results[] = $nice_result;
462
+		}
463
+		if ($relation instanceof \EE_Belongs_To_Relation) {
464
+			return array_shift($nice_results);
465
+		} else {
466
+			return $nice_results;
467
+		}
468
+	}
469
+
470
+
471
+
472
+	/**
473
+	 * Gets the collection for given relation object
474
+	 * The same as Read::get_entities_from_model(), except if the relation
475
+	 * is a HABTM relation, in which case it merges any non-foreign-key fields from
476
+	 * the join-model-object into the results
477
+	 *
478
+	 * @param string                  $id the ID of the thing we are fetching related stuff from
479
+	 * @param \EE_Model_Relation_Base $relation
480
+	 * @param \WP_REST_Request        $request
481
+	 * @return array|\WP_Error
482
+	 * @throws \EE_Error
483
+	 */
484
+	public function get_entities_from_relation($id, $relation, $request)
485
+	{
486
+		if (! $relation->get_this_model()->has_primary_key_field()) {
487
+			throw new \EE_Error(
488
+				sprintf(
489
+					__('Read::get_entities_from_relation should only be called from a model with a primary key, it was called from %1$s',
490
+						'event_espresso'),
491
+					$relation->get_this_model()->get_this_model_name()
492
+				)
493
+			);
494
+		}
495
+		return $this->_get_entities_from_relation(
496
+			array(
497
+				array(
498
+					$relation->get_this_model()->primary_key_name() => $id,
499
+				),
500
+			),
501
+			$relation,
502
+			$request
503
+		);
504
+	}
505
+
506
+
507
+
508
+	/**
509
+	 * Sets the headers that are based on the model and query params,
510
+	 * like the total records. This should only be called on the original request
511
+	 * from the client, not on subsequent internal
512
+	 *
513
+	 * @param \EEM_Base $model
514
+	 * @param array     $query_params
515
+	 * @return void
516
+	 */
517
+	protected function _set_headers_from_query_params($model, $query_params)
518
+	{
519
+		$this->_set_debug_info('model query params', $query_params);
520
+		$this->_set_debug_info('missing caps',
521
+			Capabilities::get_missing_permissions_string($model, $query_params['caps']));
522
+		//normally the limit to a 2-part array, where the 2nd item is the limit
523
+		if (! isset($query_params['limit'])) {
524
+			$query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
525
+		}
526
+		if (is_array($query_params['limit'])) {
527
+			$limit_parts = $query_params['limit'];
528
+		} else {
529
+			$limit_parts = explode(',', $query_params['limit']);
530
+			if (count($limit_parts) == 1) {
531
+				$limit_parts = array(0, $limit_parts[0]);
532
+			}
533
+		}
534
+		//remove the group by and having parts of the query, as those will
535
+		//make the sql query return an array of values, instead of just a single value
536
+		unset($query_params['group_by'], $query_params['having'], $query_params['limit']);
537
+		$count = $model->count($query_params, null, true);
538
+		$pages = $count / $limit_parts[1];
539
+		$this->_set_response_header('Total', $count, false);
540
+		$this->_set_response_header('PageSize', $limit_parts[1], false);
541
+		$this->_set_response_header('TotalPages', ceil($pages), false);
542
+	}
543
+
544
+
545
+
546
+	/**
547
+	 * Changes database results into REST API entities
548
+	 *
549
+	 * @param \EEM_Base        $model
550
+	 * @param array            $db_row     like results from $wpdb->get_results()
551
+	 * @param \WP_REST_Request $rest_request
552
+	 * @param string           $deprecated no longer used
553
+	 * @return array ready for being converted into json for sending to client
554
+	 */
555
+	public function create_entity_from_wpdb_result($model, $db_row, $rest_request, $deprecated = null)
556
+	{
557
+		if (! $rest_request instanceof \WP_REST_Request) {
558
+			//ok so this was called in the old style, where the 3rd arg was
559
+			//$include, and the 4th arg was $context
560
+			//now setup the request just to avoid fatal errors, although we won't be able
561
+			//to truly make use of it because it's kinda devoid of info
562
+			$rest_request = new \WP_REST_Request();
563
+			$rest_request->set_param('include', $rest_request);
564
+			$rest_request->set_param('caps', $deprecated);
565
+		}
566
+		if ($rest_request->get_param('caps') == null) {
567
+			$rest_request->set_param('caps', \EEM_Base::caps_read);
568
+		}
569
+		$entity_array = $this->_create_bare_entity_from_wpdb_results($model, $db_row);
570
+		$entity_array = $this->_add_extra_fields($model, $db_row, $entity_array);
571
+		$entity_array['_links'] = $this->_get_entity_links($model, $db_row, $entity_array);
572
+		$entity_array['_calculated_fields'] = $this->_get_entity_calculations($model, $db_row, $rest_request);
573
+		$entity_array = apply_filters('FHEE__Read__create_entity_from_wpdb_results__entity_before_including_requested_models',
574
+			$entity_array, $model, $rest_request->get_param('caps'), $rest_request, $this);
575
+		$entity_array = $this->_include_requested_models($model, $rest_request, $entity_array, $db_row);
576
+		$entity_array = apply_filters(
577
+			'FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal',
578
+			$entity_array,
579
+			$model,
580
+			$rest_request->get_param('caps'),
581
+			$rest_request,
582
+			$this
583
+		);
584
+		$result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields(
585
+			$entity_array,
586
+			$model,
587
+			$rest_request->get_param('caps'),
588
+			$this->get_model_version_info(),
589
+			$model->get_index_primary_key_string(
590
+				$model->deduce_fields_n_values_from_cols_n_values($db_row)
591
+			)
592
+		);
593
+		$this->_set_debug_info(
594
+			'inaccessible fields',
595
+			array_keys(array_diff_key($entity_array, $result_without_inaccessible_fields))
596
+		);
597
+		return apply_filters(
598
+			'FHEE__Read__create_entity_from_wpdb_results__entity_return',
599
+			$result_without_inaccessible_fields,
600
+			$model,
601
+			$rest_request->get_param('caps')
602
+		);
603
+	}
604
+
605
+
606
+
607
+	/**
608
+	 * Creates a REST entity array (JSON object we're going to return in the response, but
609
+	 * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry),
610
+	 * from $wpdb->get_row( $sql, ARRAY_A)
611
+	 *
612
+	 * @param \EEM_Base $model
613
+	 * @param array     $db_row
614
+	 * @return array entity mostly ready for converting to JSON and sending in the response
615
+	 */
616
+	protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row)
617
+	{
618
+		$result = $model->deduce_fields_n_values_from_cols_n_values($db_row);
619
+		$result = array_intersect_key($result,
620
+			$this->get_model_version_info()->fields_on_model_in_this_version($model));
621
+		foreach ($result as $field_name => $raw_field_value) {
622
+			$field_obj = $model->field_settings_for($field_name);
623
+			$field_value = $field_obj->prepare_for_set_from_db($raw_field_value);
624
+			if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) {
625
+				unset($result[$field_name]);
626
+			} elseif (
627
+			$this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())
628
+			) {
629
+				$result[$field_name] = array(
630
+					'raw'      => $field_obj->prepare_for_get($field_value),
631
+					'rendered' => $field_obj->prepare_for_pretty_echoing($field_value),
632
+				);
633
+			} elseif (
634
+			$this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())
635
+			) {
636
+				$result[$field_name] = array(
637
+					'raw'    => $field_obj->prepare_for_get($field_value),
638
+					'pretty' => $field_obj->prepare_for_pretty_echoing($field_value),
639
+				);
640
+			} elseif ($field_obj instanceof \EE_Datetime_Field) {
641
+				if ($field_value instanceof \DateTime) {
642
+					$timezone = $field_value->getTimezone();
643
+					$field_value->setTimezone(new \DateTimeZone('UTC'));
644
+					$result[$field_name . '_gmt'] = Model_Data_Translator::prepare_field_value_for_json(
645
+						$field_obj,
646
+						$field_value,
647
+						$this->get_model_version_info()->requested_version()
648
+					);
649
+					$field_value->setTimezone($timezone);
650
+					$result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
651
+						$field_obj,
652
+						$field_value,
653
+						$this->get_model_version_info()->requested_version()
654
+					);
655
+				}
656
+			} else {
657
+				$result[$field_name] = Model_Data_Translator::prepare_field_value_for_json(
658
+					$field_obj,
659
+					$field_obj->prepare_for_get($field_value),
660
+					$this->get_model_version_info()->requested_version()
661
+				);
662
+			}
663
+		}
664
+		return $result;
665
+	}
666
+
667
+
668
+
669
+	/**
670
+	 * Adds a few extra fields to the entity response
671
+	 *
672
+	 * @param \EEM_Base $model
673
+	 * @param array     $db_row
674
+	 * @param array     $entity_array
675
+	 * @return array modified entity
676
+	 */
677
+	protected function _add_extra_fields(\EEM_Base $model, $db_row, $entity_array)
678
+	{
679
+		if ($model instanceof \EEM_CPT_Base) {
680
+			$entity_array['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]);
681
+		}
682
+		return $entity_array;
683
+	}
684
+
685
+
686
+
687
+	/**
688
+	 * Gets links we want to add to the response
689
+	 *
690
+	 * @global \WP_REST_Server $wp_rest_server
691
+	 * @param \EEM_Base        $model
692
+	 * @param array            $db_row
693
+	 * @param array            $entity_array
694
+	 * @return array the _links item in the entity
695
+	 */
696
+	protected function _get_entity_links($model, $db_row, $entity_array)
697
+	{
698
+		//add basic links
699
+		$links = array();
700
+		if ($model->has_primary_key_field()) {
701
+			$links['self'] = array(
702
+				array(
703
+					'href' => $this->get_versioned_link_to(
704
+						\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
705
+						. '/'
706
+						. $entity_array[$model->primary_key_name()]
707
+					),
708
+				),
709
+			);
710
+		}
711
+		$links['collection'] = array(
712
+			array(
713
+				'href' => $this->get_versioned_link_to(
714
+					\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
715
+				),
716
+			),
717
+		);
718
+		//add links to related models
719
+		if ($model->has_primary_key_field()) {
720
+			foreach ($this->get_model_version_info()->relation_settings($model) as $relation_name => $relation_obj) {
721
+				$related_model_part = Read::get_related_entity_name($relation_name, $relation_obj);
722
+				$links[\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(
723
+					array(
724
+						'href'   => $this->get_versioned_link_to(
725
+							\EEH_Inflector::pluralize_and_lower($model->get_this_model_name())
726
+							. '/'
727
+							. $entity_array[$model->primary_key_name()]
728
+							. '/'
729
+							. $related_model_part
730
+						),
731
+						'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false,
732
+					),
733
+				);
734
+			}
735
+		}
736
+		return $links;
737
+	}
738
+
739
+
740
+
741
+	/**
742
+	 * Adds the included models indicated in the request to the entity provided
743
+	 *
744
+	 * @param \EEM_Base        $model
745
+	 * @param \WP_REST_Request $rest_request
746
+	 * @param array            $entity_array
747
+	 * @param array            $db_row
748
+	 * @return array the modified entity
749
+	 */
750
+	protected function _include_requested_models(
751
+		\EEM_Base $model,
752
+		\WP_REST_Request $rest_request,
753
+		$entity_array,
754
+		$db_row = array()
755
+	) {
756
+		//if $db_row not included, hope the entity array has what we need
757
+		if (! $db_row) {
758
+			$db_row = $entity_array;
759
+		}
760
+		$includes_for_this_model = $this->explode_and_get_items_prefixed_with($rest_request->get_param('include'), '');
761
+		$includes_for_this_model = $this->_remove_model_names_from_array($includes_for_this_model);
762
+		//if they passed in * or didn't specify any includes, return everything
763
+		if (! in_array('*', $includes_for_this_model)
764
+			&& ! empty($includes_for_this_model)
765
+		) {
766
+			if ($model->has_primary_key_field()) {
767
+				//always include the primary key. ya just gotta know that at least
768
+				$includes_for_this_model[] = $model->primary_key_name();
769
+			}
770
+			if ($this->explode_and_get_items_prefixed_with($rest_request->get_param('calculate'), '')) {
771
+				$includes_for_this_model[] = '_calculated_fields';
772
+			}
773
+			$entity_array = array_intersect_key($entity_array, array_flip($includes_for_this_model));
774
+		}
775
+		$relation_settings = $this->get_model_version_info()->relation_settings($model);
776
+		foreach ($relation_settings as $relation_name => $relation_obj) {
777
+			$related_fields_to_include = $this->explode_and_get_items_prefixed_with(
778
+				$rest_request->get_param('include'),
779
+				$relation_name
780
+			);
781
+			$related_fields_to_calculate = $this->explode_and_get_items_prefixed_with(
782
+				$rest_request->get_param('calculate'),
783
+				$relation_name
784
+			);
785
+			//did they specify they wanted to include a related model, or
786
+			//specific fields from a related model?
787
+			//or did they specify to calculate a field from a related model?
788
+			if ($related_fields_to_include || $related_fields_to_calculate) {
789
+				//if so, we should include at least some part of the related model
790
+				$pretend_related_request = new \WP_REST_Request();
791
+				$pretend_related_request->set_query_params(
792
+					array(
793
+						'caps'      => $rest_request->get_param('caps'),
794
+						'include'   => $related_fields_to_include,
795
+						'calculate' => $related_fields_to_calculate,
796
+					)
797
+				);
798
+				$pretend_related_request->add_header('no_rest_headers', true);
799
+				$primary_model_query_params = $model->alter_query_params_to_restrict_by_ID(
800
+					$model->get_index_primary_key_string(
801
+						$model->deduce_fields_n_values_from_cols_n_values($db_row)
802
+					)
803
+				);
804
+				$related_results = $this->_get_entities_from_relation(
805
+					$primary_model_query_params,
806
+					$relation_obj,
807
+					$pretend_related_request
808
+				);
809
+				$entity_array[Read::get_related_entity_name($relation_name, $relation_obj)] = $related_results
810
+																							  instanceof
811
+																							  \WP_Error
812
+					? null
813
+					: $related_results;
814
+			}
815
+		}
816
+		return $entity_array;
817
+	}
818
+
819
+
820
+
821
+	/**
822
+	 * Returns a new array with all the names of models removed. Eg
823
+	 * array( 'Event', 'Datetime.*', 'foobar' ) would become array( 'Datetime.*', 'foobar' )
824
+	 *
825
+	 * @param array $arr
826
+	 * @return array
827
+	 */
828
+	private function _remove_model_names_from_array($arr)
829
+	{
830
+		return array_diff($arr, array_keys(\EE_Registry::instance()->non_abstract_db_models()));
831
+	}
832
+
833
+
834
+
835
+	/**
836
+	 * Gets the calculated fields for the response
837
+	 *
838
+	 * @param \EEM_Base        $model
839
+	 * @param array            $wpdb_row
840
+	 * @param \WP_REST_Request $rest_request
841
+	 * @return \stdClass the _calculations item in the entity
842
+	 */
843
+	protected function _get_entity_calculations($model, $wpdb_row, $rest_request)
844
+	{
845
+		$calculated_fields = $this->explode_and_get_items_prefixed_with(
846
+			$rest_request->get_param('calculate'),
847
+			''
848
+		);
849
+		//note: setting calculate=* doesn't do anything
850
+		$calculated_fields_to_return = new \stdClass();
851
+		foreach ($calculated_fields as $field_to_calculate) {
852
+			try {
853
+				$calculated_fields_to_return->$field_to_calculate = Model_Data_Translator::prepare_field_value_for_json(
854
+					null,
855
+					$this->_fields_calculator->retrieve_calculated_field_value(
856
+						$model,
857
+						$field_to_calculate,
858
+						$wpdb_row,
859
+						$rest_request,
860
+						$this
861
+					),
862
+					$this->get_model_version_info()->requested_version()
863
+				);
864
+			} catch (Rest_Exception $e) {
865
+				//if we don't have permission to read it, just leave it out. but let devs know about the problem
866
+				$this->_set_response_header(
867
+					'Notices-Field-Calculation-Errors['
868
+					. $e->get_string_code()
869
+					. ']['
870
+					. $model->get_this_model_name()
871
+					. ']['
872
+					. $field_to_calculate
873
+					. ']',
874
+					$e->getMessage(),
875
+					true
876
+				);
877
+			}
878
+		}
879
+		return $calculated_fields_to_return;
880
+	}
881
+
882
+
883
+
884
+	/**
885
+	 * Gets the full URL to the resource, taking the requested version into account
886
+	 *
887
+	 * @param string $link_part_after_version_and_slash eg "events/10/datetimes"
888
+	 * @return string url eg "http://mysite.com/wp-json/ee/v4.6/events/10/datetimes"
889
+	 */
890
+	public function get_versioned_link_to($link_part_after_version_and_slash)
891
+	{
892
+		return rest_url(
893
+			\EED_Core_Rest_Api::ee_api_namespace
894
+			. $this->get_model_version_info()->requested_version()
895
+			. '/'
896
+			. $link_part_after_version_and_slash
897
+		);
898
+	}
899
+
900
+
901
+
902
+	/**
903
+	 * Gets the correct lowercase name for the relation in the API according
904
+	 * to the relation's type
905
+	 *
906
+	 * @param string                  $relation_name
907
+	 * @param \EE_Model_Relation_Base $relation_obj
908
+	 * @return string
909
+	 */
910
+	public static function get_related_entity_name($relation_name, $relation_obj)
911
+	{
912
+		if ($relation_obj instanceof \EE_Belongs_To_Relation) {
913
+			return strtolower($relation_name);
914
+		} else {
915
+			return \EEH_Inflector::pluralize_and_lower($relation_name);
916
+		}
917
+	}
918
+
919
+
920
+
921
+	/**
922
+	 * Gets the one model object with the specified id for the specified model
923
+	 *
924
+	 * @param \EEM_Base        $model
925
+	 * @param \WP_REST_Request $request
926
+	 * @return array|\WP_Error
927
+	 */
928
+	public function get_entity_from_model($model, $request)
929
+	{
930
+		$query_params = array(array($model->primary_key_name() => $request->get_param('id')), 'limit' => 1);
931
+		if ($model instanceof \EEM_Soft_Delete_Base) {
932
+			$query_params = $model->alter_query_params_so_deleted_and_undeleted_items_included($query_params);
933
+		}
934
+		$restricted_query_params = $query_params;
935
+		$restricted_query_params['caps'] = $this->validate_context($request->get_param('caps'));
936
+		$this->_set_debug_info('model query params', $restricted_query_params);
937
+		$model_rows = $model->get_all_wpdb_results($restricted_query_params);
938
+		if (! empty ($model_rows)) {
939
+			return $this->create_entity_from_wpdb_result(
940
+				$model,
941
+				array_shift($model_rows),
942
+				$request);
943
+		} else {
944
+			//ok let's test to see if we WOULD have found it, had we not had restrictions from missing capabilities
945
+			$lowercase_model_name = strtolower($model->get_this_model_name());
946
+			$model_rows_found_sans_restrictions = $model->get_all_wpdb_results($query_params);
947
+			if (! empty($model_rows_found_sans_restrictions)) {
948
+				//you got shafted- it existed but we didn't want to tell you!
949
+				return new \WP_Error(
950
+					'rest_user_cannot_read',
951
+					sprintf(
952
+						__('Sorry, you cannot read this %1$s. Missing permissions are: %2$s', 'event_espresso'),
953
+						strtolower($model->get_this_model_name()),
954
+						Capabilities::get_missing_permissions_string(
955
+							$model,
956
+							$this->validate_context($request->get_param('caps')))
957
+					),
958
+					array('status' => 403)
959
+				);
960
+			} else {
961
+				//it's not you. It just doesn't exist
962
+				return new \WP_Error(
963
+					sprintf('rest_%s_invalid_id', $lowercase_model_name),
964
+					sprintf(__('Invalid %s ID.', 'event_espresso'), $lowercase_model_name),
965
+					array('status' => 404)
966
+				);
967
+			}
968
+		}
969
+	}
970
+
971
+
972
+
973
+	/**
974
+	 * If a context is provided which isn't valid, maybe it was added in a future
975
+	 * version so just treat it as a default read
976
+	 *
977
+	 * @param string $context
978
+	 * @return string array key of EEM_Base::cap_contexts_to_cap_action_map()
979
+	 */
980
+	public function validate_context($context)
981
+	{
982
+		if (! $context) {
983
+			$context = \EEM_Base::caps_read;
984
+		}
985
+		$valid_contexts = \EEM_Base::valid_cap_contexts();
986
+		if (in_array($context, $valid_contexts)) {
987
+			return $context;
988
+		} else {
989
+			return \EEM_Base::caps_read;
990
+		}
991
+	}
992
+
993
+
994
+
995
+	/**
996
+	 * Verifies the passed in value is an allowable default where conditions value.
997
+	 *
998
+	 * @param $default_query_params
999
+	 * @return string
1000
+	 */
1001
+	public function validate_default_query_params($default_query_params)
1002
+	{
1003
+		$valid_default_where_conditions_for_api_calls = array(
1004
+			\EEM_Base::default_where_conditions_all,
1005
+			\EEM_Base::default_where_conditions_minimum_all,
1006
+			\EEM_Base::default_where_conditions_minimum_others,
1007
+		);
1008
+		if (! $default_query_params) {
1009
+			$default_query_params = \EEM_Base::default_where_conditions_all;
1010
+		}
1011
+		if (
1012
+		in_array(
1013
+			$default_query_params,
1014
+			$valid_default_where_conditions_for_api_calls,
1015
+			true
1016
+		)
1017
+		) {
1018
+			return $default_query_params;
1019
+		} else {
1020
+			return \EEM_Base::default_where_conditions_all;
1021
+		}
1022
+	}
1023
+
1024
+
1025
+
1026
+	/**
1027
+	 * Translates API filter get parameter into $query_params array used by EEM_Base::get_all().
1028
+	 * Note: right now the query parameter keys for fields (and related fields)
1029
+	 * can be left as-is, but it's quite possible this will change someday.
1030
+	 * Also, this method's contents might be candidate for moving to Model_Data_Translator
1031
+	 *
1032
+	 * @param \EEM_Base $model
1033
+	 * @param array     $query_parameters from $_GET parameter @see Read:handle_request_get_all
1034
+	 * @return array like what EEM_Base::get_all() expects or FALSE to indicate
1035
+	 *                                    that absolutely no results should be returned
1036
+	 * @throws \EE_Error
1037
+	 */
1038
+	public function create_model_query_params($model, $query_parameters)
1039
+	{
1040
+		$model_query_params = array();
1041
+		if (isset($query_parameters['where'])) {
1042
+			$model_query_params[0] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1043
+				$query_parameters['where'],
1044
+				$model,
1045
+				$this->get_model_version_info()->requested_version()
1046
+			);
1047
+		}
1048
+		if (isset($query_parameters['order_by'])) {
1049
+			$order_by = $query_parameters['order_by'];
1050
+		} elseif (isset($query_parameters['orderby'])) {
1051
+			$order_by = $query_parameters['orderby'];
1052
+		} else {
1053
+			$order_by = null;
1054
+		}
1055
+		if ($order_by !== null) {
1056
+			if (is_array($order_by)) {
1057
+				$order_by = Model_Data_Translator::prepare_field_names_in_array_keys_from_json($order_by);
1058
+			} else {
1059
+				//it's a single item
1060
+				$order_by = Model_Data_Translator::prepare_field_name_from_json($order_by);
1061
+			}
1062
+			$model_query_params['order_by'] = $order_by;
1063
+		}
1064
+		if (isset($query_parameters['group_by'])) {
1065
+			$group_by = $query_parameters['group_by'];
1066
+		} elseif (isset($query_parameters['groupby'])) {
1067
+			$group_by = $query_parameters['groupby'];
1068
+		} else {
1069
+			$group_by = array_keys($model->get_combined_primary_key_fields());
1070
+		}
1071
+		//make sure they're all real names
1072
+		if (is_array($group_by)) {
1073
+			$group_by = Model_Data_Translator::prepare_field_names_from_json($group_by);
1074
+		}
1075
+		if ($group_by !== null) {
1076
+			$model_query_params['group_by'] = $group_by;
1077
+		}
1078
+		if (isset($query_parameters['having'])) {
1079
+			$model_query_params['having'] = Model_Data_Translator::prepare_conditions_query_params_for_models(
1080
+				$query_parameters['having'],
1081
+				$model,
1082
+				$this->get_model_version_info()->requested_version()
1083
+			);
1084
+		}
1085
+		if (isset($query_parameters['order'])) {
1086
+			$model_query_params['order'] = $query_parameters['order'];
1087
+		}
1088
+		if (isset($query_parameters['mine'])) {
1089
+			$model_query_params = $model->alter_query_params_to_only_include_mine($model_query_params);
1090
+		}
1091
+		if (isset($query_parameters['limit'])) {
1092
+			//limit should be either a string like '23' or '23,43', or an array with two items in it
1093
+			if (! is_array($query_parameters['limit'])) {
1094
+				$limit_array = explode(',', (string)$query_parameters['limit']);
1095
+			} else {
1096
+				$limit_array = $query_parameters['limit'];
1097
+			}
1098
+			$sanitized_limit = array();
1099
+			foreach ($limit_array as $key => $limit_part) {
1100
+				if ($this->_debug_mode && (! is_numeric($limit_part) || count($sanitized_limit) > 2)) {
1101
+					throw new \EE_Error(
1102
+						sprintf(
1103
+							__('An invalid limit filter was provided. It was: %s. If the EE4 JSON REST API weren\'t in debug mode, this message would not appear.',
1104
+								'event_espresso'),
1105
+							wp_json_encode($query_parameters['limit'])
1106
+						)
1107
+					);
1108
+				}
1109
+				$sanitized_limit[] = (int)$limit_part;
1110
+			}
1111
+			$model_query_params['limit'] = implode(',', $sanitized_limit);
1112
+		} else {
1113
+			$model_query_params['limit'] = \EED_Core_Rest_Api::get_default_query_limit();
1114
+		}
1115
+		if (isset($query_parameters['caps'])) {
1116
+			$model_query_params['caps'] = $this->validate_context($query_parameters['caps']);
1117
+		} else {
1118
+			$model_query_params['caps'] = \EEM_Base::caps_read;
1119
+		}
1120
+		if (isset($query_parameters['default_where_conditions'])) {
1121
+			$model_query_params['default_where_conditions'] = $this->validate_default_query_params($query_parameters['default_where_conditions']);
1122
+		}
1123
+		return apply_filters('FHEE__Read__create_model_query_params', $model_query_params, $query_parameters, $model);
1124
+	}
1125
+
1126
+
1127
+
1128
+	/**
1129
+	 * Changes the REST-style query params for use in the models
1130
+	 *
1131
+	 * @deprecated
1132
+	 * @param \EEM_Base $model
1133
+	 * @param array     $query_params sub-array from @see EEM_Base::get_all()
1134
+	 * @return array
1135
+	 */
1136
+	public function prepare_rest_query_params_key_for_models($model, $query_params)
1137
+	{
1138
+		$model_ready_query_params = array();
1139
+		foreach ($query_params as $key => $value) {
1140
+			if (is_array($value)) {
1141
+				$model_ready_query_params[$key] = $this->prepare_rest_query_params_key_for_models($model, $value);
1142
+			} else {
1143
+				$model_ready_query_params[$key] = $value;
1144
+			}
1145
+		}
1146
+		return $model_ready_query_params;
1147
+	}
1148
+
1149
+
1150
+
1151
+	/**
1152
+	 * @deprecated
1153
+	 * @param $model
1154
+	 * @param $query_params
1155
+	 * @return array
1156
+	 */
1157
+	public function prepare_rest_query_params_values_for_models($model, $query_params)
1158
+	{
1159
+		$model_ready_query_params = array();
1160
+		foreach ($query_params as $key => $value) {
1161
+			if (is_array($value)) {
1162
+				$model_ready_query_params[$key] = $this->prepare_rest_query_params_values_for_models($model, $value);
1163
+			} else {
1164
+				$model_ready_query_params[$key] = $value;
1165
+			}
1166
+		}
1167
+		return $model_ready_query_params;
1168
+	}
1169
+
1170
+
1171
+
1172
+	/**
1173
+	 * Explodes the string on commas, and only returns items with $prefix followed by a period.
1174
+	 * If no prefix is specified, returns items with no period.
1175
+	 *
1176
+	 * @param string|array $string_to_explode eg "jibba,jabba, blah, blaabla" or array('jibba', 'jabba' )
1177
+	 * @param string       $prefix            "Event" or "foobar"
1178
+	 * @return array $string_to_exploded exploded on COMMAS, and if a prefix was specified
1179
+	 *                                        we only return strings starting with that and a period; if no prefix was
1180
+	 *                                        specified we return all items containing NO periods
1181
+	 */
1182
+	public function explode_and_get_items_prefixed_with($string_to_explode, $prefix)
1183
+	{
1184
+		if (is_string($string_to_explode)) {
1185
+			$exploded_contents = explode(',', $string_to_explode);
1186
+		} else if (is_array($string_to_explode)) {
1187
+			$exploded_contents = $string_to_explode;
1188
+		} else {
1189
+			$exploded_contents = array();
1190
+		}
1191
+		//if the string was empty, we want an empty array
1192
+		$exploded_contents = array_filter($exploded_contents);
1193
+		$contents_with_prefix = array();
1194
+		foreach ($exploded_contents as $item) {
1195
+			$item = trim($item);
1196
+			//if no prefix was provided, so we look for items with no "." in them
1197
+			if (! $prefix) {
1198
+				//does this item have a period?
1199
+				if (strpos($item, '.') === false) {
1200
+					//if not, then its what we're looking for
1201
+					$contents_with_prefix[] = $item;
1202
+				}
1203
+			} else if (strpos($item, $prefix . '.') === 0) {
1204
+				//this item has the prefix and a period, grab it
1205
+				$contents_with_prefix[] = substr(
1206
+					$item,
1207
+					strpos($item, $prefix . '.') + strlen($prefix . '.')
1208
+				);
1209
+			} else if ($item === $prefix) {
1210
+				//this item is JUST the prefix
1211
+				//so let's grab everything after, which is a blank string
1212
+				$contents_with_prefix[] = '';
1213
+			}
1214
+		}
1215
+		return $contents_with_prefix;
1216
+	}
1217
+
1218
+
1219
+
1220
+	/**
1221
+	 * @deprecated since 4.8.36.rc.001 You should instead use Read::explode_and_get_items_prefixed_with.
1222
+	 * Deprecated because its return values were really quite confusing- sometimes it returned
1223
+	 * an empty array (when the include string was blank or '*') or sometimes it returned
1224
+	 * array('*') (when you provided a model and a model of that kind was found).
1225
+	 * Parses the $include_string so we fetch all the field names relating to THIS model
1226
+	 * (ie have NO period in them), or for the provided model (ie start with the model
1227
+	 * name and then a period).
1228
+	 * @param string $include_string @see Read:handle_request_get_all
1229
+	 * @param string $model_name
1230
+	 * @return array of fields for this model. If $model_name is provided, then
1231
+	 *                               the fields for that model, with the model's name removed from each.
1232
+	 *                               If $include_string was blank or '*' returns an empty array
1233
+	 */
1234
+	public function extract_includes_for_this_model($include_string, $model_name = null)
1235
+	{
1236
+		if (is_array($include_string)) {
1237
+			$include_string = implode(',', $include_string);
1238
+		}
1239
+		if ($include_string === '*' || $include_string === '') {
1240
+			return array();
1241
+		}
1242
+		$includes = explode(',', $include_string);
1243
+		$extracted_fields_to_include = array();
1244
+		if ($model_name) {
1245
+			foreach ($includes as $field_to_include) {
1246
+				$field_to_include = trim($field_to_include);
1247
+				if (strpos($field_to_include, $model_name . '.') === 0) {
1248
+					//found the model name at the exact start
1249
+					$field_sans_model_name = str_replace($model_name . '.', '', $field_to_include);
1250
+					$extracted_fields_to_include[] = $field_sans_model_name;
1251
+				} elseif ($field_to_include == $model_name) {
1252
+					$extracted_fields_to_include[] = '*';
1253
+				}
1254
+			}
1255
+		} else {
1256
+			//look for ones with no period
1257
+			foreach ($includes as $field_to_include) {
1258
+				$field_to_include = trim($field_to_include);
1259
+				if (
1260
+					strpos($field_to_include, '.') === false
1261
+					&& ! $this->get_model_version_info()->is_model_name_in_this_version($field_to_include)
1262
+				) {
1263
+					$extracted_fields_to_include[] = $field_to_include;
1264
+				}
1265
+			}
1266
+		}
1267
+		return $extracted_fields_to_include;
1268
+	}
1269 1269
 }
1270 1270
 
1271 1271
 
Please login to merge, or discard this patch.
core/libraries/rest_api/Model_Version_Info.php 1 patch
Indentation   +457 added lines, -457 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 namespace EventEspresso\core\libraries\rest_api;
3 3
 
4 4
 if (! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 
@@ -23,462 +23,462 @@  discard block
 block discarded – undo
23 23
 class Model_Version_Info
24 24
 {
25 25
 
26
-    /**
27
-     * Constant used in the $_model_changes array to indicate that a model
28
-     * was completely new in this version
29
-     */
30
-    const model_added = 'model_added_in_this_version';
31
-
32
-    /**
33
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
34
-     * next-level keys are model names (eg "Event") that underwent some change in that version
35
-     * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
36
-     * or it's an array where the values are model field names,
37
-     * or API resource properties (ie, non-model fields that appear in REST API results)
38
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
39
-     *
40
-     * @var array
41
-     */
42
-    protected $_model_changes = array();
43
-
44
-    /**
45
-     * top-level keys are version numbers,
46
-     * next-level keys are model CLASSNAMES (even parent classnames),
47
-     * and next-level keys are extra resource properties to attach to those models' resources,
48
-     * and next-level key-value pairs, where the keys are:
49
-     * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
50
-     *
51
-     * @var array
52
-     */
53
-    protected $_resource_changes = array();
54
-
55
-    /**
56
-     * @var string indicating what version of the API was requested
57
-     * (eg although core might be at version 4.8.11, they may have sent a request
58
-     * for 4.6)
59
-     */
60
-    protected $_requested_version = null;
61
-
62
-    /**
63
-     * Keys are model names, values are their classnames.
64
-     * We cache this so we only need to calculate this once per request
65
-     *
66
-     * @var array
67
-     */
68
-    protected $_cached_models_for_requested_version = null;
69
-
70
-    /**
71
-     * @var array
72
-     */
73
-    protected $_cached_model_changes_between_requested_version_and_current = null;
74
-
75
-    /**
76
-     * @var array
77
-     */
78
-    protected $_cached_resource_changes_between_requested_version_and_current = null;
79
-
80
-    /**
81
-     * 2d array where top-level keys are model names, 2nd-level keys are field names
82
-     * and values are the actual field objects
83
-     *
84
-     * @var array
85
-     */
86
-    protected $_cached_fields_on_models = array();
87
-
88
-
89
-
90
-    /**
91
-     * Model_Version_Info constructor.
92
-     *
93
-     * @param string $requested_version
94
-     */
95
-    public function __construct($requested_version)
96
-    {
97
-        $this->_requested_version = $requested_version;
98
-        $this->_model_changes = array(
99
-            '4.8.29' => array(
100
-                //first version where the REST API is in EE core, so no need
101
-                //to specify how its different from the previous
102
-            ),
103
-        );
104
-        //setup data for "extra" fields added onto resources which don't actually exist on models
105
-        $this->_resource_changes = apply_filters(
106
-            'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
107
-            array()
108
-        );
109
-        $defaults = array(
110
-            'raw'              => false,
111
-            'type'             => 'N/A',
112
-            'nullable'         => true,
113
-            'table_alias'      => 'N/A',
114
-            'table_column'     => 'N/A',
115
-            'always_available' => true,
116
-        );
117
-        foreach ($this->_resource_changes as $version => $model_classnames) {
118
-            foreach ($model_classnames as $model_classname => $extra_fields) {
119
-                foreach ($extra_fields as $fieldname => $field_data) {
120
-                    $this->_resource_changes[$model_classname][$fieldname]['name'] = $fieldname;
121
-                    foreach ($defaults as $attribute => $default_value) {
122
-                        if (! isset($this->_resource_changes[$model_classname][$fieldname][$attribute])) {
123
-                            $this->_resource_changes[$model_classname][$fieldname][$attribute] = $default_value;
124
-                        }
125
-                    }
126
-                }
127
-            }
128
-        }
129
-    }
130
-
131
-
132
-
133
-    /**
134
-     * Returns a slice of Model_Version_Info::model_changes()'s array
135
-     * indicating exactly what changes happened between the current core version,
136
-     * and the version requested
137
-     *
138
-     * @return array
139
-     */
140
-    public function model_changes_between_requested_version_and_current()
141
-    {
142
-        if ($this->_cached_model_changes_between_requested_version_and_current === null) {
143
-            $model_changes = array();
144
-            foreach ($this->model_changes() as $version => $models_changed_in_version) {
145
-                if ($version <= \EED_Core_Rest_Api::core_version() && $version > $this->requested_version()) {
146
-                    $model_changes[$version] = $models_changed_in_version;
147
-                }
148
-            }
149
-            $this->_cached_model_changes_between_requested_version_and_current = $model_changes;
150
-        }
151
-        return $this->_cached_model_changes_between_requested_version_and_current;
152
-    }
153
-
154
-
155
-
156
-    /**
157
-     * Returns a slice of Model_Version_Info::model_changes()'s array
158
-     * indicating exactly what changes happened between the current core version,
159
-     * and the version requested
160
-     *
161
-     * @return array
162
-     */
163
-    public function resource_changes_between_requested_version_and_current()
164
-    {
165
-        if ($this->_cached_resource_changes_between_requested_version_and_current === null) {
166
-            $resource_changes = array();
167
-            foreach ($this->resource_changes() as $version => $model_classnames) {
168
-                if ($version <= \EED_Core_Rest_Api::core_version() && $version > $this->requested_version()) {
169
-                    $resource_changes[$version] = $model_classnames;
170
-                }
171
-            }
172
-            $this->_cached_resource_changes_between_requested_version_and_current = $resource_changes;
173
-        }
174
-        return $this->_cached_resource_changes_between_requested_version_and_current;
175
-    }
176
-
177
-
178
-
179
-    /**
180
-     * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
181
-     *
182
-     * @return string like '4.6'
183
-     */
184
-    public function requested_version()
185
-    {
186
-        return $this->_requested_version;
187
-    }
188
-
189
-
190
-
191
-    /**
192
-     * Returns an array describing how the models have changed in each version of core
193
-     * that supports the API (starting at 4.6)
194
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
195
-     * next-level keys are model names (eg "Event") that underwent some change in that version
196
-     * and the value is either NULL (indicating the model is completely NEW in this version),
197
-     * or it's an array where fields are value names.
198
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
199
-     *
200
-     * @return array
201
-     */
202
-    public function model_changes()
203
-    {
204
-        return $this->_model_changes;
205
-    }
206
-
207
-
208
-
209
-    /**
210
-     * Takes into account the requested version, and the current version, and
211
-     * what changed between the two, and tries to return.
212
-     * Analogous to EE_Registry::instance()->non_abstract_db_models
213
-     *
214
-     * @return array keys are model names, values are their classname
215
-     */
216
-    public function models_for_requested_version()
217
-    {
218
-        if ($this->_cached_models_for_requested_version === null) {
219
-            $all_models_in_current_version = \EE_Registry::instance()->non_abstract_db_models();
220
-            foreach ($this->model_changes_between_requested_version_and_current() as $version => $models_changed) {
221
-                foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
222
-                    if ($new_indicator_or_fields_added === Model_Version_Info::model_added) {
223
-                        unset($all_models_in_current_version[$model_name]);
224
-                    }
225
-                }
226
-            }
227
-            $this->_cached_models_for_requested_version = apply_filters(
228
-                'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
229
-                $all_models_in_current_version,
230
-                $this
231
-            );
232
-        }
233
-        return $this->_cached_models_for_requested_version;
234
-    }
235
-
236
-
237
-
238
-    /**
239
-     * Determines if this is a valid model name in the requested version.
240
-     * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
241
-     * version's models into account
242
-     *
243
-     * @param string $model_name eg 'Event'
244
-     * @return boolean
245
-     */
246
-    public function is_model_name_in_this_version($model_name)
247
-    {
248
-        $model_names = $this->models_for_requested_version();
249
-        if (isset($model_names[$model_name])) {
250
-            return true;
251
-        } else {
252
-            return false;
253
-        }
254
-    }
255
-
256
-
257
-
258
-    /**
259
-     * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
260
-     * version's models into account
261
-     *
262
-     * @param string $model_name
263
-     * @return \EEM_Base
264
-     * @throws \EE_Error
265
-     */
266
-    public function load_model($model_name)
267
-    {
268
-        if ($this->is_model_name_in_this_version($model_name)) {
269
-            return \EE_Registry::instance()->load_model($model_name);
270
-        } else {
271
-            throw new \EE_Error(
272
-                sprintf(
273
-                    __(
274
-                        'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
275
-                        'event_espresso'
276
-                    ),
277
-                    $model_name,
278
-                    $this->requested_version()
279
-                )
280
-            );
281
-        }
282
-    }
283
-
284
-
285
-
286
-    /**
287
-     * Gets all the fields that should exist on this model right now
288
-     *
289
-     * @param \EEM_Base $model
290
-     * @return array|\EE_Model_Field_Base[]
291
-     */
292
-    public function fields_on_model_in_this_version($model)
293
-    {
294
-        if (! isset($this->_cached_fields_on_models[$model->get_this_model_name()])) {
295
-            //get all model changes between the requested version and current core version
296
-            $changes = $this->model_changes_between_requested_version_and_current();
297
-            //fetch all fields currently on this model
298
-            $current_fields = $model->field_settings();
299
-            //remove all fields that have been added since
300
-            foreach ($changes as $version => $changes_in_version) {
301
-                if (
302
-                    isset($changes_in_version[$model->get_this_model_name()])
303
-                    && $changes_in_version[$model->get_this_model_name()] !== Model_Version_Info::model_added
304
-                ) {
305
-                    $current_fields = array_diff_key(
306
-                        $current_fields,
307
-                        array_flip($changes_in_version[$model->get_this_model_name()])
308
-                    );
309
-                }
310
-            }
311
-            $this->_cached_fields_on_models = $current_fields;
312
-        }
313
-        return $this->_cached_fields_on_models;
314
-    }
315
-
316
-
317
-
318
-    /**
319
-     * Determines if $object is of one of the classes of $classes. Similar to
320
-     * in_array(), except this checks if $object is a subclass of the classnames provided
321
-     * in $classnames
322
-     *
323
-     * @param object $object
324
-     * @param array  $classnames
325
-     * @return boolean
326
-     */
327
-    public function is_subclass_of_one($object, $classnames)
328
-    {
329
-        foreach ($classnames as $classname) {
330
-            if (is_a($object, $classname)) {
331
-                return true;
332
-            }
333
-        }
334
-        return false;
335
-    }
336
-
337
-
338
-
339
-    /**
340
-     * Returns the list of model field classes that that the API basically ignores
341
-     *
342
-     * @return array
343
-     */
344
-    public function fields_ignored()
345
-    {
346
-        return apply_filters(
347
-            'FHEE__Controller_Model_Read_fields_ignored',
348
-            array('EE_Foreign_Key_Field_Base', 'EE_Any_Foreign_Model_Name_Field')
349
-        );
350
-    }
351
-
352
-
353
-
354
-    /**
355
-     * If this field one that should be ignored by the API?
356
-     *
357
-     * @param EE_Model_Field_Base
358
-     * @return boolean
359
-     */
360
-    public function field_is_ignored($field_obj)
361
-    {
362
-        return $this->is_subclass_of_one($field_obj, $this->fields_ignored());
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     * Returns the list of model field classes that have a "raw" and non-raw formats.
369
-     * Normally the "raw" versions are only accessible to those who can edit them.
370
-     *
371
-     * @return array an array of EE_Model_Field_Base child classnames
372
-     */
373
-    public function fields_that_have_rendered_format()
374
-    {
375
-        return apply_filters(
376
-            'FHEE__Controller_Model_Read__fields_raw',
377
-            array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
378
-        );
379
-    }
380
-
381
-
382
-
383
-    /**
384
-     * If this field one that has a raw format
385
-     *
386
-     * @param EE_Model_Field_Base
387
-     * @return boolean
388
-     */
389
-    public function field_has_rendered_format($field_obj)
390
-    {
391
-        return $this->is_subclass_of_one($field_obj, $this->fields_that_have_rendered_format());
392
-    }
393
-
394
-
395
-
396
-    /**
397
-     * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
398
-     * The pretty version of the field is NOT queryable or editable, but requires no extra permissions
399
-     * to view
400
-     *
401
-     * @return array an array of EE_Model_Field_Base child classnames
402
-     */
403
-    public function fields_that_have_pretty_format()
404
-    {
405
-        return apply_filters(
406
-            'FHEE__Controller_Model_Read__fields_pretty',
407
-            array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
408
-        );
409
-    }
410
-
411
-
412
-
413
-    /**
414
-     * If this field one that has a pretty equivalent
415
-     *
416
-     * @param EE_Model_Field_Base
417
-     * @return boolean
418
-     */
419
-    public function field_has_pretty_format($field_obj)
420
-    {
421
-        return $this->is_subclass_of_one($field_obj, $this->fields_that_have_pretty_format());
422
-    }
423
-
424
-
425
-
426
-    /**
427
-     * Returns an array describing what extra API resource properties have been added through the versions
428
-     *
429
-     * @return array @see $this->_extra_resource_properties_for_models
430
-     */
431
-    public function resource_changes()
432
-    {
433
-        return $this->_resource_changes;
434
-    }
435
-
436
-
437
-
438
-    /**
439
-     * Returns an array where keys are extra resource properties in this version of the API,
440
-     * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
441
-     *
442
-     * @param \EEM_Base $model
443
-     * @return array
444
-     */
445
-    public function extra_resource_properties_for_model($model)
446
-    {
447
-        $extra_properties = array();
448
-        foreach ($this->resource_changes_between_requested_version_and_current() as $version => $model_classnames) {
449
-            foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
450
-                if (is_subclass_of($model, $model_classname)) {
451
-                    $extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
452
-                }
453
-            }
454
-        }
455
-        return $extra_properties;
456
-    }
457
-
458
-
459
-
460
-    /**
461
-     * Gets all the related models for the specified model. It's good to use this
462
-     * in case this model didn't exist for this version or something
463
-     *
464
-     * @param \EEM_Base $model
465
-     * @return \EE_Model_Relation_Base[]
466
-     */
467
-    public function relation_settings(\EEM_Base $model)
468
-    {
469
-        $relations = array();
470
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
471
-            if ($this->is_model_name_in_this_version($relation_name)) {
472
-                $relations[$relation_name] = $relation_obj;
473
-            }
474
-        }
475
-        //filter the results, but use the old filter name
476
-        return apply_filters(
477
-            'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
478
-            $relations,
479
-            $model
480
-        );
481
-    }
26
+	/**
27
+	 * Constant used in the $_model_changes array to indicate that a model
28
+	 * was completely new in this version
29
+	 */
30
+	const model_added = 'model_added_in_this_version';
31
+
32
+	/**
33
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
34
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
35
+	 * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
36
+	 * or it's an array where the values are model field names,
37
+	 * or API resource properties (ie, non-model fields that appear in REST API results)
38
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
39
+	 *
40
+	 * @var array
41
+	 */
42
+	protected $_model_changes = array();
43
+
44
+	/**
45
+	 * top-level keys are version numbers,
46
+	 * next-level keys are model CLASSNAMES (even parent classnames),
47
+	 * and next-level keys are extra resource properties to attach to those models' resources,
48
+	 * and next-level key-value pairs, where the keys are:
49
+	 * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
50
+	 *
51
+	 * @var array
52
+	 */
53
+	protected $_resource_changes = array();
54
+
55
+	/**
56
+	 * @var string indicating what version of the API was requested
57
+	 * (eg although core might be at version 4.8.11, they may have sent a request
58
+	 * for 4.6)
59
+	 */
60
+	protected $_requested_version = null;
61
+
62
+	/**
63
+	 * Keys are model names, values are their classnames.
64
+	 * We cache this so we only need to calculate this once per request
65
+	 *
66
+	 * @var array
67
+	 */
68
+	protected $_cached_models_for_requested_version = null;
69
+
70
+	/**
71
+	 * @var array
72
+	 */
73
+	protected $_cached_model_changes_between_requested_version_and_current = null;
74
+
75
+	/**
76
+	 * @var array
77
+	 */
78
+	protected $_cached_resource_changes_between_requested_version_and_current = null;
79
+
80
+	/**
81
+	 * 2d array where top-level keys are model names, 2nd-level keys are field names
82
+	 * and values are the actual field objects
83
+	 *
84
+	 * @var array
85
+	 */
86
+	protected $_cached_fields_on_models = array();
87
+
88
+
89
+
90
+	/**
91
+	 * Model_Version_Info constructor.
92
+	 *
93
+	 * @param string $requested_version
94
+	 */
95
+	public function __construct($requested_version)
96
+	{
97
+		$this->_requested_version = $requested_version;
98
+		$this->_model_changes = array(
99
+			'4.8.29' => array(
100
+				//first version where the REST API is in EE core, so no need
101
+				//to specify how its different from the previous
102
+			),
103
+		);
104
+		//setup data for "extra" fields added onto resources which don't actually exist on models
105
+		$this->_resource_changes = apply_filters(
106
+			'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
107
+			array()
108
+		);
109
+		$defaults = array(
110
+			'raw'              => false,
111
+			'type'             => 'N/A',
112
+			'nullable'         => true,
113
+			'table_alias'      => 'N/A',
114
+			'table_column'     => 'N/A',
115
+			'always_available' => true,
116
+		);
117
+		foreach ($this->_resource_changes as $version => $model_classnames) {
118
+			foreach ($model_classnames as $model_classname => $extra_fields) {
119
+				foreach ($extra_fields as $fieldname => $field_data) {
120
+					$this->_resource_changes[$model_classname][$fieldname]['name'] = $fieldname;
121
+					foreach ($defaults as $attribute => $default_value) {
122
+						if (! isset($this->_resource_changes[$model_classname][$fieldname][$attribute])) {
123
+							$this->_resource_changes[$model_classname][$fieldname][$attribute] = $default_value;
124
+						}
125
+					}
126
+				}
127
+			}
128
+		}
129
+	}
130
+
131
+
132
+
133
+	/**
134
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
135
+	 * indicating exactly what changes happened between the current core version,
136
+	 * and the version requested
137
+	 *
138
+	 * @return array
139
+	 */
140
+	public function model_changes_between_requested_version_and_current()
141
+	{
142
+		if ($this->_cached_model_changes_between_requested_version_and_current === null) {
143
+			$model_changes = array();
144
+			foreach ($this->model_changes() as $version => $models_changed_in_version) {
145
+				if ($version <= \EED_Core_Rest_Api::core_version() && $version > $this->requested_version()) {
146
+					$model_changes[$version] = $models_changed_in_version;
147
+				}
148
+			}
149
+			$this->_cached_model_changes_between_requested_version_and_current = $model_changes;
150
+		}
151
+		return $this->_cached_model_changes_between_requested_version_and_current;
152
+	}
153
+
154
+
155
+
156
+	/**
157
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
158
+	 * indicating exactly what changes happened between the current core version,
159
+	 * and the version requested
160
+	 *
161
+	 * @return array
162
+	 */
163
+	public function resource_changes_between_requested_version_and_current()
164
+	{
165
+		if ($this->_cached_resource_changes_between_requested_version_and_current === null) {
166
+			$resource_changes = array();
167
+			foreach ($this->resource_changes() as $version => $model_classnames) {
168
+				if ($version <= \EED_Core_Rest_Api::core_version() && $version > $this->requested_version()) {
169
+					$resource_changes[$version] = $model_classnames;
170
+				}
171
+			}
172
+			$this->_cached_resource_changes_between_requested_version_and_current = $resource_changes;
173
+		}
174
+		return $this->_cached_resource_changes_between_requested_version_and_current;
175
+	}
176
+
177
+
178
+
179
+	/**
180
+	 * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
181
+	 *
182
+	 * @return string like '4.6'
183
+	 */
184
+	public function requested_version()
185
+	{
186
+		return $this->_requested_version;
187
+	}
188
+
189
+
190
+
191
+	/**
192
+	 * Returns an array describing how the models have changed in each version of core
193
+	 * that supports the API (starting at 4.6)
194
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
195
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
196
+	 * and the value is either NULL (indicating the model is completely NEW in this version),
197
+	 * or it's an array where fields are value names.
198
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
199
+	 *
200
+	 * @return array
201
+	 */
202
+	public function model_changes()
203
+	{
204
+		return $this->_model_changes;
205
+	}
206
+
207
+
208
+
209
+	/**
210
+	 * Takes into account the requested version, and the current version, and
211
+	 * what changed between the two, and tries to return.
212
+	 * Analogous to EE_Registry::instance()->non_abstract_db_models
213
+	 *
214
+	 * @return array keys are model names, values are their classname
215
+	 */
216
+	public function models_for_requested_version()
217
+	{
218
+		if ($this->_cached_models_for_requested_version === null) {
219
+			$all_models_in_current_version = \EE_Registry::instance()->non_abstract_db_models();
220
+			foreach ($this->model_changes_between_requested_version_and_current() as $version => $models_changed) {
221
+				foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
222
+					if ($new_indicator_or_fields_added === Model_Version_Info::model_added) {
223
+						unset($all_models_in_current_version[$model_name]);
224
+					}
225
+				}
226
+			}
227
+			$this->_cached_models_for_requested_version = apply_filters(
228
+				'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
229
+				$all_models_in_current_version,
230
+				$this
231
+			);
232
+		}
233
+		return $this->_cached_models_for_requested_version;
234
+	}
235
+
236
+
237
+
238
+	/**
239
+	 * Determines if this is a valid model name in the requested version.
240
+	 * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
241
+	 * version's models into account
242
+	 *
243
+	 * @param string $model_name eg 'Event'
244
+	 * @return boolean
245
+	 */
246
+	public function is_model_name_in_this_version($model_name)
247
+	{
248
+		$model_names = $this->models_for_requested_version();
249
+		if (isset($model_names[$model_name])) {
250
+			return true;
251
+		} else {
252
+			return false;
253
+		}
254
+	}
255
+
256
+
257
+
258
+	/**
259
+	 * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
260
+	 * version's models into account
261
+	 *
262
+	 * @param string $model_name
263
+	 * @return \EEM_Base
264
+	 * @throws \EE_Error
265
+	 */
266
+	public function load_model($model_name)
267
+	{
268
+		if ($this->is_model_name_in_this_version($model_name)) {
269
+			return \EE_Registry::instance()->load_model($model_name);
270
+		} else {
271
+			throw new \EE_Error(
272
+				sprintf(
273
+					__(
274
+						'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
275
+						'event_espresso'
276
+					),
277
+					$model_name,
278
+					$this->requested_version()
279
+				)
280
+			);
281
+		}
282
+	}
283
+
284
+
285
+
286
+	/**
287
+	 * Gets all the fields that should exist on this model right now
288
+	 *
289
+	 * @param \EEM_Base $model
290
+	 * @return array|\EE_Model_Field_Base[]
291
+	 */
292
+	public function fields_on_model_in_this_version($model)
293
+	{
294
+		if (! isset($this->_cached_fields_on_models[$model->get_this_model_name()])) {
295
+			//get all model changes between the requested version and current core version
296
+			$changes = $this->model_changes_between_requested_version_and_current();
297
+			//fetch all fields currently on this model
298
+			$current_fields = $model->field_settings();
299
+			//remove all fields that have been added since
300
+			foreach ($changes as $version => $changes_in_version) {
301
+				if (
302
+					isset($changes_in_version[$model->get_this_model_name()])
303
+					&& $changes_in_version[$model->get_this_model_name()] !== Model_Version_Info::model_added
304
+				) {
305
+					$current_fields = array_diff_key(
306
+						$current_fields,
307
+						array_flip($changes_in_version[$model->get_this_model_name()])
308
+					);
309
+				}
310
+			}
311
+			$this->_cached_fields_on_models = $current_fields;
312
+		}
313
+		return $this->_cached_fields_on_models;
314
+	}
315
+
316
+
317
+
318
+	/**
319
+	 * Determines if $object is of one of the classes of $classes. Similar to
320
+	 * in_array(), except this checks if $object is a subclass of the classnames provided
321
+	 * in $classnames
322
+	 *
323
+	 * @param object $object
324
+	 * @param array  $classnames
325
+	 * @return boolean
326
+	 */
327
+	public function is_subclass_of_one($object, $classnames)
328
+	{
329
+		foreach ($classnames as $classname) {
330
+			if (is_a($object, $classname)) {
331
+				return true;
332
+			}
333
+		}
334
+		return false;
335
+	}
336
+
337
+
338
+
339
+	/**
340
+	 * Returns the list of model field classes that that the API basically ignores
341
+	 *
342
+	 * @return array
343
+	 */
344
+	public function fields_ignored()
345
+	{
346
+		return apply_filters(
347
+			'FHEE__Controller_Model_Read_fields_ignored',
348
+			array('EE_Foreign_Key_Field_Base', 'EE_Any_Foreign_Model_Name_Field')
349
+		);
350
+	}
351
+
352
+
353
+
354
+	/**
355
+	 * If this field one that should be ignored by the API?
356
+	 *
357
+	 * @param EE_Model_Field_Base
358
+	 * @return boolean
359
+	 */
360
+	public function field_is_ignored($field_obj)
361
+	{
362
+		return $this->is_subclass_of_one($field_obj, $this->fields_ignored());
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 * Returns the list of model field classes that have a "raw" and non-raw formats.
369
+	 * Normally the "raw" versions are only accessible to those who can edit them.
370
+	 *
371
+	 * @return array an array of EE_Model_Field_Base child classnames
372
+	 */
373
+	public function fields_that_have_rendered_format()
374
+	{
375
+		return apply_filters(
376
+			'FHEE__Controller_Model_Read__fields_raw',
377
+			array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
378
+		);
379
+	}
380
+
381
+
382
+
383
+	/**
384
+	 * If this field one that has a raw format
385
+	 *
386
+	 * @param EE_Model_Field_Base
387
+	 * @return boolean
388
+	 */
389
+	public function field_has_rendered_format($field_obj)
390
+	{
391
+		return $this->is_subclass_of_one($field_obj, $this->fields_that_have_rendered_format());
392
+	}
393
+
394
+
395
+
396
+	/**
397
+	 * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
398
+	 * The pretty version of the field is NOT queryable or editable, but requires no extra permissions
399
+	 * to view
400
+	 *
401
+	 * @return array an array of EE_Model_Field_Base child classnames
402
+	 */
403
+	public function fields_that_have_pretty_format()
404
+	{
405
+		return apply_filters(
406
+			'FHEE__Controller_Model_Read__fields_pretty',
407
+			array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
408
+		);
409
+	}
410
+
411
+
412
+
413
+	/**
414
+	 * If this field one that has a pretty equivalent
415
+	 *
416
+	 * @param EE_Model_Field_Base
417
+	 * @return boolean
418
+	 */
419
+	public function field_has_pretty_format($field_obj)
420
+	{
421
+		return $this->is_subclass_of_one($field_obj, $this->fields_that_have_pretty_format());
422
+	}
423
+
424
+
425
+
426
+	/**
427
+	 * Returns an array describing what extra API resource properties have been added through the versions
428
+	 *
429
+	 * @return array @see $this->_extra_resource_properties_for_models
430
+	 */
431
+	public function resource_changes()
432
+	{
433
+		return $this->_resource_changes;
434
+	}
435
+
436
+
437
+
438
+	/**
439
+	 * Returns an array where keys are extra resource properties in this version of the API,
440
+	 * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
441
+	 *
442
+	 * @param \EEM_Base $model
443
+	 * @return array
444
+	 */
445
+	public function extra_resource_properties_for_model($model)
446
+	{
447
+		$extra_properties = array();
448
+		foreach ($this->resource_changes_between_requested_version_and_current() as $version => $model_classnames) {
449
+			foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
450
+				if (is_subclass_of($model, $model_classname)) {
451
+					$extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
452
+				}
453
+			}
454
+		}
455
+		return $extra_properties;
456
+	}
457
+
458
+
459
+
460
+	/**
461
+	 * Gets all the related models for the specified model. It's good to use this
462
+	 * in case this model didn't exist for this version or something
463
+	 *
464
+	 * @param \EEM_Base $model
465
+	 * @return \EE_Model_Relation_Base[]
466
+	 */
467
+	public function relation_settings(\EEM_Base $model)
468
+	{
469
+		$relations = array();
470
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
471
+			if ($this->is_model_name_in_this_version($relation_name)) {
472
+				$relations[$relation_name] = $relation_obj;
473
+			}
474
+		}
475
+		//filter the results, but use the old filter name
476
+		return apply_filters(
477
+			'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
478
+			$relations,
479
+			$model
480
+		);
481
+	}
482 482
 
483 483
 }
484 484
 
Please login to merge, or discard this patch.