Completed
Branch FET-3467-waitlists (388345)
by
unknown
138:08 queued 126:13
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.000');
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.000');
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/db_classes/EE_Base_Class.class.php 2 patches
Doc Comments   +10 added lines, -9 removed lines patch added patch discarded remove patch
@@ -609,7 +609,7 @@  discard block
 block discarded – undo
609 609
      *
610 610
      * @param \EE_Datetime_Field $datetime_field
611 611
      * @param bool               $pretty
612
-     * @param null $date_or_time
612
+     * @param string|null $date_or_time
613 613
      * @return void
614 614
      * @throws \EE_Error
615 615
      */
@@ -946,7 +946,7 @@  discard block
 block discarded – undo
946 946
      *
947 947
      * @param null  $field_to_order_by  What field is being used as the reference point.
948 948
      * @param array $query_params       Any additional conditions on the query.
949
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
949
+     * @param string  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
950 950
      *                                  you can indicate just the columns you want returned
951 951
      * @return array|EE_Base_Class
952 952
      * @throws \EE_Error
@@ -971,7 +971,7 @@  discard block
 block discarded – undo
971 971
      *
972 972
      * @param null  $field_to_order_by  What field is being used as the reference point.
973 973
      * @param array $query_params       Any additional conditions on the query.
974
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
974
+     * @param string  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
975 975
      *                                  you can indicate just the column you want returned
976 976
      * @return array|EE_Base_Class
977 977
      * @throws \EE_Error
@@ -1044,7 +1044,7 @@  discard block
 block discarded – undo
1044 1044
      * This method simply returns the RAW unprocessed value for the given property in this class
1045 1045
      *
1046 1046
      * @param  string $field_name A valid fieldname
1047
-     * @return mixed              Whatever the raw value stored on the property is.
1047
+     * @return integer|null              Whatever the raw value stored on the property is.
1048 1048
      * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1049 1049
      */
1050 1050
     public function get_raw($field_name)
@@ -1321,7 +1321,7 @@  discard block
 block discarded – undo
1321 1321
      * sets the time on a datetime property
1322 1322
      *
1323 1323
      * @access protected
1324
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1324
+     * @param string $time      a valid time string for php datetime functions (or DateTime object)
1325 1325
      * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1326 1326
      * @throws \EE_Error
1327 1327
      */
@@ -1336,7 +1336,7 @@  discard block
 block discarded – undo
1336 1336
      * sets the date on a datetime property
1337 1337
      *
1338 1338
      * @access protected
1339
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1339
+     * @param string $date      a valid date string for php datetime functions ( or DateTime object)
1340 1340
      * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1341 1341
      * @throws \EE_Error
1342 1342
      */
@@ -1399,6 +1399,7 @@  discard block
 block discarded – undo
1399 1399
      * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1400 1400
      * @param string               $prepend    You can include something to prepend on the timestamp
1401 1401
      * @param string               $append     You can include something to append on the timestamp
1402
+     * @param string $args
1402 1403
      * @throws EE_Error
1403 1404
      * @return string timestamp
1404 1405
      */
@@ -1790,7 +1791,7 @@  discard block
 block discarded – undo
1790 1791
      *
1791 1792
      * @param  array  $props_n_values   incoming array of properties and their values
1792 1793
      * @param  string $classname        the classname of the child class
1793
-     * @param null    $timezone
1794
+     * @param string|null    $timezone
1794 1795
      * @param array   $date_formats     incoming date_formats in an array where the first value is the
1795 1796
      *                                  date_format and the second value is the time format
1796 1797
      * @return mixed (EE_Base_Class|bool)
@@ -1868,7 +1869,7 @@  discard block
 block discarded – undo
1868 1869
      * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1869 1870
      *
1870 1871
      * @param string $model_classname
1871
-     * @param null   $timezone
1872
+     * @param string|null   $timezone
1872 1873
      * @return EEM_Base
1873 1874
      */
1874 1875
     protected static function _get_model_instance_with_name($model_classname, $timezone = null)
@@ -2367,7 +2368,7 @@  discard block
 block discarded – undo
2367 2368
      *
2368 2369
      * @param string $meta_key
2369 2370
      * @param mixed  $meta_value
2370
-     * @param mixed  $previous_value
2371
+     * @param boolean  $previous_value
2371 2372
      * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2372 2373
      * @throws \EE_Error
2373 2374
      * NOTE: if the values haven't changed, returns 0
Please login to merge, or discard this patch.
Indentation   +2668 added lines, -2668 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
 do_action('AHEE_log', __FILE__, ' FILE LOADED', '');
5 5
 
@@ -25,2673 +25,2673 @@  discard block
 block discarded – undo
25 25
 abstract class EE_Base_Class
