Completed
Branch FET-11170-model-use-money-enti... (303cb4)
by
unknown
68:01 queued 57:04
created
core/db_models/EEM_Question.model.php 2 patches
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -71,10 +71,10 @@  discard block
 block discarded – undo
71 71
 	 *
72 72
 	 * @access protected
73 73
 	 * @var array $_question_type_categories {
74
-     * @type string $text
75
-     * @type string $single-answer-enum
76
-     * @type string $multi-answer-enum
77
-     *                    }
74
+	 * @type string $text
75
+	 * @type string $single-answer-enum
76
+	 * @type string $multi-answer-enum
77
+	 *                    }
78 78
 	 */
79 79
 	protected $_question_type_categories = array();
80 80
 
@@ -156,14 +156,14 @@  discard block
 block discarded – undo
156 156
 				'text' => array(
157 157
 					EEM_Question::QST_type_text,
158 158
 					EEM_Question::QST_type_textarea,
159
-                    EEM_Question::QST_type_date,
159
+					EEM_Question::QST_type_date,
160 160
 					EEM_Question::QST_type_html_textarea,
161 161
 					EEM_Question::QST_type_email,
162 162
 					EEM_Question::QST_type_us_phone,
163 163
 					EEM_Question::QST_type_decimal,
164
-                    EEM_Question::QST_type_int,
164
+					EEM_Question::QST_type_int,
165 165
 					EEM_Question::QST_type_url,
166
-                    EEM_Question::QST_type_year
166
+					EEM_Question::QST_type_year
167 167
 					),
168 168
 				'single-answer-enum' => array(
169 169
 					EEM_Question::QST_type_radio,
@@ -251,32 +251,32 @@  discard block
 block discarded – undo
251 251
 
252 252
 
253 253
 
254
-    /**
255
-     * Returns all the question types in the given category
256
-     * @param string $category
257
-     * @return array|mixed
258
-     */
254
+	/**
255
+	 * Returns all the question types in the given category
256
+	 * @param string $category
257
+	 * @return array|mixed
258
+	 */
259 259
 	public function question_types_in_category($category)
260
-    {
261
-        if( isset($this->_question_type_categories[$category])) {
262
-            return $this->_question_type_categories[$category];
263
-        }
264
-        return array();
265
-    }
266
-
267
-
268
-
269
-    /**
270
-     * Returns all the question types that should have question options
271
-     * @return array
272
-     */
273
-    public function question_types_with_options()
274
-    {
275
-        return array_merge(
276
-            $this->question_types_in_category('single-answer-enum'),
277
-            $this->question_types_in_category('multi-answer-enum')
278
-        );
279
-    }
260
+	{
261
+		if( isset($this->_question_type_categories[$category])) {
262
+			return $this->_question_type_categories[$category];
263
+		}
264
+		return array();
265
+	}
266
+
267
+
268
+
269
+	/**
270
+	 * Returns all the question types that should have question options
271
+	 * @return array
272
+	 */
273
+	public function question_types_with_options()
274
+	{
275
+		return array_merge(
276
+			$this->question_types_in_category('single-answer-enum'),
277
+			$this->question_types_in_category('multi-answer-enum')
278
+		);
279
+	}
280 280
 
281 281
 	/**
282 282
 	 * Returns the question type categories 2d array
Please login to merge, or discard this patch.
Spacing   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -1,8 +1,8 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
 	exit('No direct script access allowed');
3 3
 }
4
-require_once( EE_MODELS . 'EEM_Soft_Delete_Base.model.php' );
5
-require_once( EE_CLASSES . 'EE_Question.class.php' );
4
+require_once(EE_MODELS.'EEM_Soft_Delete_Base.model.php');
5
+require_once(EE_CLASSES.'EE_Question.class.php');
6 6
 
7 7
 
8 8
 
@@ -105,52 +105,52 @@  discard block
 block discarded – undo
105 105
 	 *
106 106
 	 * @param null $timezone
107 107
 	 */
108
-	protected function __construct( $timezone = NULL ) {
109
-		$this->singular_item = __('Question','event_espresso');
110
-		$this->plural_item = __('Questions','event_espresso');
111
-		$this->_allowed_question_types=apply_filters(
108
+	protected function __construct($timezone = NULL) {
109
+		$this->singular_item = __('Question', 'event_espresso');
110
+		$this->plural_item = __('Questions', 'event_espresso');
111
+		$this->_allowed_question_types = apply_filters(
112 112
 			'FHEE__EEM_Question__construct__allowed_question_types',
113 113
 			array(
114
-				EEM_Question::QST_type_text =>__('Text','event_espresso'),
115
-				EEM_Question::QST_type_textarea =>__('Textarea','event_espresso'),
116
-				EEM_Question::QST_type_checkbox =>__('Checkboxes','event_espresso'),
117
-				EEM_Question::QST_type_radio =>__('Radio Buttons','event_espresso'),
118
-				EEM_Question::QST_type_dropdown =>__('Dropdown','event_espresso'),
119
-				EEM_Question::QST_type_state =>__('State/Province Dropdown','event_espresso'),
120
-				EEM_Question::QST_type_country =>__('Country Dropdown','event_espresso'),
121
-				EEM_Question::QST_type_date =>__('Date Picker','event_espresso'),
122
-				EEM_Question::QST_type_html_textarea => __( 'HTML Textarea', 'event_espresso' ),
123
-				EEM_Question::QST_type_email => __( 'Email', 'event_espresso' ),
124
-				EEM_Question::QST_type_us_phone => __( 'USA - Format Phone', 'event_espresso' ),
125
-				EEM_Question::QST_type_decimal => __( 'Number', 'event_espresso' ),
126
-				EEM_Question::QST_type_int => __( 'Whole Number', 'event_espresso' ),
127
-				EEM_Question::QST_type_url => __( 'URL', 'event_espresso' ),
128
-				EEM_Question::QST_type_year => __( 'Year', 'event_espresso' ),
129
-				EEM_Question::QST_type_multi_select => __( 'Multi Select', 'event_espresso' )
114
+				EEM_Question::QST_type_text =>__('Text', 'event_espresso'),
115
+				EEM_Question::QST_type_textarea =>__('Textarea', 'event_espresso'),
116
+				EEM_Question::QST_type_checkbox =>__('Checkboxes', 'event_espresso'),
117
+				EEM_Question::QST_type_radio =>__('Radio Buttons', 'event_espresso'),
118
+				EEM_Question::QST_type_dropdown =>__('Dropdown', 'event_espresso'),
119
+				EEM_Question::QST_type_state =>__('State/Province Dropdown', 'event_espresso'),
120
+				EEM_Question::QST_type_country =>__('Country Dropdown', 'event_espresso'),
121
+				EEM_Question::QST_type_date =>__('Date Picker', 'event_espresso'),
122
+				EEM_Question::QST_type_html_textarea => __('HTML Textarea', 'event_espresso'),
123
+				EEM_Question::QST_type_email => __('Email', 'event_espresso'),
124
+				EEM_Question::QST_type_us_phone => __('USA - Format Phone', 'event_espresso'),
125
+				EEM_Question::QST_type_decimal => __('Number', 'event_espresso'),
126
+				EEM_Question::QST_type_int => __('Whole Number', 'event_espresso'),
127
+				EEM_Question::QST_type_url => __('URL', 'event_espresso'),
128
+				EEM_Question::QST_type_year => __('Year', 'event_espresso'),
129
+				EEM_Question::QST_type_multi_select => __('Multi Select', 'event_espresso')
130 130
 			)
131 131
 		);
132 132
 		$this->_question_descriptions = apply_filters(
133 133
 			'FHEE__EEM_Question__construct__allowed_question_types',
134 134
 			array(
135
-				EEM_Question::QST_type_text          => __( 'A single line text input field', 'event_espresso' ),
136
-				EEM_Question::QST_type_textarea      => __( 'A multi line text input field', 'event_espresso' ),
137
-				EEM_Question::QST_type_checkbox      => __( 'Allows multiple preset options to be selected', 'event_espresso' ),
138
-				EEM_Question::QST_type_radio         => __( 'Allows a single preset option to be selected', 'event_espresso' ),
139
-				EEM_Question::QST_type_dropdown      => __( 'A dropdown that allows a single selection', 'event_espresso' ),
140
-				EEM_Question::QST_type_state         => __( 'A dropdown that lists states/provinces', 'event_espresso' ),
141
-				EEM_Question::QST_type_country       => __( 'A dropdown that lists countries', 'event_espresso' ),
142
-				EEM_Question::QST_type_date          => __( 'A popup calendar that allows date selections', 'event_espresso' ),
143
-				EEM_Question::QST_type_html_textarea => __( 'A multi line text input field that allows HTML', 'event_espresso' ),
144
-				EEM_Question::QST_type_email         => __( 'A text field that must contain a valid Email address', 'event_espresso' ),
145
-				EEM_Question::QST_type_us_phone      => __( 'A text field that must contain a valid US phone number', 'event_espresso' ),
146
-				EEM_Question::QST_type_decimal       => __( 'A text field that allows number values with decimals', 'event_espresso' ),
147
-				EEM_Question::QST_type_int           => __( 'A text field that only allows whole numbers (no decimals)', 'event_espresso' ),
148
-				EEM_Question::QST_type_url           => __( 'A text field that must contain a valid URL', 'event_espresso' ),
149
-				EEM_Question::QST_type_year          => __( 'A dropdown that lists the last 100 years', 'event_espresso' ),
150
-				EEM_Question::QST_type_multi_select  => __( 'A dropdown that allows multiple selections', 'event_espresso' )
135
+				EEM_Question::QST_type_text          => __('A single line text input field', 'event_espresso'),
136
+				EEM_Question::QST_type_textarea      => __('A multi line text input field', 'event_espresso'),
137
+				EEM_Question::QST_type_checkbox      => __('Allows multiple preset options to be selected', 'event_espresso'),
138
+				EEM_Question::QST_type_radio         => __('Allows a single preset option to be selected', 'event_espresso'),
139
+				EEM_Question::QST_type_dropdown      => __('A dropdown that allows a single selection', 'event_espresso'),
140
+				EEM_Question::QST_type_state         => __('A dropdown that lists states/provinces', 'event_espresso'),
141
+				EEM_Question::QST_type_country       => __('A dropdown that lists countries', 'event_espresso'),
142
+				EEM_Question::QST_type_date          => __('A popup calendar that allows date selections', 'event_espresso'),
143
+				EEM_Question::QST_type_html_textarea => __('A multi line text input field that allows HTML', 'event_espresso'),
144
+				EEM_Question::QST_type_email         => __('A text field that must contain a valid Email address', 'event_espresso'),
145
+				EEM_Question::QST_type_us_phone      => __('A text field that must contain a valid US phone number', 'event_espresso'),
146
+				EEM_Question::QST_type_decimal       => __('A text field that allows number values with decimals', 'event_espresso'),
147
+				EEM_Question::QST_type_int           => __('A text field that only allows whole numbers (no decimals)', 'event_espresso'),
148
+				EEM_Question::QST_type_url           => __('A text field that must contain a valid URL', 'event_espresso'),
149
+				EEM_Question::QST_type_year          => __('A dropdown that lists the last 100 years', 'event_espresso'),
150
+				EEM_Question::QST_type_multi_select  => __('A dropdown that allows multiple selections', 'event_espresso')
151 151
 			)
152 152
 		);
153
-		$this->_question_type_categories = (array)apply_filters(
153
+		$this->_question_type_categories = (array) apply_filters(
154 154
 				'FHEE__EEM_Question__construct__question_type_categories',
155 155
 				array(
156 156
 				'text' => array(
@@ -177,22 +177,22 @@  discard block
 block discarded – undo
177 177
 		);
178 178
 
179 179
 		$this->_tables = array(
180
-			'Question'=>new EE_Primary_Table('esp_question','QST_ID')
180
+			'Question'=>new EE_Primary_Table('esp_question', 'QST_ID')
181 181
 		);
182 182
 		$this->_fields = array(
183 183
 			'Question'=>array(
184
-				'QST_ID'=>new EE_Primary_Key_Int_Field('QST_ID', __('Question ID','event_espresso')),
185
-				'QST_display_text'=>new EE_Post_Content_Field('QST_display_text', __('Question Text','event_espresso'), true, ''),
186
-				'QST_admin_label'=>new EE_Plain_Text_Field('QST_admin_label', __('Question Label (admin-only)','event_espresso'), true, ''),
187
-				'QST_system'=>new EE_Plain_Text_Field('QST_system', __('Internal string ID for question','event_espresso'), false, '' ),
188
-				'QST_type'=>new EE_Enum_Text_Field('QST_type', __('Question Type','event_espresso'),false, 'TEXT',$this->_allowed_question_types),
189
-				'QST_required'=>new EE_Boolean_Field('QST_required', __('Required Question?','event_espresso'), false, false),
190
-				'QST_required_text'=>new EE_Simple_HTML_Field('QST_required_text', __('Text to Display if Not Provided','event_espresso'), true, ''),
191
-				'QST_order'=>new EE_Integer_Field('QST_order', __('Question Order','event_espresso'), false, 0),
192
-				'QST_admin_only'=>new EE_Boolean_Field('QST_admin_only', __('Admin-Only Question?','event_espresso'), false, false),
193
-				'QST_max' => new EE_Infinite_Integer_Field( 'QST_max', __( 'Max Size', 'event_espresso'	), false, EE_INF ),
194
-				'QST_wp_user'=>new EE_WP_User_Field('QST_wp_user', __('Question Creator ID','event_espresso'), false ),
195
-				'QST_deleted'=>new EE_Trashed_Flag_Field('QST_deleted', __('Flag Indicating question was deleted','event_espresso'), false, false)
184
+				'QST_ID'=>new EE_Primary_Key_Int_Field('QST_ID', __('Question ID', 'event_espresso')),
185
+				'QST_display_text'=>new EE_Post_Content_Field('QST_display_text', __('Question Text', 'event_espresso'), true, ''),
186
+				'QST_admin_label'=>new EE_Plain_Text_Field('QST_admin_label', __('Question Label (admin-only)', 'event_espresso'), true, ''),
187
+				'QST_system'=>new EE_Plain_Text_Field('QST_system', __('Internal string ID for question', 'event_espresso'), false, ''),
188
+				'QST_type'=>new EE_Enum_Text_Field('QST_type', __('Question Type', 'event_espresso'), false, 'TEXT', $this->_allowed_question_types),
189
+				'QST_required'=>new EE_Boolean_Field('QST_required', __('Required Question?', 'event_espresso'), false, false),
190
+				'QST_required_text'=>new EE_Simple_HTML_Field('QST_required_text', __('Text to Display if Not Provided', 'event_espresso'), true, ''),
191
+				'QST_order'=>new EE_Integer_Field('QST_order', __('Question Order', 'event_espresso'), false, 0),
192
+				'QST_admin_only'=>new EE_Boolean_Field('QST_admin_only', __('Admin-Only Question?', 'event_espresso'), false, false),
193
+				'QST_max' => new EE_Infinite_Integer_Field('QST_max', __('Max Size', 'event_espresso'), false, EE_INF),
194
+				'QST_wp_user'=>new EE_WP_User_Field('QST_wp_user', __('Question Creator ID', 'event_espresso'), false),
195
+				'QST_deleted'=>new EE_Trashed_Flag_Field('QST_deleted', __('Flag Indicating question was deleted', 'event_espresso'), false, false)
196 196
 			)
197 197
 		);
198 198
 		$this->_model_relations = array(
@@ -204,11 +204,11 @@  discard block
 block discarded – undo
204 204
 			'Question_Group_Question'=>new EE_Has_Many_Relation()
205 205
 		);
206 206
 		//this model is generally available for reading
207
-		$this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
208
-		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Reg_Form('QST_system');
209
-		$this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Reg_Form('QST_system');
210
-		$this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Reg_Form('QST_system');
211
-		parent::__construct( $timezone );
207
+		$this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Public();
208
+		$this->_cap_restriction_generators[EEM_Base::caps_read_admin] = new EE_Restriction_Generator_Reg_Form('QST_system');
209
+		$this->_cap_restriction_generators[EEM_Base::caps_edit] = new EE_Restriction_Generator_Reg_Form('QST_system');
210
+		$this->_cap_restriction_generators[EEM_Base::caps_delete] = new EE_Restriction_Generator_Reg_Form('QST_system');
211
+		parent::__construct($timezone);
212 212
 	}
213 213
 
214 214
 	/**
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
 	 * but they can be extended
217 217
 	 * @return string[]
218 218
 	 */
219
-	public function allowed_question_types(){
219
+	public function allowed_question_types() {
220 220
 		return $this->_allowed_question_types;
221 221
 	}
222 222
 	/**
@@ -224,16 +224,16 @@  discard block
 block discarded – undo
224 224
 	 * @param string $question_type one of EEM_Question::allowed_question_types(
225 225
 	 * @return string[] like EEM_Question::allowed_question_types()
226 226
 	 */
227
-	public function question_types_in_same_category( $question_type ) {
228
-		$question_types = array( $question_type );
229
-		foreach( $this->_question_type_categories as $category => $question_types_in_category ) {
230
-			if( in_array( $question_type, $question_types_in_category ) ) {
227
+	public function question_types_in_same_category($question_type) {
228
+		$question_types = array($question_type);
229
+		foreach ($this->_question_type_categories as $category => $question_types_in_category) {
230
+			if (in_array($question_type, $question_types_in_category)) {
231 231
 				$question_types = $question_types_in_category;
232 232
 				break;
233 233
 			}
234 234
 		}
235 235
 
236
-		return array_intersect_key( $this->allowed_question_types(), array_flip( $question_types ) );
236
+		return array_intersect_key($this->allowed_question_types(), array_flip($question_types));
237 237
 	}
238 238
 
239 239
 	/**
@@ -242,11 +242,11 @@  discard block
 block discarded – undo
242 242
 	 * @param string $category one of the top-level keys of EEM_Question::question_type_categories()
243 243
 	 * @return boolean
244 244
 	 */
245
-	public function question_type_is_in_category( $question_type, $category ) {
246
-		if( ! isset( $this->_question_type_categories[ $category ] ) ) {
245
+	public function question_type_is_in_category($question_type, $category) {
246
+		if ( ! isset($this->_question_type_categories[$category])) {
247 247
 			return false;
248 248
 		}
249
-		return in_array( $question_type, $this->_question_type_categories[ $category ] );
249
+		return in_array($question_type, $this->_question_type_categories[$category]);
250 250
 	}
251 251
 
252 252
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
      */
259 259
 	public function question_types_in_category($category)
260 260
     {
261
-        if( isset($this->_question_type_categories[$category])) {
261
+        if (isset($this->_question_type_categories[$category])) {
262 262
             return $this->_question_type_categories[$category];
263 263
         }
264 264
         return array();
@@ -292,9 +292,9 @@  discard block
 block discarded – undo
292 292
 	 * @param string $system_question_group_id QSG_system
293 293
 	 * @return array of system question names (QST_system)
294 294
 	 */
295
-	public function allowed_system_questions_in_system_question_group( $system_question_group_id ) {
295
+	public function allowed_system_questions_in_system_question_group($system_question_group_id) {
296 296
 		$question_system_ids = array();
297
-		switch( $system_question_group_id ) {
297
+		switch ($system_question_group_id) {
298 298
 			case EEM_Question_Group::system_personal:
299 299
 				$question_system_ids = array(
300 300
 					EEM_Attendee::system_question_fname,
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
 				);
316 316
 				break;
317 317
 		}
318
-		return apply_filters( 'FHEE__EEM_Question__system_questions_allowed_in_system_question_group__return', $question_system_ids, $system_question_group_id );
318
+		return apply_filters('FHEE__EEM_Question__system_questions_allowed_in_system_question_group__return', $question_system_ids, $system_question_group_id);
319 319
 	}
320 320
 
321 321
 	/**
@@ -324,11 +324,11 @@  discard block
 block discarded – undo
324 324
 	 * @param string $system_question_group_id QSG_system
325 325
 	 * @return array of system question names (QST_system)
326 326
 	 */
327
-	public function required_system_questions_in_system_question_group( $system_question_group_id ) {
327
+	public function required_system_questions_in_system_question_group($system_question_group_id) {
328 328
 		$question_system_ids = null;
329
-		switch( $system_question_group_id ) {
329
+		switch ($system_question_group_id) {
330 330
 			case EEM_Question_Group::system_personal:
331
-				$question_system_ids =  array(
331
+				$question_system_ids = array(
332 332
 					EEM_Attendee::system_question_fname,
333 333
 					EEM_Attendee::system_question_email,
334 334
 				);
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
 			default:
337 337
 				$question_system_ids = array();
338 338
 		}
339
-		return apply_filters( 'FHEE__EEM_Question__system_questions_required_in_system_question_group', $question_system_ids, $system_question_group_id );
339
+		return apply_filters('FHEE__EEM_Question__system_questions_required_in_system_question_group', $question_system_ids, $system_question_group_id);
340 340
 	}
341 341
 
342 342
 
@@ -347,8 +347,8 @@  discard block
 block discarded – undo
347 347
 	 * @param $QST_system
348 348
 	 * @return int of QST_ID for the question that corresponds to that QST_system
349 349
 	 */
350
-	public function get_Question_ID_from_system_string( $QST_system ){
351
-		 return $this->get_var( array( array( 'QST_system' => $QST_system ) ) );
350
+	public function get_Question_ID_from_system_string($QST_system) {
351
+		 return $this->get_var(array(array('QST_system' => $QST_system)));
352 352
 	}
353 353
 
354 354
 
@@ -360,10 +360,10 @@  discard block
 block discarded – undo
360 360
 	 */
361 361
 	public function get_latest_question_order() {
362 362
 		$columns_to_select = array(
363
-			'max_order' => array("MAX(QST_order)","%d")
363
+			'max_order' => array("MAX(QST_order)", "%d")
364 364
 		);
365
-		$max = $this->_get_all_wpdb_results( array(), ARRAY_A, $columns_to_select );
366
-		return isset( $max[0], $max[0]['max_order'] ) ? $max[0]['max_order'] : 0;
365
+		$max = $this->_get_all_wpdb_results(array(), ARRAY_A, $columns_to_select);
366
+		return isset($max[0], $max[0]['max_order']) ? $max[0]['max_order'] : 0;
367 367
 	}
368 368
 
369 369
 	/**
@@ -392,10 +392,10 @@  discard block
 block discarded – undo
392 392
 	 * @param string $system_question_value
393 393
 	 * @return int|float
394 394
 	 */
395
-	public function absolute_max_for_system_question( $system_question_value ) {
395
+	public function absolute_max_for_system_question($system_question_value) {
396 396
 		$maxes = $this->system_question_maxes();
397
-		if( isset( $maxes[ $system_question_value ] ) ) {
398
-			return $maxes[ $system_question_value ];
397
+		if (isset($maxes[$system_question_value])) {
398
+			return $maxes[$system_question_value];
399 399
 		} else {
400 400
 			return EE_INF;
401 401
 		}
Please login to merge, or discard this patch.
display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php 2 patches
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -17,157 +17,157 @@  discard block
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * enqueues css and js, so that this can be called statically
22
-     */
23
-    public static function enqueue_styles_and_scripts()
24
-    {
25
-        wp_register_style(
26
-            'checkbox_dropdown_selector',
27
-            EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
28
-            array('espresso_default'),
29
-            EVENT_ESPRESSO_VERSION
30
-        );
31
-        wp_register_style(
32
-            'espresso_default',
33
-            EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
34
-            array('dashicons'),
35
-            EVENT_ESPRESSO_VERSION
36
-        );
37
-        wp_enqueue_style('checkbox_dropdown_selector');
38
-        wp_register_script(
39
-            'checkbox_dropdown_selector',
40
-            EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
41
-            array('jquery'),
42
-            EVENT_ESPRESSO_VERSION,
43
-            true
44
-        );
45
-        wp_enqueue_script('checkbox_dropdown_selector');
46
-    }
47
-
48
-
49
-
50
-    /**
51
-     * Informs the rest of the forms system what CSS and JS is needed to display the input
52
-     */
53
-    public function enqueue_js(){
54
-        EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
55
-    }
56
-
57
-
58
-
59
-    /**
60
-     * callback for Iframe::addStylesheets() child class methods
61
-     *
62
-     * @param array $iframe_css
63
-     * @return array
64
-     */
65
-    public function iframe_css(array $iframe_css){
66
-        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
67
-        return $iframe_css;
68
-    }
69
-
70
-
71
-
72
-    /**
73
-     * callback for Iframe::addScripts() child class methods
74
-     *
75
-     * @param array $iframe_js
76
-     * @return array
77
-     */
78
-    public function iframe_js(array $iframe_js){
79
-        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
80
-        return $iframe_js;
81
-    }
82
-
83
-
84
-    /**
85
-     * @throws EE_Error
86
-     * @return string of html to display the field
87
-     */
88
-    public function display()
89
-    {
90
-        $input = $this->get_input();
91
-        $select_button_text = $input instanceof EE_Checkbox_Dropdown_Selector_Input ? $input->select_button_text() : '';
92
-        // $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
93
-        $input->set_label_sizes();
94
-        $label_size_class = $input->get_label_size_class();
95
-        if ( ! is_array($input->raw_value()) && $input->raw_value() !== null) {
96
-            EE_Error::doing_it_wrong(
97
-                'EE_Checkbox_Display_Strategy::display()',
98
-                sprintf(
99
-                    esc_html__(
100
-                        'Input values for checkboxes should be an array of values, but the value for input "%1$s" is "%2$s". Please verify that the input name is exactly "%3$s"',
101
-                        'event_espresso'
102
-                    ),
103
-                    $input->html_id(),
104
-                    var_export($input->raw_value(), true),
105
-                    $input->html_name() . '[]'
106
-                ),
107
-                '4.8.1'
108
-            );
109
-        }
110
-
111
-
112
-        $html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
113
-        $html .= '<button id="' . $input->html_id() . '-btn"';
114
-        // $html .= ' name="' . $input->html_name() . '"';
115
-        $html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button-secondary button"';
116
-        $html .= ' style="' . $input->html_style() . '"';
117
-        $html .= ' data-target="' . $input->html_id() . '-options-dv"';
118
-        $html .= ' ' . $input->html_other_attributes() . '>';
119
-        $html .= '<span class="checkbox-dropdown-selector-selected-spn">';
120
-        $html .= $select_button_text;
121
-        $html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
122
-        $html .= '</button>';
123
-        $html .= EEH_HTML::div(
124
-            '',
125
-            $input->html_id() . '-options-dv',
126
-            'checkbox-dropdown-selector'
127
-        );
128
-        $html .= EEH_HTML::link(
129
-            '',
130
-            '<span class="dashicons dashicons-no"></span>',
131
-            esc_html__('close datetime selector', 'event_espresso'),
132
-            '',
133
-            'close-espresso-notice'
134
-        );
135
-        $html .= EEH_HTML::ul();
136
-        $input_raw_value = (array)$input->raw_value();
137
-        foreach ($input->options() as $value => $display_text) {
138
-            $html .= EEH_HTML::li();
139
-            $value = $input->get_normalization_strategy()->unnormalize_one($value);
140
-            $html_id = $this->get_sub_input_id($value);
141
-            $html .= EEH_HTML::nl(0, 'checkbox');
142
-            $html .= '<label for="'
143
-                     . $html_id
144
-                     . '" id="'
145
-                     . $html_id
146
-                     . '-lbl" class="ee-checkbox-label-after'
147
-                     . $label_size_class
148
-                     . '">';
149
-            $html .= EEH_HTML::nl(1, 'checkbox');
150
-            $html .= '<input type="checkbox"';
151
-            $html .= ' name="' . $input->html_name() . '[]"';
152
-            $html .= ' id="' . $html_id . '"';
153
-            $html .= ' class="' . $input->html_class() . '-option"';
154
-            $html .= ' style="' . $input->html_style() . '"';
155
-            $html .= ' value="' . esc_attr($value) . '"';
156
-            $html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
157
-                ? ' checked="checked"'
158
-                : '';
159
-            $html .= ' ' . $this->_input->other_html_attributes();
160
-            $html .= '>';
161
-            $html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
162
-            $html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
163
-            $html .= EEH_HTML::lix();
164
-        }
165
-        $html .= EEH_HTML::ulx();
166
-        $html .= EEH_HTML::divx();
167
-        $html .= EEH_HTML::divx();
168
-        $html .= \EEH_HTML::br();
169
-        return $html;
170
-    }
20
+	/**
21
+	 * enqueues css and js, so that this can be called statically
22
+	 */
23
+	public static function enqueue_styles_and_scripts()
24
+	{
25
+		wp_register_style(
26
+			'checkbox_dropdown_selector',
27
+			EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
28
+			array('espresso_default'),
29
+			EVENT_ESPRESSO_VERSION
30
+		);
31
+		wp_register_style(
32
+			'espresso_default',
33
+			EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
34
+			array('dashicons'),
35
+			EVENT_ESPRESSO_VERSION
36
+		);
37
+		wp_enqueue_style('checkbox_dropdown_selector');
38
+		wp_register_script(
39
+			'checkbox_dropdown_selector',
40
+			EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
41
+			array('jquery'),
42
+			EVENT_ESPRESSO_VERSION,
43
+			true
44
+		);
45
+		wp_enqueue_script('checkbox_dropdown_selector');
46
+	}
47
+
48
+
49
+
50
+	/**
51
+	 * Informs the rest of the forms system what CSS and JS is needed to display the input
52
+	 */
53
+	public function enqueue_js(){
54
+		EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
55
+	}
56
+
57
+
58
+
59
+	/**
60
+	 * callback for Iframe::addStylesheets() child class methods
61
+	 *
62
+	 * @param array $iframe_css
63
+	 * @return array
64
+	 */
65
+	public function iframe_css(array $iframe_css){
66
+		$iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
67
+		return $iframe_css;
68
+	}
69
+
70
+
71
+
72
+	/**
73
+	 * callback for Iframe::addScripts() child class methods
74
+	 *
75
+	 * @param array $iframe_js
76
+	 * @return array
77
+	 */
78
+	public function iframe_js(array $iframe_js){
79
+		$iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
80
+		return $iframe_js;
81
+	}
82
+
83
+
84
+	/**
85
+	 * @throws EE_Error
86
+	 * @return string of html to display the field
87
+	 */
88
+	public function display()
89
+	{
90
+		$input = $this->get_input();
91
+		$select_button_text = $input instanceof EE_Checkbox_Dropdown_Selector_Input ? $input->select_button_text() : '';
92
+		// $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
93
+		$input->set_label_sizes();
94
+		$label_size_class = $input->get_label_size_class();
95
+		if ( ! is_array($input->raw_value()) && $input->raw_value() !== null) {
96
+			EE_Error::doing_it_wrong(
97
+				'EE_Checkbox_Display_Strategy::display()',
98
+				sprintf(
99
+					esc_html__(
100
+						'Input values for checkboxes should be an array of values, but the value for input "%1$s" is "%2$s". Please verify that the input name is exactly "%3$s"',
101
+						'event_espresso'
102
+					),
103
+					$input->html_id(),
104
+					var_export($input->raw_value(), true),
105
+					$input->html_name() . '[]'
106
+				),
107
+				'4.8.1'
108
+			);
109
+		}
110
+
111
+
112
+		$html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
113
+		$html .= '<button id="' . $input->html_id() . '-btn"';
114
+		// $html .= ' name="' . $input->html_name() . '"';
115
+		$html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button-secondary button"';
116
+		$html .= ' style="' . $input->html_style() . '"';
117
+		$html .= ' data-target="' . $input->html_id() . '-options-dv"';
118
+		$html .= ' ' . $input->html_other_attributes() . '>';
119
+		$html .= '<span class="checkbox-dropdown-selector-selected-spn">';
120
+		$html .= $select_button_text;
121
+		$html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
122
+		$html .= '</button>';
123
+		$html .= EEH_HTML::div(
124
+			'',
125
+			$input->html_id() . '-options-dv',
126
+			'checkbox-dropdown-selector'
127
+		);
128
+		$html .= EEH_HTML::link(
129
+			'',
130
+			'<span class="dashicons dashicons-no"></span>',
131
+			esc_html__('close datetime selector', 'event_espresso'),
132
+			'',
133
+			'close-espresso-notice'
134
+		);
135
+		$html .= EEH_HTML::ul();
136
+		$input_raw_value = (array)$input->raw_value();
137
+		foreach ($input->options() as $value => $display_text) {
138
+			$html .= EEH_HTML::li();
139
+			$value = $input->get_normalization_strategy()->unnormalize_one($value);
140
+			$html_id = $this->get_sub_input_id($value);
141
+			$html .= EEH_HTML::nl(0, 'checkbox');
142
+			$html .= '<label for="'
143
+					 . $html_id
144
+					 . '" id="'
145
+					 . $html_id
146
+					 . '-lbl" class="ee-checkbox-label-after'
147
+					 . $label_size_class
148
+					 . '">';
149
+			$html .= EEH_HTML::nl(1, 'checkbox');
150
+			$html .= '<input type="checkbox"';
151
+			$html .= ' name="' . $input->html_name() . '[]"';
152
+			$html .= ' id="' . $html_id . '"';
153
+			$html .= ' class="' . $input->html_class() . '-option"';
154
+			$html .= ' style="' . $input->html_style() . '"';
155
+			$html .= ' value="' . esc_attr($value) . '"';
156
+			$html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
157
+				? ' checked="checked"'
158
+				: '';
159
+			$html .= ' ' . $this->_input->other_html_attributes();
160
+			$html .= '>';
161
+			$html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
162
+			$html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
163
+			$html .= EEH_HTML::lix();
164
+		}
165
+		$html .= EEH_HTML::ulx();
166
+		$html .= EEH_HTML::divx();
167
+		$html .= EEH_HTML::divx();
168
+		$html .= \EEH_HTML::br();
169
+		return $html;
170
+	}
171 171
 
172 172
 
173 173
 
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -24,20 +24,20 @@  discard block
 block discarded – undo
24 24
     {
25 25
         wp_register_style(
26 26
             'checkbox_dropdown_selector',
27
-            EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
27
+            EE_GLOBAL_ASSETS_URL.'css/checkbox_dropdown_selector.css',
28 28
             array('espresso_default'),
29 29
             EVENT_ESPRESSO_VERSION
30 30
         );
31 31
         wp_register_style(
32 32
             'espresso_default',
33
-            EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
33
+            EE_GLOBAL_ASSETS_URL.'css/espresso_default.css',
34 34
             array('dashicons'),
35 35
             EVENT_ESPRESSO_VERSION
36 36
         );
37 37
         wp_enqueue_style('checkbox_dropdown_selector');
38 38
         wp_register_script(
39 39
             'checkbox_dropdown_selector',
40
-            EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
40
+            EE_GLOBAL_ASSETS_URL.'scripts/checkbox_dropdown_selector.js',
41 41
             array('jquery'),
42 42
             EVENT_ESPRESSO_VERSION,
43 43
             true
@@ -50,7 +50,7 @@  discard block
 block discarded – undo
50 50
     /**
51 51
      * Informs the rest of the forms system what CSS and JS is needed to display the input
52 52
      */
53
-    public function enqueue_js(){
53
+    public function enqueue_js() {
54 54
         EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
55 55
     }
56 56
 
@@ -62,8 +62,8 @@  discard block
 block discarded – undo
62 62
      * @param array $iframe_css
63 63
      * @return array
64 64
      */
65
-    public function iframe_css(array $iframe_css){
66
-        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
65
+    public function iframe_css(array $iframe_css) {
66
+        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL.'css/checkbox_dropdown_selector.css';
67 67
         return $iframe_css;
68 68
     }
69 69
 
@@ -75,8 +75,8 @@  discard block
 block discarded – undo
75 75
      * @param array $iframe_js
76 76
      * @return array
77 77
      */
78
-    public function iframe_js(array $iframe_js){
79
-        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
78
+    public function iframe_js(array $iframe_js) {
79
+        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL.'scripts/checkbox_dropdown_selector.js';
80 80
         return $iframe_js;
81 81
     }
82 82
 
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
                     ),
103 103
                     $input->html_id(),
104 104
                     var_export($input->raw_value(), true),
105
-                    $input->html_name() . '[]'
105
+                    $input->html_name().'[]'
106 106
                 ),
107 107
                 '4.8.1'
108 108
             );
@@ -110,19 +110,19 @@  discard block
 block discarded – undo
110 110
 
111 111
 
112 112
         $html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
113
-        $html .= '<button id="' . $input->html_id() . '-btn"';
113
+        $html .= '<button id="'.$input->html_id().'-btn"';
114 114
         // $html .= ' name="' . $input->html_name() . '"';
115
-        $html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button-secondary button"';
116
-        $html .= ' style="' . $input->html_style() . '"';
117
-        $html .= ' data-target="' . $input->html_id() . '-options-dv"';
118
-        $html .= ' ' . $input->html_other_attributes() . '>';
115
+        $html .= ' class="'.$input->html_class().' checkbox-dropdown-selector-btn button-secondary button"';
116
+        $html .= ' style="'.$input->html_style().'"';
117
+        $html .= ' data-target="'.$input->html_id().'-options-dv"';
118
+        $html .= ' '.$input->html_other_attributes().'>';
119 119
         $html .= '<span class="checkbox-dropdown-selector-selected-spn">';
120 120
         $html .= $select_button_text;
121 121
         $html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
122 122
         $html .= '</button>';
123 123
         $html .= EEH_HTML::div(
124 124
             '',
125
-            $input->html_id() . '-options-dv',
125
+            $input->html_id().'-options-dv',
126 126
             'checkbox-dropdown-selector'
127 127
         );
128 128
         $html .= EEH_HTML::link(
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
             'close-espresso-notice'
134 134
         );
135 135
         $html .= EEH_HTML::ul();
136
-        $input_raw_value = (array)$input->raw_value();
136
+        $input_raw_value = (array) $input->raw_value();
137 137
         foreach ($input->options() as $value => $display_text) {
138 138
             $html .= EEH_HTML::li();
139 139
             $value = $input->get_normalization_strategy()->unnormalize_one($value);
@@ -148,18 +148,18 @@  discard block
 block discarded – undo
148 148
                      . '">';
149 149
             $html .= EEH_HTML::nl(1, 'checkbox');
150 150
             $html .= '<input type="checkbox"';
151
-            $html .= ' name="' . $input->html_name() . '[]"';
152
-            $html .= ' id="' . $html_id . '"';
153
-            $html .= ' class="' . $input->html_class() . '-option"';
154
-            $html .= ' style="' . $input->html_style() . '"';
155
-            $html .= ' value="' . esc_attr($value) . '"';
151
+            $html .= ' name="'.$input->html_name().'[]"';
152
+            $html .= ' id="'.$html_id.'"';
153
+            $html .= ' class="'.$input->html_class().'-option"';
154
+            $html .= ' style="'.$input->html_style().'"';
155
+            $html .= ' value="'.esc_attr($value).'"';
156 156
             $html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
157 157
                 ? ' checked="checked"'
158 158
                 : '';
159
-            $html .= ' ' . $this->_input->other_html_attributes();
159
+            $html .= ' '.$this->_input->other_html_attributes();
160 160
             $html .= '>';
161
-            $html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
162
-            $html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
161
+            $html .= '<span class="datetime-selector-option-text-spn">'.$display_text.'</span>';
162
+            $html .= EEH_HTML::nl(-1, 'checkbox').'</label>';
163 163
             $html .= EEH_HTML::lix();
164 164
         }
165 165
         $html .= EEH_HTML::ulx();
Please login to merge, or discard this patch.
admin_pages/registration_form/Registration_Form_Admin_Page.core.php 2 patches
Indentation   +637 added lines, -637 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 /**
@@ -28,593 +28,593 @@  discard block
 block discarded – undo
28 28
 class Registration_Form_Admin_Page extends EE_Admin_Page
29 29
 {
30 30
 
31
-    /**
32
-     * _question
33
-     * holds the specific question object for the question details screen
34
-     *
35
-     * @var EE_Question $_question
36
-     */
37
-    protected $_question;
38
-
39
-    /**
40
-     * _question_group
41
-     * holds the specific question group object for the question group details screen
42
-     *
43
-     * @var EE_Question_Group $_question_group
44
-     */
45
-    protected $_question_group;
46
-
47
-    /**
48
-     *_question_model EEM_Question model instance (for queries)
49
-     *
50
-     * @var EEM_Question $_question_model ;
51
-     */
52
-    protected $_question_model;
53
-
54
-    /**
55
-     * _question_group_model EEM_Question_group instance (for queries)
56
-     *
57
-     * @var EEM_Question_Group $_question_group_model
58
-     */
59
-    protected $_question_group_model;
60
-
61
-
62
-    /**
63
-     * @Constructor
64
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
65
-     * @access public
66
-     */
67
-    public function __construct($routing = true)
68
-    {
69
-        require_once(EE_MODELS . 'EEM_Question.model.php');
70
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
71
-        $this->_question_model       = EEM_Question::instance();
72
-        $this->_question_group_model = EEM_Question_Group::instance();
73
-        parent::__construct($routing);
74
-    }
75
-
76
-
77
-    protected function _init_page_props()
78
-    {
79
-        $this->page_slug        = REGISTRATION_FORM_PG_SLUG;
80
-        $this->page_label       = esc_html__('Registration Form', 'event_espresso');
81
-        $this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
82
-        $this->_admin_base_path = REGISTRATION_FORM_ADMIN;
83
-    }
84
-
85
-
86
-    protected function _ajax_hooks()
87
-    {
88
-    }
89
-
90
-
91
-    protected function _define_page_props()
92
-    {
93
-        $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
94
-        $this->_labels           = array(
95
-            'buttons' => array(
96
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
97
-            ),
98
-        );
99
-    }
100
-
101
-
102
-    /**
103
-     *_set_page_routes
104
-     */
105
-    protected function _set_page_routes()
106
-    {
107
-        $qst_id             = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
108
-        $this->_page_routes = array(
109
-            'default' => array(
110
-                'func'       => '_questions_overview_list_table',
111
-                'capability' => 'ee_read_questions',
112
-            ),
113
-
114
-            'edit_question' => array(
115
-                'func'       => '_edit_question',
116
-                'capability' => 'ee_edit_question',
117
-                'obj_id'     => $qst_id,
118
-                'args'       => array('edit'),
119
-            ),
120
-
121
-            'question_groups' => array(
122
-                'func'       => '_questions_groups_preview',
123
-                'capability' => 'ee_read_question_groups',
124
-            ),
125
-
126
-            'update_question' => array(
127
-                'func'       => '_insert_or_update_question',
128
-                'args'       => array('new_question' => false),
129
-                'capability' => 'ee_edit_question',
130
-                'obj_id'     => $qst_id,
131
-                'noheader'   => true,
132
-            ),
133
-        );
134
-    }
135
-
136
-
137
-    protected function _set_page_config()
138
-    {
139
-        $this->_page_config = array(
140
-            'default' => array(
141
-                'nav'           => array(
142
-                    'label' => esc_html__('Questions', 'event_espresso'),
143
-                    'order' => 10,
144
-                ),
145
-                'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
146
-                'metaboxes'     => $this->_default_espresso_metaboxes,
147
-                'help_tabs'     => array(
148
-                    'registration_form_questions_overview_help_tab'                           => array(
149
-                        'title'    => esc_html__('Questions Overview', 'event_espresso'),
150
-                        'filename' => 'registration_form_questions_overview',
151
-                    ),
152
-                    'registration_form_questions_overview_table_column_headings_help_tab'     => array(
153
-                        'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
154
-                        'filename' => 'registration_form_questions_overview_table_column_headings',
155
-                    ),
156
-                    'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array(
157
-                        'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
158
-                        'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
159
-                    ),
160
-                ),
161
-                'help_tour'     => array('Registration_Form_Questions_Overview_Help_Tour'),
162
-                'require_nonce' => false,
163
-                'qtips'         => array(
164
-                    'EE_Registration_Form_Tips',
165
-                )/**/
166
-            ),
167
-
168
-            'question_groups' => array(
169
-                'nav'           => array(
170
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
171
-                    'order' => 20,
172
-                ),
173
-                'metaboxes'     => $this->_default_espresso_metaboxes,
174
-                'help_tabs'     => array(
175
-                    'registration_form_question_groups_help_tab' => array(
176
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
177
-                        'filename' => 'registration_form_question_groups',
178
-                    ),
179
-                ),
180
-                'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
181
-                'require_nonce' => false,
182
-            ),
183
-
184
-            'edit_question' => array(
185
-                'nav'           => array(
186
-                    'label'      => esc_html__('Edit Question', 'event_espresso'),
187
-                    'order'      => 15,
188
-                    'persistent' => false,
189
-                    'url'        => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']),
190
-                        $this->_current_page_view_url) : $this->_admin_base_url,
191
-                ),
192
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
193
-                'help_tabs'     => array(
194
-                    'registration_form_edit_question_group_help_tab' => array(
195
-                        'title'    => esc_html__('Edit Question', 'event_espresso'),
196
-                        'filename' => 'registration_form_edit_question',
197
-                    ),
198
-                ),
199
-                'help_tour'     => array('Registration_Form_Edit_Question_Help_Tour'),
200
-                'require_nonce' => false,
201
-            ),
202
-        );
203
-    }
204
-
205
-
206
-    protected function _add_screen_options()
207
-    {
208
-        //todo
209
-    }
210
-
211
-    protected function _add_screen_options_default()
212
-    {
213
-        $page_title              = $this->_admin_page_title;
214
-        $this->_admin_page_title = esc_html__('Questions', 'event_espresso');
215
-        $this->_per_page_screen_option();
216
-        $this->_admin_page_title = $page_title;
217
-    }
218
-
219
-    protected function _add_screen_options_question_groups()
220
-    {
221
-        $page_title              = $this->_admin_page_title;
222
-        $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
223
-        $this->_per_page_screen_option();
224
-        $this->_admin_page_title = $page_title;
225
-    }
226
-
227
-    //none of the below group are currently used for Event Categories
228
-    protected function _add_feature_pointers()
229
-    {
230
-    }
231
-
232
-    public function load_scripts_styles()
233
-    {
234
-        wp_register_style('espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236
-        wp_enqueue_style('espresso_registration');
237
-    }
238
-
239
-    public function admin_init()
240
-    {
241
-    }
242
-
243
-    public function admin_notices()
244
-    {
245
-    }
246
-
247
-    public function admin_footer_scripts()
248
-    {
249
-    }
250
-
251
-
252
-    public function load_scripts_styles_default()
253
-    {
254
-    }
255
-
256
-
257
-    public function load_scripts_styles_add_question()
258
-    {
259
-        $this->load_scripts_styles_forms();
260
-        wp_register_script('espresso_registration_form_single',
261
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262
-            EVENT_ESPRESSO_VERSION, true);
263
-        wp_enqueue_script('espresso_registration_form_single');
264
-    }
265
-
266
-    public function load_scripts_styles_edit_question()
267
-    {
268
-        $this->load_scripts_styles_forms();
269
-        wp_register_script('espresso_registration_form_single',
270
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271
-            EVENT_ESPRESSO_VERSION, true);
272
-        wp_enqueue_script('espresso_registration_form_single');
273
-    }
274
-
275
-
276
-    public function recaptcha_info_help_tab()
277
-    {
278
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
279
-        EEH_Template::display_template($template, array());
280
-    }
281
-
282
-
283
-    public function load_scripts_styles_forms()
284
-    {
285
-        //styles
286
-        wp_enqueue_style('espresso-ui-theme');
287
-        //scripts
288
-        wp_enqueue_script('ee_admin_js');
289
-    }
290
-
291
-
292
-    protected function _set_list_table_views_default()
293
-    {
294
-        $this->_views = array(
295
-            'all' => array(
296
-                'slug'  => 'all',
297
-                'label' => esc_html__('View All Questions', 'event_espresso'),
298
-                'count' => 0,
31
+	/**
32
+	 * _question
33
+	 * holds the specific question object for the question details screen
34
+	 *
35
+	 * @var EE_Question $_question
36
+	 */
37
+	protected $_question;
38
+
39
+	/**
40
+	 * _question_group
41
+	 * holds the specific question group object for the question group details screen
42
+	 *
43
+	 * @var EE_Question_Group $_question_group
44
+	 */
45
+	protected $_question_group;
46
+
47
+	/**
48
+	 *_question_model EEM_Question model instance (for queries)
49
+	 *
50
+	 * @var EEM_Question $_question_model ;
51
+	 */
52
+	protected $_question_model;
53
+
54
+	/**
55
+	 * _question_group_model EEM_Question_group instance (for queries)
56
+	 *
57
+	 * @var EEM_Question_Group $_question_group_model
58
+	 */
59
+	protected $_question_group_model;
60
+
61
+
62
+	/**
63
+	 * @Constructor
64
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
65
+	 * @access public
66
+	 */
67
+	public function __construct($routing = true)
68
+	{
69
+		require_once(EE_MODELS . 'EEM_Question.model.php');
70
+		require_once(EE_MODELS . 'EEM_Question_Group.model.php');
71
+		$this->_question_model       = EEM_Question::instance();
72
+		$this->_question_group_model = EEM_Question_Group::instance();
73
+		parent::__construct($routing);
74
+	}
75
+
76
+
77
+	protected function _init_page_props()
78
+	{
79
+		$this->page_slug        = REGISTRATION_FORM_PG_SLUG;
80
+		$this->page_label       = esc_html__('Registration Form', 'event_espresso');
81
+		$this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
82
+		$this->_admin_base_path = REGISTRATION_FORM_ADMIN;
83
+	}
84
+
85
+
86
+	protected function _ajax_hooks()
87
+	{
88
+	}
89
+
90
+
91
+	protected function _define_page_props()
92
+	{
93
+		$this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
94
+		$this->_labels           = array(
95
+			'buttons' => array(
96
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
97
+			),
98
+		);
99
+	}
100
+
101
+
102
+	/**
103
+	 *_set_page_routes
104
+	 */
105
+	protected function _set_page_routes()
106
+	{
107
+		$qst_id             = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
108
+		$this->_page_routes = array(
109
+			'default' => array(
110
+				'func'       => '_questions_overview_list_table',
111
+				'capability' => 'ee_read_questions',
112
+			),
113
+
114
+			'edit_question' => array(
115
+				'func'       => '_edit_question',
116
+				'capability' => 'ee_edit_question',
117
+				'obj_id'     => $qst_id,
118
+				'args'       => array('edit'),
119
+			),
120
+
121
+			'question_groups' => array(
122
+				'func'       => '_questions_groups_preview',
123
+				'capability' => 'ee_read_question_groups',
124
+			),
125
+
126
+			'update_question' => array(
127
+				'func'       => '_insert_or_update_question',
128
+				'args'       => array('new_question' => false),
129
+				'capability' => 'ee_edit_question',
130
+				'obj_id'     => $qst_id,
131
+				'noheader'   => true,
132
+			),
133
+		);
134
+	}
135
+
136
+
137
+	protected function _set_page_config()
138
+	{
139
+		$this->_page_config = array(
140
+			'default' => array(
141
+				'nav'           => array(
142
+					'label' => esc_html__('Questions', 'event_espresso'),
143
+					'order' => 10,
144
+				),
145
+				'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
146
+				'metaboxes'     => $this->_default_espresso_metaboxes,
147
+				'help_tabs'     => array(
148
+					'registration_form_questions_overview_help_tab'                           => array(
149
+						'title'    => esc_html__('Questions Overview', 'event_espresso'),
150
+						'filename' => 'registration_form_questions_overview',
151
+					),
152
+					'registration_form_questions_overview_table_column_headings_help_tab'     => array(
153
+						'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
154
+						'filename' => 'registration_form_questions_overview_table_column_headings',
155
+					),
156
+					'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array(
157
+						'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
158
+						'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
159
+					),
160
+				),
161
+				'help_tour'     => array('Registration_Form_Questions_Overview_Help_Tour'),
162
+				'require_nonce' => false,
163
+				'qtips'         => array(
164
+					'EE_Registration_Form_Tips',
165
+				)/**/
166
+			),
167
+
168
+			'question_groups' => array(
169
+				'nav'           => array(
170
+					'label' => esc_html__('Question Groups', 'event_espresso'),
171
+					'order' => 20,
172
+				),
173
+				'metaboxes'     => $this->_default_espresso_metaboxes,
174
+				'help_tabs'     => array(
175
+					'registration_form_question_groups_help_tab' => array(
176
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
177
+						'filename' => 'registration_form_question_groups',
178
+					),
179
+				),
180
+				'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
181
+				'require_nonce' => false,
182
+			),
183
+
184
+			'edit_question' => array(
185
+				'nav'           => array(
186
+					'label'      => esc_html__('Edit Question', 'event_espresso'),
187
+					'order'      => 15,
188
+					'persistent' => false,
189
+					'url'        => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']),
190
+						$this->_current_page_view_url) : $this->_admin_base_url,
191
+				),
192
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
193
+				'help_tabs'     => array(
194
+					'registration_form_edit_question_group_help_tab' => array(
195
+						'title'    => esc_html__('Edit Question', 'event_espresso'),
196
+						'filename' => 'registration_form_edit_question',
197
+					),
198
+				),
199
+				'help_tour'     => array('Registration_Form_Edit_Question_Help_Tour'),
200
+				'require_nonce' => false,
201
+			),
202
+		);
203
+	}
204
+
205
+
206
+	protected function _add_screen_options()
207
+	{
208
+		//todo
209
+	}
210
+
211
+	protected function _add_screen_options_default()
212
+	{
213
+		$page_title              = $this->_admin_page_title;
214
+		$this->_admin_page_title = esc_html__('Questions', 'event_espresso');
215
+		$this->_per_page_screen_option();
216
+		$this->_admin_page_title = $page_title;
217
+	}
218
+
219
+	protected function _add_screen_options_question_groups()
220
+	{
221
+		$page_title              = $this->_admin_page_title;
222
+		$this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
223
+		$this->_per_page_screen_option();
224
+		$this->_admin_page_title = $page_title;
225
+	}
226
+
227
+	//none of the below group are currently used for Event Categories
228
+	protected function _add_feature_pointers()
229
+	{
230
+	}
231
+
232
+	public function load_scripts_styles()
233
+	{
234
+		wp_register_style('espresso_registration',
235
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236
+		wp_enqueue_style('espresso_registration');
237
+	}
238
+
239
+	public function admin_init()
240
+	{
241
+	}
242
+
243
+	public function admin_notices()
244
+	{
245
+	}
246
+
247
+	public function admin_footer_scripts()
248
+	{
249
+	}
250
+
251
+
252
+	public function load_scripts_styles_default()
253
+	{
254
+	}
255
+
256
+
257
+	public function load_scripts_styles_add_question()
258
+	{
259
+		$this->load_scripts_styles_forms();
260
+		wp_register_script('espresso_registration_form_single',
261
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262
+			EVENT_ESPRESSO_VERSION, true);
263
+		wp_enqueue_script('espresso_registration_form_single');
264
+	}
265
+
266
+	public function load_scripts_styles_edit_question()
267
+	{
268
+		$this->load_scripts_styles_forms();
269
+		wp_register_script('espresso_registration_form_single',
270
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271
+			EVENT_ESPRESSO_VERSION, true);
272
+		wp_enqueue_script('espresso_registration_form_single');
273
+	}
274
+
275
+
276
+	public function recaptcha_info_help_tab()
277
+	{
278
+		$template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
279
+		EEH_Template::display_template($template, array());
280
+	}
281
+
282
+
283
+	public function load_scripts_styles_forms()
284
+	{
285
+		//styles
286
+		wp_enqueue_style('espresso-ui-theme');
287
+		//scripts
288
+		wp_enqueue_script('ee_admin_js');
289
+	}
290
+
291
+
292
+	protected function _set_list_table_views_default()
293
+	{
294
+		$this->_views = array(
295
+			'all' => array(
296
+				'slug'  => 'all',
297
+				'label' => esc_html__('View All Questions', 'event_espresso'),
298
+				'count' => 0,
299 299
 //				'bulk_action' => array(
300 300
 //					'trash_questions' => esc_html__('Trash', 'event_espresso'),
301 301
 //					)
302
-            ),
303
-        );
304
-
305
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
306
-            'espresso_registration_form_trash_questions')
307
-        ) {
308
-            $this->_views['trash'] = array(
309
-                'slug'  => 'trash',
310
-                'label' => esc_html__('Trash', 'event_espresso'),
311
-                'count' => 0,
302
+			),
303
+		);
304
+
305
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
306
+			'espresso_registration_form_trash_questions')
307
+		) {
308
+			$this->_views['trash'] = array(
309
+				'slug'  => 'trash',
310
+				'label' => esc_html__('Trash', 'event_espresso'),
311
+				'count' => 0,
312 312
 //				'bulk_action' => array(
313 313
 //					'delete_questions' => esc_html__('Delete Permanently', 'event_espresso'),
314 314
 //					'restore_questions' => esc_html__('Restore', 'event_espresso'),
315
-            );
316
-        }
317
-    }
318
-
319
-    /**
320
-     * This just previews the question groups tab that comes in caffeinated.
321
-     *
322
-     * @return string html
323
-     */
324
-    protected function _questions_groups_preview()
325
-    {
326
-        $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
-        $this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
-                'event_espresso') . '" />';
329
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
-                'event_espresso') . '</strong>';
331
-        $this->display_admin_caf_preview_page('question_groups_tab');
332
-    }
333
-
334
-
335
-    /**
336
-     * Extracts the question field's values from the POST request to update or insert them
337
-     *
338
-     * @param \EEM_Base $model
339
-     * @return array where each key is the name of a model's field/db column, and each value is its value.
340
-     */
341
-    protected function _set_column_values_for(EEM_Base $model)
342
-    {
343
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
344
-        $set_column_values = array();
345
-
346
-        //some initial checks for proper values.
347
-        //if QST_admin_only, then no matter what QST_required is we disable.
348
-        if (! empty($this->_req_data['QST_admin_only'])) {
349
-            $this->_req_data['QST_required'] = 0;
350
-        }
351
-        foreach ($model->field_settings() as $fieldName => $settings) {
352
-            // basically if QSG_identifier is empty or not set
353
-            if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354
-                $QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
-                $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
315
+			);
316
+		}
317
+	}
318
+
319
+	/**
320
+	 * This just previews the question groups tab that comes in caffeinated.
321
+	 *
322
+	 * @return string html
323
+	 */
324
+	protected function _questions_groups_preview()
325
+	{
326
+		$this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
+		$this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
+				'event_espresso') . '" />';
329
+		$this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
+				'event_espresso') . '</strong>';
331
+		$this->display_admin_caf_preview_page('question_groups_tab');
332
+	}
333
+
334
+
335
+	/**
336
+	 * Extracts the question field's values from the POST request to update or insert them
337
+	 *
338
+	 * @param \EEM_Base $model
339
+	 * @return array where each key is the name of a model's field/db column, and each value is its value.
340
+	 */
341
+	protected function _set_column_values_for(EEM_Base $model)
342
+	{
343
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
344
+		$set_column_values = array();
345
+
346
+		//some initial checks for proper values.
347
+		//if QST_admin_only, then no matter what QST_required is we disable.
348
+		if (! empty($this->_req_data['QST_admin_only'])) {
349
+			$this->_req_data['QST_required'] = 0;
350
+		}
351
+		foreach ($model->field_settings() as $fieldName => $settings) {
352
+			// basically if QSG_identifier is empty or not set
353
+			if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354
+				$QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
+				$set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
356 356
 //				dd($set_column_values);
357
-            } //if the admin label is blank, use a slug version of the question text
358
-            else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359
-                $QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360
-                $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
-            } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
362
-                $set_column_values[$fieldName] = 0;
363
-            } else if ($fieldName === 'QST_max') {
364
-                $qst_system = EEM_Question::instance()->get_var(
365
-                    array(
366
-                        array(
367
-                            'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0,
368
-                        ),
369
-                    ),
370
-                    'QST_system');
371
-                $max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372
-                if (empty($this->_req_data['QST_max']) ||
373
-                    $this->_req_data['QST_max'] > $max_max
374
-                ) {
375
-                    $set_column_values[$fieldName] = $max_max;
376
-                }
377
-            }
378
-
379
-
380
-            //only add a property to the array if it's not null (otherwise the model should just use the default value)
381
-            if (
382
-                ! isset($set_column_values[$fieldName]) &&
383
-                isset($this->_req_data[$fieldName])
384
-            ) {
385
-                $set_column_values[$fieldName] = $this->_req_data[$fieldName];
386
-            }
387
-
388
-        }
389
-        return $set_column_values;//validation fo this data to be performed by the model before insertion.
390
-    }
391
-
392
-
393
-    /**
394
-     *_questions_overview_list_table
395
-     */
396
-    protected function _questions_overview_list_table()
397
-    {
398
-        $this->_search_btn_label = esc_html__('Questions', 'event_espresso');
399
-        $this->display_admin_list_table_page_with_sidebar();
400
-    }
401
-
402
-
403
-    /**
404
-     * _edit_question
405
-     */
406
-    protected function _edit_question()
407
-    {
408
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
409
-        $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false;
410
-
411
-        switch ($this->_req_action) {
412
-            case 'add_question' :
413
-                $this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
414
-                break;
415
-            case 'edit_question' :
416
-                $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
417
-                break;
418
-            default :
419
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
420
-        }
421
-
422
-        // add PRC_ID to title if editing
423
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
424
-        if ($ID) {
425
-            $question                 = $this->_question_model->get_one_by_ID($ID);
426
-            $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
427
-            $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
428
-        } else {
429
-            $question = EE_Question::new_instance();
430
-            $question->set_order_to_latest();
431
-            $this->_set_add_edit_form_tags('insert_question');
432
-        }
433
-        if( $question->system_ID() === EEM_Attendee::system_question_phone ){
434
-            $question_types = array_intersect_key(
435
-                EEM_Question::instance()->allowed_question_types(),
436
-                array_flip(
437
-                    array(
438
-                        EEM_Question::QST_type_text,
439
-                        EEM_Question::QST_type_us_phone
440
-                    )
441
-                )
442
-            );
443
-        } else {
444
-            $question_types = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types();
445
-        }
446
-        $this->_template_args['QST_ID']                     = $ID;
447
-        $this->_template_args['question']                   = $question;
448
-        $this->_template_args['question_types']             = $question_types;
449
-        $this->_template_args['max_max']                    = EEM_Question::instance()->absolute_max_for_system_question(
450
-            $question->system_ID()
451
-        );
452
-        $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
453
-        $this->_set_publish_post_box_vars('id', $ID);
454
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
455
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
456
-            $this->_template_args, true
457
-        );
458
-
459
-        // the details template wrapper
460
-        $this->display_admin_page_with_sidebar();
461
-    }
462
-
463
-
464
-    /**
465
-     * @return string
466
-     */
467
-    protected function _get_question_type_descriptions()
468
-    {
469
-        EE_Registry::instance()->load_helper('HTML');
470
-        $descriptions               = '';
471
-        $question_type_descriptions = EEM_Question::instance()->question_descriptions();
472
-        foreach ($question_type_descriptions as $type => $question_type_description) {
473
-            if ($type == 'HTML_TEXTAREA') {
474
-                $html = new EE_Simple_HTML_Validation_Strategy();
475
-                $question_type_description .= sprintf(
476
-                    esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
477
-                    '<br/>',
478
-                    $html->get_list_of_allowed_tags()
479
-                );
480
-            }
481
-            $descriptions .= EEH_HTML::p(
482
-                $question_type_description,
483
-                'question_type_description-' . $type,
484
-                'question_type_description description',
485
-                'display:none;'
486
-            );
487
-        }
488
-        return $descriptions;
489
-    }
490
-
491
-
492
-    /**
493
-     * @param bool|true $new_question
494
-     * @throws \EE_Error
495
-     */
496
-    protected function _insert_or_update_question($new_question = true)
497
-    {
498
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
499
-        $set_column_values = $this->_set_column_values_for($this->_question_model);
500
-        if ($new_question) {
501
-            $question = EE_Question::new_instance($set_column_values);
502
-            $action_desc = 'added';
503
-        } else {
504
-            $question     = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
505
-            $action_desc = 'updated';
506
-        }
507
-        $success = $question->save();
508
-        $ID = $question->ID();
509
-        if ($ID && $question->should_have_question_options()) {
510
-            //save the related options
511
-            //trash removed options, save old ones
512
-            //get list of all options
513
-            $options  = $question->options();
514
-            if (! empty($options)) {
515
-                foreach ($options as $option_ID => $option) {
516
-                    $option_req_index = $this->_get_option_req_data_index($option_ID);
517
-                    if ($option_req_index !== false) {
518
-                        $option->save($this->_req_data['question_options'][$option_req_index]);
519
-                    } else {
520
-                        //not found, remove it
521
-                        $option->delete();
522
-                    }
523
-                }
524
-            }
525
-            //save new related options
526
-            foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
527
-                //skip $index that is from our sample
528
-                if ( $index === 'xxcountxx' ) {
529
-                    continue;
530
-                }
531
-                //note we allow saving blank options.
532
-                if (empty($option_req_data['QSO_ID'])
533
-                ) {//no ID! save it!
534
-                    $new_option = EE_Question_Option::new_instance(array(
535
-                        'QSO_value' => $option_req_data['QSO_value'],
536
-                        'QSO_desc'  => $option_req_data['QSO_desc'],
537
-                        'QSO_order' => $option_req_data['QSO_order'],
538
-                        'QST_ID'    => $question->ID(),
539
-                    ));
540
-                    $new_option->save();
541
-                }
542
-            }
543
-        }
544
-        $query_args = array('action' => 'edit_question', 'QST_ID' => $ID);
545
-        if ($success !== false) {
546
-            $msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
547
-                $this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'),
548
-                $this->_question_model->item_name());
549
-            EE_Error::add_success($msg);
550
-        }
551
-
552
-        $this->_redirect_after_action(false, '', $action_desc, $query_args, true);
553
-    }
554
-
555
-
556
-    /**
557
-     * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
558
-     * by ID
559
-     * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
560
-     * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
561
-     *
562
-     * @param int $ID of the question option to find
563
-     * @return int index in question_options array if successful, FALSE if unsuccessful
564
-     */
565
-    protected function _get_option_req_data_index($ID)
566
-    {
567
-        $req_data_for_question_options = $this->_req_data['question_options'];
568
-        foreach ($req_data_for_question_options as $num => $option_data) {
569
-            if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
570
-                return $num;
571
-            }
572
-        }
573
-        return false;
574
-    }
575
-
576
-
577
-
578
-
579
-    /***********/
580
-    /* QUERIES */
581
-    /**
582
-     * For internal use in getting all the query parameters
583
-     * (because it's pretty well the same between question, question groups,
584
-     * and for both when searching for trashed and untrashed ones)
585
-     *
586
-     * @param EEM_Base $model either EEM_Question or EEM_Question_Group
587
-     * @param int      $per_page
588
-     * @param int      $current_page
589
-     * @return array lik EEM_Base::get_all's $query_params parameter
590
-     */
591
-    protected function get_query_params($model, $per_page = 10, $current_page = 10)
592
-    {
593
-        $query_params             = array();
594
-        $offset                   = ($current_page - 1) * $per_page;
595
-        $query_params['limit']    = array($offset, $per_page);
596
-        $order                    = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
597
-        $orderby_field            = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
598
-        $field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
599
-        $query_params['order_by'] = array($field_to_order_by => $order);
600
-        $search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
601
-        if (! empty($search_string)) {
602
-            if ($model instanceof EEM_Question_Group) {
603
-                $query_params[0] = array(
604
-                    'OR' => array(
605
-                        'QSG_name' => array('LIKE', "%$search_string%"),
606
-                        'QSG_desc' => array('LIKE', "%$search_string%"),
607
-                    ),
608
-                );
609
-            } else {
610
-                $query_params[0] = array(
611
-                    'QST_display_text' => array('LIKE', "%$search_string%"),
612
-                );
613
-            }
614
-        }
615
-
616
-        //capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
617
-        /*if ( $model instanceof EEM_Question_Group ) {
357
+			} //if the admin label is blank, use a slug version of the question text
358
+			else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359
+				$QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360
+				$set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
+			} else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
362
+				$set_column_values[$fieldName] = 0;
363
+			} else if ($fieldName === 'QST_max') {
364
+				$qst_system = EEM_Question::instance()->get_var(
365
+					array(
366
+						array(
367
+							'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0,
368
+						),
369
+					),
370
+					'QST_system');
371
+				$max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372
+				if (empty($this->_req_data['QST_max']) ||
373
+					$this->_req_data['QST_max'] > $max_max
374
+				) {
375
+					$set_column_values[$fieldName] = $max_max;
376
+				}
377
+			}
378
+
379
+
380
+			//only add a property to the array if it's not null (otherwise the model should just use the default value)
381
+			if (
382
+				! isset($set_column_values[$fieldName]) &&
383
+				isset($this->_req_data[$fieldName])
384
+			) {
385
+				$set_column_values[$fieldName] = $this->_req_data[$fieldName];
386
+			}
387
+
388
+		}
389
+		return $set_column_values;//validation fo this data to be performed by the model before insertion.
390
+	}
391
+
392
+
393
+	/**
394
+	 *_questions_overview_list_table
395
+	 */
396
+	protected function _questions_overview_list_table()
397
+	{
398
+		$this->_search_btn_label = esc_html__('Questions', 'event_espresso');
399
+		$this->display_admin_list_table_page_with_sidebar();
400
+	}
401
+
402
+
403
+	/**
404
+	 * _edit_question
405
+	 */
406
+	protected function _edit_question()
407
+	{
408
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
409
+		$ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false;
410
+
411
+		switch ($this->_req_action) {
412
+			case 'add_question' :
413
+				$this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
414
+				break;
415
+			case 'edit_question' :
416
+				$this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
417
+				break;
418
+			default :
419
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
420
+		}
421
+
422
+		// add PRC_ID to title if editing
423
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
424
+		if ($ID) {
425
+			$question                 = $this->_question_model->get_one_by_ID($ID);
426
+			$additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
427
+			$this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
428
+		} else {
429
+			$question = EE_Question::new_instance();
430
+			$question->set_order_to_latest();
431
+			$this->_set_add_edit_form_tags('insert_question');
432
+		}
433
+		if( $question->system_ID() === EEM_Attendee::system_question_phone ){
434
+			$question_types = array_intersect_key(
435
+				EEM_Question::instance()->allowed_question_types(),
436
+				array_flip(
437
+					array(
438
+						EEM_Question::QST_type_text,
439
+						EEM_Question::QST_type_us_phone
440
+					)
441
+				)
442
+			);
443
+		} else {
444
+			$question_types = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types();
445
+		}
446
+		$this->_template_args['QST_ID']                     = $ID;
447
+		$this->_template_args['question']                   = $question;
448
+		$this->_template_args['question_types']             = $question_types;
449
+		$this->_template_args['max_max']                    = EEM_Question::instance()->absolute_max_for_system_question(
450
+			$question->system_ID()
451
+		);
452
+		$this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
453
+		$this->_set_publish_post_box_vars('id', $ID);
454
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
455
+			REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
456
+			$this->_template_args, true
457
+		);
458
+
459
+		// the details template wrapper
460
+		$this->display_admin_page_with_sidebar();
461
+	}
462
+
463
+
464
+	/**
465
+	 * @return string
466
+	 */
467
+	protected function _get_question_type_descriptions()
468
+	{
469
+		EE_Registry::instance()->load_helper('HTML');
470
+		$descriptions               = '';
471
+		$question_type_descriptions = EEM_Question::instance()->question_descriptions();
472
+		foreach ($question_type_descriptions as $type => $question_type_description) {
473
+			if ($type == 'HTML_TEXTAREA') {
474
+				$html = new EE_Simple_HTML_Validation_Strategy();
475
+				$question_type_description .= sprintf(
476
+					esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
477
+					'<br/>',
478
+					$html->get_list_of_allowed_tags()
479
+				);
480
+			}
481
+			$descriptions .= EEH_HTML::p(
482
+				$question_type_description,
483
+				'question_type_description-' . $type,
484
+				'question_type_description description',
485
+				'display:none;'
486
+			);
487
+		}
488
+		return $descriptions;
489
+	}
490
+
491
+
492
+	/**
493
+	 * @param bool|true $new_question
494
+	 * @throws \EE_Error
495
+	 */
496
+	protected function _insert_or_update_question($new_question = true)
497
+	{
498
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
499
+		$set_column_values = $this->_set_column_values_for($this->_question_model);
500
+		if ($new_question) {
501
+			$question = EE_Question::new_instance($set_column_values);
502
+			$action_desc = 'added';
503
+		} else {
504
+			$question     = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
505
+			$action_desc = 'updated';
506
+		}
507
+		$success = $question->save();
508
+		$ID = $question->ID();
509
+		if ($ID && $question->should_have_question_options()) {
510
+			//save the related options
511
+			//trash removed options, save old ones
512
+			//get list of all options
513
+			$options  = $question->options();
514
+			if (! empty($options)) {
515
+				foreach ($options as $option_ID => $option) {
516
+					$option_req_index = $this->_get_option_req_data_index($option_ID);
517
+					if ($option_req_index !== false) {
518
+						$option->save($this->_req_data['question_options'][$option_req_index]);
519
+					} else {
520
+						//not found, remove it
521
+						$option->delete();
522
+					}
523
+				}
524
+			}
525
+			//save new related options
526
+			foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
527
+				//skip $index that is from our sample
528
+				if ( $index === 'xxcountxx' ) {
529
+					continue;
530
+				}
531
+				//note we allow saving blank options.
532
+				if (empty($option_req_data['QSO_ID'])
533
+				) {//no ID! save it!
534
+					$new_option = EE_Question_Option::new_instance(array(
535
+						'QSO_value' => $option_req_data['QSO_value'],
536
+						'QSO_desc'  => $option_req_data['QSO_desc'],
537
+						'QSO_order' => $option_req_data['QSO_order'],
538
+						'QST_ID'    => $question->ID(),
539
+					));
540
+					$new_option->save();
541
+				}
542
+			}
543
+		}
544
+		$query_args = array('action' => 'edit_question', 'QST_ID' => $ID);
545
+		if ($success !== false) {
546
+			$msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
547
+				$this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'),
548
+				$this->_question_model->item_name());
549
+			EE_Error::add_success($msg);
550
+		}
551
+
552
+		$this->_redirect_after_action(false, '', $action_desc, $query_args, true);
553
+	}
554
+
555
+
556
+	/**
557
+	 * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
558
+	 * by ID
559
+	 * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
560
+	 * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
561
+	 *
562
+	 * @param int $ID of the question option to find
563
+	 * @return int index in question_options array if successful, FALSE if unsuccessful
564
+	 */
565
+	protected function _get_option_req_data_index($ID)
566
+	{
567
+		$req_data_for_question_options = $this->_req_data['question_options'];
568
+		foreach ($req_data_for_question_options as $num => $option_data) {
569
+			if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
570
+				return $num;
571
+			}
572
+		}
573
+		return false;
574
+	}
575
+
576
+
577
+
578
+
579
+	/***********/
580
+	/* QUERIES */
581
+	/**
582
+	 * For internal use in getting all the query parameters
583
+	 * (because it's pretty well the same between question, question groups,
584
+	 * and for both when searching for trashed and untrashed ones)
585
+	 *
586
+	 * @param EEM_Base $model either EEM_Question or EEM_Question_Group
587
+	 * @param int      $per_page
588
+	 * @param int      $current_page
589
+	 * @return array lik EEM_Base::get_all's $query_params parameter
590
+	 */
591
+	protected function get_query_params($model, $per_page = 10, $current_page = 10)
592
+	{
593
+		$query_params             = array();
594
+		$offset                   = ($current_page - 1) * $per_page;
595
+		$query_params['limit']    = array($offset, $per_page);
596
+		$order                    = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
597
+		$orderby_field            = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
598
+		$field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
599
+		$query_params['order_by'] = array($field_to_order_by => $order);
600
+		$search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
601
+		if (! empty($search_string)) {
602
+			if ($model instanceof EEM_Question_Group) {
603
+				$query_params[0] = array(
604
+					'OR' => array(
605
+						'QSG_name' => array('LIKE', "%$search_string%"),
606
+						'QSG_desc' => array('LIKE', "%$search_string%"),
607
+					),
608
+				);
609
+			} else {
610
+				$query_params[0] = array(
611
+					'QST_display_text' => array('LIKE', "%$search_string%"),
612
+				);
613
+			}
614
+		}
615
+
616
+		//capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
617
+		/*if ( $model instanceof EEM_Question_Group ) {
618 618
             if ( ! EE_Registry::instance()->CAP->current_user_can( 'edit_others_question_groups', 'espresso_registration_form_edit_question_group' ) ) {
619 619
                 $query_params[0] = array(
620 620
                     'AND' => array(
@@ -644,62 +644,62 @@  discard block
 block discarded – undo
644 644
             }
645 645
         }/**/
646 646
 
647
-        return $query_params;
648
-
649
-    }
650
-
651
-
652
-    /**
653
-     * @param int        $per_page
654
-     * @param int        $current_page
655
-     * @param bool|false $count
656
-     * @return \EE_Soft_Delete_Base_Class[]|int
657
-     */
658
-    public function get_questions($per_page = 10, $current_page = 1, $count = false)
659
-    {
660
-        $QST          = EEM_Question::instance();
661
-        $query_params = $this->get_query_params($QST, $per_page, $current_page);
662
-        if ($count) {
663
-            $where   = isset($query_params[0]) ? array($query_params[0]) : array();
664
-            $results = $QST->count($where);
665
-        } else {
666
-            $results = $QST->get_all($query_params);
667
-        }
668
-        return $results;
669
-
670
-    }
671
-
672
-
673
-    /**
674
-     * @param            $per_page
675
-     * @param int        $current_page
676
-     * @param bool|false $count
677
-     * @return \EE_Soft_Delete_Base_Class[]|int
678
-     */
679
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
680
-    {
681
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
682
-        $where        = isset($query_params[0]) ? array($query_params[0]) : array();
683
-        $questions    = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params);
684
-        return $questions;
685
-    }
686
-
687
-
688
-    /**
689
-     * @param            $per_page
690
-     * @param int        $current_page
691
-     * @param bool|false $count
692
-     * @return \EE_Soft_Delete_Base_Class[]
693
-     */
694
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
695
-    {
696
-        /** @type EEM_Question_Group $questionGroupModel */
697
-        $questionGroupModel = EEM_Question_Group::instance();
698
-        //note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
699
-        return $questionGroupModel->get_all(
700
-            $this->get_query_params($questionGroupModel, $per_page, $current_page)
701
-        );
702
-    }
647
+		return $query_params;
648
+
649
+	}
650
+
651
+
652
+	/**
653
+	 * @param int        $per_page
654
+	 * @param int        $current_page
655
+	 * @param bool|false $count
656
+	 * @return \EE_Soft_Delete_Base_Class[]|int
657
+	 */
658
+	public function get_questions($per_page = 10, $current_page = 1, $count = false)
659
+	{
660
+		$QST          = EEM_Question::instance();
661
+		$query_params = $this->get_query_params($QST, $per_page, $current_page);
662
+		if ($count) {
663
+			$where   = isset($query_params[0]) ? array($query_params[0]) : array();
664
+			$results = $QST->count($where);
665
+		} else {
666
+			$results = $QST->get_all($query_params);
667
+		}
668
+		return $results;
669
+
670
+	}
671
+
672
+
673
+	/**
674
+	 * @param            $per_page
675
+	 * @param int        $current_page
676
+	 * @param bool|false $count
677
+	 * @return \EE_Soft_Delete_Base_Class[]|int
678
+	 */
679
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
680
+	{
681
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
682
+		$where        = isset($query_params[0]) ? array($query_params[0]) : array();
683
+		$questions    = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params);
684
+		return $questions;
685
+	}
686
+
687
+
688
+	/**
689
+	 * @param            $per_page
690
+	 * @param int        $current_page
691
+	 * @param bool|false $count
692
+	 * @return \EE_Soft_Delete_Base_Class[]
693
+	 */
694
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
695
+	{
696
+		/** @type EEM_Question_Group $questionGroupModel */
697
+		$questionGroupModel = EEM_Question_Group::instance();
698
+		//note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
699
+		return $questionGroupModel->get_all(
700
+			$this->get_query_params($questionGroupModel, $per_page, $current_page)
701
+		);
702
+	}
703 703
 
704 704
 
705 705
 } //ends Registration_Form_Admin_Page class
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if (! defined('EVENT_ESPRESSO_VERSION')) {
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3 3
     exit('NO direct script access allowed');
4 4
 }
5 5
 
@@ -66,8 +66,8 @@  discard block
 block discarded – undo
66 66
      */
67 67
     public function __construct($routing = true)
68 68
     {
69
-        require_once(EE_MODELS . 'EEM_Question.model.php');
70
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
69
+        require_once(EE_MODELS.'EEM_Question.model.php');
70
+        require_once(EE_MODELS.'EEM_Question_Group.model.php');
71 71
         $this->_question_model       = EEM_Question::instance();
72 72
         $this->_question_group_model = EEM_Question_Group::instance();
73 73
         parent::__construct($routing);
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
     public function load_scripts_styles()
233 233
     {
234 234
         wp_register_style('espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
235
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236 236
         wp_enqueue_style('espresso_registration');
237 237
     }
238 238
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
     {
259 259
         $this->load_scripts_styles_forms();
260 260
         wp_register_script('espresso_registration_form_single',
261
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
261
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262 262
             EVENT_ESPRESSO_VERSION, true);
263 263
         wp_enqueue_script('espresso_registration_form_single');
264 264
     }
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
     {
268 268
         $this->load_scripts_styles_forms();
269 269
         wp_register_script('espresso_registration_form_single',
270
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
270
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271 271
             EVENT_ESPRESSO_VERSION, true);
272 272
         wp_enqueue_script('espresso_registration_form_single');
273 273
     }
@@ -275,7 +275,7 @@  discard block
 block discarded – undo
275 275
 
276 276
     public function recaptcha_info_help_tab()
277 277
     {
278
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
278
+        $template = REGISTRATION_FORM_TEMPLATE_PATH.'recaptcha_info_help_tab.template.php';
279 279
         EEH_Template::display_template($template, array());
280 280
     }
281 281
 
@@ -324,10 +324,10 @@  discard block
 block discarded – undo
324 324
     protected function _questions_groups_preview()
325 325
     {
326 326
         $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
-        $this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
-                'event_espresso') . '" />';
329
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
-                'event_espresso') . '</strong>';
327
+        $this->_template_args['preview_img']  = '<img src="'.REGISTRATION_FORM_ASSETS_URL.'caf_reg_form_preview.jpg" alt="'.esc_attr__('Preview Question Groups Overview List Table screenshot',
328
+                'event_espresso').'" />';
329
+        $this->_template_args['preview_text'] = '<strong>'.esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
+                'event_espresso').'</strong>';
331 331
         $this->display_admin_caf_preview_page('question_groups_tab');
332 332
     }
333 333
 
@@ -345,20 +345,20 @@  discard block
 block discarded – undo
345 345
 
346 346
         //some initial checks for proper values.
347 347
         //if QST_admin_only, then no matter what QST_required is we disable.
348
-        if (! empty($this->_req_data['QST_admin_only'])) {
348
+        if ( ! empty($this->_req_data['QST_admin_only'])) {
349 349
             $this->_req_data['QST_required'] = 0;
350 350
         }
351 351
         foreach ($model->field_settings() as $fieldName => $settings) {
352 352
             // basically if QSG_identifier is empty or not set
353 353
             if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354 354
                 $QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
-                $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
355
+                $set_column_values[$fieldName] = sanitize_title($QSG_name).'-'.uniqid('', true);
356 356
 //				dd($set_column_values);
357 357
             } //if the admin label is blank, use a slug version of the question text
358 358
             else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359 359
                 $QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360 360
                 $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
-            } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
361
+            } else if ($fieldName === 'QST_admin_only' && ( ! isset($this->_req_data['QST_admin_only']))) {
362 362
                 $set_column_values[$fieldName] = 0;
363 363
             } else if ($fieldName === 'QST_max') {
364 364
                 $qst_system = EEM_Question::instance()->get_var(
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
                         ),
369 369
                     ),
370 370
                     'QST_system');
371
-                $max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
371
+                $max_max = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372 372
                 if (empty($this->_req_data['QST_max']) ||
373 373
                     $this->_req_data['QST_max'] > $max_max
374 374
                 ) {
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
             }
387 387
 
388 388
         }
389
-        return $set_column_values;//validation fo this data to be performed by the model before insertion.
389
+        return $set_column_values; //validation fo this data to be performed by the model before insertion.
390 390
     }
391 391
 
392 392
 
@@ -420,7 +420,7 @@  discard block
 block discarded – undo
420 420
         }
421 421
 
422 422
         // add PRC_ID to title if editing
423
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
423
+        $this->_admin_page_title = $ID ? $this->_admin_page_title.' # '.$ID : $this->_admin_page_title;
424 424
         if ($ID) {
425 425
             $question                 = $this->_question_model->get_one_by_ID($ID);
426 426
             $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
             $question->set_order_to_latest();
431 431
             $this->_set_add_edit_form_tags('insert_question');
432 432
         }
433
-        if( $question->system_ID() === EEM_Attendee::system_question_phone ){
433
+        if ($question->system_ID() === EEM_Attendee::system_question_phone) {
434 434
             $question_types = array_intersect_key(
435 435
                 EEM_Question::instance()->allowed_question_types(),
436 436
                 array_flip(
@@ -452,7 +452,7 @@  discard block
 block discarded – undo
452 452
         $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
453 453
         $this->_set_publish_post_box_vars('id', $ID);
454 454
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
455
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
455
+            REGISTRATION_FORM_TEMPLATE_PATH.'questions_main_meta_box.template.php',
456 456
             $this->_template_args, true
457 457
         );
458 458
 
@@ -480,7 +480,7 @@  discard block
 block discarded – undo
480 480
             }
481 481
             $descriptions .= EEH_HTML::p(
482 482
                 $question_type_description,
483
-                'question_type_description-' . $type,
483
+                'question_type_description-'.$type,
484 484
                 'question_type_description description',
485 485
                 'display:none;'
486 486
             );
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
             $question = EE_Question::new_instance($set_column_values);
502 502
             $action_desc = 'added';
503 503
         } else {
504
-            $question     = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
504
+            $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
505 505
             $action_desc = 'updated';
506 506
         }
507 507
         $success = $question->save();
@@ -510,8 +510,8 @@  discard block
 block discarded – undo
510 510
             //save the related options
511 511
             //trash removed options, save old ones
512 512
             //get list of all options
513
-            $options  = $question->options();
514
-            if (! empty($options)) {
513
+            $options = $question->options();
514
+            if ( ! empty($options)) {
515 515
                 foreach ($options as $option_ID => $option) {
516 516
                     $option_req_index = $this->_get_option_req_data_index($option_ID);
517 517
                     if ($option_req_index !== false) {
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
             //save new related options
526 526
             foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
527 527
                 //skip $index that is from our sample
528
-                if ( $index === 'xxcountxx' ) {
528
+                if ($index === 'xxcountxx') {
529 529
                     continue;
530 530
                 }
531 531
                 //note we allow saving blank options.
@@ -566,7 +566,7 @@  discard block
 block discarded – undo
566 566
     {
567 567
         $req_data_for_question_options = $this->_req_data['question_options'];
568 568
         foreach ($req_data_for_question_options as $num => $option_data) {
569
-            if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
569
+            if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
570 570
                 return $num;
571 571
             }
572 572
         }
@@ -598,7 +598,7 @@  discard block
 block discarded – undo
598 598
         $field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
599 599
         $query_params['order_by'] = array($field_to_order_by => $order);
600 600
         $search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
601
-        if (! empty($search_string)) {
601
+        if ( ! empty($search_string)) {
602 602
             if ($model instanceof EEM_Question_Group) {
603 603
                 $query_params[0] = array(
604 604
                     'OR' => array(
Please login to merge, or discard this patch.
core/services/currency/MoneyFactory.php 1 patch
Indentation   +211 added lines, -211 removed lines patch added patch discarded remove patch
@@ -30,217 +30,217 @@
 block discarded – undo
30 30
 class MoneyFactory
31 31
 {
32 32
 
33
-    /**
34
-     * @var CurrencyFactory $currency_factory
35
-     */
36
-    protected $currency_factory;
37
-
38
-    /**
39
-     * @var Calculator $calculator
40
-     */
41
-    protected $calculator;
42
-
43
-    /**
44
-     * @var MoneyFormatter[] $formatters
45
-     */
46
-    protected $formatters;
47
-
48
-
49
-    /**
50
-     * CreateMoney constructor.
51
-     *
52
-     * @param CurrencyFactory  $currency_factory
53
-     * @param Calculator       $calculator
54
-     * @param MoneyFormatter[] $formatters
55
-     */
56
-    public function __construct(
57
-        CurrencyFactory $currency_factory,
58
-        Calculator $calculator = null,
59
-        array $formatters = array()
60
-    ) {
61
-        $this->calculator = $calculator;
62
-        $this->formatters = $formatters;
63
-        $this->currency_factory = $currency_factory;
64
-    }
65
-
66
-
67
-
68
-    /**
69
-     * factory method that returns a Money object using amount specified in the currency's subunits
70
-     * example: for $12.50 USD use CreateMoney::fromSubUnits(1250, 'USD')
71
-     *
72
-     * @param int    $subunits_amount money amount IN THE SUBUNITS FOR THE CURRENCY ie: cents
73
-     *                                example: $12.50 USD would equate to a subunits amount of 1250
74
-     * @param string $currency_code
75
-     * @return Money
76
-     * @throws EE_Error
77
-     * @throws InvalidArgumentException
78
-     * @throws InvalidDataTypeException
79
-     * @throws InvalidIdentifierException
80
-     * @throws InvalidInterfaceException
81
-     */
82
-    public function createFromSubUnits($subunits_amount, $currency_code = '')
83
-    {
84
-        $currency = $this->currency_factory->createFromCode($currency_code);
85
-        return new Money(
86
-            // shift decimal BACK by number of places for currency
87
-            $subunits_amount * pow(10, $currency->decimalPlaces() * -1),
88
-            $currency,
89
-            $this->calculator(),
90
-            $this->formatters()
91
-        );
92
-    }
93
-
94
-
95
-
96
-    /**
97
-     * factory method that returns a Money object using the currency corresponding to the site's country
98
-     * example: CreateMoney::forSite(12.5)
99
-     *
100
-     * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
101
-     *                                 example: $12.5 USD would equate to a standard amount of 12.50
102
-     * @return Money
103
-     * @throws EE_Error
104
-     * @throws InvalidArgumentException
105
-     * @throws InvalidDataTypeException
106
-     * @throws InvalidIdentifierException
107
-     * @throws InvalidInterfaceException
108
-     */
109
-    public function createForSite($amount)
110
-    {
111
-        return new Money(
112
-            $amount,
113
-            $this->currency_factory->createFromCountryCode(),
114
-            $this->calculator(),
115
-            $this->formatters()
116
-        );
117
-    }
118
-
119
-
120
-
121
-    /**
122
-     * factory method that returns a Money object using the currency as specified by the supplied ISO country code
123
-     * example: CreateMoney::forCountry(12.5,'US')
124
-     *
125
-     * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
126
-     *                                 example: $12.5 USD would equate to a value amount of 12.50
127
-     * @param string           $CNT_ISO
128
-     * @return Money
129
-     * @throws EE_Error
130
-     * @throws InvalidArgumentException
131
-     * @throws InvalidDataTypeException
132
-     * @throws InvalidIdentifierException
133
-     * @throws InvalidInterfaceException
134
-     */
135
-    public function createForCountry($amount, $CNT_ISO)
136
-    {
137
-        return new Money(
138
-            $amount,
139
-            $this->currency_factory->createFromCountryCode($CNT_ISO),
140
-            $this->calculator(),
141
-            $this->formatters()
142
-        );
143
-    }
144
-
145
-
146
-
147
-    /**
148
-     * factory method that returns a Money object using the currency as specified by the supplied currency code
149
-     * example: CreateMoney::forCurrency(12.5, 'USD')
150
-     *
151
-     * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
152
-     *                                 example: $12.5 USD would equate to a value amount of 12.50
153
-     * @param string           $currency_code
154
-     * @return Money
155
-     * @throws EE_Error
156
-     * @throws InvalidArgumentException
157
-     * @throws InvalidDataTypeException
158
-     * @throws InvalidIdentifierException
159
-     * @throws InvalidInterfaceException
160
-     */
161
-    public function createForCurrency($amount, $currency_code)
162
-    {
163
-        return new Money(
164
-            $amount,
165
-            $this->currency_factory->createFromCode($currency_code),
166
-            $this->calculator(),
167
-            $this->formatters()
168
-        );
169
-    }
170
-
171
-
172
-
173
-
174
-    /**
175
-     * @return Calculator
176
-     */
177
-    public function calculator()
178
-    {
179
-        $this->initializeCalculators();
180
-        return $this->calculator;
181
-    }
182
-
183
-
184
-
185
-    /**
186
-     * loops through a filterable array of Calculator services
187
-     * and selects the first one that is supported by the current server
188
-     */
189
-    protected function initializeCalculators()
190
-    {
191
-        if ($this->calculator instanceof Calculator) {
192
-            return;
193
-        }
194
-        $calculators = apply_filters(
195
-            'FHEE__EventEspresso_core_services_currency_MoneyFactory__initializeCalculators__Calculators_array',
196
-            array(
197
-                '\EventEspresso\core\services\currency\DefaultCalculator',
198
-            )
199
-        );
200
-        foreach ($calculators as $calculator) {
201
-            if (! class_exists($calculator)) {
202
-                continue;
203
-            }
204
-            $calculator = new $calculator();
205
-            if ($calculator instanceof Calculator && $calculator->isSupported()) {
206
-                $this->calculator = $calculator;
207
-                break;
208
-            }
209
-        }
210
-    }
211
-
212
-
213
-
214
-    /**
215
-     * @return MoneyFormatter[]
216
-     */
217
-    public function formatters()
218
-    {
219
-        $this->initializeFormatters();
220
-        return $this->formatters;
221
-    }
222
-
223
-
224
-
225
-    /**
226
-     * initializes a filterable array of MoneyFormatter services
227
-     */
228
-    protected function initializeFormatters()
229
-    {
230
-        if (! empty($this->formatters)) {
231
-            return;
232
-        }
233
-        $this->formatters = apply_filters(
234
-            'FHEE__EventEspresso_core_services_currency_MoneyFactory__initializeFormatters__MoneyFormatters_array',
235
-            array(
236
-                1 => new DecimalMoneyFormatter(),
237
-                2 => new ThousandsMoneyFormatter(),
238
-                3 => new CurrencySignMoneyFormatter(),
239
-                4 => new CurrencyCodeMoneyFormatter(),
240
-                5 => new InternationalMoneyFormatter(),
241
-            )
242
-        );
243
-    }
33
+	/**
34
+	 * @var CurrencyFactory $currency_factory
35
+	 */
36
+	protected $currency_factory;
37
+
38
+	/**
39
+	 * @var Calculator $calculator
40
+	 */
41
+	protected $calculator;
42
+
43
+	/**
44
+	 * @var MoneyFormatter[] $formatters
45
+	 */
46
+	protected $formatters;
47
+
48
+
49
+	/**
50
+	 * CreateMoney constructor.
51
+	 *
52
+	 * @param CurrencyFactory  $currency_factory
53
+	 * @param Calculator       $calculator
54
+	 * @param MoneyFormatter[] $formatters
55
+	 */
56
+	public function __construct(
57
+		CurrencyFactory $currency_factory,
58
+		Calculator $calculator = null,
59
+		array $formatters = array()
60
+	) {
61
+		$this->calculator = $calculator;
62
+		$this->formatters = $formatters;
63
+		$this->currency_factory = $currency_factory;
64
+	}
65
+
66
+
67
+
68
+	/**
69
+	 * factory method that returns a Money object using amount specified in the currency's subunits
70
+	 * example: for $12.50 USD use CreateMoney::fromSubUnits(1250, 'USD')
71
+	 *
72
+	 * @param int    $subunits_amount money amount IN THE SUBUNITS FOR THE CURRENCY ie: cents
73
+	 *                                example: $12.50 USD would equate to a subunits amount of 1250
74
+	 * @param string $currency_code
75
+	 * @return Money
76
+	 * @throws EE_Error
77
+	 * @throws InvalidArgumentException
78
+	 * @throws InvalidDataTypeException
79
+	 * @throws InvalidIdentifierException
80
+	 * @throws InvalidInterfaceException
81
+	 */
82
+	public function createFromSubUnits($subunits_amount, $currency_code = '')
83
+	{
84
+		$currency = $this->currency_factory->createFromCode($currency_code);
85
+		return new Money(
86
+			// shift decimal BACK by number of places for currency
87
+			$subunits_amount * pow(10, $currency->decimalPlaces() * -1),
88
+			$currency,
89
+			$this->calculator(),
90
+			$this->formatters()
91
+		);
92
+	}
93
+
94
+
95
+
96
+	/**
97
+	 * factory method that returns a Money object using the currency corresponding to the site's country
98
+	 * example: CreateMoney::forSite(12.5)
99
+	 *
100
+	 * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
101
+	 *                                 example: $12.5 USD would equate to a standard amount of 12.50
102
+	 * @return Money
103
+	 * @throws EE_Error
104
+	 * @throws InvalidArgumentException
105
+	 * @throws InvalidDataTypeException
106
+	 * @throws InvalidIdentifierException
107
+	 * @throws InvalidInterfaceException
108
+	 */
109
+	public function createForSite($amount)
110
+	{
111
+		return new Money(
112
+			$amount,
113
+			$this->currency_factory->createFromCountryCode(),
114
+			$this->calculator(),
115
+			$this->formatters()
116
+		);
117
+	}
118
+
119
+
120
+
121
+	/**
122
+	 * factory method that returns a Money object using the currency as specified by the supplied ISO country code
123
+	 * example: CreateMoney::forCountry(12.5,'US')
124
+	 *
125
+	 * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
126
+	 *                                 example: $12.5 USD would equate to a value amount of 12.50
127
+	 * @param string           $CNT_ISO
128
+	 * @return Money
129
+	 * @throws EE_Error
130
+	 * @throws InvalidArgumentException
131
+	 * @throws InvalidDataTypeException
132
+	 * @throws InvalidIdentifierException
133
+	 * @throws InvalidInterfaceException
134
+	 */
135
+	public function createForCountry($amount, $CNT_ISO)
136
+	{
137
+		return new Money(
138
+			$amount,
139
+			$this->currency_factory->createFromCountryCode($CNT_ISO),
140
+			$this->calculator(),
141
+			$this->formatters()
142
+		);
143
+	}
144
+
145
+
146
+
147
+	/**
148
+	 * factory method that returns a Money object using the currency as specified by the supplied currency code
149
+	 * example: CreateMoney::forCurrency(12.5, 'USD')
150
+	 *
151
+	 * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
152
+	 *                                 example: $12.5 USD would equate to a value amount of 12.50
153
+	 * @param string           $currency_code
154
+	 * @return Money
155
+	 * @throws EE_Error
156
+	 * @throws InvalidArgumentException
157
+	 * @throws InvalidDataTypeException
158
+	 * @throws InvalidIdentifierException
159
+	 * @throws InvalidInterfaceException
160
+	 */
161
+	public function createForCurrency($amount, $currency_code)
162
+	{
163
+		return new Money(
164
+			$amount,
165
+			$this->currency_factory->createFromCode($currency_code),
166
+			$this->calculator(),
167
+			$this->formatters()
168
+		);
169
+	}
170
+
171
+
172
+
173
+
174
+	/**
175
+	 * @return Calculator
176
+	 */
177
+	public function calculator()
178
+	{
179
+		$this->initializeCalculators();
180
+		return $this->calculator;
181
+	}
182
+
183
+
184
+
185
+	/**
186
+	 * loops through a filterable array of Calculator services
187
+	 * and selects the first one that is supported by the current server
188
+	 */
189
+	protected function initializeCalculators()
190
+	{
191
+		if ($this->calculator instanceof Calculator) {
192
+			return;
193
+		}
194
+		$calculators = apply_filters(
195
+			'FHEE__EventEspresso_core_services_currency_MoneyFactory__initializeCalculators__Calculators_array',
196
+			array(
197
+				'\EventEspresso\core\services\currency\DefaultCalculator',
198
+			)
199
+		);
200
+		foreach ($calculators as $calculator) {
201
+			if (! class_exists($calculator)) {
202
+				continue;
203
+			}
204
+			$calculator = new $calculator();
205
+			if ($calculator instanceof Calculator && $calculator->isSupported()) {
206
+				$this->calculator = $calculator;
207
+				break;
208
+			}
209
+		}
210
+	}
211
+
212
+
213
+
214
+	/**
215
+	 * @return MoneyFormatter[]
216
+	 */
217
+	public function formatters()
218
+	{
219
+		$this->initializeFormatters();
220
+		return $this->formatters;
221
+	}
222
+
223
+
224
+
225
+	/**
226
+	 * initializes a filterable array of MoneyFormatter services
227
+	 */
228
+	protected function initializeFormatters()
229
+	{
230
+		if (! empty($this->formatters)) {
231
+			return;
232
+		}
233
+		$this->formatters = apply_filters(
234
+			'FHEE__EventEspresso_core_services_currency_MoneyFactory__initializeFormatters__MoneyFormatters_array',
235
+			array(
236
+				1 => new DecimalMoneyFormatter(),
237
+				2 => new ThousandsMoneyFormatter(),
238
+				3 => new CurrencySignMoneyFormatter(),
239
+				4 => new CurrencyCodeMoneyFormatter(),
240
+				5 => new InternationalMoneyFormatter(),
241
+			)
242
+		);
243
+	}
244 244
 
245 245
 
246 246
 }
Please login to merge, or discard this patch.
core/domain/values/currency/Money.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
      */
102 102
     private function parseAmount($amount)
103 103
     {
104
-        if (! in_array(gettype($amount), array('integer', 'double', 'string'), true)) {
104
+        if ( ! in_array(gettype($amount), array('integer', 'double', 'string'), true)) {
105 105
             throw new InvalidDataTypeException(
106 106
                 '$amount',
107 107
                 $amount,
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
         $amount *= pow(10, $this->precision());
131 131
         // then round up the remaining value if there is still a fractional amount left
132 132
         $amount = round($amount);
133
-        return (int)$amount;
133
+        return (int) $amount;
134 134
     }
135 135
 
136 136
 
@@ -201,11 +201,11 @@  discard block
 block discarded – undo
201 201
         // if we are applying thousands formatting...
202 202
         if ($formatting_level >= MoneyFormatter::ADD_THOUSANDS) {
203 203
             // then let's remove decimal formatting since it's included in thousands formatting
204
-            unset($formatters[ MoneyFormatter::DECIMAL_ONLY ]);
204
+            unset($formatters[MoneyFormatter::DECIMAL_ONLY]);
205 205
         }
206 206
         for ($x = 1; $x <= $formatting_level; $x++) {
207
-            if (isset($formatters[ $x ]) && $formatters[ $x ] instanceof MoneyFormatter) {
208
-                $formatted_amount = $formatters[ $x ]->format($formatted_amount, $this->currency);
207
+            if (isset($formatters[$x]) && $formatters[$x] instanceof MoneyFormatter) {
208
+                $formatted_amount = $formatters[$x]->format($formatted_amount, $this->currency);
209 209
             }
210 210
         }
211 211
         return (string) apply_filters(
Please login to merge, or discard this patch.
Indentation   +332 added lines, -332 removed lines patch added patch discarded remove patch
@@ -22,338 +22,338 @@
 block discarded – undo
22 22
 class Money
23 23
 {
24 24
 
25
-    /**
26
-     * number of decimal places to be added to currencies for internal computations,
27
-     * but removed before any output or formatting is applied.
28
-     * This allows us to avoid rounding errors during calculations.
29
-     */
30
-    const EXTRA_PRECISION = 3;
31
-
32
-    /**
33
-     * @var int $amount
34
-     */
35
-    private $amount;
36
-
37
-    /**
38
-     * @var Currency $currency
39
-     */
40
-    private $currency;
41
-
42
-    /**
43
-     * @var Calculator $calculator
44
-     */
45
-    protected $calculator;
46
-
47
-    /**
48
-     * @var MoneyFormatter[] $formatters
49
-     */
50
-    protected $formatters;
51
-
52
-
53
-
54
-    /**
55
-     * Money constructor.
56
-     *
57
-     * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
58
-     *                                 example: $12.5 USD would equate to a value amount of 12.50
59
-     * @param Currency         $currency
60
-     * @param Calculator       $calculator
61
-     * @param MoneyFormatter[] $formatters
62
-     * @throws InvalidDataTypeException
63
-     */
64
-    public function __construct($amount, Currency $currency, Calculator $calculator, array $formatters)
65
-    {
66
-        $this->currency   = $currency;
67
-        $this->amount     = $this->parseAmount($amount);
68
-        $this->calculator = $calculator;
69
-        $this->formatters = $formatters;
70
-    }
71
-
72
-
73
-
74
-    /**
75
-     * @return Calculator
76
-     */
77
-    protected function calculator()
78
-    {
79
-        return $this->calculator;
80
-    }
81
-
82
-
83
-
84
-    /**
85
-     * @return MoneyFormatter[]
86
-     */
87
-    protected function formatters()
88
-    {
89
-        return $this->formatters;
90
-    }
91
-
92
-
93
-
94
-    /**
95
-     * Convert's a standard unit amount into the subunits of the currency
96
-     *
97
-     * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
98
-     *                                 example: $12.5 USD would equate to a value amount of 12.50
99
-     * @return integer                 in the currency's subunit
100
-     * @throws InvalidDataTypeException
101
-     */
102
-    private function parseAmount($amount)
103
-    {
104
-        if (! in_array(gettype($amount), array('integer', 'double', 'string'), true)) {
105
-            throw new InvalidDataTypeException(
106
-                '$amount',
107
-                $amount,
108
-                'integer (or float or string)'
109
-            );
110
-        }
111
-        if ($this->currency->decimalMark() !== '.') {
112
-            // remove thousands separator and replace decimal place with standard decimal.
113
-            $amount = str_replace(
114
-                array(
115
-                    $this->currency->thousands(),
116
-                    $this->currency->decimalMark(),
117
-                ),
118
-                array(
119
-                    '',
120
-                    '.',
121
-                ),
122
-                $amount
123
-            );
124
-        }
125
-        // remove any non numeric values but leave the decimal
126
-        $amount = (float) preg_replace('/([^0-9\\.-])/', '', $amount);
127
-        // shift the decimal position by the number of decimal places used internally
128
-        // ex: 12.5 for a currency using 2 decimal places, would become 1250
129
-        // then if our extra internal precision was 3, it would become 1250000
130
-        $amount *= pow(10, $this->precision());
131
-        // then round up the remaining value if there is still a fractional amount left
132
-        $amount = round($amount);
133
-        return (int)$amount;
134
-    }
135
-
136
-
137
-
138
-    /**
139
-     * adds or subtracts additional decimal places based on the value of the Money::EXTRA_PRECISION constant
140
-     *
141
-     * @param bool $positive
142
-     * @return integer
143
-     */
144
-    private function precision($positive = true)
145
-    {
146
-        $sign = $positive ? 1 : -1;
147
-        return ((int) $this->currency->subunitOrderOfMagnitudeDiff() + Money::EXTRA_PRECISION) * $sign;
148
-    }
149
-
150
-
151
-
152
-    /**
153
-     * Returns the money amount as an unformatted string
154
-     * IF YOU REQUIRE A FORMATTED STRING, THEN USE Money::format()
155
-     * In the currency's standard units
156
-     *
157
-     * @return string
158
-     */
159
-    public function amount()
160
-    {
161
-        // shift the decimal position BACK by the number of decimal places used internally
162
-        // ex: 1250 for a currency using 2 decimal places, would become 12.50
163
-        $amount = (string) $this->amount * pow(10, $this->precision(false));
164
-        // then shave off our extra internal precision using the number of decimal places for the currency
165
-        $amount = round($amount, $this->currency->subunitOrderOfMagnitudeDiff());
166
-        return (string) $amount;
167
-    }
168
-
169
-
170
-
171
-    /**
172
-     * Returns the money SUBUNITS amount as an INTEGER
173
-     *
174
-     * @return integer
175
-     */
176
-    public function amountInSubunits()
177
-    {
178
-        // shift the decimal position BACK by the number of decimal places used internally
179
-        // for extra internal precision, but NOT for the number of decimals used by the currency
180
-        // ex: if our extra internal precision was 3, then 1250000 would become 1250
181
-        // and even if the currency used 2 decimal places, we would return 1250 and NOT 12.50
182
-        $amount = (string) $this->amount * pow(10, Money::EXTRA_PRECISION * -1);
183
-        // then shave off anything after the decimal
184
-        $amount = round($amount);
185
-        return (int) $amount;
186
-    }
187
-
188
-
189
-
190
-    /**
191
-     * applies formatting based on the specified formatting level
192
-     * corresponding to one of the constants on MoneyFormatter
193
-     *
194
-     * @param int $formatting_level
195
-     * @return string
196
-     */
197
-    public function format($formatting_level = MoneyFormatter::ADD_THOUSANDS)
198
-    {
199
-        $formatted_amount = $this->amount();
200
-        $formatters       = $this->formatters();
201
-        // if we are applying thousands formatting...
202
-        if ($formatting_level >= MoneyFormatter::ADD_THOUSANDS) {
203
-            // then let's remove decimal formatting since it's included in thousands formatting
204
-            unset($formatters[ MoneyFormatter::DECIMAL_ONLY ]);
205
-        }
206
-        for ($x = 1; $x <= $formatting_level; $x++) {
207
-            if (isset($formatters[ $x ]) && $formatters[ $x ] instanceof MoneyFormatter) {
208
-                $formatted_amount = $formatters[ $x ]->format($formatted_amount, $this->currency);
209
-            }
210
-        }
211
-        return (string) apply_filters(
212
-            'FHEE__EventEspresso_core_domain_values_currency_Money__format__formatted_amount',
213
-            $formatted_amount,
214
-            $this
215
-        );
216
-    }
217
-
218
-
219
-
220
-    /**
221
-     * Returns the Currency object for this money
222
-     *
223
-     * @return Currency
224
-     */
225
-    public function currency()
226
-    {
227
-        return $this->currency;
228
-    }
229
-
230
-
231
-
232
-    /**
233
-     * adds the supplied Money amount to this Money amount
234
-     * and returns a new Money object
235
-     *
236
-     * @param Money $other
237
-     * @return Money
238
-     * @throws InvalidArgumentException
239
-     */
240
-    public function add(Money $other)
241
-    {
242
-        $this->verifySameCurrency($other->currency());
243
-        return new Money(
244
-            $this->calculator()->add(
245
-                $this->amount(),
246
-                $other->amount()
247
-            ),
248
-            $this->currency(),
249
-            $this->calculator(),
250
-            $this->formatters()
251
-        );
252
-    }
253
-
254
-
255
-
256
-    /**
257
-     * subtracts the supplied Money amount from this Money amount
258
-     * and returns a new Money object
259
-     *
260
-     * @param Money $other
261
-     * @return Money
262
-     * @throws InvalidArgumentException
263
-     */
264
-    public function subtract(Money $other)
265
-    {
266
-        $this->verifySameCurrency($other->currency());
267
-        return new Money(
268
-            $this->calculator()->subtract(
269
-                $this->amount(),
270
-                $other->amount()
271
-            ),
272
-            $this->currency(),
273
-            $this->calculator(),
274
-            $this->formatters()
275
-        );
276
-    }
277
-
278
-
279
-
280
-    /**
281
-     * multiplies this Money amount by the supplied $multiplier
282
-     * and returns a new Money object
283
-     *
284
-     * @param float|int|string $multiplier
285
-     * @param int              $rounding_mode
286
-     * @return Money
287
-     * @throws InvalidDataTypeException
288
-     */
289
-    public function multiply($multiplier, $rounding_mode = Calculator::ROUND_HALF_UP)
290
-    {
291
-        return new Money(
292
-            $this->calculator()->multiply(
293
-                $this->amount(),
294
-                $multiplier,
295
-                $this->precision(),
296
-                $rounding_mode
297
-            ),
298
-            $this->currency(),
299
-            $this->calculator(),
300
-            $this->formatters()
301
-        );
302
-    }
303
-
304
-
305
-
306
-    /**
307
-     * divides this Money amount by the supplied $divisor
308
-     * and returns a new Money object
309
-     *
310
-     * @param float|int|string $divisor
311
-     * @param int              $rounding_mode
312
-     * @return Money
313
-     * @throws InvalidDataTypeException
314
-     */
315
-    public function divide($divisor, $rounding_mode = Calculator::ROUND_HALF_UP)
316
-    {
317
-        return new Money(
318
-            $this->calculator()->divide(
319
-                $this->amount(),
320
-                $divisor,
321
-                $this->precision(),
322
-                $rounding_mode
323
-            ),
324
-            $this->currency(),
325
-            $this->calculator(),
326
-            $this->formatters()
327
-        );
328
-    }
329
-
330
-
331
-
332
-    /**
333
-     * @param Currency $other_currency
334
-     * @throws InvalidArgumentException
335
-     */
336
-    public function verifySameCurrency(Currency $other_currency)
337
-    {
338
-        if ($this->currency()->equals($other_currency) !== true) {
339
-            throw new InvalidArgumentException(
340
-                esc_html__(
341
-                    'Currencies must be the same in order to add or subtract their values.',
342
-                    'event_espresso'
343
-                )
344
-            );
345
-        }
346
-    }
347
-
348
-
349
-
350
-    /**
351
-     * @return string
352
-     */
353
-    public function __toString()
354
-    {
355
-        return $this->format(MoneyFormatter::DECIMAL_ONLY);
356
-    }
25
+	/**
26
+	 * number of decimal places to be added to currencies for internal computations,
27
+	 * but removed before any output or formatting is applied.
28
+	 * This allows us to avoid rounding errors during calculations.
29
+	 */
30
+	const EXTRA_PRECISION = 3;
31
+
32
+	/**
33
+	 * @var int $amount
34
+	 */
35
+	private $amount;
36
+
37
+	/**
38
+	 * @var Currency $currency
39
+	 */
40
+	private $currency;
41
+
42
+	/**
43
+	 * @var Calculator $calculator
44
+	 */
45
+	protected $calculator;
46
+
47
+	/**
48
+	 * @var MoneyFormatter[] $formatters
49
+	 */
50
+	protected $formatters;
51
+
52
+
53
+
54
+	/**
55
+	 * Money constructor.
56
+	 *
57
+	 * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
58
+	 *                                 example: $12.5 USD would equate to a value amount of 12.50
59
+	 * @param Currency         $currency
60
+	 * @param Calculator       $calculator
61
+	 * @param MoneyFormatter[] $formatters
62
+	 * @throws InvalidDataTypeException
63
+	 */
64
+	public function __construct($amount, Currency $currency, Calculator $calculator, array $formatters)
65
+	{
66
+		$this->currency   = $currency;
67
+		$this->amount     = $this->parseAmount($amount);
68
+		$this->calculator = $calculator;
69
+		$this->formatters = $formatters;
70
+	}
71
+
72
+
73
+
74
+	/**
75
+	 * @return Calculator
76
+	 */
77
+	protected function calculator()
78
+	{
79
+		return $this->calculator;
80
+	}
81
+
82
+
83
+
84
+	/**
85
+	 * @return MoneyFormatter[]
86
+	 */
87
+	protected function formatters()
88
+	{
89
+		return $this->formatters;
90
+	}
91
+
92
+
93
+
94
+	/**
95
+	 * Convert's a standard unit amount into the subunits of the currency
96
+	 *
97
+	 * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
98
+	 *                                 example: $12.5 USD would equate to a value amount of 12.50
99
+	 * @return integer                 in the currency's subunit
100
+	 * @throws InvalidDataTypeException
101
+	 */
102
+	private function parseAmount($amount)
103
+	{
104
+		if (! in_array(gettype($amount), array('integer', 'double', 'string'), true)) {
105
+			throw new InvalidDataTypeException(
106
+				'$amount',
107
+				$amount,
108
+				'integer (or float or string)'
109
+			);
110
+		}
111
+		if ($this->currency->decimalMark() !== '.') {
112
+			// remove thousands separator and replace decimal place with standard decimal.
113
+			$amount = str_replace(
114
+				array(
115
+					$this->currency->thousands(),
116
+					$this->currency->decimalMark(),
117
+				),
118
+				array(
119
+					'',
120
+					'.',
121
+				),
122
+				$amount
123
+			);
124
+		}
125
+		// remove any non numeric values but leave the decimal
126
+		$amount = (float) preg_replace('/([^0-9\\.-])/', '', $amount);
127
+		// shift the decimal position by the number of decimal places used internally
128
+		// ex: 12.5 for a currency using 2 decimal places, would become 1250
129
+		// then if our extra internal precision was 3, it would become 1250000
130
+		$amount *= pow(10, $this->precision());
131
+		// then round up the remaining value if there is still a fractional amount left
132
+		$amount = round($amount);
133
+		return (int)$amount;
134
+	}
135
+
136
+
137
+
138
+	/**
139
+	 * adds or subtracts additional decimal places based on the value of the Money::EXTRA_PRECISION constant
140
+	 *
141
+	 * @param bool $positive
142
+	 * @return integer
143
+	 */
144
+	private function precision($positive = true)
145
+	{
146
+		$sign = $positive ? 1 : -1;
147
+		return ((int) $this->currency->subunitOrderOfMagnitudeDiff() + Money::EXTRA_PRECISION) * $sign;
148
+	}
149
+
150
+
151
+
152
+	/**
153
+	 * Returns the money amount as an unformatted string
154
+	 * IF YOU REQUIRE A FORMATTED STRING, THEN USE Money::format()
155
+	 * In the currency's standard units
156
+	 *
157
+	 * @return string
158
+	 */
159
+	public function amount()
160
+	{
161
+		// shift the decimal position BACK by the number of decimal places used internally
162
+		// ex: 1250 for a currency using 2 decimal places, would become 12.50
163
+		$amount = (string) $this->amount * pow(10, $this->precision(false));
164
+		// then shave off our extra internal precision using the number of decimal places for the currency
165
+		$amount = round($amount, $this->currency->subunitOrderOfMagnitudeDiff());
166
+		return (string) $amount;
167
+	}
168
+
169
+
170
+
171
+	/**
172
+	 * Returns the money SUBUNITS amount as an INTEGER
173
+	 *
174
+	 * @return integer
175
+	 */
176
+	public function amountInSubunits()
177
+	{
178
+		// shift the decimal position BACK by the number of decimal places used internally
179
+		// for extra internal precision, but NOT for the number of decimals used by the currency
180
+		// ex: if our extra internal precision was 3, then 1250000 would become 1250
181
+		// and even if the currency used 2 decimal places, we would return 1250 and NOT 12.50
182
+		$amount = (string) $this->amount * pow(10, Money::EXTRA_PRECISION * -1);
183
+		// then shave off anything after the decimal
184
+		$amount = round($amount);
185
+		return (int) $amount;
186
+	}
187
+
188
+
189
+
190
+	/**
191
+	 * applies formatting based on the specified formatting level
192
+	 * corresponding to one of the constants on MoneyFormatter
193
+	 *
194
+	 * @param int $formatting_level
195
+	 * @return string
196
+	 */
197
+	public function format($formatting_level = MoneyFormatter::ADD_THOUSANDS)
198
+	{
199
+		$formatted_amount = $this->amount();
200
+		$formatters       = $this->formatters();
201
+		// if we are applying thousands formatting...
202
+		if ($formatting_level >= MoneyFormatter::ADD_THOUSANDS) {
203
+			// then let's remove decimal formatting since it's included in thousands formatting
204
+			unset($formatters[ MoneyFormatter::DECIMAL_ONLY ]);
205
+		}
206
+		for ($x = 1; $x <= $formatting_level; $x++) {
207
+			if (isset($formatters[ $x ]) && $formatters[ $x ] instanceof MoneyFormatter) {
208
+				$formatted_amount = $formatters[ $x ]->format($formatted_amount, $this->currency);
209
+			}
210
+		}
211
+		return (string) apply_filters(
212
+			'FHEE__EventEspresso_core_domain_values_currency_Money__format__formatted_amount',
213
+			$formatted_amount,
214
+			$this
215
+		);
216
+	}
217
+
218
+
219
+
220
+	/**
221
+	 * Returns the Currency object for this money
222
+	 *
223
+	 * @return Currency
224
+	 */
225
+	public function currency()
226
+	{
227
+		return $this->currency;
228
+	}
229
+
230
+
231
+
232
+	/**
233
+	 * adds the supplied Money amount to this Money amount
234
+	 * and returns a new Money object
235
+	 *
236
+	 * @param Money $other
237
+	 * @return Money
238
+	 * @throws InvalidArgumentException
239
+	 */
240
+	public function add(Money $other)
241
+	{
242
+		$this->verifySameCurrency($other->currency());
243
+		return new Money(
244
+			$this->calculator()->add(
245
+				$this->amount(),
246
+				$other->amount()
247
+			),
248
+			$this->currency(),
249
+			$this->calculator(),
250
+			$this->formatters()
251
+		);
252
+	}
253
+
254
+
255
+
256
+	/**
257
+	 * subtracts the supplied Money amount from this Money amount
258
+	 * and returns a new Money object
259
+	 *
260
+	 * @param Money $other
261
+	 * @return Money
262
+	 * @throws InvalidArgumentException
263
+	 */
264
+	public function subtract(Money $other)
265
+	{
266
+		$this->verifySameCurrency($other->currency());
267
+		return new Money(
268
+			$this->calculator()->subtract(
269
+				$this->amount(),
270
+				$other->amount()
271
+			),
272
+			$this->currency(),
273
+			$this->calculator(),
274
+			$this->formatters()
275
+		);
276
+	}
277
+
278
+
279
+
280
+	/**
281
+	 * multiplies this Money amount by the supplied $multiplier
282
+	 * and returns a new Money object
283
+	 *
284
+	 * @param float|int|string $multiplier
285
+	 * @param int              $rounding_mode
286
+	 * @return Money
287
+	 * @throws InvalidDataTypeException
288
+	 */
289
+	public function multiply($multiplier, $rounding_mode = Calculator::ROUND_HALF_UP)
290
+	{
291
+		return new Money(
292
+			$this->calculator()->multiply(
293
+				$this->amount(),
294
+				$multiplier,
295
+				$this->precision(),
296
+				$rounding_mode
297
+			),
298
+			$this->currency(),
299
+			$this->calculator(),
300
+			$this->formatters()
301
+		);
302
+	}
303
+
304
+
305
+
306
+	/**
307
+	 * divides this Money amount by the supplied $divisor
308
+	 * and returns a new Money object
309
+	 *
310
+	 * @param float|int|string $divisor
311
+	 * @param int              $rounding_mode
312
+	 * @return Money
313
+	 * @throws InvalidDataTypeException
314
+	 */
315
+	public function divide($divisor, $rounding_mode = Calculator::ROUND_HALF_UP)
316
+	{
317
+		return new Money(
318
+			$this->calculator()->divide(
319
+				$this->amount(),
320
+				$divisor,
321
+				$this->precision(),
322
+				$rounding_mode
323
+			),
324
+			$this->currency(),
325
+			$this->calculator(),
326
+			$this->formatters()
327
+		);
328
+	}
329
+
330
+
331
+
332
+	/**
333
+	 * @param Currency $other_currency
334
+	 * @throws InvalidArgumentException
335
+	 */
336
+	public function verifySameCurrency(Currency $other_currency)
337
+	{
338
+		if ($this->currency()->equals($other_currency) !== true) {
339
+			throw new InvalidArgumentException(
340
+				esc_html__(
341
+					'Currencies must be the same in order to add or subtract their values.',
342
+					'event_espresso'
343
+				)
344
+			);
345
+		}
346
+	}
347
+
348
+
349
+
350
+	/**
351
+	 * @return string
352
+	 */
353
+	public function __toString()
354
+	{
355
+		return $this->format(MoneyFormatter::DECIMAL_ONLY);
356
+	}
357 357
 }
358 358
 // End of file Money.php
359 359
 // Location: core/entities/money/Money.php
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -38,217 +38,217 @@
 block discarded – undo
38 38
  * @since       4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 
64 64
 } else {
65
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
-        /**
68
-         * espresso_minimum_php_version_error
69
-         *
70
-         * @return void
71
-         */
72
-        function espresso_minimum_php_version_error()
73
-        {
74
-            ?>
65
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
+		/**
68
+		 * espresso_minimum_php_version_error
69
+		 *
70
+		 * @return void
71
+		 */
72
+		function espresso_minimum_php_version_error()
73
+		{
74
+			?>
75 75
             <div class="error">
76 76
                 <p>
77 77
                     <?php
78
-                    printf(
79
-                        esc_html__(
80
-                            '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.',
81
-                            'event_espresso'
82
-                        ),
83
-                        EE_MIN_PHP_VER_REQUIRED,
84
-                        PHP_VERSION,
85
-                        '<br/>',
86
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
-                    );
88
-                    ?>
78
+					printf(
79
+						esc_html__(
80
+							'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.',
81
+							'event_espresso'
82
+						),
83
+						EE_MIN_PHP_VER_REQUIRED,
84
+						PHP_VERSION,
85
+						'<br/>',
86
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
+					);
88
+					?>
89 89
                 </p>
90 90
             </div>
91 91
             <?php
92
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
93
-        }
92
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
93
+		}
94 94
 
95
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
-    } else {
97
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
-        /**
99
-         * espresso_version
100
-         * Returns the plugin version
101
-         *
102
-         * @return string
103
-         */
104
-        function espresso_version()
105
-        {
106
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.51.rc.006');
107
-        }
95
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
+	} else {
97
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
+		/**
99
+		 * espresso_version
100
+		 * Returns the plugin version
101
+		 *
102
+		 * @return string
103
+		 */
104
+		function espresso_version()
105
+		{
106
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.51.rc.006');
107
+		}
108 108
 
109
-        /**
110
-         * espresso_plugin_activation
111
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
-         */
113
-        function espresso_plugin_activation()
114
-        {
115
-            update_option('ee_espresso_activation', true);
116
-        }
109
+		/**
110
+		 * espresso_plugin_activation
111
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
+		 */
113
+		function espresso_plugin_activation()
114
+		{
115
+			update_option('ee_espresso_activation', true);
116
+		}
117 117
 
118
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
-        /**
120
-         *    espresso_load_error_handling
121
-         *    this function loads EE's class for handling exceptions and errors
122
-         */
123
-        function espresso_load_error_handling()
124
-        {
125
-            static $error_handling_loaded = false;
126
-            if ($error_handling_loaded) {
127
-                return;
128
-            }
129
-            // load debugging tools
130
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
-                require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
-                \EEH_Debug_Tools::instance();
133
-            }
134
-            // load error handling
135
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
-                require_once EE_CORE . 'EE_Error.core.php';
137
-            } else {
138
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
-            }
140
-            $error_handling_loaded = true;
141
-        }
118
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
+		/**
120
+		 *    espresso_load_error_handling
121
+		 *    this function loads EE's class for handling exceptions and errors
122
+		 */
123
+		function espresso_load_error_handling()
124
+		{
125
+			static $error_handling_loaded = false;
126
+			if ($error_handling_loaded) {
127
+				return;
128
+			}
129
+			// load debugging tools
130
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
+				require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
+				\EEH_Debug_Tools::instance();
133
+			}
134
+			// load error handling
135
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
+				require_once EE_CORE . 'EE_Error.core.php';
137
+			} else {
138
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
+			}
140
+			$error_handling_loaded = true;
141
+		}
142 142
 
143
-        /**
144
-         *    espresso_load_required
145
-         *    given a class name and path, this function will load that file or throw an exception
146
-         *
147
-         * @param    string $classname
148
-         * @param    string $full_path_to_file
149
-         * @throws    EE_Error
150
-         */
151
-        function espresso_load_required($classname, $full_path_to_file)
152
-        {
153
-            if (is_readable($full_path_to_file)) {
154
-                require_once $full_path_to_file;
155
-            } else {
156
-                throw new \EE_Error (
157
-                    sprintf(
158
-                        esc_html__(
159
-                            'The %s class file could not be located or is not readable due to file permissions.',
160
-                            'event_espresso'
161
-                        ),
162
-                        $classname
163
-                    )
164
-                );
165
-            }
166
-        }
143
+		/**
144
+		 *    espresso_load_required
145
+		 *    given a class name and path, this function will load that file or throw an exception
146
+		 *
147
+		 * @param    string $classname
148
+		 * @param    string $full_path_to_file
149
+		 * @throws    EE_Error
150
+		 */
151
+		function espresso_load_required($classname, $full_path_to_file)
152
+		{
153
+			if (is_readable($full_path_to_file)) {
154
+				require_once $full_path_to_file;
155
+			} else {
156
+				throw new \EE_Error (
157
+					sprintf(
158
+						esc_html__(
159
+							'The %s class file could not be located or is not readable due to file permissions.',
160
+							'event_espresso'
161
+						),
162
+						$classname
163
+					)
164
+				);
165
+			}
166
+		}
167 167
 
168
-        /**
169
-         * @since 4.9.27
170
-         * @throws \EE_Error
171
-         * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
-         * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
-         * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
-         * @throws \EventEspresso\core\exceptions\InvalidClassException
175
-         * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
-         * @throws \OutOfBoundsException
179
-         */
180
-        function bootstrap_espresso()
181
-        {
182
-            require_once __DIR__ . '/core/espresso_definitions.php';
183
-            try {
184
-                espresso_load_error_handling();
185
-                espresso_load_required(
186
-                    'EEH_Base',
187
-                    EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
-                );
189
-                espresso_load_required(
190
-                    'EEH_File',
191
-                    EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
-                );
193
-                espresso_load_required(
194
-                    'EEH_File',
195
-                    EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
-                );
197
-                espresso_load_required(
198
-                    'EEH_Array',
199
-                    EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
-                );
201
-                // instantiate and configure PSR4 autoloader
202
-                espresso_load_required(
203
-                    'Psr4Autoloader',
204
-                    EE_CORE . 'Psr4Autoloader.php'
205
-                );
206
-                espresso_load_required(
207
-                    'EE_Psr4AutoloaderInit',
208
-                    EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
-                );
210
-                $AutoloaderInit = new EE_Psr4AutoloaderInit();
211
-                $AutoloaderInit->initializeAutoloader();
212
-                espresso_load_required(
213
-                    'EE_Request',
214
-                    EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
-                );
216
-                espresso_load_required(
217
-                    'EE_Response',
218
-                    EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
-                );
220
-                espresso_load_required(
221
-                    'EE_Bootstrap',
222
-                    EE_CORE . 'EE_Bootstrap.core.php'
223
-                );
224
-                // bootstrap EE and the request stack
225
-                new EE_Bootstrap(
226
-                    new EE_Request($_GET, $_POST, $_COOKIE),
227
-                    new EE_Response()
228
-                );
229
-            } catch (Exception $e) {
230
-                require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
-                new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
-            }
233
-        }
234
-        bootstrap_espresso();
235
-    }
168
+		/**
169
+		 * @since 4.9.27
170
+		 * @throws \EE_Error
171
+		 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
+		 * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
+		 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
+		 * @throws \EventEspresso\core\exceptions\InvalidClassException
175
+		 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
+		 * @throws \OutOfBoundsException
179
+		 */
180
+		function bootstrap_espresso()
181
+		{
182
+			require_once __DIR__ . '/core/espresso_definitions.php';
183
+			try {
184
+				espresso_load_error_handling();
185
+				espresso_load_required(
186
+					'EEH_Base',
187
+					EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
+				);
189
+				espresso_load_required(
190
+					'EEH_File',
191
+					EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
+				);
193
+				espresso_load_required(
194
+					'EEH_File',
195
+					EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
+				);
197
+				espresso_load_required(
198
+					'EEH_Array',
199
+					EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
+				);
201
+				// instantiate and configure PSR4 autoloader
202
+				espresso_load_required(
203
+					'Psr4Autoloader',
204
+					EE_CORE . 'Psr4Autoloader.php'
205
+				);
206
+				espresso_load_required(
207
+					'EE_Psr4AutoloaderInit',
208
+					EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
+				);
210
+				$AutoloaderInit = new EE_Psr4AutoloaderInit();
211
+				$AutoloaderInit->initializeAutoloader();
212
+				espresso_load_required(
213
+					'EE_Request',
214
+					EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
+				);
216
+				espresso_load_required(
217
+					'EE_Response',
218
+					EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
+				);
220
+				espresso_load_required(
221
+					'EE_Bootstrap',
222
+					EE_CORE . 'EE_Bootstrap.core.php'
223
+				);
224
+				// bootstrap EE and the request stack
225
+				new EE_Bootstrap(
226
+					new EE_Request($_GET, $_POST, $_COOKIE),
227
+					new EE_Response()
228
+				);
229
+			} catch (Exception $e) {
230
+				require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
+				new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
+			}
233
+		}
234
+		bootstrap_espresso();
235
+	}
236 236
 }
237 237
 if (! function_exists('espresso_deactivate_plugin')) {
238
-    /**
239
-     *    deactivate_plugin
240
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
-     *
242
-     * @access public
243
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
-     * @return    void
245
-     */
246
-    function espresso_deactivate_plugin($plugin_basename = '')
247
-    {
248
-        if (! function_exists('deactivate_plugins')) {
249
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
-        }
251
-        unset($_GET['activate'], $_REQUEST['activate']);
252
-        deactivate_plugins($plugin_basename);
253
-    }
238
+	/**
239
+	 *    deactivate_plugin
240
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
+	 *
242
+	 * @access public
243
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
+	 * @return    void
245
+	 */
246
+	function espresso_deactivate_plugin($plugin_basename = '')
247
+	{
248
+		if (! function_exists('deactivate_plugins')) {
249
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
+		}
251
+		unset($_GET['activate'], $_REQUEST['activate']);
252
+		deactivate_plugins($plugin_basename);
253
+	}
254 254
 }
Please login to merge, or discard this patch.
core/helpers/EEH_File.helper.php 2 patches
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -311,8 +311,8 @@  discard block
 block discarded – undo
311 311
 		//eg if given "/var/something/somewhere/", we want to get "somewhere"'s
312 312
 		//parent folder, "/var/something/"
313 313
 		$ds = strlen($file_or_folder_path) > 1
314
-            ? strrpos($file_or_folder_path, DS, -2)
315
-            : strlen($file_or_folder_path);
314
+			? strrpos($file_or_folder_path, DS, -2)
315
+			: strlen($file_or_folder_path);
316 316
 		return substr($file_or_folder_path, 0, $ds + 1);
317 317
 	}
318 318
 
@@ -658,14 +658,14 @@  discard block
 block discarded – undo
658 658
 
659 659
 
660 660
 
661
-    /**
662
-     * Resets the file helper's state. Useful between tests that may have used a mock
663
-     * filesystem.
664
-     */
661
+	/**
662
+	 * Resets the file helper's state. Useful between tests that may have used a mock
663
+	 * filesystem.
664
+	 */
665 665
 	public static function reset()
666
-    {
667
-        self::$_wp_filesystem_direct = null;
668
-    }
666
+	{
667
+		self::$_wp_filesystem_direct = null;
668
+	}
669 669
 }
670 670
 // End of file EEH_File.helper.php
671 671
 // Location: /helpers/EEH_File.helper.php
672 672
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +174 added lines, -174 removed lines patch added patch discarded remove patch
@@ -38,30 +38,30 @@  discard block
 block discarded – undo
38 38
 	 * @throws EE_Error if filesystem credentials are required
39 39
 	 * @return WP_Filesystem_Base
40 40
 	 */
41
-	private static function _get_wp_filesystem( $filepath = null) {
42
-		if( apply_filters(
41
+	private static function _get_wp_filesystem($filepath = null) {
42
+		if (apply_filters(
43 43
 				'FHEE__EEH_File___get_wp_filesystem__allow_using_filesystem_direct',
44
-				$filepath && EEH_File::is_in_uploads_folder( $filepath ),
45
-				$filepath ) ) {
46
-			if( ! EEH_File::$_wp_filesystem_direct instanceof WP_Filesystem_Direct ) {
47
-				require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
44
+				$filepath && EEH_File::is_in_uploads_folder($filepath),
45
+				$filepath )) {
46
+			if ( ! EEH_File::$_wp_filesystem_direct instanceof WP_Filesystem_Direct) {
47
+				require_once(ABSPATH.'wp-admin/includes/class-wp-filesystem-base.php');
48 48
 				$method = 'direct';
49
-				$wp_filesystem_direct_file = apply_filters( 'filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method );
49
+				$wp_filesystem_direct_file = apply_filters('filesystem_method_file', ABSPATH.'wp-admin/includes/class-wp-filesystem-'.$method.'.php', $method);
50 50
 				//check constants defined, just like in wp-admin/includes/file.php's WP_Filesystem()
51
-				if ( ! defined('FS_CHMOD_DIR') ) {
52
-					define('FS_CHMOD_DIR', ( fileperms( ABSPATH ) & 0777 | 0755 ) );
51
+				if ( ! defined('FS_CHMOD_DIR')) {
52
+					define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0777 | 0755));
53 53
 				}
54
-				if ( ! defined('FS_CHMOD_FILE') ) {
55
-					define('FS_CHMOD_FILE', ( fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ) );
54
+				if ( ! defined('FS_CHMOD_FILE')) {
55
+					define('FS_CHMOD_FILE', (fileperms(ABSPATH.'index.php') & 0777 | 0644));
56 56
 				}
57
-				require_once( $wp_filesystem_direct_file );
58
-				EEH_File::$_wp_filesystem_direct = new WP_Filesystem_Direct( array() );
57
+				require_once($wp_filesystem_direct_file);
58
+				EEH_File::$_wp_filesystem_direct = new WP_Filesystem_Direct(array());
59 59
 			}
60 60
 			return EEH_File::$_wp_filesystem_direct;
61 61
 		}
62 62
 		global $wp_filesystem;
63 63
 		// no filesystem setup ???
64
-		if ( ! $wp_filesystem instanceof WP_Filesystem_Base ) {
64
+		if ( ! $wp_filesystem instanceof WP_Filesystem_Base) {
65 65
 			// if some eager beaver's just trying to get in there too early...
66 66
 			// let them do it, because we are one of those eager beavers! :P
67 67
 			/**
@@ -74,34 +74,34 @@  discard block
 block discarded – undo
74 74
 			 * and there may be troubles if the WP files are owned by a different user
75 75
 			 * than the server user. But both of these issues should exist in 4.4 and earlier too
76 76
 			 */
77
-			if ( FALSE && ! did_action( 'wp_loaded' )) {
77
+			if (FALSE && ! did_action('wp_loaded')) {
78 78
 				$msg = __('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso');
79
-				if ( WP_DEBUG ) {
80
-					$msg .= '<br />' .  __('The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.', 'event_espresso');
79
+				if (WP_DEBUG) {
80
+					$msg .= '<br />'.__('The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.', 'event_espresso');
81 81
 				}
82
-				throw new EE_Error( $msg );
82
+				throw new EE_Error($msg);
83 83
 			} else {
84 84
 				// should be loaded if we are past the wp_loaded hook...
85
-				if ( ! function_exists( 'WP_Filesystem' )) {
86
-					require_once( ABSPATH . 'wp-admin/includes/file.php' );
87
-					require_once( ABSPATH . 'wp-admin/includes/template.php' );
85
+				if ( ! function_exists('WP_Filesystem')) {
86
+					require_once(ABSPATH.'wp-admin/includes/file.php');
87
+					require_once(ABSPATH.'wp-admin/includes/template.php');
88 88
 				}
89 89
 				// turn on output buffering so that we can capture the credentials form
90 90
 				ob_start();
91
-				$credentials = request_filesystem_credentials( '' );
91
+				$credentials = request_filesystem_credentials('');
92 92
 				// store credentials form for the time being
93 93
 				EEH_File::$_credentials_form = ob_get_clean();
94 94
 				// basically check for direct or previously configured access
95
-				if ( ! WP_Filesystem( $credentials ) ) {
95
+				if ( ! WP_Filesystem($credentials)) {
96 96
 					// if credentials do NOT exist
97
-					if ( $credentials === FALSE ) {
98
-						add_action( 'admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999 );
99
-						throw new EE_Error( __('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso'));
100
-					} elseif( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
101
-						add_action( 'admin_notices', array( 'EEH_File', 'display_request_filesystem_credentials_form' ), 999 );
97
+					if ($credentials === FALSE) {
98
+						add_action('admin_notices', array('EEH_File', 'display_request_filesystem_credentials_form'), 999);
99
+						throw new EE_Error(__('An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.', 'event_espresso'));
100
+					} elseif (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
101
+						add_action('admin_notices', array('EEH_File', 'display_request_filesystem_credentials_form'), 999);
102 102
 						throw new EE_Error(
103 103
 								sprintf(
104
-										__( 'WP Filesystem Error: $1%s', 'event_espresso' ),
104
+										__('WP Filesystem Error: $1%s', 'event_espresso'),
105 105
 										$wp_filesystem->errors->get_error_message() ) );
106 106
 					}
107 107
 				}
@@ -114,8 +114,8 @@  discard block
 block discarded – undo
114 114
 	 * display_request_filesystem_credentials_form
115 115
 	 */
116 116
 	public static function display_request_filesystem_credentials_form() {
117
-		if ( ! empty( EEH_File::$_credentials_form )) {
118
-			echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
117
+		if ( ! empty(EEH_File::$_credentials_form)) {
118
+			echo '<div class="updated espresso-notices-attention"><p>'.EEH_File::$_credentials_form.'</p></div>';
119 119
 		}
120 120
 	}
121 121
 
@@ -133,29 +133,29 @@  discard block
 block discarded – undo
133 133
 	 * @throws EE_Error if filesystem credentials are required
134 134
 	 * @return bool
135 135
 	 */
136
-	public static function verify_filepath_and_permissions( $full_file_path = '', $file_name = '', $file_ext = '', $type_of_file = '' ) {
136
+	public static function verify_filepath_and_permissions($full_file_path = '', $file_name = '', $file_ext = '', $type_of_file = '') {
137 137
 		// load WP_Filesystem and set file permissions
138
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $full_file_path );
139
-		$full_file_path = EEH_File::standardise_directory_separators( $full_file_path );
140
-		if ( ! $wp_filesystem->is_readable( EEH_File::convert_local_filepath_to_remote_filepath( $full_file_path ) )) {
141
-			$file_name = ! empty( $type_of_file ) ? $file_name . ' ' . $type_of_file : $file_name;
142
-			$file_name .= ! empty( $file_ext ) ? ' file' : ' folder';
138
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
139
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
140
+		if ( ! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
141
+			$file_name = ! empty($type_of_file) ? $file_name.' '.$type_of_file : $file_name;
142
+			$file_name .= ! empty($file_ext) ? ' file' : ' folder';
143 143
 			$msg = sprintf(
144
-				__( 'The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s', 'event_espresso' ),
144
+				__('The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s', 'event_espresso'),
145 145
 				$file_name,
146 146
 				'<br />'
147 147
 			);
148
-			if ( EEH_File::exists( $full_file_path )) {
149
-				$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_file_path, $type_of_file );
148
+			if (EEH_File::exists($full_file_path)) {
149
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, $type_of_file);
150 150
 			} else {
151 151
 				// no file permissions means the file was not found
152 152
 				$msg .= sprintf(
153
-					__( 'Please ensure the following path is correct: "%s".', 'event_espresso' ),
153
+					__('Please ensure the following path is correct: "%s".', 'event_espresso'),
154 154
 					$full_file_path
155 155
 				);
156 156
 			}
157
-			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
158
-				throw new EE_Error( $msg . '||' . $msg );
157
+			if (defined('WP_DEBUG') && WP_DEBUG) {
158
+				throw new EE_Error($msg.'||'.$msg);
159 159
 			}
160 160
 			return FALSE;
161 161
 		}
@@ -173,24 +173,24 @@  discard block
 block discarded – undo
173 173
 	 * @throws EE_Error if filesystem credentials are required
174 174
 	 * @return string
175 175
 	 */
176
-	private static function _permissions_error_for_unreadable_filepath( $full_file_path = '', $type_of_file = '' ){
176
+	private static function _permissions_error_for_unreadable_filepath($full_file_path = '', $type_of_file = '') {
177 177
 		// load WP_Filesystem and set file permissions
178
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $full_file_path );
178
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
179 179
 		// check file permissions
180
-		$perms = $wp_filesystem->getchmod( EEH_File::convert_local_filepath_to_remote_filepath( $full_file_path ) );
181
-		if ( $perms ) {
180
+		$perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
181
+		if ($perms) {
182 182
 			// file permissions exist, but way be set incorrectly
183
-			$type_of_file = ! empty( $type_of_file ) ? $type_of_file . ' ' : '';
184
-			$type_of_file .= ! empty( $type_of_file ) ? 'file' : 'folder';
183
+			$type_of_file = ! empty($type_of_file) ? $type_of_file.' ' : '';
184
+			$type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
185 185
 			return sprintf(
186
-				__( 'File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.', 'event_espresso' ),
186
+				__('File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.', 'event_espresso'),
187 187
 				$type_of_file,
188 188
 				$perms
189 189
 			);
190 190
 		} else {
191 191
 			// file exists but file permissions could not be read ?!?!
192 192
 			return sprintf(
193
-				__( 'Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".', 'event_espresso' ),
193
+				__('Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".', 'event_espresso'),
194 194
 				$full_file_path
195 195
 			);
196 196
 		}
@@ -208,35 +208,35 @@  discard block
 block discarded – undo
208 208
 	 * can't write to it
209 209
 	 * @return bool false if folder isn't writable; true if it exists and is writeable,
210 210
 	 */
211
-	public static function ensure_folder_exists_and_is_writable( $folder = '' ){
212
-		if ( empty( $folder )) {
211
+	public static function ensure_folder_exists_and_is_writable($folder = '') {
212
+		if (empty($folder)) {
213 213
 			return false;
214 214
 		}
215 215
 		// remove ending DS
216
-		$folder = EEH_File::standardise_directory_separators( rtrim( $folder, '/\\' ));
217
-		$parent_folder = EEH_File::get_parent_folder( $folder );
216
+		$folder = EEH_File::standardise_directory_separators(rtrim($folder, '/\\'));
217
+		$parent_folder = EEH_File::get_parent_folder($folder);
218 218
 		// add DS to folder
219
-		$folder = EEH_File::end_with_directory_separator( $folder );
220
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $folder );
221
-		if ( ! $wp_filesystem->is_dir( EEH_File::convert_local_filepath_to_remote_filepath( $folder ) ) ) {
219
+		$folder = EEH_File::end_with_directory_separator($folder);
220
+		$wp_filesystem = EEH_File::_get_wp_filesystem($folder);
221
+		if ( ! $wp_filesystem->is_dir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
222 222
 			//ok so it doesn't exist. Does its parent? Can we write to it?
223
-			if(	! EEH_File::ensure_folder_exists_and_is_writable( $parent_folder ) ) {
223
+			if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
224 224
 				return false;
225 225
 			}
226
-			if ( ! EEH_File::verify_is_writable( $parent_folder, 'folder' )) {
226
+			if ( ! EEH_File::verify_is_writable($parent_folder, 'folder')) {
227 227
 				return false;
228 228
 			} else {
229
-				if ( ! $wp_filesystem->mkdir( EEH_File::convert_local_filepath_to_remote_filepath(  $folder ) ) ) {
230
-					if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
231
-						$msg = sprintf( __( '"%s" could not be created.', 'event_espresso' ), $folder );
232
-						$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $folder );
233
-						throw new EE_Error( $msg );
229
+				if ( ! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
230
+					if (defined('WP_DEBUG') && WP_DEBUG) {
231
+						$msg = sprintf(__('"%s" could not be created.', 'event_espresso'), $folder);
232
+						$msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
233
+						throw new EE_Error($msg);
234 234
 					}
235 235
 					return false;
236 236
 				}
237
-				EEH_File::add_index_file( $folder );
237
+				EEH_File::add_index_file($folder);
238 238
 			}
239
-		} elseif ( ! EEH_File::verify_is_writable( $folder, 'folder' )) {
239
+		} elseif ( ! EEH_File::verify_is_writable($folder, 'folder')) {
240 240
 			return false;
241 241
 		}
242 242
 		return true;
@@ -251,15 +251,15 @@  discard block
 block discarded – undo
251 251
 	 * @throws EE_Error if filesystem credentials are required
252 252
 	 * @return bool
253 253
 	 */
254
-	public static function verify_is_writable( $full_path = '', $file_or_folder = 'folder' ){
254
+	public static function verify_is_writable($full_path = '', $file_or_folder = 'folder') {
255 255
 		// load WP_Filesystem and set file permissions
256
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $full_path );
257
-		$full_path = EEH_File::standardise_directory_separators( $full_path );
258
-		if ( ! $wp_filesystem->is_writable( EEH_File::convert_local_filepath_to_remote_filepath( $full_path ) ) ) {
259
-			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
260
-				$msg = sprintf( __( 'The "%1$s" %2$s is not writable.', 'event_espresso' ), $full_path, $file_or_folder );
261
-				$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_path );
262
-				throw new EE_Error( $msg );
256
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
257
+		$full_path = EEH_File::standardise_directory_separators($full_path);
258
+		if ( ! $wp_filesystem->is_writable(EEH_File::convert_local_filepath_to_remote_filepath($full_path))) {
259
+			if (defined('WP_DEBUG') && WP_DEBUG) {
260
+				$msg = sprintf(__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
261
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
262
+				throw new EE_Error($msg);
263 263
 			}
264 264
 			return FALSE;
265 265
 		}
@@ -276,25 +276,25 @@  discard block
 block discarded – undo
276 276
 	 * @throws EE_Error if filesystem credentials are required
277 277
 	 * @return bool
278 278
 	 */
279
-	public static function ensure_file_exists_and_is_writable( $full_file_path = '' ) {
279
+	public static function ensure_file_exists_and_is_writable($full_file_path = '') {
280 280
 		// load WP_Filesystem and set file permissions
281
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $full_file_path );
282
-		$full_file_path = EEH_File::standardise_directory_separators( $full_file_path );
283
-		$parent_folder = EEH_File::get_parent_folder( $full_file_path );
284
-		if ( ! EEH_File::exists( $full_file_path )) {
285
-			if( ! EEH_File::ensure_folder_exists_and_is_writable( $parent_folder ) ) {
281
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
282
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
283
+		$parent_folder = EEH_File::get_parent_folder($full_file_path);
284
+		if ( ! EEH_File::exists($full_file_path)) {
285
+			if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
286 286
 				return false;
287 287
 			}
288
-			if ( ! $wp_filesystem->touch( EEH_File::convert_local_filepath_to_remote_filepath( $full_file_path ) ) ) {
289
-				if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
290
-					$msg = sprintf( __( 'The "%s" file could not be created.', 'event_espresso' ), $full_file_path );
291
-					$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_file_path );
292
-					throw new EE_Error( $msg );
288
+			if ( ! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
289
+				if (defined('WP_DEBUG') && WP_DEBUG) {
290
+					$msg = sprintf(__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
291
+					$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
292
+					throw new EE_Error($msg);
293 293
 				}
294 294
 				return false;
295 295
 			}
296 296
 		}
297
-		if ( ! EEH_File::verify_is_writable( $full_file_path, 'file' )) {
297
+		if ( ! EEH_File::verify_is_writable($full_file_path, 'file')) {
298 298
 			return false;
299 299
 		}
300 300
 		return true;
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
 	 * @param string $file_or_folder_path
307 307
 	 * @return string parent folder, ENDING with a directory separator
308 308
 	 */
309
-	public static function get_parent_folder( $file_or_folder_path ) {
309
+	public static function get_parent_folder($file_or_folder_path) {
310 310
 		//find the last DS, ignoring a DS on the very end
311 311
 		//eg if given "/var/something/somewhere/", we want to get "somewhere"'s
312 312
 		//parent folder, "/var/something/"
@@ -328,12 +328,12 @@  discard block
 block discarded – undo
328 328
 	 * @throws EE_Error if filesystem credentials are required
329 329
 	 * @return string
330 330
 	 */
331
-	public static function get_file_contents( $full_file_path = '' ){
332
-		$full_file_path = EEH_File::standardise_directory_separators( $full_file_path );
333
-		if ( EEH_File::verify_filepath_and_permissions( $full_file_path, EEH_File::get_filename_from_filepath( $full_file_path ) , EEH_File::get_file_extension( $full_file_path ))) {
331
+	public static function get_file_contents($full_file_path = '') {
332
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
333
+		if (EEH_File::verify_filepath_and_permissions($full_file_path, EEH_File::get_filename_from_filepath($full_file_path), EEH_File::get_file_extension($full_file_path))) {
334 334
 			// load WP_Filesystem and set file permissions
335
-			$wp_filesystem = EEH_File::_get_wp_filesystem( $full_file_path );
336
-			return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath( $full_file_path ) );
335
+			$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
336
+			return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
337 337
 		}
338 338
 		return '';
339 339
 	}
@@ -348,26 +348,26 @@  discard block
 block discarded – undo
348 348
 	 * @throws EE_Error if filesystem credentials are required
349 349
 	 * @return bool
350 350
 	 */
351
-	public static function write_to_file( $full_file_path = '', $file_contents = '', $file_type = '' ){
352
-		$full_file_path = EEH_File::standardise_directory_separators( $full_file_path );
353
-		$file_type = ! empty( $file_type ) ? rtrim( $file_type, ' ' ) . ' ' : '';
354
-		$folder = EEH_File::remove_filename_from_filepath( $full_file_path );
355
-		if ( ! EEH_File::verify_is_writable( $folder, 'folder' )) {
356
-			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
357
-				$msg = sprintf( __( 'The %1$sfile located at "%2$s" is not writable.', 'event_espresso' ), $file_type, $full_file_path );
358
-				$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_file_path );
359
-				throw new EE_Error( $msg );
351
+	public static function write_to_file($full_file_path = '', $file_contents = '', $file_type = '') {
352
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
353
+		$file_type = ! empty($file_type) ? rtrim($file_type, ' ').' ' : '';
354
+		$folder = EEH_File::remove_filename_from_filepath($full_file_path);
355
+		if ( ! EEH_File::verify_is_writable($folder, 'folder')) {
356
+			if (defined('WP_DEBUG') && WP_DEBUG) {
357
+				$msg = sprintf(__('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'), $file_type, $full_file_path);
358
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
359
+				throw new EE_Error($msg);
360 360
 			}
361 361
 			return FALSE;
362 362
 		}
363 363
 		// load WP_Filesystem and set file permissions
364
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $full_file_path );
364
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
365 365
 		// write the file
366
-		if ( ! $wp_filesystem->put_contents(EEH_File::convert_local_filepath_to_remote_filepath( $full_file_path ), $file_contents )) {
367
-			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
368
-				$msg = sprintf( __( 'The %1$sfile located at "%2$s" could not be written to.', 'event_espresso' ), $file_type, $full_file_path );
369
-				$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_file_path, 'f' );
370
-				throw new EE_Error( $msg );
366
+		if ( ! $wp_filesystem->put_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path), $file_contents)) {
367
+			if (defined('WP_DEBUG') && WP_DEBUG) {
368
+				$msg = sprintf(__('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'), $file_type, $full_file_path);
369
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
370
+				throw new EE_Error($msg);
371 371
 			}
372 372
 			return FALSE;
373 373
 		}
@@ -383,9 +383,9 @@  discard block
 block discarded – undo
383 383
 	 * @throws EE_Error if filesystem credentials are required
384 384
 	 * @return boolean
385 385
 	 */
386
-	public static function delete( $filepath, $recursive = false, $type = false ) {
386
+	public static function delete($filepath, $recursive = false, $type = false) {
387 387
 		$wp_filesystem = EEH_File::_get_wp_filesystem();
388
-		return $wp_filesystem->delete( $filepath, $recursive, $type ) ? TRUE : FALSE;
388
+		return $wp_filesystem->delete($filepath, $recursive, $type) ? TRUE : FALSE;
389 389
 	}
390 390
 
391 391
 
@@ -397,9 +397,9 @@  discard block
 block discarded – undo
397 397
 	 * @throws EE_Error if filesystem credentials are required
398 398
 	 * @return bool
399 399
 	 */
400
-	public static function exists( $full_file_path = '' ) {
401
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $full_file_path );
402
-		return $wp_filesystem->exists( EEH_File::convert_local_filepath_to_remote_filepath( $full_file_path ) ) ? TRUE : FALSE;
400
+	public static function exists($full_file_path = '') {
401
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
402
+		return $wp_filesystem->exists(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path)) ? TRUE : FALSE;
403 403
 	}
404 404
 
405 405
 
@@ -412,9 +412,9 @@  discard block
 block discarded – undo
412 412
 	 * @throws EE_Error if filesystem credentials are required
413 413
 	 * @return bool
414 414
 	 */
415
-	public static function is_readable( $full_file_path = '' ) {
416
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $full_file_path );
417
-		if( $wp_filesystem->is_readable( EEH_File::convert_local_filepath_to_remote_filepath(  $full_file_path ) ) ) {
415
+	public static function is_readable($full_file_path = '') {
416
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
417
+		if ($wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
418 418
 			return true;
419 419
 		} else {
420 420
 			return false;
@@ -430,8 +430,8 @@  discard block
 block discarded – undo
430 430
 	 * @param string $full_file_path
431 431
 	 * @return string
432 432
 	 */
433
-	public static function remove_filename_from_filepath( $full_file_path = '' ) {
434
-		return pathinfo( $full_file_path, PATHINFO_DIRNAME );
433
+	public static function remove_filename_from_filepath($full_file_path = '') {
434
+		return pathinfo($full_file_path, PATHINFO_DIRNAME);
435 435
 	}
436 436
 
437 437
 
@@ -441,8 +441,8 @@  discard block
 block discarded – undo
441 441
 	 * @param string $full_file_path
442 442
 	 * @return string
443 443
 	 */
444
-	public static function get_filename_from_filepath( $full_file_path = '' ) {
445
-		return pathinfo( $full_file_path, PATHINFO_BASENAME );
444
+	public static function get_filename_from_filepath($full_file_path = '') {
445
+		return pathinfo($full_file_path, PATHINFO_BASENAME);
446 446
 	}
447 447
 
448 448
 
@@ -452,8 +452,8 @@  discard block
 block discarded – undo
452 452
 	 * @param string $full_file_path
453 453
 	 * @return string
454 454
 	 */
455
-	public static function get_file_extension( $full_file_path = '' ) {
456
-		return pathinfo( $full_file_path, PATHINFO_EXTENSION );
455
+	public static function get_file_extension($full_file_path = '') {
456
+		return pathinfo($full_file_path, PATHINFO_EXTENSION);
457 457
 	}
458 458
 
459 459
 
@@ -464,10 +464,10 @@  discard block
 block discarded – undo
464 464
 	 * @throws EE_Error if filesystem credentials are required
465 465
 	 * @return bool
466 466
 	 */
467
-	public static function add_htaccess_deny_from_all( $folder = '' ) {
468
-		$folder = EEH_File::standardise_and_end_with_directory_separator( $folder );
469
-		if ( ! EEH_File::exists( $folder . '.htaccess' ) ) {
470
-			if ( ! EEH_File::write_to_file( $folder . '.htaccess', 'deny from all', '.htaccess' )) {
467
+	public static function add_htaccess_deny_from_all($folder = '') {
468
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
469
+		if ( ! EEH_File::exists($folder.'.htaccess')) {
470
+			if ( ! EEH_File::write_to_file($folder.'.htaccess', 'deny from all', '.htaccess')) {
471 471
 				return FALSE;
472 472
 			}
473 473
 		}
@@ -481,10 +481,10 @@  discard block
 block discarded – undo
481 481
 	 * @throws EE_Error if filesystem credentials are required
482 482
 	 * @return boolean
483 483
 	 */
484
-	public static function add_index_file( $folder ) {
485
-		$folder = EEH_File::standardise_and_end_with_directory_separator( $folder );
486
-		if ( ! EEH_File::exists( $folder . 'index.php' ) ) {
487
-			if ( ! EEH_File::write_to_file( $folder . 'index.php', 'You are not permitted to read from this folder', '.php' )) {
484
+	public static function add_index_file($folder) {
485
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
486
+		if ( ! EEH_File::exists($folder.'index.php')) {
487
+			if ( ! EEH_File::write_to_file($folder.'index.php', 'You are not permitted to read from this folder', '.php')) {
488 488
 				return false;
489 489
 			}
490 490
 		}
@@ -499,11 +499,11 @@  discard block
 block discarded – undo
499 499
 	 * @param string $file_path
500 500
 	 * @return string
501 501
 	 */
502
-	public static function get_classname_from_filepath_with_standard_filename( $file_path ){
502
+	public static function get_classname_from_filepath_with_standard_filename($file_path) {
503 503
 		//extract file from path
504
-		$filename = basename( $file_path );
504
+		$filename = basename($file_path);
505 505
 		//now remove the first period and everything after
506
-		$pos_of_first_period = strpos( $filename,'.' );
506
+		$pos_of_first_period = strpos($filename, '.');
507 507
 		return substr($filename, 0, $pos_of_first_period);
508 508
 	}
509 509
 
@@ -515,8 +515,8 @@  discard block
 block discarded – undo
515 515
 	 * @param string $file_path
516 516
 	 * @return string
517 517
 	 */
518
-	public static function standardise_directory_separators( $file_path ){
519
-		return str_replace( array( '\\', '/' ), DS, $file_path );
518
+	public static function standardise_directory_separators($file_path) {
519
+		return str_replace(array('\\', '/'), DS, $file_path);
520 520
 	}
521 521
 
522 522
 
@@ -527,8 +527,8 @@  discard block
 block discarded – undo
527 527
 	 * @param string $file_path
528 528
 	 * @return string
529 529
 	 */
530
-	public static function end_with_directory_separator( $file_path ){
531
-		return rtrim( $file_path, '/\\' ) . DS;
530
+	public static function end_with_directory_separator($file_path) {
531
+		return rtrim($file_path, '/\\').DS;
532 532
 	}
533 533
 
534 534
 
@@ -538,8 +538,8 @@  discard block
 block discarded – undo
538 538
 	 * @param $file_path
539 539
 	 * @return string
540 540
 	 */
541
-	public static function standardise_and_end_with_directory_separator( $file_path ){
542
-		return self::end_with_directory_separator( self::standardise_directory_separators( $file_path ));
541
+	public static function standardise_and_end_with_directory_separator($file_path) {
542
+		return self::end_with_directory_separator(self::standardise_directory_separators($file_path));
543 543
 	}
544 544
 
545 545
 
@@ -556,21 +556,21 @@  discard block
 block discarded – undo
556 556
 	 *		if $index_numerically == FALSE (Default) keys are what the class names SHOULD be;
557 557
 	 *		 and values are their filepaths
558 558
 	 */
559
-	public static function get_contents_of_folders( $folder_paths = array(), $index_numerically = FALSE ){
559
+	public static function get_contents_of_folders($folder_paths = array(), $index_numerically = FALSE) {
560 560
 		$class_to_folder_path = array();
561
-		foreach( $folder_paths as $folder_path ){
562
-			$folder_path = self::standardise_and_end_with_directory_separator( $folder_path );
561
+		foreach ($folder_paths as $folder_path) {
562
+			$folder_path = self::standardise_and_end_with_directory_separator($folder_path);
563 563
 			// load WP_Filesystem and set file permissions
564
-			$files_in_folder = glob( $folder_path . '*' );
564
+			$files_in_folder = glob($folder_path.'*');
565 565
 			$class_to_folder_path = array();
566
-			if ( $files_in_folder ) {
567
-				foreach( $files_in_folder as $file_path ){
566
+			if ($files_in_folder) {
567
+				foreach ($files_in_folder as $file_path) {
568 568
 					//only add files, not folders
569
-					if ( ! is_dir( $file_path )) {
570
-						if ( $index_numerically ) {
569
+					if ( ! is_dir($file_path)) {
570
+						if ($index_numerically) {
571 571
 							$class_to_folder_path[] = $file_path;
572 572
 						} else {
573
-							$classname = self::get_classname_from_filepath_with_standard_filename( $file_path );
573
+							$classname = self::get_classname_from_filepath_with_standard_filename($file_path);
574 574
 							$class_to_folder_path[$classname] = $file_path;
575 575
 						}
576 576
 					}
@@ -590,39 +590,39 @@  discard block
 block discarded – undo
590 590
 	 * @throws EE_Error if filesystem credentials are required
591 591
 	 * @return boolean success
592 592
 	 */
593
-	public static function copy( $source_file, $destination_file, $overwrite = FALSE ){
594
-		$full_source_path = EEH_File::standardise_directory_separators( $source_file );
595
-		if( ! EEH_File::exists( $full_source_path ) ){
596
-			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
597
-				$msg = sprintf( __( 'The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso' ), $full_source_path );
598
-				$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_source_path );
599
-				throw new EE_Error( $msg );
593
+	public static function copy($source_file, $destination_file, $overwrite = FALSE) {
594
+		$full_source_path = EEH_File::standardise_directory_separators($source_file);
595
+		if ( ! EEH_File::exists($full_source_path)) {
596
+			if (defined('WP_DEBUG') && WP_DEBUG) {
597
+				$msg = sprintf(__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'), $full_source_path);
598
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
599
+				throw new EE_Error($msg);
600 600
 			}
601 601
 			return FALSE;
602 602
 		}
603 603
 
604
-		$full_dest_path = EEH_File::standardise_directory_separators( $destination_file );
605
-		$folder = EEH_File::remove_filename_from_filepath( $full_dest_path );
606
-		if ( ! EEH_File::verify_is_writable( $folder, 'folder' )) {
607
-			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
608
-				$msg = sprintf( __( 'The file located at "%2$s" is not writable.', 'event_espresso' ), $full_dest_path );
609
-				$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_dest_path );
610
-				throw new EE_Error( $msg );
604
+		$full_dest_path = EEH_File::standardise_directory_separators($destination_file);
605
+		$folder = EEH_File::remove_filename_from_filepath($full_dest_path);
606
+		if ( ! EEH_File::verify_is_writable($folder, 'folder')) {
607
+			if (defined('WP_DEBUG') && WP_DEBUG) {
608
+				$msg = sprintf(__('The file located at "%2$s" is not writable.', 'event_espresso'), $full_dest_path);
609
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
610
+				throw new EE_Error($msg);
611 611
 			}
612 612
 			return FALSE;
613 613
 		}
614 614
 
615 615
 		// load WP_Filesystem and set file permissions
616
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $destination_file );
616
+		$wp_filesystem = EEH_File::_get_wp_filesystem($destination_file);
617 617
 		// write the file
618 618
 		if ( ! $wp_filesystem->copy(
619
-						EEH_File::convert_local_filepath_to_remote_filepath( $full_source_path ),
620
-						EEH_File::convert_local_filepath_to_remote_filepath( $full_dest_path ),
619
+						EEH_File::convert_local_filepath_to_remote_filepath($full_source_path),
620
+						EEH_File::convert_local_filepath_to_remote_filepath($full_dest_path),
621 621
 						$overwrite )) {
622
-			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
623
-				$msg = sprintf( __( 'Attempted writing to file %1$s, but could not, probably because of permissions issues', 'event_espresso' ), $full_source_path );
624
-				$msg .= EEH_File::_permissions_error_for_unreadable_filepath( $full_source_path, 'f' );
625
-				throw new EE_Error( $msg );
622
+			if (defined('WP_DEBUG') && WP_DEBUG) {
623
+				$msg = sprintf(__('Attempted writing to file %1$s, but could not, probably because of permissions issues', 'event_espresso'), $full_source_path);
624
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path, 'f');
625
+				throw new EE_Error($msg);
626 626
 			}
627 627
 			return FALSE;
628 628
 		}
@@ -634,9 +634,9 @@  discard block
 block discarded – undo
634 634
 	 * @param string $filepath
635 635
 	 * @return boolean
636 636
 	 */
637
-	public static function is_in_uploads_folder( $filepath ) {
637
+	public static function is_in_uploads_folder($filepath) {
638 638
 		$uploads = wp_upload_dir();
639
-		return strpos( $filepath, $uploads[ 'basedir' ] ) === 0 ? true : false;
639
+		return strpos($filepath, $uploads['basedir']) === 0 ? true : false;
640 640
 	}
641 641
 
642 642
 	/**
@@ -651,9 +651,9 @@  discard block
 block discarded – undo
651 651
 	 * @return string the remote filepath (eg the filepath the filesystem method, eg
652 652
 	 * ftp or ssh, will use to access the folder
653 653
 	 */
654
-	public static function convert_local_filepath_to_remote_filepath( $local_filepath ) {
655
-		$wp_filesystem = EEH_File::_get_wp_filesystem( $local_filepath );
656
-		return str_replace( WP_CONTENT_DIR . DS, $wp_filesystem->wp_content_dir(), $local_filepath );
654
+	public static function convert_local_filepath_to_remote_filepath($local_filepath) {
655
+		$wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
656
+		return str_replace(WP_CONTENT_DIR.DS, $wp_filesystem->wp_content_dir(), $local_filepath);
657 657
 	}
658 658
 
659 659
 
Please login to merge, or discard this patch.
core/EE_Dependency_Map.core.php 1 patch
Indentation   +814 added lines, -814 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use EventEspresso\core\services\loaders\LoaderInterface;
6 6
 
7 7
 if (! defined('EVENT_ESPRESSO_VERSION')) {
8
-    exit('No direct script access allowed');
8
+	exit('No direct script access allowed');
9 9
 }
10 10
 
11 11
 
@@ -22,819 +22,819 @@  discard block
 block discarded – undo
22 22
 class EE_Dependency_Map
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
-     * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
32
-     */
33
-    const load_new_object = 1;
34
-
35
-    /**
36
-     * This instructs class loaders to return a previously instantiated and cached object for the requested class.
37
-     * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
38
-     */
39
-    const load_from_cache = 2;
40
-
41
-    /**
42
-     * When registering a dependency,
43
-     * this indicates to keep any existing dependencies that already exist,
44
-     * and simply discard any new dependencies declared in the incoming data
45
-     */
46
-    const KEEP_EXISTING_DEPENDENCIES = 0;
47
-
48
-    /**
49
-     * When registering a dependency,
50
-     * this indicates to overwrite any existing dependencies that already exist using the incoming data
51
-     */
52
-    const OVERWRITE_DEPENDENCIES = 1;
53
-
54
-
55
-
56
-    /**
57
-     * @type EE_Dependency_Map $_instance
58
-     */
59
-    protected static $_instance;
60
-
61
-    /**
62
-     * @type EE_Request $request
63
-     */
64
-    protected $_request;
65
-
66
-    /**
67
-     * @type EE_Response $response
68
-     */
69
-    protected $_response;
70
-
71
-    /**
72
-     * @type LoaderInterface $loader
73
-     */
74
-    protected $loader;
75
-
76
-    /**
77
-     * @type array $_dependency_map
78
-     */
79
-    protected $_dependency_map = array();
80
-
81
-    /**
82
-     * @type array $_class_loaders
83
-     */
84
-    protected $_class_loaders = array();
85
-
86
-    /**
87
-     * @type array $_aliases
88
-     */
89
-    protected $_aliases = array();
90
-
91
-
92
-
93
-    /**
94
-     * EE_Dependency_Map constructor.
95
-     *
96
-     * @param EE_Request  $request
97
-     * @param EE_Response $response
98
-     */
99
-    protected function __construct(EE_Request $request, EE_Response $response)
100
-    {
101
-        $this->_request = $request;
102
-        $this->_response = $response;
103
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
104
-        do_action('EE_Dependency_Map____construct');
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * @throws InvalidDataTypeException
111
-     * @throws InvalidInterfaceException
112
-     * @throws InvalidArgumentException
113
-     */
114
-    public function initialize()
115
-    {
116
-        $this->_register_core_dependencies();
117
-        $this->_register_core_class_loaders();
118
-        $this->_register_core_aliases();
119
-    }
120
-
121
-
122
-
123
-    /**
124
-     * @singleton method used to instantiate class object
125
-     * @access    public
126
-     * @param EE_Request  $request
127
-     * @param EE_Response $response
128
-     * @return EE_Dependency_Map
129
-     */
130
-    public static function instance(EE_Request $request = null, EE_Response $response = null)
131
-    {
132
-        // check if class object is instantiated, and instantiated properly
133
-        if (! self::$_instance instanceof EE_Dependency_Map) {
134
-            self::$_instance = new EE_Dependency_Map($request, $response);
135
-        }
136
-        return self::$_instance;
137
-    }
138
-
139
-
140
-
141
-    /**
142
-     * @param LoaderInterface $loader
143
-     */
144
-    public function setLoader(LoaderInterface $loader)
145
-    {
146
-        $this->loader = $loader;
147
-    }
148
-
149
-
150
-
151
-    /**
152
-     * @param string $class
153
-     * @param array  $dependencies
154
-     * @param int    $overwrite
155
-     * @return bool
156
-     */
157
-    public static function register_dependencies(
158
-        $class,
159
-        array $dependencies,
160
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
161
-    ) {
162
-        return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
163
-    }
164
-
165
-
166
-
167
-    /**
168
-     * Assigns an array of class names and corresponding load sources (new or cached)
169
-     * to the class specified by the first parameter.
170
-     * IMPORTANT !!!
171
-     * The order of elements in the incoming $dependencies array MUST match
172
-     * the order of the constructor parameters for the class in question.
173
-     * This is especially important when overriding any existing dependencies that are registered.
174
-     * the third parameter controls whether any duplicate dependencies are overwritten or not.
175
-     *
176
-     * @param string $class
177
-     * @param array  $dependencies
178
-     * @param int    $overwrite
179
-     * @return bool
180
-     */
181
-    public function registerDependencies(
182
-        $class,
183
-        array $dependencies,
184
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
185
-    ) {
186
-        $class = trim($class, '\\');
187
-        $registered = false;
188
-        if (empty(self::$_instance->_dependency_map[ $class ])) {
189
-            self::$_instance->_dependency_map[ $class ] = array();
190
-        }
191
-        // we need to make sure that any aliases used when registering a dependency
192
-        // get resolved to the correct class name
193
-        foreach ((array)$dependencies as $dependency => $load_source) {
194
-            $alias = self::$_instance->get_alias($dependency);
195
-            if (
196
-                $overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
197
-                || ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
198
-            ) {
199
-                unset($dependencies[$dependency]);
200
-                $dependencies[$alias] = $load_source;
201
-                $registered = true;
202
-            }
203
-        }
204
-        // now add our two lists of dependencies together.
205
-        // using Union (+=) favours the arrays in precedence from left to right,
206
-        // so $dependencies is NOT overwritten because it is listed first
207
-        // ie: with A = B + C, entries in B take precedence over duplicate entries in C
208
-        // Union is way faster than array_merge() but should be used with caution...
209
-        // especially with numerically indexed arrays
210
-        $dependencies += self::$_instance->_dependency_map[ $class ];
211
-        // now we need to ensure that the resulting dependencies
212
-        // array only has the entries that are required for the class
213
-        // so first count how many dependencies were originally registered for the class
214
-        $dependency_count = count(self::$_instance->_dependency_map[ $class ]);
215
-        // if that count is non-zero (meaning dependencies were already registered)
216
-        self::$_instance->_dependency_map[ $class ] = $dependency_count
217
-            // then truncate the  final array to match that count
218
-            ? array_slice($dependencies, 0, $dependency_count)
219
-            // otherwise just take the incoming array because nothing previously existed
220
-            : $dependencies;
221
-        return $registered;
222
-    }
223
-
224
-
225
-
226
-    /**
227
-     * @param string $class_name
228
-     * @param string $loader
229
-     * @return bool
230
-     * @throws DomainException
231
-     */
232
-    public static function register_class_loader($class_name, $loader = 'load_core')
233
-    {
234
-        if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
235
-            throw new DomainException(
236
-                esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
237
-            );
238
-        }
239
-        // check that loader is callable or method starts with "load_" and exists in EE_Registry
240
-        if (
241
-            ! is_callable($loader)
242
-            && (
243
-                strpos($loader, 'load_') !== 0
244
-                || ! method_exists('EE_Registry', $loader)
245
-            )
246
-        ) {
247
-            throw new DomainException(
248
-                sprintf(
249
-                    esc_html__(
250
-                        '"%1$s" is not a valid loader method on EE_Registry.',
251
-                        'event_espresso'
252
-                    ),
253
-                    $loader
254
-                )
255
-            );
256
-        }
257
-        $class_name = self::$_instance->get_alias($class_name);
258
-        if (! isset(self::$_instance->_class_loaders[$class_name])) {
259
-            self::$_instance->_class_loaders[$class_name] = $loader;
260
-            return true;
261
-        }
262
-        return false;
263
-    }
264
-
265
-
266
-
267
-    /**
268
-     * @return array
269
-     */
270
-    public function dependency_map()
271
-    {
272
-        return $this->_dependency_map;
273
-    }
274
-
275
-
276
-
277
-    /**
278
-     * returns TRUE if dependency map contains a listing for the provided class name
279
-     *
280
-     * @param string $class_name
281
-     * @return boolean
282
-     */
283
-    public function has($class_name = '')
284
-    {
285
-        // all legacy models have the same dependencies
286
-        if (strpos($class_name, 'EEM_') === 0) {
287
-            $class_name = 'LEGACY_MODELS';
288
-        }
289
-        return isset($this->_dependency_map[$class_name]) ? true : false;
290
-    }
291
-
292
-
293
-
294
-    /**
295
-     * returns TRUE if dependency map contains a listing for the provided class name AND dependency
296
-     *
297
-     * @param string $class_name
298
-     * @param string $dependency
299
-     * @return bool
300
-     */
301
-    public function has_dependency_for_class($class_name = '', $dependency = '')
302
-    {
303
-        // all legacy models have the same dependencies
304
-        if (strpos($class_name, 'EEM_') === 0) {
305
-            $class_name = 'LEGACY_MODELS';
306
-        }
307
-        $dependency = $this->get_alias($dependency);
308
-        return isset($this->_dependency_map[$class_name], $this->_dependency_map[$class_name][$dependency])
309
-            ? true
310
-            : false;
311
-    }
312
-
313
-
314
-
315
-    /**
316
-     * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
317
-     *
318
-     * @param string $class_name
319
-     * @param string $dependency
320
-     * @return int
321
-     */
322
-    public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
323
-    {
324
-        // all legacy models have the same dependencies
325
-        if (strpos($class_name, 'EEM_') === 0) {
326
-            $class_name = 'LEGACY_MODELS';
327
-        }
328
-        $dependency = $this->get_alias($dependency);
329
-        return $this->has_dependency_for_class($class_name, $dependency)
330
-            ? $this->_dependency_map[$class_name][$dependency]
331
-            : EE_Dependency_Map::not_registered;
332
-    }
333
-
334
-
335
-
336
-    /**
337
-     * @param string $class_name
338
-     * @return string | Closure
339
-     */
340
-    public function class_loader($class_name)
341
-    {
342
-        // all legacy models use load_model()
343
-        if(strpos($class_name, 'EEM_') === 0){
344
-            return 'load_model';
345
-        }
346
-        $class_name = $this->get_alias($class_name);
347
-        return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
348
-    }
349
-
350
-
351
-
352
-    /**
353
-     * @return array
354
-     */
355
-    public function class_loaders()
356
-    {
357
-        return $this->_class_loaders;
358
-    }
359
-
360
-
361
-
362
-    /**
363
-     * adds an alias for a classname
364
-     *
365
-     * @param string $class_name the class name that should be used (concrete class to replace interface)
366
-     * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
367
-     * @param string $for_class  the class that has the dependency (is type hinting for the interface)
368
-     */
369
-    public function add_alias($class_name, $alias, $for_class = '')
370
-    {
371
-        if ($for_class !== '') {
372
-            if (! isset($this->_aliases[$for_class])) {
373
-                $this->_aliases[$for_class] = array();
374
-            }
375
-            $this->_aliases[$for_class][$class_name] = $alias;
376
-        }
377
-        $this->_aliases[$class_name] = $alias;
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     * returns TRUE if the provided class name has an alias
384
-     *
385
-     * @param string $class_name
386
-     * @param string $for_class
387
-     * @return bool
388
-     */
389
-    public function has_alias($class_name = '', $for_class = '')
390
-    {
391
-        return isset($this->_aliases[$for_class], $this->_aliases[$for_class][$class_name])
392
-               || (
393
-                   isset($this->_aliases[$class_name])
394
-                   && ! is_array($this->_aliases[$class_name])
395
-               );
396
-    }
397
-
398
-
399
-
400
-    /**
401
-     * returns alias for class name if one exists, otherwise returns the original classname
402
-     * functions recursively, so that multiple aliases can be used to drill down to a classname
403
-     *  for example:
404
-     *      if the following two entries were added to the _aliases array:
405
-     *          array(
406
-     *              'interface_alias'           => 'some\namespace\interface'
407
-     *              'some\namespace\interface'  => 'some\namespace\classname'
408
-     *          )
409
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
410
-     *      to load an instance of 'some\namespace\classname'
411
-     *
412
-     * @param string $class_name
413
-     * @param string $for_class
414
-     * @return string
415
-     */
416
-    public function get_alias($class_name = '', $for_class = '')
417
-    {
418
-        if (! $this->has_alias($class_name, $for_class)) {
419
-            return $class_name;
420
-        }
421
-        if ($for_class !== '' && isset($this->_aliases[ $for_class ][ $class_name ])) {
422
-            return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
423
-        }
424
-        return $this->get_alias($this->_aliases[$class_name]);
425
-    }
426
-
427
-
428
-
429
-    /**
430
-     * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
431
-     * if one exists, or whether a new object should be generated every time the requested class is loaded.
432
-     * This is done by using the following class constants:
433
-     *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
434
-     *        EE_Dependency_Map::load_new_object - generates a new object every time
435
-     */
436
-    protected function _register_core_dependencies()
437
-    {
438
-        $this->_dependency_map = array(
439
-            'EE_Request_Handler'                                                                                          => array(
440
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
441
-            ),
442
-            'EE_System'                                                                                                   => array(
443
-                'EE_Registry'                                => EE_Dependency_Map::load_from_cache,
444
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
445
-                'EE_Capabilities'                            => EE_Dependency_Map::load_from_cache,
446
-                'EE_Request'                                 => EE_Dependency_Map::load_from_cache,
447
-                'EE_Maintenance_Mode'                        => EE_Dependency_Map::load_from_cache,
448
-            ),
449
-            'EE_Session'                                                                                                  => array(
450
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
451
-                'EE_Encryption'                                           => EE_Dependency_Map::load_from_cache,
452
-            ),
453
-            'EE_Cart'                                                                                                     => array(
454
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
455
-            ),
456
-            'EE_Front_Controller'                                                                                         => array(
457
-                'EE_Registry'              => EE_Dependency_Map::load_from_cache,
458
-                'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
459
-                'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
460
-            ),
461
-            'EE_Messenger_Collection_Loader'                                                                              => array(
462
-                'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
463
-            ),
464
-            'EE_Message_Type_Collection_Loader'                                                                           => array(
465
-                'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
466
-            ),
467
-            'EE_Message_Resource_Manager'                                                                                 => array(
468
-                'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
469
-                'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
470
-                'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
471
-            ),
472
-            'EE_Message_Factory'                                                                                          => array(
473
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
474
-            ),
475
-            'EE_messages'                                                                                                 => array(
476
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
477
-            ),
478
-            'EE_Messages_Generator'                                                                                       => array(
479
-                'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
480
-                'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
481
-                'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
482
-                'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
483
-            ),
484
-            'EE_Messages_Processor'                                                                                       => array(
485
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
-            ),
487
-            'EE_Messages_Queue'                                                                                           => array(
488
-                'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
489
-            ),
490
-            'EE_Messages_Template_Defaults'                                                                               => array(
491
-                'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
492
-                'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
493
-            ),
494
-            'EE_Message_To_Generate_From_Request'                                                                         => array(
495
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
496
-                'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
497
-            ),
498
-            'EventEspresso\core\services\commands\CommandBus'                                                             => array(
499
-                'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
500
-            ),
501
-            'EventEspresso\services\commands\CommandHandler'                                                              => array(
502
-                'EE_Registry'         => EE_Dependency_Map::load_from_cache,
503
-                'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
504
-            ),
505
-            'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
506
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
507
-            ),
508
-            'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
509
-                'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
510
-                'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
511
-            ),
512
-            'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
513
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
514
-            ),
515
-            'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
516
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
517
-            ),
518
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
519
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
520
-            ),
521
-            'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
522
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
523
-            ),
524
-            'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
525
-                'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
526
-            ),
527
-            'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
528
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
529
-            ),
530
-            'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
531
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
532
-            ),
533
-            'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
534
-                'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
535
-            ),
536
-            'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
537
-                'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
538
-            ),
539
-            'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
540
-                'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
541
-            ),
542
-            'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
543
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
-            ),
545
-            'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
546
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
547
-            ),
548
-            'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
549
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
550
-            ),
551
-            'EventEspresso\core\services\database\TableManager'                                                           => array(
552
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
553
-            ),
554
-            'EE_Data_Migration_Class_Base'                                                                                => array(
555
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
556
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
557
-            ),
558
-            'EE_DMS_Core_4_1_0'                                                                                           => array(
559
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
560
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
561
-            ),
562
-            'EE_DMS_Core_4_2_0'                                                                                           => array(
563
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
564
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
565
-            ),
566
-            'EE_DMS_Core_4_3_0'                                                                                           => array(
567
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
568
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
569
-            ),
570
-            'EE_DMS_Core_4_4_0'                                                                                           => array(
571
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
572
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
573
-            ),
574
-            'EE_DMS_Core_4_5_0'                                                                                           => array(
575
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
576
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
577
-            ),
578
-            'EE_DMS_Core_4_6_0'                                                                                           => array(
579
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
580
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
581
-            ),
582
-            'EE_DMS_Core_4_7_0'                                                                                           => array(
583
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
584
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
585
-            ),
586
-            'EE_DMS_Core_4_8_0'                                                                                           => array(
587
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
588
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
589
-            ),
590
-            'EE_DMS_Core_4_9_0'                                                                                           => array(
591
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
592
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
593
-            ),
594
-            'EventEspresso\core\services\assets\Registry'                                                                 => array(
595
-                'EE_Template_Config' => EE_Dependency_Map::load_from_cache,
596
-                'EE_Currency_Config' => EE_Dependency_Map::load_from_cache,
597
-            ),
598
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
599
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
600
-            ),
601
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
602
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
603
-            ),
604
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
605
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
606
-            ),
607
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
608
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
609
-            ),
610
-            'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
611
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
612
-            ),
613
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
614
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
615
-            ),
616
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
617
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
-            ),
619
-            'EventEspresso\core\services\cache\BasicCacheManager'                        => array(
620
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
621
-            ),
622
-            'EventEspresso\core\services\cache\PostRelatedCacheManager'                  => array(
623
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
624
-            ),
625
-            'EventEspresso\core\domain\services\validation\email\EmailValidationService' => array(
626
-                'EE_Registration_Config'                                  => EE_Dependency_Map::load_from_cache,
627
-                'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
628
-            ),
629
-            'EventEspresso\core\domain\values\EmailAddress'                              => array(
630
-                null,
631
-                'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
632
-            ),
633
-            'EventEspresso\core\services\orm\ModelFieldFactory' => array(
634
-                'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
635
-            ),
636
-            'LEGACY_MODELS'                                                   => array(
637
-                null,
638
-                'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
639
-            ),
640
-            'EE_Module_Request_Router' => array(
641
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
642
-            ),
643
-            'EE_Registration_Processor' => array(
644
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
645
-            ),
646
-            'EventEspresso\core\services\currency\CurrencyFactory' => array(
647
-                'EEM_Country'                                           => EE_Dependency_Map::load_from_cache,
648
-                'EE_Organization_Config'                                => EE_Dependency_Map::load_from_cache,
649
-                'EventEspresso\core\services\currency\CurrencySubunits' => EE_Dependency_Map::load_from_cache
650
-            ),
651
-            'EventEspresso\core\services\currency\MoneyFactory' => array(
652
-                'EventEspresso\core\services\currency\CurrencyFactory'  => EE_Dependency_Map::load_from_cache,
653
-                'EventEspresso\core\services\currency\Calculator'       => EE_Dependency_Map::load_from_cache,
654
-                array()
655
-            ),
656
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' => array(
657
-                null,
658
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
659
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
660
-            ),
661
-        );
662
-    }
663
-
664
-
665
-
666
-    /**
667
-     * Registers how core classes are loaded.
668
-     * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
669
-     *        'EE_Request_Handler' => 'load_core'
670
-     *        'EE_Messages_Queue'  => 'load_lib'
671
-     *        'EEH_Debug_Tools'    => 'load_helper'
672
-     * or, if greater control is required, by providing a custom closure. For example:
673
-     *        'Some_Class' => function () {
674
-     *            return new Some_Class();
675
-     *        },
676
-     * This is required for instantiating dependencies
677
-     * where an interface has been type hinted in a class constructor. For example:
678
-     *        'Required_Interface' => function () {
679
-     *            return new A_Class_That_Implements_Required_Interface();
680
-     *        },
681
-     *
682
-     * @throws InvalidInterfaceException
683
-     * @throws InvalidDataTypeException
684
-     * @throws InvalidArgumentException
685
-     */
686
-    protected function _register_core_class_loaders()
687
-    {
688
-        //for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
689
-        //be used in a closure.
690
-        $request = &$this->_request;
691
-        $response = &$this->_response;
692
-        // $loader = &$this->loader;
693
-        $this->_class_loaders = array(
694
-            //load_core
695
-            'EE_Capabilities'                      => 'load_core',
696
-            'EE_Encryption'                        => 'load_core',
697
-            'EE_Front_Controller'                  => 'load_core',
698
-            'EE_Module_Request_Router'             => 'load_core',
699
-            'EE_Registry'                          => 'load_core',
700
-            'EE_Request'                           => function () use (&$request) {
701
-                return $request;
702
-            },
703
-            'EE_Response'                          => function () use (&$response) {
704
-                return $response;
705
-            },
706
-            'EE_Request_Handler'                   => 'load_core',
707
-            'EE_Session'                           => 'load_core',
708
-            'EE_Cron_Tasks'                        => 'load_core',
709
-            'EE_System'                            => 'load_core',
710
-            'EE_Maintenance_Mode'                  => 'load_core',
711
-            'EE_Register_CPTs'                     => 'load_core',
712
-            'EE_Admin'                             => 'load_core',
713
-            //load_lib
714
-            'EE_Message_Resource_Manager'          => 'load_lib',
715
-            'EE_Message_Type_Collection'           => 'load_lib',
716
-            'EE_Message_Type_Collection_Loader'    => 'load_lib',
717
-            'EE_Messenger_Collection'              => 'load_lib',
718
-            'EE_Messenger_Collection_Loader'       => 'load_lib',
719
-            'EE_Messages_Processor'                => 'load_lib',
720
-            'EE_Message_Repository'                => 'load_lib',
721
-            'EE_Messages_Queue'                    => 'load_lib',
722
-            'EE_Messages_Data_Handler_Collection'  => 'load_lib',
723
-            'EE_Message_Template_Group_Collection' => 'load_lib',
724
-            'EE_Payment_Method_Manager'            => 'load_lib',
725
-            'EE_Messages_Generator'                => function () {
726
-                return EE_Registry::instance()->load_lib(
727
-                    'Messages_Generator',
728
-                    array(),
729
-                    false,
730
-                    false
731
-                );
732
-            },
733
-            'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
734
-                return EE_Registry::instance()->load_lib(
735
-                    'Messages_Template_Defaults',
736
-                    $arguments,
737
-                    false,
738
-                    false
739
-                );
740
-            },
741
-            //load_model
742
-            // 'EEM_Attendee'                         => 'load_model',
743
-            // 'EEM_Message_Template_Group'           => 'load_model',
744
-            // 'EEM_Message_Template'                 => 'load_model',
745
-            //load_helper
746
-            'EEH_Parse_Shortcodes'                 => function () {
747
-                if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
748
-                    return new EEH_Parse_Shortcodes();
749
-                }
750
-                return null;
751
-            },
752
-            'EE_Template_Config'                   => function () {
753
-                return EE_Config::instance()->template_settings;
754
-            },
755
-            'EE_Currency_Config'                   => function () {
756
-                return EE_Config::instance()->currency;
757
-            },
758
-            'EE_Registration_Config'                   => function () {
759
-                return EE_Config::instance()->registration;
760
-            },
761
-            'EE_Organization_Config'                   => function () {
762
-                return EE_Config::instance()->organization;
763
-            },
764
-            'EventEspresso\core\services\loaders\Loader' => function () {
765
-                return LoaderFactory::getLoader();
766
-            },
767
-        );
768
-    }
769
-
770
-
771
-
772
-    /**
773
-     * can be used for supplying alternate names for classes,
774
-     * or for connecting interface names to instantiable classes
775
-     */
776
-    protected function _register_core_aliases()
777
-    {
778
-        $this->_aliases = array(
779
-            'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
780
-            'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
781
-            'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
782
-            'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
783
-            'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
784
-            'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
785
-            'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
786
-            'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
787
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
788
-            'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
789
-            'CreateRegCodeCommandHandler'                                                  => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
790
-            'CreateRegUrlLinkCommandHandler'                                               => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
791
-            'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
792
-            'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
793
-            'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
794
-            'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
795
-            'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
796
-            'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
797
-            'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
798
-            'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
799
-            'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
800
-            'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
801
-            'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
802
-            'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
803
-            'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
804
-            'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
805
-            'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
806
-            'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
807
-            'CommandFactoryInterface'                                                     => 'EventEspresso\core\services\commands\CommandFactoryInterface',
808
-            'EventEspresso\core\services\commands\CommandFactoryInterface'                => 'EventEspresso\core\services\commands\CommandFactory',
809
-            'EventEspresso\core\domain\services\session\SessionIdentifierInterface'       => 'EE_Session',
810
-            'EmailValidatorInterface'                                                     => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
811
-            'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface' => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
812
-            'NoticeConverterInterface'                                                    => 'EventEspresso\core\services\notices\NoticeConverterInterface',
813
-            'EventEspresso\core\services\notices\NoticeConverterInterface'                => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
814
-            'NoticesContainerInterface'                                                   => 'EventEspresso\core\services\notices\NoticesContainerInterface',
815
-            'EventEspresso\core\services\notices\NoticesContainerInterface'               => 'EventEspresso\core\services\notices\NoticesContainer',
816
-            'EventEspresso\core\services\currency\Calculator'                             => 'EventEspresso\core\services\currency\DefaultCalculator',
817
-        );
818
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
819
-            $this->_aliases['EventEspresso\core\services\notices\NoticeConverterInterface'] = 'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices';
820
-        }
821
-    }
822
-
823
-
824
-
825
-    /**
826
-     * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
827
-     * request Primarily used by unit tests.
828
-     *
829
-     * @throws InvalidDataTypeException
830
-     * @throws InvalidInterfaceException
831
-     * @throws InvalidArgumentException
832
-     */
833
-    public function reset()
834
-    {
835
-        $this->_register_core_class_loaders();
836
-        $this->_register_core_dependencies();
837
-    }
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
+	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
32
+	 */
33
+	const load_new_object = 1;
34
+
35
+	/**
36
+	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
37
+	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
38
+	 */
39
+	const load_from_cache = 2;
40
+
41
+	/**
42
+	 * When registering a dependency,
43
+	 * this indicates to keep any existing dependencies that already exist,
44
+	 * and simply discard any new dependencies declared in the incoming data
45
+	 */
46
+	const KEEP_EXISTING_DEPENDENCIES = 0;
47
+
48
+	/**
49
+	 * When registering a dependency,
50
+	 * this indicates to overwrite any existing dependencies that already exist using the incoming data
51
+	 */
52
+	const OVERWRITE_DEPENDENCIES = 1;
53
+
54
+
55
+
56
+	/**
57
+	 * @type EE_Dependency_Map $_instance
58
+	 */
59
+	protected static $_instance;
60
+
61
+	/**
62
+	 * @type EE_Request $request
63
+	 */
64
+	protected $_request;
65
+
66
+	/**
67
+	 * @type EE_Response $response
68
+	 */
69
+	protected $_response;
70
+
71
+	/**
72
+	 * @type LoaderInterface $loader
73
+	 */
74
+	protected $loader;
75
+
76
+	/**
77
+	 * @type array $_dependency_map
78
+	 */
79
+	protected $_dependency_map = array();
80
+
81
+	/**
82
+	 * @type array $_class_loaders
83
+	 */
84
+	protected $_class_loaders = array();
85
+
86
+	/**
87
+	 * @type array $_aliases
88
+	 */
89
+	protected $_aliases = array();
90
+
91
+
92
+
93
+	/**
94
+	 * EE_Dependency_Map constructor.
95
+	 *
96
+	 * @param EE_Request  $request
97
+	 * @param EE_Response $response
98
+	 */
99
+	protected function __construct(EE_Request $request, EE_Response $response)
100
+	{
101
+		$this->_request = $request;
102
+		$this->_response = $response;
103
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
104
+		do_action('EE_Dependency_Map____construct');
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * @throws InvalidDataTypeException
111
+	 * @throws InvalidInterfaceException
112
+	 * @throws InvalidArgumentException
113
+	 */
114
+	public function initialize()
115
+	{
116
+		$this->_register_core_dependencies();
117
+		$this->_register_core_class_loaders();
118
+		$this->_register_core_aliases();
119
+	}
120
+
121
+
122
+
123
+	/**
124
+	 * @singleton method used to instantiate class object
125
+	 * @access    public
126
+	 * @param EE_Request  $request
127
+	 * @param EE_Response $response
128
+	 * @return EE_Dependency_Map
129
+	 */
130
+	public static function instance(EE_Request $request = null, EE_Response $response = null)
131
+	{
132
+		// check if class object is instantiated, and instantiated properly
133
+		if (! self::$_instance instanceof EE_Dependency_Map) {
134
+			self::$_instance = new EE_Dependency_Map($request, $response);
135
+		}
136
+		return self::$_instance;
137
+	}
138
+
139
+
140
+
141
+	/**
142
+	 * @param LoaderInterface $loader
143
+	 */
144
+	public function setLoader(LoaderInterface $loader)
145
+	{
146
+		$this->loader = $loader;
147
+	}
148
+
149
+
150
+
151
+	/**
152
+	 * @param string $class
153
+	 * @param array  $dependencies
154
+	 * @param int    $overwrite
155
+	 * @return bool
156
+	 */
157
+	public static function register_dependencies(
158
+		$class,
159
+		array $dependencies,
160
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
161
+	) {
162
+		return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
163
+	}
164
+
165
+
166
+
167
+	/**
168
+	 * Assigns an array of class names and corresponding load sources (new or cached)
169
+	 * to the class specified by the first parameter.
170
+	 * IMPORTANT !!!
171
+	 * The order of elements in the incoming $dependencies array MUST match
172
+	 * the order of the constructor parameters for the class in question.
173
+	 * This is especially important when overriding any existing dependencies that are registered.
174
+	 * the third parameter controls whether any duplicate dependencies are overwritten or not.
175
+	 *
176
+	 * @param string $class
177
+	 * @param array  $dependencies
178
+	 * @param int    $overwrite
179
+	 * @return bool
180
+	 */
181
+	public function registerDependencies(
182
+		$class,
183
+		array $dependencies,
184
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
185
+	) {
186
+		$class = trim($class, '\\');
187
+		$registered = false;
188
+		if (empty(self::$_instance->_dependency_map[ $class ])) {
189
+			self::$_instance->_dependency_map[ $class ] = array();
190
+		}
191
+		// we need to make sure that any aliases used when registering a dependency
192
+		// get resolved to the correct class name
193
+		foreach ((array)$dependencies as $dependency => $load_source) {
194
+			$alias = self::$_instance->get_alias($dependency);
195
+			if (
196
+				$overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
197
+				|| ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
198
+			) {
199
+				unset($dependencies[$dependency]);
200
+				$dependencies[$alias] = $load_source;
201
+				$registered = true;
202
+			}
203
+		}
204
+		// now add our two lists of dependencies together.
205
+		// using Union (+=) favours the arrays in precedence from left to right,
206
+		// so $dependencies is NOT overwritten because it is listed first
207
+		// ie: with A = B + C, entries in B take precedence over duplicate entries in C
208
+		// Union is way faster than array_merge() but should be used with caution...
209
+		// especially with numerically indexed arrays
210
+		$dependencies += self::$_instance->_dependency_map[ $class ];
211
+		// now we need to ensure that the resulting dependencies
212
+		// array only has the entries that are required for the class
213
+		// so first count how many dependencies were originally registered for the class
214
+		$dependency_count = count(self::$_instance->_dependency_map[ $class ]);
215
+		// if that count is non-zero (meaning dependencies were already registered)
216
+		self::$_instance->_dependency_map[ $class ] = $dependency_count
217
+			// then truncate the  final array to match that count
218
+			? array_slice($dependencies, 0, $dependency_count)
219
+			// otherwise just take the incoming array because nothing previously existed
220
+			: $dependencies;
221
+		return $registered;
222
+	}
223
+
224
+
225
+
226
+	/**
227
+	 * @param string $class_name
228
+	 * @param string $loader
229
+	 * @return bool
230
+	 * @throws DomainException
231
+	 */
232
+	public static function register_class_loader($class_name, $loader = 'load_core')
233
+	{
234
+		if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
235
+			throw new DomainException(
236
+				esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
237
+			);
238
+		}
239
+		// check that loader is callable or method starts with "load_" and exists in EE_Registry
240
+		if (
241
+			! is_callable($loader)
242
+			&& (
243
+				strpos($loader, 'load_') !== 0
244
+				|| ! method_exists('EE_Registry', $loader)
245
+			)
246
+		) {
247
+			throw new DomainException(
248
+				sprintf(
249
+					esc_html__(
250
+						'"%1$s" is not a valid loader method on EE_Registry.',
251
+						'event_espresso'
252
+					),
253
+					$loader
254
+				)
255
+			);
256
+		}
257
+		$class_name = self::$_instance->get_alias($class_name);
258
+		if (! isset(self::$_instance->_class_loaders[$class_name])) {
259
+			self::$_instance->_class_loaders[$class_name] = $loader;
260
+			return true;
261
+		}
262
+		return false;
263
+	}
264
+
265
+
266
+
267
+	/**
268
+	 * @return array
269
+	 */
270
+	public function dependency_map()
271
+	{
272
+		return $this->_dependency_map;
273
+	}
274
+
275
+
276
+
277
+	/**
278
+	 * returns TRUE if dependency map contains a listing for the provided class name
279
+	 *
280
+	 * @param string $class_name
281
+	 * @return boolean
282
+	 */
283
+	public function has($class_name = '')
284
+	{
285
+		// all legacy models have the same dependencies
286
+		if (strpos($class_name, 'EEM_') === 0) {
287
+			$class_name = 'LEGACY_MODELS';
288
+		}
289
+		return isset($this->_dependency_map[$class_name]) ? true : false;
290
+	}
291
+
292
+
293
+
294
+	/**
295
+	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
296
+	 *
297
+	 * @param string $class_name
298
+	 * @param string $dependency
299
+	 * @return bool
300
+	 */
301
+	public function has_dependency_for_class($class_name = '', $dependency = '')
302
+	{
303
+		// all legacy models have the same dependencies
304
+		if (strpos($class_name, 'EEM_') === 0) {
305
+			$class_name = 'LEGACY_MODELS';
306
+		}
307
+		$dependency = $this->get_alias($dependency);
308
+		return isset($this->_dependency_map[$class_name], $this->_dependency_map[$class_name][$dependency])
309
+			? true
310
+			: false;
311
+	}
312
+
313
+
314
+
315
+	/**
316
+	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
317
+	 *
318
+	 * @param string $class_name
319
+	 * @param string $dependency
320
+	 * @return int
321
+	 */
322
+	public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
323
+	{
324
+		// all legacy models have the same dependencies
325
+		if (strpos($class_name, 'EEM_') === 0) {
326
+			$class_name = 'LEGACY_MODELS';
327
+		}
328
+		$dependency = $this->get_alias($dependency);
329
+		return $this->has_dependency_for_class($class_name, $dependency)
330
+			? $this->_dependency_map[$class_name][$dependency]
331
+			: EE_Dependency_Map::not_registered;
332
+	}
333
+
334
+
335
+
336
+	/**
337
+	 * @param string $class_name
338
+	 * @return string | Closure
339
+	 */
340
+	public function class_loader($class_name)
341
+	{
342
+		// all legacy models use load_model()
343
+		if(strpos($class_name, 'EEM_') === 0){
344
+			return 'load_model';
345
+		}
346
+		$class_name = $this->get_alias($class_name);
347
+		return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
348
+	}
349
+
350
+
351
+
352
+	/**
353
+	 * @return array
354
+	 */
355
+	public function class_loaders()
356
+	{
357
+		return $this->_class_loaders;
358
+	}
359
+
360
+
361
+
362
+	/**
363
+	 * adds an alias for a classname
364
+	 *
365
+	 * @param string $class_name the class name that should be used (concrete class to replace interface)
366
+	 * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
367
+	 * @param string $for_class  the class that has the dependency (is type hinting for the interface)
368
+	 */
369
+	public function add_alias($class_name, $alias, $for_class = '')
370
+	{
371
+		if ($for_class !== '') {
372
+			if (! isset($this->_aliases[$for_class])) {
373
+				$this->_aliases[$for_class] = array();
374
+			}
375
+			$this->_aliases[$for_class][$class_name] = $alias;
376
+		}
377
+		$this->_aliases[$class_name] = $alias;
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 * returns TRUE if the provided class name has an alias
384
+	 *
385
+	 * @param string $class_name
386
+	 * @param string $for_class
387
+	 * @return bool
388
+	 */
389
+	public function has_alias($class_name = '', $for_class = '')
390
+	{
391
+		return isset($this->_aliases[$for_class], $this->_aliases[$for_class][$class_name])
392
+			   || (
393
+				   isset($this->_aliases[$class_name])
394
+				   && ! is_array($this->_aliases[$class_name])
395
+			   );
396
+	}
397
+
398
+
399
+
400
+	/**
401
+	 * returns alias for class name if one exists, otherwise returns the original classname
402
+	 * functions recursively, so that multiple aliases can be used to drill down to a classname
403
+	 *  for example:
404
+	 *      if the following two entries were added to the _aliases array:
405
+	 *          array(
406
+	 *              'interface_alias'           => 'some\namespace\interface'
407
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
408
+	 *          )
409
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
410
+	 *      to load an instance of 'some\namespace\classname'
411
+	 *
412
+	 * @param string $class_name
413
+	 * @param string $for_class
414
+	 * @return string
415
+	 */
416
+	public function get_alias($class_name = '', $for_class = '')
417
+	{
418
+		if (! $this->has_alias($class_name, $for_class)) {
419
+			return $class_name;
420
+		}
421
+		if ($for_class !== '' && isset($this->_aliases[ $for_class ][ $class_name ])) {
422
+			return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
423
+		}
424
+		return $this->get_alias($this->_aliases[$class_name]);
425
+	}
426
+
427
+
428
+
429
+	/**
430
+	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
431
+	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
432
+	 * This is done by using the following class constants:
433
+	 *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
434
+	 *        EE_Dependency_Map::load_new_object - generates a new object every time
435
+	 */
436
+	protected function _register_core_dependencies()
437
+	{
438
+		$this->_dependency_map = array(
439
+			'EE_Request_Handler'                                                                                          => array(
440
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
441
+			),
442
+			'EE_System'                                                                                                   => array(
443
+				'EE_Registry'                                => EE_Dependency_Map::load_from_cache,
444
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
445
+				'EE_Capabilities'                            => EE_Dependency_Map::load_from_cache,
446
+				'EE_Request'                                 => EE_Dependency_Map::load_from_cache,
447
+				'EE_Maintenance_Mode'                        => EE_Dependency_Map::load_from_cache,
448
+			),
449
+			'EE_Session'                                                                                                  => array(
450
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
451
+				'EE_Encryption'                                           => EE_Dependency_Map::load_from_cache,
452
+			),
453
+			'EE_Cart'                                                                                                     => array(
454
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
455
+			),
456
+			'EE_Front_Controller'                                                                                         => array(
457
+				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
458
+				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
459
+				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
460
+			),
461
+			'EE_Messenger_Collection_Loader'                                                                              => array(
462
+				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
463
+			),
464
+			'EE_Message_Type_Collection_Loader'                                                                           => array(
465
+				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
466
+			),
467
+			'EE_Message_Resource_Manager'                                                                                 => array(
468
+				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
469
+				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
470
+				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
471
+			),
472
+			'EE_Message_Factory'                                                                                          => array(
473
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
474
+			),
475
+			'EE_messages'                                                                                                 => array(
476
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
477
+			),
478
+			'EE_Messages_Generator'                                                                                       => array(
479
+				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
480
+				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
481
+				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
482
+				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
483
+			),
484
+			'EE_Messages_Processor'                                                                                       => array(
485
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
+			),
487
+			'EE_Messages_Queue'                                                                                           => array(
488
+				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
489
+			),
490
+			'EE_Messages_Template_Defaults'                                                                               => array(
491
+				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
492
+				'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
493
+			),
494
+			'EE_Message_To_Generate_From_Request'                                                                         => array(
495
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
496
+				'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
497
+			),
498
+			'EventEspresso\core\services\commands\CommandBus'                                                             => array(
499
+				'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
500
+			),
501
+			'EventEspresso\services\commands\CommandHandler'                                                              => array(
502
+				'EE_Registry'         => EE_Dependency_Map::load_from_cache,
503
+				'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
504
+			),
505
+			'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
506
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
507
+			),
508
+			'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
509
+				'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
510
+				'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
511
+			),
512
+			'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
513
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
514
+			),
515
+			'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
516
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
517
+			),
518
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
519
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
520
+			),
521
+			'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
522
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
523
+			),
524
+			'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
525
+				'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
526
+			),
527
+			'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
528
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
529
+			),
530
+			'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
531
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
532
+			),
533
+			'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
534
+				'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
535
+			),
536
+			'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
537
+				'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
538
+			),
539
+			'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
540
+				'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
541
+			),
542
+			'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
543
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
+			),
545
+			'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
546
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
547
+			),
548
+			'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
549
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
550
+			),
551
+			'EventEspresso\core\services\database\TableManager'                                                           => array(
552
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
553
+			),
554
+			'EE_Data_Migration_Class_Base'                                                                                => array(
555
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
556
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
557
+			),
558
+			'EE_DMS_Core_4_1_0'                                                                                           => array(
559
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
560
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
561
+			),
562
+			'EE_DMS_Core_4_2_0'                                                                                           => array(
563
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
564
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
565
+			),
566
+			'EE_DMS_Core_4_3_0'                                                                                           => array(
567
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
568
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
569
+			),
570
+			'EE_DMS_Core_4_4_0'                                                                                           => array(
571
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
572
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
573
+			),
574
+			'EE_DMS_Core_4_5_0'                                                                                           => array(
575
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
576
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
577
+			),
578
+			'EE_DMS_Core_4_6_0'                                                                                           => array(
579
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
580
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
581
+			),
582
+			'EE_DMS_Core_4_7_0'                                                                                           => array(
583
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
584
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
585
+			),
586
+			'EE_DMS_Core_4_8_0'                                                                                           => array(
587
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
588
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
589
+			),
590
+			'EE_DMS_Core_4_9_0'                                                                                           => array(
591
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
592
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
593
+			),
594
+			'EventEspresso\core\services\assets\Registry'                                                                 => array(
595
+				'EE_Template_Config' => EE_Dependency_Map::load_from_cache,
596
+				'EE_Currency_Config' => EE_Dependency_Map::load_from_cache,
597
+			),
598
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
599
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
600
+			),
601
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
602
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
603
+			),
604
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
605
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
606
+			),
607
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
608
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
609
+			),
610
+			'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
611
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
612
+			),
613
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
614
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
615
+			),
616
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
617
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
+			),
619
+			'EventEspresso\core\services\cache\BasicCacheManager'                        => array(
620
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
621
+			),
622
+			'EventEspresso\core\services\cache\PostRelatedCacheManager'                  => array(
623
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
624
+			),
625
+			'EventEspresso\core\domain\services\validation\email\EmailValidationService' => array(
626
+				'EE_Registration_Config'                                  => EE_Dependency_Map::load_from_cache,
627
+				'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
628
+			),
629
+			'EventEspresso\core\domain\values\EmailAddress'                              => array(
630
+				null,
631
+				'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
632
+			),
633
+			'EventEspresso\core\services\orm\ModelFieldFactory' => array(
634
+				'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
635
+			),
636
+			'LEGACY_MODELS'                                                   => array(
637
+				null,
638
+				'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
639
+			),
640
+			'EE_Module_Request_Router' => array(
641
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
642
+			),
643
+			'EE_Registration_Processor' => array(
644
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
645
+			),
646
+			'EventEspresso\core\services\currency\CurrencyFactory' => array(
647
+				'EEM_Country'                                           => EE_Dependency_Map::load_from_cache,
648
+				'EE_Organization_Config'                                => EE_Dependency_Map::load_from_cache,
649
+				'EventEspresso\core\services\currency\CurrencySubunits' => EE_Dependency_Map::load_from_cache
650
+			),
651
+			'EventEspresso\core\services\currency\MoneyFactory' => array(
652
+				'EventEspresso\core\services\currency\CurrencyFactory'  => EE_Dependency_Map::load_from_cache,
653
+				'EventEspresso\core\services\currency\Calculator'       => EE_Dependency_Map::load_from_cache,
654
+				array()
655
+			),
656
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' => array(
657
+				null,
658
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
659
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
660
+			),
661
+		);
662
+	}
663
+
664
+
665
+
666
+	/**
667
+	 * Registers how core classes are loaded.
668
+	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
669
+	 *        'EE_Request_Handler' => 'load_core'
670
+	 *        'EE_Messages_Queue'  => 'load_lib'
671
+	 *        'EEH_Debug_Tools'    => 'load_helper'
672
+	 * or, if greater control is required, by providing a custom closure. For example:
673
+	 *        'Some_Class' => function () {
674
+	 *            return new Some_Class();
675
+	 *        },
676
+	 * This is required for instantiating dependencies
677
+	 * where an interface has been type hinted in a class constructor. For example:
678
+	 *        'Required_Interface' => function () {
679
+	 *            return new A_Class_That_Implements_Required_Interface();
680
+	 *        },
681
+	 *
682
+	 * @throws InvalidInterfaceException
683
+	 * @throws InvalidDataTypeException
684
+	 * @throws InvalidArgumentException
685
+	 */
686
+	protected function _register_core_class_loaders()
687
+	{
688
+		//for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
689
+		//be used in a closure.
690
+		$request = &$this->_request;
691
+		$response = &$this->_response;
692
+		// $loader = &$this->loader;
693
+		$this->_class_loaders = array(
694
+			//load_core
695
+			'EE_Capabilities'                      => 'load_core',
696
+			'EE_Encryption'                        => 'load_core',
697
+			'EE_Front_Controller'                  => 'load_core',
698
+			'EE_Module_Request_Router'             => 'load_core',
699
+			'EE_Registry'                          => 'load_core',
700
+			'EE_Request'                           => function () use (&$request) {
701
+				return $request;
702
+			},
703
+			'EE_Response'                          => function () use (&$response) {
704
+				return $response;
705
+			},
706
+			'EE_Request_Handler'                   => 'load_core',
707
+			'EE_Session'                           => 'load_core',
708
+			'EE_Cron_Tasks'                        => 'load_core',
709
+			'EE_System'                            => 'load_core',
710
+			'EE_Maintenance_Mode'                  => 'load_core',
711
+			'EE_Register_CPTs'                     => 'load_core',
712
+			'EE_Admin'                             => 'load_core',
713
+			//load_lib
714
+			'EE_Message_Resource_Manager'          => 'load_lib',
715
+			'EE_Message_Type_Collection'           => 'load_lib',
716
+			'EE_Message_Type_Collection_Loader'    => 'load_lib',
717
+			'EE_Messenger_Collection'              => 'load_lib',
718
+			'EE_Messenger_Collection_Loader'       => 'load_lib',
719
+			'EE_Messages_Processor'                => 'load_lib',
720
+			'EE_Message_Repository'                => 'load_lib',
721
+			'EE_Messages_Queue'                    => 'load_lib',
722
+			'EE_Messages_Data_Handler_Collection'  => 'load_lib',
723
+			'EE_Message_Template_Group_Collection' => 'load_lib',
724
+			'EE_Payment_Method_Manager'            => 'load_lib',
725
+			'EE_Messages_Generator'                => function () {
726
+				return EE_Registry::instance()->load_lib(
727
+					'Messages_Generator',
728
+					array(),
729
+					false,
730
+					false
731
+				);
732
+			},
733
+			'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
734
+				return EE_Registry::instance()->load_lib(
735
+					'Messages_Template_Defaults',
736
+					$arguments,
737
+					false,
738
+					false
739
+				);
740
+			},
741
+			//load_model
742
+			// 'EEM_Attendee'                         => 'load_model',
743
+			// 'EEM_Message_Template_Group'           => 'load_model',
744
+			// 'EEM_Message_Template'                 => 'load_model',
745
+			//load_helper
746
+			'EEH_Parse_Shortcodes'                 => function () {
747
+				if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
748
+					return new EEH_Parse_Shortcodes();
749
+				}
750
+				return null;
751
+			},
752
+			'EE_Template_Config'                   => function () {
753
+				return EE_Config::instance()->template_settings;
754
+			},
755
+			'EE_Currency_Config'                   => function () {
756
+				return EE_Config::instance()->currency;
757
+			},
758
+			'EE_Registration_Config'                   => function () {
759
+				return EE_Config::instance()->registration;
760
+			},
761
+			'EE_Organization_Config'                   => function () {
762
+				return EE_Config::instance()->organization;
763
+			},
764
+			'EventEspresso\core\services\loaders\Loader' => function () {
765
+				return LoaderFactory::getLoader();
766
+			},
767
+		);
768
+	}
769
+
770
+
771
+
772
+	/**
773
+	 * can be used for supplying alternate names for classes,
774
+	 * or for connecting interface names to instantiable classes
775
+	 */
776
+	protected function _register_core_aliases()
777
+	{
778
+		$this->_aliases = array(
779
+			'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
780
+			'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
781
+			'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
782
+			'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
783
+			'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
784
+			'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
785
+			'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
786
+			'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
787
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
788
+			'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
789
+			'CreateRegCodeCommandHandler'                                                  => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
790
+			'CreateRegUrlLinkCommandHandler'                                               => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
791
+			'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
792
+			'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
793
+			'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
794
+			'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
795
+			'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
796
+			'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
797
+			'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
798
+			'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
799
+			'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
800
+			'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
801
+			'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
802
+			'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
803
+			'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
804
+			'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
805
+			'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
806
+			'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
807
+			'CommandFactoryInterface'                                                     => 'EventEspresso\core\services\commands\CommandFactoryInterface',
808
+			'EventEspresso\core\services\commands\CommandFactoryInterface'                => 'EventEspresso\core\services\commands\CommandFactory',
809
+			'EventEspresso\core\domain\services\session\SessionIdentifierInterface'       => 'EE_Session',
810
+			'EmailValidatorInterface'                                                     => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
811
+			'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface' => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
812
+			'NoticeConverterInterface'                                                    => 'EventEspresso\core\services\notices\NoticeConverterInterface',
813
+			'EventEspresso\core\services\notices\NoticeConverterInterface'                => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
814
+			'NoticesContainerInterface'                                                   => 'EventEspresso\core\services\notices\NoticesContainerInterface',
815
+			'EventEspresso\core\services\notices\NoticesContainerInterface'               => 'EventEspresso\core\services\notices\NoticesContainer',
816
+			'EventEspresso\core\services\currency\Calculator'                             => 'EventEspresso\core\services\currency\DefaultCalculator',
817
+		);
818
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
819
+			$this->_aliases['EventEspresso\core\services\notices\NoticeConverterInterface'] = 'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices';
820
+		}
821
+	}
822
+
823
+
824
+
825
+	/**
826
+	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
827
+	 * request Primarily used by unit tests.
828
+	 *
829
+	 * @throws InvalidDataTypeException
830
+	 * @throws InvalidInterfaceException
831
+	 * @throws InvalidArgumentException
832
+	 */
833
+	public function reset()
834
+	{
835
+		$this->_register_core_class_loaders();
836
+		$this->_register_core_dependencies();
837
+	}
838 838
 
839 839
 
840 840
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Base_Class.class.php 3 patches
Doc Comments   +11 added lines, -10 removed lines patch added patch discarded remove patch
@@ -633,7 +633,7 @@  discard block
 block discarded – undo
633 633
      *
634 634
      * @param \EE_Datetime_Field $datetime_field
635 635
      * @param bool               $pretty
636
-     * @param null $date_or_time
636
+     * @param string|null $date_or_time
637 637
      * @return void
638 638
      * @throws \EE_Error
639 639
      */
@@ -972,7 +972,7 @@  discard block
 block discarded – undo
972 972
      *
973 973
      * @param null  $field_to_order_by  What field is being used as the reference point.
974 974
      * @param array $query_params       Any additional conditions on the query.
975
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
975
+     * @param string  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
976 976
      *                                  you can indicate just the columns you want returned
977 977
      * @return array|EE_Base_Class
978 978
      * @throws \EE_Error
@@ -998,7 +998,7 @@  discard block
 block discarded – undo
998 998
      *
999 999
      * @param null  $field_to_order_by  What field is being used as the reference point.
1000 1000
      * @param array $query_params       Any additional conditions on the query.
1001
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1001
+     * @param string  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1002 1002
      *                                  you can indicate just the column you want returned
1003 1003
      * @return array|EE_Base_Class
1004 1004
      * @throws \EE_Error
@@ -1072,7 +1072,7 @@  discard block
 block discarded – undo
1072 1072
      * This method simply returns the RAW unprocessed value for the given property in this class
1073 1073
      *
1074 1074
      * @param  string $field_name A valid fieldname
1075
-     * @return mixed              Whatever the raw value stored on the property is.
1075
+     * @return integer|null              Whatever the raw value stored on the property is.
1076 1076
      * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1077 1077
      */
1078 1078
     public function get_raw($field_name)
@@ -1126,7 +1126,7 @@  discard block
 block discarded – undo
1126 1126
      * or else it will throw an exception.
1127 1127
      *
1128 1128
      * @param $field_name
1129
-     * @return mixed
1129
+     * @return Money
1130 1130
      * @throws InvalidEntityException
1131 1131
      * @throws EE_Error
1132 1132
      */
@@ -1386,7 +1386,7 @@  discard block
 block discarded – undo
1386 1386
      * sets the time on a datetime property
1387 1387
      *
1388 1388
      * @access protected
1389
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1389
+     * @param string $time      a valid time string for php datetime functions (or DateTime object)
1390 1390
      * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1391 1391
      * @throws \EE_Error
1392 1392
      */
@@ -1401,7 +1401,7 @@  discard block
 block discarded – undo
1401 1401
      * sets the date on a datetime property
1402 1402
      *
1403 1403
      * @access protected
1404
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1404
+     * @param string $date      a valid date string for php datetime functions ( or DateTime object)
1405 1405
      * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1406 1406
      * @throws \EE_Error
1407 1407
      */
@@ -1464,6 +1464,7 @@  discard block
 block discarded – undo
1464 1464
      * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1465 1465
      * @param string               $prepend    You can include something to prepend on the timestamp
1466 1466
      * @param string               $append     You can include something to append on the timestamp
1467
+     * @param string $args
1467 1468
      * @throws EE_Error
1468 1469
      * @return string timestamp
1469 1470
      */
@@ -1865,7 +1866,7 @@  discard block
 block discarded – undo
1865 1866
      *
1866 1867
      * @param  array  $props_n_values   incoming array of properties and their values
1867 1868
      * @param  string $classname        the classname of the child class
1868
-     * @param null    $timezone
1869
+     * @param string|null    $timezone
1869 1870
      * @param array   $date_formats     incoming date_formats in an array where the first value is the
1870 1871
      *                                  date_format and the second value is the time format
1871 1872
      * @return mixed (EE_Base_Class|bool)
@@ -1944,7 +1945,7 @@  discard block
 block discarded – undo
1944 1945
      * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1945 1946
      *
1946 1947
      * @param string $model_classname
1947
-     * @param null   $timezone
1948
+     * @param string|null   $timezone
1948 1949
      * @return EEM_Base
1949 1950
      */
1950 1951
     protected static function _get_model_instance_with_name($model_classname, $timezone = null)
@@ -2446,7 +2447,7 @@  discard block
 block discarded – undo
2446 2447
      *
2447 2448
      * @param string $meta_key
2448 2449
      * @param mixed  $meta_value
2449
-     * @param mixed  $previous_value
2450
+     * @param boolean  $previous_value
2450 2451
      * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2451 2452
      * @throws \EE_Error
2452 2453
      * NOTE: if the values haven't changed, returns 0
Please login to merge, or discard this patch.
Indentation   +2750 added lines, -2750 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 use EventEspresso\core\exceptions\InvalidEntityException;
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
 do_action('AHEE_log', __FILE__, ' FILE LOADED', '');
10 10
 
@@ -30,2755 +30,2755 @@  discard block
 block discarded – undo
30 30
 abstract class EE_Base_Class
31 31
 {
32 32
 
33
-    /**
34
-     * This is an array of the original properties and values provided during construction
35
-     * of this model object. (keys are model field names, values are their values).
36
-     * This list is important to remember so that when we are merging data from the db, we know
37
-     * which values to override and which to not override.
38
-     *
39
-     * @var array
40
-     */
41
-    protected $_props_n_values_provided_in_constructor;
42
-
43
-    /**
44
-     * Timezone
45
-     * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
46
-     * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
47
-     * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
48
-     * access to it.
49
-     *
50
-     * @var string
51
-     */
52
-    protected $_timezone;
53
-
54
-
55
-
56
-    /**
57
-     * date format
58
-     * pattern or format for displaying dates
59
-     *
60
-     * @var string $_dt_frmt
61
-     */
62
-    protected $_dt_frmt;
63
-
64
-
65
-
66
-    /**
67
-     * time format
68
-     * pattern or format for displaying time
69
-     *
70
-     * @var string $_tm_frmt
71
-     */
72
-    protected $_tm_frmt;
73
-
74
-
75
-
76
-    /**
77
-     * This property is for holding a cached array of object properties indexed by property name as the key.
78
-     * The purpose of this is for setting a cache on properties that may have calculated values after a
79
-     * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
80
-     * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
81
-     *
82
-     * @var array
83
-     */
84
-    protected $_cached_properties = array();
85
-
86
-    /**
87
-     * An array containing keys of the related model, and values are either an array of related mode objects or a
88
-     * single
89
-     * related model object. see the model's _model_relations. The keys should match those specified. And if the
90
-     * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
91
-     * all others have an array)
92
-     *
93
-     * @var array
94
-     */
95
-    protected $_model_relations = array();
96
-
97
-    /**
98
-     * Array where keys are field names (see the model's _fields property) and values are their values. To see what
99
-     * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
100
-     *
101
-     * @var array
102
-     */
103
-    protected $_fields = array();
104
-
105
-    /**
106
-     * @var boolean indicating whether or not this model object is intended to ever be saved
107
-     * For example, we might create model objects intended to only be used for the duration
108
-     * of this request and to be thrown away, and if they were accidentally saved
109
-     * it would be a bug.
110
-     */
111
-    protected $_allow_persist = true;
112
-
113
-    /**
114
-     * @var boolean indicating whether or not this model object's properties have changed since construction
115
-     */
116
-    protected $_has_changes = false;
117
-
118
-    /**
119
-     * @var EEM_Base
120
-     */
121
-    protected $_model;
122
-
123
-
124
-
125
-    /**
126
-     * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
127
-     * play nice
128
-     *
129
-     * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
130
-     *                                                         layer of the model's _fields array, (eg, EVT_ID,
131
-     *                                                         TXN_amount, QST_name, etc) and values are their values
132
-     * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
133
-     *                                                         corresponding db model or not.
134
-     * @param string  $timezone                                indicate what timezone you want any datetime fields to
135
-     *                                                         be in when instantiating a EE_Base_Class object.
136
-     * @param array   $date_formats                            An array of date formats to set on construct where first
137
-     *                                                         value is the date_format and second value is the time
138
-     *                                                         format.
139
-     * @throws EE_Error
140
-     */
141
-    protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
142
-    {
143
-        $className = get_class($this);
144
-        do_action("AHEE__{$className}__construct", $this, $fieldValues);
145
-        $model = $this->get_model();
146
-        $model_fields = $model->field_settings(false);
147
-        // ensure $fieldValues is an array
148
-        $fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
149
-        // EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
150
-        // verify client code has not passed any invalid field names
151
-        foreach ($fieldValues as $field_name => $field_value) {
152
-            if ( ! isset($model_fields[$field_name])) {
153
-                throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
154
-                    "event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
155
-            }
156
-        }
157
-        // EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
158
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
159
-        if ( ! empty($date_formats) && is_array($date_formats)) {
160
-            list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
161
-        } else {
162
-            //set default formats for date and time
163
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
164
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
165
-        }
166
-        //if db model is instantiating
167
-        if ($bydb) {
168
-            //client code has indicated these field values are from the database
169
-            foreach ($model_fields as $fieldName => $field) {
170
-                $this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
171
-            }
172
-        } else {
173
-            //we're constructing a brand
174
-            //new instance of the model object. Generally, this means we'll need to do more field validation
175
-            foreach ($model_fields as $fieldName => $field) {
176
-                $this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
177
-            }
178
-        }
179
-        //remember what values were passed to this constructor
180
-        $this->_props_n_values_provided_in_constructor = $fieldValues;
181
-        //remember in entity mapper
182
-        if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
183
-            $model->add_to_entity_map($this);
184
-        }
185
-        //setup all the relations
186
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
187
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
188
-                $this->_model_relations[$relation_name] = null;
189
-            } else {
190
-                $this->_model_relations[$relation_name] = array();
191
-            }
192
-        }
193
-        /**
194
-         * Action done at the end of each model object construction
195
-         *
196
-         * @param EE_Base_Class $this the model object just created
197
-         */
198
-        do_action('AHEE__EE_Base_Class__construct__finished', $this);
199
-    }
200
-
201
-
202
-
203
-    /**
204
-     * Gets whether or not this model object is allowed to persist/be saved to the database.
205
-     *
206
-     * @return boolean
207
-     */
208
-    public function allow_persist()
209
-    {
210
-        return $this->_allow_persist;
211
-    }
212
-
213
-
214
-
215
-    /**
216
-     * Sets whether or not this model object should be allowed to be saved to the DB.
217
-     * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
218
-     * you got new information that somehow made you change your mind.
219
-     *
220
-     * @param boolean $allow_persist
221
-     * @return boolean
222
-     */
223
-    public function set_allow_persist($allow_persist)
224
-    {
225
-        return $this->_allow_persist = $allow_persist;
226
-    }
227
-
228
-
229
-
230
-    /**
231
-     * Gets the field's original value when this object was constructed during this request.
232
-     * This can be helpful when determining if a model object has changed or not
233
-     *
234
-     * @param string $field_name
235
-     * @return mixed|null
236
-     * @throws \EE_Error
237
-     */
238
-    public function get_original($field_name)
239
-    {
240
-        if (isset($this->_props_n_values_provided_in_constructor[$field_name])
241
-            && $field_settings = $this->get_model()->field_settings_for($field_name)
242
-        ) {
243
-            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
244
-        } else {
245
-            return null;
246
-        }
247
-    }
248
-
249
-
250
-
251
-    /**
252
-     * @param EE_Base_Class $obj
253
-     * @return string
254
-     */
255
-    public function get_class($obj)
256
-    {
257
-        return get_class($obj);
258
-    }
259
-
260
-
261
-
262
-    /**
263
-     * Overrides parent because parent expects old models.
264
-     * This also doesn't do any validation, and won't work for serialized arrays
265
-     *
266
-     * @param    string $field_name
267
-     * @param    mixed  $field_value
268
-     * @param bool      $use_default
269
-     * @throws \EE_Error
270
-     */
271
-    public function set($field_name, $field_value, $use_default = false)
272
-    {
273
-        // if not using default and nothing has changed, and object has already been setup (has ID),
274
-        // then don't do anything
275
-        if (
276
-            ! $use_default
277
-            && $this->_fields[$field_name] === $field_value
278
-            && $this->ID()
279
-        ) {
280
-            return;
281
-        }
282
-        $model = $this->get_model();
283
-        $this->_has_changes = true;
284
-        $field_obj = $model->field_settings_for($field_name);
285
-        if ($field_obj instanceof EE_Model_Field_Base) {
286
-            //			if ( method_exists( $field_obj, 'set_timezone' )) {
287
-            if ($field_obj instanceof EE_Datetime_Field) {
288
-                $field_obj->set_timezone($this->_timezone);
289
-                $field_obj->set_date_format($this->_dt_frmt);
290
-                $field_obj->set_time_format($this->_tm_frmt);
291
-            }
292
-            $holder_of_value = $field_obj->prepare_for_set($field_value);
293
-            //should the value be null?
294
-            if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
295
-                $this->_fields[$field_name] = $field_obj->get_default_value();
296
-                /**
297
-                 * To save having to refactor all the models, if a default value is used for a
298
-                 * EE_Datetime_Field, and that value is not null nor is it a DateTime
299
-                 * object.  Then let's do a set again to ensure that it becomes a DateTime
300
-                 * object.
301
-                 *
302
-                 * @since 4.6.10+
303
-                 */
304
-                if (
305
-                    $field_obj instanceof EE_Datetime_Field
306
-                    && $this->_fields[$field_name] !== null
307
-                    && ! $this->_fields[$field_name] instanceof DateTime
308
-                ) {
309
-                    empty($this->_fields[$field_name])
310
-                        ? $this->set($field_name, time())
311
-                        : $this->set($field_name, $this->_fields[$field_name]);
312
-                }
313
-            } else {
314
-                $this->_fields[$field_name] = $holder_of_value;
315
-            }
316
-            //if we're not in the constructor...
317
-            //now check if what we set was a primary key
318
-            if (
319
-                //note: props_n_values_provided_in_constructor is only set at the END of the constructor
320
-                $this->_props_n_values_provided_in_constructor
321
-                && $field_value
322
-                && $field_name === $model->primary_key_name()
323
-            ) {
324
-                //if so, we want all this object's fields to be filled either with
325
-                //what we've explicitly set on this model
326
-                //or what we have in the db
327
-                // echo "setting primary key!";
328
-                $fields_on_model = self::_get_model(get_class($this))->field_settings();
329
-                $obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
330
-                foreach ($fields_on_model as $field_obj) {
331
-                    if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
332
-                         && $field_obj->get_name() !== $field_name
333
-                    ) {
334
-                        $this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
335
-                    }
336
-                }
337
-                //oh this model object has an ID? well make sure its in the entity mapper
338
-                $model->add_to_entity_map($this);
339
-            }
340
-            //let's unset any cache for this field_name from the $_cached_properties property.
341
-            $this->_clear_cached_property($field_name);
342
-        } else {
343
-            throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
344
-                "event_espresso"), $field_name));
345
-        }
346
-    }
347
-
348
-
349
-
350
-    /**
351
-     * This sets the field value on the db column if it exists for the given $column_name or
352
-     * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
353
-     *
354
-     * @see EE_message::get_column_value for related documentation on the necessity of this method.
355
-     * @param string $field_name  Must be the exact column name.
356
-     * @param mixed  $field_value The value to set.
357
-     * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
358
-     * @throws \EE_Error
359
-     */
360
-    public function set_field_or_extra_meta($field_name, $field_value)
361
-    {
362
-        if ($this->get_model()->has_field($field_name)) {
363
-            $this->set($field_name, $field_value);
364
-            return true;
365
-        } else {
366
-            //ensure this object is saved first so that extra meta can be properly related.
367
-            $this->save();
368
-            return $this->update_extra_meta($field_name, $field_value);
369
-        }
370
-    }
371
-
372
-
373
-
374
-    /**
375
-     * This retrieves the value of the db column set on this class or if that's not present
376
-     * it will attempt to retrieve from extra_meta if found.
377
-     * Example Usage:
378
-     * Via EE_Message child class:
379
-     * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
380
-     * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
381
-     * also have additional main fields specific to the messenger.  The system accommodates those extra
382
-     * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
383
-     * value for those extra fields dynamically via the EE_message object.
384
-     *
385
-     * @param  string $field_name expecting the fully qualified field name.
386
-     * @return mixed|null  value for the field if found.  null if not found.
387
-     * @throws \EE_Error
388
-     */
389
-    public function get_field_or_extra_meta($field_name)
390
-    {
391
-        if ($this->get_model()->has_field($field_name)) {
392
-            $column_value = $this->get($field_name);
393
-        } else {
394
-            //This isn't a column in the main table, let's see if it is in the extra meta.
395
-            $column_value = $this->get_extra_meta($field_name, true, null);
396
-        }
397
-        return $column_value;
398
-    }
399
-
400
-
401
-
402
-    /**
403
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
404
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
405
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
406
-     * available to all child classes that may be using the EE_Datetime_Field for a field data type.
407
-     *
408
-     * @access public
409
-     * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
410
-     * @return void
411
-     * @throws \EE_Error
412
-     */
413
-    public function set_timezone($timezone = '')
414
-    {
415
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
416
-        //make sure we clear all cached properties because they won't be relevant now
417
-        $this->_clear_cached_properties();
418
-        //make sure we update field settings and the date for all EE_Datetime_Fields
419
-        $model_fields = $this->get_model()->field_settings(false);
420
-        foreach ($model_fields as $field_name => $field_obj) {
421
-            if ($field_obj instanceof EE_Datetime_Field) {
422
-                $field_obj->set_timezone($this->_timezone);
423
-                if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
424
-                    $this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
425
-                }
426
-            }
427
-        }
428
-    }
429
-
430
-
431
-
432
-    /**
433
-     * This just returns whatever is set for the current timezone.
434
-     *
435
-     * @access public
436
-     * @return string timezone string
437
-     */
438
-    public function get_timezone()
439
-    {
440
-        return $this->_timezone;
441
-    }
442
-
443
-
444
-
445
-    /**
446
-     * This sets the internal date format to what is sent in to be used as the new default for the class
447
-     * internally instead of wp set date format options
448
-     *
449
-     * @since 4.6
450
-     * @param string $format should be a format recognizable by PHP date() functions.
451
-     */
452
-    public function set_date_format($format)
453
-    {
454
-        $this->_dt_frmt = $format;
455
-        //clear cached_properties because they won't be relevant now.
456
-        $this->_clear_cached_properties();
457
-    }
458
-
459
-
460
-
461
-    /**
462
-     * This sets the internal time format string to what is sent in to be used as the new default for the
463
-     * class internally instead of wp set time format options.
464
-     *
465
-     * @since 4.6
466
-     * @param string $format should be a format recognizable by PHP date() functions.
467
-     */
468
-    public function set_time_format($format)
469
-    {
470
-        $this->_tm_frmt = $format;
471
-        //clear cached_properties because they won't be relevant now.
472
-        $this->_clear_cached_properties();
473
-    }
474
-
475
-
476
-
477
-    /**
478
-     * This returns the current internal set format for the date and time formats.
479
-     *
480
-     * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
481
-     *                             where the first value is the date format and the second value is the time format.
482
-     * @return mixed string|array
483
-     */
484
-    public function get_format($full = true)
485
-    {
486
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
487
-    }
488
-
489
-
490
-
491
-    /**
492
-     * cache
493
-     * stores the passed model object on the current model object.
494
-     * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
495
-     *
496
-     * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
497
-     *                                       'Registration' associated with this model object
498
-     * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
499
-     *                                       that could be a payment or a registration)
500
-     * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
501
-     *                                       items which will be stored in an array on this object
502
-     * @throws EE_Error
503
-     * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
504
-     *                  related thing, no array)
505
-     */
506
-    public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
507
-    {
508
-        // its entirely possible that there IS no related object yet in which case there is nothing to cache.
509
-        if ( ! $object_to_cache instanceof EE_Base_Class) {
510
-            return false;
511
-        }
512
-        // also get "how" the object is related, or throw an error
513
-        if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
514
-            throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
515
-                $relationName, get_class($this)));
516
-        }
517
-        // how many things are related ?
518
-        if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
519
-            // 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
520
-            // so for these model objects just set it to be cached
521
-            $this->_model_relations[$relationName] = $object_to_cache;
522
-            $return = true;
523
-        } else {
524
-            // 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.
525
-            // eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
526
-            if ( ! is_array($this->_model_relations[$relationName])) {
527
-                // if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
528
-                $this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
529
-                    ? array($this->_model_relations[$relationName]) : array();
530
-            }
531
-            // first check for a cache_id which is normally empty
532
-            if ( ! empty($cache_id)) {
533
-                // 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
534
-                $this->_model_relations[$relationName][$cache_id] = $object_to_cache;
535
-                $return = $cache_id;
536
-            } elseif ($object_to_cache->ID()) {
537
-                // OR the cached object originally came from the db, so let's just use it's PK for an ID
538
-                $this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
539
-                $return = $object_to_cache->ID();
540
-            } else {
541
-                // OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
542
-                $this->_model_relations[$relationName][] = $object_to_cache;
543
-                // move the internal pointer to the end of the array
544
-                end($this->_model_relations[$relationName]);
545
-                // and grab the key so that we can return it
546
-                $return = key($this->_model_relations[$relationName]);
547
-            }
548
-        }
549
-        return $return;
550
-    }
551
-
552
-
553
-
554
-    /**
555
-     * For adding an item to the cached_properties property.
556
-     *
557
-     * @access protected
558
-     * @param string      $fieldname the property item the corresponding value is for.
559
-     * @param mixed       $value     The value we are caching.
560
-     * @param string|null $cache_type
561
-     * @return void
562
-     * @throws \EE_Error
563
-     */
564
-    protected function _set_cached_property($fieldname, $value, $cache_type = null)
565
-    {
566
-        //first make sure this property exists
567
-        $this->get_model()->field_settings_for($fieldname);
568
-        $cache_type = empty($cache_type) ? 'standard' : $cache_type;
569
-        $this->_cached_properties[$fieldname][$cache_type] = $value;
570
-    }
571
-
572
-
573
-
574
-    /**
575
-     * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
576
-     * This also SETS the cache if we return the actual property!
577
-     *
578
-     * @param string $fieldname        the name of the property we're trying to retrieve
579
-     * @param bool   $pretty
580
-     * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
581
-     *                                 (in cases where the same property may be used for different outputs
582
-     *                                 - i.e. datetime, money etc.)
583
-     *                                 It can also accept certain pre-defined "schema" strings
584
-     *                                 to define how to output the property.
585
-     *                                 see the field's prepare_for_pretty_echoing for what strings can be used
586
-     * @return mixed                   whatever the value for the property is we're retrieving
587
-     * @throws \EE_Error
588
-     */
589
-    protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
590
-    {
591
-        //verify the field exists
592
-        $model = $this->get_model();
593
-        $model->field_settings_for($fieldname);
594
-        $cache_type = $pretty ? 'pretty' : 'standard';
595
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
596
-        if (isset($this->_cached_properties[$fieldname][$cache_type])) {
597
-            return $this->_cached_properties[$fieldname][$cache_type];
598
-        }
599
-        $value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
600
-        $this->_set_cached_property($fieldname, $value, $cache_type);
601
-        return $value;
602
-    }
603
-
604
-
605
-
606
-    /**
607
-     * If the cache didn't fetch the needed item, this fetches it.
608
-     * @param string $fieldname
609
-     * @param bool $pretty
610
-     * @param string $extra_cache_ref
611
-     * @return mixed
612
-     */
613
-    protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
614
-    {
615
-        $field_obj = $this->get_model()->field_settings_for($fieldname);
616
-        // If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
617
-        if ($field_obj instanceof EE_Datetime_Field) {
618
-            $this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
619
-        }
620
-        if ( ! isset($this->_fields[$fieldname])) {
621
-            $this->_fields[$fieldname] = null;
622
-        }
623
-        $value = $pretty
624
-            ? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
625
-            : $field_obj->prepare_for_get($this->_fields[$fieldname]);
626
-        return $value;
627
-    }
628
-
629
-
630
-
631
-    /**
632
-     * set timezone, formats, and output for EE_Datetime_Field objects
633
-     *
634
-     * @param \EE_Datetime_Field $datetime_field
635
-     * @param bool               $pretty
636
-     * @param null $date_or_time
637
-     * @return void
638
-     * @throws \EE_Error
639
-     */
640
-    protected function _prepare_datetime_field(
641
-        EE_Datetime_Field $datetime_field,
642
-        $pretty = false,
643
-        $date_or_time = null
644
-    ) {
645
-        $datetime_field->set_timezone($this->_timezone);
646
-        $datetime_field->set_date_format($this->_dt_frmt, $pretty);
647
-        $datetime_field->set_time_format($this->_tm_frmt, $pretty);
648
-        //set the output returned
649
-        switch ($date_or_time) {
650
-            case 'D' :
651
-                $datetime_field->set_date_time_output('date');
652
-                break;
653
-            case 'T' :
654
-                $datetime_field->set_date_time_output('time');
655
-                break;
656
-            default :
657
-                $datetime_field->set_date_time_output();
658
-        }
659
-    }
660
-
661
-
662
-
663
-    /**
664
-     * This just takes care of clearing out the cached_properties
665
-     *
666
-     * @return void
667
-     */
668
-    protected function _clear_cached_properties()
669
-    {
670
-        $this->_cached_properties = array();
671
-    }
672
-
673
-
674
-
675
-    /**
676
-     * This just clears out ONE property if it exists in the cache
677
-     *
678
-     * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
679
-     * @return void
680
-     */
681
-    protected function _clear_cached_property($property_name)
682
-    {
683
-        if (isset($this->_cached_properties[$property_name])) {
684
-            unset($this->_cached_properties[$property_name]);
685
-        }
686
-    }
687
-
688
-
689
-
690
-    /**
691
-     * Ensures that this related thing is a model object.
692
-     *
693
-     * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
694
-     * @param string $model_name   name of the related thing, eg 'Attendee',
695
-     * @return EE_Base_Class
696
-     * @throws \EE_Error
697
-     */
698
-    protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
699
-    {
700
-        $other_model_instance = self::_get_model_instance_with_name(
701
-            self::_get_model_classname($model_name),
702
-            $this->_timezone
703
-        );
704
-        return $other_model_instance->ensure_is_obj($object_or_id);
705
-    }
706
-
707
-
708
-
709
-    /**
710
-     * Forgets the cached model of the given relation Name. So the next time we request it,
711
-     * we will fetch it again from the database. (Handy if you know it's changed somehow).
712
-     * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
713
-     * then only remove that one object from our cached array. Otherwise, clear the entire list
714
-     *
715
-     * @param string $relationName                         one of the keys in the _model_relations array on the model.
716
-     *                                                     Eg 'Registration'
717
-     * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
718
-     *                                                     if you intend to use $clear_all = TRUE, or the relation only
719
-     *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
720
-     * @param bool   $clear_all                            This flags clearing the entire cache relation property if
721
-     *                                                     this is HasMany or HABTM.
722
-     * @throws EE_Error
723
-     * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
724
-     *                       relation from all
725
-     */
726
-    public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
727
-    {
728
-        $relationship_to_model = $this->get_model()->related_settings_for($relationName);
729
-        $index_in_cache = '';
730
-        if ( ! $relationship_to_model) {
731
-            throw new EE_Error(
732
-                sprintf(
733
-                    __("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
734
-                    $relationName,
735
-                    get_class($this)
736
-                )
737
-            );
738
-        }
739
-        if ($clear_all) {
740
-            $obj_removed = true;
741
-            $this->_model_relations[$relationName] = null;
742
-        } elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
743
-            $obj_removed = $this->_model_relations[$relationName];
744
-            $this->_model_relations[$relationName] = null;
745
-        } else {
746
-            if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
747
-                && $object_to_remove_or_index_into_array->ID()
748
-            ) {
749
-                $index_in_cache = $object_to_remove_or_index_into_array->ID();
750
-                if (is_array($this->_model_relations[$relationName])
751
-                    && ! isset($this->_model_relations[$relationName][$index_in_cache])
752
-                ) {
753
-                    $index_found_at = null;
754
-                    //find this object in the array even though it has a different key
755
-                    foreach ($this->_model_relations[$relationName] as $index => $obj) {
756
-                        if (
757
-                            $obj instanceof EE_Base_Class
758
-                            && (
759
-                                $obj == $object_to_remove_or_index_into_array
760
-                                || $obj->ID() === $object_to_remove_or_index_into_array->ID()
761
-                            )
762
-                        ) {
763
-                            $index_found_at = $index;
764
-                            break;
765
-                        }
766
-                    }
767
-                    if ($index_found_at) {
768
-                        $index_in_cache = $index_found_at;
769
-                    } else {
770
-                        //it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
771
-                        //if it wasn't in it to begin with. So we're done
772
-                        return $object_to_remove_or_index_into_array;
773
-                    }
774
-                }
775
-            } elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
776
-                //so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
777
-                foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
778
-                    if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
779
-                        $index_in_cache = $index;
780
-                    }
781
-                }
782
-            } else {
783
-                $index_in_cache = $object_to_remove_or_index_into_array;
784
-            }
785
-            //supposedly we've found it. But it could just be that the client code
786
-            //provided a bad index/object
787
-            if (
788
-            isset(
789
-                $this->_model_relations[$relationName],
790
-                $this->_model_relations[$relationName][$index_in_cache]
791
-            )
792
-            ) {
793
-                $obj_removed = $this->_model_relations[$relationName][$index_in_cache];
794
-                unset($this->_model_relations[$relationName][$index_in_cache]);
795
-            } else {
796
-                //that thing was never cached anyways.
797
-                $obj_removed = null;
798
-            }
799
-        }
800
-        return $obj_removed;
801
-    }
802
-
803
-
804
-
805
-    /**
806
-     * update_cache_after_object_save
807
-     * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
808
-     * obtained after being saved to the db
809
-     *
810
-     * @param string         $relationName       - the type of object that is cached
811
-     * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
812
-     * @param string         $current_cache_id   - the ID that was used when originally caching the object
813
-     * @return boolean TRUE on success, FALSE on fail
814
-     * @throws \EE_Error
815
-     */
816
-    public function update_cache_after_object_save(
817
-        $relationName,
818
-        EE_Base_Class $newly_saved_object,
819
-        $current_cache_id = ''
820
-    ) {
821
-        // verify that incoming object is of the correct type
822
-        $obj_class = 'EE_' . $relationName;
823
-        if ($newly_saved_object instanceof $obj_class) {
824
-            /* @type EE_Base_Class $newly_saved_object */
825
-            // now get the type of relation
826
-            $relationship_to_model = $this->get_model()->related_settings_for($relationName);
827
-            // if this is a 1:1 relationship
828
-            if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
829
-                // then just replace the cached object with the newly saved object
830
-                $this->_model_relations[$relationName] = $newly_saved_object;
831
-                return true;
832
-                // or if it's some kind of sordid feral polyamorous relationship...
833
-            } elseif (is_array($this->_model_relations[$relationName])
834
-                      && isset($this->_model_relations[$relationName][$current_cache_id])
835
-            ) {
836
-                // then remove the current cached item
837
-                unset($this->_model_relations[$relationName][$current_cache_id]);
838
-                // and cache the newly saved object using it's new ID
839
-                $this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
840
-                return true;
841
-            }
842
-        }
843
-        return false;
844
-    }
845
-
846
-
847
-
848
-    /**
849
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
850
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
851
-     *
852
-     * @param string $relationName
853
-     * @return EE_Base_Class
854
-     */
855
-    public function get_one_from_cache($relationName)
856
-    {
857
-        $cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
858
-            : null;
859
-        if (is_array($cached_array_or_object)) {
860
-            return array_shift($cached_array_or_object);
861
-        } else {
862
-            return $cached_array_or_object;
863
-        }
864
-    }
865
-
866
-
867
-
868
-    /**
869
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
870
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
871
-     *
872
-     * @param string $relationName
873
-     * @throws \EE_Error
874
-     * @return EE_Base_Class[] NOT necessarily indexed by primary keys
875
-     */
876
-    public function get_all_from_cache($relationName)
877
-    {
878
-        $objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
879
-        // if the result is not an array, but exists, make it an array
880
-        $objects = is_array($objects) ? $objects : array($objects);
881
-        //bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
882
-        //basically, if this model object was stored in the session, and these cached model objects
883
-        //already have IDs, let's make sure they're in their model's entity mapper
884
-        //otherwise we will have duplicates next time we call
885
-        // EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
886
-        $model = EE_Registry::instance()->load_model($relationName);
887
-        foreach ($objects as $model_object) {
888
-            if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
889
-                //ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
890
-                if ($model_object->ID()) {
891
-                    $model->add_to_entity_map($model_object);
892
-                }
893
-            } else {
894
-                throw new EE_Error(
895
-                    sprintf(
896
-                        __(
897
-                            'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
898
-                            'event_espresso'
899
-                        ),
900
-                        $relationName,
901
-                        gettype($model_object)
902
-                    )
903
-                );
904
-            }
905
-        }
906
-        return $objects;
907
-    }
908
-
909
-
910
-
911
-    /**
912
-     * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
913
-     * matching the given query conditions.
914
-     *
915
-     * @param null  $field_to_order_by  What field is being used as the reference point.
916
-     * @param int   $limit              How many objects to return.
917
-     * @param array $query_params       Any additional conditions on the query.
918
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
919
-     *                                  you can indicate just the columns you want returned
920
-     * @return array|EE_Base_Class[]
921
-     * @throws \EE_Error
922
-     */
923
-    public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
924
-    {
925
-        $model = $this->get_model();
926
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
927
-            ? $model->get_primary_key_field()->get_name()
928
-            : $field_to_order_by;
929
-        $current_value = ! empty($field) ? $this->get($field) : null;
930
-        if (empty($field) || empty($current_value)) {
931
-            return array();
932
-        }
933
-        return $model->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
934
-    }
935
-
936
-
937
-
938
-    /**
939
-     * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
940
-     * matching the given query conditions.
941
-     *
942
-     * @param null  $field_to_order_by  What field is being used as the reference point.
943
-     * @param int   $limit              How many objects to return.
944
-     * @param array $query_params       Any additional conditions on the query.
945
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
946
-     *                                  you can indicate just the columns you want returned
947
-     * @return array|EE_Base_Class[]
948
-     * @throws \EE_Error
949
-     */
950
-    public function previous_x(
951
-        $field_to_order_by = null,
952
-        $limit = 1,
953
-        $query_params = array(),
954
-        $columns_to_select = null
955
-    ) {
956
-        $model = $this->get_model();
957
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
958
-            ? $model->get_primary_key_field()->get_name()
959
-            : $field_to_order_by;
960
-        $current_value = ! empty($field) ? $this->get($field) : null;
961
-        if (empty($field) || empty($current_value)) {
962
-            return array();
963
-        }
964
-        return $model->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
965
-    }
966
-
967
-
968
-
969
-    /**
970
-     * Returns the next EE_Base_Class object in sequence from this object as found in the database
971
-     * matching the given query conditions.
972
-     *
973
-     * @param null  $field_to_order_by  What field is being used as the reference point.
974
-     * @param array $query_params       Any additional conditions on the query.
975
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
976
-     *                                  you can indicate just the columns you want returned
977
-     * @return array|EE_Base_Class
978
-     * @throws \EE_Error
979
-     */
980
-    public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
981
-    {
982
-        $model = $this->get_model();
983
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
984
-            ? $model->get_primary_key_field()->get_name()
985
-            : $field_to_order_by;
986
-        $current_value = ! empty($field) ? $this->get($field) : null;
987
-        if (empty($field) || empty($current_value)) {
988
-            return array();
989
-        }
990
-        return $model->next($current_value, $field, $query_params, $columns_to_select);
991
-    }
992
-
993
-
994
-
995
-    /**
996
-     * Returns the previous EE_Base_Class object in sequence from this object as found in the database
997
-     * matching the given query conditions.
998
-     *
999
-     * @param null  $field_to_order_by  What field is being used as the reference point.
1000
-     * @param array $query_params       Any additional conditions on the query.
1001
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1002
-     *                                  you can indicate just the column you want returned
1003
-     * @return array|EE_Base_Class
1004
-     * @throws \EE_Error
1005
-     */
1006
-    public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1007
-    {
1008
-        $model = $this->get_model();
1009
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
1010
-            ? $model->get_primary_key_field()->get_name()
1011
-            : $field_to_order_by;
1012
-        $current_value = ! empty($field) ? $this->get($field) : null;
1013
-        if (empty($field) || empty($current_value)) {
1014
-            return array();
1015
-        }
1016
-        return $model->previous($current_value, $field, $query_params, $columns_to_select);
1017
-    }
1018
-
1019
-
1020
-
1021
-    /**
1022
-     * Overrides parent because parent expects old models.
1023
-     * This also doesn't do any validation, and won't work for serialized arrays
1024
-     *
1025
-     * @param string $field_name
1026
-     * @param mixed  $field_value_from_db
1027
-     * @throws \EE_Error
1028
-     */
1029
-    public function set_from_db($field_name, $field_value_from_db)
1030
-    {
1031
-        $field_obj = $this->get_model()->field_settings_for($field_name);
1032
-        if ($field_obj instanceof EE_Model_Field_Base) {
1033
-            //you would think the DB has no NULLs for non-null label fields right? wrong!
1034
-            //eg, a CPT model object could have an entry in the posts table, but no
1035
-            //entry in the meta table. Meaning that all its columns in the meta table
1036
-            //are null! yikes! so when we find one like that, use defaults for its meta columns
1037
-            if ($field_value_from_db === null) {
1038
-                if ($field_obj->is_nullable()) {
1039
-                    //if the field allows nulls, then let it be null
1040
-                    $field_value = null;
1041
-                } else {
1042
-                    $field_value = $field_obj->get_default_value();
1043
-                }
1044
-            } else {
1045
-                $field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1046
-            }
1047
-            $this->_fields[$field_name] = $field_value;
1048
-            $this->_clear_cached_property($field_name);
1049
-        }
1050
-    }
1051
-
1052
-
1053
-
1054
-    /**
1055
-     * verifies that the specified field is of the correct type
1056
-     *
1057
-     * @param string $field_name
1058
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1059
-     *                                (in cases where the same property may be used for different outputs
1060
-     *                                - i.e. datetime, money etc.)
1061
-     * @return mixed
1062
-     * @throws \EE_Error
1063
-     */
1064
-    public function get($field_name, $extra_cache_ref = null)
1065
-    {
1066
-        return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1067
-    }
1068
-
1069
-
1070
-
1071
-    /**
1072
-     * This method simply returns the RAW unprocessed value for the given property in this class
1073
-     *
1074
-     * @param  string $field_name A valid fieldname
1075
-     * @return mixed              Whatever the raw value stored on the property is.
1076
-     * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1077
-     */
1078
-    public function get_raw($field_name)
1079
-    {
1080
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1081
-        return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1082
-            ? $this->_fields[$field_name]->format('U')
1083
-            : $this->_fields[$field_name];
1084
-    }
1085
-
1086
-
1087
-
1088
-    /**
1089
-     * This is used to return the internal DateTime object used for a field that is a
1090
-     * EE_Datetime_Field.
1091
-     *
1092
-     * @param string $field_name               The field name retrieving the DateTime object.
1093
-     * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1094
-     * @throws \EE_Error
1095
-     *                                         an error is set and false returned.  If the field IS an
1096
-     *                                         EE_Datetime_Field and but the field value is null, then
1097
-     *                                         just null is returned (because that indicates that likely
1098
-     *                                         this field is nullable).
1099
-     */
1100
-    public function get_DateTime_object($field_name)
1101
-    {
1102
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1103
-        if ( ! $field_settings instanceof EE_Datetime_Field) {
1104
-            EE_Error::add_error(
1105
-                sprintf(
1106
-                    __(
1107
-                        'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1108
-                        'event_espresso'
1109
-                    ),
1110
-                    $field_name
1111
-                ),
1112
-                __FILE__,
1113
-                __FUNCTION__,
1114
-                __LINE__
1115
-            );
1116
-            return false;
1117
-        }
1118
-        return $this->_fields[$field_name];
1119
-    }
1120
-
1121
-
1122
-
1123
-    /**
1124
-     * Gets a Money object for the specified field. Please note that this should only be
1125
-     * used for fields corresponding to EE_Money_Fields, and it will always return a money object,
1126
-     * or else it will throw an exception.
1127
-     *
1128
-     * @param $field_name
1129
-     * @return mixed
1130
-     * @throws InvalidEntityException
1131
-     * @throws EE_Error
1132
-     */
1133
-    public function getMoneyObject($field_name)
1134
-    {
1135
-        $field = $this->get_model()->field_settings_for($field_name);
1136
-        $value = isset($this->_fields[$field_name]) ? $this->_fields[$field_name] : null;
1137
-        if (! $field instanceof EE_Money_Field
1138
-            || ! $value instanceof Money) {
1139
-            throw new InvalidEntityException(
1140
-                get_class($value),
1141
-                'Money',
1142
-                sprintf(
1143
-                    esc_html__(
1144
-                        // @codingStandardsIgnoreStart
1145
-                        'Tried to retrieve money value from %1$s with ID %2$s from field %3$s but no money object present.',
1146
-                        // @codingStandardsIgnoreEnd
1147
-                        'event_espresso'
1148
-                    ),
1149
-                    get_class($this),
1150
-                    $this->ID(),
1151
-                    $field_name
1152
-                )
1153
-            );
1154
-        }
1155
-        return $value;
1156
-    }
1157
-
1158
-
1159
-
1160
-    /**
1161
-     * To be used in template to immediately echo out the value, and format it for output.
1162
-     * Eg, should call stripslashes and whatnot before echoing
1163
-     *
1164
-     * @param string $field_name      the name of the field as it appears in the DB
1165
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1166
-     *                                (in cases where the same property may be used for different outputs
1167
-     *                                - i.e. datetime, money etc.)
1168
-     * @return void
1169
-     * @throws \EE_Error
1170
-     */
1171
-    public function e($field_name, $extra_cache_ref = null)
1172
-    {
1173
-        echo $this->get_pretty($field_name, $extra_cache_ref);
1174
-    }
1175
-
1176
-
1177
-
1178
-    /**
1179
-     * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1180
-     * can be easily used as the value of form input.
1181
-     *
1182
-     * @param string $field_name
1183
-     * @return void
1184
-     * @throws \EE_Error
1185
-     */
1186
-    public function f($field_name)
1187
-    {
1188
-        $this->e($field_name, 'form_input');
1189
-    }
1190
-
1191
-
1192
-
1193
-    /**
1194
-     * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1195
-     * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1196
-     * to see what options are available.
1197
-     * @param string $field_name
1198
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1199
-     *                                (in cases where the same property may be used for different outputs
1200
-     *                                - i.e. datetime, money etc.)
1201
-     * @return mixed
1202
-     * @throws \EE_Error
1203
-     */
1204
-    public function get_pretty($field_name, $extra_cache_ref = null)
1205
-    {
1206
-        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1207
-    }
1208
-
1209
-
1210
-
1211
-    /**
1212
-     * This simply returns the datetime for the given field name
1213
-     * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1214
-     * (and the equivalent e_date, e_time, e_datetime).
1215
-     *
1216
-     * @access   protected
1217
-     * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1218
-     * @param string   $dt_frmt      valid datetime format used for date
1219
-     *                               (if '' then we just use the default on the field,
1220
-     *                               if NULL we use the last-used format)
1221
-     * @param string   $tm_frmt      Same as above except this is for time format
1222
-     * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1223
-     * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1224
-     * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1225
-     *                               if field is not a valid dtt field, or void if echoing
1226
-     * @throws \EE_Error
1227
-     */
1228
-    protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1229
-    {
1230
-        // clear cached property
1231
-        $this->_clear_cached_property($field_name);
1232
-        //reset format properties because they are used in get()
1233
-        $this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1234
-        $this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1235
-        if ($echo) {
1236
-            $this->e($field_name, $date_or_time);
1237
-            return '';
1238
-        }
1239
-        return $this->get($field_name, $date_or_time);
1240
-    }
1241
-
1242
-
1243
-
1244
-    /**
1245
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1246
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1247
-     * other echoes the pretty value for dtt)
1248
-     *
1249
-     * @param  string $field_name name of model object datetime field holding the value
1250
-     * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1251
-     * @return string            datetime value formatted
1252
-     * @throws \EE_Error
1253
-     */
1254
-    public function get_date($field_name, $format = '')
1255
-    {
1256
-        return $this->_get_datetime($field_name, $format, null, 'D');
1257
-    }
1258
-
1259
-
1260
-
1261
-    /**
1262
-     * @param      $field_name
1263
-     * @param string $format
1264
-     * @throws \EE_Error
1265
-     */
1266
-    public function e_date($field_name, $format = '')
1267
-    {
1268
-        $this->_get_datetime($field_name, $format, null, 'D', true);
1269
-    }
1270
-
1271
-
1272
-
1273
-    /**
1274
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1275
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1276
-     * other echoes the pretty value for dtt)
1277
-     *
1278
-     * @param  string $field_name name of model object datetime field holding the value
1279
-     * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1280
-     * @return string             datetime value formatted
1281
-     * @throws \EE_Error
1282
-     */
1283
-    public function get_time($field_name, $format = '')
1284
-    {
1285
-        return $this->_get_datetime($field_name, null, $format, 'T');
1286
-    }
1287
-
1288
-
1289
-
1290
-    /**
1291
-     * @param      $field_name
1292
-     * @param string $format
1293
-     * @throws \EE_Error
1294
-     */
1295
-    public function e_time($field_name, $format = '')
1296
-    {
1297
-        $this->_get_datetime($field_name, null, $format, 'T', true);
1298
-    }
1299
-
1300
-
1301
-
1302
-    /**
1303
-     * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1304
-     * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1305
-     * other echoes the pretty value for dtt)
1306
-     *
1307
-     * @param  string $field_name name of model object datetime field holding the value
1308
-     * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1309
-     * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1310
-     * @return string             datetime value formatted
1311
-     * @throws \EE_Error
1312
-     */
1313
-    public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1314
-    {
1315
-        return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1316
-    }
1317
-
1318
-
1319
-
1320
-    /**
1321
-     * @param string $field_name
1322
-     * @param string $dt_frmt
1323
-     * @param string $tm_frmt
1324
-     * @throws \EE_Error
1325
-     */
1326
-    public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1327
-    {
1328
-        $this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1329
-    }
1330
-
1331
-
1332
-
1333
-    /**
1334
-     * Get the i8ln value for a date using the WordPress @see date_i18n function.
1335
-     *
1336
-     * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1337
-     * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1338
-     *                           on the object will be used.
1339
-     * @return string Date and time string in set locale or false if no field exists for the given
1340
-     * @throws \EE_Error
1341
-     *                           field name.
1342
-     */
1343
-    public function get_i18n_datetime($field_name, $format = '')
1344
-    {
1345
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1346
-        return date_i18n(
1347
-            $format,
1348
-            EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1349
-        );
1350
-    }
1351
-
1352
-
1353
-
1354
-    /**
1355
-     * This method validates whether the given field name is a valid field on the model object as well as it is of a
1356
-     * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1357
-     * thrown.
1358
-     *
1359
-     * @param  string $field_name The field name being checked
1360
-     * @throws EE_Error
1361
-     * @return EE_Datetime_Field
1362
-     */
1363
-    protected function _get_dtt_field_settings($field_name)
1364
-    {
1365
-        $field = $this->get_model()->field_settings_for($field_name);
1366
-        //check if field is dtt
1367
-        if ($field instanceof EE_Datetime_Field) {
1368
-            return $field;
1369
-        } else {
1370
-            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',
1371
-                'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1372
-        }
1373
-    }
1374
-
1375
-
1376
-
1377
-
1378
-    /**
1379
-     * NOTE ABOUT BELOW:
1380
-     * These convenience date and time setters are for setting date and time independently.  In other words you might
1381
-     * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1382
-     * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1383
-     * method and make sure you send the entire datetime value for setting.
1384
-     */
1385
-    /**
1386
-     * sets the time on a datetime property
1387
-     *
1388
-     * @access protected
1389
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1390
-     * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1391
-     * @throws \EE_Error
1392
-     */
1393
-    protected function _set_time_for($time, $fieldname)
1394
-    {
1395
-        $this->_set_date_time('T', $time, $fieldname);
1396
-    }
1397
-
1398
-
1399
-
1400
-    /**
1401
-     * sets the date on a datetime property
1402
-     *
1403
-     * @access protected
1404
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1405
-     * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1406
-     * @throws \EE_Error
1407
-     */
1408
-    protected function _set_date_for($date, $fieldname)
1409
-    {
1410
-        $this->_set_date_time('D', $date, $fieldname);
1411
-    }
1412
-
1413
-
1414
-
1415
-    /**
1416
-     * This takes care of setting a date or time independently on a given model object property. This method also
1417
-     * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1418
-     *
1419
-     * @access protected
1420
-     * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1421
-     * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1422
-     * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1423
-     *                                        EE_Datetime_Field property)
1424
-     * @throws \EE_Error
1425
-     */
1426
-    protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1427
-    {
1428
-        $field = $this->_get_dtt_field_settings($fieldname);
1429
-        $field->set_timezone($this->_timezone);
1430
-        $field->set_date_format($this->_dt_frmt);
1431
-        $field->set_time_format($this->_tm_frmt);
1432
-        switch ($what) {
1433
-            case 'T' :
1434
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1435
-                    $datetime_value,
1436
-                    $this->_fields[$fieldname]
1437
-                );
1438
-                break;
1439
-            case 'D' :
1440
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1441
-                    $datetime_value,
1442
-                    $this->_fields[$fieldname]
1443
-                );
1444
-                break;
1445
-            case 'B' :
1446
-                $this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1447
-                break;
1448
-        }
1449
-        $this->_clear_cached_property($fieldname);
1450
-    }
1451
-
1452
-
1453
-
1454
-    /**
1455
-     * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1456
-     * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1457
-     * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1458
-     * that could lead to some unexpected results!
1459
-     *
1460
-     * @access public
1461
-     * @param string               $field_name This is the name of the field on the object that contains the date/time
1462
-     *                                         value being returned.
1463
-     * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1464
-     * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1465
-     * @param string               $prepend    You can include something to prepend on the timestamp
1466
-     * @param string               $append     You can include something to append on the timestamp
1467
-     * @throws EE_Error
1468
-     * @return string timestamp
1469
-     */
1470
-    public function display_in_my_timezone(
1471
-        $field_name,
1472
-        $callback = 'get_datetime',
1473
-        $args = null,
1474
-        $prepend = '',
1475
-        $append = ''
1476
-    ) {
1477
-        $timezone = EEH_DTT_Helper::get_timezone();
1478
-        if ($timezone === $this->_timezone) {
1479
-            return '';
1480
-        }
1481
-        $original_timezone = $this->_timezone;
1482
-        $this->set_timezone($timezone);
1483
-        $fn = (array)$field_name;
1484
-        $args = array_merge($fn, (array)$args);
1485
-        if ( ! method_exists($this, $callback)) {
1486
-            throw new EE_Error(
1487
-                sprintf(
1488
-                    __(
1489
-                        'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1490
-                        'event_espresso'
1491
-                    ),
1492
-                    $callback
1493
-                )
1494
-            );
1495
-        }
1496
-        $args = (array)$args;
1497
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1498
-        $this->set_timezone($original_timezone);
1499
-        return $return;
1500
-    }
1501
-
1502
-
1503
-
1504
-    /**
1505
-     * Deletes this model object.
1506
-     * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1507
-     * override
1508
-     * `EE_Base_Class::_delete` NOT this class.
1509
-     *
1510
-     * @return boolean | int
1511
-     * @throws \EE_Error
1512
-     */
1513
-    public function delete()
1514
-    {
1515
-        /**
1516
-         * Called just before the `EE_Base_Class::_delete` method call.
1517
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1518
-         * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1519
-         * soft deletes (trash) the object and does not permanently delete it.
1520
-         *
1521
-         * @param EE_Base_Class $model_object about to be 'deleted'
1522
-         */
1523
-        do_action('AHEE__EE_Base_Class__delete__before', $this);
1524
-        $result = $this->_delete();
1525
-        /**
1526
-         * Called just after the `EE_Base_Class::_delete` method call.
1527
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1528
-         * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1529
-         * soft deletes (trash) the object and does not permanently delete it.
1530
-         *
1531
-         * @param EE_Base_Class $model_object that was just 'deleted'
1532
-         * @param boolean       $result
1533
-         */
1534
-        do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1535
-        return $result;
1536
-    }
1537
-
1538
-
1539
-
1540
-    /**
1541
-     * Calls the specific delete method for the instantiated class.
1542
-     * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1543
-     * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1544
-     * `EE_Base_Class::delete`
1545
-     *
1546
-     * @return bool|int
1547
-     * @throws \EE_Error
1548
-     */
1549
-    protected function _delete()
1550
-    {
1551
-        return $this->delete_permanently();
1552
-    }
1553
-
1554
-
1555
-
1556
-    /**
1557
-     * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1558
-     * error)
1559
-     *
1560
-     * @return bool | int
1561
-     * @throws \EE_Error
1562
-     */
1563
-    public function delete_permanently()
1564
-    {
1565
-        /**
1566
-         * Called just before HARD deleting a model object
1567
-         *
1568
-         * @param EE_Base_Class $model_object about to be 'deleted'
1569
-         */
1570
-        do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1571
-        $model = $this->get_model();
1572
-        $result = $model->delete_permanently_by_ID($this->ID());
1573
-        $this->refresh_cache_of_related_objects();
1574
-        /**
1575
-         * Called just after HARD deleting a model object
1576
-         *
1577
-         * @param EE_Base_Class $model_object that was just 'deleted'
1578
-         * @param boolean       $result
1579
-         */
1580
-        do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1581
-        return $result;
1582
-    }
1583
-
1584
-
1585
-
1586
-    /**
1587
-     * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1588
-     * related model objects
1589
-     *
1590
-     * @throws \EE_Error
1591
-     */
1592
-    public function refresh_cache_of_related_objects()
1593
-    {
1594
-        $model = $this->get_model();
1595
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1596
-            if ( ! empty($this->_model_relations[$relation_name])) {
1597
-                $related_objects = $this->_model_relations[$relation_name];
1598
-                if ($relation_obj instanceof EE_Belongs_To_Relation) {
1599
-                    //this relation only stores a single model object, not an array
1600
-                    //but let's make it consistent
1601
-                    $related_objects = array($related_objects);
1602
-                }
1603
-                foreach ($related_objects as $related_object) {
1604
-                    //only refresh their cache if they're in memory
1605
-                    if ($related_object instanceof EE_Base_Class) {
1606
-                        $related_object->clear_cache($model->get_this_model_name(), $this);
1607
-                    }
1608
-                }
1609
-            }
1610
-        }
1611
-    }
1612
-
1613
-
1614
-
1615
-    /**
1616
-     *        Saves this object to the database. An array may be supplied to set some values on this
1617
-     * object just before saving.
1618
-     *
1619
-     * @access public
1620
-     * @param array $set_cols_n_values keys are field names, values are their new values,
1621
-     *                                 if provided during the save() method (often client code will change the fields'
1622
-     *                                 values before calling save)
1623
-     * @throws \EE_Error
1624
-     * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1625
-     *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1626
-     */
1627
-    public function save($set_cols_n_values = array())
1628
-    {
1629
-        $model = $this->get_model();
1630
-        /**
1631
-         * Filters the fields we're about to save on the model object
1632
-         *
1633
-         * @param array         $set_cols_n_values
1634
-         * @param EE_Base_Class $model_object
1635
-         */
1636
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1637
-            $this);
1638
-        //set attributes as provided in $set_cols_n_values
1639
-        foreach ($set_cols_n_values as $column => $value) {
1640
-            $this->set($column, $value);
1641
-        }
1642
-        // no changes ? then don't do anything
1643
-        if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1644
-            return 0;
1645
-        }
1646
-        /**
1647
-         * Saving a model object.
1648
-         * Before we perform a save, this action is fired.
1649
-         *
1650
-         * @param EE_Base_Class $model_object the model object about to be saved.
1651
-         */
1652
-        do_action('AHEE__EE_Base_Class__save__begin', $this);
1653
-        if ( ! $this->allow_persist()) {
1654
-            return 0;
1655
-        }
1656
-        //now get current attribute values
1657
-        $save_cols_n_values = $this->_fields;
1658
-        //if the object already has an ID, update it. Otherwise, insert it
1659
-        //also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1660
-        $old_assumption_concerning_value_preparation = $model
1661
-                                                            ->get_assumption_concerning_values_already_prepared_by_model_object();
1662
-        $model->assume_values_already_prepared_by_model_object(true);
1663
-        //does this model have an autoincrement PK?
1664
-        if ($model->has_primary_key_field()) {
1665
-            if ($model->get_primary_key_field()->is_auto_increment()) {
1666
-                //ok check if it's set, if so: update; if not, insert
1667
-                if ( ! empty($save_cols_n_values[$model->primary_key_name()])) {
1668
-                    $results = $model->update_by_ID($save_cols_n_values, $this->ID());
1669
-                } else {
1670
-                    unset($save_cols_n_values[$model->primary_key_name()]);
1671
-                    $results = $model->insert($save_cols_n_values);
1672
-                    if ($results) {
1673
-                        //if successful, set the primary key
1674
-                        //but don't use the normal SET method, because it will check if
1675
-                        //an item with the same ID exists in the mapper & db, then
1676
-                        //will find it in the db (because we just added it) and THAT object
1677
-                        //will get added to the mapper before we can add this one!
1678
-                        //but if we just avoid using the SET method, all that headache can be avoided
1679
-                        $pk_field_name = $model->primary_key_name();
1680
-                        $this->_fields[$pk_field_name] = $results;
1681
-                        $this->_clear_cached_property($pk_field_name);
1682
-                        $model->add_to_entity_map($this);
1683
-                        $this->_update_cached_related_model_objs_fks();
1684
-                    }
1685
-                }
1686
-            } else {//PK is NOT auto-increment
1687
-                //so check if one like it already exists in the db
1688
-                if ($model->exists_by_ID($this->ID())) {
1689
-                    if (WP_DEBUG && ! $this->in_entity_map()) {
1690
-                        throw new EE_Error(
1691
-                            sprintf(
1692
-                                __('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',
1693
-                                    'event_espresso'),
1694
-                                get_class($this),
1695
-                                get_class($model) . '::instance()->add_to_entity_map()',
1696
-                                get_class($model) . '::instance()->get_one_by_ID()',
1697
-                                '<br />'
1698
-                            )
1699
-                        );
1700
-                    }
1701
-                    $results = $model->update_by_ID($save_cols_n_values, $this->ID());
1702
-                } else {
1703
-                    $results = $model->insert($save_cols_n_values);
1704
-                    $this->_update_cached_related_model_objs_fks();
1705
-                }
1706
-            }
1707
-        } else {//there is NO primary key
1708
-            $already_in_db = false;
1709
-            foreach ($model->unique_indexes() as $index) {
1710
-                $uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1711
-                if ($model->exists(array($uniqueness_where_params))) {
1712
-                    $already_in_db = true;
1713
-                }
1714
-            }
1715
-            if ($already_in_db) {
1716
-                $combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1717
-                    $model->get_combined_primary_key_fields());
1718
-                $results = $model->update($save_cols_n_values, $combined_pk_fields_n_values);
1719
-            } else {
1720
-                $results = $model->insert($save_cols_n_values);
1721
-            }
1722
-        }
1723
-        //restore the old assumption about values being prepared by the model object
1724
-        $model
1725
-             ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1726
-        /**
1727
-         * After saving the model object this action is called
1728
-         *
1729
-         * @param EE_Base_Class $model_object which was just saved
1730
-         * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1731
-         *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1732
-         */
1733
-        do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1734
-        $this->_has_changes = false;
1735
-        return $results;
1736
-    }
1737
-
1738
-
1739
-
1740
-    /**
1741
-     * Updates the foreign key on related models objects pointing to this to have this model object's ID
1742
-     * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1743
-     * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1744
-     * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1745
-     * 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
1746
-     * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1747
-     * or not they exist in the DB (if they do, their DB records will be automatically updated)
1748
-     *
1749
-     * @return void
1750
-     * @throws \EE_Error
1751
-     */
1752
-    protected function _update_cached_related_model_objs_fks()
1753
-    {
1754
-        $model = $this->get_model();
1755
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1756
-            if ($relation_obj instanceof EE_Has_Many_Relation) {
1757
-                foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1758
-                    $fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1759
-                        $model->get_this_model_name()
1760
-                    );
1761
-                    $related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1762
-                    if ($related_model_obj_in_cache->ID()) {
1763
-                        $related_model_obj_in_cache->save();
1764
-                    }
1765
-                }
1766
-            }
1767
-        }
1768
-    }
1769
-
1770
-
1771
-
1772
-    /**
1773
-     * Saves this model object and its NEW cached relations to the database.
1774
-     * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1775
-     * In order for that to work, we would need to mark model objects as dirty/clean...
1776
-     * because otherwise, there's a potential for infinite looping of saving
1777
-     * Saves the cached related model objects, and ensures the relation between them
1778
-     * and this object and properly setup
1779
-     *
1780
-     * @return int ID of new model object on save; 0 on failure+
1781
-     * @throws \EE_Error
1782
-     */
1783
-    public function save_new_cached_related_model_objs()
1784
-    {
1785
-        //make sure this has been saved
1786
-        if ( ! $this->ID()) {
1787
-            $id = $this->save();
1788
-        } else {
1789
-            $id = $this->ID();
1790
-        }
1791
-        //now save all the NEW cached model objects  (ie they don't exist in the DB)
1792
-        foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1793
-            if ($this->_model_relations[$relationName]) {
1794
-                //is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1795
-                //or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1796
-                if ($relationObj instanceof EE_Belongs_To_Relation) {
1797
-                    //add a relation to that relation type (which saves the appropriate thing in the process)
1798
-                    //but ONLY if it DOES NOT exist in the DB
1799
-                    /* @var $related_model_obj EE_Base_Class */
1800
-                    $related_model_obj = $this->_model_relations[$relationName];
1801
-                    //					if( ! $related_model_obj->ID()){
1802
-                    $this->_add_relation_to($related_model_obj, $relationName);
1803
-                    $related_model_obj->save_new_cached_related_model_objs();
1804
-                    //					}
1805
-                } else {
1806
-                    foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1807
-                        //add a relation to that relation type (which saves the appropriate thing in the process)
1808
-                        //but ONLY if it DOES NOT exist in the DB
1809
-                        //						if( ! $related_model_obj->ID()){
1810
-                        $this->_add_relation_to($related_model_obj, $relationName);
1811
-                        $related_model_obj->save_new_cached_related_model_objs();
1812
-                        //						}
1813
-                    }
1814
-                }
1815
-            }
1816
-        }
1817
-        return $id;
1818
-    }
1819
-
1820
-
1821
-
1822
-    /**
1823
-     * for getting a model while instantiated.
1824
-     *
1825
-     * @return \EEM_Base | \EEM_CPT_Base
1826
-     */
1827
-    public function get_model()
1828
-    {
1829
-        if( ! $this->_model){
1830
-            $modelName = self::_get_model_classname(get_class($this));
1831
-            $this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
1832
-        } else {
1833
-            $this->_model->set_timezone($this->_timezone);
1834
-        }
1835
-
1836
-        return $this->_model;
1837
-    }
1838
-
1839
-
1840
-
1841
-    /**
1842
-     * @param $props_n_values
1843
-     * @param $classname
1844
-     * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1845
-     * @throws \EE_Error
1846
-     */
1847
-    protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1848
-    {
1849
-        //TODO: will not work for Term_Relationships because they have no PK!
1850
-        $primary_id_ref = self::_get_primary_key_name($classname);
1851
-        if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1852
-            $id = $props_n_values[$primary_id_ref];
1853
-            return self::_get_model($classname)->get_from_entity_map($id);
1854
-        }
1855
-        return false;
1856
-    }
1857
-
1858
-
1859
-
1860
-    /**
1861
-     * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1862
-     * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1863
-     * 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
1864
-     * we return false.
1865
-     *
1866
-     * @param  array  $props_n_values   incoming array of properties and their values
1867
-     * @param  string $classname        the classname of the child class
1868
-     * @param null    $timezone
1869
-     * @param array   $date_formats     incoming date_formats in an array where the first value is the
1870
-     *                                  date_format and the second value is the time format
1871
-     * @return mixed (EE_Base_Class|bool)
1872
-     * @throws \EE_Error
1873
-     */
1874
-    protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1875
-    {
1876
-        $existing = null;
1877
-        $model = self::_get_model($classname, $timezone);
1878
-        if ($model->has_primary_key_field()) {
1879
-            $primary_id_ref = self::_get_primary_key_name($classname);
1880
-            if (array_key_exists($primary_id_ref, $props_n_values)
1881
-                && ! empty($props_n_values[$primary_id_ref])
1882
-            ) {
1883
-                $existing = $model->get_one_by_ID(
1884
-                    $props_n_values[$primary_id_ref]
1885
-                );
1886
-            }
1887
-        } elseif ($model->has_all_combined_primary_key_fields($props_n_values)) {
1888
-            //no primary key on this model, but there's still a matching item in the DB
1889
-            $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1890
-                self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1891
-            );
1892
-        }
1893
-        if ($existing) {
1894
-            //set date formats if present before setting values
1895
-            if ( ! empty($date_formats) && is_array($date_formats)) {
1896
-                $existing->set_date_format($date_formats[0]);
1897
-                $existing->set_time_format($date_formats[1]);
1898
-            } else {
1899
-                //set default formats for date and time
1900
-                $existing->set_date_format(get_option('date_format'));
1901
-                $existing->set_time_format(get_option('time_format'));
1902
-            }
1903
-            foreach ($props_n_values as $property => $field_value) {
1904
-                $existing->set($property, $field_value);
1905
-            }
1906
-            return $existing;
1907
-        } else {
1908
-            return false;
1909
-        }
1910
-    }
1911
-
1912
-
1913
-
1914
-    /**
1915
-     * Gets the EEM_*_Model for this class
1916
-     *
1917
-     * @access public now, as this is more convenient
1918
-     * @param      $classname
1919
-     * @param null $timezone
1920
-     * @throws EE_Error
1921
-     * @return EEM_Base
1922
-     */
1923
-    protected static function _get_model($classname, $timezone = null)
1924
-    {
1925
-        //find model for this class
1926
-        if ( ! $classname) {
1927
-            throw new EE_Error(
1928
-                sprintf(
1929
-                    __(
1930
-                        "What were you thinking calling _get_model(%s)?? You need to specify the class name",
1931
-                        "event_espresso"
1932
-                    ),
1933
-                    $classname
1934
-                )
1935
-            );
1936
-        }
1937
-        $modelName = self::_get_model_classname($classname);
1938
-        return self::_get_model_instance_with_name($modelName, $timezone);
1939
-    }
1940
-
1941
-
1942
-
1943
-    /**
1944
-     * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1945
-     *
1946
-     * @param string $model_classname
1947
-     * @param null   $timezone
1948
-     * @return EEM_Base
1949
-     */
1950
-    protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1951
-    {
1952
-        $model_classname = str_replace('EEM_', '', $model_classname);
1953
-        $model = EE_Registry::instance()->load_model($model_classname);
1954
-        $model->set_timezone($timezone);
1955
-        return $model;
1956
-    }
1957
-
1958
-
1959
-
1960
-    /**
1961
-     * If a model name is provided (eg Registration), gets the model classname for that model.
1962
-     * Also works if a model class's classname is provided (eg EE_Registration).
1963
-     *
1964
-     * @param null $model_name
1965
-     * @return string like EEM_Attendee
1966
-     */
1967
-    private static function _get_model_classname($model_name = null)
1968
-    {
1969
-        if (strpos($model_name, "EE_") === 0) {
1970
-            $model_classname = str_replace("EE_", "EEM_", $model_name);
1971
-        } else {
1972
-            $model_classname = "EEM_" . $model_name;
1973
-        }
1974
-        return $model_classname;
1975
-    }
1976
-
1977
-
1978
-
1979
-    /**
1980
-     * returns the name of the primary key attribute
1981
-     *
1982
-     * @param null $classname
1983
-     * @throws EE_Error
1984
-     * @return string
1985
-     */
1986
-    protected static function _get_primary_key_name($classname = null)
1987
-    {
1988
-        if ( ! $classname) {
1989
-            throw new EE_Error(
1990
-                sprintf(
1991
-                    __("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1992
-                    $classname
1993
-                )
1994
-            );
1995
-        }
1996
-        return self::_get_model($classname)->get_primary_key_field()->get_name();
1997
-    }
1998
-
1999
-
2000
-
2001
-    /**
2002
-     * Gets the value of the primary key.
2003
-     * If the object hasn't yet been saved, it should be whatever the model field's default was
2004
-     * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
2005
-     * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
2006
-     *
2007
-     * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
2008
-     * @throws \EE_Error
2009
-     */
2010
-    public function ID()
2011
-    {
2012
-        $model = $this->get_model();
2013
-        //now that we know the name of the variable, use a variable variable to get its value and return its
2014
-        if ($model->has_primary_key_field()) {
2015
-            return $this->_fields[$model->primary_key_name()];
2016
-        } else {
2017
-            return $model->get_index_primary_key_string($this->_fields);
2018
-        }
2019
-    }
2020
-
2021
-
2022
-
2023
-    /**
2024
-     * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
2025
-     * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
2026
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
2027
-     *
2028
-     * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
2029
-     * @param string $relationName                     eg 'Events','Question',etc.
2030
-     *                                                 an attendee to a group, you also want to specify which role they
2031
-     *                                                 will have in that group. So you would use this parameter to
2032
-     *                                                 specify array('role-column-name'=>'role-id')
2033
-     * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
2034
-     *                                                 allow you to further constrict the relation to being added.
2035
-     *                                                 However, keep in mind that the columns (keys) given must match a
2036
-     *                                                 column on the JOIN table and currently only the HABTM models
2037
-     *                                                 accept these additional conditions.  Also remember that if an
2038
-     *                                                 exact match isn't found for these extra cols/val pairs, then a
2039
-     *                                                 NEW row is created in the join table.
2040
-     * @param null   $cache_id
2041
-     * @throws EE_Error
2042
-     * @return EE_Base_Class the object the relation was added to
2043
-     */
2044
-    public function _add_relation_to(
2045
-        $otherObjectModelObjectOrID,
2046
-        $relationName,
2047
-        $extra_join_model_fields_n_values = array(),
2048
-        $cache_id = null
2049
-    ) {
2050
-        $model = $this->get_model();
2051
-        //if this thing exists in the DB, save the relation to the DB
2052
-        if ($this->ID()) {
2053
-            $otherObject = $model
2054
-                                ->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2055
-                                    $extra_join_model_fields_n_values);
2056
-            //clear cache so future get_many_related and get_first_related() return new results.
2057
-            $this->clear_cache($relationName, $otherObject, true);
2058
-            if ($otherObject instanceof EE_Base_Class) {
2059
-                $otherObject->clear_cache($model->get_this_model_name(), $this);
2060
-            }
2061
-        } else {
2062
-            //this thing doesn't exist in the DB,  so just cache it
2063
-            if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2064
-                throw new EE_Error(sprintf(
2065
-                    __('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',
2066
-                        'event_espresso'),
2067
-                    $otherObjectModelObjectOrID,
2068
-                    get_class($this)
2069
-                ));
2070
-            } else {
2071
-                $otherObject = $otherObjectModelObjectOrID;
2072
-            }
2073
-            $this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2074
-        }
2075
-        if ($otherObject instanceof EE_Base_Class) {
2076
-            //fix the reciprocal relation too
2077
-            if ($otherObject->ID()) {
2078
-                //its saved so assumed relations exist in the DB, so we can just
2079
-                //clear the cache so future queries use the updated info in the DB
2080
-                $otherObject->clear_cache($model->get_this_model_name(), null, true);
2081
-            } else {
2082
-                //it's not saved, so it caches relations like this
2083
-                $otherObject->cache($model->get_this_model_name(), $this);
2084
-            }
2085
-        }
2086
-        return $otherObject;
2087
-    }
2088
-
2089
-
2090
-
2091
-    /**
2092
-     * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2093
-     * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2094
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2095
-     * from the cache
2096
-     *
2097
-     * @param mixed  $otherObjectModelObjectOrID
2098
-     *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2099
-     *                to the DB yet
2100
-     * @param string $relationName
2101
-     * @param array  $where_query
2102
-     *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2103
-     *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2104
-     *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2105
-     *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2106
-     *                created in the join table.
2107
-     * @return EE_Base_Class the relation was removed from
2108
-     * @throws \EE_Error
2109
-     */
2110
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2111
-    {
2112
-        if ($this->ID()) {
2113
-            //if this exists in the DB, save the relation change to the DB too
2114
-            $otherObject = $this->get_model()
2115
-                                ->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2116
-                                    $where_query);
2117
-            $this->clear_cache($relationName, $otherObject);
2118
-        } else {
2119
-            //this doesn't exist in the DB, just remove it from the cache
2120
-            $otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2121
-        }
2122
-        if ($otherObject instanceof EE_Base_Class) {
2123
-            $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2124
-        }
2125
-        return $otherObject;
2126
-    }
2127
-
2128
-
2129
-
2130
-    /**
2131
-     * Removes ALL the related things for the $relationName.
2132
-     *
2133
-     * @param string $relationName
2134
-     * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2135
-     * @return EE_Base_Class
2136
-     * @throws \EE_Error
2137
-     */
2138
-    public function _remove_relations($relationName, $where_query_params = array())
2139
-    {
2140
-        if ($this->ID()) {
2141
-            //if this exists in the DB, save the relation change to the DB too
2142
-            $otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2143
-            $this->clear_cache($relationName, null, true);
2144
-        } else {
2145
-            //this doesn't exist in the DB, just remove it from the cache
2146
-            $otherObjects = $this->clear_cache($relationName, null, true);
2147
-        }
2148
-        if (is_array($otherObjects)) {
2149
-            foreach ($otherObjects as $otherObject) {
2150
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2151
-            }
2152
-        }
2153
-        return $otherObjects;
2154
-    }
2155
-
2156
-
2157
-
2158
-    /**
2159
-     * Gets all the related model objects of the specified type. Eg, if the current class if
2160
-     * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2161
-     * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2162
-     * because we want to get even deleted items etc.
2163
-     *
2164
-     * @param string $relationName key in the model's _model_relations array
2165
-     * @param array  $query_params like EEM_Base::get_all
2166
-     * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2167
-     * @throws \EE_Error
2168
-     *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2169
-     *                             you want IDs
2170
-     */
2171
-    public function get_many_related($relationName, $query_params = array())
2172
-    {
2173
-        if ($this->ID()) {
2174
-            //this exists in the DB, so get the related things from either the cache or the DB
2175
-            //if there are query parameters, forget about caching the related model objects.
2176
-            if ($query_params) {
2177
-                $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2178
-            } else {
2179
-                //did we already cache the result of this query?
2180
-                $cached_results = $this->get_all_from_cache($relationName);
2181
-                if ( ! $cached_results) {
2182
-                    $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2183
-                    //if no query parameters were passed, then we got all the related model objects
2184
-                    //for that relation. We can cache them then.
2185
-                    foreach ($related_model_objects as $related_model_object) {
2186
-                        $this->cache($relationName, $related_model_object);
2187
-                    }
2188
-                } else {
2189
-                    $related_model_objects = $cached_results;
2190
-                }
2191
-            }
2192
-        } else {
2193
-            //this doesn't exist in the DB, so just get the related things from the cache
2194
-            $related_model_objects = $this->get_all_from_cache($relationName);
2195
-        }
2196
-        return $related_model_objects;
2197
-    }
2198
-
2199
-
2200
-
2201
-    /**
2202
-     * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2203
-     * unless otherwise specified in the $query_params
2204
-     *
2205
-     * @param string $relation_name  model_name like 'Event', or 'Registration'
2206
-     * @param array  $query_params   like EEM_Base::get_all's
2207
-     * @param string $field_to_count name of field to count by. By default, uses primary key
2208
-     * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2209
-     *                               that by the setting $distinct to TRUE;
2210
-     * @return int
2211
-     */
2212
-    public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2213
-    {
2214
-        return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2215
-    }
2216
-
2217
-
2218
-
2219
-    /**
2220
-     * Instead of getting the related model objects, simply sums up the values of the specified field.
2221
-     * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2222
-     *
2223
-     * @param string $relation_name model_name like 'Event', or 'Registration'
2224
-     * @param array  $query_params  like EEM_Base::get_all's
2225
-     * @param string $field_to_sum  name of field to count by.
2226
-     *                              By default, uses primary key (which doesn't make much sense, so you should probably
2227
-     *                              change it)
2228
-     * @return int
2229
-     */
2230
-    public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2231
-    {
2232
-        return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2233
-    }
2234
-
2235
-
2236
-
2237
-    /**
2238
-     * Gets the first (ie, one) related model object of the specified type.
2239
-     *
2240
-     * @param string $relationName key in the model's _model_relations array
2241
-     * @param array  $query_params like EEM_Base::get_all
2242
-     * @return EE_Base_Class (not an array, a single object)
2243
-     * @throws \EE_Error
2244
-     */
2245
-    public function get_first_related($relationName, $query_params = array())
2246
-    {
2247
-        $model = $this->get_model();
2248
-        if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2249
-            //if they've provided some query parameters, don't bother trying to cache the result
2250
-            //also make sure we're not caching the result of get_first_related
2251
-            //on a relation which should have an array of objects (because the cache might have an array of objects)
2252
-            if ($query_params
2253
-                || ! $model->related_settings_for($relationName)
2254
-                     instanceof
2255
-                     EE_Belongs_To_Relation
2256
-            ) {
2257
-                $related_model_object = $model->get_first_related($this, $relationName, $query_params);
2258
-            } else {
2259
-                //first, check if we've already cached the result of this query
2260
-                $cached_result = $this->get_one_from_cache($relationName);
2261
-                if ( ! $cached_result) {
2262
-                    $related_model_object = $model->get_first_related($this, $relationName, $query_params);
2263
-                    $this->cache($relationName, $related_model_object);
2264
-                } else {
2265
-                    $related_model_object = $cached_result;
2266
-                }
2267
-            }
2268
-        } else {
2269
-            $related_model_object = null;
2270
-            //this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2271
-            if ($model->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2272
-                $related_model_object = $model->get_first_related($this, $relationName, $query_params);
2273
-            }
2274
-            //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
2275
-            if ( ! $related_model_object) {
2276
-                $related_model_object = $this->get_one_from_cache($relationName);
2277
-            }
2278
-        }
2279
-        return $related_model_object;
2280
-    }
2281
-
2282
-
2283
-
2284
-    /**
2285
-     * Does a delete on all related objects of type $relationName and removes
2286
-     * the current model object's relation to them. If they can't be deleted (because
2287
-     * of blocking related model objects) does nothing. If the related model objects are
2288
-     * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2289
-     * If this model object doesn't exist yet in the DB, just removes its related things
2290
-     *
2291
-     * @param string $relationName
2292
-     * @param array  $query_params like EEM_Base::get_all's
2293
-     * @return int how many deleted
2294
-     * @throws \EE_Error
2295
-     */
2296
-    public function delete_related($relationName, $query_params = array())
2297
-    {
2298
-        if ($this->ID()) {
2299
-            $count = $this->get_model()->delete_related($this, $relationName, $query_params);
2300
-        } else {
2301
-            $count = count($this->get_all_from_cache($relationName));
2302
-            $this->clear_cache($relationName, null, true);
2303
-        }
2304
-        return $count;
2305
-    }
2306
-
2307
-
2308
-
2309
-    /**
2310
-     * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2311
-     * the current model object's relation to them. If they can't be deleted (because
2312
-     * of blocking related model objects) just does a soft delete on it instead, if possible.
2313
-     * If the related thing isn't a soft-deletable model object, this function is identical
2314
-     * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2315
-     *
2316
-     * @param string $relationName
2317
-     * @param array  $query_params like EEM_Base::get_all's
2318
-     * @return int how many deleted (including those soft deleted)
2319
-     * @throws \EE_Error
2320
-     */
2321
-    public function delete_related_permanently($relationName, $query_params = array())
2322
-    {
2323
-        if ($this->ID()) {
2324
-            $count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2325
-        } else {
2326
-            $count = count($this->get_all_from_cache($relationName));
2327
-        }
2328
-        $this->clear_cache($relationName, null, true);
2329
-        return $count;
2330
-    }
2331
-
2332
-
2333
-
2334
-    /**
2335
-     * is_set
2336
-     * Just a simple utility function children can use for checking if property exists
2337
-     *
2338
-     * @access  public
2339
-     * @param  string $field_name property to check
2340
-     * @return bool                              TRUE if existing,FALSE if not.
2341
-     */
2342
-    public function is_set($field_name)
2343
-    {
2344
-        return isset($this->_fields[$field_name]);
2345
-    }
2346
-
2347
-
2348
-
2349
-    /**
2350
-     * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2351
-     * EE_Error exception if they don't
2352
-     *
2353
-     * @param  mixed (string|array) $properties properties to check
2354
-     * @throws EE_Error
2355
-     * @return bool                              TRUE if existing, throw EE_Error if not.
2356
-     */
2357
-    protected function _property_exists($properties)
2358
-    {
2359
-        foreach ((array)$properties as $property_name) {
2360
-            //first make sure this property exists
2361
-            if ( ! $this->_fields[$property_name]) {
2362
-                throw new EE_Error(
2363
-                    sprintf(
2364
-                        __(
2365
-                            'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2366
-                            'event_espresso'
2367
-                        ),
2368
-                        $property_name
2369
-                    )
2370
-                );
2371
-            }
2372
-        }
2373
-        return true;
2374
-    }
2375
-
2376
-
2377
-
2378
-    /**
2379
-     * This simply returns an array of model fields for this object
2380
-     *
2381
-     * @return array
2382
-     * @throws \EE_Error
2383
-     */
2384
-    public function model_field_array()
2385
-    {
2386
-        $fields = $this->get_model()->field_settings(false);
2387
-        $properties = array();
2388
-        //remove prepended underscore
2389
-        foreach ($fields as $field_name => $settings) {
2390
-            $properties[$field_name] = $this->get($field_name);
2391
-        }
2392
-        return $properties;
2393
-    }
2394
-
2395
-
2396
-
2397
-    /**
2398
-     * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2399
-     * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2400
-     * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2401
-     * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2402
-     * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2403
-     * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2404
-     * was called, and an array of the original arguments passed to the function. Whatever their callback function
2405
-     * returns will be returned by this function. Example: in functions.php (or in a plugin):
2406
-     * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2407
-     * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2408
-     * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2409
-     *        return $previousReturnValue.$returnString;
2410
-     * }
2411
-     * require('EE_Answer.class.php');
2412
-     * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2413
-     * echo $answer->my_callback('monkeys',100);
2414
-     * //will output "you called my_callback! and passed args:monkeys,100"
2415
-     *
2416
-     * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2417
-     * @param array  $args       array of original arguments passed to the function
2418
-     * @throws EE_Error
2419
-     * @return mixed whatever the plugin which calls add_filter decides
2420
-     */
2421
-    public function __call($methodName, $args)
2422
-    {
2423
-        $className = get_class($this);
2424
-        $tagName = "FHEE__{$className}__{$methodName}";
2425
-        if ( ! has_filter($tagName)) {
2426
-            throw new EE_Error(
2427
-                sprintf(
2428
-                    __(
2429
-                        "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;}",
2430
-                        "event_espresso"
2431
-                    ),
2432
-                    $methodName,
2433
-                    $className,
2434
-                    $tagName
2435
-                )
2436
-            );
2437
-        }
2438
-        return apply_filters($tagName, null, $this, $args);
2439
-    }
2440
-
2441
-
2442
-
2443
-    /**
2444
-     * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2445
-     * A $previous_value can be specified in case there are many meta rows with the same key
2446
-     *
2447
-     * @param string $meta_key
2448
-     * @param mixed  $meta_value
2449
-     * @param mixed  $previous_value
2450
-     * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2451
-     * @throws \EE_Error
2452
-     * NOTE: if the values haven't changed, returns 0
2453
-     */
2454
-    public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2455
-    {
2456
-        $query_params = array(
2457
-            array(
2458
-                'EXM_key'  => $meta_key,
2459
-                'OBJ_ID'   => $this->ID(),
2460
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2461
-            ),
2462
-        );
2463
-        if ($previous_value !== null) {
2464
-            $query_params[0]['EXM_value'] = $meta_value;
2465
-        }
2466
-        $existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2467
-        if ( ! $existing_rows_like_that) {
2468
-            return $this->add_extra_meta($meta_key, $meta_value);
2469
-        }
2470
-        foreach ($existing_rows_like_that as $existing_row) {
2471
-            $existing_row->save(array('EXM_value' => $meta_value));
2472
-        }
2473
-        return count($existing_rows_like_that);
2474
-    }
2475
-
2476
-
2477
-
2478
-    /**
2479
-     * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2480
-     * no other extra meta for this model object have the same key. Returns TRUE if the
2481
-     * extra meta row was entered, false if not
2482
-     *
2483
-     * @param string  $meta_key
2484
-     * @param mixed   $meta_value
2485
-     * @param boolean $unique
2486
-     * @return boolean
2487
-     * @throws \EE_Error
2488
-     */
2489
-    public function add_extra_meta($meta_key, $meta_value, $unique = false)
2490
-    {
2491
-        if ($unique) {
2492
-            $existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2493
-                array(
2494
-                    array(
2495
-                        'EXM_key'  => $meta_key,
2496
-                        'OBJ_ID'   => $this->ID(),
2497
-                        'EXM_type' => $this->get_model()->get_this_model_name(),
2498
-                    ),
2499
-                )
2500
-            );
2501
-            if ($existing_extra_meta) {
2502
-                return false;
2503
-            }
2504
-        }
2505
-        $new_extra_meta = EE_Extra_Meta::new_instance(
2506
-            array(
2507
-                'EXM_key'   => $meta_key,
2508
-                'EXM_value' => $meta_value,
2509
-                'OBJ_ID'    => $this->ID(),
2510
-                'EXM_type'  => $this->get_model()->get_this_model_name(),
2511
-            )
2512
-        );
2513
-        $new_extra_meta->save();
2514
-        return true;
2515
-    }
2516
-
2517
-
2518
-
2519
-    /**
2520
-     * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2521
-     * is specified, only deletes extra meta records with that value.
2522
-     *
2523
-     * @param string $meta_key
2524
-     * @param mixed  $meta_value
2525
-     * @return int number of extra meta rows deleted
2526
-     * @throws \EE_Error
2527
-     */
2528
-    public function delete_extra_meta($meta_key, $meta_value = null)
2529
-    {
2530
-        $query_params = array(
2531
-            array(
2532
-                'EXM_key'  => $meta_key,
2533
-                'OBJ_ID'   => $this->ID(),
2534
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2535
-            ),
2536
-        );
2537
-        if ($meta_value !== null) {
2538
-            $query_params[0]['EXM_value'] = $meta_value;
2539
-        }
2540
-        return EEM_Extra_Meta::instance()->delete($query_params);
2541
-    }
2542
-
2543
-
2544
-
2545
-    /**
2546
-     * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2547
-     * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2548
-     * You can specify $default is case you haven't found the extra meta
2549
-     *
2550
-     * @param string  $meta_key
2551
-     * @param boolean $single
2552
-     * @param mixed   $default if we don't find anything, what should we return?
2553
-     * @return mixed single value if $single; array if ! $single
2554
-     * @throws \EE_Error
2555
-     */
2556
-    public function get_extra_meta($meta_key, $single = false, $default = null)
2557
-    {
2558
-        if ($single) {
2559
-            $result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2560
-            if ($result instanceof EE_Extra_Meta) {
2561
-                return $result->value();
2562
-            }
2563
-        } else {
2564
-            $results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2565
-            if ($results) {
2566
-                $values = array();
2567
-                foreach ($results as $result) {
2568
-                    if ($result instanceof EE_Extra_Meta) {
2569
-                        $values[$result->ID()] = $result->value();
2570
-                    }
2571
-                }
2572
-                return $values;
2573
-            }
2574
-        }
2575
-        //if nothing discovered yet return default.
2576
-        return apply_filters(
2577
-            'FHEE__EE_Base_Class__get_extra_meta__default_value',
2578
-            $default,
2579
-            $meta_key,
2580
-            $single,
2581
-            $this
2582
-            );
2583
-    }
2584
-
2585
-
2586
-
2587
-    /**
2588
-     * Returns a simple array of all the extra meta associated with this model object.
2589
-     * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2590
-     * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2591
-     * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2592
-     * If $one_of_each_key is false, it will return an array with the top-level keys being
2593
-     * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2594
-     * finally the extra meta's value as each sub-value. (eg
2595
-     * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2596
-     *
2597
-     * @param boolean $one_of_each_key
2598
-     * @return array
2599
-     * @throws \EE_Error
2600
-     */
2601
-    public function all_extra_meta_array($one_of_each_key = true)
2602
-    {
2603
-        $return_array = array();
2604
-        if ($one_of_each_key) {
2605
-            $extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2606
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2607
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2608
-                    $return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2609
-                }
2610
-            }
2611
-        } else {
2612
-            $extra_meta_objs = $this->get_many_related('Extra_Meta');
2613
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2614
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2615
-                    if ( ! isset($return_array[$extra_meta_obj->key()])) {
2616
-                        $return_array[$extra_meta_obj->key()] = array();
2617
-                    }
2618
-                    $return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2619
-                }
2620
-            }
2621
-        }
2622
-        return $return_array;
2623
-    }
2624
-
2625
-
2626
-
2627
-    /**
2628
-     * Gets a pretty nice displayable nice for this model object. Often overridden
2629
-     *
2630
-     * @return string
2631
-     * @throws \EE_Error
2632
-     */
2633
-    public function name()
2634
-    {
2635
-        //find a field that's not a text field
2636
-        $field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2637
-        if ($field_we_can_use) {
2638
-            return $this->get($field_we_can_use->get_name());
2639
-        } else {
2640
-            $first_few_properties = $this->model_field_array();
2641
-            $first_few_properties = array_slice($first_few_properties, 0, 3);
2642
-            $name_parts = array();
2643
-            foreach ($first_few_properties as $name => $value) {
2644
-                $name_parts[] = "$name:$value";
2645
-            }
2646
-            return implode(",", $name_parts);
2647
-        }
2648
-    }
2649
-
2650
-
2651
-
2652
-    /**
2653
-     * in_entity_map
2654
-     * Checks if this model object has been proven to already be in the entity map
2655
-     *
2656
-     * @return boolean
2657
-     * @throws \EE_Error
2658
-     */
2659
-    public function in_entity_map()
2660
-    {
2661
-        if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2662
-            //well, if we looked, did we find it in the entity map?
2663
-            return true;
2664
-        } else {
2665
-            return false;
2666
-        }
2667
-    }
2668
-
2669
-
2670
-
2671
-    /**
2672
-     * refresh_from_db
2673
-     * Makes sure the fields and values on this model object are in-sync with what's in the database.
2674
-     *
2675
-     * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2676
-     * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2677
-     */
2678
-    public function refresh_from_db()
2679
-    {
2680
-        if ($this->ID() && $this->in_entity_map()) {
2681
-            $this->get_model()->refresh_entity_map_from_db($this->ID());
2682
-        } else {
2683
-            //if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2684
-            //if it has an ID but it's not in the map, and you're asking me to refresh it
2685
-            //that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2686
-            //absolutely nothing in it for this ID
2687
-            if (WP_DEBUG) {
2688
-                throw new EE_Error(
2689
-                    sprintf(
2690
-                        __('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.',
2691
-                            'event_espresso'),
2692
-                        $this->ID(),
2693
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2694
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2695
-                    )
2696
-                );
2697
-            }
2698
-        }
2699
-    }
2700
-
2701
-
2702
-
2703
-    /**
2704
-     * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2705
-     * (probably a bad assumption they have made, oh well)
2706
-     *
2707
-     * @return string
2708
-     */
2709
-    public function __toString()
2710
-    {
2711
-        try {
2712
-            return sprintf('%s (%s)', $this->name(), $this->ID());
2713
-        } catch (Exception $e) {
2714
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2715
-            return '';
2716
-        }
2717
-    }
2718
-
2719
-
2720
-
2721
-    /**
2722
-     * Clear related model objects if they're already in the DB, because otherwise when we
2723
-     * UN-serialize this model object we'll need to be careful to add them to the entity map.
2724
-     * This means if we have made changes to those related model objects, and want to unserialize
2725
-     * the this model object on a subsequent request, changes to those related model objects will be lost.
2726
-     * Instead, those related model objects should be directly serialized and stored.
2727
-     * Eg, the following won't work:
2728
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2729
-     * $att = $reg->attendee();
2730
-     * $att->set( 'ATT_fname', 'Dirk' );
2731
-     * update_option( 'my_option', serialize( $reg ) );
2732
-     * //END REQUEST
2733
-     * //START NEXT REQUEST
2734
-     * $reg = get_option( 'my_option' );
2735
-     * $reg->attendee()->save();
2736
-     * And would need to be replace with:
2737
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2738
-     * $att = $reg->attendee();
2739
-     * $att->set( 'ATT_fname', 'Dirk' );
2740
-     * update_option( 'my_option', serialize( $reg ) );
2741
-     * //END REQUEST
2742
-     * //START NEXT REQUEST
2743
-     * $att = get_option( 'my_option' );
2744
-     * $att->save();
2745
-     *
2746
-     * @return array
2747
-     * @throws \EE_Error
2748
-     */
2749
-    public function __sleep()
2750
-    {
2751
-        $model = $this->get_model();
2752
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
2753
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
2754
-                $classname = 'EE_' . $model->get_this_model_name();
2755
-                if (
2756
-                    $this->get_one_from_cache($relation_name) instanceof $classname
2757
-                    && $this->get_one_from_cache($relation_name)->ID()
2758
-                ) {
2759
-                    $this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2760
-                }
2761
-            }
2762
-        }
2763
-        $this->_props_n_values_provided_in_constructor = array();
2764
-        $properties_to_serialize = get_object_vars($this);
2765
-        //don't serialize the model. It's big and that risks recursion
2766
-        unset($properties_to_serialize['_model']);
2767
-        return array_keys($properties_to_serialize);
2768
-    }
2769
-
2770
-
2771
-
2772
-    /**
2773
-     * restore _props_n_values_provided_in_constructor
2774
-     * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2775
-     * and therefore should NOT be used to determine if state change has occurred since initial construction.
2776
-     * At best, you would only be able to detect if state change has occurred during THIS request.
2777
-     */
2778
-    public function __wakeup()
2779
-    {
2780
-        $this->_props_n_values_provided_in_constructor = $this->_fields;
2781
-    }
33
+	/**
34
+	 * This is an array of the original properties and values provided during construction
35
+	 * of this model object. (keys are model field names, values are their values).
36
+	 * This list is important to remember so that when we are merging data from the db, we know
37
+	 * which values to override and which to not override.
38
+	 *
39
+	 * @var array
40
+	 */
41
+	protected $_props_n_values_provided_in_constructor;
42
+
43
+	/**
44
+	 * Timezone
45
+	 * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
46
+	 * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
47
+	 * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
48
+	 * access to it.
49
+	 *
50
+	 * @var string
51
+	 */
52
+	protected $_timezone;
53
+
54
+
55
+
56
+	/**
57
+	 * date format
58
+	 * pattern or format for displaying dates
59
+	 *
60
+	 * @var string $_dt_frmt
61
+	 */
62
+	protected $_dt_frmt;
63
+
64
+
65
+
66
+	/**
67
+	 * time format
68
+	 * pattern or format for displaying time
69
+	 *
70
+	 * @var string $_tm_frmt
71
+	 */
72
+	protected $_tm_frmt;
73
+
74
+
75
+
76
+	/**
77
+	 * This property is for holding a cached array of object properties indexed by property name as the key.
78
+	 * The purpose of this is for setting a cache on properties that may have calculated values after a
79
+	 * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
80
+	 * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
81
+	 *
82
+	 * @var array
83
+	 */
84
+	protected $_cached_properties = array();
85
+
86
+	/**
87
+	 * An array containing keys of the related model, and values are either an array of related mode objects or a
88
+	 * single
89
+	 * related model object. see the model's _model_relations. The keys should match those specified. And if the
90
+	 * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
91
+	 * all others have an array)
92
+	 *
93
+	 * @var array
94
+	 */
95
+	protected $_model_relations = array();
96
+
97
+	/**
98
+	 * Array where keys are field names (see the model's _fields property) and values are their values. To see what
99
+	 * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
100
+	 *
101
+	 * @var array
102
+	 */
103
+	protected $_fields = array();
104
+
105
+	/**
106
+	 * @var boolean indicating whether or not this model object is intended to ever be saved
107
+	 * For example, we might create model objects intended to only be used for the duration
108
+	 * of this request and to be thrown away, and if they were accidentally saved
109
+	 * it would be a bug.
110
+	 */
111
+	protected $_allow_persist = true;
112
+
113
+	/**
114
+	 * @var boolean indicating whether or not this model object's properties have changed since construction
115
+	 */
116
+	protected $_has_changes = false;
117
+
118
+	/**
119
+	 * @var EEM_Base
120
+	 */
121
+	protected $_model;
122
+
123
+
124
+
125
+	/**
126
+	 * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
127
+	 * play nice
128
+	 *
129
+	 * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
130
+	 *                                                         layer of the model's _fields array, (eg, EVT_ID,
131
+	 *                                                         TXN_amount, QST_name, etc) and values are their values
132
+	 * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
133
+	 *                                                         corresponding db model or not.
134
+	 * @param string  $timezone                                indicate what timezone you want any datetime fields to
135
+	 *                                                         be in when instantiating a EE_Base_Class object.
136
+	 * @param array   $date_formats                            An array of date formats to set on construct where first
137
+	 *                                                         value is the date_format and second value is the time
138
+	 *                                                         format.
139
+	 * @throws EE_Error
140
+	 */
141
+	protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
142
+	{
143
+		$className = get_class($this);
144
+		do_action("AHEE__{$className}__construct", $this, $fieldValues);
145
+		$model = $this->get_model();
146
+		$model_fields = $model->field_settings(false);
147
+		// ensure $fieldValues is an array
148
+		$fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
149
+		// EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
150
+		// verify client code has not passed any invalid field names
151
+		foreach ($fieldValues as $field_name => $field_value) {
152
+			if ( ! isset($model_fields[$field_name])) {
153
+				throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
154
+					"event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
155
+			}
156
+		}
157
+		// EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
158
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
159
+		if ( ! empty($date_formats) && is_array($date_formats)) {
160
+			list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
161
+		} else {
162
+			//set default formats for date and time
163
+			$this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
164
+			$this->_tm_frmt = (string)get_option('time_format', 'g:i a');
165
+		}
166
+		//if db model is instantiating
167
+		if ($bydb) {
168
+			//client code has indicated these field values are from the database
169
+			foreach ($model_fields as $fieldName => $field) {
170
+				$this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
171
+			}
172
+		} else {
173
+			//we're constructing a brand
174
+			//new instance of the model object. Generally, this means we'll need to do more field validation
175
+			foreach ($model_fields as $fieldName => $field) {
176
+				$this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
177
+			}
178
+		}
179
+		//remember what values were passed to this constructor
180
+		$this->_props_n_values_provided_in_constructor = $fieldValues;
181
+		//remember in entity mapper
182
+		if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
183
+			$model->add_to_entity_map($this);
184
+		}
185
+		//setup all the relations
186
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
187
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
188
+				$this->_model_relations[$relation_name] = null;
189
+			} else {
190
+				$this->_model_relations[$relation_name] = array();
191
+			}
192
+		}
193
+		/**
194
+		 * Action done at the end of each model object construction
195
+		 *
196
+		 * @param EE_Base_Class $this the model object just created
197
+		 */
198
+		do_action('AHEE__EE_Base_Class__construct__finished', $this);
199
+	}
200
+
201
+
202
+
203
+	/**
204
+	 * Gets whether or not this model object is allowed to persist/be saved to the database.
205
+	 *
206
+	 * @return boolean
207
+	 */
208
+	public function allow_persist()
209
+	{
210
+		return $this->_allow_persist;
211
+	}
212
+
213
+
214
+
215
+	/**
216
+	 * Sets whether or not this model object should be allowed to be saved to the DB.
217
+	 * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
218
+	 * you got new information that somehow made you change your mind.
219
+	 *
220
+	 * @param boolean $allow_persist
221
+	 * @return boolean
222
+	 */
223
+	public function set_allow_persist($allow_persist)
224
+	{
225
+		return $this->_allow_persist = $allow_persist;
226
+	}
227
+
228
+
229
+
230
+	/**
231
+	 * Gets the field's original value when this object was constructed during this request.
232
+	 * This can be helpful when determining if a model object has changed or not
233
+	 *
234
+	 * @param string $field_name
235
+	 * @return mixed|null
236
+	 * @throws \EE_Error
237
+	 */
238
+	public function get_original($field_name)
239
+	{
240
+		if (isset($this->_props_n_values_provided_in_constructor[$field_name])
241
+			&& $field_settings = $this->get_model()->field_settings_for($field_name)
242
+		) {
243
+			return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
244
+		} else {
245
+			return null;
246
+		}
247
+	}
248
+
249
+
250
+
251
+	/**
252
+	 * @param EE_Base_Class $obj
253
+	 * @return string
254
+	 */
255
+	public function get_class($obj)
256
+	{
257
+		return get_class($obj);
258
+	}
259
+
260
+
261
+
262
+	/**
263
+	 * Overrides parent because parent expects old models.
264
+	 * This also doesn't do any validation, and won't work for serialized arrays
265
+	 *
266
+	 * @param    string $field_name
267
+	 * @param    mixed  $field_value
268
+	 * @param bool      $use_default
269
+	 * @throws \EE_Error
270
+	 */
271
+	public function set($field_name, $field_value, $use_default = false)
272
+	{
273
+		// if not using default and nothing has changed, and object has already been setup (has ID),
274
+		// then don't do anything
275
+		if (
276
+			! $use_default
277
+			&& $this->_fields[$field_name] === $field_value
278
+			&& $this->ID()
279
+		) {
280
+			return;
281
+		}
282
+		$model = $this->get_model();
283
+		$this->_has_changes = true;
284
+		$field_obj = $model->field_settings_for($field_name);
285
+		if ($field_obj instanceof EE_Model_Field_Base) {
286
+			//			if ( method_exists( $field_obj, 'set_timezone' )) {
287
+			if ($field_obj instanceof EE_Datetime_Field) {
288
+				$field_obj->set_timezone($this->_timezone);
289
+				$field_obj->set_date_format($this->_dt_frmt);
290
+				$field_obj->set_time_format($this->_tm_frmt);
291
+			}
292
+			$holder_of_value = $field_obj->prepare_for_set($field_value);
293
+			//should the value be null?
294
+			if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
295
+				$this->_fields[$field_name] = $field_obj->get_default_value();
296
+				/**
297
+				 * To save having to refactor all the models, if a default value is used for a
298
+				 * EE_Datetime_Field, and that value is not null nor is it a DateTime
299
+				 * object.  Then let's do a set again to ensure that it becomes a DateTime
300
+				 * object.
301
+				 *
302
+				 * @since 4.6.10+
303
+				 */
304
+				if (
305
+					$field_obj instanceof EE_Datetime_Field
306
+					&& $this->_fields[$field_name] !== null
307
+					&& ! $this->_fields[$field_name] instanceof DateTime
308
+				) {
309
+					empty($this->_fields[$field_name])
310
+						? $this->set($field_name, time())
311
+						: $this->set($field_name, $this->_fields[$field_name]);
312
+				}
313
+			} else {
314
+				$this->_fields[$field_name] = $holder_of_value;
315
+			}
316
+			//if we're not in the constructor...
317
+			//now check if what we set was a primary key
318
+			if (
319
+				//note: props_n_values_provided_in_constructor is only set at the END of the constructor
320
+				$this->_props_n_values_provided_in_constructor
321
+				&& $field_value
322
+				&& $field_name === $model->primary_key_name()
323
+			) {
324
+				//if so, we want all this object's fields to be filled either with
325
+				//what we've explicitly set on this model
326
+				//or what we have in the db
327
+				// echo "setting primary key!";
328
+				$fields_on_model = self::_get_model(get_class($this))->field_settings();
329
+				$obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
330
+				foreach ($fields_on_model as $field_obj) {
331
+					if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
332
+						 && $field_obj->get_name() !== $field_name
333
+					) {
334
+						$this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
335
+					}
336
+				}
337
+				//oh this model object has an ID? well make sure its in the entity mapper
338
+				$model->add_to_entity_map($this);
339
+			}
340
+			//let's unset any cache for this field_name from the $_cached_properties property.
341
+			$this->_clear_cached_property($field_name);
342
+		} else {
343
+			throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
344
+				"event_espresso"), $field_name));
345
+		}
346
+	}
347
+
348
+
349
+
350
+	/**
351
+	 * This sets the field value on the db column if it exists for the given $column_name or
352
+	 * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
353
+	 *
354
+	 * @see EE_message::get_column_value for related documentation on the necessity of this method.
355
+	 * @param string $field_name  Must be the exact column name.
356
+	 * @param mixed  $field_value The value to set.
357
+	 * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
358
+	 * @throws \EE_Error
359
+	 */
360
+	public function set_field_or_extra_meta($field_name, $field_value)
361
+	{
362
+		if ($this->get_model()->has_field($field_name)) {
363
+			$this->set($field_name, $field_value);
364
+			return true;
365
+		} else {
366
+			//ensure this object is saved first so that extra meta can be properly related.
367
+			$this->save();
368
+			return $this->update_extra_meta($field_name, $field_value);
369
+		}
370
+	}
371
+
372
+
373
+
374
+	/**
375
+	 * This retrieves the value of the db column set on this class or if that's not present
376
+	 * it will attempt to retrieve from extra_meta if found.
377
+	 * Example Usage:
378
+	 * Via EE_Message child class:
379
+	 * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
380
+	 * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
381
+	 * also have additional main fields specific to the messenger.  The system accommodates those extra
382
+	 * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
383
+	 * value for those extra fields dynamically via the EE_message object.
384
+	 *
385
+	 * @param  string $field_name expecting the fully qualified field name.
386
+	 * @return mixed|null  value for the field if found.  null if not found.
387
+	 * @throws \EE_Error
388
+	 */
389
+	public function get_field_or_extra_meta($field_name)
390
+	{
391
+		if ($this->get_model()->has_field($field_name)) {
392
+			$column_value = $this->get($field_name);
393
+		} else {
394
+			//This isn't a column in the main table, let's see if it is in the extra meta.
395
+			$column_value = $this->get_extra_meta($field_name, true, null);
396
+		}
397
+		return $column_value;
398
+	}
399
+
400
+
401
+
402
+	/**
403
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
404
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
405
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
406
+	 * available to all child classes that may be using the EE_Datetime_Field for a field data type.
407
+	 *
408
+	 * @access public
409
+	 * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
410
+	 * @return void
411
+	 * @throws \EE_Error
412
+	 */
413
+	public function set_timezone($timezone = '')
414
+	{
415
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
416
+		//make sure we clear all cached properties because they won't be relevant now
417
+		$this->_clear_cached_properties();
418
+		//make sure we update field settings and the date for all EE_Datetime_Fields
419
+		$model_fields = $this->get_model()->field_settings(false);
420
+		foreach ($model_fields as $field_name => $field_obj) {
421
+			if ($field_obj instanceof EE_Datetime_Field) {
422
+				$field_obj->set_timezone($this->_timezone);
423
+				if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
424
+					$this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
425
+				}
426
+			}
427
+		}
428
+	}
429
+
430
+
431
+
432
+	/**
433
+	 * This just returns whatever is set for the current timezone.
434
+	 *
435
+	 * @access public
436
+	 * @return string timezone string
437
+	 */
438
+	public function get_timezone()
439
+	{
440
+		return $this->_timezone;
441
+	}
442
+
443
+
444
+
445
+	/**
446
+	 * This sets the internal date format to what is sent in to be used as the new default for the class
447
+	 * internally instead of wp set date format options
448
+	 *
449
+	 * @since 4.6
450
+	 * @param string $format should be a format recognizable by PHP date() functions.
451
+	 */
452
+	public function set_date_format($format)
453
+	{
454
+		$this->_dt_frmt = $format;
455
+		//clear cached_properties because they won't be relevant now.
456
+		$this->_clear_cached_properties();
457
+	}
458
+
459
+
460
+
461
+	/**
462
+	 * This sets the internal time format string to what is sent in to be used as the new default for the
463
+	 * class internally instead of wp set time format options.
464
+	 *
465
+	 * @since 4.6
466
+	 * @param string $format should be a format recognizable by PHP date() functions.
467
+	 */
468
+	public function set_time_format($format)
469
+	{
470
+		$this->_tm_frmt = $format;
471
+		//clear cached_properties because they won't be relevant now.
472
+		$this->_clear_cached_properties();
473
+	}
474
+
475
+
476
+
477
+	/**
478
+	 * This returns the current internal set format for the date and time formats.
479
+	 *
480
+	 * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
481
+	 *                             where the first value is the date format and the second value is the time format.
482
+	 * @return mixed string|array
483
+	 */
484
+	public function get_format($full = true)
485
+	{
486
+		return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
487
+	}
488
+
489
+
490
+
491
+	/**
492
+	 * cache
493
+	 * stores the passed model object on the current model object.
494
+	 * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
495
+	 *
496
+	 * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
497
+	 *                                       'Registration' associated with this model object
498
+	 * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
499
+	 *                                       that could be a payment or a registration)
500
+	 * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
501
+	 *                                       items which will be stored in an array on this object
502
+	 * @throws EE_Error
503
+	 * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
504
+	 *                  related thing, no array)
505
+	 */
506
+	public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
507
+	{
508
+		// its entirely possible that there IS no related object yet in which case there is nothing to cache.
509
+		if ( ! $object_to_cache instanceof EE_Base_Class) {
510
+			return false;
511
+		}
512
+		// also get "how" the object is related, or throw an error
513
+		if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
514
+			throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
515
+				$relationName, get_class($this)));
516
+		}
517
+		// how many things are related ?
518
+		if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
519
+			// 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
520
+			// so for these model objects just set it to be cached
521
+			$this->_model_relations[$relationName] = $object_to_cache;
522
+			$return = true;
523
+		} else {
524
+			// 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.
525
+			// eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
526
+			if ( ! is_array($this->_model_relations[$relationName])) {
527
+				// if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
528
+				$this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
529
+					? array($this->_model_relations[$relationName]) : array();
530
+			}
531
+			// first check for a cache_id which is normally empty
532
+			if ( ! empty($cache_id)) {
533
+				// 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
534
+				$this->_model_relations[$relationName][$cache_id] = $object_to_cache;
535
+				$return = $cache_id;
536
+			} elseif ($object_to_cache->ID()) {
537
+				// OR the cached object originally came from the db, so let's just use it's PK for an ID
538
+				$this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
539
+				$return = $object_to_cache->ID();
540
+			} else {
541
+				// OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
542
+				$this->_model_relations[$relationName][] = $object_to_cache;
543
+				// move the internal pointer to the end of the array
544
+				end($this->_model_relations[$relationName]);
545
+				// and grab the key so that we can return it
546
+				$return = key($this->_model_relations[$relationName]);
547
+			}
548
+		}
549
+		return $return;
550
+	}
551
+
552
+
553
+
554
+	/**
555
+	 * For adding an item to the cached_properties property.
556
+	 *
557
+	 * @access protected
558
+	 * @param string      $fieldname the property item the corresponding value is for.
559
+	 * @param mixed       $value     The value we are caching.
560
+	 * @param string|null $cache_type
561
+	 * @return void
562
+	 * @throws \EE_Error
563
+	 */
564
+	protected function _set_cached_property($fieldname, $value, $cache_type = null)
565
+	{
566
+		//first make sure this property exists
567
+		$this->get_model()->field_settings_for($fieldname);
568
+		$cache_type = empty($cache_type) ? 'standard' : $cache_type;
569
+		$this->_cached_properties[$fieldname][$cache_type] = $value;
570
+	}
571
+
572
+
573
+
574
+	/**
575
+	 * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
576
+	 * This also SETS the cache if we return the actual property!
577
+	 *
578
+	 * @param string $fieldname        the name of the property we're trying to retrieve
579
+	 * @param bool   $pretty
580
+	 * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
581
+	 *                                 (in cases where the same property may be used for different outputs
582
+	 *                                 - i.e. datetime, money etc.)
583
+	 *                                 It can also accept certain pre-defined "schema" strings
584
+	 *                                 to define how to output the property.
585
+	 *                                 see the field's prepare_for_pretty_echoing for what strings can be used
586
+	 * @return mixed                   whatever the value for the property is we're retrieving
587
+	 * @throws \EE_Error
588
+	 */
589
+	protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
590
+	{
591
+		//verify the field exists
592
+		$model = $this->get_model();
593
+		$model->field_settings_for($fieldname);
594
+		$cache_type = $pretty ? 'pretty' : 'standard';
595
+		$cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
596
+		if (isset($this->_cached_properties[$fieldname][$cache_type])) {
597
+			return $this->_cached_properties[$fieldname][$cache_type];
598
+		}
599
+		$value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
600
+		$this->_set_cached_property($fieldname, $value, $cache_type);
601
+		return $value;
602
+	}
603
+
604
+
605
+
606
+	/**
607
+	 * If the cache didn't fetch the needed item, this fetches it.
608
+	 * @param string $fieldname
609
+	 * @param bool $pretty
610
+	 * @param string $extra_cache_ref
611
+	 * @return mixed
612
+	 */
613
+	protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
614
+	{
615
+		$field_obj = $this->get_model()->field_settings_for($fieldname);
616
+		// If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
617
+		if ($field_obj instanceof EE_Datetime_Field) {
618
+			$this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
619
+		}
620
+		if ( ! isset($this->_fields[$fieldname])) {
621
+			$this->_fields[$fieldname] = null;
622
+		}
623
+		$value = $pretty
624
+			? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
625
+			: $field_obj->prepare_for_get($this->_fields[$fieldname]);
626
+		return $value;
627
+	}
628
+
629
+
630
+
631
+	/**
632
+	 * set timezone, formats, and output for EE_Datetime_Field objects
633
+	 *
634
+	 * @param \EE_Datetime_Field $datetime_field
635
+	 * @param bool               $pretty
636
+	 * @param null $date_or_time
637
+	 * @return void
638
+	 * @throws \EE_Error
639
+	 */
640
+	protected function _prepare_datetime_field(
641
+		EE_Datetime_Field $datetime_field,
642
+		$pretty = false,
643
+		$date_or_time = null
644
+	) {
645
+		$datetime_field->set_timezone($this->_timezone);
646
+		$datetime_field->set_date_format($this->_dt_frmt, $pretty);
647
+		$datetime_field->set_time_format($this->_tm_frmt, $pretty);
648
+		//set the output returned
649
+		switch ($date_or_time) {
650
+			case 'D' :
651
+				$datetime_field->set_date_time_output('date');
652
+				break;
653
+			case 'T' :
654
+				$datetime_field->set_date_time_output('time');
655
+				break;
656
+			default :
657
+				$datetime_field->set_date_time_output();
658
+		}
659
+	}
660
+
661
+
662
+
663
+	/**
664
+	 * This just takes care of clearing out the cached_properties
665
+	 *
666
+	 * @return void
667
+	 */
668
+	protected function _clear_cached_properties()
669
+	{
670
+		$this->_cached_properties = array();
671
+	}
672
+
673
+
674
+
675
+	/**
676
+	 * This just clears out ONE property if it exists in the cache
677
+	 *
678
+	 * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
679
+	 * @return void
680
+	 */
681
+	protected function _clear_cached_property($property_name)
682
+	{
683
+		if (isset($this->_cached_properties[$property_name])) {
684
+			unset($this->_cached_properties[$property_name]);
685
+		}
686
+	}
687
+
688
+
689
+
690
+	/**
691
+	 * Ensures that this related thing is a model object.
692
+	 *
693
+	 * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
694
+	 * @param string $model_name   name of the related thing, eg 'Attendee',
695
+	 * @return EE_Base_Class
696
+	 * @throws \EE_Error
697
+	 */
698
+	protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
699
+	{
700
+		$other_model_instance = self::_get_model_instance_with_name(
701
+			self::_get_model_classname($model_name),
702
+			$this->_timezone
703
+		);
704
+		return $other_model_instance->ensure_is_obj($object_or_id);
705
+	}
706
+
707
+
708
+
709
+	/**
710
+	 * Forgets the cached model of the given relation Name. So the next time we request it,
711
+	 * we will fetch it again from the database. (Handy if you know it's changed somehow).
712
+	 * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
713
+	 * then only remove that one object from our cached array. Otherwise, clear the entire list
714
+	 *
715
+	 * @param string $relationName                         one of the keys in the _model_relations array on the model.
716
+	 *                                                     Eg 'Registration'
717
+	 * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
718
+	 *                                                     if you intend to use $clear_all = TRUE, or the relation only
719
+	 *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
720
+	 * @param bool   $clear_all                            This flags clearing the entire cache relation property if
721
+	 *                                                     this is HasMany or HABTM.
722
+	 * @throws EE_Error
723
+	 * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
724
+	 *                       relation from all
725
+	 */
726
+	public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
727
+	{
728
+		$relationship_to_model = $this->get_model()->related_settings_for($relationName);
729
+		$index_in_cache = '';
730
+		if ( ! $relationship_to_model) {
731
+			throw new EE_Error(
732
+				sprintf(
733
+					__("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
734
+					$relationName,
735
+					get_class($this)
736
+				)
737
+			);
738
+		}
739
+		if ($clear_all) {
740
+			$obj_removed = true;
741
+			$this->_model_relations[$relationName] = null;
742
+		} elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
743
+			$obj_removed = $this->_model_relations[$relationName];
744
+			$this->_model_relations[$relationName] = null;
745
+		} else {
746
+			if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
747
+				&& $object_to_remove_or_index_into_array->ID()
748
+			) {
749
+				$index_in_cache = $object_to_remove_or_index_into_array->ID();
750
+				if (is_array($this->_model_relations[$relationName])
751
+					&& ! isset($this->_model_relations[$relationName][$index_in_cache])
752
+				) {
753
+					$index_found_at = null;
754
+					//find this object in the array even though it has a different key
755
+					foreach ($this->_model_relations[$relationName] as $index => $obj) {
756
+						if (
757
+							$obj instanceof EE_Base_Class
758
+							&& (
759
+								$obj == $object_to_remove_or_index_into_array
760
+								|| $obj->ID() === $object_to_remove_or_index_into_array->ID()
761
+							)
762
+						) {
763
+							$index_found_at = $index;
764
+							break;
765
+						}
766
+					}
767
+					if ($index_found_at) {
768
+						$index_in_cache = $index_found_at;
769
+					} else {
770
+						//it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
771
+						//if it wasn't in it to begin with. So we're done
772
+						return $object_to_remove_or_index_into_array;
773
+					}
774
+				}
775
+			} elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
776
+				//so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
777
+				foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
778
+					if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
779
+						$index_in_cache = $index;
780
+					}
781
+				}
782
+			} else {
783
+				$index_in_cache = $object_to_remove_or_index_into_array;
784
+			}
785
+			//supposedly we've found it. But it could just be that the client code
786
+			//provided a bad index/object
787
+			if (
788
+			isset(
789
+				$this->_model_relations[$relationName],
790
+				$this->_model_relations[$relationName][$index_in_cache]
791
+			)
792
+			) {
793
+				$obj_removed = $this->_model_relations[$relationName][$index_in_cache];
794
+				unset($this->_model_relations[$relationName][$index_in_cache]);
795
+			} else {
796
+				//that thing was never cached anyways.
797
+				$obj_removed = null;
798
+			}
799
+		}
800
+		return $obj_removed;
801
+	}
802
+
803
+
804
+
805
+	/**
806
+	 * update_cache_after_object_save
807
+	 * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
808
+	 * obtained after being saved to the db
809
+	 *
810
+	 * @param string         $relationName       - the type of object that is cached
811
+	 * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
812
+	 * @param string         $current_cache_id   - the ID that was used when originally caching the object
813
+	 * @return boolean TRUE on success, FALSE on fail
814
+	 * @throws \EE_Error
815
+	 */
816
+	public function update_cache_after_object_save(
817
+		$relationName,
818
+		EE_Base_Class $newly_saved_object,
819
+		$current_cache_id = ''
820
+	) {
821
+		// verify that incoming object is of the correct type
822
+		$obj_class = 'EE_' . $relationName;
823
+		if ($newly_saved_object instanceof $obj_class) {
824
+			/* @type EE_Base_Class $newly_saved_object */
825
+			// now get the type of relation
826
+			$relationship_to_model = $this->get_model()->related_settings_for($relationName);
827
+			// if this is a 1:1 relationship
828
+			if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
829
+				// then just replace the cached object with the newly saved object
830
+				$this->_model_relations[$relationName] = $newly_saved_object;
831
+				return true;
832
+				// or if it's some kind of sordid feral polyamorous relationship...
833
+			} elseif (is_array($this->_model_relations[$relationName])
834
+					  && isset($this->_model_relations[$relationName][$current_cache_id])
835
+			) {
836
+				// then remove the current cached item
837
+				unset($this->_model_relations[$relationName][$current_cache_id]);
838
+				// and cache the newly saved object using it's new ID
839
+				$this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
840
+				return true;
841
+			}
842
+		}
843
+		return false;
844
+	}
845
+
846
+
847
+
848
+	/**
849
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
850
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
851
+	 *
852
+	 * @param string $relationName
853
+	 * @return EE_Base_Class
854
+	 */
855
+	public function get_one_from_cache($relationName)
856
+	{
857
+		$cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
858
+			: null;
859
+		if (is_array($cached_array_or_object)) {
860
+			return array_shift($cached_array_or_object);
861
+		} else {
862
+			return $cached_array_or_object;
863
+		}
864
+	}
865
+
866
+
867
+
868
+	/**
869
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
870
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
871
+	 *
872
+	 * @param string $relationName
873
+	 * @throws \EE_Error
874
+	 * @return EE_Base_Class[] NOT necessarily indexed by primary keys
875
+	 */
876
+	public function get_all_from_cache($relationName)
877
+	{
878
+		$objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
879
+		// if the result is not an array, but exists, make it an array
880
+		$objects = is_array($objects) ? $objects : array($objects);
881
+		//bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
882
+		//basically, if this model object was stored in the session, and these cached model objects
883
+		//already have IDs, let's make sure they're in their model's entity mapper
884
+		//otherwise we will have duplicates next time we call
885
+		// EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
886
+		$model = EE_Registry::instance()->load_model($relationName);
887
+		foreach ($objects as $model_object) {
888
+			if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
889
+				//ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
890
+				if ($model_object->ID()) {
891
+					$model->add_to_entity_map($model_object);
892
+				}
893
+			} else {
894
+				throw new EE_Error(
895
+					sprintf(
896
+						__(
897
+							'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
898
+							'event_espresso'
899
+						),
900
+						$relationName,
901
+						gettype($model_object)
902
+					)
903
+				);
904
+			}
905
+		}
906
+		return $objects;
907
+	}
908
+
909
+
910
+
911
+	/**
912
+	 * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
913
+	 * matching the given query conditions.
914
+	 *
915
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
916
+	 * @param int   $limit              How many objects to return.
917
+	 * @param array $query_params       Any additional conditions on the query.
918
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
919
+	 *                                  you can indicate just the columns you want returned
920
+	 * @return array|EE_Base_Class[]
921
+	 * @throws \EE_Error
922
+	 */
923
+	public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
924
+	{
925
+		$model = $this->get_model();
926
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
927
+			? $model->get_primary_key_field()->get_name()
928
+			: $field_to_order_by;
929
+		$current_value = ! empty($field) ? $this->get($field) : null;
930
+		if (empty($field) || empty($current_value)) {
931
+			return array();
932
+		}
933
+		return $model->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
934
+	}
935
+
936
+
937
+
938
+	/**
939
+	 * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
940
+	 * matching the given query conditions.
941
+	 *
942
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
943
+	 * @param int   $limit              How many objects to return.
944
+	 * @param array $query_params       Any additional conditions on the query.
945
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
946
+	 *                                  you can indicate just the columns you want returned
947
+	 * @return array|EE_Base_Class[]
948
+	 * @throws \EE_Error
949
+	 */
950
+	public function previous_x(
951
+		$field_to_order_by = null,
952
+		$limit = 1,
953
+		$query_params = array(),
954
+		$columns_to_select = null
955
+	) {
956
+		$model = $this->get_model();
957
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
958
+			? $model->get_primary_key_field()->get_name()
959
+			: $field_to_order_by;
960
+		$current_value = ! empty($field) ? $this->get($field) : null;
961
+		if (empty($field) || empty($current_value)) {
962
+			return array();
963
+		}
964
+		return $model->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
965
+	}
966
+
967
+
968
+
969
+	/**
970
+	 * Returns the next EE_Base_Class object in sequence from this object as found in the database
971
+	 * matching the given query conditions.
972
+	 *
973
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
974
+	 * @param array $query_params       Any additional conditions on the query.
975
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
976
+	 *                                  you can indicate just the columns you want returned
977
+	 * @return array|EE_Base_Class
978
+	 * @throws \EE_Error
979
+	 */
980
+	public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
981
+	{
982
+		$model = $this->get_model();
983
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
984
+			? $model->get_primary_key_field()->get_name()
985
+			: $field_to_order_by;
986
+		$current_value = ! empty($field) ? $this->get($field) : null;
987
+		if (empty($field) || empty($current_value)) {
988
+			return array();
989
+		}
990
+		return $model->next($current_value, $field, $query_params, $columns_to_select);
991
+	}
992
+
993
+
994
+
995
+	/**
996
+	 * Returns the previous EE_Base_Class object in sequence from this object as found in the database
997
+	 * matching the given query conditions.
998
+	 *
999
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
1000
+	 * @param array $query_params       Any additional conditions on the query.
1001
+	 * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1002
+	 *                                  you can indicate just the column you want returned
1003
+	 * @return array|EE_Base_Class
1004
+	 * @throws \EE_Error
1005
+	 */
1006
+	public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1007
+	{
1008
+		$model = $this->get_model();
1009
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
1010
+			? $model->get_primary_key_field()->get_name()
1011
+			: $field_to_order_by;
1012
+		$current_value = ! empty($field) ? $this->get($field) : null;
1013
+		if (empty($field) || empty($current_value)) {
1014
+			return array();
1015
+		}
1016
+		return $model->previous($current_value, $field, $query_params, $columns_to_select);
1017
+	}
1018
+
1019
+
1020
+
1021
+	/**
1022
+	 * Overrides parent because parent expects old models.
1023
+	 * This also doesn't do any validation, and won't work for serialized arrays
1024
+	 *
1025
+	 * @param string $field_name
1026
+	 * @param mixed  $field_value_from_db
1027
+	 * @throws \EE_Error
1028
+	 */
1029
+	public function set_from_db($field_name, $field_value_from_db)
1030
+	{
1031
+		$field_obj = $this->get_model()->field_settings_for($field_name);
1032
+		if ($field_obj instanceof EE_Model_Field_Base) {
1033
+			//you would think the DB has no NULLs for non-null label fields right? wrong!
1034
+			//eg, a CPT model object could have an entry in the posts table, but no
1035
+			//entry in the meta table. Meaning that all its columns in the meta table
1036
+			//are null! yikes! so when we find one like that, use defaults for its meta columns
1037
+			if ($field_value_from_db === null) {
1038
+				if ($field_obj->is_nullable()) {
1039
+					//if the field allows nulls, then let it be null
1040
+					$field_value = null;
1041
+				} else {
1042
+					$field_value = $field_obj->get_default_value();
1043
+				}
1044
+			} else {
1045
+				$field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1046
+			}
1047
+			$this->_fields[$field_name] = $field_value;
1048
+			$this->_clear_cached_property($field_name);
1049
+		}
1050
+	}
1051
+
1052
+
1053
+
1054
+	/**
1055
+	 * verifies that the specified field is of the correct type
1056
+	 *
1057
+	 * @param string $field_name
1058
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1059
+	 *                                (in cases where the same property may be used for different outputs
1060
+	 *                                - i.e. datetime, money etc.)
1061
+	 * @return mixed
1062
+	 * @throws \EE_Error
1063
+	 */
1064
+	public function get($field_name, $extra_cache_ref = null)
1065
+	{
1066
+		return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1067
+	}
1068
+
1069
+
1070
+
1071
+	/**
1072
+	 * This method simply returns the RAW unprocessed value for the given property in this class
1073
+	 *
1074
+	 * @param  string $field_name A valid fieldname
1075
+	 * @return mixed              Whatever the raw value stored on the property is.
1076
+	 * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1077
+	 */
1078
+	public function get_raw($field_name)
1079
+	{
1080
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1081
+		return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1082
+			? $this->_fields[$field_name]->format('U')
1083
+			: $this->_fields[$field_name];
1084
+	}
1085
+
1086
+
1087
+
1088
+	/**
1089
+	 * This is used to return the internal DateTime object used for a field that is a
1090
+	 * EE_Datetime_Field.
1091
+	 *
1092
+	 * @param string $field_name               The field name retrieving the DateTime object.
1093
+	 * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1094
+	 * @throws \EE_Error
1095
+	 *                                         an error is set and false returned.  If the field IS an
1096
+	 *                                         EE_Datetime_Field and but the field value is null, then
1097
+	 *                                         just null is returned (because that indicates that likely
1098
+	 *                                         this field is nullable).
1099
+	 */
1100
+	public function get_DateTime_object($field_name)
1101
+	{
1102
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1103
+		if ( ! $field_settings instanceof EE_Datetime_Field) {
1104
+			EE_Error::add_error(
1105
+				sprintf(
1106
+					__(
1107
+						'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1108
+						'event_espresso'
1109
+					),
1110
+					$field_name
1111
+				),
1112
+				__FILE__,
1113
+				__FUNCTION__,
1114
+				__LINE__
1115
+			);
1116
+			return false;
1117
+		}
1118
+		return $this->_fields[$field_name];
1119
+	}
1120
+
1121
+
1122
+
1123
+	/**
1124
+	 * Gets a Money object for the specified field. Please note that this should only be
1125
+	 * used for fields corresponding to EE_Money_Fields, and it will always return a money object,
1126
+	 * or else it will throw an exception.
1127
+	 *
1128
+	 * @param $field_name
1129
+	 * @return mixed
1130
+	 * @throws InvalidEntityException
1131
+	 * @throws EE_Error
1132
+	 */
1133
+	public function getMoneyObject($field_name)
1134
+	{
1135
+		$field = $this->get_model()->field_settings_for($field_name);
1136
+		$value = isset($this->_fields[$field_name]) ? $this->_fields[$field_name] : null;
1137
+		if (! $field instanceof EE_Money_Field
1138
+			|| ! $value instanceof Money) {
1139
+			throw new InvalidEntityException(
1140
+				get_class($value),
1141
+				'Money',
1142
+				sprintf(
1143
+					esc_html__(
1144
+						// @codingStandardsIgnoreStart
1145
+						'Tried to retrieve money value from %1$s with ID %2$s from field %3$s but no money object present.',
1146
+						// @codingStandardsIgnoreEnd
1147
+						'event_espresso'
1148
+					),
1149
+					get_class($this),
1150
+					$this->ID(),
1151
+					$field_name
1152
+				)
1153
+			);
1154
+		}
1155
+		return $value;
1156
+	}
1157
+
1158
+
1159
+
1160
+	/**
1161
+	 * To be used in template to immediately echo out the value, and format it for output.
1162
+	 * Eg, should call stripslashes and whatnot before echoing
1163
+	 *
1164
+	 * @param string $field_name      the name of the field as it appears in the DB
1165
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1166
+	 *                                (in cases where the same property may be used for different outputs
1167
+	 *                                - i.e. datetime, money etc.)
1168
+	 * @return void
1169
+	 * @throws \EE_Error
1170
+	 */
1171
+	public function e($field_name, $extra_cache_ref = null)
1172
+	{
1173
+		echo $this->get_pretty($field_name, $extra_cache_ref);
1174
+	}
1175
+
1176
+
1177
+
1178
+	/**
1179
+	 * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1180
+	 * can be easily used as the value of form input.
1181
+	 *
1182
+	 * @param string $field_name
1183
+	 * @return void
1184
+	 * @throws \EE_Error
1185
+	 */
1186
+	public function f($field_name)
1187
+	{
1188
+		$this->e($field_name, 'form_input');
1189
+	}
1190
+
1191
+
1192
+
1193
+	/**
1194
+	 * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1195
+	 * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1196
+	 * to see what options are available.
1197
+	 * @param string $field_name
1198
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1199
+	 *                                (in cases where the same property may be used for different outputs
1200
+	 *                                - i.e. datetime, money etc.)
1201
+	 * @return mixed
1202
+	 * @throws \EE_Error
1203
+	 */
1204
+	public function get_pretty($field_name, $extra_cache_ref = null)
1205
+	{
1206
+		return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1207
+	}
1208
+
1209
+
1210
+
1211
+	/**
1212
+	 * This simply returns the datetime for the given field name
1213
+	 * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1214
+	 * (and the equivalent e_date, e_time, e_datetime).
1215
+	 *
1216
+	 * @access   protected
1217
+	 * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1218
+	 * @param string   $dt_frmt      valid datetime format used for date
1219
+	 *                               (if '' then we just use the default on the field,
1220
+	 *                               if NULL we use the last-used format)
1221
+	 * @param string   $tm_frmt      Same as above except this is for time format
1222
+	 * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1223
+	 * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1224
+	 * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1225
+	 *                               if field is not a valid dtt field, or void if echoing
1226
+	 * @throws \EE_Error
1227
+	 */
1228
+	protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1229
+	{
1230
+		// clear cached property
1231
+		$this->_clear_cached_property($field_name);
1232
+		//reset format properties because they are used in get()
1233
+		$this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1234
+		$this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1235
+		if ($echo) {
1236
+			$this->e($field_name, $date_or_time);
1237
+			return '';
1238
+		}
1239
+		return $this->get($field_name, $date_or_time);
1240
+	}
1241
+
1242
+
1243
+
1244
+	/**
1245
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1246
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1247
+	 * other echoes the pretty value for dtt)
1248
+	 *
1249
+	 * @param  string $field_name name of model object datetime field holding the value
1250
+	 * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1251
+	 * @return string            datetime value formatted
1252
+	 * @throws \EE_Error
1253
+	 */
1254
+	public function get_date($field_name, $format = '')
1255
+	{
1256
+		return $this->_get_datetime($field_name, $format, null, 'D');
1257
+	}
1258
+
1259
+
1260
+
1261
+	/**
1262
+	 * @param      $field_name
1263
+	 * @param string $format
1264
+	 * @throws \EE_Error
1265
+	 */
1266
+	public function e_date($field_name, $format = '')
1267
+	{
1268
+		$this->_get_datetime($field_name, $format, null, 'D', true);
1269
+	}
1270
+
1271
+
1272
+
1273
+	/**
1274
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1275
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1276
+	 * other echoes the pretty value for dtt)
1277
+	 *
1278
+	 * @param  string $field_name name of model object datetime field holding the value
1279
+	 * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1280
+	 * @return string             datetime value formatted
1281
+	 * @throws \EE_Error
1282
+	 */
1283
+	public function get_time($field_name, $format = '')
1284
+	{
1285
+		return $this->_get_datetime($field_name, null, $format, 'T');
1286
+	}
1287
+
1288
+
1289
+
1290
+	/**
1291
+	 * @param      $field_name
1292
+	 * @param string $format
1293
+	 * @throws \EE_Error
1294
+	 */
1295
+	public function e_time($field_name, $format = '')
1296
+	{
1297
+		$this->_get_datetime($field_name, null, $format, 'T', true);
1298
+	}
1299
+
1300
+
1301
+
1302
+	/**
1303
+	 * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1304
+	 * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1305
+	 * other echoes the pretty value for dtt)
1306
+	 *
1307
+	 * @param  string $field_name name of model object datetime field holding the value
1308
+	 * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1309
+	 * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1310
+	 * @return string             datetime value formatted
1311
+	 * @throws \EE_Error
1312
+	 */
1313
+	public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1314
+	{
1315
+		return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1316
+	}
1317
+
1318
+
1319
+
1320
+	/**
1321
+	 * @param string $field_name
1322
+	 * @param string $dt_frmt
1323
+	 * @param string $tm_frmt
1324
+	 * @throws \EE_Error
1325
+	 */
1326
+	public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1327
+	{
1328
+		$this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1329
+	}
1330
+
1331
+
1332
+
1333
+	/**
1334
+	 * Get the i8ln value for a date using the WordPress @see date_i18n function.
1335
+	 *
1336
+	 * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1337
+	 * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1338
+	 *                           on the object will be used.
1339
+	 * @return string Date and time string in set locale or false if no field exists for the given
1340
+	 * @throws \EE_Error
1341
+	 *                           field name.
1342
+	 */
1343
+	public function get_i18n_datetime($field_name, $format = '')
1344
+	{
1345
+		$format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1346
+		return date_i18n(
1347
+			$format,
1348
+			EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1349
+		);
1350
+	}
1351
+
1352
+
1353
+
1354
+	/**
1355
+	 * This method validates whether the given field name is a valid field on the model object as well as it is of a
1356
+	 * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1357
+	 * thrown.
1358
+	 *
1359
+	 * @param  string $field_name The field name being checked
1360
+	 * @throws EE_Error
1361
+	 * @return EE_Datetime_Field
1362
+	 */
1363
+	protected function _get_dtt_field_settings($field_name)
1364
+	{
1365
+		$field = $this->get_model()->field_settings_for($field_name);
1366
+		//check if field is dtt
1367
+		if ($field instanceof EE_Datetime_Field) {
1368
+			return $field;
1369
+		} else {
1370
+			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',
1371
+				'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1372
+		}
1373
+	}
1374
+
1375
+
1376
+
1377
+
1378
+	/**
1379
+	 * NOTE ABOUT BELOW:
1380
+	 * These convenience date and time setters are for setting date and time independently.  In other words you might
1381
+	 * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1382
+	 * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1383
+	 * method and make sure you send the entire datetime value for setting.
1384
+	 */
1385
+	/**
1386
+	 * sets the time on a datetime property
1387
+	 *
1388
+	 * @access protected
1389
+	 * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1390
+	 * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1391
+	 * @throws \EE_Error
1392
+	 */
1393
+	protected function _set_time_for($time, $fieldname)
1394
+	{
1395
+		$this->_set_date_time('T', $time, $fieldname);
1396
+	}
1397
+
1398
+
1399
+
1400
+	/**
1401
+	 * sets the date on a datetime property
1402
+	 *
1403
+	 * @access protected
1404
+	 * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1405
+	 * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1406
+	 * @throws \EE_Error
1407
+	 */
1408
+	protected function _set_date_for($date, $fieldname)
1409
+	{
1410
+		$this->_set_date_time('D', $date, $fieldname);
1411
+	}
1412
+
1413
+
1414
+
1415
+	/**
1416
+	 * This takes care of setting a date or time independently on a given model object property. This method also
1417
+	 * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1418
+	 *
1419
+	 * @access protected
1420
+	 * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1421
+	 * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1422
+	 * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1423
+	 *                                        EE_Datetime_Field property)
1424
+	 * @throws \EE_Error
1425
+	 */
1426
+	protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1427
+	{
1428
+		$field = $this->_get_dtt_field_settings($fieldname);
1429
+		$field->set_timezone($this->_timezone);
1430
+		$field->set_date_format($this->_dt_frmt);
1431
+		$field->set_time_format($this->_tm_frmt);
1432
+		switch ($what) {
1433
+			case 'T' :
1434
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1435
+					$datetime_value,
1436
+					$this->_fields[$fieldname]
1437
+				);
1438
+				break;
1439
+			case 'D' :
1440
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1441
+					$datetime_value,
1442
+					$this->_fields[$fieldname]
1443
+				);
1444
+				break;
1445
+			case 'B' :
1446
+				$this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1447
+				break;
1448
+		}
1449
+		$this->_clear_cached_property($fieldname);
1450
+	}
1451
+
1452
+
1453
+
1454
+	/**
1455
+	 * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1456
+	 * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1457
+	 * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1458
+	 * that could lead to some unexpected results!
1459
+	 *
1460
+	 * @access public
1461
+	 * @param string               $field_name This is the name of the field on the object that contains the date/time
1462
+	 *                                         value being returned.
1463
+	 * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1464
+	 * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1465
+	 * @param string               $prepend    You can include something to prepend on the timestamp
1466
+	 * @param string               $append     You can include something to append on the timestamp
1467
+	 * @throws EE_Error
1468
+	 * @return string timestamp
1469
+	 */
1470
+	public function display_in_my_timezone(
1471
+		$field_name,
1472
+		$callback = 'get_datetime',
1473
+		$args = null,
1474
+		$prepend = '',
1475
+		$append = ''
1476
+	) {
1477
+		$timezone = EEH_DTT_Helper::get_timezone();
1478
+		if ($timezone === $this->_timezone) {
1479
+			return '';
1480
+		}
1481
+		$original_timezone = $this->_timezone;
1482
+		$this->set_timezone($timezone);
1483
+		$fn = (array)$field_name;
1484
+		$args = array_merge($fn, (array)$args);
1485
+		if ( ! method_exists($this, $callback)) {
1486
+			throw new EE_Error(
1487
+				sprintf(
1488
+					__(
1489
+						'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1490
+						'event_espresso'
1491
+					),
1492
+					$callback
1493
+				)
1494
+			);
1495
+		}
1496
+		$args = (array)$args;
1497
+		$return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1498
+		$this->set_timezone($original_timezone);
1499
+		return $return;
1500
+	}
1501
+
1502
+
1503
+
1504
+	/**
1505
+	 * Deletes this model object.
1506
+	 * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1507
+	 * override
1508
+	 * `EE_Base_Class::_delete` NOT this class.
1509
+	 *
1510
+	 * @return boolean | int
1511
+	 * @throws \EE_Error
1512
+	 */
1513
+	public function delete()
1514
+	{
1515
+		/**
1516
+		 * Called just before the `EE_Base_Class::_delete` method call.
1517
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1518
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1519
+		 * soft deletes (trash) the object and does not permanently delete it.
1520
+		 *
1521
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1522
+		 */
1523
+		do_action('AHEE__EE_Base_Class__delete__before', $this);
1524
+		$result = $this->_delete();
1525
+		/**
1526
+		 * Called just after the `EE_Base_Class::_delete` method call.
1527
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1528
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1529
+		 * soft deletes (trash) the object and does not permanently delete it.
1530
+		 *
1531
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1532
+		 * @param boolean       $result
1533
+		 */
1534
+		do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1535
+		return $result;
1536
+	}
1537
+
1538
+
1539
+
1540
+	/**
1541
+	 * Calls the specific delete method for the instantiated class.
1542
+	 * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1543
+	 * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1544
+	 * `EE_Base_Class::delete`
1545
+	 *
1546
+	 * @return bool|int
1547
+	 * @throws \EE_Error
1548
+	 */
1549
+	protected function _delete()
1550
+	{
1551
+		return $this->delete_permanently();
1552
+	}
1553
+
1554
+
1555
+
1556
+	/**
1557
+	 * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1558
+	 * error)
1559
+	 *
1560
+	 * @return bool | int
1561
+	 * @throws \EE_Error
1562
+	 */
1563
+	public function delete_permanently()
1564
+	{
1565
+		/**
1566
+		 * Called just before HARD deleting a model object
1567
+		 *
1568
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1569
+		 */
1570
+		do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1571
+		$model = $this->get_model();
1572
+		$result = $model->delete_permanently_by_ID($this->ID());
1573
+		$this->refresh_cache_of_related_objects();
1574
+		/**
1575
+		 * Called just after HARD deleting a model object
1576
+		 *
1577
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1578
+		 * @param boolean       $result
1579
+		 */
1580
+		do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1581
+		return $result;
1582
+	}
1583
+
1584
+
1585
+
1586
+	/**
1587
+	 * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1588
+	 * related model objects
1589
+	 *
1590
+	 * @throws \EE_Error
1591
+	 */
1592
+	public function refresh_cache_of_related_objects()
1593
+	{
1594
+		$model = $this->get_model();
1595
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1596
+			if ( ! empty($this->_model_relations[$relation_name])) {
1597
+				$related_objects = $this->_model_relations[$relation_name];
1598
+				if ($relation_obj instanceof EE_Belongs_To_Relation) {
1599
+					//this relation only stores a single model object, not an array
1600
+					//but let's make it consistent
1601
+					$related_objects = array($related_objects);
1602
+				}
1603
+				foreach ($related_objects as $related_object) {
1604
+					//only refresh their cache if they're in memory
1605
+					if ($related_object instanceof EE_Base_Class) {
1606
+						$related_object->clear_cache($model->get_this_model_name(), $this);
1607
+					}
1608
+				}
1609
+			}
1610
+		}
1611
+	}
1612
+
1613
+
1614
+
1615
+	/**
1616
+	 *        Saves this object to the database. An array may be supplied to set some values on this
1617
+	 * object just before saving.
1618
+	 *
1619
+	 * @access public
1620
+	 * @param array $set_cols_n_values keys are field names, values are their new values,
1621
+	 *                                 if provided during the save() method (often client code will change the fields'
1622
+	 *                                 values before calling save)
1623
+	 * @throws \EE_Error
1624
+	 * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1625
+	 *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1626
+	 */
1627
+	public function save($set_cols_n_values = array())
1628
+	{
1629
+		$model = $this->get_model();
1630
+		/**
1631
+		 * Filters the fields we're about to save on the model object
1632
+		 *
1633
+		 * @param array         $set_cols_n_values
1634
+		 * @param EE_Base_Class $model_object
1635
+		 */
1636
+		$set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1637
+			$this);
1638
+		//set attributes as provided in $set_cols_n_values
1639
+		foreach ($set_cols_n_values as $column => $value) {
1640
+			$this->set($column, $value);
1641
+		}
1642
+		// no changes ? then don't do anything
1643
+		if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1644
+			return 0;
1645
+		}
1646
+		/**
1647
+		 * Saving a model object.
1648
+		 * Before we perform a save, this action is fired.
1649
+		 *
1650
+		 * @param EE_Base_Class $model_object the model object about to be saved.
1651
+		 */
1652
+		do_action('AHEE__EE_Base_Class__save__begin', $this);
1653
+		if ( ! $this->allow_persist()) {
1654
+			return 0;
1655
+		}
1656
+		//now get current attribute values
1657
+		$save_cols_n_values = $this->_fields;
1658
+		//if the object already has an ID, update it. Otherwise, insert it
1659
+		//also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1660
+		$old_assumption_concerning_value_preparation = $model
1661
+															->get_assumption_concerning_values_already_prepared_by_model_object();
1662
+		$model->assume_values_already_prepared_by_model_object(true);
1663
+		//does this model have an autoincrement PK?
1664
+		if ($model->has_primary_key_field()) {
1665
+			if ($model->get_primary_key_field()->is_auto_increment()) {
1666
+				//ok check if it's set, if so: update; if not, insert
1667
+				if ( ! empty($save_cols_n_values[$model->primary_key_name()])) {
1668
+					$results = $model->update_by_ID($save_cols_n_values, $this->ID());
1669
+				} else {
1670
+					unset($save_cols_n_values[$model->primary_key_name()]);
1671
+					$results = $model->insert($save_cols_n_values);
1672
+					if ($results) {
1673
+						//if successful, set the primary key
1674
+						//but don't use the normal SET method, because it will check if
1675
+						//an item with the same ID exists in the mapper & db, then
1676
+						//will find it in the db (because we just added it) and THAT object
1677
+						//will get added to the mapper before we can add this one!
1678
+						//but if we just avoid using the SET method, all that headache can be avoided
1679
+						$pk_field_name = $model->primary_key_name();
1680
+						$this->_fields[$pk_field_name] = $results;
1681
+						$this->_clear_cached_property($pk_field_name);
1682
+						$model->add_to_entity_map($this);
1683
+						$this->_update_cached_related_model_objs_fks();
1684
+					}
1685
+				}
1686
+			} else {//PK is NOT auto-increment
1687
+				//so check if one like it already exists in the db
1688
+				if ($model->exists_by_ID($this->ID())) {
1689
+					if (WP_DEBUG && ! $this->in_entity_map()) {
1690
+						throw new EE_Error(
1691
+							sprintf(
1692
+								__('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',
1693
+									'event_espresso'),
1694
+								get_class($this),
1695
+								get_class($model) . '::instance()->add_to_entity_map()',
1696
+								get_class($model) . '::instance()->get_one_by_ID()',
1697
+								'<br />'
1698
+							)
1699
+						);
1700
+					}
1701
+					$results = $model->update_by_ID($save_cols_n_values, $this->ID());
1702
+				} else {
1703
+					$results = $model->insert($save_cols_n_values);
1704
+					$this->_update_cached_related_model_objs_fks();
1705
+				}
1706
+			}
1707
+		} else {//there is NO primary key
1708
+			$already_in_db = false;
1709
+			foreach ($model->unique_indexes() as $index) {
1710
+				$uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1711
+				if ($model->exists(array($uniqueness_where_params))) {
1712
+					$already_in_db = true;
1713
+				}
1714
+			}
1715
+			if ($already_in_db) {
1716
+				$combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1717
+					$model->get_combined_primary_key_fields());
1718
+				$results = $model->update($save_cols_n_values, $combined_pk_fields_n_values);
1719
+			} else {
1720
+				$results = $model->insert($save_cols_n_values);
1721
+			}
1722
+		}
1723
+		//restore the old assumption about values being prepared by the model object
1724
+		$model
1725
+			 ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1726
+		/**
1727
+		 * After saving the model object this action is called
1728
+		 *
1729
+		 * @param EE_Base_Class $model_object which was just saved
1730
+		 * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1731
+		 *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1732
+		 */
1733
+		do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1734
+		$this->_has_changes = false;
1735
+		return $results;
1736
+	}
1737
+
1738
+
1739
+
1740
+	/**
1741
+	 * Updates the foreign key on related models objects pointing to this to have this model object's ID
1742
+	 * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1743
+	 * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1744
+	 * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1745
+	 * 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
1746
+	 * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1747
+	 * or not they exist in the DB (if they do, their DB records will be automatically updated)
1748
+	 *
1749
+	 * @return void
1750
+	 * @throws \EE_Error
1751
+	 */
1752
+	protected function _update_cached_related_model_objs_fks()
1753
+	{
1754
+		$model = $this->get_model();
1755
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1756
+			if ($relation_obj instanceof EE_Has_Many_Relation) {
1757
+				foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1758
+					$fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1759
+						$model->get_this_model_name()
1760
+					);
1761
+					$related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1762
+					if ($related_model_obj_in_cache->ID()) {
1763
+						$related_model_obj_in_cache->save();
1764
+					}
1765
+				}
1766
+			}
1767
+		}
1768
+	}
1769
+
1770
+
1771
+
1772
+	/**
1773
+	 * Saves this model object and its NEW cached relations to the database.
1774
+	 * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1775
+	 * In order for that to work, we would need to mark model objects as dirty/clean...
1776
+	 * because otherwise, there's a potential for infinite looping of saving
1777
+	 * Saves the cached related model objects, and ensures the relation between them
1778
+	 * and this object and properly setup
1779
+	 *
1780
+	 * @return int ID of new model object on save; 0 on failure+
1781
+	 * @throws \EE_Error
1782
+	 */
1783
+	public function save_new_cached_related_model_objs()
1784
+	{
1785
+		//make sure this has been saved
1786
+		if ( ! $this->ID()) {
1787
+			$id = $this->save();
1788
+		} else {
1789
+			$id = $this->ID();
1790
+		}
1791
+		//now save all the NEW cached model objects  (ie they don't exist in the DB)
1792
+		foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1793
+			if ($this->_model_relations[$relationName]) {
1794
+				//is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1795
+				//or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1796
+				if ($relationObj instanceof EE_Belongs_To_Relation) {
1797
+					//add a relation to that relation type (which saves the appropriate thing in the process)
1798
+					//but ONLY if it DOES NOT exist in the DB
1799
+					/* @var $related_model_obj EE_Base_Class */
1800
+					$related_model_obj = $this->_model_relations[$relationName];
1801
+					//					if( ! $related_model_obj->ID()){
1802
+					$this->_add_relation_to($related_model_obj, $relationName);
1803
+					$related_model_obj->save_new_cached_related_model_objs();
1804
+					//					}
1805
+				} else {
1806
+					foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1807
+						//add a relation to that relation type (which saves the appropriate thing in the process)
1808
+						//but ONLY if it DOES NOT exist in the DB
1809
+						//						if( ! $related_model_obj->ID()){
1810
+						$this->_add_relation_to($related_model_obj, $relationName);
1811
+						$related_model_obj->save_new_cached_related_model_objs();
1812
+						//						}
1813
+					}
1814
+				}
1815
+			}
1816
+		}
1817
+		return $id;
1818
+	}
1819
+
1820
+
1821
+
1822
+	/**
1823
+	 * for getting a model while instantiated.
1824
+	 *
1825
+	 * @return \EEM_Base | \EEM_CPT_Base
1826
+	 */
1827
+	public function get_model()
1828
+	{
1829
+		if( ! $this->_model){
1830
+			$modelName = self::_get_model_classname(get_class($this));
1831
+			$this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
1832
+		} else {
1833
+			$this->_model->set_timezone($this->_timezone);
1834
+		}
1835
+
1836
+		return $this->_model;
1837
+	}
1838
+
1839
+
1840
+
1841
+	/**
1842
+	 * @param $props_n_values
1843
+	 * @param $classname
1844
+	 * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1845
+	 * @throws \EE_Error
1846
+	 */
1847
+	protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1848
+	{
1849
+		//TODO: will not work for Term_Relationships because they have no PK!
1850
+		$primary_id_ref = self::_get_primary_key_name($classname);
1851
+		if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1852
+			$id = $props_n_values[$primary_id_ref];
1853
+			return self::_get_model($classname)->get_from_entity_map($id);
1854
+		}
1855
+		return false;
1856
+	}
1857
+
1858
+
1859
+
1860
+	/**
1861
+	 * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1862
+	 * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1863
+	 * 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
1864
+	 * we return false.
1865
+	 *
1866
+	 * @param  array  $props_n_values   incoming array of properties and their values
1867
+	 * @param  string $classname        the classname of the child class
1868
+	 * @param null    $timezone
1869
+	 * @param array   $date_formats     incoming date_formats in an array where the first value is the
1870
+	 *                                  date_format and the second value is the time format
1871
+	 * @return mixed (EE_Base_Class|bool)
1872
+	 * @throws \EE_Error
1873
+	 */
1874
+	protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1875
+	{
1876
+		$existing = null;
1877
+		$model = self::_get_model($classname, $timezone);
1878
+		if ($model->has_primary_key_field()) {
1879
+			$primary_id_ref = self::_get_primary_key_name($classname);
1880
+			if (array_key_exists($primary_id_ref, $props_n_values)
1881
+				&& ! empty($props_n_values[$primary_id_ref])
1882
+			) {
1883
+				$existing = $model->get_one_by_ID(
1884
+					$props_n_values[$primary_id_ref]
1885
+				);
1886
+			}
1887
+		} elseif ($model->has_all_combined_primary_key_fields($props_n_values)) {
1888
+			//no primary key on this model, but there's still a matching item in the DB
1889
+			$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1890
+				self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1891
+			);
1892
+		}
1893
+		if ($existing) {
1894
+			//set date formats if present before setting values
1895
+			if ( ! empty($date_formats) && is_array($date_formats)) {
1896
+				$existing->set_date_format($date_formats[0]);
1897
+				$existing->set_time_format($date_formats[1]);
1898
+			} else {
1899
+				//set default formats for date and time
1900
+				$existing->set_date_format(get_option('date_format'));
1901
+				$existing->set_time_format(get_option('time_format'));
1902
+			}
1903
+			foreach ($props_n_values as $property => $field_value) {
1904
+				$existing->set($property, $field_value);
1905
+			}
1906
+			return $existing;
1907
+		} else {
1908
+			return false;
1909
+		}
1910
+	}
1911
+
1912
+
1913
+
1914
+	/**
1915
+	 * Gets the EEM_*_Model for this class
1916
+	 *
1917
+	 * @access public now, as this is more convenient
1918
+	 * @param      $classname
1919
+	 * @param null $timezone
1920
+	 * @throws EE_Error
1921
+	 * @return EEM_Base
1922
+	 */
1923
+	protected static function _get_model($classname, $timezone = null)
1924
+	{
1925
+		//find model for this class
1926
+		if ( ! $classname) {
1927
+			throw new EE_Error(
1928
+				sprintf(
1929
+					__(
1930
+						"What were you thinking calling _get_model(%s)?? You need to specify the class name",
1931
+						"event_espresso"
1932
+					),
1933
+					$classname
1934
+				)
1935
+			);
1936
+		}
1937
+		$modelName = self::_get_model_classname($classname);
1938
+		return self::_get_model_instance_with_name($modelName, $timezone);
1939
+	}
1940
+
1941
+
1942
+
1943
+	/**
1944
+	 * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1945
+	 *
1946
+	 * @param string $model_classname
1947
+	 * @param null   $timezone
1948
+	 * @return EEM_Base
1949
+	 */
1950
+	protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1951
+	{
1952
+		$model_classname = str_replace('EEM_', '', $model_classname);
1953
+		$model = EE_Registry::instance()->load_model($model_classname);
1954
+		$model->set_timezone($timezone);
1955
+		return $model;
1956
+	}
1957
+
1958
+
1959
+
1960
+	/**
1961
+	 * If a model name is provided (eg Registration), gets the model classname for that model.
1962
+	 * Also works if a model class's classname is provided (eg EE_Registration).
1963
+	 *
1964
+	 * @param null $model_name
1965
+	 * @return string like EEM_Attendee
1966
+	 */
1967
+	private static function _get_model_classname($model_name = null)
1968
+	{
1969
+		if (strpos($model_name, "EE_") === 0) {
1970
+			$model_classname = str_replace("EE_", "EEM_", $model_name);
1971
+		} else {
1972
+			$model_classname = "EEM_" . $model_name;
1973
+		}
1974
+		return $model_classname;
1975
+	}
1976
+
1977
+
1978
+
1979
+	/**
1980
+	 * returns the name of the primary key attribute
1981
+	 *
1982
+	 * @param null $classname
1983
+	 * @throws EE_Error
1984
+	 * @return string
1985
+	 */
1986
+	protected static function _get_primary_key_name($classname = null)
1987
+	{
1988
+		if ( ! $classname) {
1989
+			throw new EE_Error(
1990
+				sprintf(
1991
+					__("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1992
+					$classname
1993
+				)
1994
+			);
1995
+		}
1996
+		return self::_get_model($classname)->get_primary_key_field()->get_name();
1997
+	}
1998
+
1999
+
2000
+
2001
+	/**
2002
+	 * Gets the value of the primary key.
2003
+	 * If the object hasn't yet been saved, it should be whatever the model field's default was
2004
+	 * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
2005
+	 * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
2006
+	 *
2007
+	 * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
2008
+	 * @throws \EE_Error
2009
+	 */
2010
+	public function ID()
2011
+	{
2012
+		$model = $this->get_model();
2013
+		//now that we know the name of the variable, use a variable variable to get its value and return its
2014
+		if ($model->has_primary_key_field()) {
2015
+			return $this->_fields[$model->primary_key_name()];
2016
+		} else {
2017
+			return $model->get_index_primary_key_string($this->_fields);
2018
+		}
2019
+	}
2020
+
2021
+
2022
+
2023
+	/**
2024
+	 * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
2025
+	 * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
2026
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
2027
+	 *
2028
+	 * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
2029
+	 * @param string $relationName                     eg 'Events','Question',etc.
2030
+	 *                                                 an attendee to a group, you also want to specify which role they
2031
+	 *                                                 will have in that group. So you would use this parameter to
2032
+	 *                                                 specify array('role-column-name'=>'role-id')
2033
+	 * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
2034
+	 *                                                 allow you to further constrict the relation to being added.
2035
+	 *                                                 However, keep in mind that the columns (keys) given must match a
2036
+	 *                                                 column on the JOIN table and currently only the HABTM models
2037
+	 *                                                 accept these additional conditions.  Also remember that if an
2038
+	 *                                                 exact match isn't found for these extra cols/val pairs, then a
2039
+	 *                                                 NEW row is created in the join table.
2040
+	 * @param null   $cache_id
2041
+	 * @throws EE_Error
2042
+	 * @return EE_Base_Class the object the relation was added to
2043
+	 */
2044
+	public function _add_relation_to(
2045
+		$otherObjectModelObjectOrID,
2046
+		$relationName,
2047
+		$extra_join_model_fields_n_values = array(),
2048
+		$cache_id = null
2049
+	) {
2050
+		$model = $this->get_model();
2051
+		//if this thing exists in the DB, save the relation to the DB
2052
+		if ($this->ID()) {
2053
+			$otherObject = $model
2054
+								->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2055
+									$extra_join_model_fields_n_values);
2056
+			//clear cache so future get_many_related and get_first_related() return new results.
2057
+			$this->clear_cache($relationName, $otherObject, true);
2058
+			if ($otherObject instanceof EE_Base_Class) {
2059
+				$otherObject->clear_cache($model->get_this_model_name(), $this);
2060
+			}
2061
+		} else {
2062
+			//this thing doesn't exist in the DB,  so just cache it
2063
+			if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2064
+				throw new EE_Error(sprintf(
2065
+					__('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',
2066
+						'event_espresso'),
2067
+					$otherObjectModelObjectOrID,
2068
+					get_class($this)
2069
+				));
2070
+			} else {
2071
+				$otherObject = $otherObjectModelObjectOrID;
2072
+			}
2073
+			$this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2074
+		}
2075
+		if ($otherObject instanceof EE_Base_Class) {
2076
+			//fix the reciprocal relation too
2077
+			if ($otherObject->ID()) {
2078
+				//its saved so assumed relations exist in the DB, so we can just
2079
+				//clear the cache so future queries use the updated info in the DB
2080
+				$otherObject->clear_cache($model->get_this_model_name(), null, true);
2081
+			} else {
2082
+				//it's not saved, so it caches relations like this
2083
+				$otherObject->cache($model->get_this_model_name(), $this);
2084
+			}
2085
+		}
2086
+		return $otherObject;
2087
+	}
2088
+
2089
+
2090
+
2091
+	/**
2092
+	 * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2093
+	 * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2094
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2095
+	 * from the cache
2096
+	 *
2097
+	 * @param mixed  $otherObjectModelObjectOrID
2098
+	 *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2099
+	 *                to the DB yet
2100
+	 * @param string $relationName
2101
+	 * @param array  $where_query
2102
+	 *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2103
+	 *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2104
+	 *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2105
+	 *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2106
+	 *                created in the join table.
2107
+	 * @return EE_Base_Class the relation was removed from
2108
+	 * @throws \EE_Error
2109
+	 */
2110
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2111
+	{
2112
+		if ($this->ID()) {
2113
+			//if this exists in the DB, save the relation change to the DB too
2114
+			$otherObject = $this->get_model()
2115
+								->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2116
+									$where_query);
2117
+			$this->clear_cache($relationName, $otherObject);
2118
+		} else {
2119
+			//this doesn't exist in the DB, just remove it from the cache
2120
+			$otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2121
+		}
2122
+		if ($otherObject instanceof EE_Base_Class) {
2123
+			$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2124
+		}
2125
+		return $otherObject;
2126
+	}
2127
+
2128
+
2129
+
2130
+	/**
2131
+	 * Removes ALL the related things for the $relationName.
2132
+	 *
2133
+	 * @param string $relationName
2134
+	 * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2135
+	 * @return EE_Base_Class
2136
+	 * @throws \EE_Error
2137
+	 */
2138
+	public function _remove_relations($relationName, $where_query_params = array())
2139
+	{
2140
+		if ($this->ID()) {
2141
+			//if this exists in the DB, save the relation change to the DB too
2142
+			$otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2143
+			$this->clear_cache($relationName, null, true);
2144
+		} else {
2145
+			//this doesn't exist in the DB, just remove it from the cache
2146
+			$otherObjects = $this->clear_cache($relationName, null, true);
2147
+		}
2148
+		if (is_array($otherObjects)) {
2149
+			foreach ($otherObjects as $otherObject) {
2150
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2151
+			}
2152
+		}
2153
+		return $otherObjects;
2154
+	}
2155
+
2156
+
2157
+
2158
+	/**
2159
+	 * Gets all the related model objects of the specified type. Eg, if the current class if
2160
+	 * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2161
+	 * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2162
+	 * because we want to get even deleted items etc.
2163
+	 *
2164
+	 * @param string $relationName key in the model's _model_relations array
2165
+	 * @param array  $query_params like EEM_Base::get_all
2166
+	 * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2167
+	 * @throws \EE_Error
2168
+	 *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2169
+	 *                             you want IDs
2170
+	 */
2171
+	public function get_many_related($relationName, $query_params = array())
2172
+	{
2173
+		if ($this->ID()) {
2174
+			//this exists in the DB, so get the related things from either the cache or the DB
2175
+			//if there are query parameters, forget about caching the related model objects.
2176
+			if ($query_params) {
2177
+				$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2178
+			} else {
2179
+				//did we already cache the result of this query?
2180
+				$cached_results = $this->get_all_from_cache($relationName);
2181
+				if ( ! $cached_results) {
2182
+					$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2183
+					//if no query parameters were passed, then we got all the related model objects
2184
+					//for that relation. We can cache them then.
2185
+					foreach ($related_model_objects as $related_model_object) {
2186
+						$this->cache($relationName, $related_model_object);
2187
+					}
2188
+				} else {
2189
+					$related_model_objects = $cached_results;
2190
+				}
2191
+			}
2192
+		} else {
2193
+			//this doesn't exist in the DB, so just get the related things from the cache
2194
+			$related_model_objects = $this->get_all_from_cache($relationName);
2195
+		}
2196
+		return $related_model_objects;
2197
+	}
2198
+
2199
+
2200
+
2201
+	/**
2202
+	 * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2203
+	 * unless otherwise specified in the $query_params
2204
+	 *
2205
+	 * @param string $relation_name  model_name like 'Event', or 'Registration'
2206
+	 * @param array  $query_params   like EEM_Base::get_all's
2207
+	 * @param string $field_to_count name of field to count by. By default, uses primary key
2208
+	 * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2209
+	 *                               that by the setting $distinct to TRUE;
2210
+	 * @return int
2211
+	 */
2212
+	public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2213
+	{
2214
+		return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2215
+	}
2216
+
2217
+
2218
+
2219
+	/**
2220
+	 * Instead of getting the related model objects, simply sums up the values of the specified field.
2221
+	 * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2222
+	 *
2223
+	 * @param string $relation_name model_name like 'Event', or 'Registration'
2224
+	 * @param array  $query_params  like EEM_Base::get_all's
2225
+	 * @param string $field_to_sum  name of field to count by.
2226
+	 *                              By default, uses primary key (which doesn't make much sense, so you should probably
2227
+	 *                              change it)
2228
+	 * @return int
2229
+	 */
2230
+	public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2231
+	{
2232
+		return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2233
+	}
2234
+
2235
+
2236
+
2237
+	/**
2238
+	 * Gets the first (ie, one) related model object of the specified type.
2239
+	 *
2240
+	 * @param string $relationName key in the model's _model_relations array
2241
+	 * @param array  $query_params like EEM_Base::get_all
2242
+	 * @return EE_Base_Class (not an array, a single object)
2243
+	 * @throws \EE_Error
2244
+	 */
2245
+	public function get_first_related($relationName, $query_params = array())
2246
+	{
2247
+		$model = $this->get_model();
2248
+		if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2249
+			//if they've provided some query parameters, don't bother trying to cache the result
2250
+			//also make sure we're not caching the result of get_first_related
2251
+			//on a relation which should have an array of objects (because the cache might have an array of objects)
2252
+			if ($query_params
2253
+				|| ! $model->related_settings_for($relationName)
2254
+					 instanceof
2255
+					 EE_Belongs_To_Relation
2256
+			) {
2257
+				$related_model_object = $model->get_first_related($this, $relationName, $query_params);
2258
+			} else {
2259
+				//first, check if we've already cached the result of this query
2260
+				$cached_result = $this->get_one_from_cache($relationName);
2261
+				if ( ! $cached_result) {
2262
+					$related_model_object = $model->get_first_related($this, $relationName, $query_params);
2263
+					$this->cache($relationName, $related_model_object);
2264
+				} else {
2265
+					$related_model_object = $cached_result;
2266
+				}
2267
+			}
2268
+		} else {
2269
+			$related_model_object = null;
2270
+			//this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2271
+			if ($model->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2272
+				$related_model_object = $model->get_first_related($this, $relationName, $query_params);
2273
+			}
2274
+			//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
2275
+			if ( ! $related_model_object) {
2276
+				$related_model_object = $this->get_one_from_cache($relationName);
2277
+			}
2278
+		}
2279
+		return $related_model_object;
2280
+	}
2281
+
2282
+
2283
+
2284
+	/**
2285
+	 * Does a delete on all related objects of type $relationName and removes
2286
+	 * the current model object's relation to them. If they can't be deleted (because
2287
+	 * of blocking related model objects) does nothing. If the related model objects are
2288
+	 * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2289
+	 * If this model object doesn't exist yet in the DB, just removes its related things
2290
+	 *
2291
+	 * @param string $relationName
2292
+	 * @param array  $query_params like EEM_Base::get_all's
2293
+	 * @return int how many deleted
2294
+	 * @throws \EE_Error
2295
+	 */
2296
+	public function delete_related($relationName, $query_params = array())
2297
+	{
2298
+		if ($this->ID()) {
2299
+			$count = $this->get_model()->delete_related($this, $relationName, $query_params);
2300
+		} else {
2301
+			$count = count($this->get_all_from_cache($relationName));
2302
+			$this->clear_cache($relationName, null, true);
2303
+		}
2304
+		return $count;
2305
+	}
2306
+
2307
+
2308
+
2309
+	/**
2310
+	 * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2311
+	 * the current model object's relation to them. If they can't be deleted (because
2312
+	 * of blocking related model objects) just does a soft delete on it instead, if possible.
2313
+	 * If the related thing isn't a soft-deletable model object, this function is identical
2314
+	 * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2315
+	 *
2316
+	 * @param string $relationName
2317
+	 * @param array  $query_params like EEM_Base::get_all's
2318
+	 * @return int how many deleted (including those soft deleted)
2319
+	 * @throws \EE_Error
2320
+	 */
2321
+	public function delete_related_permanently($relationName, $query_params = array())
2322
+	{
2323
+		if ($this->ID()) {
2324
+			$count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2325
+		} else {
2326
+			$count = count($this->get_all_from_cache($relationName));
2327
+		}
2328
+		$this->clear_cache($relationName, null, true);
2329
+		return $count;
2330
+	}
2331
+
2332
+
2333
+
2334
+	/**
2335
+	 * is_set
2336
+	 * Just a simple utility function children can use for checking if property exists
2337
+	 *
2338
+	 * @access  public
2339
+	 * @param  string $field_name property to check
2340
+	 * @return bool                              TRUE if existing,FALSE if not.
2341
+	 */
2342
+	public function is_set($field_name)
2343
+	{
2344
+		return isset($this->_fields[$field_name]);
2345
+	}
2346
+
2347
+
2348
+
2349
+	/**
2350
+	 * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2351
+	 * EE_Error exception if they don't
2352
+	 *
2353
+	 * @param  mixed (string|array) $properties properties to check
2354
+	 * @throws EE_Error
2355
+	 * @return bool                              TRUE if existing, throw EE_Error if not.
2356
+	 */
2357
+	protected function _property_exists($properties)
2358
+	{
2359
+		foreach ((array)$properties as $property_name) {
2360
+			//first make sure this property exists
2361
+			if ( ! $this->_fields[$property_name]) {
2362
+				throw new EE_Error(
2363
+					sprintf(
2364
+						__(
2365
+							'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2366
+							'event_espresso'
2367
+						),
2368
+						$property_name
2369
+					)
2370
+				);
2371
+			}
2372
+		}
2373
+		return true;
2374
+	}
2375
+
2376
+
2377
+
2378
+	/**
2379
+	 * This simply returns an array of model fields for this object
2380
+	 *
2381
+	 * @return array
2382
+	 * @throws \EE_Error
2383
+	 */
2384
+	public function model_field_array()
2385
+	{
2386
+		$fields = $this->get_model()->field_settings(false);
2387
+		$properties = array();
2388
+		//remove prepended underscore
2389
+		foreach ($fields as $field_name => $settings) {
2390
+			$properties[$field_name] = $this->get($field_name);
2391
+		}
2392
+		return $properties;
2393
+	}
2394
+
2395
+
2396
+
2397
+	/**
2398
+	 * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2399
+	 * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2400
+	 * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2401
+	 * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2402
+	 * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2403
+	 * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2404
+	 * was called, and an array of the original arguments passed to the function. Whatever their callback function
2405
+	 * returns will be returned by this function. Example: in functions.php (or in a plugin):
2406
+	 * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2407
+	 * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2408
+	 * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2409
+	 *        return $previousReturnValue.$returnString;
2410
+	 * }
2411
+	 * require('EE_Answer.class.php');
2412
+	 * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2413
+	 * echo $answer->my_callback('monkeys',100);
2414
+	 * //will output "you called my_callback! and passed args:monkeys,100"
2415
+	 *
2416
+	 * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2417
+	 * @param array  $args       array of original arguments passed to the function
2418
+	 * @throws EE_Error
2419
+	 * @return mixed whatever the plugin which calls add_filter decides
2420
+	 */
2421
+	public function __call($methodName, $args)
2422
+	{
2423
+		$className = get_class($this);
2424
+		$tagName = "FHEE__{$className}__{$methodName}";
2425
+		if ( ! has_filter($tagName)) {
2426
+			throw new EE_Error(
2427
+				sprintf(
2428
+					__(
2429
+						"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;}",
2430
+						"event_espresso"
2431
+					),
2432
+					$methodName,
2433
+					$className,
2434
+					$tagName
2435
+				)
2436
+			);
2437
+		}
2438
+		return apply_filters($tagName, null, $this, $args);
2439
+	}
2440
+
2441
+
2442
+
2443
+	/**
2444
+	 * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2445
+	 * A $previous_value can be specified in case there are many meta rows with the same key
2446
+	 *
2447
+	 * @param string $meta_key
2448
+	 * @param mixed  $meta_value
2449
+	 * @param mixed  $previous_value
2450
+	 * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2451
+	 * @throws \EE_Error
2452
+	 * NOTE: if the values haven't changed, returns 0
2453
+	 */
2454
+	public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2455
+	{
2456
+		$query_params = array(
2457
+			array(
2458
+				'EXM_key'  => $meta_key,
2459
+				'OBJ_ID'   => $this->ID(),
2460
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2461
+			),
2462
+		);
2463
+		if ($previous_value !== null) {
2464
+			$query_params[0]['EXM_value'] = $meta_value;
2465
+		}
2466
+		$existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2467
+		if ( ! $existing_rows_like_that) {
2468
+			return $this->add_extra_meta($meta_key, $meta_value);
2469
+		}
2470
+		foreach ($existing_rows_like_that as $existing_row) {
2471
+			$existing_row->save(array('EXM_value' => $meta_value));
2472
+		}
2473
+		return count($existing_rows_like_that);
2474
+	}
2475
+
2476
+
2477
+
2478
+	/**
2479
+	 * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2480
+	 * no other extra meta for this model object have the same key. Returns TRUE if the
2481
+	 * extra meta row was entered, false if not
2482
+	 *
2483
+	 * @param string  $meta_key
2484
+	 * @param mixed   $meta_value
2485
+	 * @param boolean $unique
2486
+	 * @return boolean
2487
+	 * @throws \EE_Error
2488
+	 */
2489
+	public function add_extra_meta($meta_key, $meta_value, $unique = false)
2490
+	{
2491
+		if ($unique) {
2492
+			$existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2493
+				array(
2494
+					array(
2495
+						'EXM_key'  => $meta_key,
2496
+						'OBJ_ID'   => $this->ID(),
2497
+						'EXM_type' => $this->get_model()->get_this_model_name(),
2498
+					),
2499
+				)
2500
+			);
2501
+			if ($existing_extra_meta) {
2502
+				return false;
2503
+			}
2504
+		}
2505
+		$new_extra_meta = EE_Extra_Meta::new_instance(
2506
+			array(
2507
+				'EXM_key'   => $meta_key,
2508
+				'EXM_value' => $meta_value,
2509
+				'OBJ_ID'    => $this->ID(),
2510
+				'EXM_type'  => $this->get_model()->get_this_model_name(),
2511
+			)
2512
+		);
2513
+		$new_extra_meta->save();
2514
+		return true;
2515
+	}
2516
+
2517
+
2518
+
2519
+	/**
2520
+	 * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2521
+	 * is specified, only deletes extra meta records with that value.
2522
+	 *
2523
+	 * @param string $meta_key
2524
+	 * @param mixed  $meta_value
2525
+	 * @return int number of extra meta rows deleted
2526
+	 * @throws \EE_Error
2527
+	 */
2528
+	public function delete_extra_meta($meta_key, $meta_value = null)
2529
+	{
2530
+		$query_params = array(
2531
+			array(
2532
+				'EXM_key'  => $meta_key,
2533
+				'OBJ_ID'   => $this->ID(),
2534
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2535
+			),
2536
+		);
2537
+		if ($meta_value !== null) {
2538
+			$query_params[0]['EXM_value'] = $meta_value;
2539
+		}
2540
+		return EEM_Extra_Meta::instance()->delete($query_params);
2541
+	}
2542
+
2543
+
2544
+
2545
+	/**
2546
+	 * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2547
+	 * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2548
+	 * You can specify $default is case you haven't found the extra meta
2549
+	 *
2550
+	 * @param string  $meta_key
2551
+	 * @param boolean $single
2552
+	 * @param mixed   $default if we don't find anything, what should we return?
2553
+	 * @return mixed single value if $single; array if ! $single
2554
+	 * @throws \EE_Error
2555
+	 */
2556
+	public function get_extra_meta($meta_key, $single = false, $default = null)
2557
+	{
2558
+		if ($single) {
2559
+			$result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2560
+			if ($result instanceof EE_Extra_Meta) {
2561
+				return $result->value();
2562
+			}
2563
+		} else {
2564
+			$results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2565
+			if ($results) {
2566
+				$values = array();
2567
+				foreach ($results as $result) {
2568
+					if ($result instanceof EE_Extra_Meta) {
2569
+						$values[$result->ID()] = $result->value();
2570
+					}
2571
+				}
2572
+				return $values;
2573
+			}
2574
+		}
2575
+		//if nothing discovered yet return default.
2576
+		return apply_filters(
2577
+			'FHEE__EE_Base_Class__get_extra_meta__default_value',
2578
+			$default,
2579
+			$meta_key,
2580
+			$single,
2581
+			$this
2582
+			);
2583
+	}
2584
+
2585
+
2586
+
2587
+	/**
2588
+	 * Returns a simple array of all the extra meta associated with this model object.
2589
+	 * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2590
+	 * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2591
+	 * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2592
+	 * If $one_of_each_key is false, it will return an array with the top-level keys being
2593
+	 * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2594
+	 * finally the extra meta's value as each sub-value. (eg
2595
+	 * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2596
+	 *
2597
+	 * @param boolean $one_of_each_key
2598
+	 * @return array
2599
+	 * @throws \EE_Error
2600
+	 */
2601
+	public function all_extra_meta_array($one_of_each_key = true)
2602
+	{
2603
+		$return_array = array();
2604
+		if ($one_of_each_key) {
2605
+			$extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2606
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2607
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2608
+					$return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2609
+				}
2610
+			}
2611
+		} else {
2612
+			$extra_meta_objs = $this->get_many_related('Extra_Meta');
2613
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2614
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2615
+					if ( ! isset($return_array[$extra_meta_obj->key()])) {
2616
+						$return_array[$extra_meta_obj->key()] = array();
2617
+					}
2618
+					$return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2619
+				}
2620
+			}
2621
+		}
2622
+		return $return_array;
2623
+	}
2624
+
2625
+
2626
+
2627
+	/**
2628
+	 * Gets a pretty nice displayable nice for this model object. Often overridden
2629
+	 *
2630
+	 * @return string
2631
+	 * @throws \EE_Error
2632
+	 */
2633
+	public function name()
2634
+	{
2635
+		//find a field that's not a text field
2636
+		$field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2637
+		if ($field_we_can_use) {
2638
+			return $this->get($field_we_can_use->get_name());
2639
+		} else {
2640
+			$first_few_properties = $this->model_field_array();
2641
+			$first_few_properties = array_slice($first_few_properties, 0, 3);
2642
+			$name_parts = array();
2643
+			foreach ($first_few_properties as $name => $value) {
2644
+				$name_parts[] = "$name:$value";
2645
+			}
2646
+			return implode(",", $name_parts);
2647
+		}
2648
+	}
2649
+
2650
+
2651
+
2652
+	/**
2653
+	 * in_entity_map
2654
+	 * Checks if this model object has been proven to already be in the entity map
2655
+	 *
2656
+	 * @return boolean
2657
+	 * @throws \EE_Error
2658
+	 */
2659
+	public function in_entity_map()
2660
+	{
2661
+		if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2662
+			//well, if we looked, did we find it in the entity map?
2663
+			return true;
2664
+		} else {
2665
+			return false;
2666
+		}
2667
+	}
2668
+
2669
+
2670
+
2671
+	/**
2672
+	 * refresh_from_db
2673
+	 * Makes sure the fields and values on this model object are in-sync with what's in the database.
2674
+	 *
2675
+	 * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2676
+	 * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2677
+	 */
2678
+	public function refresh_from_db()
2679
+	{
2680
+		if ($this->ID() && $this->in_entity_map()) {
2681
+			$this->get_model()->refresh_entity_map_from_db($this->ID());
2682
+		} else {
2683
+			//if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2684
+			//if it has an ID but it's not in the map, and you're asking me to refresh it
2685
+			//that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2686
+			//absolutely nothing in it for this ID
2687
+			if (WP_DEBUG) {
2688
+				throw new EE_Error(
2689
+					sprintf(
2690
+						__('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.',
2691
+							'event_espresso'),
2692
+						$this->ID(),
2693
+						get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2694
+						get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2695
+					)
2696
+				);
2697
+			}
2698
+		}
2699
+	}
2700
+
2701
+
2702
+
2703
+	/**
2704
+	 * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2705
+	 * (probably a bad assumption they have made, oh well)
2706
+	 *
2707
+	 * @return string
2708
+	 */
2709
+	public function __toString()
2710
+	{
2711
+		try {
2712
+			return sprintf('%s (%s)', $this->name(), $this->ID());
2713
+		} catch (Exception $e) {
2714
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2715
+			return '';
2716
+		}
2717
+	}
2718
+
2719
+
2720
+
2721
+	/**
2722
+	 * Clear related model objects if they're already in the DB, because otherwise when we
2723
+	 * UN-serialize this model object we'll need to be careful to add them to the entity map.
2724
+	 * This means if we have made changes to those related model objects, and want to unserialize
2725
+	 * the this model object on a subsequent request, changes to those related model objects will be lost.
2726
+	 * Instead, those related model objects should be directly serialized and stored.
2727
+	 * Eg, the following won't work:
2728
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2729
+	 * $att = $reg->attendee();
2730
+	 * $att->set( 'ATT_fname', 'Dirk' );
2731
+	 * update_option( 'my_option', serialize( $reg ) );
2732
+	 * //END REQUEST
2733
+	 * //START NEXT REQUEST
2734
+	 * $reg = get_option( 'my_option' );
2735
+	 * $reg->attendee()->save();
2736
+	 * And would need to be replace with:
2737
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2738
+	 * $att = $reg->attendee();
2739
+	 * $att->set( 'ATT_fname', 'Dirk' );
2740
+	 * update_option( 'my_option', serialize( $reg ) );
2741
+	 * //END REQUEST
2742
+	 * //START NEXT REQUEST
2743
+	 * $att = get_option( 'my_option' );
2744
+	 * $att->save();
2745
+	 *
2746
+	 * @return array
2747
+	 * @throws \EE_Error
2748
+	 */
2749
+	public function __sleep()
2750
+	{
2751
+		$model = $this->get_model();
2752
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
2753
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
2754
+				$classname = 'EE_' . $model->get_this_model_name();
2755
+				if (
2756
+					$this->get_one_from_cache($relation_name) instanceof $classname
2757
+					&& $this->get_one_from_cache($relation_name)->ID()
2758
+				) {
2759
+					$this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2760
+				}
2761
+			}
2762
+		}
2763
+		$this->_props_n_values_provided_in_constructor = array();
2764
+		$properties_to_serialize = get_object_vars($this);
2765
+		//don't serialize the model. It's big and that risks recursion
2766
+		unset($properties_to_serialize['_model']);
2767
+		return array_keys($properties_to_serialize);
2768
+	}
2769
+
2770
+
2771
+
2772
+	/**
2773
+	 * restore _props_n_values_provided_in_constructor
2774
+	 * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2775
+	 * and therefore should NOT be used to determine if state change has occurred since initial construction.
2776
+	 * At best, you would only be able to detect if state change has occurred during THIS request.
2777
+	 */
2778
+	public function __wakeup()
2779
+	{
2780
+		$this->_props_n_values_provided_in_constructor = $this->_fields;
2781
+	}
2782 2782
 
2783 2783
 
2784 2784
 
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -160,8 +160,8 @@  discard block
 block discarded – undo
160 160
             list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
161 161
         } else {
162 162
             //set default formats for date and time
163
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
164
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
163
+            $this->_dt_frmt = (string) get_option('date_format', 'Y-m-d');
164
+            $this->_tm_frmt = (string) get_option('time_format', 'g:i a');
165 165
         }
166 166
         //if db model is instantiating
167 167
         if ($bydb) {
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
      */
484 484
     public function get_format($full = true)
485 485
     {
486
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
486
+        return $full ? $this->_dt_frmt.' '.$this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
487 487
     }
488 488
 
489 489
 
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
         $model = $this->get_model();
593 593
         $model->field_settings_for($fieldname);
594 594
         $cache_type = $pretty ? 'pretty' : 'standard';
595
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
595
+        $cache_type .= ! empty($extra_cache_ref) ? '_'.$extra_cache_ref : '';
596 596
         if (isset($this->_cached_properties[$fieldname][$cache_type])) {
597 597
             return $this->_cached_properties[$fieldname][$cache_type];
598 598
         }
@@ -819,7 +819,7 @@  discard block
 block discarded – undo
819 819
         $current_cache_id = ''
820 820
     ) {
821 821
         // verify that incoming object is of the correct type
822
-        $obj_class = 'EE_' . $relationName;
822
+        $obj_class = 'EE_'.$relationName;
823 823
         if ($newly_saved_object instanceof $obj_class) {
824 824
             /* @type EE_Base_Class $newly_saved_object */
825 825
             // now get the type of relation
@@ -1134,7 +1134,7 @@  discard block
 block discarded – undo
1134 1134
     {
1135 1135
         $field = $this->get_model()->field_settings_for($field_name);
1136 1136
         $value = isset($this->_fields[$field_name]) ? $this->_fields[$field_name] : null;
1137
-        if (! $field instanceof EE_Money_Field
1137
+        if ( ! $field instanceof EE_Money_Field
1138 1138
             || ! $value instanceof Money) {
1139 1139
             throw new InvalidEntityException(
1140 1140
                 get_class($value),
@@ -1342,7 +1342,7 @@  discard block
 block discarded – undo
1342 1342
      */
1343 1343
     public function get_i18n_datetime($field_name, $format = '')
1344 1344
     {
1345
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1345
+        $format = empty($format) ? $this->_dt_frmt.' '.$this->_tm_frmt : $format;
1346 1346
         return date_i18n(
1347 1347
             $format,
1348 1348
             EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
@@ -1480,8 +1480,8 @@  discard block
 block discarded – undo
1480 1480
         }
1481 1481
         $original_timezone = $this->_timezone;
1482 1482
         $this->set_timezone($timezone);
1483
-        $fn = (array)$field_name;
1484
-        $args = array_merge($fn, (array)$args);
1483
+        $fn = (array) $field_name;
1484
+        $args = array_merge($fn, (array) $args);
1485 1485
         if ( ! method_exists($this, $callback)) {
1486 1486
             throw new EE_Error(
1487 1487
                 sprintf(
@@ -1493,8 +1493,8 @@  discard block
 block discarded – undo
1493 1493
                 )
1494 1494
             );
1495 1495
         }
1496
-        $args = (array)$args;
1497
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1496
+        $args = (array) $args;
1497
+        $return = $prepend.call_user_func_array(array($this, $callback), $args).$append;
1498 1498
         $this->set_timezone($original_timezone);
1499 1499
         return $return;
1500 1500
     }
@@ -1633,14 +1633,14 @@  discard block
 block discarded – undo
1633 1633
          * @param array         $set_cols_n_values
1634 1634
          * @param EE_Base_Class $model_object
1635 1635
          */
1636
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1636
+        $set_cols_n_values = (array) apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1637 1637
             $this);
1638 1638
         //set attributes as provided in $set_cols_n_values
1639 1639
         foreach ($set_cols_n_values as $column => $value) {
1640 1640
             $this->set($column, $value);
1641 1641
         }
1642 1642
         // no changes ? then don't do anything
1643
-        if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1643
+        if ( ! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1644 1644
             return 0;
1645 1645
         }
1646 1646
         /**
@@ -1692,8 +1692,8 @@  discard block
 block discarded – undo
1692 1692
                                 __('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',
1693 1693
                                     'event_espresso'),
1694 1694
                                 get_class($this),
1695
-                                get_class($model) . '::instance()->add_to_entity_map()',
1696
-                                get_class($model) . '::instance()->get_one_by_ID()',
1695
+                                get_class($model).'::instance()->add_to_entity_map()',
1696
+                                get_class($model).'::instance()->get_one_by_ID()',
1697 1697
                                 '<br />'
1698 1698
                             )
1699 1699
                         );
@@ -1826,7 +1826,7 @@  discard block
 block discarded – undo
1826 1826
      */
1827 1827
     public function get_model()
1828 1828
     {
1829
-        if( ! $this->_model){
1829
+        if ( ! $this->_model) {
1830 1830
             $modelName = self::_get_model_classname(get_class($this));
1831 1831
             $this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
1832 1832
         } else {
@@ -1969,7 +1969,7 @@  discard block
 block discarded – undo
1969 1969
         if (strpos($model_name, "EE_") === 0) {
1970 1970
             $model_classname = str_replace("EE_", "EEM_", $model_name);
1971 1971
         } else {
1972
-            $model_classname = "EEM_" . $model_name;
1972
+            $model_classname = "EEM_".$model_name;
1973 1973
         }
1974 1974
         return $model_classname;
1975 1975
     }
@@ -2356,7 +2356,7 @@  discard block
 block discarded – undo
2356 2356
      */
2357 2357
     protected function _property_exists($properties)
2358 2358
     {
2359
-        foreach ((array)$properties as $property_name) {
2359
+        foreach ((array) $properties as $property_name) {
2360 2360
             //first make sure this property exists
2361 2361
             if ( ! $this->_fields[$property_name]) {
2362 2362
                 throw new EE_Error(
@@ -2690,8 +2690,8 @@  discard block
 block discarded – undo
2690 2690
                         __('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.',
2691 2691
                             'event_espresso'),
2692 2692
                         $this->ID(),
2693
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2694
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2693
+                        get_class($this->get_model()).'::instance()->add_to_entity_map()',
2694
+                        get_class($this->get_model()).'::instance()->refresh_entity_map()'
2695 2695
                     )
2696 2696
                 );
2697 2697
             }
@@ -2751,7 +2751,7 @@  discard block
 block discarded – undo
2751 2751
         $model = $this->get_model();
2752 2752
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
2753 2753
             if ($relation_obj instanceof EE_Belongs_To_Relation) {
2754
-                $classname = 'EE_' . $model->get_this_model_name();
2754
+                $classname = 'EE_'.$model->get_this_model_name();
2755 2755
                 if (
2756 2756
                     $this->get_one_from_cache($relation_name) instanceof $classname
2757 2757
                     && $this->get_one_from_cache($relation_name)->ID()
Please login to merge, or discard this patch.