26 26
 {
27 27
 
28
-    /**
29
-     * This is an array of the original properties and values provided during construction
30
-     * of this model object. (keys are model field names, values are their values).
31
-     * This list is important to remember so that when we are merging data from the db, we know
32
-     * which values to override and which to not override.
33
-     *
34
-     * @var array
35
-     */
36
-    protected $_props_n_values_provided_in_constructor;
37
-
38
-    /**
39
-     * Timezone
40
-     * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
-     * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
-     * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
-     * access to it.
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_timezone;
48
-
49
-
50
-
51
-    /**
52
-     * date format
53
-     * pattern or format for displaying dates
54
-     *
55
-     * @var string $_dt_frmt
56
-     */
57
-    protected $_dt_frmt;
58
-
59
-
60
-
61
-    /**
62
-     * time format
63
-     * pattern or format for displaying time
64
-     *
65
-     * @var string $_tm_frmt
66
-     */
67
-    protected $_tm_frmt;
68
-
69
-
70
-
71
-    /**
72
-     * This property is for holding a cached array of object properties indexed by property name as the key.
73
-     * The purpose of this is for setting a cache on properties that may have calculated values after a
74
-     * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
-     * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
-     *
77
-     * @var array
78
-     */
79
-    protected $_cached_properties = array();
80
-
81
-    /**
82
-     * An array containing keys of the related model, and values are either an array of related mode objects or a
83
-     * single
84
-     * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
-     * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
-     * all others have an array)
87
-     *
88
-     * @var array
89
-     */
90
-    protected $_model_relations = array();
91
-
92
-    /**
93
-     * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
-     * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
-     *
96
-     * @var array
97
-     */
98
-    protected $_fields = array();
99
-
100
-    /**
101
-     * @var boolean indicating whether or not this model object is intended to ever be saved
102
-     * For example, we might create model objects intended to only be used for the duration
103
-     * of this request and to be thrown away, and if they were accidentally saved
104
-     * it would be a bug.
105
-     */
106
-    protected $_allow_persist = true;
107
-
108
-    /**
109
-     * @var boolean indicating whether or not this model object's properties have changed since construction
110
-     */
111
-    protected $_has_changes = false;
112
-
113
-
114
-
115
-    /**
116
-     * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
117
-     * play nice
118
-     *
119
-     * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
120
-     *                                                         layer of the model's _fields array, (eg, EVT_ID,
121
-     *                                                         TXN_amount, QST_name, etc) and values are their values
122
-     * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
123
-     *                                                         corresponding db model or not.
124
-     * @param string  $timezone                                indicate what timezone you want any datetime fields to
125
-     *                                                         be in when instantiating a EE_Base_Class object.
126
-     * @param array   $date_formats                            An array of date formats to set on construct where first
127
-     *                                                         value is the date_format and second value is the time
128
-     *                                                         format.
129
-     * @throws EE_Error
130
-     */
131
-    protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
132
-    {
133
-        $className = get_class($this);
134
-        do_action("AHEE__{$className}__construct", $this, $fieldValues);
135
-        $model = $this->get_model();
136
-        $model_fields = $model->field_settings(false);
137
-        // ensure $fieldValues is an array
138
-        $fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
139
-        // EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
140
-        // verify client code has not passed any invalid field names
141
-        foreach ($fieldValues as $field_name => $field_value) {
142
-            if ( ! isset($model_fields[$field_name])) {
143
-                throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
144
-                    "event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
145
-            }
146
-        }
147
-        // EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
148
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
149
-        if ( ! empty($date_formats) && is_array($date_formats)) {
150
-            list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
151
-        } else {
152
-            //set default formats for date and time
153
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
154
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
155
-        }
156
-        //if db model is instantiating
157
-        if ($bydb) {
158
-            //client code has indicated these field values are from the database
159
-            foreach ($model_fields as $fieldName => $field) {
160
-                $this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
161
-            }
162
-        } else {
163
-            //we're constructing a brand
164
-            //new instance of the model object. Generally, this means we'll need to do more field validation
165
-            foreach ($model_fields as $fieldName => $field) {
166
-                $this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
167
-            }
168
-        }
169
-        //remember what values were passed to this constructor
170
-        $this->_props_n_values_provided_in_constructor = $fieldValues;
171
-        //remember in entity mapper
172
-        if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
173
-            $model->add_to_entity_map($this);
174
-        }
175
-        //setup all the relations
176
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
177
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
178
-                $this->_model_relations[$relation_name] = null;
179
-            } else {
180
-                $this->_model_relations[$relation_name] = array();
181
-            }
182
-        }
183
-        /**
184
-         * Action done at the end of each model object construction
185
-         *
186
-         * @param EE_Base_Class $this the model object just created
187
-         */
188
-        do_action('AHEE__EE_Base_Class__construct__finished', $this);
189
-    }
190
-
191
-
192
-
193
-    /**
194
-     * Gets whether or not this model object is allowed to persist/be saved to the database.
195
-     *
196
-     * @return boolean
197
-     */
198
-    public function allow_persist()
199
-    {
200
-        return $this->_allow_persist;
201
-    }
202
-
203
-
204
-
205
-    /**
206
-     * Sets whether or not this model object should be allowed to be saved to the DB.
207
-     * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
208
-     * you got new information that somehow made you change your mind.
209
-     *
210
-     * @param boolean $allow_persist
211
-     * @return boolean
212
-     */
213
-    public function set_allow_persist($allow_persist)
214
-    {
215
-        return $this->_allow_persist = $allow_persist;
216
-    }
217
-
218
-
219
-
220
-    /**
221
-     * Gets the field's original value when this object was constructed during this request.
222
-     * This can be helpful when determining if a model object has changed or not
223
-     *
224
-     * @param string $field_name
225
-     * @return mixed|null
226
-     * @throws \EE_Error
227
-     */
228
-    public function get_original($field_name)
229
-    {
230
-        if (isset($this->_props_n_values_provided_in_constructor[$field_name])
231
-            && $field_settings = $this->get_model()->field_settings_for($field_name)
232
-        ) {
233
-            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
234
-        } else {
235
-            return null;
236
-        }
237
-    }
238
-
239
-
240
-
241
-    /**
242
-     * @param EE_Base_Class $obj
243
-     * @return string
244
-     */
245
-    public function get_class($obj)
246
-    {
247
-        return get_class($obj);
248
-    }
249
-
250
-
251
-
252
-    /**
253
-     * Overrides parent because parent expects old models.
254
-     * This also doesn't do any validation, and won't work for serialized arrays
255
-     *
256
-     * @param    string $field_name
257
-     * @param    mixed  $field_value
258
-     * @param bool      $use_default
259
-     * @throws \EE_Error
260
-     */
261
-    public function set($field_name, $field_value, $use_default = false)
262
-    {
263
-        // if not using default and nothing has changed, and object has already been setup (has ID),
264
-        // then don't do anything
265
-        if (
266
-            ! $use_default
267
-            && $this->_fields[$field_name] === $field_value
268
-            && $this->ID()
269
-        ) {
270
-            return;
271
-        }
272
-        $this->_has_changes = true;
273
-        $field_obj = $this->get_model()->field_settings_for($field_name);
274
-        if ($field_obj instanceof EE_Model_Field_Base) {
275
-            //			if ( method_exists( $field_obj, 'set_timezone' )) {
276
-            if ($field_obj instanceof EE_Datetime_Field) {
277
-                $field_obj->set_timezone($this->_timezone);
278
-                $field_obj->set_date_format($this->_dt_frmt);
279
-                $field_obj->set_time_format($this->_tm_frmt);
280
-            }
281
-            $holder_of_value = $field_obj->prepare_for_set($field_value);
282
-            //should the value be null?
283
-            if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
284
-                $this->_fields[$field_name] = $field_obj->get_default_value();
285
-                /**
286
-                 * To save having to refactor all the models, if a default value is used for a
287
-                 * EE_Datetime_Field, and that value is not null nor is it a DateTime
288
-                 * object.  Then let's do a set again to ensure that it becomes a DateTime
289
-                 * object.
290
-                 *
291
-                 * @since 4.6.10+
292
-                 */
293
-                if (
294
-                    $field_obj instanceof EE_Datetime_Field
295
-                    && $this->_fields[$field_name] !== null
296
-                    && ! $this->_fields[$field_name] instanceof DateTime
297
-                ) {
298
-                    empty($this->_fields[$field_name])
299
-                        ? $this->set($field_name, time())
300
-                        : $this->set($field_name, $this->_fields[$field_name]);
301
-                }
302
-            } else {
303
-                $this->_fields[$field_name] = $holder_of_value;
304
-            }
305
-            //if we're not in the constructor...
306
-            //now check if what we set was a primary key
307
-            if (
308
-                //note: props_n_values_provided_in_constructor is only set at the END of the constructor
309
-                $this->_props_n_values_provided_in_constructor
310
-                && $field_value
311
-                && $field_name === self::_get_primary_key_name(get_class($this))
312
-            ) {
313
-                //if so, we want all this object's fields to be filled either with
314
-                //what we've explicitly set on this model
315
-                //or what we have in the db
316
-                // echo "setting primary key!";
317
-                $fields_on_model = self::_get_model(get_class($this))->field_settings();
318
-                $obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
319
-                foreach ($fields_on_model as $field_obj) {
320
-                    if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
321
-                         && $field_obj->get_name() !== $field_name
322
-                    ) {
323
-                        $this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
324
-                    }
325
-                }
326
-                //oh this model object has an ID? well make sure its in the entity mapper
327
-                $this->get_model()->add_to_entity_map($this);
328
-            }
329
-            //let's unset any cache for this field_name from the $_cached_properties property.
330
-            $this->_clear_cached_property($field_name);
331
-        } else {
332
-            throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
333
-                "event_espresso"), $field_name));
334
-        }
335
-    }
336
-
337
-
338
-
339
-    /**
340
-     * This sets the field value on the db column if it exists for the given $column_name or
341
-     * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
342
-     *
343
-     * @see EE_message::get_column_value for related documentation on the necessity of this method.
344
-     * @param string $field_name  Must be the exact column name.
345
-     * @param mixed  $field_value The value to set.
346
-     * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
347
-     * @throws \EE_Error
348
-     */
349
-    public function set_field_or_extra_meta($field_name, $field_value)
350
-    {
351
-        if ($this->get_model()->has_field($field_name)) {
352
-            $this->set($field_name, $field_value);
353
-            return true;
354
-        } else {
355
-            //ensure this object is saved first so that extra meta can be properly related.
356
-            $this->save();
357
-            return $this->update_extra_meta($field_name, $field_value);
358
-        }
359
-    }
360
-
361
-
362
-
363
-    /**
364
-     * This retrieves the value of the db column set on this class or if that's not present
365
-     * it will attempt to retrieve from extra_meta if found.
366
-     * Example Usage:
367
-     * Via EE_Message child class:
368
-     * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
369
-     * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
370
-     * also have additional main fields specific to the messenger.  The system accommodates those extra
371
-     * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
372
-     * value for those extra fields dynamically via the EE_message object.
373
-     *
374
-     * @param  string $field_name expecting the fully qualified field name.
375
-     * @return mixed|null  value for the field if found.  null if not found.
376
-     * @throws \EE_Error
377
-     */
378
-    public function get_field_or_extra_meta($field_name)
379
-    {
380
-        if ($this->get_model()->has_field($field_name)) {
381
-            $column_value = $this->get($field_name);
382
-        } else {
383
-            //This isn't a column in the main table, let's see if it is in the extra meta.
384
-            $column_value = $this->get_extra_meta($field_name, true, null);
385
-        }
386
-        return $column_value;
387
-    }
388
-
389
-
390
-
391
-    /**
392
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
393
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
394
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
395
-     * available to all child classes that may be using the EE_Datetime_Field for a field data type.
396
-     *
397
-     * @access public
398
-     * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
399
-     * @return void
400
-     * @throws \EE_Error
401
-     */
402
-    public function set_timezone($timezone = '')
403
-    {
404
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
405
-        //make sure we clear all cached properties because they won't be relevant now
406
-        $this->_clear_cached_properties();
407
-        //make sure we update field settings and the date for all EE_Datetime_Fields
408
-        $model_fields = $this->get_model()->field_settings(false);
409
-        foreach ($model_fields as $field_name => $field_obj) {
410
-            if ($field_obj instanceof EE_Datetime_Field) {
411
-                $field_obj->set_timezone($this->_timezone);
412
-                if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
413
-                    $this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
414
-                }
415
-            }
416
-        }
417
-    }
418
-
419
-
420
-
421
-    /**
422
-     * This just returns whatever is set for the current timezone.
423
-     *
424
-     * @access public
425
-     * @return string timezone string
426
-     */
427
-    public function get_timezone()
428
-    {
429
-        return $this->_timezone;
430
-    }
431
-
432
-
433
-
434
-    /**
435
-     * This sets the internal date format to what is sent in to be used as the new default for the class
436
-     * internally instead of wp set date format options
437
-     *
438
-     * @since 4.6
439
-     * @param string $format should be a format recognizable by PHP date() functions.
440
-     */
441
-    public function set_date_format($format)
442
-    {
443
-        $this->_dt_frmt = $format;
444
-        //clear cached_properties because they won't be relevant now.
445
-        $this->_clear_cached_properties();
446
-    }
447
-
448
-
449
-
450
-    /**
451
-     * This sets the internal time format string to what is sent in to be used as the new default for the
452
-     * class internally instead of wp set time format options.
453
-     *
454
-     * @since 4.6
455
-     * @param string $format should be a format recognizable by PHP date() functions.
456
-     */
457
-    public function set_time_format($format)
458
-    {
459
-        $this->_tm_frmt = $format;
460
-        //clear cached_properties because they won't be relevant now.
461
-        $this->_clear_cached_properties();
462
-    }
463
-
464
-
465
-
466
-    /**
467
-     * This returns the current internal set format for the date and time formats.
468
-     *
469
-     * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
470
-     *                             where the first value is the date format and the second value is the time format.
471
-     * @return mixed string|array
472
-     */
473
-    public function get_format($full = true)
474
-    {
475
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
476
-    }
477
-
478
-
479
-
480
-    /**
481
-     * cache
482
-     * stores the passed model object on the current model object.
483
-     * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
484
-     *
485
-     * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
486
-     *                                       'Registration' associated with this model object
487
-     * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
488
-     *                                       that could be a payment or a registration)
489
-     * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
490
-     *                                       items which will be stored in an array on this object
491
-     * @throws EE_Error
492
-     * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
493
-     *                  related thing, no array)
494
-     */
495
-    public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
496
-    {
497
-        // its entirely possible that there IS no related object yet in which case there is nothing to cache.
498
-        if ( ! $object_to_cache instanceof EE_Base_Class) {
499
-            return false;
500
-        }
501
-        // also get "how" the object is related, or throw an error
502
-        if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
503
-            throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
504
-                $relationName, get_class($this)));
505
-        }
506
-        // how many things are related ?
507
-        if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
508
-            // if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
509
-            // so for these model objects just set it to be cached
510
-            $this->_model_relations[$relationName] = $object_to_cache;
511
-            $return = true;
512
-        } else {
513
-            // otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
514
-            // eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
515
-            if ( ! is_array($this->_model_relations[$relationName])) {
516
-                // if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
517
-                $this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
518
-                    ? array($this->_model_relations[$relationName]) : array();
519
-            }
520
-            // first check for a cache_id which is normally empty
521
-            if ( ! empty($cache_id)) {
522
-                // if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
523
-                $this->_model_relations[$relationName][$cache_id] = $object_to_cache;
524
-                $return = $cache_id;
525
-            } elseif ($object_to_cache->ID()) {
526
-                // OR the cached object originally came from the db, so let's just use it's PK for an ID
527
-                $this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
528
-                $return = $object_to_cache->ID();
529
-            } else {
530
-                // OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
531
-                $this->_model_relations[$relationName][] = $object_to_cache;
532
-                // move the internal pointer to the end of the array
533
-                end($this->_model_relations[$relationName]);
534
-                // and grab the key so that we can return it
535
-                $return = key($this->_model_relations[$relationName]);
536
-            }
537
-        }
538
-        return $return;
539
-    }
540
-
541
-
542
-
543
-    /**
544
-     * For adding an item to the cached_properties property.
545
-     *
546
-     * @access protected
547
-     * @param string      $fieldname the property item the corresponding value is for.
548
-     * @param mixed       $value     The value we are caching.
549
-     * @param string|null $cache_type
550
-     * @return void
551
-     * @throws \EE_Error
552
-     */
553
-    protected function _set_cached_property($fieldname, $value, $cache_type = null)
554
-    {
555
-        //first make sure this property exists
556
-        $this->get_model()->field_settings_for($fieldname);
557
-        $cache_type = empty($cache_type) ? 'standard' : $cache_type;
558
-        $this->_cached_properties[$fieldname][$cache_type] = $value;
559
-    }
560
-
561
-
562
-
563
-    /**
564
-     * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
565
-     * This also SETS the cache if we return the actual property!
566
-     *
567
-     * @param string $fieldname        the name of the property we're trying to retrieve
568
-     * @param bool   $pretty
569
-     * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
570
-     *                                 (in cases where the same property may be used for different outputs
571
-     *                                 - i.e. datetime, money etc.)
572
-     *                                 It can also accept certain pre-defined "schema" strings
573
-     *                                 to define how to output the property.
574
-     *                                 see the field's prepare_for_pretty_echoing for what strings can be used
575
-     * @return mixed                   whatever the value for the property is we're retrieving
576
-     * @throws \EE_Error
577
-     */
578
-    protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
579
-    {
580
-        //verify the field exists
581
-        $this->get_model()->field_settings_for($fieldname);
582
-        $cache_type = $pretty ? 'pretty' : 'standard';
583
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
584
-        if (isset($this->_cached_properties[$fieldname][$cache_type])) {
585
-            return $this->_cached_properties[$fieldname][$cache_type];
586
-        }
587
-        $field_obj = $this->get_model()->field_settings_for($fieldname);
588
-        if ($field_obj instanceof EE_Model_Field_Base) {
589
-            // If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
590
-            if ($field_obj instanceof EE_Datetime_Field) {
591
-                $this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
592
-            }
593
-            if ( ! isset($this->_fields[$fieldname])) {
594
-                $this->_fields[$fieldname] = null;
595
-            }
596
-            $value = $pretty
597
-                ? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
598
-                : $field_obj->prepare_for_get($this->_fields[$fieldname]);
599
-            $this->_set_cached_property($fieldname, $value, $cache_type);
600
-            return $value;
601
-        }
602
-        return null;
603
-    }
604
-
605
-
606
-
607
-    /**
608
-     * set timezone, formats, and output for EE_Datetime_Field objects
609
-     *
610
-     * @param \EE_Datetime_Field $datetime_field
611
-     * @param bool               $pretty
612
-     * @param null $date_or_time
613
-     * @return void
614
-     * @throws \EE_Error
615
-     */
616
-    protected function _prepare_datetime_field(
617
-        EE_Datetime_Field $datetime_field,
618
-        $pretty = false,
619
-        $date_or_time = null
620
-    ) {
621
-        $datetime_field->set_timezone($this->_timezone);
622
-        $datetime_field->set_date_format($this->_dt_frmt, $pretty);
623
-        $datetime_field->set_time_format($this->_tm_frmt, $pretty);
624
-        //set the output returned
625
-        switch ($date_or_time) {
626
-            case 'D' :
627
-                $datetime_field->set_date_time_output('date');
628
-                break;
629
-            case 'T' :
630
-                $datetime_field->set_date_time_output('time');
631
-                break;
632
-            default :
633
-                $datetime_field->set_date_time_output();
634
-        }
635
-    }
636
-
637
-
638
-
639
-    /**
640
-     * This just takes care of clearing out the cached_properties
641
-     *
642
-     * @return void
643
-     */
644
-    protected function _clear_cached_properties()
645
-    {
646
-        $this->_cached_properties = array();
647
-    }
648
-
649
-
650
-
651
-    /**
652
-     * This just clears out ONE property if it exists in the cache
653
-     *
654
-     * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
655
-     * @return void
656
-     */
657
-    protected function _clear_cached_property($property_name)
658
-    {
659
-        if (isset($this->_cached_properties[$property_name])) {
660
-            unset($this->_cached_properties[$property_name]);
661
-        }
662
-    }
663
-
664
-
665
-
666
-    /**
667
-     * Ensures that this related thing is a model object.
668
-     *
669
-     * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
670
-     * @param string $model_name   name of the related thing, eg 'Attendee',
671
-     * @return EE_Base_Class
672
-     * @throws \EE_Error
673
-     */
674
-    protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
675
-    {
676
-        $other_model_instance = self::_get_model_instance_with_name(
677
-            self::_get_model_classname($model_name),
678
-            $this->_timezone
679
-        );
680
-        return $other_model_instance->ensure_is_obj($object_or_id);
681
-    }
682
-
683
-
684
-
685
-    /**
686
-     * Forgets the cached model of the given relation Name. So the next time we request it,
687
-     * we will fetch it again from the database. (Handy if you know it's changed somehow).
688
-     * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
689
-     * then only remove that one object from our cached array. Otherwise, clear the entire list
690
-     *
691
-     * @param string $relationName                         one of the keys in the _model_relations array on the model.
692
-     *                                                     Eg 'Registration'
693
-     * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
694
-     *                                                     if you intend to use $clear_all = TRUE, or the relation only
695
-     *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
696
-     * @param bool   $clear_all                            This flags clearing the entire cache relation property if
697
-     *                                                     this is HasMany or HABTM.
698
-     * @throws EE_Error
699
-     * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
700
-     *                       relation from all
701
-     */
702
-    public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
703
-    {
704
-        $relationship_to_model = $this->get_model()->related_settings_for($relationName);
705
-        $index_in_cache = '';
706
-        if ( ! $relationship_to_model) {
707
-            throw new EE_Error(
708
-                sprintf(
709
-                    __("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
710
-                    $relationName,
711
-                    get_class($this)
712
-                )
713
-            );
714
-        }
715
-        if ($clear_all) {
716
-            $obj_removed = true;
717
-            $this->_model_relations[$relationName] = null;
718
-        } elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
719
-            $obj_removed = $this->_model_relations[$relationName];
720
-            $this->_model_relations[$relationName] = null;
721
-        } else {
722
-            if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
723
-                && $object_to_remove_or_index_into_array->ID()
724
-            ) {
725
-                $index_in_cache = $object_to_remove_or_index_into_array->ID();
726
-                if (is_array($this->_model_relations[$relationName])
727
-                    && ! isset($this->_model_relations[$relationName][$index_in_cache])
728
-                ) {
729
-                    $index_found_at = null;
730
-                    //find this object in the array even though it has a different key
731
-                    foreach ($this->_model_relations[$relationName] as $index => $obj) {
732
-                        if (
733
-                            $obj instanceof EE_Base_Class
734
-                            && (
735
-                                $obj == $object_to_remove_or_index_into_array
736
-                                || $obj->ID() === $object_to_remove_or_index_into_array->ID()
737
-                            )
738
-                        ) {
739
-                            $index_found_at = $index;
740
-                            break;
741
-                        }
742
-                    }
743
-                    if ($index_found_at) {
744
-                        $index_in_cache = $index_found_at;
745
-                    } else {
746
-                        //it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
747
-                        //if it wasn't in it to begin with. So we're done
748
-                        return $object_to_remove_or_index_into_array;
749
-                    }
750
-                }
751
-            } elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
752
-                //so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
753
-                foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
754
-                    if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
755
-                        $index_in_cache = $index;
756
-                    }
757
-                }
758
-            } else {
759
-                $index_in_cache = $object_to_remove_or_index_into_array;
760
-            }
761
-            //supposedly we've found it. But it could just be that the client code
762
-            //provided a bad index/object
763
-            if (
764
-            isset(
765
-                $this->_model_relations[$relationName],
766
-                $this->_model_relations[$relationName][$index_in_cache]
767
-            )
768
-            ) {
769
-                $obj_removed = $this->_model_relations[$relationName][$index_in_cache];
770
-                unset($this->_model_relations[$relationName][$index_in_cache]);
771
-            } else {
772
-                //that thing was never cached anyways.
773
-                $obj_removed = null;
774
-            }
775
-        }
776
-        return $obj_removed;
777
-    }
778
-
779
-
780
-
781
-    /**
782
-     * update_cache_after_object_save
783
-     * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
784
-     * obtained after being saved to the db
785
-     *
786
-     * @param string         $relationName       - the type of object that is cached
787
-     * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
788
-     * @param string         $current_cache_id   - the ID that was used when originally caching the object
789
-     * @return boolean TRUE on success, FALSE on fail
790
-     * @throws \EE_Error
791
-     */
792
-    public function update_cache_after_object_save(
793
-        $relationName,
794
-        EE_Base_Class $newly_saved_object,
795
-        $current_cache_id = ''
796
-    ) {
797
-        // verify that incoming object is of the correct type
798
-        $obj_class = 'EE_' . $relationName;
799
-        if ($newly_saved_object instanceof $obj_class) {
800
-            /* @type EE_Base_Class $newly_saved_object */
801
-            // now get the type of relation
802
-            $relationship_to_model = $this->get_model()->related_settings_for($relationName);
803
-            // if this is a 1:1 relationship
804
-            if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
805
-                // then just replace the cached object with the newly saved object
806
-                $this->_model_relations[$relationName] = $newly_saved_object;
807
-                return true;
808
-                // or if it's some kind of sordid feral polyamorous relationship...
809
-            } elseif (is_array($this->_model_relations[$relationName])
810
-                      && isset($this->_model_relations[$relationName][$current_cache_id])
811
-            ) {
812
-                // then remove the current cached item
813
-                unset($this->_model_relations[$relationName][$current_cache_id]);
814
-                // and cache the newly saved object using it's new ID
815
-                $this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
816
-                return true;
817
-            }
818
-        }
819
-        return false;
820
-    }
821
-
822
-
823
-
824
-    /**
825
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
826
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
827
-     *
828
-     * @param string $relationName
829
-     * @return EE_Base_Class
830
-     */
831
-    public function get_one_from_cache($relationName)
832
-    {
833
-        $cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
834
-            : null;
835
-        if (is_array($cached_array_or_object)) {
836
-            return array_shift($cached_array_or_object);
837
-        } else {
838
-            return $cached_array_or_object;
839
-        }
840
-    }
841
-
842
-
843
-
844
-    /**
845
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
846
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
847
-     *
848
-     * @param string $relationName
849
-     * @throws \EE_Error
850
-     * @return EE_Base_Class[] NOT necessarily indexed by primary keys
851
-     */
852
-    public function get_all_from_cache($relationName)
853
-    {
854
-        $objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
855
-        // if the result is not an array, but exists, make it an array
856
-        $objects = is_array($objects) ? $objects : array($objects);
857
-        //bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
858
-        //basically, if this model object was stored in the session, and these cached model objects
859
-        //already have IDs, let's make sure they're in their model's entity mapper
860
-        //otherwise we will have duplicates next time we call
861
-        // EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
862
-        $model = EE_Registry::instance()->load_model($relationName);
863
-        foreach ($objects as $model_object) {
864
-            if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
865
-                //ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
866
-                if ($model_object->ID()) {
867
-                    $model->add_to_entity_map($model_object);
868
-                }
869
-            } else {
870
-                throw new EE_Error(
871
-                    sprintf(
872
-                        __(
873
-                            'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
874
-                            'event_espresso'
875
-                        ),
876
-                        $relationName,
877
-                        gettype($model_object)
878
-                    )
879
-                );
880
-            }
881
-        }
882
-        return $objects;
883
-    }
884
-
885
-
886
-
887
-    /**
888
-     * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
889
-     * matching the given query conditions.
890
-     *
891
-     * @param null  $field_to_order_by  What field is being used as the reference point.
892
-     * @param int   $limit              How many objects to return.
893
-     * @param array $query_params       Any additional conditions on the query.
894
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
895
-     *                                  you can indicate just the columns you want returned
896
-     * @return array|EE_Base_Class[]
897
-     * @throws \EE_Error
898
-     */
899
-    public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
900
-    {
901
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
902
-            ? $this->get_model()->get_primary_key_field()->get_name()
903
-            : $field_to_order_by;
904
-        $current_value = ! empty($field) ? $this->get($field) : null;
905
-        if (empty($field) || empty($current_value)) {
906
-            return array();
907
-        }
908
-        return $this->get_model()->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
909
-    }
910
-
911
-
912
-
913
-    /**
914
-     * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
915
-     * matching the given query conditions.
916
-     *
917
-     * @param null  $field_to_order_by  What field is being used as the reference point.
918
-     * @param int   $limit              How many objects to return.
919
-     * @param array $query_params       Any additional conditions on the query.
920
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
921
-     *                                  you can indicate just the columns you want returned
922
-     * @return array|EE_Base_Class[]
923
-     * @throws \EE_Error
924
-     */
925
-    public function previous_x(
926
-        $field_to_order_by = null,
927
-        $limit = 1,
928
-        $query_params = array(),
929
-        $columns_to_select = null
930
-    ) {
931
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
932
-            ? $this->get_model()->get_primary_key_field()->get_name()
933
-            : $field_to_order_by;
934
-        $current_value = ! empty($field) ? $this->get($field) : null;
935
-        if (empty($field) || empty($current_value)) {
936
-            return array();
937
-        }
938
-        return $this->get_model()->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
939
-    }
940
-
941
-
942
-
943
-    /**
944
-     * Returns the next EE_Base_Class object in sequence from this object as found in the database
945
-     * matching the given query conditions.
946
-     *
947
-     * @param null  $field_to_order_by  What field is being used as the reference point.
948
-     * @param array $query_params       Any additional conditions on the query.
949
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
950
-     *                                  you can indicate just the columns you want returned
951
-     * @return array|EE_Base_Class
952
-     * @throws \EE_Error
953
-     */
954
-    public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
955
-    {
956
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
957
-            ? $this->get_model()->get_primary_key_field()->get_name()
958
-            : $field_to_order_by;
959
-        $current_value = ! empty($field) ? $this->get($field) : null;
960
-        if (empty($field) || empty($current_value)) {
961
-            return array();
962
-        }
963
-        return $this->get_model()->next($current_value, $field, $query_params, $columns_to_select);
964
-    }
965
-
966
-
967
-
968
-    /**
969
-     * Returns the previous EE_Base_Class object in sequence from this object as found in the database
970
-     * matching the given query conditions.
971
-     *
972
-     * @param null  $field_to_order_by  What field is being used as the reference point.
973
-     * @param array $query_params       Any additional conditions on the query.
974
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
975
-     *                                  you can indicate just the column you want returned
976
-     * @return array|EE_Base_Class
977
-     * @throws \EE_Error
978
-     */
979
-    public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
980
-    {
981
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
982
-            ? $this->get_model()->get_primary_key_field()->get_name()
983
-            : $field_to_order_by;
984
-        $current_value = ! empty($field) ? $this->get($field) : null;
985
-        if (empty($field) || empty($current_value)) {
986
-            return array();
987
-        }
988
-        return $this->get_model()->previous($current_value, $field, $query_params, $columns_to_select);
989
-    }
990
-
991
-
992
-
993
-    /**
994
-     * Overrides parent because parent expects old models.
995
-     * This also doesn't do any validation, and won't work for serialized arrays
996
-     *
997
-     * @param string $field_name
998
-     * @param mixed  $field_value_from_db
999
-     * @throws \EE_Error
1000
-     */
1001
-    public function set_from_db($field_name, $field_value_from_db)
1002
-    {
1003
-        $field_obj = $this->get_model()->field_settings_for($field_name);
1004
-        if ($field_obj instanceof EE_Model_Field_Base) {
1005
-            //you would think the DB has no NULLs for non-null label fields right? wrong!
1006
-            //eg, a CPT model object could have an entry in the posts table, but no
1007
-            //entry in the meta table. Meaning that all its columns in the meta table
1008
-            //are null! yikes! so when we find one like that, use defaults for its meta columns
1009
-            if ($field_value_from_db === null) {
1010
-                if ($field_obj->is_nullable()) {
1011
-                    //if the field allows nulls, then let it be null
1012
-                    $field_value = null;
1013
-                } else {
1014
-                    $field_value = $field_obj->get_default_value();
1015
-                }
1016
-            } else {
1017
-                $field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1018
-            }
1019
-            $this->_fields[$field_name] = $field_value;
1020
-            $this->_clear_cached_property($field_name);
1021
-        }
1022
-    }
1023
-
1024
-
1025
-
1026
-    /**
1027
-     * verifies that the specified field is of the correct type
1028
-     *
1029
-     * @param string $field_name
1030
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1031
-     *                                (in cases where the same property may be used for different outputs
1032
-     *                                - i.e. datetime, money etc.)
1033
-     * @return mixed
1034
-     * @throws \EE_Error
1035
-     */
1036
-    public function get($field_name, $extra_cache_ref = null)
1037
-    {
1038
-        return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1039
-    }
1040
-
1041
-
1042
-
1043
-    /**
1044
-     * This method simply returns the RAW unprocessed value for the given property in this class
1045
-     *
1046
-     * @param  string $field_name A valid fieldname
1047
-     * @return mixed              Whatever the raw value stored on the property is.
1048
-     * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1049
-     */
1050
-    public function get_raw($field_name)
1051
-    {
1052
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1053
-        return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1054
-            ? $this->_fields[$field_name]->format('U')
1055
-            : $this->_fields[$field_name];
1056
-    }
1057
-
1058
-
1059
-
1060
-    /**
1061
-     * This is used to return the internal DateTime object used for a field that is a
1062
-     * EE_Datetime_Field.
1063
-     *
1064
-     * @param string $field_name               The field name retrieving the DateTime object.
1065
-     * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1066
-     * @throws \EE_Error
1067
-     *                                         an error is set and false returned.  If the field IS an
1068
-     *                                         EE_Datetime_Field and but the field value is null, then
1069
-     *                                         just null is returned (because that indicates that likely
1070
-     *                                         this field is nullable).
1071
-     */
1072
-    public function get_DateTime_object($field_name)
1073
-    {
1074
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1075
-        if ( ! $field_settings instanceof EE_Datetime_Field) {
1076
-            EE_Error::add_error(
1077
-                sprintf(
1078
-                    __(
1079
-                        'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1080
-                        'event_espresso'
1081
-                    ),
1082
-                    $field_name
1083
-                ),
1084
-                __FILE__,
1085
-                __FUNCTION__,
1086
-                __LINE__
1087
-            );
1088
-            return false;
1089
-        }
1090
-        return $this->_fields[$field_name];
1091
-    }
1092
-
1093
-
1094
-
1095
-    /**
1096
-     * To be used in template to immediately echo out the value, and format it for output.
1097
-     * Eg, should call stripslashes and whatnot before echoing
1098
-     *
1099
-     * @param string $field_name      the name of the field as it appears in the DB
1100
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1101
-     *                                (in cases where the same property may be used for different outputs
1102
-     *                                - i.e. datetime, money etc.)
1103
-     * @return void
1104
-     * @throws \EE_Error
1105
-     */
1106
-    public function e($field_name, $extra_cache_ref = null)
1107
-    {
1108
-        echo $this->get_pretty($field_name, $extra_cache_ref);
1109
-    }
1110
-
1111
-
1112
-
1113
-    /**
1114
-     * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1115
-     * can be easily used as the value of form input.
1116
-     *
1117
-     * @param string $field_name
1118
-     * @return void
1119
-     * @throws \EE_Error
1120
-     */
1121
-    public function f($field_name)
1122
-    {
1123
-        $this->e($field_name, 'form_input');
1124
-    }
1125
-
1126
-
1127
-
1128
-    /**
1129
-     * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1130
-     * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1131
-     * to see what options are available.
1132
-     * @param string $field_name
1133
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1134
-     *                                (in cases where the same property may be used for different outputs
1135
-     *                                - i.e. datetime, money etc.)
1136
-     * @return mixed
1137
-     * @throws \EE_Error
1138
-     */
1139
-    public function get_pretty($field_name, $extra_cache_ref = null)
1140
-    {
1141
-        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1142
-    }
1143
-
1144
-
1145
-
1146
-    /**
1147
-     * This simply returns the datetime for the given field name
1148
-     * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1149
-     * (and the equivalent e_date, e_time, e_datetime).
1150
-     *
1151
-     * @access   protected
1152
-     * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1153
-     * @param string   $dt_frmt      valid datetime format used for date
1154
-     *                               (if '' then we just use the default on the field,
1155
-     *                               if NULL we use the last-used format)
1156
-     * @param string   $tm_frmt      Same as above except this is for time format
1157
-     * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1158
-     * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1159
-     * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1160
-     *                               if field is not a valid dtt field, or void if echoing
1161
-     * @throws \EE_Error
1162
-     */
1163
-    protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1164
-    {
1165
-        // clear cached property
1166
-        $this->_clear_cached_property($field_name);
1167
-        //reset format properties because they are used in get()
1168
-        $this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1169
-        $this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1170
-        if ($echo) {
1171
-            $this->e($field_name, $date_or_time);
1172
-            return '';
1173
-        }
1174
-        return $this->get($field_name, $date_or_time);
1175
-    }
1176
-
1177
-
1178
-
1179
-    /**
1180
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1181
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1182
-     * other echoes the pretty value for dtt)
1183
-     *
1184
-     * @param  string $field_name name of model object datetime field holding the value
1185
-     * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1186
-     * @return string            datetime value formatted
1187
-     * @throws \EE_Error
1188
-     */
1189
-    public function get_date($field_name, $format = '')
1190
-    {
1191
-        return $this->_get_datetime($field_name, $format, null, 'D');
1192
-    }
1193
-
1194
-
1195
-
1196
-    /**
1197
-     * @param      $field_name
1198
-     * @param string $format
1199
-     * @throws \EE_Error
1200
-     */
1201
-    public function e_date($field_name, $format = '')
1202
-    {
1203
-        $this->_get_datetime($field_name, $format, null, 'D', true);
1204
-    }
1205
-
1206
-
1207
-
1208
-    /**
1209
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1210
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1211
-     * other echoes the pretty value for dtt)
1212
-     *
1213
-     * @param  string $field_name name of model object datetime field holding the value
1214
-     * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1215
-     * @return string             datetime value formatted
1216
-     * @throws \EE_Error
1217
-     */
1218
-    public function get_time($field_name, $format = '')
1219
-    {
1220
-        return $this->_get_datetime($field_name, null, $format, 'T');
1221
-    }
1222
-
1223
-
1224
-
1225
-    /**
1226
-     * @param      $field_name
1227
-     * @param string $format
1228
-     * @throws \EE_Error
1229
-     */
1230
-    public function e_time($field_name, $format = '')
1231
-    {
1232
-        $this->_get_datetime($field_name, null, $format, 'T', true);
1233
-    }
1234
-
1235
-
1236
-
1237
-    /**
1238
-     * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1239
-     * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1240
-     * other echoes the pretty value for dtt)
1241
-     *
1242
-     * @param  string $field_name name of model object datetime field holding the value
1243
-     * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1244
-     * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1245
-     * @return string             datetime value formatted
1246
-     * @throws \EE_Error
1247
-     */
1248
-    public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1249
-    {
1250
-        return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1251
-    }
1252
-
1253
-
1254
-
1255
-    /**
1256
-     * @param string $field_name
1257
-     * @param string $dt_frmt
1258
-     * @param string $tm_frmt
1259
-     * @throws \EE_Error
1260
-     */
1261
-    public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1262
-    {
1263
-        $this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1264
-    }
1265
-
1266
-
1267
-
1268
-    /**
1269
-     * Get the i8ln value for a date using the WordPress @see date_i18n function.
1270
-     *
1271
-     * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1272
-     * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1273
-     *                           on the object will be used.
1274
-     * @return string Date and time string in set locale or false if no field exists for the given
1275
-     * @throws \EE_Error
1276
-     *                           field name.
1277
-     */
1278
-    public function get_i18n_datetime($field_name, $format = '')
1279
-    {
1280
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1281
-        return date_i18n(
1282
-            $format,
1283
-            EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1284
-        );
1285
-    }
1286
-
1287
-
1288
-
1289
-    /**
1290
-     * This method validates whether the given field name is a valid field on the model object as well as it is of a
1291
-     * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1292
-     * thrown.
1293
-     *
1294
-     * @param  string $field_name The field name being checked
1295
-     * @throws EE_Error
1296
-     * @return EE_Datetime_Field
1297
-     */
1298
-    protected function _get_dtt_field_settings($field_name)
1299
-    {
1300
-        $field = $this->get_model()->field_settings_for($field_name);
1301
-        //check if field is dtt
1302
-        if ($field instanceof EE_Datetime_Field) {
1303
-            return $field;
1304
-        } else {
1305
-            throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1306
-                'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1307
-        }
1308
-    }
1309
-
1310
-
1311
-
1312
-
1313
-    /**
1314
-     * NOTE ABOUT BELOW:
1315
-     * These convenience date and time setters are for setting date and time independently.  In other words you might
1316
-     * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1317
-     * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1318
-     * method and make sure you send the entire datetime value for setting.
1319
-     */
1320
-    /**
1321
-     * sets the time on a datetime property
1322
-     *
1323
-     * @access protected
1324
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1325
-     * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1326
-     * @throws \EE_Error
1327
-     */
1328
-    protected function _set_time_for($time, $fieldname)
1329
-    {
1330
-        $this->_set_date_time('T', $time, $fieldname);
1331
-    }
1332
-
1333
-
1334
-
1335
-    /**
1336
-     * sets the date on a datetime property
1337
-     *
1338
-     * @access protected
1339
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1340
-     * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1341
-     * @throws \EE_Error
1342
-     */
1343
-    protected function _set_date_for($date, $fieldname)
1344
-    {
1345
-        $this->_set_date_time('D', $date, $fieldname);
1346
-    }
1347
-
1348
-
1349
-
1350
-    /**
1351
-     * This takes care of setting a date or time independently on a given model object property. This method also
1352
-     * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1353
-     *
1354
-     * @access protected
1355
-     * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1356
-     * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1357
-     * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1358
-     *                                        EE_Datetime_Field property)
1359
-     * @throws \EE_Error
1360
-     */
1361
-    protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1362
-    {
1363
-        $field = $this->_get_dtt_field_settings($fieldname);
1364
-        $field->set_timezone($this->_timezone);
1365
-        $field->set_date_format($this->_dt_frmt);
1366
-        $field->set_time_format($this->_tm_frmt);
1367
-        switch ($what) {
1368
-            case 'T' :
1369
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1370
-                    $datetime_value,
1371
-                    $this->_fields[$fieldname]
1372
-                );
1373
-                break;
1374
-            case 'D' :
1375
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1376
-                    $datetime_value,
1377
-                    $this->_fields[$fieldname]
1378
-                );
1379
-                break;
1380
-            case 'B' :
1381
-                $this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1382
-                break;
1383
-        }
1384
-        $this->_clear_cached_property($fieldname);
1385
-    }
1386
-
1387
-
1388
-
1389
-    /**
1390
-     * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1391
-     * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1392
-     * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1393
-     * that could lead to some unexpected results!
1394
-     *
1395
-     * @access public
1396
-     * @param string               $field_name This is the name of the field on the object that contains the date/time
1397
-     *                                         value being returned.
1398
-     * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1399
-     * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1400
-     * @param string               $prepend    You can include something to prepend on the timestamp
1401
-     * @param string               $append     You can include something to append on the timestamp
1402
-     * @throws EE_Error
1403
-     * @return string timestamp
1404
-     */
1405
-    public function display_in_my_timezone(
1406
-        $field_name,
1407
-        $callback = 'get_datetime',
1408
-        $args = null,
1409
-        $prepend = '',
1410
-        $append = ''
1411
-    ) {
1412
-        $timezone = EEH_DTT_Helper::get_timezone();
1413
-        if ($timezone === $this->_timezone) {
1414
-            return '';
1415
-        }
1416
-        $original_timezone = $this->_timezone;
1417
-        $this->set_timezone($timezone);
1418
-        $fn = (array)$field_name;
1419
-        $args = array_merge($fn, (array)$args);
1420
-        if ( ! method_exists($this, $callback)) {
1421
-            throw new EE_Error(
1422
-                sprintf(
1423
-                    __(
1424
-                        'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1425
-                        'event_espresso'
1426
-                    ),
1427
-                    $callback
1428
-                )
1429
-            );
1430
-        }
1431
-        $args = (array)$args;
1432
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1433
-        $this->set_timezone($original_timezone);
1434
-        return $return;
1435
-    }
1436
-
1437
-
1438
-
1439
-    /**
1440
-     * Deletes this model object.
1441
-     * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1442
-     * override
1443
-     * `EE_Base_Class::_delete` NOT this class.
1444
-     *
1445
-     * @return boolean | int
1446
-     * @throws \EE_Error
1447
-     */
1448
-    public function delete()
1449
-    {
1450
-        /**
1451
-         * Called just before the `EE_Base_Class::_delete` method call.
1452
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1453
-         * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1454
-         * soft deletes (trash) the object and does not permanently delete it.
1455
-         *
1456
-         * @param EE_Base_Class $model_object about to be 'deleted'
1457
-         */
1458
-        do_action('AHEE__EE_Base_Class__delete__before', $this);
1459
-        $result = $this->_delete();
1460
-        /**
1461
-         * Called just after the `EE_Base_Class::_delete` method call.
1462
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1463
-         * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1464
-         * soft deletes (trash) the object and does not permanently delete it.
1465
-         *
1466
-         * @param EE_Base_Class $model_object that was just 'deleted'
1467
-         * @param boolean       $result
1468
-         */
1469
-        do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1470
-        return $result;
1471
-    }
1472
-
1473
-
1474
-
1475
-    /**
1476
-     * Calls the specific delete method for the instantiated class.
1477
-     * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1478
-     * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1479
-     * `EE_Base_Class::delete`
1480
-     *
1481
-     * @return bool|int
1482
-     * @throws \EE_Error
1483
-     */
1484
-    protected function _delete()
1485
-    {
1486
-        return $this->delete_permanently();
1487
-    }
1488
-
1489
-
1490
-
1491
-    /**
1492
-     * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1493
-     * error)
1494
-     *
1495
-     * @return bool | int
1496
-     * @throws \EE_Error
1497
-     */
1498
-    public function delete_permanently()
1499
-    {
1500
-        /**
1501
-         * Called just before HARD deleting a model object
1502
-         *
1503
-         * @param EE_Base_Class $model_object about to be 'deleted'
1504
-         */
1505
-        do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1506
-        $model = $this->get_model();
1507
-        $result = $model->delete_permanently_by_ID($this->ID());
1508
-        $this->refresh_cache_of_related_objects();
1509
-        /**
1510
-         * Called just after HARD deleting a model object
1511
-         *
1512
-         * @param EE_Base_Class $model_object that was just 'deleted'
1513
-         * @param boolean       $result
1514
-         */
1515
-        do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1516
-        return $result;
1517
-    }
1518
-
1519
-
1520
-
1521
-    /**
1522
-     * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1523
-     * related model objects
1524
-     *
1525
-     * @throws \EE_Error
1526
-     */
1527
-    public function refresh_cache_of_related_objects()
1528
-    {
1529
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1530
-            if ( ! empty($this->_model_relations[$relation_name])) {
1531
-                $related_objects = $this->_model_relations[$relation_name];
1532
-                if ($relation_obj instanceof EE_Belongs_To_Relation) {
1533
-                    //this relation only stores a single model object, not an array
1534
-                    //but let's make it consistent
1535
-                    $related_objects = array($related_objects);
1536
-                }
1537
-                foreach ($related_objects as $related_object) {
1538
-                    //only refresh their cache if they're in memory
1539
-                    if ($related_object instanceof EE_Base_Class) {
1540
-                        $related_object->clear_cache($this->get_model()->get_this_model_name(), $this);
1541
-                    }
1542
-                }
1543
-            }
1544
-        }
1545
-    }
1546
-
1547
-
1548
-
1549
-    /**
1550
-     *        Saves this object to the database. An array may be supplied to set some values on this
1551
-     * object just before saving.
1552
-     *
1553
-     * @access public
1554
-     * @param array $set_cols_n_values keys are field names, values are their new values,
1555
-     *                                 if provided during the save() method (often client code will change the fields'
1556
-     *                                 values before calling save)
1557
-     * @throws \EE_Error
1558
-     * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1559
-     *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1560
-     */
1561
-    public function save($set_cols_n_values = array())
1562
-    {
1563
-        // no changes ? then don't do anything
1564
-        if ( ! $this->_has_changes && empty($set_cols_n_values) && $this->ID()) {
1565
-            return 0;
1566
-        }
1567
-        /**
1568
-         * Filters the fields we're about to save on the model object
1569
-         *
1570
-         * @param array         $set_cols_n_values
1571
-         * @param EE_Base_Class $model_object
1572
-         */
1573
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1574
-            $this);
1575
-        //set attributes as provided in $set_cols_n_values
1576
-        foreach ($set_cols_n_values as $column => $value) {
1577
-            $this->set($column, $value);
1578
-        }
1579
-        /**
1580
-         * Saving a model object.
1581
-         * Before we perform a save, this action is fired.
1582
-         *
1583
-         * @param EE_Base_Class $model_object the model object about to be saved.
1584
-         */
1585
-        do_action('AHEE__EE_Base_Class__save__begin', $this);
1586
-        if ( ! $this->allow_persist()) {
1587
-            return 0;
1588
-        }
1589
-        //now get current attribute values
1590
-        $save_cols_n_values = $this->_fields;
1591
-        //if the object already has an ID, update it. Otherwise, insert it
1592
-        //also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1593
-        $old_assumption_concerning_value_preparation = $this->get_model()
1594
-                                                            ->get_assumption_concerning_values_already_prepared_by_model_object();
1595
-        $this->get_model()->assume_values_already_prepared_by_model_object(true);
1596
-        //does this model have an autoincrement PK?
1597
-        if ($this->get_model()->has_primary_key_field()) {
1598
-            if ($this->get_model()->get_primary_key_field()->is_auto_increment()) {
1599
-                //ok check if it's set, if so: update; if not, insert
1600
-                if ( ! empty($save_cols_n_values[self::_get_primary_key_name(get_class($this))])) {
1601
-                    $results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1602
-                } else {
1603
-                    unset($save_cols_n_values[self::_get_primary_key_name(get_class($this))]);
1604
-                    $results = $this->get_model()->insert($save_cols_n_values);
1605
-                    if ($results) {
1606
-                        //if successful, set the primary key
1607
-                        //but don't use the normal SET method, because it will check if
1608
-                        //an item with the same ID exists in the mapper & db, then
1609
-                        //will find it in the db (because we just added it) and THAT object
1610
-                        //will get added to the mapper before we can add this one!
1611
-                        //but if we just avoid using the SET method, all that headache can be avoided
1612
-                        $pk_field_name = self::_get_primary_key_name(get_class($this));
1613
-                        $this->_fields[$pk_field_name] = $results;
1614
-                        $this->_clear_cached_property($pk_field_name);
1615
-                        $this->get_model()->add_to_entity_map($this);
1616
-                        $this->_update_cached_related_model_objs_fks();
1617
-                    }
1618
-                }
1619
-            } else {//PK is NOT auto-increment
1620
-                //so check if one like it already exists in the db
1621
-                if ($this->get_model()->exists_by_ID($this->ID())) {
1622
-                    if (WP_DEBUG && ! $this->in_entity_map()) {
1623
-                        throw new EE_Error(
1624
-                            sprintf(
1625
-                                __('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1626
-                                    'event_espresso'),
1627
-                                get_class($this),
1628
-                                get_class($this->get_model()) . '::instance()->add_to_entity_map()',
1629
-                                get_class($this->get_model()) . '::instance()->get_one_by_ID()',
1630
-                                '<br />'
1631
-                            )
1632
-                        );
1633
-                    }
1634
-                    $results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1635
-                } else {
1636
-                    $results = $this->get_model()->insert($save_cols_n_values);
1637
-                    $this->_update_cached_related_model_objs_fks();
1638
-                }
1639
-            }
1640
-        } else {//there is NO primary key
1641
-            $already_in_db = false;
1642
-            foreach ($this->get_model()->unique_indexes() as $index) {
1643
-                $uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1644
-                if ($this->get_model()->exists(array($uniqueness_where_params))) {
1645
-                    $already_in_db = true;
1646
-                }
1647
-            }
1648
-            if ($already_in_db) {
1649
-                $combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1650
-                    $this->get_model()->get_combined_primary_key_fields());
1651
-                $results = $this->get_model()->update($save_cols_n_values, $combined_pk_fields_n_values);
1652
-            } else {
1653
-                $results = $this->get_model()->insert($save_cols_n_values);
1654
-            }
1655
-        }
1656
-        //restore the old assumption about values being prepared by the model object
1657
-        $this->get_model()
1658
-             ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1659
-        /**
1660
-         * After saving the model object this action is called
1661
-         *
1662
-         * @param EE_Base_Class $model_object which was just saved
1663
-         * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1664
-         *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1665
-         */
1666
-        do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1667
-        return $results;
1668
-    }
1669
-
1670
-
1671
-
1672
-    /**
1673
-     * Updates the foreign key on related models objects pointing to this to have this model object's ID
1674
-     * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1675
-     * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1676
-     * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1677
-     * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1678
-     * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1679
-     * or not they exist in the DB (if they do, their DB records will be automatically updated)
1680
-     *
1681
-     * @return void
1682
-     * @throws \EE_Error
1683
-     */
1684
-    protected function _update_cached_related_model_objs_fks()
1685
-    {
1686
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1687
-            if ($relation_obj instanceof EE_Has_Many_Relation) {
1688
-                foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1689
-                    $fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1690
-                        $this->get_model()->get_this_model_name()
1691
-                    );
1692
-                    $related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1693
-                    if ($related_model_obj_in_cache->ID()) {
1694
-                        $related_model_obj_in_cache->save();
1695
-                    }
1696
-                }
1697
-            }
1698
-        }
1699
-    }
1700
-
1701
-
1702
-
1703
-    /**
1704
-     * Saves this model object and its NEW cached relations to the database.
1705
-     * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1706
-     * In order for that to work, we would need to mark model objects as dirty/clean...
1707
-     * because otherwise, there's a potential for infinite looping of saving
1708
-     * Saves the cached related model objects, and ensures the relation between them
1709
-     * and this object and properly setup
1710
-     *
1711
-     * @return int ID of new model object on save; 0 on failure+
1712
-     * @throws \EE_Error
1713
-     */
1714
-    public function save_new_cached_related_model_objs()
1715
-    {
1716
-        //make sure this has been saved
1717
-        if ( ! $this->ID()) {
1718
-            $id = $this->save();
1719
-        } else {
1720
-            $id = $this->ID();
1721
-        }
1722
-        //now save all the NEW cached model objects  (ie they don't exist in the DB)
1723
-        foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1724
-            if ($this->_model_relations[$relationName]) {
1725
-                //is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1726
-                //or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1727
-                if ($relationObj instanceof EE_Belongs_To_Relation) {
1728
-                    //add a relation to that relation type (which saves the appropriate thing in the process)
1729
-                    //but ONLY if it DOES NOT exist in the DB
1730
-                    /* @var $related_model_obj EE_Base_Class */
1731
-                    $related_model_obj = $this->_model_relations[$relationName];
1732
-                    //					if( ! $related_model_obj->ID()){
1733
-                    $this->_add_relation_to($related_model_obj, $relationName);
1734
-                    $related_model_obj->save_new_cached_related_model_objs();
1735
-                    //					}
1736
-                } else {
1737
-                    foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1738
-                        //add a relation to that relation type (which saves the appropriate thing in the process)
1739
-                        //but ONLY if it DOES NOT exist in the DB
1740
-                        //						if( ! $related_model_obj->ID()){
1741
-                        $this->_add_relation_to($related_model_obj, $relationName);
1742
-                        $related_model_obj->save_new_cached_related_model_objs();
1743
-                        //						}
1744
-                    }
1745
-                }
1746
-            }
1747
-        }
1748
-        return $id;
1749
-    }
1750
-
1751
-
1752
-
1753
-    /**
1754
-     * for getting a model while instantiated.
1755
-     *
1756
-     * @return \EEM_Base | \EEM_CPT_Base
1757
-     */
1758
-    public function get_model()
1759
-    {
1760
-        $modelName = self::_get_model_classname(get_class($this));
1761
-        return self::_get_model_instance_with_name($modelName, $this->_timezone);
1762
-    }
1763
-
1764
-
1765
-
1766
-    /**
1767
-     * @param $props_n_values
1768
-     * @param $classname
1769
-     * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1770
-     * @throws \EE_Error
1771
-     */
1772
-    protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1773
-    {
1774
-        //TODO: will not work for Term_Relationships because they have no PK!
1775
-        $primary_id_ref = self::_get_primary_key_name($classname);
1776
-        if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1777
-            $id = $props_n_values[$primary_id_ref];
1778
-            return self::_get_model($classname)->get_from_entity_map($id);
1779
-        }
1780
-        return false;
1781
-    }
1782
-
1783
-
1784
-
1785
-    /**
1786
-     * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1787
-     * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1788
-     * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1789
-     * we return false.
1790
-     *
1791
-     * @param  array  $props_n_values   incoming array of properties and their values
1792
-     * @param  string $classname        the classname of the child class
1793
-     * @param null    $timezone
1794
-     * @param array   $date_formats     incoming date_formats in an array where the first value is the
1795
-     *                                  date_format and the second value is the time format
1796
-     * @return mixed (EE_Base_Class|bool)
1797
-     * @throws \EE_Error
1798
-     */
1799
-    protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1800
-    {
1801
-        $existing = null;
1802
-        if (self::_get_model($classname)->has_primary_key_field()) {
1803
-            $primary_id_ref = self::_get_primary_key_name($classname);
1804
-            if (array_key_exists($primary_id_ref, $props_n_values)
1805
-                && ! empty($props_n_values[$primary_id_ref])
1806
-            ) {
1807
-                $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1808
-                    $props_n_values[$primary_id_ref]
1809
-                );
1810
-            }
1811
-        } elseif (self::_get_model($classname, $timezone)->has_all_combined_primary_key_fields($props_n_values)) {
1812
-            //no primary key on this model, but there's still a matching item in the DB
1813
-            $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1814
-                self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1815
-            );
1816
-        }
1817
-        if ($existing) {
1818
-            //set date formats if present before setting values
1819
-            if ( ! empty($date_formats) && is_array($date_formats)) {
1820
-                $existing->set_date_format($date_formats[0]);
1821
-                $existing->set_time_format($date_formats[1]);
1822
-            } else {
1823
-                //set default formats for date and time
1824
-                $existing->set_date_format(get_option('date_format'));
1825
-                $existing->set_time_format(get_option('time_format'));
1826
-            }
1827
-            foreach ($props_n_values as $property => $field_value) {
1828
-                $existing->set($property, $field_value);
1829
-            }
1830
-            return $existing;
1831
-        } else {
1832
-            return false;
1833
-        }
1834
-    }
1835
-
1836
-
1837
-
1838
-    /**
1839
-     * Gets the EEM_*_Model for this class
1840
-     *
1841
-     * @access public now, as this is more convenient
1842
-     * @param      $classname
1843
-     * @param null $timezone
1844
-     * @throws EE_Error
1845
-     * @return EEM_Base
1846
-     */
1847
-    protected static function _get_model($classname, $timezone = null)
1848
-    {
1849
-        //find model for this class
1850
-        if ( ! $classname) {
1851
-            throw new EE_Error(
1852
-                sprintf(
1853
-                    __(
1854
-                        "What were you thinking calling _get_model(%s)?? You need to specify the class name",
1855
-                        "event_espresso"
1856
-                    ),
1857
-                    $classname
1858
-                )
1859
-            );
1860
-        }
1861
-        $modelName = self::_get_model_classname($classname);
1862
-        return self::_get_model_instance_with_name($modelName, $timezone);
1863
-    }
1864
-
1865
-
1866
-
1867
-    /**
1868
-     * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1869
-     *
1870
-     * @param string $model_classname
1871
-     * @param null   $timezone
1872
-     * @return EEM_Base
1873
-     */
1874
-    protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1875
-    {
1876
-        $model_classname = str_replace('EEM_', '', $model_classname);
1877
-        $model = EE_Registry::instance()->load_model($model_classname);
1878
-        $model->set_timezone($timezone);
1879
-        return $model;
1880
-    }
1881
-
1882
-
1883
-
1884
-    /**
1885
-     * If a model name is provided (eg Registration), gets the model classname for that model.
1886
-     * Also works if a model class's classname is provided (eg EE_Registration).
1887
-     *
1888
-     * @param null $model_name
1889
-     * @return string like EEM_Attendee
1890
-     */
1891
-    private static function _get_model_classname($model_name = null)
1892
-    {
1893
-        if (strpos($model_name, "EE_") === 0) {
1894
-            $model_classname = str_replace("EE_", "EEM_", $model_name);
1895
-        } else {
1896
-            $model_classname = "EEM_" . $model_name;
1897
-        }
1898
-        return $model_classname;
1899
-    }
1900
-
1901
-
1902
-
1903
-    /**
1904
-     * returns the name of the primary key attribute
1905
-     *
1906
-     * @param null $classname
1907
-     * @throws EE_Error
1908
-     * @return string
1909
-     */
1910
-    protected static function _get_primary_key_name($classname = null)
1911
-    {
1912
-        if ( ! $classname) {
1913
-            throw new EE_Error(
1914
-                sprintf(
1915
-                    __("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1916
-                    $classname
1917
-                )
1918
-            );
1919
-        }
1920
-        return self::_get_model($classname)->get_primary_key_field()->get_name();
1921
-    }
1922
-
1923
-
1924
-
1925
-    /**
1926
-     * Gets the value of the primary key.
1927
-     * If the object hasn't yet been saved, it should be whatever the model field's default was
1928
-     * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
1929
-     * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
1930
-     *
1931
-     * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
1932
-     * @throws \EE_Error
1933
-     */
1934
-    public function ID()
1935
-    {
1936
-        //now that we know the name of the variable, use a variable variable to get its value and return its
1937
-        if ($this->get_model()->has_primary_key_field()) {
1938
-            return $this->_fields[self::_get_primary_key_name(get_class($this))];
1939
-        } else {
1940
-            return $this->get_model()->get_index_primary_key_string($this->_fields);
1941
-        }
1942
-    }
1943
-
1944
-
1945
-
1946
-    /**
1947
-     * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
1948
-     * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
1949
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
1950
-     *
1951
-     * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
1952
-     * @param string $relationName                     eg 'Events','Question',etc.
1953
-     *                                                 an attendee to a group, you also want to specify which role they
1954
-     *                                                 will have in that group. So you would use this parameter to
1955
-     *                                                 specify array('role-column-name'=>'role-id')
1956
-     * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
1957
-     *                                                 allow you to further constrict the relation to being added.
1958
-     *                                                 However, keep in mind that the columns (keys) given must match a
1959
-     *                                                 column on the JOIN table and currently only the HABTM models
1960
-     *                                                 accept these additional conditions.  Also remember that if an
1961
-     *                                                 exact match isn't found for these extra cols/val pairs, then a
1962
-     *                                                 NEW row is created in the join table.
1963
-     * @param null   $cache_id
1964
-     * @throws EE_Error
1965
-     * @return EE_Base_Class the object the relation was added to
1966
-     */
1967
-    public function _add_relation_to(
1968
-        $otherObjectModelObjectOrID,
1969
-        $relationName,
1970
-        $extra_join_model_fields_n_values = array(),
1971
-        $cache_id = null
1972
-    ) {
1973
-        //if this thing exists in the DB, save the relation to the DB
1974
-        if ($this->ID()) {
1975
-            $otherObject = $this->get_model()
1976
-                                ->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
1977
-                                    $extra_join_model_fields_n_values);
1978
-            //clear cache so future get_many_related and get_first_related() return new results.
1979
-            $this->clear_cache($relationName, $otherObject, true);
1980
-            if ($otherObject instanceof EE_Base_Class) {
1981
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
1982
-            }
1983
-        } else {
1984
-            //this thing doesn't exist in the DB,  so just cache it
1985
-            if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
1986
-                throw new EE_Error(sprintf(
1987
-                    __('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
1988
-                        'event_espresso'),
1989
-                    $otherObjectModelObjectOrID,
1990
-                    get_class($this)
1991
-                ));
1992
-            } else {
1993
-                $otherObject = $otherObjectModelObjectOrID;
1994
-            }
1995
-            $this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
1996
-        }
1997
-        if ($otherObject instanceof EE_Base_Class) {
1998
-            //fix the reciprocal relation too
1999
-            if ($otherObject->ID()) {
2000
-                //its saved so assumed relations exist in the DB, so we can just
2001
-                //clear the cache so future queries use the updated info in the DB
2002
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), null, true);
2003
-            } else {
2004
-                //it's not saved, so it caches relations like this
2005
-                $otherObject->cache($this->get_model()->get_this_model_name(), $this);
2006
-            }
2007
-        }
2008
-        return $otherObject;
2009
-    }
2010
-
2011
-
2012
-
2013
-    /**
2014
-     * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2015
-     * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2016
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2017
-     * from the cache
2018
-     *
2019
-     * @param mixed  $otherObjectModelObjectOrID
2020
-     *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2021
-     *                to the DB yet
2022
-     * @param string $relationName
2023
-     * @param array  $where_query
2024
-     *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2025
-     *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2026
-     *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2027
-     *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2028
-     *                created in the join table.
2029
-     * @return EE_Base_Class the relation was removed from
2030
-     * @throws \EE_Error
2031
-     */
2032
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2033
-    {
2034
-        if ($this->ID()) {
2035
-            //if this exists in the DB, save the relation change to the DB too
2036
-            $otherObject = $this->get_model()
2037
-                                ->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2038
-                                    $where_query);
2039
-            $this->clear_cache($relationName, $otherObject);
2040
-        } else {
2041
-            //this doesn't exist in the DB, just remove it from the cache
2042
-            $otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2043
-        }
2044
-        if ($otherObject instanceof EE_Base_Class) {
2045
-            $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2046
-        }
2047
-        return $otherObject;
2048
-    }
2049
-
2050
-
2051
-
2052
-    /**
2053
-     * Removes ALL the related things for the $relationName.
2054
-     *
2055
-     * @param string $relationName
2056
-     * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2057
-     * @return EE_Base_Class
2058
-     * @throws \EE_Error
2059
-     */
2060
-    public function _remove_relations($relationName, $where_query_params = array())
2061
-    {
2062
-        if ($this->ID()) {
2063
-            //if this exists in the DB, save the relation change to the DB too
2064
-            $otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2065
-            $this->clear_cache($relationName, null, true);
2066
-        } else {
2067
-            //this doesn't exist in the DB, just remove it from the cache
2068
-            $otherObjects = $this->clear_cache($relationName, null, true);
2069
-        }
2070
-        if (is_array($otherObjects)) {
2071
-            foreach ($otherObjects as $otherObject) {
2072
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2073
-            }
2074
-        }
2075
-        return $otherObjects;
2076
-    }
2077
-
2078
-
2079
-
2080
-    /**
2081
-     * Gets all the related model objects of the specified type. Eg, if the current class if
2082
-     * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2083
-     * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2084
-     * because we want to get even deleted items etc.
2085
-     *
2086
-     * @param string $relationName key in the model's _model_relations array
2087
-     * @param array  $query_params like EEM_Base::get_all
2088
-     * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2089
-     * @throws \EE_Error
2090
-     *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2091
-     *                             you want IDs
2092
-     */
2093
-    public function get_many_related($relationName, $query_params = array())
2094
-    {
2095
-        if ($this->ID()) {
2096
-            //this exists in the DB, so get the related things from either the cache or the DB
2097
-            //if there are query parameters, forget about caching the related model objects.
2098
-            if ($query_params) {
2099
-                $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2100
-            } else {
2101
-                //did we already cache the result of this query?
2102
-                $cached_results = $this->get_all_from_cache($relationName);
2103
-                if ( ! $cached_results) {
2104
-                    $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2105
-                    //if no query parameters were passed, then we got all the related model objects
2106
-                    //for that relation. We can cache them then.
2107
-                    foreach ($related_model_objects as $related_model_object) {
2108
-                        $this->cache($relationName, $related_model_object);
2109
-                    }
2110
-                } else {
2111
-                    $related_model_objects = $cached_results;
2112
-                }
2113
-            }
2114
-        } else {
2115
-            //this doesn't exist in the DB, so just get the related things from the cache
2116
-            $related_model_objects = $this->get_all_from_cache($relationName);
2117
-        }
2118
-        return $related_model_objects;
2119
-    }
2120
-
2121
-
2122
-
2123
-    /**
2124
-     * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2125
-     * unless otherwise specified in the $query_params
2126
-     *
2127
-     * @param string $relation_name  model_name like 'Event', or 'Registration'
2128
-     * @param array  $query_params   like EEM_Base::get_all's
2129
-     * @param string $field_to_count name of field to count by. By default, uses primary key
2130
-     * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2131
-     *                               that by the setting $distinct to TRUE;
2132
-     * @return int
2133
-     */
2134
-    public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2135
-    {
2136
-        return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2137
-    }
2138
-
2139
-
2140
-
2141
-    /**
2142
-     * Instead of getting the related model objects, simply sums up the values of the specified field.
2143
-     * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2144
-     *
2145
-     * @param string $relation_name model_name like 'Event', or 'Registration'
2146
-     * @param array  $query_params  like EEM_Base::get_all's
2147
-     * @param string $field_to_sum  name of field to count by.
2148
-     *                              By default, uses primary key (which doesn't make much sense, so you should probably
2149
-     *                              change it)
2150
-     * @return int
2151
-     */
2152
-    public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2153
-    {
2154
-        return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2155
-    }
2156
-
2157
-
2158
-
2159
-    /**
2160
-     * Gets the first (ie, one) related model object of the specified type.
2161
-     *
2162
-     * @param string $relationName key in the model's _model_relations array
2163
-     * @param array  $query_params like EEM_Base::get_all
2164
-     * @return EE_Base_Class (not an array, a single object)
2165
-     * @throws \EE_Error
2166
-     */
2167
-    public function get_first_related($relationName, $query_params = array())
2168
-    {
2169
-        if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2170
-            //if they've provided some query parameters, don't bother trying to cache the result
2171
-            //also make sure we're not caching the result of get_first_related
2172
-            //on a relation which should have an array of objects (because the cache might have an array of objects)
2173
-            if ($query_params
2174
-                || ! $this->get_model()->related_settings_for($relationName)
2175
-                     instanceof
2176
-                     EE_Belongs_To_Relation
2177
-            ) {
2178
-                $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2179
-            } else {
2180
-                //first, check if we've already cached the result of this query
2181
-                $cached_result = $this->get_one_from_cache($relationName);
2182
-                if ( ! $cached_result) {
2183
-                    $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2184
-                    $this->cache($relationName, $related_model_object);
2185
-                } else {
2186
-                    $related_model_object = $cached_result;
2187
-                }
2188
-            }
2189
-        } else {
2190
-            $related_model_object = null;
2191
-            //this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2192
-            if ($this->get_model()->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2193
-                $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2194
-            }
2195
-            //this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2196
-            if ( ! $related_model_object) {
2197
-                $related_model_object = $this->get_one_from_cache($relationName);
2198
-            }
2199
-        }
2200
-        return $related_model_object;
2201
-    }
2202
-
2203
-
2204
-
2205
-    /**
2206
-     * Does a delete on all related objects of type $relationName and removes
2207
-     * the current model object's relation to them. If they can't be deleted (because
2208
-     * of blocking related model objects) does nothing. If the related model objects are
2209
-     * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2210
-     * If this model object doesn't exist yet in the DB, just removes its related things
2211
-     *
2212
-     * @param string $relationName
2213
-     * @param array  $query_params like EEM_Base::get_all's
2214
-     * @return int how many deleted
2215
-     * @throws \EE_Error
2216
-     */
2217
-    public function delete_related($relationName, $query_params = array())
2218
-    {
2219
-        if ($this->ID()) {
2220
-            $count = $this->get_model()->delete_related($this, $relationName, $query_params);
2221
-        } else {
2222
-            $count = count($this->get_all_from_cache($relationName));
2223
-            $this->clear_cache($relationName, null, true);
2224
-        }
2225
-        return $count;
2226
-    }
2227
-
2228
-
2229
-
2230
-    /**
2231
-     * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2232
-     * the current model object's relation to them. If they can't be deleted (because
2233
-     * of blocking related model objects) just does a soft delete on it instead, if possible.
2234
-     * If the related thing isn't a soft-deletable model object, this function is identical
2235
-     * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2236
-     *
2237
-     * @param string $relationName
2238
-     * @param array  $query_params like EEM_Base::get_all's
2239
-     * @return int how many deleted (including those soft deleted)
2240
-     * @throws \EE_Error
2241
-     */
2242
-    public function delete_related_permanently($relationName, $query_params = array())
2243
-    {
2244
-        if ($this->ID()) {
2245
-            $count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2246
-        } else {
2247
-            $count = count($this->get_all_from_cache($relationName));
2248
-        }
2249
-        $this->clear_cache($relationName, null, true);
2250
-        return $count;
2251
-    }
2252
-
2253
-
2254
-
2255
-    /**
2256
-     * is_set
2257
-     * Just a simple utility function children can use for checking if property exists
2258
-     *
2259
-     * @access  public
2260
-     * @param  string $field_name property to check
2261
-     * @return bool                              TRUE if existing,FALSE if not.
2262
-     */
2263
-    public function is_set($field_name)
2264
-    {
2265
-        return isset($this->_fields[$field_name]);
2266
-    }
2267
-
2268
-
2269
-
2270
-    /**
2271
-     * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2272
-     * EE_Error exception if they don't
2273
-     *
2274
-     * @param  mixed (string|array) $properties properties to check
2275
-     * @throws EE_Error
2276
-     * @return bool                              TRUE if existing, throw EE_Error if not.
2277
-     */
2278
-    protected function _property_exists($properties)
2279
-    {
2280
-        foreach ((array)$properties as $property_name) {
2281
-            //first make sure this property exists
2282
-            if ( ! $this->_fields[$property_name]) {
2283
-                throw new EE_Error(
2284
-                    sprintf(
2285
-                        __(
2286
-                            'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2287
-                            'event_espresso'
2288
-                        ),
2289
-                        $property_name
2290
-                    )
2291
-                );
2292
-            }
2293
-        }
2294
-        return true;
2295
-    }
2296
-
2297
-
2298
-
2299
-    /**
2300
-     * This simply returns an array of model fields for this object
2301
-     *
2302
-     * @return array
2303
-     * @throws \EE_Error
2304
-     */
2305
-    public function model_field_array()
2306
-    {
2307
-        $fields = $this->get_model()->field_settings(false);
2308
-        $properties = array();
2309
-        //remove prepended underscore
2310
-        foreach ($fields as $field_name => $settings) {
2311
-            $properties[$field_name] = $this->get($field_name);
2312
-        }
2313
-        return $properties;
2314
-    }
2315
-
2316
-
2317
-
2318
-    /**
2319
-     * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2320
-     * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2321
-     * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2322
-     * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2323
-     * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2324
-     * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2325
-     * was called, and an array of the original arguments passed to the function. Whatever their callback function
2326
-     * returns will be returned by this function. Example: in functions.php (or in a plugin):
2327
-     * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2328
-     * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2329
-     * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2330
-     *        return $previousReturnValue.$returnString;
2331
-     * }
2332
-     * require('EE_Answer.class.php');
2333
-     * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2334
-     * echo $answer->my_callback('monkeys',100);
2335
-     * //will output "you called my_callback! and passed args:monkeys,100"
2336
-     *
2337
-     * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2338
-     * @param array  $args       array of original arguments passed to the function
2339
-     * @throws EE_Error
2340
-     * @return mixed whatever the plugin which calls add_filter decides
2341
-     */
2342
-    public function __call($methodName, $args)
2343
-    {
2344
-        $className = get_class($this);
2345
-        $tagName = "FHEE__{$className}__{$methodName}";
2346
-        if ( ! has_filter($tagName)) {
2347
-            throw new EE_Error(
2348
-                sprintf(
2349
-                    __(
2350
-                        "Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2351
-                        "event_espresso"
2352
-                    ),
2353
-                    $methodName,
2354
-                    $className,
2355
-                    $tagName
2356
-                )
2357
-            );
2358
-        }
2359
-        return apply_filters($tagName, null, $this, $args);
2360
-    }
2361
-
2362
-
2363
-
2364
-    /**
2365
-     * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2366
-     * A $previous_value can be specified in case there are many meta rows with the same key
2367
-     *
2368
-     * @param string $meta_key
2369
-     * @param mixed  $meta_value
2370
-     * @param mixed  $previous_value
2371
-     * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2372
-     * @throws \EE_Error
2373
-     * NOTE: if the values haven't changed, returns 0
2374
-     */
2375
-    public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2376
-    {
2377
-        $query_params = array(
2378
-            array(
2379
-                'EXM_key'  => $meta_key,
2380
-                'OBJ_ID'   => $this->ID(),
2381
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2382
-            ),
2383
-        );
2384
-        if ($previous_value !== null) {
2385
-            $query_params[0]['EXM_value'] = $meta_value;
2386
-        }
2387
-        $existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2388
-        if ( ! $existing_rows_like_that) {
2389
-            return $this->add_extra_meta($meta_key, $meta_value);
2390
-        }
2391
-        foreach ($existing_rows_like_that as $existing_row) {
2392
-            $existing_row->save(array('EXM_value' => $meta_value));
2393
-        }
2394
-        return count($existing_rows_like_that);
2395
-    }
2396
-
2397
-
2398
-
2399
-    /**
2400
-     * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2401
-     * no other extra meta for this model object have the same key. Returns TRUE if the
2402
-     * extra meta row was entered, false if not
2403
-     *
2404
-     * @param string  $meta_key
2405
-     * @param string  $meta_value
2406
-     * @param boolean $unique
2407
-     * @return boolean
2408
-     * @throws \EE_Error
2409
-     */
2410
-    public function add_extra_meta($meta_key, $meta_value, $unique = false)
2411
-    {
2412
-        if ($unique) {
2413
-            $existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2414
-                array(
2415
-                    array(
2416
-                        'EXM_key'  => $meta_key,
2417
-                        'OBJ_ID'   => $this->ID(),
2418
-                        'EXM_type' => $this->get_model()->get_this_model_name(),
2419
-                    ),
2420
-                )
2421
-            );
2422
-            if ($existing_extra_meta) {
2423
-                return false;
2424
-            }
2425
-        }
2426
-        $new_extra_meta = EE_Extra_Meta::new_instance(
2427
-            array(
2428
-                'EXM_key'   => $meta_key,
2429
-                'EXM_value' => $meta_value,
2430
-                'OBJ_ID'    => $this->ID(),
2431
-                'EXM_type'  => $this->get_model()->get_this_model_name(),
2432
-            )
2433
-        );
2434
-        $new_extra_meta->save();
2435
-        return true;
2436
-    }
2437
-
2438
-
2439
-
2440
-    /**
2441
-     * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2442
-     * is specified, only deletes extra meta records with that value.
2443
-     *
2444
-     * @param string $meta_key
2445
-     * @param string $meta_value
2446
-     * @return int number of extra meta rows deleted
2447
-     * @throws \EE_Error
2448
-     */
2449
-    public function delete_extra_meta($meta_key, $meta_value = null)
2450
-    {
2451
-        $query_params = array(
2452
-            array(
2453
-                'EXM_key'  => $meta_key,
2454
-                'OBJ_ID'   => $this->ID(),
2455
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2456
-            ),
2457
-        );
2458
-        if ($meta_value !== null) {
2459
-            $query_params[0]['EXM_value'] = $meta_value;
2460
-        }
2461
-        return EEM_Extra_Meta::instance()->delete($query_params);
2462
-    }
2463
-
2464
-
2465
-
2466
-    /**
2467
-     * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2468
-     * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2469
-     * You can specify $default is case you haven't found the extra meta
2470
-     *
2471
-     * @param string  $meta_key
2472
-     * @param boolean $single
2473
-     * @param mixed   $default if we don't find anything, what should we return?
2474
-     * @return mixed single value if $single; array if ! $single
2475
-     * @throws \EE_Error
2476
-     */
2477
-    public function get_extra_meta($meta_key, $single = false, $default = null)
2478
-    {
2479
-        if ($single) {
2480
-            $result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2481
-            if ($result instanceof EE_Extra_Meta) {
2482
-                return $result->value();
2483
-            } else {
2484
-                return $default;
2485
-            }
2486
-        } else {
2487
-            $results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2488
-            if ($results) {
2489
-                $values = array();
2490
-                foreach ($results as $result) {
2491
-                    if ($result instanceof EE_Extra_Meta) {
2492
-                        $values[$result->ID()] = $result->value();
2493
-                    }
2494
-                }
2495
-                return $values;
2496
-            } else {
2497
-                return $default;
2498
-            }
2499
-        }
2500
-    }
2501
-
2502
-
2503
-
2504
-    /**
2505
-     * Returns a simple array of all the extra meta associated with this model object.
2506
-     * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2507
-     * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2508
-     * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2509
-     * If $one_of_each_key is false, it will return an array with the top-level keys being
2510
-     * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2511
-     * finally the extra meta's value as each sub-value. (eg
2512
-     * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2513
-     *
2514
-     * @param boolean $one_of_each_key
2515
-     * @return array
2516
-     * @throws \EE_Error
2517
-     */
2518
-    public function all_extra_meta_array($one_of_each_key = true)
2519
-    {
2520
-        $return_array = array();
2521
-        if ($one_of_each_key) {
2522
-            $extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2523
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2524
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2525
-                    $return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2526
-                }
2527
-            }
2528
-        } else {
2529
-            $extra_meta_objs = $this->get_many_related('Extra_Meta');
2530
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2531
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2532
-                    if ( ! isset($return_array[$extra_meta_obj->key()])) {
2533
-                        $return_array[$extra_meta_obj->key()] = array();
2534
-                    }
2535
-                    $return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2536
-                }
2537
-            }
2538
-        }
2539
-        return $return_array;
2540
-    }
2541
-
2542
-
2543
-
2544
-    /**
2545
-     * Gets a pretty nice displayable nice for this model object. Often overridden
2546
-     *
2547
-     * @return string
2548
-     * @throws \EE_Error
2549
-     */
2550
-    public function name()
2551
-    {
2552
-        //find a field that's not a text field
2553
-        $field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2554
-        if ($field_we_can_use) {
2555
-            return $this->get($field_we_can_use->get_name());
2556
-        } else {
2557
-            $first_few_properties = $this->model_field_array();
2558
-            $first_few_properties = array_slice($first_few_properties, 0, 3);
2559
-            $name_parts = array();
2560
-            foreach ($first_few_properties as $name => $value) {
2561
-                $name_parts[] = "$name:$value";
2562
-            }
2563
-            return implode(",", $name_parts);
2564
-        }
2565
-    }
2566
-
2567
-
2568
-
2569
-    /**
2570
-     * in_entity_map
2571
-     * Checks if this model object has been proven to already be in the entity map
2572
-     *
2573
-     * @return boolean
2574
-     * @throws \EE_Error
2575
-     */
2576
-    public function in_entity_map()
2577
-    {
2578
-        if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2579
-            //well, if we looked, did we find it in the entity map?
2580
-            return true;
2581
-        } else {
2582
-            return false;
2583
-        }
2584
-    }
2585
-
2586
-
2587
-
2588
-    /**
2589
-     * refresh_from_db
2590
-     * Makes sure the fields and values on this model object are in-sync with what's in the database.
2591
-     *
2592
-     * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2593
-     * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2594
-     */
2595
-    public function refresh_from_db()
2596
-    {
2597
-        if ($this->ID() && $this->in_entity_map()) {
2598
-            $this->get_model()->refresh_entity_map_from_db($this->ID());
2599
-        } else {
2600
-            //if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2601
-            //if it has an ID but it's not in the map, and you're asking me to refresh it
2602
-            //that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2603
-            //absolutely nothing in it for this ID
2604
-            if (WP_DEBUG) {
2605
-                throw new EE_Error(
2606
-                    sprintf(
2607
-                        __('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2608
-                            'event_espresso'),
2609
-                        $this->ID(),
2610
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2611
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2612
-                    )
2613
-                );
2614
-            }
2615
-        }
2616
-    }
2617
-
2618
-
2619
-
2620
-    /**
2621
-     * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2622
-     * (probably a bad assumption they have made, oh well)
2623
-     *
2624
-     * @return string
2625
-     */
2626
-    public function __toString()
2627
-    {
2628
-        try {
2629
-            return sprintf('%s (%s)', $this->name(), $this->ID());
2630
-        } catch (Exception $e) {
2631
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2632
-            return '';
2633
-        }
2634
-    }
2635
-
2636
-
2637
-
2638
-    /**
2639
-     * Clear related model objects if they're already in the DB, because otherwise when we
2640
-     * UN-serialize this model object we'll need to be careful to add them to the entity map.
2641
-     * This means if we have made changes to those related model objects, and want to unserialize
2642
-     * the this model object on a subsequent request, changes to those related model objects will be lost.
2643
-     * Instead, those related model objects should be directly serialized and stored.
2644
-     * Eg, the following won't work:
2645
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2646
-     * $att = $reg->attendee();
2647
-     * $att->set( 'ATT_fname', 'Dirk' );
2648
-     * update_option( 'my_option', serialize( $reg ) );
2649
-     * //END REQUEST
2650
-     * //START NEXT REQUEST
2651
-     * $reg = get_option( 'my_option' );
2652
-     * $reg->attendee()->save();
2653
-     * And would need to be replace with:
2654
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2655
-     * $att = $reg->attendee();
2656
-     * $att->set( 'ATT_fname', 'Dirk' );
2657
-     * update_option( 'my_option', serialize( $reg ) );
2658
-     * //END REQUEST
2659
-     * //START NEXT REQUEST
2660
-     * $att = get_option( 'my_option' );
2661
-     * $att->save();
2662
-     *
2663
-     * @return array
2664
-     * @throws \EE_Error
2665
-     */
2666
-    public function __sleep()
2667
-    {
2668
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
2669
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
2670
-                $classname = 'EE_' . $this->get_model()->get_this_model_name();
2671
-                if (
2672
-                    $this->get_one_from_cache($relation_name) instanceof $classname
2673
-                    && $this->get_one_from_cache($relation_name)->ID()
2674
-                ) {
2675
-                    $this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2676
-                }
2677
-            }
2678
-        }
2679
-        $this->_props_n_values_provided_in_constructor = array();
2680
-        return array_keys(get_object_vars($this));
2681
-    }
2682
-
2683
-
2684
-
2685
-    /**
2686
-     * restore _props_n_values_provided_in_constructor
2687
-     * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2688
-     * and therefore should NOT be used to determine if state change has occurred since initial construction.
2689
-     * At best, you would only be able to detect if state change has occurred during THIS request.
2690
-     */
2691
-    public function __wakeup()
2692
-    {
2693
-        $this->_props_n_values_provided_in_constructor = $this->_fields;
2694
-    }
28
+	/**
29
+	 * This is an array of the original properties and values provided during construction
30
+	 * of this model object. (keys are model field names, values are their values).
31
+	 * This list is important to remember so that when we are merging data from the db, we know
32
+	 * which values to override and which to not override.
33
+	 *
34
+	 * @var array
35
+	 */
36
+	protected $_props_n_values_provided_in_constructor;
37
+
38
+	/**
39
+	 * Timezone
40
+	 * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
+	 * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
+	 * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
+	 * access to it.
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_timezone;
48
+
49
+
50
+
51
+	/**
52
+	 * date format
53
+	 * pattern or format for displaying dates
54
+	 *
55
+	 * @var string $_dt_frmt
56
+	 */
57
+	protected $_dt_frmt;
58
+
59
+
60
+
61
+	/**
62
+	 * time format
63
+	 * pattern or format for displaying time
64
+	 *
65
+	 * @var string $_tm_frmt
66
+	 */
67
+	protected $_tm_frmt;
68
+
69
+
70
+
71
+	/**
72
+	 * This property is for holding a cached array of object properties indexed by property name as the key.
73
+	 * The purpose of this is for setting a cache on properties that may have calculated values after a
74
+	 * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
+	 * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
+	 *
77
+	 * @var array
78
+	 */
79
+	protected $_cached_properties = array();
80
+
81
+	/**
82
+	 * An array containing keys of the related model, and values are either an array of related mode objects or a
83
+	 * single
84
+	 * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
+	 * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
+	 * all others have an array)
87
+	 *
88
+	 * @var array
89
+	 */
90
+	protected $_model_relations = array();
91
+
92
+	/**
93
+	 * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
+	 * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
+	 *
96
+	 * @var array
97
+	 */
98
+	protected $_fields = array();
99
+
100
+	/**
101
+	 * @var boolean indicating whether or not this model object is intended to ever be saved
102
+	 * For example, we might create model objects intended to only be used for the duration
103
+	 * of this request and to be thrown away, and if they were accidentally saved
104
+	 * it would be a bug.
105
+	 */
106
+	protected $_allow_persist = true;
107
+
108
+	/**
109
+	 * @var boolean indicating whether or not this model object's properties have changed since construction
110
+	 */
111
+	protected $_has_changes = false;
112
+
113
+
114
+
115
+	/**
116
+	 * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
117
+	 * play nice
118
+	 *
119
+	 * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
120
+	 *                                                         layer of the model's _fields array, (eg, EVT_ID,
121
+	 *                                                         TXN_amount, QST_name, etc) and values are their values
122
+	 * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
123
+	 *                                                         corresponding db model or not.
124
+	 * @param string  $timezone                                indicate what timezone you want any datetime fields to
125
+	 *                                                         be in when instantiating a EE_Base_Class object.
126
+	 * @param array   $date_formats                            An array of date formats to set on construct where first
127
+	 *                                                         value is the date_format and second value is the time
128
+	 *                                                         format.
129
+	 * @throws EE_Error
130
+	 */
131
+	protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
132
+	{
133
+		$className = get_class($this);
134
+		do_action("AHEE__{$className}__construct", $this, $fieldValues);
135
+		$model = $this->get_model();
136
+		$model_fields = $model->field_settings(false);
137
+		// ensure $fieldValues is an array
138
+		$fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
139
+		// EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
140
+		// verify client code has not passed any invalid field names
141
+		foreach ($fieldValues as $field_name => $field_value) {
142
+			if ( ! isset($model_fields[$field_name])) {
143
+				throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
144
+					"event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
145
+			}
146
+		}
147
+		// EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
148
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
149
+		if ( ! empty($date_formats) && is_array($date_formats)) {
150
+			list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
151
+		} else {
152
+			//set default formats for date and time
153
+			$this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
154
+			$this->_tm_frmt = (string)get_option('time_format', 'g:i a');
155
+		}
156
+		//if db model is instantiating
157
+		if ($bydb) {
158
+			//client code has indicated these field values are from the database
159
+			foreach ($model_fields as $fieldName => $field) {
160
+				$this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
161
+			}
162
+		} else {
163
+			//we're constructing a brand
164
+			//new instance of the model object. Generally, this means we'll need to do more field validation
165
+			foreach ($model_fields as $fieldName => $field) {
166
+				$this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
167
+			}
168
+		}
169
+		//remember what values were passed to this constructor
170
+		$this->_props_n_values_provided_in_constructor = $fieldValues;
171
+		//remember in entity mapper
172
+		if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
173
+			$model->add_to_entity_map($this);
174
+		}
175
+		//setup all the relations
176
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
177
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
178
+				$this->_model_relations[$relation_name] = null;
179
+			} else {
180
+				$this->_model_relations[$relation_name] = array();
181
+			}
182
+		}
183
+		/**
184
+		 * Action done at the end of each model object construction
185
+		 *
186
+		 * @param EE_Base_Class $this the model object just created
187
+		 */
188
+		do_action('AHEE__EE_Base_Class__construct__finished', $this);
189
+	}
190
+
191
+
192
+
193
+	/**
194
+	 * Gets whether or not this model object is allowed to persist/be saved to the database.
195
+	 *
196
+	 * @return boolean
197
+	 */
198
+	public function allow_persist()
199
+	{
200
+		return $this->_allow_persist;
201
+	}
202
+
203
+
204
+
205
+	/**
206
+	 * Sets whether or not this model object should be allowed to be saved to the DB.
207
+	 * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
208
+	 * you got new information that somehow made you change your mind.
209
+	 *
210
+	 * @param boolean $allow_persist
211
+	 * @return boolean
212
+	 */
213
+	public function set_allow_persist($allow_persist)
214
+	{
215
+		return $this->_allow_persist = $allow_persist;
216
+	}
217
+
218
+
219
+
220
+	/**
221
+	 * Gets the field's original value when this object was constructed during this request.
222
+	 * This can be helpful when determining if a model object has changed or not
223
+	 *
224
+	 * @param string $field_name
225
+	 * @return mixed|null
226
+	 * @throws \EE_Error
227
+	 */
228
+	public function get_original($field_name)
229
+	{
230
+		if (isset($this->_props_n_values_provided_in_constructor[$field_name])
231
+			&& $field_settings = $this->get_model()->field_settings_for($field_name)
232
+		) {
233
+			return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
234
+		} else {
235
+			return null;
236
+		}
237
+	}
238
+
239
+
240
+
241
+	/**
242
+	 * @param EE_Base_Class $obj
243
+	 * @return string
244
+	 */
245
+	public function get_class($obj)
246
+	{
247
+		return get_class($obj);
248
+	}
249
+
250
+
251
+
252
+	/**
253
+	 * Overrides parent because parent expects old models.
254
+	 * This also doesn't do any validation, and won't work for serialized arrays
255
+	 *
256
+	 * @param    string $field_name
257
+	 * @param    mixed  $field_value
258
+	 * @param bool      $use_default
259
+	 * @throws \EE_Error
260
+	 */
261
+	public function set($field_name, $field_value, $use_default = false)
262
+	{
263
+		// if not using default and nothing has changed, and object has already been setup (has ID),
264
+		// then don't do anything
265
+		if (
266
+			! $use_default
267
+			&& $this->_fields[$field_name] === $field_value
268
+			&& $this->ID()
269
+		) {
270
+			return;
271
+		}
272
+		$this->_has_changes = true;
273
+		$field_obj = $this->get_model()->field_settings_for($field_name);
274
+		if ($field_obj instanceof EE_Model_Field_Base) {
275
+			//			if ( method_exists( $field_obj, 'set_timezone' )) {
276
+			if ($field_obj instanceof EE_Datetime_Field) {
277
+				$field_obj->set_timezone($this->_timezone);
278
+				$field_obj->set_date_format($this->_dt_frmt);
279
+				$field_obj->set_time_format($this->_tm_frmt);
280
+			}
281
+			$holder_of_value = $field_obj->prepare_for_set($field_value);
282
+			//should the value be null?
283
+			if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
284
+				$this->_fields[$field_name] = $field_obj->get_default_value();
285
+				/**
286
+				 * To save having to refactor all the models, if a default value is used for a
287
+				 * EE_Datetime_Field, and that value is not null nor is it a DateTime
288
+				 * object.  Then let's do a set again to ensure that it becomes a DateTime
289
+				 * object.
290
+				 *
291
+				 * @since 4.6.10+
292
+				 */
293
+				if (
294
+					$field_obj instanceof EE_Datetime_Field
295
+					&& $this->_fields[$field_name] !== null
296
+					&& ! $this->_fields[$field_name] instanceof DateTime
297
+				) {
298
+					empty($this->_fields[$field_name])
299
+						? $this->set($field_name, time())
300
+						: $this->set($field_name, $this->_fields[$field_name]);
301
+				}
302
+			} else {
303
+				$this->_fields[$field_name] = $holder_of_value;
304
+			}
305
+			//if we're not in the constructor...
306
+			//now check if what we set was a primary key
307
+			if (
308
+				//note: props_n_values_provided_in_constructor is only set at the END of the constructor
309
+				$this->_props_n_values_provided_in_constructor
310
+				&& $field_value
311
+				&& $field_name === self::_get_primary_key_name(get_class($this))
312
+			) {
313
+				//if so, we want all this object's fields to be filled either with
314
+				//what we've explicitly set on this model
315
+				//or what we have in the db
316
+				// echo "setting primary key!";
317
+				$fields_on_model = self::_get_model(get_class($this))->field_settings();
318
+				$obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
319
+				foreach ($fields_on_model as $field_obj) {
320
+					if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
321
+						 && $field_obj->get_name() !== $field_name
322
+					) {
323
+						$this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
324
+					}
325
+				}
326
+				//oh this model object has an ID? well make sure its in the entity mapper
327
+				$this->get_model()->add_to_entity_map($this);
328
+			}
329
+			//let's unset any cache for this field_name from the $_cached_properties property.
330
+			$this->_clear_cached_property($field_name);
331
+		} else {
332
+			throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
333
+				"event_espresso"), $field_name));
334
+		}
335
+	}
336
+
337
+
338
+
339
+	/**
340
+	 * This sets the field value on the db column if it exists for the given $column_name or
341
+	 * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
342
+	 *
343
+	 * @see EE_message::get_column_value for related documentation on the necessity of this method.
344
+	 * @param string $field_name  Must be the exact column name.
345
+	 * @param mixed  $field_value The value to set.
346
+	 * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
347
+	 * @throws \EE_Error
348
+	 */
349
+	public function set_field_or_extra_meta($field_name, $field_value)
350
+	{
351
+		if ($this->get_model()->has_field($field_name)) {
352
+			$this->set($field_name, $field_value);
353
+			return true;
354
+		} else {
355
+			//ensure this object is saved first so that extra meta can be properly related.
356
+			$this->save();
357
+			return $this->update_extra_meta($field_name, $field_value);
358
+		}
359
+	}
360
+
361
+
362
+
363
+	/**
364
+	 * This retrieves the value of the db column set on this class or if that's not present
365
+	 * it will attempt to retrieve from extra_meta if found.
366
+	 * Example Usage:
367
+	 * Via EE_Message child class:
368
+	 * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
369
+	 * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
370
+	 * also have additional main fields specific to the messenger.  The system accommodates those extra
371
+	 * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
372
+	 * value for those extra fields dynamically via the EE_message object.
373
+	 *
374
+	 * @param  string $field_name expecting the fully qualified field name.
375
+	 * @return mixed|null  value for the field if found.  null if not found.
376
+	 * @throws \EE_Error
377
+	 */
378
+	public function get_field_or_extra_meta($field_name)
379
+	{
380
+		if ($this->get_model()->has_field($field_name)) {
381
+			$column_value = $this->get($field_name);
382
+		} else {
383
+			//This isn't a column in the main table, let's see if it is in the extra meta.
384
+			$column_value = $this->get_extra_meta($field_name, true, null);
385
+		}
386
+		return $column_value;
387
+	}
388
+
389
+
390
+
391
+	/**
392
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
393
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
394
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
395
+	 * available to all child classes that may be using the EE_Datetime_Field for a field data type.
396
+	 *
397
+	 * @access public
398
+	 * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
399
+	 * @return void
400
+	 * @throws \EE_Error
401
+	 */
402
+	public function set_timezone($timezone = '')
403
+	{
404
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
405
+		//make sure we clear all cached properties because they won't be relevant now
406
+		$this->_clear_cached_properties();
407
+		//make sure we update field settings and the date for all EE_Datetime_Fields
408
+		$model_fields = $this->get_model()->field_settings(false);
409
+		foreach ($model_fields as $field_name => $field_obj) {
410
+			if ($field_obj instanceof EE_Datetime_Field) {
411
+				$field_obj->set_timezone($this->_timezone);
412
+				if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
413
+					$this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
414
+				}
415
+			}
416
+		}
417
+	}
418
+
419
+
420
+
421
+	/**
422
+	 * This just returns whatever is set for the current timezone.
423
+	 *
424
+	 * @access public
425
+	 * @return string timezone string
426
+	 */
427
+	public function get_timezone()
428
+	{
429
+		return $this->_timezone;
430
+	}
431
+
432
+
433
+
434
+	/**
435
+	 * This sets the internal date format to what is sent in to be used as the new default for the class
436
+	 * internally instead of wp set date format options
437
+	 *
438
+	 * @since 4.6
439
+	 * @param string $format should be a format recognizable by PHP date() functions.
440
+	 */
441
+	public function set_date_format($format)
442
+	{
443
+		$this->_dt_frmt = $format;
444
+		//clear cached_properties because they won't be relevant now.
445
+		$this->_clear_cached_properties();
446
+	}
447
+
448
+
449
+
450
+	/**
451
+	 * This sets the internal time format string to what is sent in to be used as the new default for the
452
+	 * class internally instead of wp set time format options.
453
+	 *
454
+	 * @since 4.6
455
+	 * @param string $format should be a format recognizable by PHP date() functions.
456
+	 */
457
+	public function set_time_format($format)
458
+	{
459
+		$this->_tm_frmt = $format;
460
+		//clear cached_properties because they won't be relevant now.
461
+		$this->_clear_cached_properties();
462
+	}
463
+
464
+
465
+
466
+	/**
467
+	 * This returns the current internal set format for the date and time formats.
468
+	 *
469
+	 * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
470
+	 *                             where the first value is the date format and the second value is the time format.
471
+	 * @return mixed string|array
472
+	 */
473
+	public function get_format($full = true)
474
+	{
475
+		return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
476
+	}
477
+
478
+
479
+
480
+	/**
481
+	 * cache
482
+	 * stores the passed model object on the current model object.
483
+	 * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
484
+	 *
485
+	 * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
486
+	 *                                       'Registration' associated with this model object
487
+	 * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
488
+	 *                                       that could be a payment or a registration)
489
+	 * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
490
+	 *                                       items which will be stored in an array on this object
491
+	 * @throws EE_Error
492
+	 * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
493
+	 *                  related thing, no array)
494
+	 */
495
+	public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
496
+	{
497
+		// its entirely possible that there IS no related object yet in which case there is nothing to cache.
498
+		if ( ! $object_to_cache instanceof EE_Base_Class) {
499
+			return false;
500
+		}
501
+		// also get "how" the object is related, or throw an error
502
+		if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
503
+			throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
504
+				$relationName, get_class($this)));
505
+		}
506
+		// how many things are related ?
507
+		if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
508
+			// if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
509
+			// so for these model objects just set it to be cached
510
+			$this->_model_relations[$relationName] = $object_to_cache;
511
+			$return = true;
512
+		} else {
513
+			// otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
514
+			// eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
515
+			if ( ! is_array($this->_model_relations[$relationName])) {
516
+				// if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
517
+				$this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
518
+					? array($this->_model_relations[$relationName]) : array();
519
+			}
520
+			// first check for a cache_id which is normally empty
521
+			if ( ! empty($cache_id)) {
522
+				// if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
523
+				$this->_model_relations[$relationName][$cache_id] = $object_to_cache;
524
+				$return = $cache_id;
525
+			} elseif ($object_to_cache->ID()) {
526
+				// OR the cached object originally came from the db, so let's just use it's PK for an ID
527
+				$this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
528
+				$return = $object_to_cache->ID();
529
+			} else {
530
+				// OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
531
+				$this->_model_relations[$relationName][] = $object_to_cache;
532
+				// move the internal pointer to the end of the array
533
+				end($this->_model_relations[$relationName]);
534
+				// and grab the key so that we can return it
535
+				$return = key($this->_model_relations[$relationName]);
536
+			}
537
+		}
538
+		return $return;
539
+	}
540
+
541
+
542
+
543
+	/**
544
+	 * For adding an item to the cached_properties property.
545
+	 *
546
+	 * @access protected
547
+	 * @param string      $fieldname the property item the corresponding value is for.
548
+	 * @param mixed       $value     The value we are caching.
549
+	 * @param string|null $cache_type
550
+	 * @return void
551
+	 * @throws \EE_Error
552
+	 */
553
+	protected function _set_cached_property($fieldname, $value, $cache_type = null)
554
+	{
555
+		//first make sure this property exists
556
+		$this->get_model()->field_settings_for($fieldname);
557
+		$cache_type = empty($cache_type) ? 'standard' : $cache_type;
558
+		$this->_cached_properties[$fieldname][$cache_type] = $value;
559
+	}
560
+
561
+
562
+
563
+	/**
564
+	 * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
565
+	 * This also SETS the cache if we return the actual property!
566
+	 *
567
+	 * @param string $fieldname        the name of the property we're trying to retrieve
568
+	 * @param bool   $pretty
569
+	 * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
570
+	 *                                 (in cases where the same property may be used for different outputs
571
+	 *                                 - i.e. datetime, money etc.)
572
+	 *                                 It can also accept certain pre-defined "schema" strings
573
+	 *                                 to define how to output the property.
574
+	 *                                 see the field's prepare_for_pretty_echoing for what strings can be used
575
+	 * @return mixed                   whatever the value for the property is we're retrieving
576
+	 * @throws \EE_Error
577
+	 */
578
+	protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
579
+	{
580
+		//verify the field exists
581
+		$this->get_model()->field_settings_for($fieldname);
582
+		$cache_type = $pretty ? 'pretty' : 'standard';
583
+		$cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
584
+		if (isset($this->_cached_properties[$fieldname][$cache_type])) {
585
+			return $this->_cached_properties[$fieldname][$cache_type];
586
+		}
587
+		$field_obj = $this->get_model()->field_settings_for($fieldname);
588
+		if ($field_obj instanceof EE_Model_Field_Base) {
589
+			// If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
590
+			if ($field_obj instanceof EE_Datetime_Field) {
591
+				$this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
592
+			}
593
+			if ( ! isset($this->_fields[$fieldname])) {
594
+				$this->_fields[$fieldname] = null;
595
+			}
596
+			$value = $pretty
597
+				? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
598
+				: $field_obj->prepare_for_get($this->_fields[$fieldname]);
599
+			$this->_set_cached_property($fieldname, $value, $cache_type);
600
+			return $value;
601
+		}
602
+		return null;
603
+	}
604
+
605
+
606
+
607
+	/**
608
+	 * set timezone, formats, and output for EE_Datetime_Field objects
609
+	 *
610
+	 * @param \EE_Datetime_Field $datetime_field
611
+	 * @param bool               $pretty
612
+	 * @param null $date_or_time
613
+	 * @return void
614
+	 * @throws \EE_Error
615
+	 */
616
+	protected function _prepare_datetime_field(
617
+		EE_Datetime_Field $datetime_field,
618
+		$pretty = false,
619
+		$date_or_time = null
620
+	) {
621
+		$datetime_field->set_timezone($this->_timezone);
622
+		$datetime_field->set_date_format($this->_dt_frmt, $pretty);
623
+		$datetime_field->set_time_format($this->_tm_frmt, $pretty);
624
+		//set the output returned
625
+		switch ($date_or_time) {
626
+			case 'D' :
627
+				$datetime_field->set_date_time_output('date');
628
+				break;
629
+			case 'T' :
630
+				$datetime_field->set_date_time_output('time');
631
+				break;
632
+			default :
633
+				$datetime_field->set_date_time_output();
634
+		}
635
+	}
636
+
637
+
638
+
639
+	/**
640
+	 * This just takes care of clearing out the cached_properties
641
+	 *
642
+	 * @return void
643
+	 */
644
+	protected function _clear_cached_properties()
645
+	{
646
+		$this->_cached_properties = array();
647
+	}
648
+
649
+
650
+
651
+	/**
652
+	 * This just clears out ONE property if it exists in the cache
653
+	 *
654
+	 * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
655
+	 * @return void
656
+	 */
657
+	protected function _clear_cached_property($property_name)
658
+	{
659
+		if (isset($this->_cached_properties[$property_name])) {
660
+			unset($this->_cached_properties[$property_name]);
661
+		}
662
+	}
663
+
664
+
665
+
666
+	/**
667
+	 * Ensures that this related thing is a model object.
668
+	 *
669
+	 * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
670
+	 * @param string $model_name   name of the related thing, eg 'Attendee',
671
+	 * @return EE_Base_Class
672
+	 * @throws \EE_Error
673
+	 */
674
+	protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
675
+	{
676
+		$other_model_instance = self::_get_model_instance_with_name(
677
+			self::_get_model_classname($model_name),
678
+			$this->_timezone
679
+		);
680
+		return $other_model_instance->ensure_is_obj($object_or_id);
681
+	}
682
+
683
+
684
+
685
+	/**
686
+	 * Forgets the cached model of the given relation Name. So the next time we request it,
687
+	 * we will fetch it again from the database. (Handy if you know it's changed somehow).
688
+	 * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
689
+	 * then only remove that one object from our cached array. Otherwise, clear the entire list
690
+	 *
691
+	 * @param string $relationName                         one of the keys in the _model_relations array on the model.
692
+	 *                                                     Eg 'Registration'
693
+	 * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
694
+	 *                                                     if you intend to use $clear_all = TRUE, or the relation only
695
+	 *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
696
+	 * @param bool   $clear_all                            This flags clearing the entire cache relation property if
697
+	 *                                                     this is HasMany or HABTM.
698
+	 * @throws EE_Error
699
+	 * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
700
+	 *                       relation from all
701
+	 */
702
+	public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
703
+	{
704
+		$relationship_to_model = $this->get_model()->related_settings_for($relationName);
705
+		$index_in_cache = '';
706
+		if ( ! $relationship_to_model) {
707
+			throw new EE_Error(
708
+				sprintf(
709
+					__("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
710
+					$relationName,
711
+					get_class($this)
712
+				)
713
+			);
714
+		}
715
+		if ($clear_all) {
716
+			$obj_removed = true;
717
+			$this->_model_relations[$relationName] = null;
718
+		} elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
719
+			$obj_removed = $this->_model_relations[$relationName];
720
+			$this->_model_relations[$relationName] = null;
721
+		} else {
722
+			if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
723
+				&& $object_to_remove_or_index_into_array->ID()
724
+			) {
725
+				$index_in_cache = $object_to_remove_or_index_into_array->ID();
726
+				if (is_array($this->_model_relations[$relationName])
727
+					&& ! isset($this->_model_relations[$relationName][$index_in_cache])
728
+				) {
729
+					$index_found_at = null;
730
+					//find this object in the array even though it has a different key
731
+					foreach ($this->_model_relations[$relationName] as $index => $obj) {
732
+						if (
733
+							$obj instanceof EE_Base_Class
734
+							&& (
735
+								$obj == $object_to_remove_or_index_into_array
736
+								|| $obj->ID() === $object_to_remove_or_index_into_array->ID()
737
+							)
738
+						) {
739
+							$index_found_at = $index;
740
+							break;
741
+						}
742
+					}
743
+					if ($index_found_at) {
744
+						$index_in_cache = $index_found_at;
745
+					} else {
746
+						//it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
747
+						//if it wasn't in it to begin with. So we're done
748
+						return $object_to_remove_or_index_into_array;
749
+					}
750
+				}
751
+			} elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
752
+				//so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
753
+				foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
754
+					if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
755
+						$index_in_cache = $index;
756
+					}
757
+				}
758
+			} else {
759
+				$index_in_cache = $object_to_remove_or_index_into_array;
760
+			}
761
+			//supposedly we've found it. But it could just be that the client code
762
+			//provided a bad index/object
763
+			if (
764
+			isset(
765
+				$this->_model_relations[$relationName],
766
+				$this->_model_relations[$relationName][$index_in_cache]
767
+			)
768
+			) {
769
+				$obj_removed = $this->_model_relations[$relationName][$index_in_cache];
770
+				unset($this->_model_relations[$relationName][$index_in_cache]);
771
+			} else {
772
+				//that thing was never cached anyways.
773
+				$obj_removed = null;
774
+			}
775
+		}
776
+		return $obj_removed;
777
+	}
778
+
779
+
780
+
781
+	/**
782
+	 * update_cache_after_object_save
783
+	 * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
784
+	 * obtained after being saved to the db
785
+	 *
786
+	 * @param string         $relationName       - the type of object that is cached
787
+	 * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
788
+	 * @param string         $current_cache_id   - the ID that was used when originally caching the object
789
+	 * @return boolean TRUE on success, FALSE on fail
790
+	 * @throws \EE_Error
791
+	 */
792
+	public function update_cache_after_object_save(
793
+		$relationName,
794
+		EE_Base_Class $newly_saved_object,
795
+		$current_cache_id = ''
796
+	) {
797
+		// verify that incoming object is of the correct type
798
+		$obj_class = 'EE_' . $relationName;
799
+		if ($newly_saved_object instanceof $obj_class) {
800
+			/* @type EE_Base_Class $newly_saved_object */
801
+			// now get the type of relation
802
+			$relationship_to_model = $this->get_model()->related_settings_for($relationName);
803
+			// if this is a 1:1 relationship
804
+			if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
805
+				// then just replace the cached object with the newly saved object
806
+				$this->_model_relations[$relationName] = $newly_saved_object;
807
+				return true;
808
+				// or if it's some kind of sordid feral polyamorous relationship...
809
+			} elseif (is_array($this->_model_relations[$relationName])
810
+					  && isset($this->_model_relations[$relationName][$current_cache_id])
811
+			) {
812
+				// then remove the current cached item
813
+				unset($this->_model_relations[$relationName][$current_cache_id]);
814
+				// and cache the newly saved object using it's new ID
815
+				$this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
816
+				return true;
817
+			}
818
+		}
819
+		return false;
820
+	}
821
+
822
+
823
+
824
+	/**
825
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
826
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
827
+	 *
828
+	 * @param string $relationName
829
+	 * @return EE_Base_Class
830
+	 */
831
+	public function get_one_from_cache($relationName)
832
+	{
833
+		$cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
834
+			: null;
835
+		if (is_array($cached_array_or_object)) {
836
+			return array_shift($cached_array_or_object);
837
+		} else {
838
+			return $cached_array_or_object;
839
+		}
840
+	}
841
+
842
+
843
+
844
+	/**
845
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
846
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
847
+	 *
848
+	 * @param string $relationName
849
+	 * @throws \EE_Error
850
+	 * @return EE_Base_Class[] NOT necessarily indexed by primary keys
851
+	 */
852
+	public function get_all_from_cache($relationName)
853
+	{
854
+		$objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
855
+		// if the result is not an array, but exists, make it an array
856
+		$objects = is_array($objects) ? $objects : array($objects);
857
+		//bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
858
+		//basically, if this model object was stored in the session, and these cached model objects
859
+		//already have IDs, let's make sure they're in their model's entity mapper
860
+		//otherwise we will have duplicates next time we call
861
+		// EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
862
+		$model = EE_Registry::instance()->load_model($relationName);
863
+		foreach ($objects as $model_object) {
864
+			if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
865
+				//ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
866
+				if ($model_object->ID()) {
867
+					$model->add_to_entity_map($model_object);
868
+				}
869
+			} else {
870
+				throw new EE_Error(
871
+					sprintf(
872
+						__(
873
+							'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
874
+							'event_espresso'
875
+						),
876
+						$relationName,
877
+						gettype($model_object)
878
+					)
879
+				);
880
+			}
881
+		}
882
+		return $objects;
883
+	}
884
+
885
+
886
+
887
+	/**
888
+	 * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
889
+	 * matching the given query conditions.
890
+	 *
891
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
892
+	 * @param int   $limit              How many objects to return.
893
+	 * @param array $query_params       Any additional conditions on the query.
894
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
895
+	 *                                  you can indicate just the columns you want returned
896
+	 * @return array|EE_Base_Class[]
897
+	 * @throws \EE_Error
898
+	 */
899
+	public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
900
+	{
901
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
902
+			? $this->get_model()->get_primary_key_field()->get_name()
903
+			: $field_to_order_by;
904
+		$current_value = ! empty($field) ? $this->get($field) : null;
905
+		if (empty($field) || empty($current_value)) {
906
+			return array();
907
+		}
908
+		return $this->get_model()->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
909
+	}
910
+
911
+
912
+
913
+	/**
914
+	 * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
915
+	 * matching the given query conditions.
916
+	 *
917
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
918
+	 * @param int   $limit              How many objects to return.
919
+	 * @param array $query_params       Any additional conditions on the query.
920
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
921
+	 *                                  you can indicate just the columns you want returned
922
+	 * @return array|EE_Base_Class[]
923
+	 * @throws \EE_Error
924
+	 */
925
+	public function previous_x(
926
+		$field_to_order_by = null,
927
+		$limit = 1,
928
+		$query_params = array(),
929
+		$columns_to_select = null
930
+	) {
931
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
932
+			? $this->get_model()->get_primary_key_field()->get_name()
933
+			: $field_to_order_by;
934
+		$current_value = ! empty($field) ? $this->get($field) : null;
935
+		if (empty($field) || empty($current_value)) {
936
+			return array();
937
+		}
938
+		return $this->get_model()->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
939
+	}
940
+
941
+
942
+
943
+	/**
944
+	 * Returns the next EE_Base_Class object in sequence from this object as found in the database
945
+	 * matching the given query conditions.
946
+	 *
947
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
948
+	 * @param array $query_params       Any additional conditions on the query.
949
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
950
+	 *                                  you can indicate just the columns you want returned
951
+	 * @return array|EE_Base_Class
952
+	 * @throws \EE_Error
953
+	 */
954
+	public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
955
+	{
956
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
957
+			? $this->get_model()->get_primary_key_field()->get_name()
958
+			: $field_to_order_by;
959
+		$current_value = ! empty($field) ? $this->get($field) : null;
960
+		if (empty($field) || empty($current_value)) {
961
+			return array();
962
+		}
963
+		return $this->get_model()->next($current_value, $field, $query_params, $columns_to_select);
964
+	}
965
+
966
+
967
+
968
+	/**
969
+	 * Returns the previous EE_Base_Class object in sequence from this object as found in the database
970
+	 * matching the given query conditions.
971
+	 *
972
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
973
+	 * @param array $query_params       Any additional conditions on the query.
974
+	 * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
975
+	 *                                  you can indicate just the column you want returned
976
+	 * @return array|EE_Base_Class
977
+	 * @throws \EE_Error
978
+	 */
979
+	public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
980
+	{
981
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
982
+			? $this->get_model()->get_primary_key_field()->get_name()
983
+			: $field_to_order_by;
984
+		$current_value = ! empty($field) ? $this->get($field) : null;
985
+		if (empty($field) || empty($current_value)) {
986
+			return array();
987
+		}
988
+		return $this->get_model()->previous($current_value, $field, $query_params, $columns_to_select);
989
+	}
990
+
991
+
992
+
993
+	/**
994
+	 * Overrides parent because parent expects old models.
995
+	 * This also doesn't do any validation, and won't work for serialized arrays
996
+	 *
997
+	 * @param string $field_name
998
+	 * @param mixed  $field_value_from_db
999
+	 * @throws \EE_Error
1000
+	 */
1001
+	public function set_from_db($field_name, $field_value_from_db)
1002
+	{
1003
+		$field_obj = $this->get_model()->field_settings_for($field_name);
1004
+		if ($field_obj instanceof EE_Model_Field_Base) {
1005
+			//you would think the DB has no NULLs for non-null label fields right? wrong!
1006
+			//eg, a CPT model object could have an entry in the posts table, but no
1007
+			//entry in the meta table. Meaning that all its columns in the meta table
1008
+			//are null! yikes! so when we find one like that, use defaults for its meta columns
1009
+			if ($field_value_from_db === null) {
1010
+				if ($field_obj->is_nullable()) {
1011
+					//if the field allows nulls, then let it be null
1012
+					$field_value = null;
1013
+				} else {
1014
+					$field_value = $field_obj->get_default_value();
1015
+				}
1016
+			} else {
1017
+				$field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1018
+			}
1019
+			$this->_fields[$field_name] = $field_value;
1020
+			$this->_clear_cached_property($field_name);
1021
+		}
1022
+	}
1023
+
1024
+
1025
+
1026
+	/**
1027
+	 * verifies that the specified field is of the correct type
1028
+	 *
1029
+	 * @param string $field_name
1030
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1031
+	 *                                (in cases where the same property may be used for different outputs
1032
+	 *                                - i.e. datetime, money etc.)
1033
+	 * @return mixed
1034
+	 * @throws \EE_Error
1035
+	 */
1036
+	public function get($field_name, $extra_cache_ref = null)
1037
+	{
1038
+		return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1039
+	}
1040
+
1041
+
1042
+
1043
+	/**
1044
+	 * This method simply returns the RAW unprocessed value for the given property in this class
1045
+	 *
1046
+	 * @param  string $field_name A valid fieldname
1047
+	 * @return mixed              Whatever the raw value stored on the property is.
1048
+	 * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1049
+	 */
1050
+	public function get_raw($field_name)
1051
+	{
1052
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1053
+		return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1054
+			? $this->_fields[$field_name]->format('U')
1055
+			: $this->_fields[$field_name];
1056
+	}
1057
+
1058
+
1059
+
1060
+	/**
1061
+	 * This is used to return the internal DateTime object used for a field that is a
1062
+	 * EE_Datetime_Field.
1063
+	 *
1064
+	 * @param string $field_name               The field name retrieving the DateTime object.
1065
+	 * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1066
+	 * @throws \EE_Error
1067
+	 *                                         an error is set and false returned.  If the field IS an
1068
+	 *                                         EE_Datetime_Field and but the field value is null, then
1069
+	 *                                         just null is returned (because that indicates that likely
1070
+	 *                                         this field is nullable).
1071
+	 */
1072
+	public function get_DateTime_object($field_name)
1073
+	{
1074
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1075
+		if ( ! $field_settings instanceof EE_Datetime_Field) {
1076
+			EE_Error::add_error(
1077
+				sprintf(
1078
+					__(
1079
+						'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1080
+						'event_espresso'
1081
+					),
1082
+					$field_name
1083
+				),
1084
+				__FILE__,
1085
+				__FUNCTION__,
1086
+				__LINE__
1087
+			);
1088
+			return false;
1089
+		}
1090
+		return $this->_fields[$field_name];
1091
+	}
1092
+
1093
+
1094
+
1095
+	/**
1096
+	 * To be used in template to immediately echo out the value, and format it for output.
1097
+	 * Eg, should call stripslashes and whatnot before echoing
1098
+	 *
1099
+	 * @param string $field_name      the name of the field as it appears in the DB
1100
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1101
+	 *                                (in cases where the same property may be used for different outputs
1102
+	 *                                - i.e. datetime, money etc.)
1103
+	 * @return void
1104
+	 * @throws \EE_Error
1105
+	 */
1106
+	public function e($field_name, $extra_cache_ref = null)
1107
+	{
1108
+		echo $this->get_pretty($field_name, $extra_cache_ref);
1109
+	}
1110
+
1111
+
1112
+
1113
+	/**
1114
+	 * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1115
+	 * can be easily used as the value of form input.
1116
+	 *
1117
+	 * @param string $field_name
1118
+	 * @return void
1119
+	 * @throws \EE_Error
1120
+	 */
1121
+	public function f($field_name)
1122
+	{
1123
+		$this->e($field_name, 'form_input');
1124
+	}
1125
+
1126
+
1127
+
1128
+	/**
1129
+	 * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1130
+	 * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1131
+	 * to see what options are available.
1132
+	 * @param string $field_name
1133
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1134
+	 *                                (in cases where the same property may be used for different outputs
1135
+	 *                                - i.e. datetime, money etc.)
1136
+	 * @return mixed
1137
+	 * @throws \EE_Error
1138
+	 */
1139
+	public function get_pretty($field_name, $extra_cache_ref = null)
1140
+	{
1141
+		return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1142
+	}
1143
+
1144
+
1145
+
1146
+	/**
1147
+	 * This simply returns the datetime for the given field name
1148
+	 * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1149
+	 * (and the equivalent e_date, e_time, e_datetime).
1150
+	 *
1151
+	 * @access   protected
1152
+	 * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1153
+	 * @param string   $dt_frmt      valid datetime format used for date
1154
+	 *                               (if '' then we just use the default on the field,
1155
+	 *                               if NULL we use the last-used format)
1156
+	 * @param string   $tm_frmt      Same as above except this is for time format
1157
+	 * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1158
+	 * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1159
+	 * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1160
+	 *                               if field is not a valid dtt field, or void if echoing
1161
+	 * @throws \EE_Error
1162
+	 */
1163
+	protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1164
+	{
1165
+		// clear cached property
1166
+		$this->_clear_cached_property($field_name);
1167
+		//reset format properties because they are used in get()
1168
+		$this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1169
+		$this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1170
+		if ($echo) {
1171
+			$this->e($field_name, $date_or_time);
1172
+			return '';
1173
+		}
1174
+		return $this->get($field_name, $date_or_time);
1175
+	}
1176
+
1177
+
1178
+
1179
+	/**
1180
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1181
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1182
+	 * other echoes the pretty value for dtt)
1183
+	 *
1184
+	 * @param  string $field_name name of model object datetime field holding the value
1185
+	 * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1186
+	 * @return string            datetime value formatted
1187
+	 * @throws \EE_Error
1188
+	 */
1189
+	public function get_date($field_name, $format = '')
1190
+	{
1191
+		return $this->_get_datetime($field_name, $format, null, 'D');
1192
+	}
1193
+
1194
+
1195
+
1196
+	/**
1197
+	 * @param      $field_name
1198
+	 * @param string $format
1199
+	 * @throws \EE_Error
1200
+	 */
1201
+	public function e_date($field_name, $format = '')
1202
+	{
1203
+		$this->_get_datetime($field_name, $format, null, 'D', true);
1204
+	}
1205
+
1206
+
1207
+
1208
+	/**
1209
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1210
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1211
+	 * other echoes the pretty value for dtt)
1212
+	 *
1213
+	 * @param  string $field_name name of model object datetime field holding the value
1214
+	 * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1215
+	 * @return string             datetime value formatted
1216
+	 * @throws \EE_Error
1217
+	 */
1218
+	public function get_time($field_name, $format = '')
1219
+	{
1220
+		return $this->_get_datetime($field_name, null, $format, 'T');
1221
+	}
1222
+
1223
+
1224
+
1225
+	/**
1226
+	 * @param      $field_name
1227
+	 * @param string $format
1228
+	 * @throws \EE_Error
1229
+	 */
1230
+	public function e_time($field_name, $format = '')
1231
+	{
1232
+		$this->_get_datetime($field_name, null, $format, 'T', true);
1233
+	}
1234
+
1235
+
1236
+
1237
+	/**
1238
+	 * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1239
+	 * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1240
+	 * other echoes the pretty value for dtt)
1241
+	 *
1242
+	 * @param  string $field_name name of model object datetime field holding the value
1243
+	 * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1244
+	 * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1245
+	 * @return string             datetime value formatted
1246
+	 * @throws \EE_Error
1247
+	 */
1248
+	public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1249
+	{
1250
+		return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1251
+	}
1252
+
1253
+
1254
+
1255
+	/**
1256
+	 * @param string $field_name
1257
+	 * @param string $dt_frmt
1258
+	 * @param string $tm_frmt
1259
+	 * @throws \EE_Error
1260
+	 */
1261
+	public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1262
+	{
1263
+		$this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1264
+	}
1265
+
1266
+
1267
+
1268
+	/**
1269
+	 * Get the i8ln value for a date using the WordPress @see date_i18n function.
1270
+	 *
1271
+	 * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1272
+	 * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1273
+	 *                           on the object will be used.
1274
+	 * @return string Date and time string in set locale or false if no field exists for the given
1275
+	 * @throws \EE_Error
1276
+	 *                           field name.
1277
+	 */
1278
+	public function get_i18n_datetime($field_name, $format = '')
1279
+	{
1280
+		$format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1281
+		return date_i18n(
1282
+			$format,
1283
+			EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1284
+		);
1285
+	}
1286
+
1287
+
1288
+
1289
+	/**
1290
+	 * This method validates whether the given field name is a valid field on the model object as well as it is of a
1291
+	 * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1292
+	 * thrown.
1293
+	 *
1294
+	 * @param  string $field_name The field name being checked
1295
+	 * @throws EE_Error
1296
+	 * @return EE_Datetime_Field
1297
+	 */
1298
+	protected function _get_dtt_field_settings($field_name)
1299
+	{
1300
+		$field = $this->get_model()->field_settings_for($field_name);
1301
+		//check if field is dtt
1302
+		if ($field instanceof EE_Datetime_Field) {
1303
+			return $field;
1304
+		} else {
1305
+			throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1306
+				'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1307
+		}
1308
+	}
1309
+
1310
+
1311
+
1312
+
1313
+	/**
1314
+	 * NOTE ABOUT BELOW:
1315
+	 * These convenience date and time setters are for setting date and time independently.  In other words you might
1316
+	 * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1317
+	 * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1318
+	 * method and make sure you send the entire datetime value for setting.
1319
+	 */
1320
+	/**
1321
+	 * sets the time on a datetime property
1322
+	 *
1323
+	 * @access protected
1324
+	 * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1325
+	 * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1326
+	 * @throws \EE_Error
1327
+	 */
1328
+	protected function _set_time_for($time, $fieldname)
1329
+	{
1330
+		$this->_set_date_time('T', $time, $fieldname);
1331
+	}
1332
+
1333
+
1334
+
1335
+	/**
1336
+	 * sets the date on a datetime property
1337
+	 *
1338
+	 * @access protected
1339
+	 * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1340
+	 * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1341
+	 * @throws \EE_Error
1342
+	 */
1343
+	protected function _set_date_for($date, $fieldname)
1344
+	{
1345
+		$this->_set_date_time('D', $date, $fieldname);
1346
+	}
1347
+
1348
+
1349
+
1350
+	/**
1351
+	 * This takes care of setting a date or time independently on a given model object property. This method also
1352
+	 * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1353
+	 *
1354
+	 * @access protected
1355
+	 * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1356
+	 * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1357
+	 * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1358
+	 *                                        EE_Datetime_Field property)
1359
+	 * @throws \EE_Error
1360
+	 */
1361
+	protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1362
+	{
1363
+		$field = $this->_get_dtt_field_settings($fieldname);
1364
+		$field->set_timezone($this->_timezone);
1365
+		$field->set_date_format($this->_dt_frmt);
1366
+		$field->set_time_format($this->_tm_frmt);
1367
+		switch ($what) {
1368
+			case 'T' :
1369
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1370
+					$datetime_value,
1371
+					$this->_fields[$fieldname]
1372
+				);
1373
+				break;
1374
+			case 'D' :
1375
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1376
+					$datetime_value,
1377
+					$this->_fields[$fieldname]
1378
+				);
1379
+				break;
1380
+			case 'B' :
1381
+				$this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1382
+				break;
1383
+		}
1384
+		$this->_clear_cached_property($fieldname);
1385
+	}
1386
+
1387
+
1388
+
1389
+	/**
1390
+	 * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1391
+	 * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1392
+	 * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1393
+	 * that could lead to some unexpected results!
1394
+	 *
1395
+	 * @access public
1396
+	 * @param string               $field_name This is the name of the field on the object that contains the date/time
1397
+	 *                                         value being returned.
1398
+	 * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1399
+	 * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1400
+	 * @param string               $prepend    You can include something to prepend on the timestamp
1401
+	 * @param string               $append     You can include something to append on the timestamp
1402
+	 * @throws EE_Error
1403
+	 * @return string timestamp
1404
+	 */
1405
+	public function display_in_my_timezone(
1406
+		$field_name,
1407
+		$callback = 'get_datetime',
1408
+		$args = null,
1409
+		$prepend = '',
1410
+		$append = ''
1411
+	) {
1412
+		$timezone = EEH_DTT_Helper::get_timezone();
1413
+		if ($timezone === $this->_timezone) {
1414
+			return '';
1415
+		}
1416
+		$original_timezone = $this->_timezone;
1417
+		$this->set_timezone($timezone);
1418
+		$fn = (array)$field_name;
1419
+		$args = array_merge($fn, (array)$args);
1420
+		if ( ! method_exists($this, $callback)) {
1421
+			throw new EE_Error(
1422
+				sprintf(
1423
+					__(
1424
+						'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1425
+						'event_espresso'
1426
+					),
1427
+					$callback
1428
+				)
1429
+			);
1430
+		}
1431
+		$args = (array)$args;
1432
+		$return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1433
+		$this->set_timezone($original_timezone);
1434
+		return $return;
1435
+	}
1436
+
1437
+
1438
+
1439
+	/**
1440
+	 * Deletes this model object.
1441
+	 * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1442
+	 * override
1443
+	 * `EE_Base_Class::_delete` NOT this class.
1444
+	 *
1445
+	 * @return boolean | int
1446
+	 * @throws \EE_Error
1447
+	 */
1448
+	public function delete()
1449
+	{
1450
+		/**
1451
+		 * Called just before the `EE_Base_Class::_delete` method call.
1452
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1453
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1454
+		 * soft deletes (trash) the object and does not permanently delete it.
1455
+		 *
1456
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1457
+		 */
1458
+		do_action('AHEE__EE_Base_Class__delete__before', $this);
1459
+		$result = $this->_delete();
1460
+		/**
1461
+		 * Called just after the `EE_Base_Class::_delete` method call.
1462
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1463
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1464
+		 * soft deletes (trash) the object and does not permanently delete it.
1465
+		 *
1466
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1467
+		 * @param boolean       $result
1468
+		 */
1469
+		do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1470
+		return $result;
1471
+	}
1472
+
1473
+
1474
+
1475
+	/**
1476
+	 * Calls the specific delete method for the instantiated class.
1477
+	 * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1478
+	 * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1479
+	 * `EE_Base_Class::delete`
1480
+	 *
1481
+	 * @return bool|int
1482
+	 * @throws \EE_Error
1483
+	 */
1484
+	protected function _delete()
1485
+	{
1486
+		return $this->delete_permanently();
1487
+	}
1488
+
1489
+
1490
+
1491
+	/**
1492
+	 * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1493
+	 * error)
1494
+	 *
1495
+	 * @return bool | int
1496
+	 * @throws \EE_Error
1497
+	 */
1498
+	public function delete_permanently()
1499
+	{
1500
+		/**
1501
+		 * Called just before HARD deleting a model object
1502
+		 *
1503
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1504
+		 */
1505
+		do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1506
+		$model = $this->get_model();
1507
+		$result = $model->delete_permanently_by_ID($this->ID());
1508
+		$this->refresh_cache_of_related_objects();
1509
+		/**
1510
+		 * Called just after HARD deleting a model object
1511
+		 *
1512
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1513
+		 * @param boolean       $result
1514
+		 */
1515
+		do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1516
+		return $result;
1517
+	}
1518
+
1519
+
1520
+
1521
+	/**
1522
+	 * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1523
+	 * related model objects
1524
+	 *
1525
+	 * @throws \EE_Error
1526
+	 */
1527
+	public function refresh_cache_of_related_objects()
1528
+	{
1529
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1530
+			if ( ! empty($this->_model_relations[$relation_name])) {
1531
+				$related_objects = $this->_model_relations[$relation_name];
1532
+				if ($relation_obj instanceof EE_Belongs_To_Relation) {
1533
+					//this relation only stores a single model object, not an array
1534
+					//but let's make it consistent
1535
+					$related_objects = array($related_objects);
1536
+				}
1537
+				foreach ($related_objects as $related_object) {
1538
+					//only refresh their cache if they're in memory
1539
+					if ($related_object instanceof EE_Base_Class) {
1540
+						$related_object->clear_cache($this->get_model()->get_this_model_name(), $this);
1541
+					}
1542
+				}
1543
+			}
1544
+		}
1545
+	}
1546
+
1547
+
1548
+
1549
+	/**
1550
+	 *        Saves this object to the database. An array may be supplied to set some values on this
1551
+	 * object just before saving.
1552
+	 *
1553
+	 * @access public
1554
+	 * @param array $set_cols_n_values keys are field names, values are their new values,
1555
+	 *                                 if provided during the save() method (often client code will change the fields'
1556
+	 *                                 values before calling save)
1557
+	 * @throws \EE_Error
1558
+	 * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1559
+	 *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1560
+	 */
1561
+	public function save($set_cols_n_values = array())
1562
+	{
1563
+		// no changes ? then don't do anything
1564
+		if ( ! $this->_has_changes && empty($set_cols_n_values) && $this->ID()) {
1565
+			return 0;
1566
+		}
1567
+		/**
1568
+		 * Filters the fields we're about to save on the model object
1569
+		 *
1570
+		 * @param array         $set_cols_n_values
1571
+		 * @param EE_Base_Class $model_object
1572
+		 */
1573
+		$set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1574
+			$this);
1575
+		//set attributes as provided in $set_cols_n_values
1576
+		foreach ($set_cols_n_values as $column => $value) {
1577
+			$this->set($column, $value);
1578
+		}
1579
+		/**
1580
+		 * Saving a model object.
1581
+		 * Before we perform a save, this action is fired.
1582
+		 *
1583
+		 * @param EE_Base_Class $model_object the model object about to be saved.
1584
+		 */
1585
+		do_action('AHEE__EE_Base_Class__save__begin', $this);
1586
+		if ( ! $this->allow_persist()) {
1587
+			return 0;
1588
+		}
1589
+		//now get current attribute values
1590
+		$save_cols_n_values = $this->_fields;
1591
+		//if the object already has an ID, update it. Otherwise, insert it
1592
+		//also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1593
+		$old_assumption_concerning_value_preparation = $this->get_model()
1594
+															->get_assumption_concerning_values_already_prepared_by_model_object();
1595
+		$this->get_model()->assume_values_already_prepared_by_model_object(true);
1596
+		//does this model have an autoincrement PK?
1597
+		if ($this->get_model()->has_primary_key_field()) {
1598
+			if ($this->get_model()->get_primary_key_field()->is_auto_increment()) {
1599
+				//ok check if it's set, if so: update; if not, insert
1600
+				if ( ! empty($save_cols_n_values[self::_get_primary_key_name(get_class($this))])) {
1601
+					$results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1602
+				} else {
1603
+					unset($save_cols_n_values[self::_get_primary_key_name(get_class($this))]);
1604
+					$results = $this->get_model()->insert($save_cols_n_values);
1605
+					if ($results) {
1606
+						//if successful, set the primary key
1607
+						//but don't use the normal SET method, because it will check if
1608
+						//an item with the same ID exists in the mapper & db, then
1609
+						//will find it in the db (because we just added it) and THAT object
1610
+						//will get added to the mapper before we can add this one!
1611
+						//but if we just avoid using the SET method, all that headache can be avoided
1612
+						$pk_field_name = self::_get_primary_key_name(get_class($this));
1613
+						$this->_fields[$pk_field_name] = $results;
1614
+						$this->_clear_cached_property($pk_field_name);
1615
+						$this->get_model()->add_to_entity_map($this);
1616
+						$this->_update_cached_related_model_objs_fks();
1617
+					}
1618
+				}
1619
+			} else {//PK is NOT auto-increment
1620
+				//so check if one like it already exists in the db
1621
+				if ($this->get_model()->exists_by_ID($this->ID())) {
1622
+					if (WP_DEBUG && ! $this->in_entity_map()) {
1623
+						throw new EE_Error(
1624
+							sprintf(
1625
+								__('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1626
+									'event_espresso'),
1627
+								get_class($this),
1628
+								get_class($this->get_model()) . '::instance()->add_to_entity_map()',
1629
+								get_class($this->get_model()) . '::instance()->get_one_by_ID()',
1630
+								'<br />'
1631
+							)
1632
+						);
1633
+					}
1634
+					$results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1635
+				} else {
1636
+					$results = $this->get_model()->insert($save_cols_n_values);
1637
+					$this->_update_cached_related_model_objs_fks();
1638
+				}
1639
+			}
1640
+		} else {//there is NO primary key
1641
+			$already_in_db = false;
1642
+			foreach ($this->get_model()->unique_indexes() as $index) {
1643
+				$uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1644
+				if ($this->get_model()->exists(array($uniqueness_where_params))) {
1645
+					$already_in_db = true;
1646
+				}
1647
+			}
1648
+			if ($already_in_db) {
1649
+				$combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1650
+					$this->get_model()->get_combined_primary_key_fields());
1651
+				$results = $this->get_model()->update($save_cols_n_values, $combined_pk_fields_n_values);
1652
+			} else {
1653
+				$results = $this->get_model()->insert($save_cols_n_values);
1654
+			}
1655
+		}
1656
+		//restore the old assumption about values being prepared by the model object
1657
+		$this->get_model()
1658
+			 ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1659
+		/**
1660
+		 * After saving the model object this action is called
1661
+		 *
1662
+		 * @param EE_Base_Class $model_object which was just saved
1663
+		 * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1664
+		 *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1665
+		 */
1666
+		do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1667
+		return $results;
1668
+	}
1669
+
1670
+
1671
+
1672
+	/**
1673
+	 * Updates the foreign key on related models objects pointing to this to have this model object's ID
1674
+	 * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1675
+	 * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1676
+	 * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1677
+	 * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1678
+	 * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1679
+	 * or not they exist in the DB (if they do, their DB records will be automatically updated)
1680
+	 *
1681
+	 * @return void
1682
+	 * @throws \EE_Error
1683
+	 */
1684
+	protected function _update_cached_related_model_objs_fks()
1685
+	{
1686
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1687
+			if ($relation_obj instanceof EE_Has_Many_Relation) {
1688
+				foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1689
+					$fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1690
+						$this->get_model()->get_this_model_name()
1691
+					);
1692
+					$related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1693
+					if ($related_model_obj_in_cache->ID()) {
1694
+						$related_model_obj_in_cache->save();
1695
+					}
1696
+				}
1697
+			}
1698
+		}
1699
+	}
1700
+
1701
+
1702
+
1703
+	/**
1704
+	 * Saves this model object and its NEW cached relations to the database.
1705
+	 * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1706
+	 * In order for that to work, we would need to mark model objects as dirty/clean...
1707
+	 * because otherwise, there's a potential for infinite looping of saving
1708
+	 * Saves the cached related model objects, and ensures the relation between them
1709
+	 * and this object and properly setup
1710
+	 *
1711
+	 * @return int ID of new model object on save; 0 on failure+
1712
+	 * @throws \EE_Error
1713
+	 */
1714
+	public function save_new_cached_related_model_objs()
1715
+	{
1716
+		//make sure this has been saved
1717
+		if ( ! $this->ID()) {
1718
+			$id = $this->save();
1719
+		} else {
1720
+			$id = $this->ID();
1721
+		}
1722
+		//now save all the NEW cached model objects  (ie they don't exist in the DB)
1723
+		foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1724
+			if ($this->_model_relations[$relationName]) {
1725
+				//is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1726
+				//or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1727
+				if ($relationObj instanceof EE_Belongs_To_Relation) {
1728
+					//add a relation to that relation type (which saves the appropriate thing in the process)
1729
+					//but ONLY if it DOES NOT exist in the DB
1730
+					/* @var $related_model_obj EE_Base_Class */
1731
+					$related_model_obj = $this->_model_relations[$relationName];
1732
+					//					if( ! $related_model_obj->ID()){
1733
+					$this->_add_relation_to($related_model_obj, $relationName);
1734
+					$related_model_obj->save_new_cached_related_model_objs();
1735
+					//					}
1736
+				} else {
1737
+					foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1738
+						//add a relation to that relation type (which saves the appropriate thing in the process)
1739
+						//but ONLY if it DOES NOT exist in the DB
1740
+						//						if( ! $related_model_obj->ID()){
1741
+						$this->_add_relation_to($related_model_obj, $relationName);
1742
+						$related_model_obj->save_new_cached_related_model_objs();
1743
+						//						}
1744
+					}
1745
+				}
1746
+			}
1747
+		}
1748
+		return $id;
1749
+	}
1750
+
1751
+
1752
+
1753
+	/**
1754
+	 * for getting a model while instantiated.
1755
+	 *
1756
+	 * @return \EEM_Base | \EEM_CPT_Base
1757
+	 */
1758
+	public function get_model()
1759
+	{
1760
+		$modelName = self::_get_model_classname(get_class($this));
1761
+		return self::_get_model_instance_with_name($modelName, $this->_timezone);
1762
+	}
1763
+
1764
+
1765
+
1766
+	/**
1767
+	 * @param $props_n_values
1768
+	 * @param $classname
1769
+	 * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1770
+	 * @throws \EE_Error
1771
+	 */
1772
+	protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1773
+	{
1774
+		//TODO: will not work for Term_Relationships because they have no PK!
1775
+		$primary_id_ref = self::_get_primary_key_name($classname);
1776
+		if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1777
+			$id = $props_n_values[$primary_id_ref];
1778
+			return self::_get_model($classname)->get_from_entity_map($id);
1779
+		}
1780
+		return false;
1781
+	}
1782
+
1783
+
1784
+
1785
+	/**
1786
+	 * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1787
+	 * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1788
+	 * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1789
+	 * we return false.
1790
+	 *
1791
+	 * @param  array  $props_n_values   incoming array of properties and their values
1792
+	 * @param  string $classname        the classname of the child class
1793
+	 * @param null    $timezone
1794
+	 * @param array   $date_formats     incoming date_formats in an array where the first value is the
1795
+	 *                                  date_format and the second value is the time format
1796
+	 * @return mixed (EE_Base_Class|bool)
1797
+	 * @throws \EE_Error
1798
+	 */
1799
+	protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1800
+	{
1801
+		$existing = null;
1802
+		if (self::_get_model($classname)->has_primary_key_field()) {
1803
+			$primary_id_ref = self::_get_primary_key_name($classname);
1804
+			if (array_key_exists($primary_id_ref, $props_n_values)
1805
+				&& ! empty($props_n_values[$primary_id_ref])
1806
+			) {
1807
+				$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1808
+					$props_n_values[$primary_id_ref]
1809
+				);
1810
+			}
1811
+		} elseif (self::_get_model($classname, $timezone)->has_all_combined_primary_key_fields($props_n_values)) {
1812
+			//no primary key on this model, but there's still a matching item in the DB
1813
+			$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1814
+				self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1815
+			);
1816
+		}
1817
+		if ($existing) {
1818
+			//set date formats if present before setting values
1819
+			if ( ! empty($date_formats) && is_array($date_formats)) {
1820
+				$existing->set_date_format($date_formats[0]);
1821
+				$existing->set_time_format($date_formats[1]);
1822
+			} else {
1823
+				//set default formats for date and time
1824
+				$existing->set_date_format(get_option('date_format'));
1825
+				$existing->set_time_format(get_option('time_format'));
1826
+			}
1827
+			foreach ($props_n_values as $property => $field_value) {
1828
+				$existing->set($property, $field_value);
1829
+			}
1830
+			return $existing;
1831
+		} else {
1832
+			return false;
1833
+		}
1834
+	}
1835
+
1836
+
1837
+
1838
+	/**
1839
+	 * Gets the EEM_*_Model for this class
1840
+	 *
1841
+	 * @access public now, as this is more convenient
1842
+	 * @param      $classname
1843
+	 * @param null $timezone
1844
+	 * @throws EE_Error
1845
+	 * @return EEM_Base
1846
+	 */
1847
+	protected static function _get_model($classname, $timezone = null)
1848
+	{
1849
+		//find model for this class
1850
+		if ( ! $classname) {
1851
+			throw new EE_Error(
1852
+				sprintf(
1853
+					__(
1854
+						"What were you thinking calling _get_model(%s)?? You need to specify the class name",
1855
+						"event_espresso"
1856
+					),
1857
+					$classname
1858
+				)
1859
+			);
1860
+		}
1861
+		$modelName = self::_get_model_classname($classname);
1862
+		return self::_get_model_instance_with_name($modelName, $timezone);
1863
+	}
1864
+
1865
+
1866
+
1867
+	/**
1868
+	 * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1869
+	 *
1870
+	 * @param string $model_classname
1871
+	 * @param null   $timezone
1872
+	 * @return EEM_Base
1873
+	 */
1874
+	protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1875
+	{
1876
+		$model_classname = str_replace('EEM_', '', $model_classname);
1877
+		$model = EE_Registry::instance()->load_model($model_classname);
1878
+		$model->set_timezone($timezone);
1879
+		return $model;
1880
+	}
1881
+
1882
+
1883
+
1884
+	/**
1885
+	 * If a model name is provided (eg Registration), gets the model classname for that model.
1886
+	 * Also works if a model class's classname is provided (eg EE_Registration).
1887
+	 *
1888
+	 * @param null $model_name
1889
+	 * @return string like EEM_Attendee
1890
+	 */
1891
+	private static function _get_model_classname($model_name = null)
1892
+	{
1893
+		if (strpos($model_name, "EE_") === 0) {
1894
+			$model_classname = str_replace("EE_", "EEM_", $model_name);
1895
+		} else {
1896
+			$model_classname = "EEM_" . $model_name;
1897
+		}
1898
+		return $model_classname;
1899
+	}
1900
+
1901
+
1902
+
1903
+	/**
1904
+	 * returns the name of the primary key attribute
1905
+	 *
1906
+	 * @param null $classname
1907
+	 * @throws EE_Error
1908
+	 * @return string
1909
+	 */
1910
+	protected static function _get_primary_key_name($classname = null)
1911
+	{
1912
+		if ( ! $classname) {
1913
+			throw new EE_Error(
1914
+				sprintf(
1915
+					__("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1916
+					$classname
1917
+				)
1918
+			);
1919
+		}
1920
+		return self::_get_model($classname)->get_primary_key_field()->get_name();
1921
+	}
1922
+
1923
+
1924
+
1925
+	/**
1926
+	 * Gets the value of the primary key.
1927
+	 * If the object hasn't yet been saved, it should be whatever the model field's default was
1928
+	 * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
1929
+	 * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
1930
+	 *
1931
+	 * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
1932
+	 * @throws \EE_Error
1933
+	 */
1934
+	public function ID()
1935
+	{
1936
+		//now that we know the name of the variable, use a variable variable to get its value and return its
1937
+		if ($this->get_model()->has_primary_key_field()) {
1938
+			return $this->_fields[self::_get_primary_key_name(get_class($this))];
1939
+		} else {
1940
+			return $this->get_model()->get_index_primary_key_string($this->_fields);
1941
+		}
1942
+	}
1943
+
1944
+
1945
+
1946
+	/**
1947
+	 * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
1948
+	 * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
1949
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
1950
+	 *
1951
+	 * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
1952
+	 * @param string $relationName                     eg 'Events','Question',etc.
1953
+	 *                                                 an attendee to a group, you also want to specify which role they
1954
+	 *                                                 will have in that group. So you would use this parameter to
1955
+	 *                                                 specify array('role-column-name'=>'role-id')
1956
+	 * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
1957
+	 *                                                 allow you to further constrict the relation to being added.
1958
+	 *                                                 However, keep in mind that the columns (keys) given must match a
1959
+	 *                                                 column on the JOIN table and currently only the HABTM models
1960
+	 *                                                 accept these additional conditions.  Also remember that if an
1961
+	 *                                                 exact match isn't found for these extra cols/val pairs, then a
1962
+	 *                                                 NEW row is created in the join table.
1963
+	 * @param null   $cache_id
1964
+	 * @throws EE_Error
1965
+	 * @return EE_Base_Class the object the relation was added to
1966
+	 */
1967
+	public function _add_relation_to(
1968
+		$otherObjectModelObjectOrID,
1969
+		$relationName,
1970
+		$extra_join_model_fields_n_values = array(),
1971
+		$cache_id = null
1972
+	) {
1973
+		//if this thing exists in the DB, save the relation to the DB
1974
+		if ($this->ID()) {
1975
+			$otherObject = $this->get_model()
1976
+								->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
1977
+									$extra_join_model_fields_n_values);
1978
+			//clear cache so future get_many_related and get_first_related() return new results.
1979
+			$this->clear_cache($relationName, $otherObject, true);
1980
+			if ($otherObject instanceof EE_Base_Class) {
1981
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
1982
+			}
1983
+		} else {
1984
+			//this thing doesn't exist in the DB,  so just cache it
1985
+			if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
1986
+				throw new EE_Error(sprintf(
1987
+					__('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
1988
+						'event_espresso'),
1989
+					$otherObjectModelObjectOrID,
1990
+					get_class($this)
1991
+				));
1992
+			} else {
1993
+				$otherObject = $otherObjectModelObjectOrID;
1994
+			}
1995
+			$this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
1996
+		}
1997
+		if ($otherObject instanceof EE_Base_Class) {
1998
+			//fix the reciprocal relation too
1999
+			if ($otherObject->ID()) {
2000
+				//its saved so assumed relations exist in the DB, so we can just
2001
+				//clear the cache so future queries use the updated info in the DB
2002
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), null, true);
2003
+			} else {
2004
+				//it's not saved, so it caches relations like this
2005
+				$otherObject->cache($this->get_model()->get_this_model_name(), $this);
2006
+			}
2007
+		}
2008
+		return $otherObject;
2009
+	}
2010
+
2011
+
2012
+
2013
+	/**
2014
+	 * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2015
+	 * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2016
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2017
+	 * from the cache
2018
+	 *
2019
+	 * @param mixed  $otherObjectModelObjectOrID
2020
+	 *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2021
+	 *                to the DB yet
2022
+	 * @param string $relationName
2023
+	 * @param array  $where_query
2024
+	 *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2025
+	 *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2026
+	 *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2027
+	 *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2028
+	 *                created in the join table.
2029
+	 * @return EE_Base_Class the relation was removed from
2030
+	 * @throws \EE_Error
2031
+	 */
2032
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2033
+	{
2034
+		if ($this->ID()) {
2035
+			//if this exists in the DB, save the relation change to the DB too
2036
+			$otherObject = $this->get_model()
2037
+								->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2038
+									$where_query);
2039
+			$this->clear_cache($relationName, $otherObject);
2040
+		} else {
2041
+			//this doesn't exist in the DB, just remove it from the cache
2042
+			$otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2043
+		}
2044
+		if ($otherObject instanceof EE_Base_Class) {
2045
+			$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2046
+		}
2047
+		return $otherObject;
2048
+	}
2049
+
2050
+
2051
+
2052
+	/**
2053
+	 * Removes ALL the related things for the $relationName.
2054
+	 *
2055
+	 * @param string $relationName
2056
+	 * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2057
+	 * @return EE_Base_Class
2058
+	 * @throws \EE_Error
2059
+	 */
2060
+	public function _remove_relations($relationName, $where_query_params = array())
2061
+	{
2062
+		if ($this->ID()) {
2063
+			//if this exists in the DB, save the relation change to the DB too
2064
+			$otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2065
+			$this->clear_cache($relationName, null, true);
2066
+		} else {
2067
+			//this doesn't exist in the DB, just remove it from the cache
2068
+			$otherObjects = $this->clear_cache($relationName, null, true);
2069
+		}
2070
+		if (is_array($otherObjects)) {
2071
+			foreach ($otherObjects as $otherObject) {
2072
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2073
+			}
2074
+		}
2075
+		return $otherObjects;
2076
+	}
2077
+
2078
+
2079
+
2080
+	/**
2081
+	 * Gets all the related model objects of the specified type. Eg, if the current class if
2082
+	 * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2083
+	 * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2084
+	 * because we want to get even deleted items etc.
2085
+	 *
2086
+	 * @param string $relationName key in the model's _model_relations array
2087
+	 * @param array  $query_params like EEM_Base::get_all
2088
+	 * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2089
+	 * @throws \EE_Error
2090
+	 *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2091
+	 *                             you want IDs
2092
+	 */
2093
+	public function get_many_related($relationName, $query_params = array())
2094
+	{
2095
+		if ($this->ID()) {
2096
+			//this exists in the DB, so get the related things from either the cache or the DB
2097
+			//if there are query parameters, forget about caching the related model objects.
2098
+			if ($query_params) {
2099
+				$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2100
+			} else {
2101
+				//did we already cache the result of this query?
2102
+				$cached_results = $this->get_all_from_cache($relationName);
2103
+				if ( ! $cached_results) {
2104
+					$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2105
+					//if no query parameters were passed, then we got all the related model objects
2106
+					//for that relation. We can cache them then.
2107
+					foreach ($related_model_objects as $related_model_object) {
2108
+						$this->cache($relationName, $related_model_object);
2109
+					}
2110
+				} else {
2111
+					$related_model_objects = $cached_results;
2112
+				}
2113
+			}
2114
+		} else {
2115
+			//this doesn't exist in the DB, so just get the related things from the cache
2116
+			$related_model_objects = $this->get_all_from_cache($relationName);
2117
+		}
2118
+		return $related_model_objects;
2119
+	}
2120
+
2121
+
2122
+
2123
+	/**
2124
+	 * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2125
+	 * unless otherwise specified in the $query_params
2126
+	 *
2127
+	 * @param string $relation_name  model_name like 'Event', or 'Registration'
2128
+	 * @param array  $query_params   like EEM_Base::get_all's
2129
+	 * @param string $field_to_count name of field to count by. By default, uses primary key
2130
+	 * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2131
+	 *                               that by the setting $distinct to TRUE;
2132
+	 * @return int
2133
+	 */
2134
+	public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2135
+	{
2136
+		return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2137
+	}
2138
+
2139
+
2140
+
2141
+	/**
2142
+	 * Instead of getting the related model objects, simply sums up the values of the specified field.
2143
+	 * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2144
+	 *
2145
+	 * @param string $relation_name model_name like 'Event', or 'Registration'
2146
+	 * @param array  $query_params  like EEM_Base::get_all's
2147
+	 * @param string $field_to_sum  name of field to count by.
2148
+	 *                              By default, uses primary key (which doesn't make much sense, so you should probably
2149
+	 *                              change it)
2150
+	 * @return int
2151
+	 */
2152
+	public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2153
+	{
2154
+		return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2155
+	}
2156
+
2157
+
2158
+
2159
+	/**
2160
+	 * Gets the first (ie, one) related model object of the specified type.
2161
+	 *
2162
+	 * @param string $relationName key in the model's _model_relations array
2163
+	 * @param array  $query_params like EEM_Base::get_all
2164
+	 * @return EE_Base_Class (not an array, a single object)
2165
+	 * @throws \EE_Error
2166
+	 */
2167
+	public function get_first_related($relationName, $query_params = array())
2168
+	{
2169
+		if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2170
+			//if they've provided some query parameters, don't bother trying to cache the result
2171
+			//also make sure we're not caching the result of get_first_related
2172
+			//on a relation which should have an array of objects (because the cache might have an array of objects)
2173
+			if ($query_params
2174
+				|| ! $this->get_model()->related_settings_for($relationName)
2175
+					 instanceof
2176
+					 EE_Belongs_To_Relation
2177
+			) {
2178
+				$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2179
+			} else {
2180
+				//first, check if we've already cached the result of this query
2181
+				$cached_result = $this->get_one_from_cache($relationName);
2182
+				if ( ! $cached_result) {
2183
+					$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2184
+					$this->cache($relationName, $related_model_object);
2185
+				} else {
2186
+					$related_model_object = $cached_result;
2187
+				}
2188
+			}
2189
+		} else {
2190
+			$related_model_object = null;
2191
+			//this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2192
+			if ($this->get_model()->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2193
+				$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2194
+			}
2195
+			//this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2196
+			if ( ! $related_model_object) {
2197
+				$related_model_object = $this->get_one_from_cache($relationName);
2198
+			}
2199
+		}
2200
+		return $related_model_object;
2201
+	}
2202
+
2203
+
2204
+
2205
+	/**
2206
+	 * Does a delete on all related objects of type $relationName and removes
2207
+	 * the current model object's relation to them. If they can't be deleted (because
2208
+	 * of blocking related model objects) does nothing. If the related model objects are
2209
+	 * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2210
+	 * If this model object doesn't exist yet in the DB, just removes its related things
2211
+	 *
2212
+	 * @param string $relationName
2213
+	 * @param array  $query_params like EEM_Base::get_all's
2214
+	 * @return int how many deleted
2215
+	 * @throws \EE_Error
2216
+	 */
2217
+	public function delete_related($relationName, $query_params = array())
2218
+	{
2219
+		if ($this->ID()) {
2220
+			$count = $this->get_model()->delete_related($this, $relationName, $query_params);
2221
+		} else {
2222
+			$count = count($this->get_all_from_cache($relationName));
2223
+			$this->clear_cache($relationName, null, true);
2224
+		}
2225
+		return $count;
2226
+	}
2227
+
2228
+
2229
+
2230
+	/**
2231
+	 * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2232
+	 * the current model object's relation to them. If they can't be deleted (because
2233
+	 * of blocking related model objects) just does a soft delete on it instead, if possible.
2234
+	 * If the related thing isn't a soft-deletable model object, this function is identical
2235
+	 * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2236
+	 *
2237
+	 * @param string $relationName
2238
+	 * @param array  $query_params like EEM_Base::get_all's
2239
+	 * @return int how many deleted (including those soft deleted)
2240
+	 * @throws \EE_Error
2241
+	 */
2242
+	public function delete_related_permanently($relationName, $query_params = array())
2243
+	{
2244
+		if ($this->ID()) {
2245
+			$count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2246
+		} else {
2247
+			$count = count($this->get_all_from_cache($relationName));
2248
+		}
2249
+		$this->clear_cache($relationName, null, true);
2250
+		return $count;
2251
+	}
2252
+
2253
+
2254
+
2255
+	/**
2256
+	 * is_set
2257
+	 * Just a simple utility function children can use for checking if property exists
2258
+	 *
2259
+	 * @access  public
2260
+	 * @param  string $field_name property to check
2261
+	 * @return bool                              TRUE if existing,FALSE if not.
2262
+	 */
2263
+	public function is_set($field_name)
2264
+	{
2265
+		return isset($this->_fields[$field_name]);
2266
+	}
2267
+
2268
+
2269
+
2270
+	/**
2271
+	 * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2272
+	 * EE_Error exception if they don't
2273
+	 *
2274
+	 * @param  mixed (string|array) $properties properties to check
2275
+	 * @throws EE_Error
2276
+	 * @return bool                              TRUE if existing, throw EE_Error if not.
2277
+	 */
2278
+	protected function _property_exists($properties)
2279
+	{
2280
+		foreach ((array)$properties as $property_name) {
2281
+			//first make sure this property exists
2282
+			if ( ! $this->_fields[$property_name]) {
2283
+				throw new EE_Error(
2284
+					sprintf(
2285
+						__(
2286
+							'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2287
+							'event_espresso'
2288
+						),
2289
+						$property_name
2290
+					)
2291
+				);
2292
+			}
2293
+		}
2294
+		return true;
2295
+	}
2296
+
2297
+
2298
+
2299
+	/**
2300
+	 * This simply returns an array of model fields for this object
2301
+	 *
2302
+	 * @return array
2303
+	 * @throws \EE_Error
2304
+	 */
2305
+	public function model_field_array()
2306
+	{
2307
+		$fields = $this->get_model()->field_settings(false);
2308
+		$properties = array();
2309
+		//remove prepended underscore
2310
+		foreach ($fields as $field_name => $settings) {
2311
+			$properties[$field_name] = $this->get($field_name);
2312
+		}
2313
+		return $properties;
2314
+	}
2315
+
2316
+
2317
+
2318
+	/**
2319
+	 * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2320
+	 * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2321
+	 * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2322
+	 * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2323
+	 * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2324
+	 * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2325
+	 * was called, and an array of the original arguments passed to the function. Whatever their callback function
2326
+	 * returns will be returned by this function. Example: in functions.php (or in a plugin):
2327
+	 * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2328
+	 * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2329
+	 * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2330
+	 *        return $previousReturnValue.$returnString;
2331
+	 * }
2332
+	 * require('EE_Answer.class.php');
2333
+	 * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2334
+	 * echo $answer->my_callback('monkeys',100);
2335
+	 * //will output "you called my_callback! and passed args:monkeys,100"
2336
+	 *
2337
+	 * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2338
+	 * @param array  $args       array of original arguments passed to the function
2339
+	 * @throws EE_Error
2340
+	 * @return mixed whatever the plugin which calls add_filter decides
2341
+	 */
2342
+	public function __call($methodName, $args)
2343
+	{
2344
+		$className = get_class($this);
2345
+		$tagName = "FHEE__{$className}__{$methodName}";
2346
+		if ( ! has_filter($tagName)) {
2347
+			throw new EE_Error(
2348
+				sprintf(
2349
+					__(
2350
+						"Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2351
+						"event_espresso"
2352
+					),
2353
+					$methodName,
2354
+					$className,
2355
+					$tagName
2356
+				)
2357
+			);
2358
+		}
2359
+		return apply_filters($tagName, null, $this, $args);
2360
+	}
2361
+
2362
+
2363
+
2364
+	/**
2365
+	 * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2366
+	 * A $previous_value can be specified in case there are many meta rows with the same key
2367
+	 *
2368
+	 * @param string $meta_key
2369
+	 * @param mixed  $meta_value
2370
+	 * @param mixed  $previous_value
2371
+	 * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2372
+	 * @throws \EE_Error
2373
+	 * NOTE: if the values haven't changed, returns 0
2374
+	 */
2375
+	public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2376
+	{
2377
+		$query_params = array(
2378
+			array(
2379
+				'EXM_key'  => $meta_key,
2380
+				'OBJ_ID'   => $this->ID(),
2381
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2382
+			),
2383
+		);
2384
+		if ($previous_value !== null) {
2385
+			$query_params[0]['EXM_value'] = $meta_value;
2386
+		}
2387
+		$existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2388
+		if ( ! $existing_rows_like_that) {
2389
+			return $this->add_extra_meta($meta_key, $meta_value);
2390
+		}
2391
+		foreach ($existing_rows_like_that as $existing_row) {
2392
+			$existing_row->save(array('EXM_value' => $meta_value));
2393
+		}
2394
+		return count($existing_rows_like_that);
2395
+	}
2396
+
2397
+
2398
+
2399
+	/**
2400
+	 * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2401
+	 * no other extra meta for this model object have the same key. Returns TRUE if the
2402
+	 * extra meta row was entered, false if not
2403
+	 *
2404
+	 * @param string  $meta_key
2405
+	 * @param string  $meta_value
2406
+	 * @param boolean $unique
2407
+	 * @return boolean
2408
+	 * @throws \EE_Error
2409
+	 */
2410
+	public function add_extra_meta($meta_key, $meta_value, $unique = false)
2411
+	{
2412
+		if ($unique) {
2413
+			$existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2414
+				array(
2415
+					array(
2416
+						'EXM_key'  => $meta_key,
2417
+						'OBJ_ID'   => $this->ID(),
2418
+						'EXM_type' => $this->get_model()->get_this_model_name(),
2419
+					),
2420
+				)
2421
+			);
2422
+			if ($existing_extra_meta) {
2423
+				return false;
2424
+			}
2425
+		}
2426
+		$new_extra_meta = EE_Extra_Meta::new_instance(
2427
+			array(
2428
+				'EXM_key'   => $meta_key,
2429
+				'EXM_value' => $meta_value,
2430
+				'OBJ_ID'    => $this->ID(),
2431
+				'EXM_type'  => $this->get_model()->get_this_model_name(),
2432
+			)
2433
+		);
2434
+		$new_extra_meta->save();
2435
+		return true;
2436
+	}
2437
+
2438
+
2439
+
2440
+	/**
2441
+	 * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2442
+	 * is specified, only deletes extra meta records with that value.
2443
+	 *
2444
+	 * @param string $meta_key
2445
+	 * @param string $meta_value
2446
+	 * @return int number of extra meta rows deleted
2447
+	 * @throws \EE_Error
2448
+	 */
2449
+	public function delete_extra_meta($meta_key, $meta_value = null)
2450
+	{
2451
+		$query_params = array(
2452
+			array(
2453
+				'EXM_key'  => $meta_key,
2454
+				'OBJ_ID'   => $this->ID(),
2455
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2456
+			),
2457
+		);
2458
+		if ($meta_value !== null) {
2459
+			$query_params[0]['EXM_value'] = $meta_value;
2460
+		}
2461
+		return EEM_Extra_Meta::instance()->delete($query_params);
2462
+	}
2463
+
2464
+
2465
+
2466
+	/**
2467
+	 * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2468
+	 * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2469
+	 * You can specify $default is case you haven't found the extra meta
2470
+	 *
2471
+	 * @param string  $meta_key
2472
+	 * @param boolean $single
2473
+	 * @param mixed   $default if we don't find anything, what should we return?
2474
+	 * @return mixed single value if $single; array if ! $single
2475
+	 * @throws \EE_Error
2476
+	 */
2477
+	public function get_extra_meta($meta_key, $single = false, $default = null)
2478
+	{
2479
+		if ($single) {
2480
+			$result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2481
+			if ($result instanceof EE_Extra_Meta) {
2482
+				return $result->value();
2483
+			} else {
2484
+				return $default;
2485
+			}
2486
+		} else {
2487
+			$results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2488
+			if ($results) {
2489
+				$values = array();
2490
+				foreach ($results as $result) {
2491
+					if ($result instanceof EE_Extra_Meta) {
2492
+						$values[$result->ID()] = $result->value();
2493
+					}
2494
+				}
2495
+				return $values;
2496
+			} else {
2497
+				return $default;
2498
+			}
2499
+		}
2500
+	}
2501
+
2502
+
2503
+
2504
+	/**
2505
+	 * Returns a simple array of all the extra meta associated with this model object.
2506
+	 * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2507
+	 * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2508
+	 * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2509
+	 * If $one_of_each_key is false, it will return an array with the top-level keys being
2510
+	 * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2511
+	 * finally the extra meta's value as each sub-value. (eg
2512
+	 * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2513
+	 *
2514
+	 * @param boolean $one_of_each_key
2515
+	 * @return array
2516
+	 * @throws \EE_Error
2517
+	 */
2518
+	public function all_extra_meta_array($one_of_each_key = true)
2519
+	{
2520
+		$return_array = array();
2521
+		if ($one_of_each_key) {
2522
+			$extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2523
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2524
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2525
+					$return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2526
+				}
2527
+			}
2528
+		} else {
2529
+			$extra_meta_objs = $this->get_many_related('Extra_Meta');
2530
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2531
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2532
+					if ( ! isset($return_array[$extra_meta_obj->key()])) {
2533
+						$return_array[$extra_meta_obj->key()] = array();
2534
+					}
2535
+					$return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2536
+				}
2537
+			}
2538
+		}
2539
+		return $return_array;
2540
+	}
2541
+
2542
+
2543
+
2544
+	/**
2545
+	 * Gets a pretty nice displayable nice for this model object. Often overridden
2546
+	 *
2547
+	 * @return string
2548
+	 * @throws \EE_Error
2549
+	 */
2550
+	public function name()
2551
+	{
2552
+		//find a field that's not a text field
2553
+		$field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2554
+		if ($field_we_can_use) {
2555
+			return $this->get($field_we_can_use->get_name());
2556
+		} else {
2557
+			$first_few_properties = $this->model_field_array();
2558
+			$first_few_properties = array_slice($first_few_properties, 0, 3);
2559
+			$name_parts = array();
2560
+			foreach ($first_few_properties as $name => $value) {
2561
+				$name_parts[] = "$name:$value";
2562
+			}
2563
+			return implode(",", $name_parts);
2564
+		}
2565
+	}
2566
+
2567
+
2568
+
2569
+	/**
2570
+	 * in_entity_map
2571
+	 * Checks if this model object has been proven to already be in the entity map
2572
+	 *
2573
+	 * @return boolean
2574
+	 * @throws \EE_Error
2575
+	 */
2576
+	public function in_entity_map()
2577
+	{
2578
+		if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2579
+			//well, if we looked, did we find it in the entity map?
2580
+			return true;
2581
+		} else {
2582
+			return false;
2583
+		}
2584
+	}
2585
+
2586
+
2587
+
2588
+	/**
2589
+	 * refresh_from_db
2590
+	 * Makes sure the fields and values on this model object are in-sync with what's in the database.
2591
+	 *
2592
+	 * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2593
+	 * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2594
+	 */
2595
+	public function refresh_from_db()
2596
+	{
2597
+		if ($this->ID() && $this->in_entity_map()) {
2598
+			$this->get_model()->refresh_entity_map_from_db($this->ID());
2599
+		} else {
2600
+			//if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2601
+			//if it has an ID but it's not in the map, and you're asking me to refresh it
2602
+			//that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2603
+			//absolutely nothing in it for this ID
2604
+			if (WP_DEBUG) {
2605
+				throw new EE_Error(
2606
+					sprintf(
2607
+						__('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2608
+							'event_espresso'),
2609
+						$this->ID(),
2610
+						get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2611
+						get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2612
+					)
2613
+				);
2614
+			}
2615
+		}
2616
+	}
2617
+
2618
+
2619
+
2620
+	/**
2621
+	 * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2622
+	 * (probably a bad assumption they have made, oh well)
2623
+	 *
2624
+	 * @return string
2625
+	 */
2626
+	public function __toString()
2627
+	{
2628
+		try {
2629
+			return sprintf('%s (%s)', $this->name(), $this->ID());
2630
+		} catch (Exception $e) {
2631
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2632
+			return '';
2633
+		}
2634
+	}
2635
+
2636
+
2637
+
2638
+	/**
2639
+	 * Clear related model objects if they're already in the DB, because otherwise when we
2640
+	 * UN-serialize this model object we'll need to be careful to add them to the entity map.
2641
+	 * This means if we have made changes to those related model objects, and want to unserialize
2642
+	 * the this model object on a subsequent request, changes to those related model objects will be lost.
2643
+	 * Instead, those related model objects should be directly serialized and stored.
2644
+	 * Eg, the following won't work:
2645
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2646
+	 * $att = $reg->attendee();
2647
+	 * $att->set( 'ATT_fname', 'Dirk' );
2648
+	 * update_option( 'my_option', serialize( $reg ) );
2649
+	 * //END REQUEST
2650
+	 * //START NEXT REQUEST
2651
+	 * $reg = get_option( 'my_option' );
2652
+	 * $reg->attendee()->save();
2653
+	 * And would need to be replace with:
2654
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2655
+	 * $att = $reg->attendee();
2656
+	 * $att->set( 'ATT_fname', 'Dirk' );
2657
+	 * update_option( 'my_option', serialize( $reg ) );
2658
+	 * //END REQUEST
2659
+	 * //START NEXT REQUEST
2660
+	 * $att = get_option( 'my_option' );
2661
+	 * $att->save();
2662
+	 *
2663
+	 * @return array
2664
+	 * @throws \EE_Error
2665
+	 */
2666
+	public function __sleep()
2667
+	{
2668
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
2669
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
2670
+				$classname = 'EE_' . $this->get_model()->get_this_model_name();
2671
+				if (
2672
+					$this->get_one_from_cache($relation_name) instanceof $classname
2673
+					&& $this->get_one_from_cache($relation_name)->ID()
2674
+				) {
2675
+					$this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2676
+				}
2677
+			}
2678
+		}
2679
+		$this->_props_n_values_provided_in_constructor = array();
2680
+		return array_keys(get_object_vars($this));
2681
+	}
2682
+
2683
+
2684
+
2685
+	/**
2686
+	 * restore _props_n_values_provided_in_constructor
2687
+	 * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2688
+	 * and therefore should NOT be used to determine if state change has occurred since initial construction.
2689
+	 * At best, you would only be able to detect if state change has occurred during THIS request.
2690
+	 */
2691
+	public function __wakeup()
2692
+	{
2693
+		$this->_props_n_values_provided_in_constructor = $this->_fields;
2694
+	}
2695 2695
 
2696 2696
 
2697 2697
 
Please login to merge, or discard this patch.
core/EE_Dependency_Map.core.php 2 patches
Indentation   +597 added lines, -597 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 use EventEspresso\core\services\loaders\LoaderInterface;
5 5
 
6 6
 if (! defined('EVENT_ESPRESSO_VERSION')) {
7
-    exit('No direct script access allowed');
7
+	exit('No direct script access allowed');
8 8
 }
9 9
 
10 10
 
@@ -22,602 +22,602 @@  discard block
 block discarded – undo
22 22
 {
23 23
 
24 24
 
25
-    /**
26
-     * This means that the requested class dependency is not present in the dependency map
27
-     */
28
-    const not_registered = 0;
29
-
30
-
31
-    /**
32
-     * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
33
-     */
34
-    const load_new_object = 1;
35
-
36
-    /**
37
-     * This instructs class loaders to return a previously instantiated and cached object for the requested class.
38
-     * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
39
-     */
40
-    const load_from_cache = 2;
41
-
42
-    /**
43
-     * @type EE_Dependency_Map $_instance
44
-     */
45
-    protected static $_instance;
46
-
47
-    /**
48
-     * @type EE_Request $request
49
-     */
50
-    protected $_request;
51
-
52
-    /**
53
-     * @type EE_Response $response
54
-     */
55
-    protected $_response;
56
-
57
-    /**
58
-     * @type LoaderInterface $loader
59
-     */
60
-    protected $loader;
61
-
62
-    /**
63
-     * @type array $_dependency_map
64
-     */
65
-    protected $_dependency_map = array();
66
-
67
-    /**
68
-     * @type array $_class_loaders
69
-     */
70
-    protected $_class_loaders = array();
71
-
72
-    /**
73
-     * @type array $_aliases
74
-     */
75
-    protected $_aliases = array();
76
-
77
-
78
-
79
-    /**
80
-     * EE_Dependency_Map constructor.
81
-     *
82
-     * @param EE_Request  $request
83
-     * @param EE_Response $response
84
-     */
85
-    protected function __construct(EE_Request $request, EE_Response $response)
86
-    {
87
-        $this->_request = $request;
88
-        $this->_response = $response;
89
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
90
-        do_action('EE_Dependency_Map____construct');
91
-    }
92
-
93
-
94
-
95
-    /**
96
-     * @throws InvalidDataTypeException
97
-     * @throws InvalidInterfaceException
98
-     * @throws InvalidArgumentException
99
-     */
100
-    public function initialize()
101
-    {
102
-        $this->_register_core_dependencies();
103
-        $this->_register_core_class_loaders();
104
-        $this->_register_core_aliases();
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * @singleton method used to instantiate class object
111
-     * @access    public
112
-     * @param EE_Request  $request
113
-     * @param EE_Response $response
114
-     * @return EE_Dependency_Map
115
-     */
116
-    public static function instance(EE_Request $request = null, EE_Response $response = null)
117
-    {
118
-        // check if class object is instantiated, and instantiated properly
119
-        if (! self::$_instance instanceof EE_Dependency_Map) {
120
-            self::$_instance = new EE_Dependency_Map($request, $response);
121
-        }
122
-        return self::$_instance;
123
-    }
124
-
125
-
126
-
127
-    /**
128
-     * @param LoaderInterface $loader
129
-     */
130
-    public function setLoader(LoaderInterface $loader)
131
-    {
132
-        $this->loader = $loader;
133
-    }
134
-
135
-
136
-
137
-    /**
138
-     * @param string $class
139
-     * @param array  $dependencies
140
-     * @return boolean
141
-     */
142
-    public static function register_dependencies($class, $dependencies)
143
-    {
144
-        if (! isset(self::$_instance->_dependency_map[$class])) {
145
-            // we need to make sure that any aliases used when registering a dependency
146
-            // get resolved to the correct class name
147
-            foreach ((array)$dependencies as $dependency => $load_source) {
148
-                $alias = self::$_instance->get_alias($dependency);
149
-                unset($dependencies[$dependency]);
150
-                $dependencies[$alias] = $load_source;
151
-            }
152
-            self::$_instance->_dependency_map[$class] = (array)$dependencies;
153
-            return true;
154
-        }
155
-        return false;
156
-    }
157
-
158
-
159
-
160
-    /**
161
-     * @param string $class_name
162
-     * @param string $loader
163
-     * @return bool
164
-     * @throws EE_Error
165
-     */
166
-    public static function register_class_loader($class_name, $loader = 'load_core')
167
-    {
168
-        // check that loader is callable or method starts with "load_" and exists in EE_Registry
169
-        if (
170
-            ! is_callable($loader)
171
-            && (
172
-                strpos($loader, 'load_') !== 0
173
-                || ! method_exists('EE_Registry', $loader)
174
-            )
175
-        ) {
176
-            throw new EE_Error(
177
-                sprintf(
178
-                    __('"%1$s" is not a valid loader method on EE_Registry.', 'event_espresso'),
179
-                    $loader
180
-                )
181
-            );
182
-        }
183
-        $class_name = self::$_instance->get_alias($class_name);
184
-        if (! isset(self::$_instance->_class_loaders[$class_name])) {
185
-            self::$_instance->_class_loaders[$class_name] = $loader;
186
-            return true;
187
-        }
188
-        return false;
189
-    }
190
-
191
-
192
-
193
-    /**
194
-     * @return array
195
-     */
196
-    public function dependency_map()
197
-    {
198
-        return $this->_dependency_map;
199
-    }
200
-
201
-
202
-
203
-    /**
204
-     * returns TRUE if dependency map contains a listing for the provided class name
205
-     *
206
-     * @param string $class_name
207
-     * @return boolean
208
-     */
209
-    public function has($class_name = '')
210
-    {
211
-        return isset($this->_dependency_map[$class_name]) ? true : false;
212
-    }
213
-
214
-
215
-
216
-    /**
217
-     * returns TRUE if dependency map contains a listing for the provided class name AND dependency
218
-     *
219
-     * @param string $class_name
220
-     * @param string $dependency
221
-     * @return bool
222
-     */
223
-    public function has_dependency_for_class($class_name = '', $dependency = '')
224
-    {
225
-        $dependency = $this->get_alias($dependency);
226
-        return isset($this->_dependency_map[$class_name], $this->_dependency_map[$class_name][$dependency])
227
-            ? true
228
-            : false;
229
-    }
230
-
231
-
232
-
233
-    /**
234
-     * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
235
-     *
236
-     * @param string $class_name
237
-     * @param string $dependency
238
-     * @return int
239
-     */
240
-    public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
241
-    {
242
-        $dependency = $this->get_alias($dependency);
243
-        return $this->has_dependency_for_class($class_name, $dependency)
244
-            ? $this->_dependency_map[$class_name][$dependency]
245
-            : EE_Dependency_Map::not_registered;
246
-    }
247
-
248
-
249
-
250
-    /**
251
-     * @param string $class_name
252
-     * @return string | Closure
253
-     */
254
-    public function class_loader($class_name)
255
-    {
256
-        $class_name = $this->get_alias($class_name);
257
-        return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
258
-    }
259
-
260
-
261
-
262
-    /**
263
-     * @return array
264
-     */
265
-    public function class_loaders()
266
-    {
267
-        return $this->_class_loaders;
268
-    }
269
-
270
-
271
-
272
-    /**
273
-     * adds an alias for a classname
274
-     *
275
-     * @param string $class_name the class name that should be used (concrete class to replace interface)
276
-     * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
277
-     * @param string $for_class  the class that has the dependency (is type hinting for the interface)
278
-     */
279
-    public function add_alias($class_name, $alias, $for_class = '')
280
-    {
281
-        if ($for_class !== '') {
282
-            if (! isset($this->_aliases[$for_class])) {
283
-                $this->_aliases[$for_class] = array();
284
-            }
285
-            $this->_aliases[$for_class][$class_name] = $alias;
286
-        }
287
-        $this->_aliases[$class_name] = $alias;
288
-    }
289
-
290
-
291
-
292
-    /**
293
-     * returns TRUE if the provided class name has an alias
294
-     *
295
-     * @param string $class_name
296
-     * @param string $for_class
297
-     * @return bool
298
-     */
299
-    public function has_alias($class_name = '', $for_class = '')
300
-    {
301
-        if (isset($this->_aliases[$for_class], $this->_aliases[$for_class][$class_name])) {
302
-            return true;
303
-        }
304
-        return isset($this->_aliases[$class_name]) && ! is_array($this->_aliases[$class_name]) ? true : false;
305
-    }
306
-
307
-
308
-
309
-    /**
310
-     * returns alias for class name if one exists, otherwise returns the original classname
311
-     * functions recursively, so that multiple aliases can be used to drill down to a classname
312
-     *  for example:
313
-     *      if the following two entries were added to the _aliases array:
314
-     *          array(
315
-     *              'interface_alias'           => 'some\namespace\interface'
316
-     *              'some\namespace\interface'  => 'some\namespace\classname'
317
-     *          )
318
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
319
-     *      to load an instance of 'some\namespace\classname'
320
-     *
321
-     * @param string $class_name
322
-     * @param string $for_class
323
-     * @return string
324
-     */
325
-    public function get_alias($class_name = '', $for_class = '')
326
-    {
327
-        if (! $this->has_alias($class_name, $for_class)) {
328
-            return $class_name;
329
-        }
330
-        if ($for_class !== '') {
331
-            return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
332
-        }
333
-        return $this->get_alias($this->_aliases[$class_name]);
334
-    }
335
-
336
-
337
-
338
-    /**
339
-     * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
340
-     * if one exists, or whether a new object should be generated every time the requested class is loaded.
341
-     * This is done by using the following class constants:
342
-     *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
343
-     *        EE_Dependency_Map::load_new_object - generates a new object every time
344
-     */
345
-    protected function _register_core_dependencies()
346
-    {
347
-        $this->_dependency_map = array(
348
-            'EE_Request_Handler'                                                                                          => array(
349
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
350
-            ),
351
-            'EE_System'                                                                                                   => array(
352
-                'EE_Registry' => EE_Dependency_Map::load_from_cache,
353
-            ),
354
-            'EE_Session'                                                                                                  => array(
355
-                'EE_Encryption' => EE_Dependency_Map::load_from_cache,
356
-            ),
357
-            'EE_Cart'                                                                                                     => array(
358
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
359
-            ),
360
-            'EE_Front_Controller'                                                                                         => array(
361
-                'EE_Registry'              => EE_Dependency_Map::load_from_cache,
362
-                'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
363
-                'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
364
-            ),
365
-            'EE_Messenger_Collection_Loader'                                                                              => array(
366
-                'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
367
-            ),
368
-            'EE_Message_Type_Collection_Loader'                                                                           => array(
369
-                'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
370
-            ),
371
-            'EE_Message_Resource_Manager'                                                                                 => array(
372
-                'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
373
-                'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
374
-                'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
375
-            ),
376
-            'EE_Message_Factory'                                                                                          => array(
377
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
378
-            ),
379
-            'EE_messages'                                                                                                 => array(
380
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
381
-            ),
382
-            'EE_Messages_Generator'                                                                                       => array(
383
-                'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
384
-                'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
385
-                'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
386
-                'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
387
-            ),
388
-            'EE_Messages_Processor'                                                                                       => array(
389
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
390
-            ),
391
-            'EE_Messages_Queue'                                                                                           => array(
392
-                'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
393
-            ),
394
-            'EE_Messages_Template_Defaults'                                                                               => array(
395
-                'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
396
-                'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
397
-            ),
398
-            'EE_Message_To_Generate_From_Request'                                                                         => array(
399
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
400
-                'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
401
-            ),
402
-            'EventEspresso\core\services\commands\CommandBus'                                                             => array(
403
-                'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
404
-            ),
405
-            'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
406
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
407
-            ),
408
-            'EventEspresso\core\services\commands\CompositeCommandHandler'                                                              => array(
409
-                'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
410
-                'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
411
-            ),
412
-            'EventEspresso\core\services\commands\CommandFactory'                                                              => array(
413
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
414
-            ),
415
-            'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
416
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
417
-            ),
418
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
419
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
420
-            ),
421
-            'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
422
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
423
-            ),
424
-            'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
425
-                'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
426
-            ),
427
-            'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
428
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
429
-            ),
430
-            'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
431
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
432
-            ),
433
-            'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
434
-                'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
435
-            ),
436
-            'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
437
-                'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
438
-            ),
439
-            'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
440
-                'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
441
-            ),
442
-            'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
443
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
444
-            ),
445
-            'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
446
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
447
-            ),
448
-            'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
449
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
450
-            ),
451
-            'EventEspresso\core\services\database\TableManager'                                                           => array(
452
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
453
-            ),
454
-            'EE_Data_Migration_Class_Base'                                                                                => array(
455
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
456
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
457
-            ),
458
-            'EE_DMS_Core_4_1_0'                                                                                           => array(
459
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
460
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
461
-            ),
462
-            'EE_DMS_Core_4_2_0'                                                                                           => array(
463
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
464
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
465
-            ),
466
-            'EE_DMS_Core_4_3_0'                                                                                           => array(
467
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
468
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
469
-            ),
470
-            'EE_DMS_Core_4_4_0'                                                                                           => array(
471
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
472
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
473
-            ),
474
-            'EE_DMS_Core_4_5_0'                                                                                           => array(
475
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
476
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
477
-            ),
478
-            'EE_DMS_Core_4_6_0'                                                                                           => array(
479
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
480
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
481
-            ),
482
-            'EE_DMS_Core_4_7_0'                                                                                           => array(
483
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
484
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
485
-            ),
486
-            'EE_DMS_Core_4_8_0'                                                                                           => array(
487
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
488
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
489
-            ),
490
-            'EE_DMS_Core_4_9_0'                                                                                           => array(
491
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
492
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
493
-            ),
494
-        );
495
-    }
496
-
497
-
498
-
499
-    /**
500
-     * Registers how core classes are loaded.
501
-     * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
502
-     *        'EE_Request_Handler' => 'load_core'
503
-     *        'EE_Messages_Queue'  => 'load_lib'
504
-     *        'EEH_Debug_Tools'    => 'load_helper'
505
-     * or, if greater control is required, by providing a custom closure. For example:
506
-     *        'Some_Class' => function () {
507
-     *            return new Some_Class();
508
-     *        },
509
-     * This is required for instantiating dependencies
510
-     * where an interface has been type hinted in a class constructor. For example:
511
-     *        'Required_Interface' => function () {
512
-     *            return new A_Class_That_Implements_Required_Interface();
513
-     *        },
514
-     */
515
-    protected function _register_core_class_loaders()
516
-    {
517
-        //for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
518
-        //be used in a closure.
519
-        $request = &$this->_request;
520
-        $response = &$this->_response;
521
-        $loader = &$this->loader;
522
-        $this->_class_loaders = array(
523
-            //load_core
524
-            'EE_Capabilities'                      => 'load_core',
525
-            'EE_Encryption'                        => 'load_core',
526
-            'EE_Front_Controller'                  => 'load_core',
527
-            'EE_Module_Request_Router'             => 'load_core',
528
-            'EE_Registry'                          => 'load_core',
529
-            'EE_Request'                           => function () use (&$request) {
530
-                return $request;
531
-            },
532
-            'EE_Response'                          => function () use (&$response) {
533
-                return $response;
534
-            },
535
-            'EE_Request_Handler'                   => 'load_core',
536
-            'EE_Session'                           => 'load_core',
537
-            'EE_System'                            => 'load_core',
538
-            //load_lib
539
-            'EE_Message_Resource_Manager'          => 'load_lib',
540
-            'EE_Message_Type_Collection'           => 'load_lib',
541
-            'EE_Message_Type_Collection_Loader'    => 'load_lib',
542
-            'EE_Messenger_Collection'              => 'load_lib',
543
-            'EE_Messenger_Collection_Loader'       => 'load_lib',
544
-            'EE_Messages_Processor'                => 'load_lib',
545
-            'EE_Message_Repository'                => 'load_lib',
546
-            'EE_Messages_Queue'                    => 'load_lib',
547
-            'EE_Messages_Data_Handler_Collection'  => 'load_lib',
548
-            'EE_Message_Template_Group_Collection' => 'load_lib',
549
-            'EE_Messages_Generator'                => function () {
550
-                return EE_Registry::instance()->load_lib('Messages_Generator', array(), false, false);
551
-            },
552
-            'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
553
-                return EE_Registry::instance()->load_lib('Messages_Template_Defaults', $arguments, false, false);
554
-            },
555
-            //load_model
556
-            'EEM_Attendee'                         => 'load_model',
557
-            'EEM_Message_Template_Group'           => 'load_model',
558
-            'EEM_Message_Template'                 => 'load_model',
559
-            //load_helper
560
-            'EEH_Parse_Shortcodes'                 => function () {
561
-                if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
562
-                    return new EEH_Parse_Shortcodes();
563
-                }
564
-                return null;
565
-            },
566
-            'EventEspresso\core\services\loaders\Loader' => function () use (&$loader) {
567
-                return $loader;
568
-            },
569
-        );
570
-    }
571
-
572
-
573
-
574
-    /**
575
-     * can be used for supplying alternate names for classes,
576
-     * or for connecting interface names to instantiable classes
577
-     */
578
-    protected function _register_core_aliases()
579
-    {
580
-        $this->_aliases = array(
581
-            'CommandBusInterface'                                                 => 'EventEspresso\core\services\commands\CommandBusInterface',
582
-            'EventEspresso\core\services\commands\CommandBusInterface'            => 'EventEspresso\core\services\commands\CommandBus',
583
-            'CommandHandlerManagerInterface'                                      => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
584
-            'EventEspresso\core\services\commands\CommandHandlerManagerInterface' => 'EventEspresso\core\services\commands\CommandHandlerManager',
585
-            'CapChecker'                                                          => 'EventEspresso\core\services\commands\middleware\CapChecker',
586
-            'AddActionHook'                                                       => 'EventEspresso\core\services\commands\middleware\AddActionHook',
587
-            'CapabilitiesChecker'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
588
-            'CapabilitiesCheckerInterface'                                        => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
589
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
590
-            'CreateRegistrationService'                                           => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
591
-            'CreateRegCodeCommandHandler'                                         => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
592
-            'CreateRegUrlLinkCommandHandler'                                      => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
593
-            'CreateRegistrationCommandHandler'                                    => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
594
-            'CopyRegistrationDetailsCommandHandler'                               => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
595
-            'CopyRegistrationPaymentsCommandHandler'                              => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
596
-            'CancelRegistrationAndTicketLineItemCommandHandler'                   => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
597
-            'UpdateRegistrationAndTransactionAfterChangeCommandHandler'           => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
598
-            'CreateTicketLineItemCommandHandler'                                  => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
599
-            'TableManager'                                                        => 'EventEspresso\core\services\database\TableManager',
600
-            'TableAnalysis'                                                       => 'EventEspresso\core\services\database\TableAnalysis',
601
-            'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
602
-            'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
603
-            'LoaderInterface'                                                     => 'EventEspresso\core\services\loaders\LoaderInterface',
604
-            'EventEspresso\core\services\loaders\LoaderInterface'                 => 'EventEspresso\core\services\loaders\Loader',
605
-            'CommandFactoryInterface'                                             => 'EventEspresso\core\services\commands\CommandFactoryInterface',
606
-            'EventEspresso\core\services\commands\CommandFactoryInterface'        => 'EventEspresso\core\services\commands\CommandFactory',
607
-        );
608
-    }
609
-
610
-
611
-
612
-    /**
613
-     * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
614
-     * request Primarily used by unit tests.
615
-     */
616
-    public function reset()
617
-    {
618
-        $this->_register_core_class_loaders();
619
-        $this->_register_core_dependencies();
620
-    }
25
+	/**
26
+	 * This means that the requested class dependency is not present in the dependency map
27
+	 */
28
+	const not_registered = 0;
29
+
30
+
31
+	/**
32
+	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
33
+	 */
34
+	const load_new_object = 1;
35
+
36
+	/**
37
+	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
38
+	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
39
+	 */
40
+	const load_from_cache = 2;
41
+
42
+	/**
43
+	 * @type EE_Dependency_Map $_instance
44
+	 */
45
+	protected static $_instance;
46
+
47
+	/**
48
+	 * @type EE_Request $request
49
+	 */
50
+	protected $_request;
51
+
52
+	/**
53
+	 * @type EE_Response $response
54
+	 */
55
+	protected $_response;
56
+
57
+	/**
58
+	 * @type LoaderInterface $loader
59
+	 */
60
+	protected $loader;
61
+
62
+	/**
63
+	 * @type array $_dependency_map
64
+	 */
65
+	protected $_dependency_map = array();
66
+
67
+	/**
68
+	 * @type array $_class_loaders
69
+	 */
70
+	protected $_class_loaders = array();
71
+
72
+	/**
73
+	 * @type array $_aliases
74
+	 */
75
+	protected $_aliases = array();
76
+
77
+
78
+
79
+	/**
80
+	 * EE_Dependency_Map constructor.
81
+	 *
82
+	 * @param EE_Request  $request
83
+	 * @param EE_Response $response
84
+	 */
85
+	protected function __construct(EE_Request $request, EE_Response $response)
86
+	{
87
+		$this->_request = $request;
88
+		$this->_response = $response;
89
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
90
+		do_action('EE_Dependency_Map____construct');
91
+	}
92
+
93
+
94
+
95
+	/**
96
+	 * @throws InvalidDataTypeException
97
+	 * @throws InvalidInterfaceException
98
+	 * @throws InvalidArgumentException
99
+	 */
100
+	public function initialize()
101
+	{
102
+		$this->_register_core_dependencies();
103
+		$this->_register_core_class_loaders();
104
+		$this->_register_core_aliases();
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * @singleton method used to instantiate class object
111
+	 * @access    public
112
+	 * @param EE_Request  $request
113
+	 * @param EE_Response $response
114
+	 * @return EE_Dependency_Map
115
+	 */
116
+	public static function instance(EE_Request $request = null, EE_Response $response = null)
117
+	{
118
+		// check if class object is instantiated, and instantiated properly
119
+		if (! self::$_instance instanceof EE_Dependency_Map) {
120
+			self::$_instance = new EE_Dependency_Map($request, $response);
121
+		}
122
+		return self::$_instance;
123
+	}
124
+
125
+
126
+
127
+	/**
128
+	 * @param LoaderInterface $loader
129
+	 */
130
+	public function setLoader(LoaderInterface $loader)
131
+	{
132
+		$this->loader = $loader;
133
+	}
134
+
135
+
136
+
137
+	/**
138
+	 * @param string $class
139
+	 * @param array  $dependencies
140
+	 * @return boolean
141
+	 */
142
+	public static function register_dependencies($class, $dependencies)
143
+	{
144
+		if (! isset(self::$_instance->_dependency_map[$class])) {
145
+			// we need to make sure that any aliases used when registering a dependency
146
+			// get resolved to the correct class name
147
+			foreach ((array)$dependencies as $dependency => $load_source) {
148
+				$alias = self::$_instance->get_alias($dependency);
149
+				unset($dependencies[$dependency]);
150
+				$dependencies[$alias] = $load_source;
151
+			}
152
+			self::$_instance->_dependency_map[$class] = (array)$dependencies;
153
+			return true;
154
+		}
155
+		return false;
156
+	}
157
+
158
+
159
+
160
+	/**
161
+	 * @param string $class_name
162
+	 * @param string $loader
163
+	 * @return bool
164
+	 * @throws EE_Error
165
+	 */
166
+	public static function register_class_loader($class_name, $loader = 'load_core')
167
+	{
168
+		// check that loader is callable or method starts with "load_" and exists in EE_Registry
169
+		if (
170
+			! is_callable($loader)
171
+			&& (
172
+				strpos($loader, 'load_') !== 0
173
+				|| ! method_exists('EE_Registry', $loader)
174
+			)
175
+		) {
176
+			throw new EE_Error(
177
+				sprintf(
178
+					__('"%1$s" is not a valid loader method on EE_Registry.', 'event_espresso'),
179
+					$loader
180
+				)
181
+			);
182
+		}
183
+		$class_name = self::$_instance->get_alias($class_name);
184
+		if (! isset(self::$_instance->_class_loaders[$class_name])) {
185
+			self::$_instance->_class_loaders[$class_name] = $loader;
186
+			return true;
187
+		}
188
+		return false;
189
+	}
190
+
191
+
192
+
193
+	/**
194
+	 * @return array
195
+	 */
196
+	public function dependency_map()
197
+	{
198
+		return $this->_dependency_map;
199
+	}
200
+
201
+
202
+
203
+	/**
204
+	 * returns TRUE if dependency map contains a listing for the provided class name
205
+	 *
206
+	 * @param string $class_name
207
+	 * @return boolean
208
+	 */
209
+	public function has($class_name = '')
210
+	{
211
+		return isset($this->_dependency_map[$class_name]) ? true : false;
212
+	}
213
+
214
+
215
+
216
+	/**
217
+	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
218
+	 *
219
+	 * @param string $class_name
220
+	 * @param string $dependency
221
+	 * @return bool
222
+	 */
223
+	public function has_dependency_for_class($class_name = '', $dependency = '')
224
+	{
225
+		$dependency = $this->get_alias($dependency);
226
+		return isset($this->_dependency_map[$class_name], $this->_dependency_map[$class_name][$dependency])
227
+			? true
228
+			: false;
229
+	}
230
+
231
+
232
+
233
+	/**
234
+	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
235
+	 *
236
+	 * @param string $class_name
237
+	 * @param string $dependency
238
+	 * @return int
239
+	 */
240
+	public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
241
+	{
242
+		$dependency = $this->get_alias($dependency);
243
+		return $this->has_dependency_for_class($class_name, $dependency)
244
+			? $this->_dependency_map[$class_name][$dependency]
245
+			: EE_Dependency_Map::not_registered;
246
+	}
247
+
248
+
249
+
250
+	/**
251
+	 * @param string $class_name
252
+	 * @return string | Closure
253
+	 */
254
+	public function class_loader($class_name)
255
+	{
256
+		$class_name = $this->get_alias($class_name);
257
+		return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
258
+	}
259
+
260
+
261
+
262
+	/**
263
+	 * @return array
264
+	 */
265
+	public function class_loaders()
266
+	{
267
+		return $this->_class_loaders;
268
+	}
269
+
270
+
271
+
272
+	/**
273
+	 * adds an alias for a classname
274
+	 *
275
+	 * @param string $class_name the class name that should be used (concrete class to replace interface)
276
+	 * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
277
+	 * @param string $for_class  the class that has the dependency (is type hinting for the interface)
278
+	 */
279
+	public function add_alias($class_name, $alias, $for_class = '')
280
+	{
281
+		if ($for_class !== '') {
282
+			if (! isset($this->_aliases[$for_class])) {
283
+				$this->_aliases[$for_class] = array();
284
+			}
285
+			$this->_aliases[$for_class][$class_name] = $alias;
286
+		}
287
+		$this->_aliases[$class_name] = $alias;
288
+	}
289
+
290
+
291
+
292
+	/**
293
+	 * returns TRUE if the provided class name has an alias
294
+	 *
295
+	 * @param string $class_name
296
+	 * @param string $for_class
297
+	 * @return bool
298
+	 */
299
+	public function has_alias($class_name = '', $for_class = '')
300
+	{
301
+		if (isset($this->_aliases[$for_class], $this->_aliases[$for_class][$class_name])) {
302
+			return true;
303
+		}
304
+		return isset($this->_aliases[$class_name]) && ! is_array($this->_aliases[$class_name]) ? true : false;
305
+	}
306
+
307
+
308
+
309
+	/**
310
+	 * returns alias for class name if one exists, otherwise returns the original classname
311
+	 * functions recursively, so that multiple aliases can be used to drill down to a classname
312
+	 *  for example:
313
+	 *      if the following two entries were added to the _aliases array:
314
+	 *          array(
315
+	 *              'interface_alias'           => 'some\namespace\interface'
316
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
317
+	 *          )
318
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
319
+	 *      to load an instance of 'some\namespace\classname'
320
+	 *
321
+	 * @param string $class_name
322
+	 * @param string $for_class
323
+	 * @return string
324
+	 */
325
+	public function get_alias($class_name = '', $for_class = '')
326
+	{
327
+		if (! $this->has_alias($class_name, $for_class)) {
328
+			return $class_name;
329
+		}
330
+		if ($for_class !== '') {
331
+			return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
332
+		}
333
+		return $this->get_alias($this->_aliases[$class_name]);
334
+	}
335
+
336
+
337
+
338
+	/**
339
+	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
340
+	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
341
+	 * This is done by using the following class constants:
342
+	 *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
343
+	 *        EE_Dependency_Map::load_new_object - generates a new object every time
344
+	 */
345
+	protected function _register_core_dependencies()
346
+	{
347
+		$this->_dependency_map = array(
348
+			'EE_Request_Handler'                                                                                          => array(
349
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
350
+			),
351
+			'EE_System'                                                                                                   => array(
352
+				'EE_Registry' => EE_Dependency_Map::load_from_cache,
353
+			),
354
+			'EE_Session'                                                                                                  => array(
355
+				'EE_Encryption' => EE_Dependency_Map::load_from_cache,
356
+			),
357
+			'EE_Cart'                                                                                                     => array(
358
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
359
+			),
360
+			'EE_Front_Controller'                                                                                         => array(
361
+				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
362
+				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
363
+				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
364
+			),
365
+			'EE_Messenger_Collection_Loader'                                                                              => array(
366
+				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
367
+			),
368
+			'EE_Message_Type_Collection_Loader'                                                                           => array(
369
+				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
370
+			),
371
+			'EE_Message_Resource_Manager'                                                                                 => array(
372
+				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
373
+				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
374
+				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
375
+			),
376
+			'EE_Message_Factory'                                                                                          => array(
377
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
378
+			),
379
+			'EE_messages'                                                                                                 => array(
380
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
381
+			),
382
+			'EE_Messages_Generator'                                                                                       => array(
383
+				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
384
+				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
385
+				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
386
+				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
387
+			),
388
+			'EE_Messages_Processor'                                                                                       => array(
389
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
390
+			),
391
+			'EE_Messages_Queue'                                                                                           => array(
392
+				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
393
+			),
394
+			'EE_Messages_Template_Defaults'                                                                               => array(
395
+				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
396
+				'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
397
+			),
398
+			'EE_Message_To_Generate_From_Request'                                                                         => array(
399
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
400
+				'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
401
+			),
402
+			'EventEspresso\core\services\commands\CommandBus'                                                             => array(
403
+				'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
404
+			),
405
+			'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
406
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
407
+			),
408
+			'EventEspresso\core\services\commands\CompositeCommandHandler'                                                              => array(
409
+				'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
410
+				'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
411
+			),
412
+			'EventEspresso\core\services\commands\CommandFactory'                                                              => array(
413
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
414
+			),
415
+			'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
416
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
417
+			),
418
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
419
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
420
+			),
421
+			'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
422
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
423
+			),
424
+			'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
425
+				'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
426
+			),
427
+			'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
428
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
429
+			),
430
+			'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
431
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
432
+			),
433
+			'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
434
+				'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
435
+			),
436
+			'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
437
+				'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
438
+			),
439
+			'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
440
+				'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
441
+			),
442
+			'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
443
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
444
+			),
445
+			'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
446
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
447
+			),
448
+			'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
449
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
450
+			),
451
+			'EventEspresso\core\services\database\TableManager'                                                           => array(
452
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
453
+			),
454
+			'EE_Data_Migration_Class_Base'                                                                                => array(
455
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
456
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
457
+			),
458
+			'EE_DMS_Core_4_1_0'                                                                                           => array(
459
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
460
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
461
+			),
462
+			'EE_DMS_Core_4_2_0'                                                                                           => array(
463
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
464
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
465
+			),
466
+			'EE_DMS_Core_4_3_0'                                                                                           => array(
467
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
468
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
469
+			),
470
+			'EE_DMS_Core_4_4_0'                                                                                           => array(
471
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
472
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
473
+			),
474
+			'EE_DMS_Core_4_5_0'                                                                                           => array(
475
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
476
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
477
+			),
478
+			'EE_DMS_Core_4_6_0'                                                                                           => array(
479
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
480
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
481
+			),
482
+			'EE_DMS_Core_4_7_0'                                                                                           => array(
483
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
484
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
485
+			),
486
+			'EE_DMS_Core_4_8_0'                                                                                           => array(
487
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
488
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
489
+			),
490
+			'EE_DMS_Core_4_9_0'                                                                                           => array(
491
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
492
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
493
+			),
494
+		);
495
+	}
496
+
497
+
498
+
499
+	/**
500
+	 * Registers how core classes are loaded.
501
+	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
502
+	 *        'EE_Request_Handler' => 'load_core'
503
+	 *        'EE_Messages_Queue'  => 'load_lib'
504
+	 *        'EEH_Debug_Tools'    => 'load_helper'
505
+	 * or, if greater control is required, by providing a custom closure. For example:
506
+	 *        'Some_Class' => function () {
507
+	 *            return new Some_Class();
508
+	 *        },
509
+	 * This is required for instantiating dependencies
510
+	 * where an interface has been type hinted in a class constructor. For example:
511
+	 *        'Required_Interface' => function () {
512
+	 *            return new A_Class_That_Implements_Required_Interface();
513
+	 *        },
514
+	 */
515
+	protected function _register_core_class_loaders()
516
+	{
517
+		//for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
518
+		//be used in a closure.
519
+		$request = &$this->_request;
520
+		$response = &$this->_response;
521
+		$loader = &$this->loader;
522
+		$this->_class_loaders = array(
523
+			//load_core
524
+			'EE_Capabilities'                      => 'load_core',
525
+			'EE_Encryption'                        => 'load_core',
526
+			'EE_Front_Controller'                  => 'load_core',
527
+			'EE_Module_Request_Router'             => 'load_core',
528
+			'EE_Registry'                          => 'load_core',
529
+			'EE_Request'                           => function () use (&$request) {
530
+				return $request;
531
+			},
532
+			'EE_Response'                          => function () use (&$response) {
533
+				return $response;
534
+			},
535
+			'EE_Request_Handler'                   => 'load_core',
536
+			'EE_Session'                           => 'load_core',
537
+			'EE_System'                            => 'load_core',
538
+			//load_lib
539
+			'EE_Message_Resource_Manager'          => 'load_lib',
540
+			'EE_Message_Type_Collection'           => 'load_lib',
541
+			'EE_Message_Type_Collection_Loader'    => 'load_lib',
542
+			'EE_Messenger_Collection'              => 'load_lib',
543
+			'EE_Messenger_Collection_Loader'       => 'load_lib',
544
+			'EE_Messages_Processor'                => 'load_lib',
545
+			'EE_Message_Repository'                => 'load_lib',
546
+			'EE_Messages_Queue'                    => 'load_lib',
547
+			'EE_Messages_Data_Handler_Collection'  => 'load_lib',
548
+			'EE_Message_Template_Group_Collection' => 'load_lib',
549
+			'EE_Messages_Generator'                => function () {
550
+				return EE_Registry::instance()->load_lib('Messages_Generator', array(), false, false);
551
+			},
552
+			'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
553
+				return EE_Registry::instance()->load_lib('Messages_Template_Defaults', $arguments, false, false);
554
+			},
555
+			//load_model
556
+			'EEM_Attendee'                         => 'load_model',
557
+			'EEM_Message_Template_Group'           => 'load_model',
558
+			'EEM_Message_Template'                 => 'load_model',
559
+			//load_helper
560
+			'EEH_Parse_Shortcodes'                 => function () {
561
+				if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
562
+					return new EEH_Parse_Shortcodes();
563
+				}
564
+				return null;
565
+			},
566
+			'EventEspresso\core\services\loaders\Loader' => function () use (&$loader) {
567
+				return $loader;
568
+			},
569
+		);
570
+	}
571
+
572
+
573
+
574
+	/**
575
+	 * can be used for supplying alternate names for classes,
576
+	 * or for connecting interface names to instantiable classes
577
+	 */
578
+	protected function _register_core_aliases()
579
+	{
580
+		$this->_aliases = array(
581
+			'CommandBusInterface'                                                 => 'EventEspresso\core\services\commands\CommandBusInterface',
582
+			'EventEspresso\core\services\commands\CommandBusInterface'            => 'EventEspresso\core\services\commands\CommandBus',
583
+			'CommandHandlerManagerInterface'                                      => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
584
+			'EventEspresso\core\services\commands\CommandHandlerManagerInterface' => 'EventEspresso\core\services\commands\CommandHandlerManager',
585
+			'CapChecker'                                                          => 'EventEspresso\core\services\commands\middleware\CapChecker',
586
+			'AddActionHook'                                                       => 'EventEspresso\core\services\commands\middleware\AddActionHook',
587
+			'CapabilitiesChecker'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
588
+			'CapabilitiesCheckerInterface'                                        => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
589
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
590
+			'CreateRegistrationService'                                           => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
591
+			'CreateRegCodeCommandHandler'                                         => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
592
+			'CreateRegUrlLinkCommandHandler'                                      => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
593
+			'CreateRegistrationCommandHandler'                                    => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
594
+			'CopyRegistrationDetailsCommandHandler'                               => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
595
+			'CopyRegistrationPaymentsCommandHandler'                              => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
596
+			'CancelRegistrationAndTicketLineItemCommandHandler'                   => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
597
+			'UpdateRegistrationAndTransactionAfterChangeCommandHandler'           => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
598
+			'CreateTicketLineItemCommandHandler'                                  => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
599
+			'TableManager'                                                        => 'EventEspresso\core\services\database\TableManager',
600
+			'TableAnalysis'                                                       => 'EventEspresso\core\services\database\TableAnalysis',
601
+			'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
602
+			'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
603
+			'LoaderInterface'                                                     => 'EventEspresso\core\services\loaders\LoaderInterface',
604
+			'EventEspresso\core\services\loaders\LoaderInterface'                 => 'EventEspresso\core\services\loaders\Loader',
605
+			'CommandFactoryInterface'                                             => 'EventEspresso\core\services\commands\CommandFactoryInterface',
606
+			'EventEspresso\core\services\commands\CommandFactoryInterface'        => 'EventEspresso\core\services\commands\CommandFactory',
607
+		);
608
+	}
609
+
610
+
611
+
612
+	/**
613
+	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
614
+	 * request Primarily used by unit tests.
615
+	 */
616
+	public function reset()
617
+	{
618
+		$this->_register_core_class_loaders();
619
+		$this->_register_core_dependencies();
620
+	}
621 621
 
622 622
 
623 623
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@  discard block
 block discarded – undo
3 3
 use EventEspresso\core\exceptions\InvalidInterfaceException;
4 4
 use EventEspresso\core\services\loaders\LoaderInterface;
5 5
 
6
-if (! defined('EVENT_ESPRESSO_VERSION')) {
6
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
7 7
     exit('No direct script access allowed');
8 8
 }
9 9
 
@@ -116,7 +116,7 @@  discard block
 block discarded – undo
116 116
     public static function instance(EE_Request $request = null, EE_Response $response = null)
117 117
     {
118 118
         // check if class object is instantiated, and instantiated properly
119
-        if (! self::$_instance instanceof EE_Dependency_Map) {
119
+        if ( ! self::$_instance instanceof EE_Dependency_Map) {
120 120
             self::$_instance = new EE_Dependency_Map($request, $response);
121 121
         }
122 122
         return self::$_instance;
@@ -141,15 +141,15 @@  discard block
 block discarded – undo
141 141
      */
142 142
     public static function register_dependencies($class, $dependencies)
143 143
     {
144
-        if (! isset(self::$_instance->_dependency_map[$class])) {
144
+        if ( ! isset(self::$_instance->_dependency_map[$class])) {
145 145
             // we need to make sure that any aliases used when registering a dependency
146 146
             // get resolved to the correct class name
147
-            foreach ((array)$dependencies as $dependency => $load_source) {
147
+            foreach ((array) $dependencies as $dependency => $load_source) {
148 148
                 $alias = self::$_instance->get_alias($dependency);
149 149
                 unset($dependencies[$dependency]);
150 150
                 $dependencies[$alias] = $load_source;
151 151
             }
152
-            self::$_instance->_dependency_map[$class] = (array)$dependencies;
152
+            self::$_instance->_dependency_map[$class] = (array) $dependencies;
153 153
             return true;
154 154
         }
155 155
         return false;
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
             );
182 182
         }
183 183
         $class_name = self::$_instance->get_alias($class_name);
184
-        if (! isset(self::$_instance->_class_loaders[$class_name])) {
184
+        if ( ! isset(self::$_instance->_class_loaders[$class_name])) {
185 185
             self::$_instance->_class_loaders[$class_name] = $loader;
186 186
             return true;
187 187
         }
@@ -279,7 +279,7 @@  discard block
 block discarded – undo
279 279
     public function add_alias($class_name, $alias, $for_class = '')
280 280
     {
281 281
         if ($for_class !== '') {
282
-            if (! isset($this->_aliases[$for_class])) {
282
+            if ( ! isset($this->_aliases[$for_class])) {
283 283
                 $this->_aliases[$for_class] = array();
284 284
             }
285 285
             $this->_aliases[$for_class][$class_name] = $alias;
@@ -324,7 +324,7 @@  discard block
 block discarded – undo
324 324
      */
325 325
     public function get_alias($class_name = '', $for_class = '')
326 326
     {
327
-        if (! $this->has_alias($class_name, $for_class)) {
327
+        if ( ! $this->has_alias($class_name, $for_class)) {
328 328
             return $class_name;
329 329
         }
330 330
         if ($for_class !== '') {
@@ -526,10 +526,10 @@  discard block
 block discarded – undo
526 526
             'EE_Front_Controller'                  => 'load_core',
527 527
             'EE_Module_Request_Router'             => 'load_core',
528 528
             'EE_Registry'                          => 'load_core',
529
-            'EE_Request'                           => function () use (&$request) {
529
+            'EE_Request'                           => function() use (&$request) {
530 530
                 return $request;
531 531
             },
532
-            'EE_Response'                          => function () use (&$response) {
532
+            'EE_Response'                          => function() use (&$response) {
533 533
                 return $response;
534 534
             },
535 535
             'EE_Request_Handler'                   => 'load_core',
@@ -546,10 +546,10 @@  discard block
 block discarded – undo
546 546
             'EE_Messages_Queue'                    => 'load_lib',
547 547
             'EE_Messages_Data_Handler_Collection'  => 'load_lib',
548 548
             'EE_Message_Template_Group_Collection' => 'load_lib',
549
-            'EE_Messages_Generator'                => function () {
549
+            'EE_Messages_Generator'                => function() {
550 550
                 return EE_Registry::instance()->load_lib('Messages_Generator', array(), false, false);
551 551
             },
552
-            'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
552
+            'EE_Messages_Template_Defaults'        => function($arguments = array()) {
553 553
                 return EE_Registry::instance()->load_lib('Messages_Template_Defaults', $arguments, false, false);
554 554
             },
555 555
             //load_model
@@ -557,13 +557,13 @@  discard block
 block discarded – undo
557 557
             'EEM_Message_Template_Group'           => 'load_model',
558 558
             'EEM_Message_Template'                 => 'load_model',
559 559
             //load_helper
560
-            'EEH_Parse_Shortcodes'                 => function () {
560
+            'EEH_Parse_Shortcodes'                 => function() {
561 561
                 if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
562 562
                     return new EEH_Parse_Shortcodes();
563 563
                 }
564 564
                 return null;
565 565
             },
566
-            'EventEspresso\core\services\loaders\Loader' => function () use (&$loader) {
566
+            'EventEspresso\core\services\loaders\Loader' => function() use (&$loader) {
567 567
                 return $loader;
568 568
             },
569 569
         );
Please login to merge, or discard this patch.
core/libraries/form_sections/form_handlers/FormHandler.php 2 patches
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -122,19 +122,19 @@  discard block
 block discarded – undo
122 122
 
123 123
 
124 124
 
125
-    /**
126
-     * Form constructor.
127
-     *
128
-     * @param string       $form_name
129
-     * @param string       $admin_name
130
-     * @param string       $slug
131
-     * @param string       $form_action
132
-     * @param string       $form_config
133
-     * @param EE_Registry $registry
134
-     * @throws InvalidDataTypeException
135
-     * @throws DomainException
136
-     * @throws InvalidArgumentException
137
-     */
125
+	/**
126
+	 * Form constructor.
127
+	 *
128
+	 * @param string       $form_name
129
+	 * @param string       $admin_name
130
+	 * @param string       $slug
131
+	 * @param string       $form_action
132
+	 * @param string       $form_config
133
+	 * @param EE_Registry $registry
134
+	 * @throws InvalidDataTypeException
135
+	 * @throws DomainException
136
+	 * @throws InvalidArgumentException
137
+	 */
138 138
 	public function __construct(
139 139
 		$form_name,
140 140
 		$admin_name,
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
 	 * @throws LogicException
176 176
 	 */
177 177
 	public function form( $for_display = false ) {
178
-        if ( ! $this->formIsValid() ) {
178
+		if ( ! $this->formIsValid() ) {
179 179
 			return null;
180 180
 		}
181 181
 		if ( $for_display ) {
@@ -198,14 +198,14 @@  discard block
 block discarded – undo
198 198
 	 * @throws LogicException
199 199
 	 */
200 200
 	public function formIsValid() {
201
-        if ( ! $this->form instanceof EE_Form_Section_Proper) {
201
+		if ( ! $this->form instanceof EE_Form_Section_Proper) {
202 202
 			static $generated = false;
203 203
 			if ( ! $generated ) {
204 204
 				$generated = true;
205 205
 				$form = $this->generate();
206
-                if ($form instanceof EE_Form_Section_Proper) {
207
-                    $this->setForm($form);
208
-                }
206
+				if ($form instanceof EE_Form_Section_Proper) {
207
+					$this->setForm($form);
208
+				}
209 209
 			}
210 210
 			return $this->verifyForm();
211 211
 		}
@@ -340,11 +340,11 @@  discard block
 block discarded – undo
340 340
 
341 341
 
342 342
 
343
-    /**
344
-     * @param string $submit_btn_text
345
-     * @throws InvalidDataTypeException
346
-     * @throws InvalidArgumentException
347
-     */
343
+	/**
344
+	 * @param string $submit_btn_text
345
+	 * @throws InvalidDataTypeException
346
+	 * @throws InvalidArgumentException
347
+	 */
348 348
 	public function setSubmitBtnText( $submit_btn_text ) {
349 349
 		if ( ! is_string( $submit_btn_text ) ) {
350 350
 			throw new InvalidDataTypeException( '$submit_btn_text', $submit_btn_text, 'string' );
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
 					FormHandler::ADD_FORM_SUBMIT_ONLY,
430 430
 					FormHandler::DO_NOT_SETUP_FORM
431 431
 				),
432
-                true
432
+				true
433 433
 			)
434 434
 		) {
435 435
 			throw new DomainException(
@@ -577,7 +577,7 @@  discard block
 block discarded – undo
577 577
 	 * @throws EE_Error
578 578
 	 */
579 579
 	public function display() {
580
-        $form_html = apply_filters(
580
+		$form_html = apply_filters(
581 581
 			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__display__before_form',
582 582
 			''
583 583
 		);
@@ -616,11 +616,11 @@  discard block
 block discarded – undo
616 616
 	 */
617 617
 	public function process( $submitted_form_data = array() ) {
618 618
 		if ( ! $this->form()->was_submitted( $submitted_form_data ) ) {
619
-            throw new InvalidFormSubmissionException( $this->form_name );
619
+			throw new InvalidFormSubmissionException( $this->form_name );
620 620
 		}
621
-        $this->form( true )->receive_form_submission( $submitted_form_data );
621
+		$this->form( true )->receive_form_submission( $submitted_form_data );
622 622
 		if ( ! $this->form()->is_valid() ) {
623
-            throw new InvalidFormSubmissionException(
623
+			throw new InvalidFormSubmissionException(
624 624
 				$this->form_name,
625 625
 				sprintf(
626 626
 					__(
Please login to merge, or discard this patch.
Spacing   +68 added lines, -68 removed lines patch added patch discarded remove patch
@@ -13,8 +13,8 @@  discard block
 block discarded – undo
13 13
 use EventEspresso\core\exceptions\InvalidDataTypeException;
14 14
 use EventEspresso\core\exceptions\InvalidFormSubmissionException;
15 15
 
16
-if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
17
-	exit( 'No direct script access allowed' );
16
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
17
+	exit('No direct script access allowed');
18 18
 }
19 19
 
20 20
 
@@ -30,7 +30,7 @@  discard block
 block discarded – undo
30 30
  * @author        Brent Christensen
31 31
  * @since         4.9.0
32 32
  */
33
-abstract class FormHandler implements FormHandlerInterface{
33
+abstract class FormHandler implements FormHandlerInterface {
34 34
 
35 35
 	/**
36 36
 	 * will add opening and closing HTML form tags as well as a submit button
@@ -143,12 +143,12 @@  discard block
 block discarded – undo
143 143
 		$form_config = FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
144 144
 		EE_Registry $registry
145 145
 	) {
146
-		$this->setFormName( $form_name );
147
-		$this->setAdminName( $admin_name );
148
-		$this->setSlug( $slug );
149
-		$this->setFormAction( $form_action );
150
-		$this->setFormConfig( $form_config );
151
-		$this->setSubmitBtnText( __( 'Submit', 'event_espresso' ) );
146
+		$this->setFormName($form_name);
147
+		$this->setAdminName($admin_name);
148
+		$this->setSlug($slug);
149
+		$this->setFormAction($form_action);
150
+		$this->setFormConfig($form_config);
151
+		$this->setSubmitBtnText(__('Submit', 'event_espresso'));
152 152
 		$this->registry = $registry;
153 153
 	}
154 154
 
@@ -174,11 +174,11 @@  discard block
 block discarded – undo
174 174
 	 * @throws EE_Error
175 175
 	 * @throws LogicException
176 176
 	 */
177
-	public function form( $for_display = false ) {
178
-        if ( ! $this->formIsValid() ) {
177
+	public function form($for_display = false) {
178
+        if ( ! $this->formIsValid()) {
179 179
 			return null;
180 180
 		}
181
-		if ( $for_display ) {
181
+		if ($for_display) {
182 182
 			$form_config = $this->formConfig();
183 183
 			if (
184 184
 				$form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
@@ -200,7 +200,7 @@  discard block
 block discarded – undo
200 200
 	public function formIsValid() {
201 201
         if ( ! $this->form instanceof EE_Form_Section_Proper) {
202 202
 			static $generated = false;
203
-			if ( ! $generated ) {
203
+			if ( ! $generated) {
204 204
 				$generated = true;
205 205
 				$form = $this->generate();
206 206
                 if ($form instanceof EE_Form_Section_Proper) {
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
 		}
225 225
 		throw new LogicException(
226 226
 			sprintf(
227
-				__( 'The "%1$s" form is invalid or missing', 'event_espresso' ),
227
+				__('The "%1$s" form is invalid or missing', 'event_espresso'),
228 228
 				$this->form_name
229 229
 			)
230 230
 		);
@@ -235,7 +235,7 @@  discard block
 block discarded – undo
235 235
 	/**
236 236
 	 * @param EE_Form_Section_Proper $form
237 237
 	 */
238
-	public function setForm( EE_Form_Section_Proper $form ) {
238
+	public function setForm(EE_Form_Section_Proper $form) {
239 239
 		$this->form = $form;
240 240
 	}
241 241
 
@@ -253,8 +253,8 @@  discard block
 block discarded – undo
253 253
 	/**
254 254
 	 * @param boolean $displayable
255 255
 	 */
256
-	public function setDisplayable( $displayable = false ) {
257
-		$this->displayable = filter_var( $displayable, FILTER_VALIDATE_BOOLEAN );
256
+	public function setDisplayable($displayable = false) {
257
+		$this->displayable = filter_var($displayable, FILTER_VALIDATE_BOOLEAN);
258 258
 	}
259 259
 
260 260
 
@@ -274,9 +274,9 @@  discard block
 block discarded – undo
274 274
 	 * @param string $form_name
275 275
 	 * @throws InvalidDataTypeException
276 276
 	 */
277
-	public function setFormName( $form_name ) {
278
-		if ( ! is_string( $form_name ) ) {
279
-			throw new InvalidDataTypeException( '$form_name', $form_name, 'string' );
277
+	public function setFormName($form_name) {
278
+		if ( ! is_string($form_name)) {
279
+			throw new InvalidDataTypeException('$form_name', $form_name, 'string');
280 280
 		}
281 281
 		$this->form_name = $form_name;
282 282
 	}
@@ -298,9 +298,9 @@  discard block
 block discarded – undo
298 298
 	 * @param string $admin_name
299 299
 	 * @throws InvalidDataTypeException
300 300
 	 */
301
-	public function setAdminName( $admin_name ) {
302
-		if ( ! is_string( $admin_name ) ) {
303
-			throw new InvalidDataTypeException( '$admin_name', $admin_name, 'string' );
301
+	public function setAdminName($admin_name) {
302
+		if ( ! is_string($admin_name)) {
303
+			throw new InvalidDataTypeException('$admin_name', $admin_name, 'string');
304 304
 		}
305 305
 		$this->admin_name = $admin_name;
306 306
 	}
@@ -322,9 +322,9 @@  discard block
 block discarded – undo
322 322
 	 * @param string $slug
323 323
 	 * @throws InvalidDataTypeException
324 324
 	 */
325
-	public function setSlug( $slug ) {
326
-		if ( ! is_string( $slug ) ) {
327
-			throw new InvalidDataTypeException( '$slug', $slug, 'string' );
325
+	public function setSlug($slug) {
326
+		if ( ! is_string($slug)) {
327
+			throw new InvalidDataTypeException('$slug', $slug, 'string');
328 328
 		}
329 329
 		$this->slug = $slug;
330 330
 	}
@@ -345,13 +345,13 @@  discard block
 block discarded – undo
345 345
      * @throws InvalidDataTypeException
346 346
      * @throws InvalidArgumentException
347 347
      */
348
-	public function setSubmitBtnText( $submit_btn_text ) {
349
-		if ( ! is_string( $submit_btn_text ) ) {
350
-			throw new InvalidDataTypeException( '$submit_btn_text', $submit_btn_text, 'string' );
348
+	public function setSubmitBtnText($submit_btn_text) {
349
+		if ( ! is_string($submit_btn_text)) {
350
+			throw new InvalidDataTypeException('$submit_btn_text', $submit_btn_text, 'string');
351 351
 		}
352
-		if ( empty( $submit_btn_text ) ) {
352
+		if (empty($submit_btn_text)) {
353 353
 			throw new InvalidArgumentException(
354
-				__( 'Can not set Submit button text because an empty string was provided.', 'event_espresso' )
354
+				__('Can not set Submit button text because an empty string was provided.', 'event_espresso')
355 355
 			);
356 356
 		}
357 357
 		$this->submit_btn_text = $submit_btn_text;
@@ -363,8 +363,8 @@  discard block
 block discarded – undo
363 363
 	 * @return string
364 364
 	 */
365 365
 	public function formAction() {
366
-		return ! empty( $this->form_args )
367
-			? add_query_arg( $this->form_args, $this->form_action )
366
+		return ! empty($this->form_args)
367
+			? add_query_arg($this->form_args, $this->form_action)
368 368
 			: $this->form_action;
369 369
 	}
370 370
 
@@ -374,9 +374,9 @@  discard block
 block discarded – undo
374 374
 	 * @param string $form_action
375 375
 	 * @throws InvalidDataTypeException
376 376
 	 */
377
-	public function setFormAction( $form_action ) {
378
-		if ( ! is_string( $form_action ) ) {
379
-			throw new InvalidDataTypeException( '$form_action', $form_action, 'string' );
377
+	public function setFormAction($form_action) {
378
+		if ( ! is_string($form_action)) {
379
+			throw new InvalidDataTypeException('$form_action', $form_action, 'string');
380 380
 		}
381 381
 		$this->form_action = $form_action;
382 382
 	}
@@ -388,20 +388,20 @@  discard block
 block discarded – undo
388 388
 	 * @throws InvalidDataTypeException
389 389
 	 * @throws InvalidArgumentException
390 390
 	 */
391
-	public function addFormActionArgs( $form_args = array() ) {
392
-		if ( is_object( $form_args ) ) {
391
+	public function addFormActionArgs($form_args = array()) {
392
+		if (is_object($form_args)) {
393 393
 			throw new InvalidDataTypeException(
394 394
 				'$form_args',
395 395
 				$form_args,
396 396
 				'anything other than an object was expected.'
397 397
 			);
398 398
 		}
399
-		if ( empty( $form_args ) ) {
399
+		if (empty($form_args)) {
400 400
 			throw new InvalidArgumentException(
401
-				__( 'The redirect arguments can not be an empty array.', 'event_espresso' )
401
+				__('The redirect arguments can not be an empty array.', 'event_espresso')
402 402
 			);
403 403
 		}
404
-		$this->form_args = array_merge( $this->form_args, $form_args );
404
+		$this->form_args = array_merge($this->form_args, $form_args);
405 405
 	}
406 406
 
407 407
 
@@ -419,7 +419,7 @@  discard block
 block discarded – undo
419 419
 	 * @param string $form_config
420 420
 	 * @throws DomainException
421 421
 	 */
422
-	public function setFormConfig( $form_config ) {
422
+	public function setFormConfig($form_config) {
423 423
 		if (
424 424
 			! in_array(
425 425
 				$form_config,
@@ -434,7 +434,7 @@  discard block
 block discarded – undo
434 434
 		) {
435 435
 			throw new DomainException(
436 436
 				sprintf(
437
-					__( '"%1$s" is not a valid value for the form config. Please use one of the class constants on \EventEspresso\core\libraries\form_sections\form_handlers\Form', 'event_espresso' ),
437
+					__('"%1$s" is not a valid value for the form config. Please use one of the class constants on \EventEspresso\core\libraries\form_sections\form_handlers\Form', 'event_espresso'),
438 438
 					$form_config
439 439
 				)
440 440
 			);
@@ -454,7 +454,7 @@  discard block
 block discarded – undo
454 454
 	 * @return boolean
455 455
 	 */
456 456
 	public function initialize() {
457
-		$this->form_has_errors = EE_Error::has_error( true );
457
+		$this->form_has_errors = EE_Error::has_error(true);
458 458
 		return true;
459 459
 	}
460 460
 
@@ -468,7 +468,7 @@  discard block
 block discarded – undo
468 468
 	 * @throws EE_Error
469 469
 	 */
470 470
 	public function enqueueStylesAndScripts() {
471
-		$this->form( false )->enqueue_js();
471
+		$this->form(false)->enqueue_js();
472 472
 	}
473 473
 
474 474
 
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
 	 *
479 479
 	 * @return EE_Form_Section_Proper
480 480
 	 */
481
-	abstract public function generate() ;
481
+	abstract public function generate();
482 482
 
483 483
 
484 484
 
@@ -488,15 +488,15 @@  discard block
 block discarded – undo
488 488
 	 * @param string $text
489 489
 	 * @return EE_Submit_Input
490 490
 	 */
491
-	public function generateSubmitButton( $text = '' ) {
492
-		$text = ! empty( $text ) ? $text : $this->submitBtnText();
491
+	public function generateSubmitButton($text = '') {
492
+		$text = ! empty($text) ? $text : $this->submitBtnText();
493 493
 		return new EE_Submit_Input(
494 494
 			array(
495
-				'html_name'             => 'ee-form-submit-' . $this->slug(),
496
-				'html_id'               => 'ee-form-submit-' . $this->slug(),
495
+				'html_name'             => 'ee-form-submit-'.$this->slug(),
496
+				'html_id'               => 'ee-form-submit-'.$this->slug(),
497 497
 				'html_class'            => 'ee-form-submit',
498 498
 				'html_label'            => '&nbsp;',
499
-				'other_html_attributes' => ' rel="' . $this->slug() . '"',
499
+				'other_html_attributes' => ' rel="'.$this->slug().'"',
500 500
 				'default'               => $text
501 501
 			)
502 502
 		);
@@ -512,12 +512,12 @@  discard block
 block discarded – undo
512 512
 	 * @throws LogicException
513 513
 	 * @throws EE_Error
514 514
 	 */
515
-	public function appendSubmitButton( $text = '' ) {
516
-		if ( $this->form->subsection_exists( $this->slug() . '-submit-btn' ) ) {
515
+	public function appendSubmitButton($text = '') {
516
+		if ($this->form->subsection_exists($this->slug().'-submit-btn')) {
517 517
 			return;
518 518
 		}
519 519
 		$this->form->add_subsections(
520
-			array( $this->slug() . '-submit-btn' => $this->generateSubmitButton( $text ) ),
520
+			array($this->slug().'-submit-btn' => $this->generateSubmitButton($text)),
521 521
 			null,
522 522
 			false
523 523
 		);
@@ -531,18 +531,18 @@  discard block
 block discarded – undo
531 531
 	 * @param string $text
532 532
 	 * @return EE_Submit_Input
533 533
 	 */
534
-	public function generateCancelButton( $text = '' ) {
534
+	public function generateCancelButton($text = '') {
535 535
 		$cancel_button = new EE_Submit_Input(
536 536
 			array(
537
-				'html_name'             => 'ee-form-submit-' . $this->slug(), // YES! Same name as submit !!!
538
-				'html_id'               => 'ee-cancel-form-' . $this->slug(),
537
+				'html_name'             => 'ee-form-submit-'.$this->slug(), // YES! Same name as submit !!!
538
+				'html_id'               => 'ee-cancel-form-'.$this->slug(),
539 539
 				'html_class'            => 'ee-cancel-form',
540 540
 				'html_label'            => '&nbsp;',
541
-				'other_html_attributes' => ' rel="' . $this->slug() . '"',
542
-				'default'               => ! empty( $text ) ? $text : __( 'Cancel', 'event_espresso' )
541
+				'other_html_attributes' => ' rel="'.$this->slug().'"',
542
+				'default'               => ! empty($text) ? $text : __('Cancel', 'event_espresso')
543 543
 			)
544 544
 		);
545
-		$cancel_button->set_button_css_attributes( false );
545
+		$cancel_button->set_button_css_attributes(false);
546 546
 		return $cancel_button;
547 547
 	}
548 548
 
@@ -558,7 +558,7 @@  discard block
 block discarded – undo
558 558
 		$this->form->add_subsections(
559 559
 			array(
560 560
 				'clear-submit-btn-float' => new EE_Form_Section_HTML(
561
-					EEH_HTML::div( '', '', 'clear-float' ) . EEH_HTML::divx()
561
+					EEH_HTML::div('', '', 'clear-float').EEH_HTML::divx()
562 562
 				)
563 563
 			),
564 564
 			null,
@@ -586,9 +586,9 @@  discard block
 block discarded – undo
586 586
 			$form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
587 587
 			|| $form_config === FormHandler::ADD_FORM_TAGS_ONLY
588 588
 		) {
589
-			$form_html .= $this->form()->form_open( $this->formAction() );
589
+			$form_html .= $this->form()->form_open($this->formAction());
590 590
 		}
591
-		$form_html .= $this->form( true )->get_html( $this->form_has_errors );
591
+		$form_html .= $this->form(true)->get_html($this->form_has_errors);
592 592
 		if (
593 593
 			$form_config === FormHandler::ADD_FORM_TAGS_AND_SUBMIT
594 594
 			|| $form_config === FormHandler::ADD_FORM_TAGS_ONLY
@@ -614,12 +614,12 @@  discard block
 block discarded – undo
614 614
 	 * @throws LogicException
615 615
 	 * @throws InvalidFormSubmissionException
616 616
 	 */
617
-	public function process( $submitted_form_data = array() ) {
618
-		if ( ! $this->form()->was_submitted( $submitted_form_data ) ) {
619
-            throw new InvalidFormSubmissionException( $this->form_name );
617
+	public function process($submitted_form_data = array()) {
618
+		if ( ! $this->form()->was_submitted($submitted_form_data)) {
619
+            throw new InvalidFormSubmissionException($this->form_name);
620 620
 		}
621
-        $this->form( true )->receive_form_submission( $submitted_form_data );
622
-		if ( ! $this->form()->is_valid() ) {
621
+        $this->form(true)->receive_form_submission($submitted_form_data);
622
+		if ( ! $this->form()->is_valid()) {
623 623
             throw new InvalidFormSubmissionException(
624 624
 				$this->form_name,
625 625
 				sprintf(
Please login to merge, or discard this patch.
core/services/commands/notices/ConvertNotices.php 1 patch
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -17,58 +17,58 @@
 block discarded – undo
17 17
 abstract class ConvertNotices
18 18
 {
19 19
 
20
-    /**
21
-     * @var CommandHandlerNotices $notices
22
-     */
23
-    private $notices;
20
+	/**
21
+	 * @var CommandHandlerNotices $notices
22
+	 */
23
+	private $notices;
24 24
 
25
-    /**
26
-     * if set to true, then errors will be thrown as exceptions
27
-     *
28
-     * @var boolean $throw_exceptions
29
-     */
30
-    private $throw_exceptions;
25
+	/**
26
+	 * if set to true, then errors will be thrown as exceptions
27
+	 *
28
+	 * @var boolean $throw_exceptions
29
+	 */
30
+	private $throw_exceptions;
31 31
 
32 32
 
33 33
 
34
-    /**
35
-     * ConvertNotices constructor.
36
-     *
37
-     * @param CommandHandlerNotices $notices
38
-     * @param bool                  $throw_exceptions
39
-     */
40
-    public function __construct(CommandHandlerNotices $notices, $throw_exceptions = false)
41
-    {
42
-        $this->notices = $notices;
43
-        $this->throw_exceptions = $throw_exceptions;
44
-    }
34
+	/**
35
+	 * ConvertNotices constructor.
36
+	 *
37
+	 * @param CommandHandlerNotices $notices
38
+	 * @param bool                  $throw_exceptions
39
+	 */
40
+	public function __construct(CommandHandlerNotices $notices, $throw_exceptions = false)
41
+	{
42
+		$this->notices = $notices;
43
+		$this->throw_exceptions = $throw_exceptions;
44
+	}
45 45
 
46 46
 
47 47
 
48
-    /**
49
-     * @return CommandHandlerNotices
50
-     */
51
-    public function getNotices()
52
-    {
53
-        return $this->notices;
54
-    }
48
+	/**
49
+	 * @return CommandHandlerNotices
50
+	 */
51
+	public function getNotices()
52
+	{
53
+		return $this->notices;
54
+	}
55 55
 
56 56
 
57 57
 
58
-    /**
59
-     * @return bool
60
-     */
61
-    public function getThrowExceptions()
62
-    {
63
-        return $this->throw_exceptions;
64
-    }
58
+	/**
59
+	 * @return bool
60
+	 */
61
+	public function getThrowExceptions()
62
+	{
63
+		return $this->throw_exceptions;
64
+	}
65 65
 
66 66
 
67 67
 
68
-    /**
69
-     * Converts CommandHandlerNotice objects into other format
70
-     */
71
-    abstract public function process();
68
+	/**
69
+	 * Converts CommandHandlerNotice objects into other format
70
+	 */
71
+	abstract public function process();
72 72
 
73 73
 
74 74
 }
Please login to merge, or discard this patch.
core/services/commands/notices/CommandHandlerNotice.php 1 patch
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -17,108 +17,108 @@
 block discarded – undo
17 17
 class CommandHandlerNotice
18 18
 {
19 19
 
20
-    const ERROR = 'error';
21
-    const ATTENTION = 'attention';
22
-    const SUCCESS = 'success';
20
+	const ERROR = 'error';
21
+	const ATTENTION = 'attention';
22
+	const SUCCESS = 'success';
23 23
 
24
-    /**
25
-     * @var string $type
26
-     */
27
-    private $type;
24
+	/**
25
+	 * @var string $type
26
+	 */
27
+	private $type;
28 28
 
29 29
 
30
-    /**
31
-     * @var string $message
32
-     */
33
-    private $message;
30
+	/**
31
+	 * @var string $message
32
+	 */
33
+	private $message;
34 34
 
35 35
 
36
-    /**
37
-     * @var string $file
38
-     */
39
-    private $file;
36
+	/**
37
+	 * @var string $file
38
+	 */
39
+	private $file;
40 40
 
41 41
 
42
-    /**
43
-     * @var string $func
44
-     */
45
-    private $func;
42
+	/**
43
+	 * @var string $func
44
+	 */
45
+	private $func;
46 46
 
47 47
 
48
-    /**
49
-     * @var string $line
50
-     */
51
-    private $line;
48
+	/**
49
+	 * @var string $line
50
+	 */
51
+	private $line;
52 52
 
53 53
 
54 54
 
55
-    /**
56
-     * CommandHandlerNotice constructor.
57
-     *
58
-     * @param string $type
59
-     * @param string $message
60
-     * @param string $file
61
-     * @param string $func
62
-     * @param string $line
63
-     */
64
-    public function __construct($type, $message, $file, $func, $line)
65
-    {
66
-        $this->type = $type;
67
-        $this->message = $message;
68
-        $this->file = $file;
69
-        $this->func = $func;
70
-        $this->line = $line;
71
-    }
55
+	/**
56
+	 * CommandHandlerNotice constructor.
57
+	 *
58
+	 * @param string $type
59
+	 * @param string $message
60
+	 * @param string $file
61
+	 * @param string $func
62
+	 * @param string $line
63
+	 */
64
+	public function __construct($type, $message, $file, $func, $line)
65
+	{
66
+		$this->type = $type;
67
+		$this->message = $message;
68
+		$this->file = $file;
69
+		$this->func = $func;
70
+		$this->line = $line;
71
+	}
72 72
 
73 73
 
74 74
 
75
-    /**
76
-     * @return string
77
-     */
78
-    public function type()
79
-    {
80
-        return $this->type;
81
-    }
75
+	/**
76
+	 * @return string
77
+	 */
78
+	public function type()
79
+	{
80
+		return $this->type;
81
+	}
82 82
 
83 83
 
84 84
 
85
-    /**
86
-     * @return string
87
-     */
88
-    public function message()
89
-    {
90
-        return $this->message;
91
-    }
85
+	/**
86
+	 * @return string
87
+	 */
88
+	public function message()
89
+	{
90
+		return $this->message;
91
+	}
92 92
 
93 93
 
94 94
 
95
-    /**
96
-     * @return string
97
-     */
98
-    public function file()
99
-    {
100
-        return $this->file;
101
-    }
95
+	/**
96
+	 * @return string
97
+	 */
98
+	public function file()
99
+	{
100
+		return $this->file;
101
+	}
102 102
 
103 103
 
104 104
 
105
-    /**
106
-     * @return string
107
-     */
108
-    public function func()
109
-    {
110
-        return $this->func;
111
-    }
105
+	/**
106
+	 * @return string
107
+	 */
108
+	public function func()
109
+	{
110
+		return $this->func;
111
+	}
112 112
 
113 113
 
114 114
 
115
-    /**
116
-     * @return string
117
-     */
118
-    public function line()
119
-    {
120
-        return $this->line;
121
-    }
115
+	/**
116
+	 * @return string
117
+	 */
118
+	public function line()
119
+	{
120
+		return $this->line;
121
+	}
122 122
 
123 123
 
124 124
 
Please login to merge, or discard this patch.
core/services/commands/notices/CommandHandlerNotices.php 1 patch
Indentation   +105 added lines, -105 removed lines patch added patch discarded remove patch
@@ -18,151 +18,151 @@
 block discarded – undo
18 18
 {
19 19
 
20 20
 
21
-    /**
22
-     * @var CommandHandlerNotice[] $attention
23
-     */
24
-    private $attention = array();
21
+	/**
22
+	 * @var CommandHandlerNotice[] $attention
23
+	 */
24
+	private $attention = array();
25 25
 
26 26
 
27
-    /**
28
-     * @var CommandHandlerNotice[] $error
29
-     */
30
-    private $error = array();
27
+	/**
28
+	 * @var CommandHandlerNotice[] $error
29
+	 */
30
+	private $error = array();
31 31
 
32 32
 
33
-    /**
34
-     * @var CommandHandlerNotice[] $success
35
-     */
36
-    private $success = array();
33
+	/**
34
+	 * @var CommandHandlerNotice[] $success
35
+	 */
36
+	private $success = array();
37 37
 
38 38
 
39 39
 
40
-    /**
41
-     * @param string $notice
42
-     * @param string $file
43
-     * @param string $func
44
-     * @param string $line
45
-     */
46
-    public function addAttention($notice, $file = '', $func = '', $line = '')
47
-    {
48
-        $this->attention[] = new CommandHandlerNotice(CommandHandlerNotice::ATTENTION, $notice, $file, $func, $line);
49
-    }
40
+	/**
41
+	 * @param string $notice
42
+	 * @param string $file
43
+	 * @param string $func
44
+	 * @param string $line
45
+	 */
46
+	public function addAttention($notice, $file = '', $func = '', $line = '')
47
+	{
48
+		$this->attention[] = new CommandHandlerNotice(CommandHandlerNotice::ATTENTION, $notice, $file, $func, $line);
49
+	}
50 50
 
51 51
 
52 52
 
53
-    /**
54
-     * @param string $notice
55
-     * @param string $file
56
-     * @param string $func
57
-     * @param string $line
58
-     */
59
-    public function addError($notice, $file, $func, $line)
60
-    {
61
-        $this->error[] = new CommandHandlerNotice(CommandHandlerNotice::ERROR, $notice, $file, $func, $line);
62
-    }
53
+	/**
54
+	 * @param string $notice
55
+	 * @param string $file
56
+	 * @param string $func
57
+	 * @param string $line
58
+	 */
59
+	public function addError($notice, $file, $func, $line)
60
+	{
61
+		$this->error[] = new CommandHandlerNotice(CommandHandlerNotice::ERROR, $notice, $file, $func, $line);
62
+	}
63 63
 
64 64
 
65 65
 
66
-    /**
67
-     * @param string $notice
68
-     * @param string $file
69
-     * @param string $func
70
-     * @param string $line
71
-     */
72
-    public function addSuccess($notice, $file = '', $func = '', $line = '')
73
-    {
74
-        $this->success[] = new CommandHandlerNotice(CommandHandlerNotice::SUCCESS, $notice, $file, $func, $line);
75
-    }
66
+	/**
67
+	 * @param string $notice
68
+	 * @param string $file
69
+	 * @param string $func
70
+	 * @param string $line
71
+	 */
72
+	public function addSuccess($notice, $file = '', $func = '', $line = '')
73
+	{
74
+		$this->success[] = new CommandHandlerNotice(CommandHandlerNotice::SUCCESS, $notice, $file, $func, $line);
75
+	}
76 76
 
77 77
 
78 78
 
79
-    /**
80
-     * @return boolean
81
-     */
82
-    public function hasAttention()
83
-    {
84
-        return ! empty($this->attention);
85
-    }
79
+	/**
80
+	 * @return boolean
81
+	 */
82
+	public function hasAttention()
83
+	{
84
+		return ! empty($this->attention);
85
+	}
86 86
 
87 87
 
88 88
 
89
-    /**
90
-     * @return boolean
91
-     */
92
-    public function hasError()
93
-    {
94
-        return ! empty($this->error);
95
-    }
89
+	/**
90
+	 * @return boolean
91
+	 */
92
+	public function hasError()
93
+	{
94
+		return ! empty($this->error);
95
+	}
96 96
 
97 97
 
98 98
 
99
-    /**
100
-     * @return boolean
101
-     */
102
-    public function hasSuccess()
103
-    {
104
-        return ! empty($this->success);
105
-    }
99
+	/**
100
+	 * @return boolean
101
+	 */
102
+	public function hasSuccess()
103
+	{
104
+		return ! empty($this->success);
105
+	}
106 106
 
107 107
 
108 108
 
109
-    /**
110
-     * @return int
111
-     */
112
-    public function countAttention()
113
-    {
114
-        return count($this->attention);
115
-    }
109
+	/**
110
+	 * @return int
111
+	 */
112
+	public function countAttention()
113
+	{
114
+		return count($this->attention);
115
+	}
116 116
 
117 117
 
118 118
 
119
-    /**
120
-     * @return int
121
-     */
122
-    public function countError()
123
-    {
124
-        return count($this->error);
125
-    }
119
+	/**
120
+	 * @return int
121
+	 */
122
+	public function countError()
123
+	{
124
+		return count($this->error);
125
+	}
126 126
 
127 127
 
128 128
 
129
-    /**
130
-     * @return int
131
-     */
132
-    public function countSuccess()
133
-    {
134
-        return count($this->success);
135
-    }
129
+	/**
130
+	 * @return int
131
+	 */
132
+	public function countSuccess()
133
+	{
134
+		return count($this->success);
135
+	}
136 136
 
137 137
 
138 138
 
139
-    /**
140
-     * @return CommandHandlerNotice[]
141
-     */
142
-    public function getAttention()
143
-    {
144
-        return $this->attention;
145
-    }
139
+	/**
140
+	 * @return CommandHandlerNotice[]
141
+	 */
142
+	public function getAttention()
143
+	{
144
+		return $this->attention;
145
+	}
146 146
 
147 147
 
148 148
 
149
-    /**
150
-     * @return CommandHandlerNotice[]
151
-     */
152
-    public function getError()
153
-    {
154
-        return $this->error;
155
-    }
149
+	/**
150
+	 * @return CommandHandlerNotice[]
151
+	 */
152
+	public function getError()
153
+	{
154
+		return $this->error;
155
+	}
156 156
 
157 157
 
158 158
 
159
-    /**
160
-     * @return CommandHandlerNotice[]
161
-     */
162
-    public function getSuccess()
163
-    {
164
-        return $this->success;
165
-    }
159
+	/**
160
+	 * @return CommandHandlerNotice[]
161
+	 */
162
+	public function getSuccess()
163
+	{
164
+		return $this->success;
165
+	}
166 166
 
167 167
 
168 168
 }
Please login to merge, or discard this patch.
core/services/commands/notices/ConvertNoticesToEeErrors.php 2 patches
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -21,56 +21,56 @@
 block discarded – undo
21 21
 
22 22
 
23 23
 
24
-    /**
25
-     * Converts CommandHandlerNotice objects into EE_Error notifications
26
-     *
27
-     * @throws EE_Error
28
-     */
29
-    public function process()
30
-    {
31
-        // \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
32
-        if ($this->getNotices()->hasAttention()) {
33
-            foreach ($this->getNotices()->getAttention() as $notice) {
34
-                // \EEH_Debug_Tools::printr($notice->message(), $notice->type(), __FILE__, __LINE__);
35
-                EE_Error::add_attention(
36
-                    $notice->message(),
37
-                    $notice->file(),
38
-                    $notice->func(),
39
-                    $notice->line()
40
-                );
41
-            }
42
-        }
43
-        if ($this->getNotices()->hasError()) {
44
-            $error_string = esc_html__('The following errors occurred:', 'event_espresso');
45
-            foreach ($this->getNotices()->getError() as $notice) {
46
-                // \EEH_Debug_Tools::printr($notice->message(), $notice->type(), __FILE__, __LINE__);
47
-                if ($this->getThrowExceptions()) {
48
-                    $error_string .= '<br />' . $notice->message();
49
-                } else {
50
-                    EE_Error::add_error(
51
-                        $notice->message(),
52
-                        $notice->file(),
53
-                        $notice->func(),
54
-                        $notice->line()
55
-                    );
56
-                }
57
-            }
58
-            if ($this->getThrowExceptions()) {
59
-                throw new EE_Error($error_string);
60
-            }
61
-        }
62
-        if ($this->getNotices()->hasSuccess()) {
63
-            foreach ($this->getNotices()->getSuccess() as $notice) {
64
-                // \EEH_Debug_Tools::printr($notice->message(), $notice->type(), __FILE__, __LINE__);
65
-                EE_Error::add_success(
66
-                    $notice->message(),
67
-                    $notice->file(),
68
-                    $notice->func(),
69
-                    $notice->line()
70
-                );
71
-            }
72
-        }
73
-    }
24
+	/**
25
+	 * Converts CommandHandlerNotice objects into EE_Error notifications
26
+	 *
27
+	 * @throws EE_Error
28
+	 */
29
+	public function process()
30
+	{
31
+		// \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
32
+		if ($this->getNotices()->hasAttention()) {
33
+			foreach ($this->getNotices()->getAttention() as $notice) {
34
+				// \EEH_Debug_Tools::printr($notice->message(), $notice->type(), __FILE__, __LINE__);
35
+				EE_Error::add_attention(
36
+					$notice->message(),
37
+					$notice->file(),
38
+					$notice->func(),
39
+					$notice->line()
40
+				);
41
+			}
42
+		}
43
+		if ($this->getNotices()->hasError()) {
44
+			$error_string = esc_html__('The following errors occurred:', 'event_espresso');
45
+			foreach ($this->getNotices()->getError() as $notice) {
46
+				// \EEH_Debug_Tools::printr($notice->message(), $notice->type(), __FILE__, __LINE__);
47
+				if ($this->getThrowExceptions()) {
48
+					$error_string .= '<br />' . $notice->message();
49
+				} else {
50
+					EE_Error::add_error(
51
+						$notice->message(),
52
+						$notice->file(),
53
+						$notice->func(),
54
+						$notice->line()
55
+					);
56
+				}
57
+			}
58
+			if ($this->getThrowExceptions()) {
59
+				throw new EE_Error($error_string);
60
+			}
61
+		}
62
+		if ($this->getNotices()->hasSuccess()) {
63
+			foreach ($this->getNotices()->getSuccess() as $notice) {
64
+				// \EEH_Debug_Tools::printr($notice->message(), $notice->type(), __FILE__, __LINE__);
65
+				EE_Error::add_success(
66
+					$notice->message(),
67
+					$notice->file(),
68
+					$notice->func(),
69
+					$notice->line()
70
+				);
71
+			}
72
+		}
73
+	}
74 74
 
75 75
 
76 76
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -45,7 +45,7 @@
 block discarded – undo
45 45
             foreach ($this->getNotices()->getError() as $notice) {
46 46
                 // \EEH_Debug_Tools::printr($notice->message(), $notice->type(), __FILE__, __LINE__);
47 47
                 if ($this->getThrowExceptions()) {
48
-                    $error_string .= '<br />' . $notice->message();
48
+                    $error_string .= '<br />'.$notice->message();
49 49
                 } else {
50 50
                     EE_Error::add_error(
51 51
                         $notice->message(),
Please login to merge, or discard this patch.
core/services/commands/middleware/CapChecker.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -9,7 +9,7 @@  discard block
 block discarded – undo
9 9
 use EventEspresso\core\services\commands\CommandRequiresCapCheckInterface;
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
 
@@ -29,41 +29,41 @@  discard block
 block discarded – undo
29 29
 class CapChecker implements CommandBusMiddlewareInterface
30 30
 {
31 31
 
32
-    /**
33
-     * @type CapabilitiesCheckerInterface $capabilities_checker
34
-     */
35
-    private $capabilities_checker;
32
+	/**
33
+	 * @type CapabilitiesCheckerInterface $capabilities_checker
34
+	 */
35
+	private $capabilities_checker;
36 36
 
37 37
 
38 38
 
39
-    /**
40
-     * CapChecker constructor
41
-     *
42
-     * @param CapabilitiesCheckerInterface $capabilities_checker
43
-     */
44
-    public function __construct(CapabilitiesCheckerInterface $capabilities_checker)
45
-    {
46
-        $this->capabilities_checker = $capabilities_checker;
47
-    }
39
+	/**
40
+	 * CapChecker constructor
41
+	 *
42
+	 * @param CapabilitiesCheckerInterface $capabilities_checker
43
+	 */
44
+	public function __construct(CapabilitiesCheckerInterface $capabilities_checker)
45
+	{
46
+		$this->capabilities_checker = $capabilities_checker;
47
+	}
48 48
 
49 49
 
50 50
 
51
-    /**
52
-     * @param CommandInterface $command
53
-     * @param Closure         $next
54
-     * @return mixed
55
-     * @throws InvalidClassException
56
-     * @throws InsufficientPermissionsException
57
-     */
58
-    public function handle(CommandInterface $command, Closure $next)
59
-    {
60
-        if ($command instanceof CommandRequiresCapCheckInterface) {
61
-            $this->capabilities_checker->processCapCheck(
62
-                $command->getCapCheck()
63
-            );
64
-        }
65
-        return $next($command);
66
-    }
51
+	/**
52
+	 * @param CommandInterface $command
53
+	 * @param Closure         $next
54
+	 * @return mixed
55
+	 * @throws InvalidClassException
56
+	 * @throws InsufficientPermissionsException
57
+	 */
58
+	public function handle(CommandInterface $command, Closure $next)
59
+	{
60
+		if ($command instanceof CommandRequiresCapCheckInterface) {
61
+			$this->capabilities_checker->processCapCheck(
62
+				$command->getCapCheck()
63
+			);
64
+		}
65
+		return $next($command);
66
+	}
67 67
 
68 68
 
69 69
 }
Please login to merge, or discard this patch.