@@ -15,565 +15,565 @@ |
||
15 | 15 | abstract class EEM_CPT_Base extends EEM_Soft_Delete_Base |
16 | 16 | { |
17 | 17 | |
18 | - const EVENT_CATEGORY_TAXONOMY = 'espresso_event_categories'; |
|
19 | - |
|
20 | - /** |
|
21 | - * @var string post_status_publish - the wp post status for published cpts |
|
22 | - */ |
|
23 | - const post_status_publish = 'publish'; |
|
24 | - |
|
25 | - /** |
|
26 | - * @var string post_status_future - the wp post status for scheduled cpts |
|
27 | - */ |
|
28 | - const post_status_future = 'future'; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var string post_status_draft - the wp post status for draft cpts |
|
32 | - */ |
|
33 | - const post_status_draft = 'draft'; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var string post_status_pending - the wp post status for pending cpts |
|
37 | - */ |
|
38 | - const post_status_pending = 'pending'; |
|
39 | - |
|
40 | - /** |
|
41 | - * @var string post_status_private - the wp post status for private cpts |
|
42 | - */ |
|
43 | - const post_status_private = 'private'; |
|
44 | - |
|
45 | - /** |
|
46 | - * @var string post_status_trashed - the wp post status for trashed cpts |
|
47 | - */ |
|
48 | - const post_status_trashed = 'trash'; |
|
49 | - |
|
50 | - /** |
|
51 | - * This is an array of custom statuses for the given CPT model (modified by children) |
|
52 | - * format: |
|
53 | - * array( |
|
54 | - * 'status_name' => array( |
|
55 | - * 'label' => __('Status Name', 'event_espresso'), |
|
56 | - * 'public' => TRUE //whether a public status or not. |
|
57 | - * ) |
|
58 | - * ) |
|
59 | - * |
|
60 | - * @var array |
|
61 | - */ |
|
62 | - protected $_custom_stati = array(); |
|
63 | - |
|
64 | - |
|
65 | - /** |
|
66 | - * Adds a relationship to Term_Taxonomy for each CPT_Base |
|
67 | - * |
|
68 | - * @param string $timezone |
|
69 | - * @throws \EE_Error |
|
70 | - */ |
|
71 | - protected function __construct($timezone = '') |
|
72 | - { |
|
73 | - // adds a relationship to Term_Taxonomy for all these models. For this to work |
|
74 | - // Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly |
|
75 | - // eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry |
|
76 | - // with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value |
|
77 | - // must also be new EE_HABTM_Relation('Term_Relationship'); |
|
78 | - $this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship'); |
|
79 | - $primary_table_name = null; |
|
80 | - // add the common _status field to all CPT primary tables. |
|
81 | - foreach ($this->_tables as $alias => $table_obj) { |
|
82 | - if ($table_obj instanceof EE_Primary_Table) { |
|
83 | - $primary_table_name = $alias; |
|
84 | - } |
|
85 | - } |
|
86 | - // set default wp post statuses if child has not already set. |
|
87 | - if (! isset($this->_fields[ $primary_table_name ]['status'])) { |
|
88 | - $this->_fields[ $primary_table_name ]['status'] = new EE_WP_Post_Status_Field( |
|
89 | - 'post_status', |
|
90 | - __("Event Status", "event_espresso"), |
|
91 | - false, |
|
92 | - 'draft' |
|
93 | - ); |
|
94 | - } |
|
95 | - if (! isset($this->_fields[ $primary_table_name ]['to_ping'])) { |
|
96 | - $this->_fields[ $primary_table_name ]['to_ping'] = new EE_DB_Only_Text_Field( |
|
97 | - 'to_ping', |
|
98 | - __('To Ping', 'event_espresso'), |
|
99 | - false, |
|
100 | - '' |
|
101 | - ); |
|
102 | - } |
|
103 | - if (! isset($this->_fields[ $primary_table_name ]['pinged'])) { |
|
104 | - $this->_fields[ $primary_table_name ]['pinged'] = new EE_DB_Only_Text_Field( |
|
105 | - 'pinged', |
|
106 | - __('Pinged', 'event_espresso'), |
|
107 | - false, |
|
108 | - '' |
|
109 | - ); |
|
110 | - } |
|
111 | - if (! isset($this->_fields[ $primary_table_name ]['comment_status'])) { |
|
112 | - $this->_fields[ $primary_table_name ]['comment_status'] = new EE_Plain_Text_Field( |
|
113 | - 'comment_status', |
|
114 | - __('Comment Status', 'event_espresso'), |
|
115 | - false, |
|
116 | - 'open' |
|
117 | - ); |
|
118 | - } |
|
119 | - if (! isset($this->_fields[ $primary_table_name ]['ping_status'])) { |
|
120 | - $this->_fields[ $primary_table_name ]['ping_status'] = new EE_Plain_Text_Field( |
|
121 | - 'ping_status', |
|
122 | - __('Ping Status', 'event_espresso'), |
|
123 | - false, |
|
124 | - 'open' |
|
125 | - ); |
|
126 | - } |
|
127 | - if (! isset($this->_fields[ $primary_table_name ]['post_content_filtered'])) { |
|
128 | - $this->_fields[ $primary_table_name ]['post_content_filtered'] = new EE_DB_Only_Text_Field( |
|
129 | - 'post_content_filtered', |
|
130 | - __('Post Content Filtered', 'event_espresso'), |
|
131 | - false, |
|
132 | - '' |
|
133 | - ); |
|
134 | - } |
|
135 | - if (! isset($this->_model_relations['Post_Meta'])) { |
|
136 | - // don't block deletes though because we want to maintain the current behaviour |
|
137 | - $this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false); |
|
138 | - } |
|
139 | - if (! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
140 | - // nothing was set during child constructor, so set default |
|
141 | - $this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type()); |
|
142 | - } |
|
143 | - if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
144 | - // nothing was set during child constructor, so set default |
|
145 | - // it's ok for child classes to specify this, but generally this is more DRY |
|
146 | - $this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type()); |
|
147 | - } |
|
148 | - parent::__construct($timezone); |
|
149 | - } |
|
150 | - |
|
151 | - |
|
152 | - /** |
|
153 | - * @return array |
|
154 | - */ |
|
155 | - public function public_event_stati() |
|
156 | - { |
|
157 | - // @see wp-includes/post.php |
|
158 | - return get_post_stati(array('public' => true)); |
|
159 | - } |
|
160 | - |
|
161 | - |
|
162 | - /** |
|
163 | - * Searches for field on this model of type 'deleted_flag'. if it is found, |
|
164 | - * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name |
|
165 | - * |
|
166 | - * @return string |
|
167 | - * @throws EE_Error |
|
168 | - */ |
|
169 | - public function deleted_field_name() |
|
170 | - { |
|
171 | - throw new EE_Error( |
|
172 | - sprintf( |
|
173 | - __( |
|
174 | - "EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name", |
|
175 | - "event_espresso" |
|
176 | - ) |
|
177 | - ) |
|
178 | - ); |
|
179 | - } |
|
180 | - |
|
181 | - |
|
182 | - /** |
|
183 | - * Gets the field's name that sets the post status |
|
184 | - * |
|
185 | - * @return string |
|
186 | - * @throws EE_Error |
|
187 | - */ |
|
188 | - public function post_status_field_name() |
|
189 | - { |
|
190 | - $field = $this->get_a_field_of_type('EE_WP_Post_Status_Field'); |
|
191 | - if ($field) { |
|
192 | - return $field->get_name(); |
|
193 | - } else { |
|
194 | - throw new EE_Error( |
|
195 | - sprintf( |
|
196 | - __( |
|
197 | - 'We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?', |
|
198 | - 'event_espresso' |
|
199 | - ), |
|
200 | - get_class($this), |
|
201 | - get_class($this) |
|
202 | - ) |
|
203 | - ); |
|
204 | - } |
|
205 | - } |
|
206 | - |
|
207 | - |
|
208 | - /** |
|
209 | - * Alters the query params so that only trashed/soft-deleted items are considered |
|
210 | - * |
|
211 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
212 | - * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
213 | - */ |
|
214 | - protected function _alter_query_params_so_only_trashed_items_included($query_params) |
|
215 | - { |
|
216 | - $post_status_field_name = $this->post_status_field_name(); |
|
217 | - $query_params[0][ $post_status_field_name ] = self::post_status_trashed; |
|
218 | - return $query_params; |
|
219 | - } |
|
220 | - |
|
221 | - |
|
222 | - /** |
|
223 | - * Alters the query params so each item's deleted status is ignored. |
|
224 | - * |
|
225 | - * @param array $query_params |
|
226 | - * @return array |
|
227 | - */ |
|
228 | - protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params) |
|
229 | - { |
|
230 | - $query_params['default_where_conditions'] = 'minimum'; |
|
231 | - return $query_params; |
|
232 | - } |
|
233 | - |
|
234 | - |
|
235 | - /** |
|
236 | - * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered. |
|
237 | - * |
|
238 | - * @param boolean $delete true to indicate deletion, false to indicate restoration |
|
239 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
240 | - * @return boolean success |
|
241 | - */ |
|
242 | - public function delete_or_restore($delete = true, $query_params = array()) |
|
243 | - { |
|
244 | - $post_status_field_name = $this->post_status_field_name(); |
|
245 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
246 | - $new_status = $delete ? self::post_status_trashed : 'draft'; |
|
247 | - if ($this->update(array($post_status_field_name => $new_status), $query_params)) { |
|
248 | - return true; |
|
249 | - } else { |
|
250 | - return false; |
|
251 | - } |
|
252 | - } |
|
253 | - |
|
254 | - |
|
255 | - /** |
|
256 | - * meta_table |
|
257 | - * returns first EE_Secondary_Table table name |
|
258 | - * |
|
259 | - * @access public |
|
260 | - * @return string |
|
261 | - */ |
|
262 | - public function meta_table() |
|
263 | - { |
|
264 | - $meta_table = $this->_get_other_tables(); |
|
265 | - $meta_table = reset($meta_table); |
|
266 | - return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null; |
|
267 | - } |
|
268 | - |
|
269 | - |
|
270 | - /** |
|
271 | - * This simply returns an array of the meta table fields (useful for when we just need to update those fields) |
|
272 | - * |
|
273 | - * @param bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields. Defaults to false (no |
|
274 | - * db only fields) |
|
275 | - * @return array |
|
276 | - */ |
|
277 | - public function get_meta_table_fields($all = false) |
|
278 | - { |
|
279 | - $all_fields = $fields_to_return = array(); |
|
280 | - foreach ($this->_tables as $alias => $table_obj) { |
|
281 | - if ($table_obj instanceof EE_Secondary_Table) { |
|
282 | - $all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields); |
|
283 | - } |
|
284 | - } |
|
285 | - if (! $all) { |
|
286 | - foreach ($all_fields as $name => $obj) { |
|
287 | - if ($obj instanceof EE_DB_Only_Field_Base) { |
|
288 | - continue; |
|
289 | - } |
|
290 | - $fields_to_return[] = $name; |
|
291 | - } |
|
292 | - } else { |
|
293 | - $fields_to_return = array_keys($all_fields); |
|
294 | - } |
|
295 | - return $fields_to_return; |
|
296 | - } |
|
297 | - |
|
298 | - |
|
299 | - /** |
|
300 | - * Adds an event category with the specified name and description to the specified |
|
301 | - * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary, |
|
302 | - * and adds an entry in the term_relationship if necessary. |
|
303 | - * |
|
304 | - * @param EE_CPT_Base $cpt_model_object |
|
305 | - * @param string $category_name (used to derive the term slug too) |
|
306 | - * @param string $category_description |
|
307 | - * @param int $parent_term_taxonomy_id |
|
308 | - * @return EE_Term_Taxonomy |
|
309 | - */ |
|
310 | - public function add_event_category( |
|
311 | - EE_CPT_Base $cpt_model_object, |
|
312 | - $category_name, |
|
313 | - $category_description = '', |
|
314 | - $parent_term_taxonomy_id = null |
|
315 | - ) { |
|
316 | - // create term |
|
317 | - require_once(EE_MODELS . 'EEM_Term.model.php'); |
|
318 | - // first, check for a term by the same name or slug |
|
319 | - $category_slug = sanitize_title($category_name); |
|
320 | - $term = EEM_Term::instance()->get_one( |
|
321 | - array( |
|
322 | - array( |
|
323 | - 'OR' => array( |
|
324 | - 'name' => $category_name, |
|
325 | - 'slug' => $category_slug, |
|
326 | - ), |
|
327 | - 'Term_Taxonomy.taxonomy' => self::EVENT_CATEGORY_TAXONOMY |
|
328 | - ), |
|
329 | - ) |
|
330 | - ); |
|
331 | - if (! $term) { |
|
332 | - $term = EE_Term::new_instance( |
|
333 | - array( |
|
334 | - 'name' => $category_name, |
|
335 | - 'slug' => $category_slug, |
|
336 | - ) |
|
337 | - ); |
|
338 | - $term->save(); |
|
339 | - } |
|
340 | - // make sure there's a term-taxonomy entry too |
|
341 | - require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php'); |
|
342 | - $term_taxonomy = EEM_Term_Taxonomy::instance()->get_one( |
|
343 | - array( |
|
344 | - array( |
|
345 | - 'term_id' => $term->ID(), |
|
346 | - 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY, |
|
347 | - ), |
|
348 | - ) |
|
349 | - ); |
|
350 | - /** @var $term_taxonomy EE_Term_Taxonomy */ |
|
351 | - if (! $term_taxonomy) { |
|
352 | - $term_taxonomy = EE_Term_Taxonomy::new_instance( |
|
353 | - array( |
|
354 | - 'term_id' => $term->ID(), |
|
355 | - 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY, |
|
356 | - 'description' => $category_description, |
|
357 | - 'term_count' => 1, |
|
358 | - 'parent' => $parent_term_taxonomy_id, |
|
359 | - ) |
|
360 | - ); |
|
361 | - $term_taxonomy->save(); |
|
362 | - } else { |
|
363 | - $term_taxonomy->set_count($term_taxonomy->count() + 1); |
|
364 | - $term_taxonomy->save(); |
|
365 | - } |
|
366 | - return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy'); |
|
367 | - } |
|
368 | - |
|
369 | - |
|
370 | - /** |
|
371 | - * Removed the category specified by name as having a relation to this event. |
|
372 | - * Does not remove the term or term_taxonomy. |
|
373 | - * |
|
374 | - * @param EE_CPT_Base $cpt_model_object_event |
|
375 | - * @param string $category_name name of the event category (term) |
|
376 | - * @return bool |
|
377 | - */ |
|
378 | - public function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name) |
|
379 | - { |
|
380 | - // find the term_taxonomy by that name |
|
381 | - $term_taxonomy = $this->get_first_related( |
|
382 | - $cpt_model_object_event, |
|
383 | - 'Term_Taxonomy', |
|
384 | - array(array('Term.name' => $category_name, 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY)) |
|
385 | - ); |
|
386 | - /** @var $term_taxonomy EE_Term_Taxonomy */ |
|
387 | - if ($term_taxonomy) { |
|
388 | - $term_taxonomy->set_count($term_taxonomy->count() - 1); |
|
389 | - $term_taxonomy->save(); |
|
390 | - } |
|
391 | - return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy'); |
|
392 | - } |
|
393 | - |
|
394 | - |
|
395 | - /** |
|
396 | - * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the |
|
397 | - * given CPT ID. It accepts the same params as what get_the_post_thumbnail() accepts. |
|
398 | - * |
|
399 | - * @link http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail |
|
400 | - * @access public |
|
401 | - * @param int $id the ID for the cpt we want the feature image for |
|
402 | - * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array |
|
403 | - * representing width and height in pixels (i.e. array(32,32) ). |
|
404 | - * @param string|array $attr Optional. Query string or array of attributes. |
|
405 | - * @return string HTML image element |
|
406 | - */ |
|
407 | - public function get_feature_image($id, $size = 'thumbnail', $attr = '') |
|
408 | - { |
|
409 | - return get_the_post_thumbnail($id, $size, $attr); |
|
410 | - } |
|
411 | - |
|
412 | - |
|
413 | - /** |
|
414 | - * Just a handy way to get the list of post statuses currently registered with WP. |
|
415 | - * |
|
416 | - * @global array $wp_post_statuses set in wp core for storing all the post stati |
|
417 | - * @return array |
|
418 | - */ |
|
419 | - public function get_post_statuses() |
|
420 | - { |
|
421 | - global $wp_post_statuses; |
|
422 | - $statuses = array(); |
|
423 | - foreach ($wp_post_statuses as $post_status => $args_object) { |
|
424 | - $statuses[ $post_status ] = $args_object->label; |
|
425 | - } |
|
426 | - return $statuses; |
|
427 | - } |
|
428 | - |
|
429 | - |
|
430 | - /** |
|
431 | - * public method that can be used to retrieve the protected status array on the instantiated cpt model |
|
432 | - * |
|
433 | - * @return array array of statuses. |
|
434 | - */ |
|
435 | - public function get_status_array() |
|
436 | - { |
|
437 | - $statuses = $this->get_post_statuses(); |
|
438 | - // first the global filter |
|
439 | - $statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses); |
|
440 | - // now the class specific filter |
|
441 | - $statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses); |
|
442 | - return $statuses; |
|
443 | - } |
|
444 | - |
|
445 | - |
|
446 | - /** |
|
447 | - * this returns the post statuses that are NOT the default wordpress status |
|
448 | - * |
|
449 | - * @return array |
|
450 | - */ |
|
451 | - public function get_custom_post_statuses() |
|
452 | - { |
|
453 | - $new_stati = array(); |
|
454 | - foreach ($this->_custom_stati as $status => $props) { |
|
455 | - $new_stati[ $status ] = $props['label']; |
|
456 | - } |
|
457 | - return $new_stati; |
|
458 | - } |
|
459 | - |
|
460 | - |
|
461 | - /** |
|
462 | - * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which |
|
463 | - * are a row from the posts table. If we're missing any fields required for the model, |
|
464 | - * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries, |
|
465 | - * make sure you are attaching all the model's fields onto the post) |
|
466 | - * |
|
467 | - * @param WP_Post|array $post |
|
468 | - * @return EE_Base_Class|EE_Soft_Delete_Base_Class |
|
469 | - */ |
|
470 | - public function instantiate_class_from_post_object_orig($post) |
|
471 | - { |
|
472 | - $post = (array) $post; |
|
473 | - $has_all_necessary_fields_for_table = true; |
|
474 | - // check if the post has fields on the meta table already |
|
475 | - foreach ($this->_get_other_tables() as $table_obj) { |
|
476 | - $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias()); |
|
477 | - foreach ($fields_for_that_table as $field_obj) { |
|
478 | - if ( |
|
479 | - ! isset($post[ $field_obj->get_table_column() ]) |
|
480 | - && ! isset($post[ $field_obj->get_qualified_column() ]) |
|
481 | - ) { |
|
482 | - $has_all_necessary_fields_for_table = false; |
|
483 | - } |
|
484 | - } |
|
485 | - } |
|
486 | - // if we don't have all the fields we need, then just fetch the proper model from the DB |
|
487 | - if (! $has_all_necessary_fields_for_table) { |
|
488 | - return $this->get_one_by_ID($post['ID']); |
|
489 | - } else { |
|
490 | - return $this->instantiate_class_from_array_or_object($post); |
|
491 | - } |
|
492 | - } |
|
493 | - |
|
494 | - |
|
495 | - /** |
|
496 | - * @param null $post |
|
497 | - * @return EE_Base_Class|EE_Soft_Delete_Base_Class |
|
498 | - */ |
|
499 | - public function instantiate_class_from_post_object($post = null) |
|
500 | - { |
|
501 | - if (empty($post)) { |
|
502 | - global $post; |
|
503 | - } |
|
504 | - $post = (array) $post; |
|
505 | - $tables_needing_to_be_queried = array(); |
|
506 | - // check if the post has fields on the meta table already |
|
507 | - foreach ($this->get_tables() as $table_obj) { |
|
508 | - $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias()); |
|
509 | - foreach ($fields_for_that_table as $field_obj) { |
|
510 | - if ( |
|
511 | - ! isset($post[ $field_obj->get_table_column() ]) |
|
512 | - && ! isset($post[ $field_obj->get_qualified_column() ]) |
|
513 | - ) { |
|
514 | - $tables_needing_to_be_queried[ $table_obj->get_table_alias() ] = $table_obj; |
|
515 | - } |
|
516 | - } |
|
517 | - } |
|
518 | - // if we don't have all the fields we need, then just fetch the proper model from the DB |
|
519 | - if ($tables_needing_to_be_queried) { |
|
520 | - if ( |
|
521 | - count($tables_needing_to_be_queried) == 1 |
|
522 | - && reset($tables_needing_to_be_queried) |
|
523 | - instanceof |
|
524 | - EE_Secondary_Table |
|
525 | - ) { |
|
526 | - // so we're only missing data from a secondary table. Well that's not too hard to query for |
|
527 | - $table_to_query = reset($tables_needing_to_be_queried); |
|
528 | - $missing_data = $this->_do_wpdb_query( |
|
529 | - 'get_row', |
|
530 | - array( |
|
531 | - 'SELECT * FROM ' |
|
532 | - . $table_to_query->get_table_name() |
|
533 | - . ' WHERE ' |
|
534 | - . $table_to_query->get_fk_on_table() |
|
535 | - . ' = ' |
|
536 | - . $post['ID'], |
|
537 | - ARRAY_A, |
|
538 | - ) |
|
539 | - ); |
|
540 | - if (! empty($missing_data)) { |
|
541 | - $post = array_merge($post, $missing_data); |
|
542 | - } |
|
543 | - } else { |
|
544 | - return $this->get_one_by_ID($post['ID']); |
|
545 | - } |
|
546 | - } |
|
547 | - return $this->instantiate_class_from_array_or_object($post); |
|
548 | - } |
|
549 | - |
|
550 | - |
|
551 | - /** |
|
552 | - * Gets the post type associated with this |
|
553 | - * |
|
554 | - * @throws EE_Error |
|
555 | - * @return string |
|
556 | - */ |
|
557 | - public function post_type() |
|
558 | - { |
|
559 | - $post_type_field = null; |
|
560 | - foreach ($this->field_settings(true) as $field_obj) { |
|
561 | - if ($field_obj instanceof EE_WP_Post_Type_Field) { |
|
562 | - $post_type_field = $field_obj; |
|
563 | - break; |
|
564 | - } |
|
565 | - } |
|
566 | - if ($post_type_field == null) { |
|
567 | - throw new EE_Error( |
|
568 | - sprintf( |
|
569 | - __( |
|
570 | - "CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt", |
|
571 | - "event_espresso" |
|
572 | - ), |
|
573 | - get_class($this) |
|
574 | - ) |
|
575 | - ); |
|
576 | - } |
|
577 | - return $post_type_field->get_default_value(); |
|
578 | - } |
|
18 | + const EVENT_CATEGORY_TAXONOMY = 'espresso_event_categories'; |
|
19 | + |
|
20 | + /** |
|
21 | + * @var string post_status_publish - the wp post status for published cpts |
|
22 | + */ |
|
23 | + const post_status_publish = 'publish'; |
|
24 | + |
|
25 | + /** |
|
26 | + * @var string post_status_future - the wp post status for scheduled cpts |
|
27 | + */ |
|
28 | + const post_status_future = 'future'; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var string post_status_draft - the wp post status for draft cpts |
|
32 | + */ |
|
33 | + const post_status_draft = 'draft'; |
|
34 | + |
|
35 | + /** |
|
36 | + * @var string post_status_pending - the wp post status for pending cpts |
|
37 | + */ |
|
38 | + const post_status_pending = 'pending'; |
|
39 | + |
|
40 | + /** |
|
41 | + * @var string post_status_private - the wp post status for private cpts |
|
42 | + */ |
|
43 | + const post_status_private = 'private'; |
|
44 | + |
|
45 | + /** |
|
46 | + * @var string post_status_trashed - the wp post status for trashed cpts |
|
47 | + */ |
|
48 | + const post_status_trashed = 'trash'; |
|
49 | + |
|
50 | + /** |
|
51 | + * This is an array of custom statuses for the given CPT model (modified by children) |
|
52 | + * format: |
|
53 | + * array( |
|
54 | + * 'status_name' => array( |
|
55 | + * 'label' => __('Status Name', 'event_espresso'), |
|
56 | + * 'public' => TRUE //whether a public status or not. |
|
57 | + * ) |
|
58 | + * ) |
|
59 | + * |
|
60 | + * @var array |
|
61 | + */ |
|
62 | + protected $_custom_stati = array(); |
|
63 | + |
|
64 | + |
|
65 | + /** |
|
66 | + * Adds a relationship to Term_Taxonomy for each CPT_Base |
|
67 | + * |
|
68 | + * @param string $timezone |
|
69 | + * @throws \EE_Error |
|
70 | + */ |
|
71 | + protected function __construct($timezone = '') |
|
72 | + { |
|
73 | + // adds a relationship to Term_Taxonomy for all these models. For this to work |
|
74 | + // Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly |
|
75 | + // eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry |
|
76 | + // with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value |
|
77 | + // must also be new EE_HABTM_Relation('Term_Relationship'); |
|
78 | + $this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship'); |
|
79 | + $primary_table_name = null; |
|
80 | + // add the common _status field to all CPT primary tables. |
|
81 | + foreach ($this->_tables as $alias => $table_obj) { |
|
82 | + if ($table_obj instanceof EE_Primary_Table) { |
|
83 | + $primary_table_name = $alias; |
|
84 | + } |
|
85 | + } |
|
86 | + // set default wp post statuses if child has not already set. |
|
87 | + if (! isset($this->_fields[ $primary_table_name ]['status'])) { |
|
88 | + $this->_fields[ $primary_table_name ]['status'] = new EE_WP_Post_Status_Field( |
|
89 | + 'post_status', |
|
90 | + __("Event Status", "event_espresso"), |
|
91 | + false, |
|
92 | + 'draft' |
|
93 | + ); |
|
94 | + } |
|
95 | + if (! isset($this->_fields[ $primary_table_name ]['to_ping'])) { |
|
96 | + $this->_fields[ $primary_table_name ]['to_ping'] = new EE_DB_Only_Text_Field( |
|
97 | + 'to_ping', |
|
98 | + __('To Ping', 'event_espresso'), |
|
99 | + false, |
|
100 | + '' |
|
101 | + ); |
|
102 | + } |
|
103 | + if (! isset($this->_fields[ $primary_table_name ]['pinged'])) { |
|
104 | + $this->_fields[ $primary_table_name ]['pinged'] = new EE_DB_Only_Text_Field( |
|
105 | + 'pinged', |
|
106 | + __('Pinged', 'event_espresso'), |
|
107 | + false, |
|
108 | + '' |
|
109 | + ); |
|
110 | + } |
|
111 | + if (! isset($this->_fields[ $primary_table_name ]['comment_status'])) { |
|
112 | + $this->_fields[ $primary_table_name ]['comment_status'] = new EE_Plain_Text_Field( |
|
113 | + 'comment_status', |
|
114 | + __('Comment Status', 'event_espresso'), |
|
115 | + false, |
|
116 | + 'open' |
|
117 | + ); |
|
118 | + } |
|
119 | + if (! isset($this->_fields[ $primary_table_name ]['ping_status'])) { |
|
120 | + $this->_fields[ $primary_table_name ]['ping_status'] = new EE_Plain_Text_Field( |
|
121 | + 'ping_status', |
|
122 | + __('Ping Status', 'event_espresso'), |
|
123 | + false, |
|
124 | + 'open' |
|
125 | + ); |
|
126 | + } |
|
127 | + if (! isset($this->_fields[ $primary_table_name ]['post_content_filtered'])) { |
|
128 | + $this->_fields[ $primary_table_name ]['post_content_filtered'] = new EE_DB_Only_Text_Field( |
|
129 | + 'post_content_filtered', |
|
130 | + __('Post Content Filtered', 'event_espresso'), |
|
131 | + false, |
|
132 | + '' |
|
133 | + ); |
|
134 | + } |
|
135 | + if (! isset($this->_model_relations['Post_Meta'])) { |
|
136 | + // don't block deletes though because we want to maintain the current behaviour |
|
137 | + $this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false); |
|
138 | + } |
|
139 | + if (! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
140 | + // nothing was set during child constructor, so set default |
|
141 | + $this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type()); |
|
142 | + } |
|
143 | + if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
144 | + // nothing was set during child constructor, so set default |
|
145 | + // it's ok for child classes to specify this, but generally this is more DRY |
|
146 | + $this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type()); |
|
147 | + } |
|
148 | + parent::__construct($timezone); |
|
149 | + } |
|
150 | + |
|
151 | + |
|
152 | + /** |
|
153 | + * @return array |
|
154 | + */ |
|
155 | + public function public_event_stati() |
|
156 | + { |
|
157 | + // @see wp-includes/post.php |
|
158 | + return get_post_stati(array('public' => true)); |
|
159 | + } |
|
160 | + |
|
161 | + |
|
162 | + /** |
|
163 | + * Searches for field on this model of type 'deleted_flag'. if it is found, |
|
164 | + * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name |
|
165 | + * |
|
166 | + * @return string |
|
167 | + * @throws EE_Error |
|
168 | + */ |
|
169 | + public function deleted_field_name() |
|
170 | + { |
|
171 | + throw new EE_Error( |
|
172 | + sprintf( |
|
173 | + __( |
|
174 | + "EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name", |
|
175 | + "event_espresso" |
|
176 | + ) |
|
177 | + ) |
|
178 | + ); |
|
179 | + } |
|
180 | + |
|
181 | + |
|
182 | + /** |
|
183 | + * Gets the field's name that sets the post status |
|
184 | + * |
|
185 | + * @return string |
|
186 | + * @throws EE_Error |
|
187 | + */ |
|
188 | + public function post_status_field_name() |
|
189 | + { |
|
190 | + $field = $this->get_a_field_of_type('EE_WP_Post_Status_Field'); |
|
191 | + if ($field) { |
|
192 | + return $field->get_name(); |
|
193 | + } else { |
|
194 | + throw new EE_Error( |
|
195 | + sprintf( |
|
196 | + __( |
|
197 | + 'We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?', |
|
198 | + 'event_espresso' |
|
199 | + ), |
|
200 | + get_class($this), |
|
201 | + get_class($this) |
|
202 | + ) |
|
203 | + ); |
|
204 | + } |
|
205 | + } |
|
206 | + |
|
207 | + |
|
208 | + /** |
|
209 | + * Alters the query params so that only trashed/soft-deleted items are considered |
|
210 | + * |
|
211 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
212 | + * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
213 | + */ |
|
214 | + protected function _alter_query_params_so_only_trashed_items_included($query_params) |
|
215 | + { |
|
216 | + $post_status_field_name = $this->post_status_field_name(); |
|
217 | + $query_params[0][ $post_status_field_name ] = self::post_status_trashed; |
|
218 | + return $query_params; |
|
219 | + } |
|
220 | + |
|
221 | + |
|
222 | + /** |
|
223 | + * Alters the query params so each item's deleted status is ignored. |
|
224 | + * |
|
225 | + * @param array $query_params |
|
226 | + * @return array |
|
227 | + */ |
|
228 | + protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params) |
|
229 | + { |
|
230 | + $query_params['default_where_conditions'] = 'minimum'; |
|
231 | + return $query_params; |
|
232 | + } |
|
233 | + |
|
234 | + |
|
235 | + /** |
|
236 | + * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered. |
|
237 | + * |
|
238 | + * @param boolean $delete true to indicate deletion, false to indicate restoration |
|
239 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
240 | + * @return boolean success |
|
241 | + */ |
|
242 | + public function delete_or_restore($delete = true, $query_params = array()) |
|
243 | + { |
|
244 | + $post_status_field_name = $this->post_status_field_name(); |
|
245 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
246 | + $new_status = $delete ? self::post_status_trashed : 'draft'; |
|
247 | + if ($this->update(array($post_status_field_name => $new_status), $query_params)) { |
|
248 | + return true; |
|
249 | + } else { |
|
250 | + return false; |
|
251 | + } |
|
252 | + } |
|
253 | + |
|
254 | + |
|
255 | + /** |
|
256 | + * meta_table |
|
257 | + * returns first EE_Secondary_Table table name |
|
258 | + * |
|
259 | + * @access public |
|
260 | + * @return string |
|
261 | + */ |
|
262 | + public function meta_table() |
|
263 | + { |
|
264 | + $meta_table = $this->_get_other_tables(); |
|
265 | + $meta_table = reset($meta_table); |
|
266 | + return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null; |
|
267 | + } |
|
268 | + |
|
269 | + |
|
270 | + /** |
|
271 | + * This simply returns an array of the meta table fields (useful for when we just need to update those fields) |
|
272 | + * |
|
273 | + * @param bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields. Defaults to false (no |
|
274 | + * db only fields) |
|
275 | + * @return array |
|
276 | + */ |
|
277 | + public function get_meta_table_fields($all = false) |
|
278 | + { |
|
279 | + $all_fields = $fields_to_return = array(); |
|
280 | + foreach ($this->_tables as $alias => $table_obj) { |
|
281 | + if ($table_obj instanceof EE_Secondary_Table) { |
|
282 | + $all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields); |
|
283 | + } |
|
284 | + } |
|
285 | + if (! $all) { |
|
286 | + foreach ($all_fields as $name => $obj) { |
|
287 | + if ($obj instanceof EE_DB_Only_Field_Base) { |
|
288 | + continue; |
|
289 | + } |
|
290 | + $fields_to_return[] = $name; |
|
291 | + } |
|
292 | + } else { |
|
293 | + $fields_to_return = array_keys($all_fields); |
|
294 | + } |
|
295 | + return $fields_to_return; |
|
296 | + } |
|
297 | + |
|
298 | + |
|
299 | + /** |
|
300 | + * Adds an event category with the specified name and description to the specified |
|
301 | + * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary, |
|
302 | + * and adds an entry in the term_relationship if necessary. |
|
303 | + * |
|
304 | + * @param EE_CPT_Base $cpt_model_object |
|
305 | + * @param string $category_name (used to derive the term slug too) |
|
306 | + * @param string $category_description |
|
307 | + * @param int $parent_term_taxonomy_id |
|
308 | + * @return EE_Term_Taxonomy |
|
309 | + */ |
|
310 | + public function add_event_category( |
|
311 | + EE_CPT_Base $cpt_model_object, |
|
312 | + $category_name, |
|
313 | + $category_description = '', |
|
314 | + $parent_term_taxonomy_id = null |
|
315 | + ) { |
|
316 | + // create term |
|
317 | + require_once(EE_MODELS . 'EEM_Term.model.php'); |
|
318 | + // first, check for a term by the same name or slug |
|
319 | + $category_slug = sanitize_title($category_name); |
|
320 | + $term = EEM_Term::instance()->get_one( |
|
321 | + array( |
|
322 | + array( |
|
323 | + 'OR' => array( |
|
324 | + 'name' => $category_name, |
|
325 | + 'slug' => $category_slug, |
|
326 | + ), |
|
327 | + 'Term_Taxonomy.taxonomy' => self::EVENT_CATEGORY_TAXONOMY |
|
328 | + ), |
|
329 | + ) |
|
330 | + ); |
|
331 | + if (! $term) { |
|
332 | + $term = EE_Term::new_instance( |
|
333 | + array( |
|
334 | + 'name' => $category_name, |
|
335 | + 'slug' => $category_slug, |
|
336 | + ) |
|
337 | + ); |
|
338 | + $term->save(); |
|
339 | + } |
|
340 | + // make sure there's a term-taxonomy entry too |
|
341 | + require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php'); |
|
342 | + $term_taxonomy = EEM_Term_Taxonomy::instance()->get_one( |
|
343 | + array( |
|
344 | + array( |
|
345 | + 'term_id' => $term->ID(), |
|
346 | + 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY, |
|
347 | + ), |
|
348 | + ) |
|
349 | + ); |
|
350 | + /** @var $term_taxonomy EE_Term_Taxonomy */ |
|
351 | + if (! $term_taxonomy) { |
|
352 | + $term_taxonomy = EE_Term_Taxonomy::new_instance( |
|
353 | + array( |
|
354 | + 'term_id' => $term->ID(), |
|
355 | + 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY, |
|
356 | + 'description' => $category_description, |
|
357 | + 'term_count' => 1, |
|
358 | + 'parent' => $parent_term_taxonomy_id, |
|
359 | + ) |
|
360 | + ); |
|
361 | + $term_taxonomy->save(); |
|
362 | + } else { |
|
363 | + $term_taxonomy->set_count($term_taxonomy->count() + 1); |
|
364 | + $term_taxonomy->save(); |
|
365 | + } |
|
366 | + return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy'); |
|
367 | + } |
|
368 | + |
|
369 | + |
|
370 | + /** |
|
371 | + * Removed the category specified by name as having a relation to this event. |
|
372 | + * Does not remove the term or term_taxonomy. |
|
373 | + * |
|
374 | + * @param EE_CPT_Base $cpt_model_object_event |
|
375 | + * @param string $category_name name of the event category (term) |
|
376 | + * @return bool |
|
377 | + */ |
|
378 | + public function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name) |
|
379 | + { |
|
380 | + // find the term_taxonomy by that name |
|
381 | + $term_taxonomy = $this->get_first_related( |
|
382 | + $cpt_model_object_event, |
|
383 | + 'Term_Taxonomy', |
|
384 | + array(array('Term.name' => $category_name, 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY)) |
|
385 | + ); |
|
386 | + /** @var $term_taxonomy EE_Term_Taxonomy */ |
|
387 | + if ($term_taxonomy) { |
|
388 | + $term_taxonomy->set_count($term_taxonomy->count() - 1); |
|
389 | + $term_taxonomy->save(); |
|
390 | + } |
|
391 | + return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy'); |
|
392 | + } |
|
393 | + |
|
394 | + |
|
395 | + /** |
|
396 | + * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the |
|
397 | + * given CPT ID. It accepts the same params as what get_the_post_thumbnail() accepts. |
|
398 | + * |
|
399 | + * @link http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail |
|
400 | + * @access public |
|
401 | + * @param int $id the ID for the cpt we want the feature image for |
|
402 | + * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array |
|
403 | + * representing width and height in pixels (i.e. array(32,32) ). |
|
404 | + * @param string|array $attr Optional. Query string or array of attributes. |
|
405 | + * @return string HTML image element |
|
406 | + */ |
|
407 | + public function get_feature_image($id, $size = 'thumbnail', $attr = '') |
|
408 | + { |
|
409 | + return get_the_post_thumbnail($id, $size, $attr); |
|
410 | + } |
|
411 | + |
|
412 | + |
|
413 | + /** |
|
414 | + * Just a handy way to get the list of post statuses currently registered with WP. |
|
415 | + * |
|
416 | + * @global array $wp_post_statuses set in wp core for storing all the post stati |
|
417 | + * @return array |
|
418 | + */ |
|
419 | + public function get_post_statuses() |
|
420 | + { |
|
421 | + global $wp_post_statuses; |
|
422 | + $statuses = array(); |
|
423 | + foreach ($wp_post_statuses as $post_status => $args_object) { |
|
424 | + $statuses[ $post_status ] = $args_object->label; |
|
425 | + } |
|
426 | + return $statuses; |
|
427 | + } |
|
428 | + |
|
429 | + |
|
430 | + /** |
|
431 | + * public method that can be used to retrieve the protected status array on the instantiated cpt model |
|
432 | + * |
|
433 | + * @return array array of statuses. |
|
434 | + */ |
|
435 | + public function get_status_array() |
|
436 | + { |
|
437 | + $statuses = $this->get_post_statuses(); |
|
438 | + // first the global filter |
|
439 | + $statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses); |
|
440 | + // now the class specific filter |
|
441 | + $statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses); |
|
442 | + return $statuses; |
|
443 | + } |
|
444 | + |
|
445 | + |
|
446 | + /** |
|
447 | + * this returns the post statuses that are NOT the default wordpress status |
|
448 | + * |
|
449 | + * @return array |
|
450 | + */ |
|
451 | + public function get_custom_post_statuses() |
|
452 | + { |
|
453 | + $new_stati = array(); |
|
454 | + foreach ($this->_custom_stati as $status => $props) { |
|
455 | + $new_stati[ $status ] = $props['label']; |
|
456 | + } |
|
457 | + return $new_stati; |
|
458 | + } |
|
459 | + |
|
460 | + |
|
461 | + /** |
|
462 | + * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which |
|
463 | + * are a row from the posts table. If we're missing any fields required for the model, |
|
464 | + * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries, |
|
465 | + * make sure you are attaching all the model's fields onto the post) |
|
466 | + * |
|
467 | + * @param WP_Post|array $post |
|
468 | + * @return EE_Base_Class|EE_Soft_Delete_Base_Class |
|
469 | + */ |
|
470 | + public function instantiate_class_from_post_object_orig($post) |
|
471 | + { |
|
472 | + $post = (array) $post; |
|
473 | + $has_all_necessary_fields_for_table = true; |
|
474 | + // check if the post has fields on the meta table already |
|
475 | + foreach ($this->_get_other_tables() as $table_obj) { |
|
476 | + $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias()); |
|
477 | + foreach ($fields_for_that_table as $field_obj) { |
|
478 | + if ( |
|
479 | + ! isset($post[ $field_obj->get_table_column() ]) |
|
480 | + && ! isset($post[ $field_obj->get_qualified_column() ]) |
|
481 | + ) { |
|
482 | + $has_all_necessary_fields_for_table = false; |
|
483 | + } |
|
484 | + } |
|
485 | + } |
|
486 | + // if we don't have all the fields we need, then just fetch the proper model from the DB |
|
487 | + if (! $has_all_necessary_fields_for_table) { |
|
488 | + return $this->get_one_by_ID($post['ID']); |
|
489 | + } else { |
|
490 | + return $this->instantiate_class_from_array_or_object($post); |
|
491 | + } |
|
492 | + } |
|
493 | + |
|
494 | + |
|
495 | + /** |
|
496 | + * @param null $post |
|
497 | + * @return EE_Base_Class|EE_Soft_Delete_Base_Class |
|
498 | + */ |
|
499 | + public function instantiate_class_from_post_object($post = null) |
|
500 | + { |
|
501 | + if (empty($post)) { |
|
502 | + global $post; |
|
503 | + } |
|
504 | + $post = (array) $post; |
|
505 | + $tables_needing_to_be_queried = array(); |
|
506 | + // check if the post has fields on the meta table already |
|
507 | + foreach ($this->get_tables() as $table_obj) { |
|
508 | + $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias()); |
|
509 | + foreach ($fields_for_that_table as $field_obj) { |
|
510 | + if ( |
|
511 | + ! isset($post[ $field_obj->get_table_column() ]) |
|
512 | + && ! isset($post[ $field_obj->get_qualified_column() ]) |
|
513 | + ) { |
|
514 | + $tables_needing_to_be_queried[ $table_obj->get_table_alias() ] = $table_obj; |
|
515 | + } |
|
516 | + } |
|
517 | + } |
|
518 | + // if we don't have all the fields we need, then just fetch the proper model from the DB |
|
519 | + if ($tables_needing_to_be_queried) { |
|
520 | + if ( |
|
521 | + count($tables_needing_to_be_queried) == 1 |
|
522 | + && reset($tables_needing_to_be_queried) |
|
523 | + instanceof |
|
524 | + EE_Secondary_Table |
|
525 | + ) { |
|
526 | + // so we're only missing data from a secondary table. Well that's not too hard to query for |
|
527 | + $table_to_query = reset($tables_needing_to_be_queried); |
|
528 | + $missing_data = $this->_do_wpdb_query( |
|
529 | + 'get_row', |
|
530 | + array( |
|
531 | + 'SELECT * FROM ' |
|
532 | + . $table_to_query->get_table_name() |
|
533 | + . ' WHERE ' |
|
534 | + . $table_to_query->get_fk_on_table() |
|
535 | + . ' = ' |
|
536 | + . $post['ID'], |
|
537 | + ARRAY_A, |
|
538 | + ) |
|
539 | + ); |
|
540 | + if (! empty($missing_data)) { |
|
541 | + $post = array_merge($post, $missing_data); |
|
542 | + } |
|
543 | + } else { |
|
544 | + return $this->get_one_by_ID($post['ID']); |
|
545 | + } |
|
546 | + } |
|
547 | + return $this->instantiate_class_from_array_or_object($post); |
|
548 | + } |
|
549 | + |
|
550 | + |
|
551 | + /** |
|
552 | + * Gets the post type associated with this |
|
553 | + * |
|
554 | + * @throws EE_Error |
|
555 | + * @return string |
|
556 | + */ |
|
557 | + public function post_type() |
|
558 | + { |
|
559 | + $post_type_field = null; |
|
560 | + foreach ($this->field_settings(true) as $field_obj) { |
|
561 | + if ($field_obj instanceof EE_WP_Post_Type_Field) { |
|
562 | + $post_type_field = $field_obj; |
|
563 | + break; |
|
564 | + } |
|
565 | + } |
|
566 | + if ($post_type_field == null) { |
|
567 | + throw new EE_Error( |
|
568 | + sprintf( |
|
569 | + __( |
|
570 | + "CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt", |
|
571 | + "event_espresso" |
|
572 | + ), |
|
573 | + get_class($this) |
|
574 | + ) |
|
575 | + ); |
|
576 | + } |
|
577 | + return $post_type_field->get_default_value(); |
|
578 | + } |
|
579 | 579 | } |
@@ -10,136 +10,136 @@ |
||
10 | 10 | class EEM_Question_Group extends EEM_Soft_Delete_Base |
11 | 11 | { |
12 | 12 | |
13 | - const system_personal = 1; |
|
13 | + const system_personal = 1; |
|
14 | 14 | |
15 | - const system_address = 2; |
|
15 | + const system_address = 2; |
|
16 | 16 | |
17 | - /** |
|
18 | - * private instance of the EEM_Question_Group object |
|
19 | - * |
|
20 | - * @var EEM_Question_Group |
|
21 | - */ |
|
22 | - protected static $_instance = null; |
|
17 | + /** |
|
18 | + * private instance of the EEM_Question_Group object |
|
19 | + * |
|
20 | + * @var EEM_Question_Group |
|
21 | + */ |
|
22 | + protected static $_instance = null; |
|
23 | 23 | |
24 | 24 | |
25 | - /** |
|
26 | - * EEM_Question_Group constructor. |
|
27 | - * |
|
28 | - * @param string|null $timezone |
|
29 | - */ |
|
30 | - protected function __construct($timezone = '') |
|
31 | - { |
|
32 | - $this->singular_item = esc_html__('Question Group', 'event_espresso'); |
|
33 | - $this->plural_item = esc_html__('Question Groups', 'event_espresso'); |
|
25 | + /** |
|
26 | + * EEM_Question_Group constructor. |
|
27 | + * |
|
28 | + * @param string|null $timezone |
|
29 | + */ |
|
30 | + protected function __construct($timezone = '') |
|
31 | + { |
|
32 | + $this->singular_item = esc_html__('Question Group', 'event_espresso'); |
|
33 | + $this->plural_item = esc_html__('Question Groups', 'event_espresso'); |
|
34 | 34 | |
35 | - $this->_tables = [ |
|
36 | - 'Question_Group' => new EE_Primary_Table('esp_question_group', 'QSG_ID'), |
|
37 | - ]; |
|
38 | - $this->_fields = [ |
|
39 | - 'Question_Group' => [ |
|
40 | - 'QSG_ID' => new EE_Primary_Key_Int_Field( |
|
41 | - 'QSG_ID', |
|
42 | - esc_html__('Question Group ID', 'event_espresso') |
|
43 | - ), |
|
44 | - 'QSG_deleted' => new EE_Trashed_Flag_Field( |
|
45 | - 'QSG_deleted', |
|
46 | - esc_html__('Flag indicating this question group was deleted', 'event_espresso'), |
|
47 | - false, |
|
48 | - false |
|
49 | - ), |
|
50 | - 'QSG_desc' => new EE_Post_Content_Field( |
|
51 | - 'QSG_desc', |
|
52 | - esc_html__('Description of Question Group', 'event_espresso'), |
|
53 | - true, |
|
54 | - '' |
|
55 | - ), |
|
56 | - 'QSG_identifier' => new EE_Plain_Text_Field( |
|
57 | - 'QSG_identifier', |
|
58 | - esc_html__('Text ID for question Group', 'event_espresso'), |
|
59 | - false, |
|
60 | - '' |
|
61 | - ), |
|
62 | - 'QSG_name' => new EE_Plain_Text_Field( |
|
63 | - 'QSG_name', |
|
64 | - esc_html__('Question Group Name', 'event_espresso'), |
|
65 | - false, |
|
66 | - '' |
|
67 | - ), |
|
68 | - 'QSG_order' => new EE_Integer_Field( |
|
69 | - 'QSG_order', |
|
70 | - esc_html__('Order in which to show the question group', 'event_espresso'), |
|
71 | - true, |
|
72 | - 0 |
|
73 | - ), |
|
74 | - 'QSG_show_group_desc' => new EE_Boolean_Field( |
|
75 | - 'QSG_show_group_desc', |
|
76 | - esc_html__( |
|
77 | - 'Flag indicating whether to show the group\s description on the registration page', |
|
78 | - 'event_espresso' |
|
79 | - ), |
|
80 | - false, |
|
81 | - false |
|
82 | - ), |
|
83 | - 'QSG_show_group_name' => new EE_Boolean_Field( |
|
84 | - 'QSG_show_group_name', |
|
85 | - esc_html__( |
|
86 | - 'Flag indicating whether to show the group\'s name on the registration page', |
|
87 | - 'event_espresso' |
|
88 | - ), |
|
89 | - false, |
|
90 | - true |
|
91 | - ), |
|
92 | - 'QSG_system' => new EE_Integer_Field( |
|
93 | - 'QSG_system', |
|
94 | - esc_html__( |
|
95 | - 'Indicate IF this is a system group and if it is what system group it corresponds to.', |
|
96 | - 'event_espresso' |
|
97 | - ), |
|
98 | - false, |
|
99 | - 0 |
|
100 | - ), |
|
101 | - 'QSG_wp_user' => new EE_WP_User_Field( |
|
102 | - 'QSG_wp_user', |
|
103 | - esc_html__('Question Group Creator ID', 'event_espresso'), |
|
104 | - false |
|
105 | - ), |
|
106 | - ], |
|
107 | - ]; |
|
108 | - $this->_model_relations = [ |
|
109 | - 'Event' => new EE_HABTM_Relation('Event_Question_Group'), |
|
110 | - 'Event_Question_Group' => new EE_Has_Many_Relation(), |
|
111 | - 'Question' => new EE_HABTM_Relation('Question_Group_Question'), |
|
112 | - 'WP_User' => new EE_Belongs_To_Relation(), |
|
113 | - ]; |
|
114 | - // this model is generally available for reading |
|
115 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = |
|
116 | - new EE_Restriction_Generator_Public(); |
|
117 | - $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
118 | - new EE_Restriction_Generator_Reg_Form('QSG_system'); |
|
119 | - $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = |
|
120 | - new EE_Restriction_Generator_Reg_Form('QSG_system'); |
|
121 | - $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
122 | - new EE_Restriction_Generator_Reg_Form('QSG_system'); |
|
35 | + $this->_tables = [ |
|
36 | + 'Question_Group' => new EE_Primary_Table('esp_question_group', 'QSG_ID'), |
|
37 | + ]; |
|
38 | + $this->_fields = [ |
|
39 | + 'Question_Group' => [ |
|
40 | + 'QSG_ID' => new EE_Primary_Key_Int_Field( |
|
41 | + 'QSG_ID', |
|
42 | + esc_html__('Question Group ID', 'event_espresso') |
|
43 | + ), |
|
44 | + 'QSG_deleted' => new EE_Trashed_Flag_Field( |
|
45 | + 'QSG_deleted', |
|
46 | + esc_html__('Flag indicating this question group was deleted', 'event_espresso'), |
|
47 | + false, |
|
48 | + false |
|
49 | + ), |
|
50 | + 'QSG_desc' => new EE_Post_Content_Field( |
|
51 | + 'QSG_desc', |
|
52 | + esc_html__('Description of Question Group', 'event_espresso'), |
|
53 | + true, |
|
54 | + '' |
|
55 | + ), |
|
56 | + 'QSG_identifier' => new EE_Plain_Text_Field( |
|
57 | + 'QSG_identifier', |
|
58 | + esc_html__('Text ID for question Group', 'event_espresso'), |
|
59 | + false, |
|
60 | + '' |
|
61 | + ), |
|
62 | + 'QSG_name' => new EE_Plain_Text_Field( |
|
63 | + 'QSG_name', |
|
64 | + esc_html__('Question Group Name', 'event_espresso'), |
|
65 | + false, |
|
66 | + '' |
|
67 | + ), |
|
68 | + 'QSG_order' => new EE_Integer_Field( |
|
69 | + 'QSG_order', |
|
70 | + esc_html__('Order in which to show the question group', 'event_espresso'), |
|
71 | + true, |
|
72 | + 0 |
|
73 | + ), |
|
74 | + 'QSG_show_group_desc' => new EE_Boolean_Field( |
|
75 | + 'QSG_show_group_desc', |
|
76 | + esc_html__( |
|
77 | + 'Flag indicating whether to show the group\s description on the registration page', |
|
78 | + 'event_espresso' |
|
79 | + ), |
|
80 | + false, |
|
81 | + false |
|
82 | + ), |
|
83 | + 'QSG_show_group_name' => new EE_Boolean_Field( |
|
84 | + 'QSG_show_group_name', |
|
85 | + esc_html__( |
|
86 | + 'Flag indicating whether to show the group\'s name on the registration page', |
|
87 | + 'event_espresso' |
|
88 | + ), |
|
89 | + false, |
|
90 | + true |
|
91 | + ), |
|
92 | + 'QSG_system' => new EE_Integer_Field( |
|
93 | + 'QSG_system', |
|
94 | + esc_html__( |
|
95 | + 'Indicate IF this is a system group and if it is what system group it corresponds to.', |
|
96 | + 'event_espresso' |
|
97 | + ), |
|
98 | + false, |
|
99 | + 0 |
|
100 | + ), |
|
101 | + 'QSG_wp_user' => new EE_WP_User_Field( |
|
102 | + 'QSG_wp_user', |
|
103 | + esc_html__('Question Group Creator ID', 'event_espresso'), |
|
104 | + false |
|
105 | + ), |
|
106 | + ], |
|
107 | + ]; |
|
108 | + $this->_model_relations = [ |
|
109 | + 'Event' => new EE_HABTM_Relation('Event_Question_Group'), |
|
110 | + 'Event_Question_Group' => new EE_Has_Many_Relation(), |
|
111 | + 'Question' => new EE_HABTM_Relation('Question_Group_Question'), |
|
112 | + 'WP_User' => new EE_Belongs_To_Relation(), |
|
113 | + ]; |
|
114 | + // this model is generally available for reading |
|
115 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = |
|
116 | + new EE_Restriction_Generator_Public(); |
|
117 | + $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
118 | + new EE_Restriction_Generator_Reg_Form('QSG_system'); |
|
119 | + $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = |
|
120 | + new EE_Restriction_Generator_Reg_Form('QSG_system'); |
|
121 | + $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
122 | + new EE_Restriction_Generator_Reg_Form('QSG_system'); |
|
123 | 123 | |
124 | - parent::__construct($timezone); |
|
125 | - } |
|
124 | + parent::__construct($timezone); |
|
125 | + } |
|
126 | 126 | |
127 | 127 | |
128 | - /** |
|
129 | - * searches the db for the question group with the latest question order and returns that value. |
|
130 | - * |
|
131 | - * @return int |
|
132 | - * @throws EE_Error |
|
133 | - */ |
|
134 | - public function get_latest_question_group_order(): int |
|
135 | - { |
|
136 | - $max = $this->_get_all_wpdb_results( |
|
137 | - [], |
|
138 | - ARRAY_A, |
|
139 | - [ |
|
140 | - 'max_order' => ["MAX(QSG_order)", "%d"], |
|
141 | - ] |
|
142 | - ); |
|
143 | - return $max[0]['max_order']; |
|
144 | - } |
|
128 | + /** |
|
129 | + * searches the db for the question group with the latest question order and returns that value. |
|
130 | + * |
|
131 | + * @return int |
|
132 | + * @throws EE_Error |
|
133 | + */ |
|
134 | + public function get_latest_question_group_order(): int |
|
135 | + { |
|
136 | + $max = $this->_get_all_wpdb_results( |
|
137 | + [], |
|
138 | + ARRAY_A, |
|
139 | + [ |
|
140 | + 'max_order' => ["MAX(QSG_order)", "%d"], |
|
141 | + ] |
|
142 | + ); |
|
143 | + return $max[0]['max_order']; |
|
144 | + } |
|
145 | 145 | } |
@@ -13,34 +13,34 @@ |
||
13 | 13 | class EEM_Registration_Payment extends EEM_Base |
14 | 14 | { |
15 | 15 | |
16 | - // private instance |
|
17 | - protected static $_instance = null; |
|
16 | + // private instance |
|
17 | + protected static $_instance = null; |
|
18 | 18 | |
19 | 19 | |
20 | - protected function __construct($timezone = '') |
|
21 | - { |
|
20 | + protected function __construct($timezone = '') |
|
21 | + { |
|
22 | 22 | |
23 | - $this->singular_item = __('Registration Payment', 'event_espresso'); |
|
24 | - $this->plural_item = __('Registration Payments', 'event_espresso'); |
|
23 | + $this->singular_item = __('Registration Payment', 'event_espresso'); |
|
24 | + $this->plural_item = __('Registration Payments', 'event_espresso'); |
|
25 | 25 | |
26 | - $this->_tables = array( |
|
27 | - 'Registration_Payment' => new EE_Primary_Table('esp_registration_payment', 'RPY_ID') |
|
28 | - ); |
|
26 | + $this->_tables = array( |
|
27 | + 'Registration_Payment' => new EE_Primary_Table('esp_registration_payment', 'RPY_ID') |
|
28 | + ); |
|
29 | 29 | |
30 | - $this->_fields = array( |
|
31 | - 'Registration_Payment' => array( |
|
32 | - 'RPY_ID' => new EE_Primary_Key_Int_Field('RPY_ID', __('Registration Payment ID', 'event_espresso')), |
|
33 | - 'REG_ID' => new EE_Foreign_Key_Int_Field('REG_ID', __('Registration ID', 'event_espresso'), false, 0, 'Registration'), |
|
34 | - 'PAY_ID' => new EE_Foreign_Key_Int_Field('PAY_ID', __('Payment ID', 'event_espresso'), true, null, 'Payment'), |
|
35 | - 'RPY_amount' => new EE_Money_Field('RPY_amount', __('Amount attributed to the registration', 'event_espresso'), false, 0), |
|
36 | - ) |
|
37 | - ); |
|
30 | + $this->_fields = array( |
|
31 | + 'Registration_Payment' => array( |
|
32 | + 'RPY_ID' => new EE_Primary_Key_Int_Field('RPY_ID', __('Registration Payment ID', 'event_espresso')), |
|
33 | + 'REG_ID' => new EE_Foreign_Key_Int_Field('REG_ID', __('Registration ID', 'event_espresso'), false, 0, 'Registration'), |
|
34 | + 'PAY_ID' => new EE_Foreign_Key_Int_Field('PAY_ID', __('Payment ID', 'event_espresso'), true, null, 'Payment'), |
|
35 | + 'RPY_amount' => new EE_Money_Field('RPY_amount', __('Amount attributed to the registration', 'event_espresso'), false, 0), |
|
36 | + ) |
|
37 | + ); |
|
38 | 38 | |
39 | - $this->_model_relations = array( |
|
40 | - 'Registration' => new EE_Belongs_To_Relation(), |
|
41 | - 'Payment' => new EE_Belongs_To_Relation(), |
|
42 | - ); |
|
39 | + $this->_model_relations = array( |
|
40 | + 'Registration' => new EE_Belongs_To_Relation(), |
|
41 | + 'Payment' => new EE_Belongs_To_Relation(), |
|
42 | + ); |
|
43 | 43 | |
44 | - parent::__construct($timezone); |
|
45 | - } |
|
44 | + parent::__construct($timezone); |
|
45 | + } |
|
46 | 46 | } |
@@ -10,233 +10,233 @@ |
||
10 | 10 | class EEM_Term_Relationship extends EEM_Base |
11 | 11 | { |
12 | 12 | |
13 | - // private instance of the Attendee object |
|
14 | - protected static $_instance = null; |
|
15 | - |
|
16 | - |
|
17 | - |
|
18 | - /** |
|
19 | - * EEM_Term_Relationship constructor. |
|
20 | - * |
|
21 | - * @param string $timezone |
|
22 | - */ |
|
23 | - protected function __construct($timezone = '') |
|
24 | - { |
|
25 | - $this->singular_item = __('Term Relationship', 'event_espresso'); |
|
26 | - $this->plural_item = __('Term Relationships', 'event_espresso'); |
|
27 | - $this->_tables = array( |
|
28 | - 'Term_Relationship' => new EE_Primary_Table('term_relationships'), |
|
29 | - ); |
|
30 | - $models_this_can_attach_to = array_keys(EE_Registry::instance()->cpt_models()); |
|
31 | - $this->_fields = array( |
|
32 | - 'Term_Relationship' => array( |
|
33 | - 'object_id' => new EE_Foreign_Key_Int_Field( |
|
34 | - 'object_id', |
|
35 | - __('Object(Post) ID', 'event_espresso'), |
|
36 | - false, |
|
37 | - 0, |
|
38 | - $models_this_can_attach_to |
|
39 | - ), |
|
40 | - 'term_taxonomy_id' => new EE_Foreign_Key_Int_Field( |
|
41 | - 'term_taxonomy_id', |
|
42 | - __( |
|
43 | - 'Term (in context of a taxonomy) ID', |
|
44 | - 'event_espresso' |
|
45 | - ), |
|
46 | - false, |
|
47 | - 0, |
|
48 | - 'Term_Taxonomy' |
|
49 | - ), |
|
50 | - 'term_order' => new EE_Integer_Field( |
|
51 | - 'term_order', |
|
52 | - __('Term Order', 'event_espresso'), |
|
53 | - false, |
|
54 | - 0 |
|
55 | - ), |
|
56 | - ), |
|
57 | - ); |
|
58 | - $this->_model_relations = array( |
|
59 | - 'Term_Taxonomy' => new EE_Belongs_To_Relation(), |
|
60 | - ); |
|
61 | - foreach ($models_this_can_attach_to as $model_name) { |
|
62 | - $this->_model_relations[ $model_name ] = new EE_Belongs_To_Relation(); |
|
63 | - } |
|
64 | - $this->_wp_core_model = true; |
|
65 | - $this->_indexes = array( |
|
66 | - 'PRIMARY' => new EE_Primary_Key_Index(array('object_id', 'term_taxonomy_id')), |
|
67 | - ); |
|
68 | - $path_to_event_model = 'Event'; |
|
69 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Event_Related_Public( |
|
70 | - $path_to_event_model |
|
71 | - ); |
|
72 | - $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
73 | - new EE_Restriction_Generator_Event_Related_Protected( |
|
74 | - $path_to_event_model |
|
75 | - ); |
|
76 | - $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
77 | - $path_to_event_model |
|
78 | - ); |
|
79 | - $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
80 | - new EE_Restriction_Generator_Event_Related_Protected( |
|
81 | - $path_to_event_model, |
|
82 | - EEM_Base::caps_edit |
|
83 | - ); |
|
84 | - $path_to_tax_model = 'Term_Taxonomy.'; |
|
85 | - // add cap restrictions for editing term relations to the "ee_assign_*" |
|
86 | - // and for deleting term relations too |
|
87 | - $cap_contexts_affected = array(EEM_Base::caps_edit, EEM_Base::caps_delete); |
|
88 | - foreach ($cap_contexts_affected as $cap_context_affected) { |
|
89 | - $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_category'] = |
|
90 | - new EE_Default_Where_Conditions( |
|
91 | - array( |
|
92 | - $path_to_tax_model . 'taxonomy*ee_assign_event_category' => array( |
|
93 | - '!=', |
|
94 | - 'espresso_event_categories', |
|
95 | - ), |
|
96 | - ) |
|
97 | - ); |
|
98 | - $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_venue_category'] = |
|
99 | - new EE_Default_Where_Conditions( |
|
100 | - array( |
|
101 | - $path_to_tax_model . 'taxonomy*ee_assign_venue_category' => array( |
|
102 | - '!=', |
|
103 | - 'espresso_venue_categories', |
|
104 | - ), |
|
105 | - ) |
|
106 | - ); |
|
107 | - $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_type'] = new EE_Default_Where_Conditions( |
|
108 | - array( |
|
109 | - $path_to_tax_model . 'taxonomy*ee_assign_event_type' => array('!=', 'espresso_event_type'), |
|
110 | - ) |
|
111 | - ); |
|
112 | - } |
|
113 | - parent::__construct($timezone); |
|
114 | - add_filter( |
|
115 | - 'FHEE__Read__create_model_query_params', |
|
116 | - array('EEM_Term_Relationship', 'rest_api_query_params'), |
|
117 | - 10, |
|
118 | - 3 |
|
119 | - ); |
|
120 | - } |
|
121 | - |
|
122 | - |
|
123 | - /** |
|
124 | - * Makes sure all term-taxonomy counts are correct |
|
125 | - * |
|
126 | - * @param int $term_taxonomy_id the id of the term taxonomy to update. If NULL, updates ALL |
|
127 | - * @global wpdb $wpdb |
|
128 | - * @return int the number of rows affected |
|
129 | - * @throws EE_Error |
|
130 | - */ |
|
131 | - public function update_term_taxonomy_counts($term_taxonomy_id = null) |
|
132 | - { |
|
133 | - // because this uses a subquery and sometimes assigning to column to be another column's |
|
134 | - // value, we just write the SQL directly. |
|
135 | - global $wpdb; |
|
136 | - |
|
137 | - $query = " |
|
13 | + // private instance of the Attendee object |
|
14 | + protected static $_instance = null; |
|
15 | + |
|
16 | + |
|
17 | + |
|
18 | + /** |
|
19 | + * EEM_Term_Relationship constructor. |
|
20 | + * |
|
21 | + * @param string $timezone |
|
22 | + */ |
|
23 | + protected function __construct($timezone = '') |
|
24 | + { |
|
25 | + $this->singular_item = __('Term Relationship', 'event_espresso'); |
|
26 | + $this->plural_item = __('Term Relationships', 'event_espresso'); |
|
27 | + $this->_tables = array( |
|
28 | + 'Term_Relationship' => new EE_Primary_Table('term_relationships'), |
|
29 | + ); |
|
30 | + $models_this_can_attach_to = array_keys(EE_Registry::instance()->cpt_models()); |
|
31 | + $this->_fields = array( |
|
32 | + 'Term_Relationship' => array( |
|
33 | + 'object_id' => new EE_Foreign_Key_Int_Field( |
|
34 | + 'object_id', |
|
35 | + __('Object(Post) ID', 'event_espresso'), |
|
36 | + false, |
|
37 | + 0, |
|
38 | + $models_this_can_attach_to |
|
39 | + ), |
|
40 | + 'term_taxonomy_id' => new EE_Foreign_Key_Int_Field( |
|
41 | + 'term_taxonomy_id', |
|
42 | + __( |
|
43 | + 'Term (in context of a taxonomy) ID', |
|
44 | + 'event_espresso' |
|
45 | + ), |
|
46 | + false, |
|
47 | + 0, |
|
48 | + 'Term_Taxonomy' |
|
49 | + ), |
|
50 | + 'term_order' => new EE_Integer_Field( |
|
51 | + 'term_order', |
|
52 | + __('Term Order', 'event_espresso'), |
|
53 | + false, |
|
54 | + 0 |
|
55 | + ), |
|
56 | + ), |
|
57 | + ); |
|
58 | + $this->_model_relations = array( |
|
59 | + 'Term_Taxonomy' => new EE_Belongs_To_Relation(), |
|
60 | + ); |
|
61 | + foreach ($models_this_can_attach_to as $model_name) { |
|
62 | + $this->_model_relations[ $model_name ] = new EE_Belongs_To_Relation(); |
|
63 | + } |
|
64 | + $this->_wp_core_model = true; |
|
65 | + $this->_indexes = array( |
|
66 | + 'PRIMARY' => new EE_Primary_Key_Index(array('object_id', 'term_taxonomy_id')), |
|
67 | + ); |
|
68 | + $path_to_event_model = 'Event'; |
|
69 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Event_Related_Public( |
|
70 | + $path_to_event_model |
|
71 | + ); |
|
72 | + $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
73 | + new EE_Restriction_Generator_Event_Related_Protected( |
|
74 | + $path_to_event_model |
|
75 | + ); |
|
76 | + $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
77 | + $path_to_event_model |
|
78 | + ); |
|
79 | + $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
80 | + new EE_Restriction_Generator_Event_Related_Protected( |
|
81 | + $path_to_event_model, |
|
82 | + EEM_Base::caps_edit |
|
83 | + ); |
|
84 | + $path_to_tax_model = 'Term_Taxonomy.'; |
|
85 | + // add cap restrictions for editing term relations to the "ee_assign_*" |
|
86 | + // and for deleting term relations too |
|
87 | + $cap_contexts_affected = array(EEM_Base::caps_edit, EEM_Base::caps_delete); |
|
88 | + foreach ($cap_contexts_affected as $cap_context_affected) { |
|
89 | + $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_category'] = |
|
90 | + new EE_Default_Where_Conditions( |
|
91 | + array( |
|
92 | + $path_to_tax_model . 'taxonomy*ee_assign_event_category' => array( |
|
93 | + '!=', |
|
94 | + 'espresso_event_categories', |
|
95 | + ), |
|
96 | + ) |
|
97 | + ); |
|
98 | + $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_venue_category'] = |
|
99 | + new EE_Default_Where_Conditions( |
|
100 | + array( |
|
101 | + $path_to_tax_model . 'taxonomy*ee_assign_venue_category' => array( |
|
102 | + '!=', |
|
103 | + 'espresso_venue_categories', |
|
104 | + ), |
|
105 | + ) |
|
106 | + ); |
|
107 | + $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_type'] = new EE_Default_Where_Conditions( |
|
108 | + array( |
|
109 | + $path_to_tax_model . 'taxonomy*ee_assign_event_type' => array('!=', 'espresso_event_type'), |
|
110 | + ) |
|
111 | + ); |
|
112 | + } |
|
113 | + parent::__construct($timezone); |
|
114 | + add_filter( |
|
115 | + 'FHEE__Read__create_model_query_params', |
|
116 | + array('EEM_Term_Relationship', 'rest_api_query_params'), |
|
117 | + 10, |
|
118 | + 3 |
|
119 | + ); |
|
120 | + } |
|
121 | + |
|
122 | + |
|
123 | + /** |
|
124 | + * Makes sure all term-taxonomy counts are correct |
|
125 | + * |
|
126 | + * @param int $term_taxonomy_id the id of the term taxonomy to update. If NULL, updates ALL |
|
127 | + * @global wpdb $wpdb |
|
128 | + * @return int the number of rows affected |
|
129 | + * @throws EE_Error |
|
130 | + */ |
|
131 | + public function update_term_taxonomy_counts($term_taxonomy_id = null) |
|
132 | + { |
|
133 | + // because this uses a subquery and sometimes assigning to column to be another column's |
|
134 | + // value, we just write the SQL directly. |
|
135 | + global $wpdb; |
|
136 | + |
|
137 | + $query = " |
|
138 | 138 | UPDATE {$wpdb->term_taxonomy} AS tt |
139 | 139 | SET count = ( |
140 | 140 | select count(*) as proper_count from {$wpdb->term_relationships} AS tr |
141 | 141 | WHERE tt.term_taxonomy_id = tr.term_taxonomy_id |
142 | 142 | )"; |
143 | 143 | |
144 | - if ($term_taxonomy_id) { |
|
145 | - $query .= ' WHERE tt.term_taxonomy_id = %d'; |
|
146 | - $query = $wpdb->prepare( |
|
147 | - $query, |
|
148 | - $term_taxonomy_id |
|
149 | - ); |
|
150 | - } |
|
151 | - $rows_affected = $this->_do_wpdb_query( |
|
152 | - 'query', |
|
153 | - array( |
|
154 | - $query, |
|
155 | - ) |
|
156 | - ); |
|
157 | - return $rows_affected; |
|
158 | - } |
|
159 | - |
|
160 | - |
|
161 | - |
|
162 | - /** |
|
163 | - * Overrides the parent to also make sure term-taxonomy counts are up-to-date after |
|
164 | - * inserting |
|
165 | - * |
|
166 | - * @param array $field_n_values @see EEM_Base::insert |
|
167 | - * @return boolean |
|
168 | - */ |
|
169 | - public function insert($field_n_values) |
|
170 | - { |
|
171 | - $return = parent::insert($field_n_values); |
|
172 | - if (isset($field_n_values['term_taxonomy_id'])) { |
|
173 | - $this->update_term_taxonomy_counts($field_n_values['term_taxonomy_id']); |
|
174 | - } |
|
175 | - return $return; |
|
176 | - } |
|
177 | - |
|
178 | - |
|
179 | - |
|
180 | - /** |
|
181 | - * Overrides parent so that after an update, we also check the term_taxonomy_counts are |
|
182 | - * all ok |
|
183 | - * |
|
184 | - * @param array $fields_n_values see EEM_Base::update |
|
185 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
186 | - * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects |
|
187 | - * in this model's entity map according to $fields_n_values that match |
|
188 | - * $query_params. This obviously has some overhead, so you can disable it |
|
189 | - * by setting this to FALSE, but be aware that model objects being used |
|
190 | - * could get out-of-sync with the database |
|
191 | - * @return int |
|
192 | - */ |
|
193 | - public function update($fields_n_values, $query_params, $keep_model_objs_in_sync = true) |
|
194 | - { |
|
195 | - $count = parent::update($fields_n_values, $query_params, $keep_model_objs_in_sync); |
|
196 | - if ($count) { |
|
197 | - $this->update_term_taxonomy_counts(); |
|
198 | - } |
|
199 | - return $count; |
|
200 | - } |
|
201 | - |
|
202 | - |
|
203 | - |
|
204 | - /** |
|
205 | - * Overrides parent so that after running this, we also double-check |
|
206 | - * the term taxonomy counts are up-to-date |
|
207 | - * |
|
208 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
209 | - * @param boolean $allow_blocking |
|
210 | - * @return int @see EEM_Base::delete |
|
211 | - */ |
|
212 | - public function delete($query_params, $allow_blocking = true) |
|
213 | - { |
|
214 | - $count = parent::delete($query_params, $allow_blocking); |
|
215 | - if ($count) { |
|
216 | - $this->update_term_taxonomy_counts(); |
|
217 | - } |
|
218 | - return $count; |
|
219 | - } |
|
220 | - |
|
221 | - |
|
222 | - |
|
223 | - /** |
|
224 | - * Makes sure that during REST API queries, we only return term relationships |
|
225 | - * for term taxonomies which should be shown in the rest api |
|
226 | - * |
|
227 | - * @param array $model_query_params |
|
228 | - * @param array $querystring_query_params |
|
229 | - * @param EEM_Base $model |
|
230 | - * @return array |
|
231 | - */ |
|
232 | - public static function rest_api_query_params($model_query_params, $querystring_query_params, $model) |
|
233 | - { |
|
234 | - if ($model === EEM_Term_Relationship::instance()) { |
|
235 | - $taxonomies = get_taxonomies(array('show_in_rest' => true)); |
|
236 | - if (! empty($taxonomies)) { |
|
237 | - $model_query_params[0]['Term_Taxonomy.taxonomy'] = array('IN', $taxonomies); |
|
238 | - } |
|
239 | - } |
|
240 | - return $model_query_params; |
|
241 | - } |
|
144 | + if ($term_taxonomy_id) { |
|
145 | + $query .= ' WHERE tt.term_taxonomy_id = %d'; |
|
146 | + $query = $wpdb->prepare( |
|
147 | + $query, |
|
148 | + $term_taxonomy_id |
|
149 | + ); |
|
150 | + } |
|
151 | + $rows_affected = $this->_do_wpdb_query( |
|
152 | + 'query', |
|
153 | + array( |
|
154 | + $query, |
|
155 | + ) |
|
156 | + ); |
|
157 | + return $rows_affected; |
|
158 | + } |
|
159 | + |
|
160 | + |
|
161 | + |
|
162 | + /** |
|
163 | + * Overrides the parent to also make sure term-taxonomy counts are up-to-date after |
|
164 | + * inserting |
|
165 | + * |
|
166 | + * @param array $field_n_values @see EEM_Base::insert |
|
167 | + * @return boolean |
|
168 | + */ |
|
169 | + public function insert($field_n_values) |
|
170 | + { |
|
171 | + $return = parent::insert($field_n_values); |
|
172 | + if (isset($field_n_values['term_taxonomy_id'])) { |
|
173 | + $this->update_term_taxonomy_counts($field_n_values['term_taxonomy_id']); |
|
174 | + } |
|
175 | + return $return; |
|
176 | + } |
|
177 | + |
|
178 | + |
|
179 | + |
|
180 | + /** |
|
181 | + * Overrides parent so that after an update, we also check the term_taxonomy_counts are |
|
182 | + * all ok |
|
183 | + * |
|
184 | + * @param array $fields_n_values see EEM_Base::update |
|
185 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
186 | + * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects |
|
187 | + * in this model's entity map according to $fields_n_values that match |
|
188 | + * $query_params. This obviously has some overhead, so you can disable it |
|
189 | + * by setting this to FALSE, but be aware that model objects being used |
|
190 | + * could get out-of-sync with the database |
|
191 | + * @return int |
|
192 | + */ |
|
193 | + public function update($fields_n_values, $query_params, $keep_model_objs_in_sync = true) |
|
194 | + { |
|
195 | + $count = parent::update($fields_n_values, $query_params, $keep_model_objs_in_sync); |
|
196 | + if ($count) { |
|
197 | + $this->update_term_taxonomy_counts(); |
|
198 | + } |
|
199 | + return $count; |
|
200 | + } |
|
201 | + |
|
202 | + |
|
203 | + |
|
204 | + /** |
|
205 | + * Overrides parent so that after running this, we also double-check |
|
206 | + * the term taxonomy counts are up-to-date |
|
207 | + * |
|
208 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
209 | + * @param boolean $allow_blocking |
|
210 | + * @return int @see EEM_Base::delete |
|
211 | + */ |
|
212 | + public function delete($query_params, $allow_blocking = true) |
|
213 | + { |
|
214 | + $count = parent::delete($query_params, $allow_blocking); |
|
215 | + if ($count) { |
|
216 | + $this->update_term_taxonomy_counts(); |
|
217 | + } |
|
218 | + return $count; |
|
219 | + } |
|
220 | + |
|
221 | + |
|
222 | + |
|
223 | + /** |
|
224 | + * Makes sure that during REST API queries, we only return term relationships |
|
225 | + * for term taxonomies which should be shown in the rest api |
|
226 | + * |
|
227 | + * @param array $model_query_params |
|
228 | + * @param array $querystring_query_params |
|
229 | + * @param EEM_Base $model |
|
230 | + * @return array |
|
231 | + */ |
|
232 | + public static function rest_api_query_params($model_query_params, $querystring_query_params, $model) |
|
233 | + { |
|
234 | + if ($model === EEM_Term_Relationship::instance()) { |
|
235 | + $taxonomies = get_taxonomies(array('show_in_rest' => true)); |
|
236 | + if (! empty($taxonomies)) { |
|
237 | + $model_query_params[0]['Term_Taxonomy.taxonomy'] = array('IN', $taxonomies); |
|
238 | + } |
|
239 | + } |
|
240 | + return $model_query_params; |
|
241 | + } |
|
242 | 242 | } |
@@ -14,40 +14,40 @@ |
||
14 | 14 | class EEM_Checkin extends EEM_Base |
15 | 15 | { |
16 | 16 | |
17 | - // private instance of the EEM_Checkin object |
|
18 | - protected static $_instance = null; |
|
17 | + // private instance of the EEM_Checkin object |
|
18 | + protected static $_instance = null; |
|
19 | 19 | |
20 | 20 | |
21 | 21 | |
22 | - /** |
|
23 | - * private constructor to prevent direct creation |
|
24 | - * @Constructor |
|
25 | - * @access protected |
|
26 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any incoming timezone data that gets saved). Note this just sends the timezone info to the date time model field objects. Default is NULL (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
27 | - * @return void |
|
28 | - */ |
|
29 | - protected function __construct($timezone = '') |
|
30 | - { |
|
31 | - $this->singular_item = __('Check-In', 'event_espresso'); |
|
32 | - $this->plural_item = __('Check-Ins', 'event_espresso'); |
|
22 | + /** |
|
23 | + * private constructor to prevent direct creation |
|
24 | + * @Constructor |
|
25 | + * @access protected |
|
26 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any incoming timezone data that gets saved). Note this just sends the timezone info to the date time model field objects. Default is NULL (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
27 | + * @return void |
|
28 | + */ |
|
29 | + protected function __construct($timezone = '') |
|
30 | + { |
|
31 | + $this->singular_item = __('Check-In', 'event_espresso'); |
|
32 | + $this->plural_item = __('Check-Ins', 'event_espresso'); |
|
33 | 33 | |
34 | - $this->_tables = array( |
|
35 | - 'Checkin' => new EE_Primary_Table('esp_checkin', 'CHK_ID') |
|
36 | - ); |
|
37 | - $this->_fields = array( |
|
38 | - 'Checkin' => array( |
|
39 | - 'CHK_ID' => new EE_Primary_Key_Int_Field('CHK_ID', 'Check-in ID'), |
|
40 | - 'REG_ID' => new EE_Foreign_Key_Int_Field('REG_ID', 'Registration Id', false, 0, 'Registration'), |
|
41 | - 'DTT_ID' => new EE_Foreign_Key_Int_Field('DTT_ID', 'Datetime Id', false, 0, 'Datetime'), |
|
42 | - 'CHK_in' => new EE_Boolean_Field('CHK_in', 'Whether a person has checked in or checked out', false, true), |
|
43 | - 'CHK_timestamp' => new EE_Datetime_Field('CHK_timestamp', __('When the row was modified', 'event_espresso'), false, EE_Datetime_Field::now, $timezone) |
|
44 | - ) |
|
45 | - ); |
|
46 | - $this->_model_relations = array( |
|
47 | - 'Registration' => new EE_Belongs_To_Relation(), |
|
48 | - 'Datetime' => new EE_Belongs_To_Relation() |
|
49 | - ); |
|
50 | - $this->_model_chain_to_wp_user = 'Registration.Event'; |
|
51 | - parent::__construct($timezone); |
|
52 | - } |
|
34 | + $this->_tables = array( |
|
35 | + 'Checkin' => new EE_Primary_Table('esp_checkin', 'CHK_ID') |
|
36 | + ); |
|
37 | + $this->_fields = array( |
|
38 | + 'Checkin' => array( |
|
39 | + 'CHK_ID' => new EE_Primary_Key_Int_Field('CHK_ID', 'Check-in ID'), |
|
40 | + 'REG_ID' => new EE_Foreign_Key_Int_Field('REG_ID', 'Registration Id', false, 0, 'Registration'), |
|
41 | + 'DTT_ID' => new EE_Foreign_Key_Int_Field('DTT_ID', 'Datetime Id', false, 0, 'Datetime'), |
|
42 | + 'CHK_in' => new EE_Boolean_Field('CHK_in', 'Whether a person has checked in or checked out', false, true), |
|
43 | + 'CHK_timestamp' => new EE_Datetime_Field('CHK_timestamp', __('When the row was modified', 'event_espresso'), false, EE_Datetime_Field::now, $timezone) |
|
44 | + ) |
|
45 | + ); |
|
46 | + $this->_model_relations = array( |
|
47 | + 'Registration' => new EE_Belongs_To_Relation(), |
|
48 | + 'Datetime' => new EE_Belongs_To_Relation() |
|
49 | + ); |
|
50 | + $this->_model_chain_to_wp_user = 'Registration.Event'; |
|
51 | + parent::__construct($timezone); |
|
52 | + } |
|
53 | 53 | } |
@@ -11,31 +11,31 @@ |
||
11 | 11 | */ |
12 | 12 | class EEM_Currency_Payment_Method extends EEM_Base |
13 | 13 | { |
14 | - // private instance of the Attendee object |
|
15 | - protected static $_instance = null; |
|
14 | + // private instance of the Attendee object |
|
15 | + protected static $_instance = null; |
|
16 | 16 | |
17 | 17 | |
18 | - protected function __construct($timezone = '') |
|
19 | - { |
|
20 | - $this->singular_item = __('Currency Usable by Payment Method', 'event_espresso'); |
|
21 | - $this->plural_item = __('Currencies Usable by Payment Methods', 'event_espresso'); |
|
22 | - $this->_tables = array( |
|
23 | - 'Currency_Payment_Method' => new EE_Primary_Table('esp_currency_payment_method', 'CPM_ID') |
|
24 | - ); |
|
25 | - $this->_fields = array( |
|
26 | - 'Currency_Payment_Method' => array( |
|
27 | - 'CPM_ID' => new EE_Primary_Key_Int_Field('CPM_ID', __('Currency to Payment Method LInk ID', 'event_espresso')), |
|
28 | - 'CUR_code' => new EE_Foreign_Key_String_Field('CUR_code', __('Currency Code', 'event_espresso'), false, '', 'Currency'), |
|
29 | - 'PMD_ID' => new EE_Foreign_Key_Int_Field('PMD_ID', __('Paymetn Method ID', 'event_espresso'), false, 0, 'Payment_Method') |
|
30 | - ) |
|
31 | - ); |
|
32 | - $this->_model_relations = array( |
|
33 | - 'Currency' => new EE_Belongs_To_Relation(), |
|
34 | - 'Payment_Method' => new EE_Belongs_To_Relation() |
|
35 | - ); |
|
36 | - // this model is generally available for reading |
|
37 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public(); |
|
38 | - $this->_caps_slug = 'payment_methods'; |
|
39 | - parent::__construct($timezone); |
|
40 | - } |
|
18 | + protected function __construct($timezone = '') |
|
19 | + { |
|
20 | + $this->singular_item = __('Currency Usable by Payment Method', 'event_espresso'); |
|
21 | + $this->plural_item = __('Currencies Usable by Payment Methods', 'event_espresso'); |
|
22 | + $this->_tables = array( |
|
23 | + 'Currency_Payment_Method' => new EE_Primary_Table('esp_currency_payment_method', 'CPM_ID') |
|
24 | + ); |
|
25 | + $this->_fields = array( |
|
26 | + 'Currency_Payment_Method' => array( |
|
27 | + 'CPM_ID' => new EE_Primary_Key_Int_Field('CPM_ID', __('Currency to Payment Method LInk ID', 'event_espresso')), |
|
28 | + 'CUR_code' => new EE_Foreign_Key_String_Field('CUR_code', __('Currency Code', 'event_espresso'), false, '', 'Currency'), |
|
29 | + 'PMD_ID' => new EE_Foreign_Key_Int_Field('PMD_ID', __('Paymetn Method ID', 'event_espresso'), false, 0, 'Payment_Method') |
|
30 | + ) |
|
31 | + ); |
|
32 | + $this->_model_relations = array( |
|
33 | + 'Currency' => new EE_Belongs_To_Relation(), |
|
34 | + 'Payment_Method' => new EE_Belongs_To_Relation() |
|
35 | + ); |
|
36 | + // this model is generally available for reading |
|
37 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public(); |
|
38 | + $this->_caps_slug = 'payment_methods'; |
|
39 | + parent::__construct($timezone); |
|
40 | + } |
|
41 | 41 | } |
@@ -15,916 +15,916 @@ |
||
15 | 15 | class EEM_Event extends EEM_CPT_Base |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the |
|
20 | - * event |
|
21 | - */ |
|
22 | - const sold_out = 'sold_out'; |
|
23 | - |
|
24 | - /** |
|
25 | - * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later |
|
26 | - * date) |
|
27 | - */ |
|
28 | - const postponed = 'postponed'; |
|
29 | - |
|
30 | - /** |
|
31 | - * constant used by status(), indicating that the event will no longer occur |
|
32 | - */ |
|
33 | - const cancelled = 'cancelled'; |
|
34 | - |
|
35 | - |
|
36 | - /** |
|
37 | - * @var string |
|
38 | - */ |
|
39 | - protected static $_default_reg_status; |
|
40 | - |
|
41 | - |
|
42 | - /** |
|
43 | - * This is the default for the additional limit field. |
|
44 | - * @var int |
|
45 | - */ |
|
46 | - protected static $_default_additional_limit = 10; |
|
47 | - |
|
48 | - |
|
49 | - /** |
|
50 | - * private instance of the Event object |
|
51 | - * |
|
52 | - * @var EEM_Event |
|
53 | - */ |
|
54 | - protected static $_instance; |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * Adds a relationship to Term_Taxonomy for each CPT_Base |
|
59 | - * |
|
60 | - * @param string $timezone |
|
61 | - * @throws \EE_Error |
|
62 | - * @throws ReflectionException |
|
63 | - */ |
|
64 | - protected function __construct($timezone = '') |
|
65 | - { |
|
66 | - EE_Registry::instance()->load_model('Registration'); |
|
67 | - $this->singular_item = esc_html__('Event', 'event_espresso'); |
|
68 | - $this->plural_item = esc_html__('Events', 'event_espresso'); |
|
69 | - // to remove Cancelled events from the frontend, copy the following filter to your functions.php file |
|
70 | - // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' ); |
|
71 | - // to remove Postponed events from the frontend, copy the following filter to your functions.php file |
|
72 | - // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' ); |
|
73 | - // to remove Sold Out events from the frontend, copy the following filter to your functions.php file |
|
74 | - // add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' ); |
|
75 | - $this->_custom_stati = apply_filters( |
|
76 | - 'AFEE__EEM_Event__construct___custom_stati', |
|
77 | - array( |
|
78 | - EEM_Event::cancelled => array( |
|
79 | - 'label' => esc_html__('Cancelled', 'event_espresso'), |
|
80 | - 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true), |
|
81 | - ), |
|
82 | - EEM_Event::postponed => array( |
|
83 | - 'label' => esc_html__('Postponed', 'event_espresso'), |
|
84 | - 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true), |
|
85 | - ), |
|
86 | - EEM_Event::sold_out => array( |
|
87 | - 'label' => esc_html__('Sold Out', 'event_espresso'), |
|
88 | - 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true), |
|
89 | - ), |
|
90 | - ) |
|
91 | - ); |
|
92 | - self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment |
|
93 | - : self::$_default_reg_status; |
|
94 | - $this->_tables = array( |
|
95 | - 'Event_CPT' => new EE_Primary_Table('posts', 'ID'), |
|
96 | - 'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'), |
|
97 | - ); |
|
98 | - $this->_fields = array( |
|
99 | - 'Event_CPT' => array( |
|
100 | - 'EVT_ID' => new EE_Primary_Key_Int_Field( |
|
101 | - 'ID', |
|
102 | - esc_html__('Post ID for Event', 'event_espresso') |
|
103 | - ), |
|
104 | - 'EVT_name' => new EE_Plain_Text_Field( |
|
105 | - 'post_title', |
|
106 | - esc_html__('Event Name', 'event_espresso'), |
|
107 | - false, |
|
108 | - '' |
|
109 | - ), |
|
110 | - 'EVT_desc' => new EE_Post_Content_Field( |
|
111 | - 'post_content', |
|
112 | - esc_html__('Event Description', 'event_espresso'), |
|
113 | - false, |
|
114 | - '' |
|
115 | - ), |
|
116 | - 'EVT_slug' => new EE_Slug_Field( |
|
117 | - 'post_name', |
|
118 | - esc_html__('Event Slug', 'event_espresso'), |
|
119 | - false, |
|
120 | - '' |
|
121 | - ), |
|
122 | - 'EVT_created' => new EE_Datetime_Field( |
|
123 | - 'post_date', |
|
124 | - esc_html__('Date/Time Event Created', 'event_espresso'), |
|
125 | - false, |
|
126 | - EE_Datetime_Field::now |
|
127 | - ), |
|
128 | - 'EVT_short_desc' => new EE_Simple_HTML_Field( |
|
129 | - 'post_excerpt', |
|
130 | - esc_html__('Event Short Description', 'event_espresso'), |
|
131 | - false, |
|
132 | - '' |
|
133 | - ), |
|
134 | - 'EVT_modified' => new EE_Datetime_Field( |
|
135 | - 'post_modified', |
|
136 | - esc_html__('Date/Time Event Modified', 'event_espresso'), |
|
137 | - false, |
|
138 | - EE_Datetime_Field::now |
|
139 | - ), |
|
140 | - 'EVT_wp_user' => new EE_WP_User_Field( |
|
141 | - 'post_author', |
|
142 | - esc_html__('Event Creator ID', 'event_espresso'), |
|
143 | - false |
|
144 | - ), |
|
145 | - 'parent' => new EE_Integer_Field( |
|
146 | - 'post_parent', |
|
147 | - esc_html__('Event Parent ID', 'event_espresso'), |
|
148 | - false, |
|
149 | - 0 |
|
150 | - ), |
|
151 | - 'EVT_order' => new EE_Integer_Field( |
|
152 | - 'menu_order', |
|
153 | - esc_html__('Event Menu Order', 'event_espresso'), |
|
154 | - false, |
|
155 | - 1 |
|
156 | - ), |
|
157 | - 'post_type' => new EE_WP_Post_Type_Field('espresso_events'), |
|
158 | - // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ), |
|
159 | - 'status' => new EE_WP_Post_Status_Field( |
|
160 | - 'post_status', |
|
161 | - esc_html__('Event Status', 'event_espresso'), |
|
162 | - false, |
|
163 | - 'draft', |
|
164 | - $this->_custom_stati |
|
165 | - ), |
|
166 | - 'password' => new EE_Password_Field( |
|
167 | - 'post_password', |
|
168 | - __('Password', 'event_espresso'), |
|
169 | - false, |
|
170 | - '', |
|
171 | - array( |
|
172 | - 'EVT_desc', |
|
173 | - 'EVT_short_desc', |
|
174 | - 'EVT_display_desc', |
|
175 | - 'EVT_display_ticket_selector', |
|
176 | - 'EVT_visible_on', |
|
177 | - 'EVT_additional_limit', |
|
178 | - 'EVT_default_registration_status', |
|
179 | - 'EVT_member_only', |
|
180 | - 'EVT_phone', |
|
181 | - 'EVT_allow_overflow', |
|
182 | - 'EVT_timezone_string', |
|
183 | - 'EVT_external_URL', |
|
184 | - 'EVT_donations' |
|
185 | - ) |
|
186 | - ) |
|
187 | - ), |
|
188 | - 'Event_Meta' => array( |
|
189 | - 'EVTM_ID' => new EE_DB_Only_Float_Field( |
|
190 | - 'EVTM_ID', |
|
191 | - esc_html__('Event Meta Row ID', 'event_espresso'), |
|
192 | - false |
|
193 | - ), |
|
194 | - 'EVT_ID_fk' => new EE_DB_Only_Int_Field( |
|
195 | - 'EVT_ID', |
|
196 | - esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'), |
|
197 | - false |
|
198 | - ), |
|
199 | - 'EVT_display_desc' => new EE_Boolean_Field( |
|
200 | - 'EVT_display_desc', |
|
201 | - esc_html__('Display Description Flag', 'event_espresso'), |
|
202 | - false, |
|
203 | - true |
|
204 | - ), |
|
205 | - 'EVT_display_ticket_selector' => new EE_Boolean_Field( |
|
206 | - 'EVT_display_ticket_selector', |
|
207 | - esc_html__('Display Ticket Selector Flag', 'event_espresso'), |
|
208 | - false, |
|
209 | - true |
|
210 | - ), |
|
211 | - 'EVT_visible_on' => new EE_Datetime_Field( |
|
212 | - 'EVT_visible_on', |
|
213 | - esc_html__('Event Visible Date', 'event_espresso'), |
|
214 | - true, |
|
215 | - EE_Datetime_Field::now |
|
216 | - ), |
|
217 | - 'EVT_additional_limit' => new EE_Integer_Field( |
|
218 | - 'EVT_additional_limit', |
|
219 | - esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
220 | - true, |
|
221 | - self::$_default_additional_limit |
|
222 | - ), |
|
223 | - 'EVT_default_registration_status' => new EE_Enum_Text_Field( |
|
224 | - 'EVT_default_registration_status', |
|
225 | - esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
226 | - false, |
|
227 | - EEM_Event::$_default_reg_status, |
|
228 | - EEM_Registration::reg_status_array() |
|
229 | - ), |
|
230 | - 'EVT_member_only' => new EE_Boolean_Field( |
|
231 | - 'EVT_member_only', |
|
232 | - esc_html__('Member-Only Event Flag', 'event_espresso'), |
|
233 | - false, |
|
234 | - false |
|
235 | - ), |
|
236 | - 'EVT_phone' => new EE_Plain_Text_Field( |
|
237 | - 'EVT_phone', |
|
238 | - esc_html__('Event Phone Number', 'event_espresso'), |
|
239 | - false, |
|
240 | - '' |
|
241 | - ), |
|
242 | - 'EVT_allow_overflow' => new EE_Boolean_Field( |
|
243 | - 'EVT_allow_overflow', |
|
244 | - esc_html__('Allow Overflow on Event', 'event_espresso'), |
|
245 | - false, |
|
246 | - false |
|
247 | - ), |
|
248 | - 'EVT_timezone_string' => new EE_Plain_Text_Field( |
|
249 | - 'EVT_timezone_string', |
|
250 | - esc_html__('Timezone (name) for Event times', 'event_espresso'), |
|
251 | - false, |
|
252 | - '' |
|
253 | - ), |
|
254 | - 'EVT_external_URL' => new EE_Plain_Text_Field( |
|
255 | - 'EVT_external_URL', |
|
256 | - esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'), |
|
257 | - true |
|
258 | - ), |
|
259 | - 'EVT_donations' => new EE_Boolean_Field( |
|
260 | - 'EVT_donations', |
|
261 | - esc_html__('Accept Donations?', 'event_espresso'), |
|
262 | - false, |
|
263 | - false |
|
264 | - ), |
|
265 | - ), |
|
266 | - ); |
|
267 | - $this->_model_relations = array( |
|
268 | - 'Registration' => new EE_Has_Many_Relation(), |
|
269 | - 'Datetime' => new EE_Has_Many_Relation(), |
|
270 | - 'Question_Group' => new EE_HABTM_Relation('Event_Question_Group'), |
|
271 | - 'Event_Question_Group' => new EE_Has_Many_Relation(), |
|
272 | - 'Venue' => new EE_HABTM_Relation('Event_Venue'), |
|
273 | - 'Term_Relationship' => new EE_Has_Many_Relation(), |
|
274 | - 'Term_Taxonomy' => new EE_HABTM_Relation('Term_Relationship'), |
|
275 | - 'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'), |
|
276 | - 'Attendee' => new EE_HABTM_Relation('Registration'), |
|
277 | - 'WP_User' => new EE_Belongs_To_Relation(), |
|
278 | - ); |
|
279 | - // this model is generally available for reading |
|
280 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public(); |
|
281 | - $this->model_chain_to_password = ''; |
|
282 | - parent::__construct($timezone); |
|
283 | - } |
|
284 | - |
|
285 | - |
|
286 | - /** |
|
287 | - * @param string $default_reg_status |
|
288 | - * @throws EE_Error |
|
289 | - * @throws EE_Error |
|
290 | - */ |
|
291 | - public static function set_default_reg_status($default_reg_status) |
|
292 | - { |
|
293 | - self::$_default_reg_status = $default_reg_status; |
|
294 | - // if EEM_Event has already been instantiated, |
|
295 | - // then we need to reset the `EVT_default_reg_status` field to use the new default. |
|
296 | - if (self::$_instance instanceof EEM_Event) { |
|
297 | - $default_reg_status = new EE_Enum_Text_Field( |
|
298 | - 'EVT_default_registration_status', |
|
299 | - esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
300 | - false, |
|
301 | - $default_reg_status, |
|
302 | - EEM_Registration::reg_status_array() |
|
303 | - ); |
|
304 | - $default_reg_status->_construct_finalize( |
|
305 | - 'Event_Meta', |
|
306 | - 'EVT_default_registration_status', |
|
307 | - 'EEM_Event' |
|
308 | - ); |
|
309 | - self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status; |
|
310 | - } |
|
311 | - } |
|
312 | - |
|
313 | - |
|
314 | - /** |
|
315 | - * Used to override the default for the additional limit field. |
|
316 | - * @param $additional_limit |
|
317 | - */ |
|
318 | - public static function set_default_additional_limit($additional_limit) |
|
319 | - { |
|
320 | - self::$_default_additional_limit = (int) $additional_limit; |
|
321 | - if (self::$_instance instanceof EEM_Event) { |
|
322 | - self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field( |
|
323 | - 'EVT_additional_limit', |
|
324 | - __('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
325 | - true, |
|
326 | - self::$_default_additional_limit |
|
327 | - ); |
|
328 | - self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize( |
|
329 | - 'Event_Meta', |
|
330 | - 'EVT_additional_limit', |
|
331 | - 'EEM_Event' |
|
332 | - ); |
|
333 | - } |
|
334 | - } |
|
335 | - |
|
336 | - |
|
337 | - /** |
|
338 | - * Return what is currently set as the default additional limit for the event. |
|
339 | - * @return int |
|
340 | - */ |
|
341 | - public static function get_default_additional_limit() |
|
342 | - { |
|
343 | - return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit); |
|
344 | - } |
|
345 | - |
|
346 | - |
|
347 | - /** |
|
348 | - * get_question_groups |
|
349 | - * |
|
350 | - * @return array |
|
351 | - * @throws \EE_Error |
|
352 | - * @throws ReflectionException |
|
353 | - */ |
|
354 | - public function get_all_question_groups() |
|
355 | - { |
|
356 | - return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
357 | - array( |
|
358 | - array('QSG_deleted' => false), |
|
359 | - 'order_by' => array('QSG_order' => 'ASC'), |
|
360 | - ) |
|
361 | - ); |
|
362 | - } |
|
363 | - |
|
364 | - |
|
365 | - /** |
|
366 | - * get_question_groups |
|
367 | - * |
|
368 | - * @param int $EVT_ID |
|
369 | - * @return array|bool |
|
370 | - * @throws \EE_Error |
|
371 | - * @throws ReflectionException |
|
372 | - */ |
|
373 | - public function get_all_event_question_groups($EVT_ID = 0) |
|
374 | - { |
|
375 | - if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
376 | - EE_Error::add_error( |
|
377 | - esc_html__( |
|
378 | - 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
379 | - 'event_espresso' |
|
380 | - ), |
|
381 | - __FILE__, |
|
382 | - __FUNCTION__, |
|
383 | - __LINE__ |
|
384 | - ); |
|
385 | - return false; |
|
386 | - } |
|
387 | - return EE_Registry::instance()->load_model('Event_Question_Group')->get_all( |
|
388 | - array( |
|
389 | - array('EVT_ID' => $EVT_ID), |
|
390 | - ) |
|
391 | - ); |
|
392 | - } |
|
393 | - |
|
394 | - |
|
395 | - /** |
|
396 | - * get_question_groups |
|
397 | - * |
|
398 | - * @param int $EVT_ID |
|
399 | - * @param boolean $for_primary_attendee |
|
400 | - * @return array|bool |
|
401 | - * @throws EE_Error |
|
402 | - * @throws InvalidArgumentException |
|
403 | - * @throws ReflectionException |
|
404 | - * @throws InvalidDataTypeException |
|
405 | - * @throws InvalidInterfaceException |
|
406 | - */ |
|
407 | - public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true) |
|
408 | - { |
|
409 | - if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
410 | - EE_Error::add_error( |
|
411 | - esc_html__( |
|
412 | - // @codingStandardsIgnoreStart |
|
413 | - 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
414 | - // @codingStandardsIgnoreEnd |
|
415 | - 'event_espresso' |
|
416 | - ), |
|
417 | - __FILE__, |
|
418 | - __FUNCTION__, |
|
419 | - __LINE__ |
|
420 | - ); |
|
421 | - return false; |
|
422 | - } |
|
423 | - $query_params = [ |
|
424 | - [ |
|
425 | - 'EVT_ID' => $EVT_ID, |
|
426 | - EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true |
|
427 | - ] |
|
428 | - ]; |
|
429 | - if ($for_primary_attendee) { |
|
430 | - $query_params[0]['EQG_primary'] = true; |
|
431 | - } else { |
|
432 | - $query_params[0]['EQG_additional'] = true; |
|
433 | - } |
|
434 | - return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params); |
|
435 | - } |
|
436 | - |
|
437 | - |
|
438 | - /** |
|
439 | - * get_question_groups |
|
440 | - * |
|
441 | - * @param int $EVT_ID |
|
442 | - * @param EE_Registration $registration |
|
443 | - * @return array|bool |
|
444 | - * @throws EE_Error |
|
445 | - * @throws InvalidArgumentException |
|
446 | - * @throws InvalidDataTypeException |
|
447 | - * @throws InvalidInterfaceException |
|
448 | - * @throws ReflectionException |
|
449 | - */ |
|
450 | - public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration) |
|
451 | - { |
|
452 | - if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
453 | - EE_Error::add_error( |
|
454 | - esc_html__( |
|
455 | - 'An error occurred. No Question Groups could be retrieved because an Event ID was not received.', |
|
456 | - 'event_espresso' |
|
457 | - ), |
|
458 | - __FILE__, |
|
459 | - __FUNCTION__, |
|
460 | - __LINE__ |
|
461 | - ); |
|
462 | - return false; |
|
463 | - } |
|
464 | - return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
465 | - [ |
|
466 | - [ |
|
467 | - 'Event_Question_Group.EVT_ID' => $EVT_ID, |
|
468 | - 'Event_Question_Group.' |
|
469 | - . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
470 | - $registration->is_primary_registrant() |
|
471 | - ) => true |
|
472 | - ], |
|
473 | - 'order_by' => ['QSG_order' => 'ASC'], |
|
474 | - ] |
|
475 | - ); |
|
476 | - } |
|
477 | - |
|
478 | - |
|
479 | - /** |
|
480 | - * get_question_target_db_column |
|
481 | - * |
|
482 | - * @param string $QSG_IDs csv list of $QSG IDs |
|
483 | - * @return array|bool |
|
484 | - * @throws \EE_Error |
|
485 | - * @throws ReflectionException |
|
486 | - */ |
|
487 | - public function get_questions_in_groups($QSG_IDs = '') |
|
488 | - { |
|
489 | - if (empty($QSG_IDs)) { |
|
490 | - EE_Error::add_error( |
|
491 | - esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'), |
|
492 | - __FILE__, |
|
493 | - __FUNCTION__, |
|
494 | - __LINE__ |
|
495 | - ); |
|
496 | - return false; |
|
497 | - } |
|
498 | - return EE_Registry::instance()->load_model('Question')->get_all( |
|
499 | - array( |
|
500 | - array( |
|
501 | - 'Question_Group.QSG_ID' => array('IN', $QSG_IDs), |
|
502 | - 'QST_deleted' => false, |
|
503 | - 'QST_admin_only' => is_admin(), |
|
504 | - ), |
|
505 | - 'order_by' => 'QST_order', |
|
506 | - ) |
|
507 | - ); |
|
508 | - } |
|
509 | - |
|
510 | - |
|
511 | - /** |
|
512 | - * get_options_for_question |
|
513 | - * |
|
514 | - * @param string $QST_IDs csv list of $QST IDs |
|
515 | - * @return array|bool |
|
516 | - * @throws \EE_Error |
|
517 | - * @throws ReflectionException |
|
518 | - */ |
|
519 | - public function get_options_for_question($QST_IDs) |
|
520 | - { |
|
521 | - if (empty($QST_IDs)) { |
|
522 | - EE_Error::add_error( |
|
523 | - esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'), |
|
524 | - __FILE__, |
|
525 | - __FUNCTION__, |
|
526 | - __LINE__ |
|
527 | - ); |
|
528 | - return false; |
|
529 | - } |
|
530 | - return EE_Registry::instance()->load_model('Question_Option')->get_all( |
|
531 | - array( |
|
532 | - array( |
|
533 | - 'Question.QST_ID' => array('IN', $QST_IDs), |
|
534 | - 'QSO_deleted' => false, |
|
535 | - ), |
|
536 | - 'order_by' => 'QSO_ID', |
|
537 | - ) |
|
538 | - ); |
|
539 | - } |
|
540 | - |
|
541 | - |
|
542 | - /** |
|
543 | - * Gets all events that are published |
|
544 | - * and have event start time earlier than now and an event end time later than now |
|
545 | - * |
|
546 | - * @param array $query_params An array of query params to further filter on |
|
547 | - * (note that status and DTT_EVT_start and DTT_EVT_end will be overridden) |
|
548 | - * @param bool $count whether to return the count or not (default FALSE) |
|
549 | - * @return EE_Event[]|int |
|
550 | - * @throws \EE_Error |
|
551 | - * @throws ReflectionException |
|
552 | - */ |
|
553 | - public function get_active_events($query_params, $count = false) |
|
554 | - { |
|
555 | - if (array_key_exists(0, $query_params)) { |
|
556 | - $where_params = $query_params[0]; |
|
557 | - unset($query_params[0]); |
|
558 | - } else { |
|
559 | - $where_params = array(); |
|
560 | - } |
|
561 | - // if we have count make sure we don't include group by |
|
562 | - if ($count && isset($query_params['group_by'])) { |
|
563 | - unset($query_params['group_by']); |
|
564 | - } |
|
565 | - // let's add specific query_params for active_events |
|
566 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
567 | - $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
568 | - // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions |
|
569 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
570 | - $where_params['Datetime.DTT_EVT_start******'] = array( |
|
571 | - '<', |
|
572 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
573 | - ); |
|
574 | - } else { |
|
575 | - $where_params['Datetime.DTT_EVT_start'] = array( |
|
576 | - '<', |
|
577 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
578 | - ); |
|
579 | - } |
|
580 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
581 | - $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
582 | - '>', |
|
583 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
584 | - ); |
|
585 | - } else { |
|
586 | - $where_params['Datetime.DTT_EVT_end'] = array( |
|
587 | - '>', |
|
588 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
589 | - ); |
|
590 | - } |
|
591 | - $query_params[0] = $where_params; |
|
592 | - // don't use $query_params with count() |
|
593 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
594 | - return $count |
|
595 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
596 | - : $this->get_all($query_params); |
|
597 | - } |
|
598 | - |
|
599 | - |
|
600 | - /** |
|
601 | - * get all events that are published and have an event start time later than now |
|
602 | - * |
|
603 | - * @param array $query_params An array of query params to further filter on |
|
604 | - * (Note that status and DTT_EVT_start will be overridden) |
|
605 | - * @param bool $count whether to return the count or not (default FALSE) |
|
606 | - * @return EE_Event[]|int |
|
607 | - * @throws \EE_Error |
|
608 | - * @throws ReflectionException |
|
609 | - */ |
|
610 | - public function get_upcoming_events($query_params, $count = false) |
|
611 | - { |
|
612 | - if (array_key_exists(0, $query_params)) { |
|
613 | - $where_params = $query_params[0]; |
|
614 | - unset($query_params[0]); |
|
615 | - } else { |
|
616 | - $where_params = array(); |
|
617 | - } |
|
618 | - // if we have count make sure we don't include group by |
|
619 | - if ($count && isset($query_params['group_by'])) { |
|
620 | - unset($query_params['group_by']); |
|
621 | - } |
|
622 | - // let's add specific query_params for active_events |
|
623 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
624 | - // we need to pull events with a status of publish and sold_out |
|
625 | - $event_status = array('publish', EEM_Event::sold_out); |
|
626 | - // check if the user can read private events and if so add the 'private status to the were params' |
|
627 | - if (EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_upcoming_events')) { |
|
628 | - $event_status[] = 'private'; |
|
629 | - } |
|
630 | - $where_params['status'] = array('IN', $event_status); |
|
631 | - // if there are already query_params matching DTT_EVT_start then we need to modify that to add them. |
|
632 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
633 | - $where_params['Datetime.DTT_EVT_start*****'] = array( |
|
634 | - '>', |
|
635 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
636 | - ); |
|
637 | - } else { |
|
638 | - $where_params['Datetime.DTT_EVT_start'] = array( |
|
639 | - '>', |
|
640 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
641 | - ); |
|
642 | - } |
|
643 | - $query_params[0] = $where_params; |
|
644 | - // don't use $query_params with count() |
|
645 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
646 | - return $count |
|
647 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
648 | - : $this->get_all($query_params); |
|
649 | - } |
|
650 | - |
|
651 | - |
|
652 | - /** |
|
653 | - * Gets all events that are published |
|
654 | - * and have an event end time later than now |
|
655 | - * |
|
656 | - * @param array $query_params An array of query params to further filter on |
|
657 | - * (note that status and DTT_EVT_end will be overridden) |
|
658 | - * @param bool $count whether to return the count or not (default FALSE) |
|
659 | - * @return EE_Event[]|int |
|
660 | - * @throws \EE_Error |
|
661 | - * @throws ReflectionException |
|
662 | - */ |
|
663 | - public function get_active_and_upcoming_events($query_params, $count = false) |
|
664 | - { |
|
665 | - if (array_key_exists(0, $query_params)) { |
|
666 | - $where_params = $query_params[0]; |
|
667 | - unset($query_params[0]); |
|
668 | - } else { |
|
669 | - $where_params = array(); |
|
670 | - } |
|
671 | - // if we have count make sure we don't include group by |
|
672 | - if ($count && isset($query_params['group_by'])) { |
|
673 | - unset($query_params['group_by']); |
|
674 | - } |
|
675 | - // let's add specific query_params for active_events |
|
676 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
677 | - $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
678 | - // add where params for DTT_EVT_end |
|
679 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
680 | - $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
681 | - '>', |
|
682 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
683 | - ); |
|
684 | - } else { |
|
685 | - $where_params['Datetime.DTT_EVT_end'] = array( |
|
686 | - '>', |
|
687 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
688 | - ); |
|
689 | - } |
|
690 | - $query_params[0] = $where_params; |
|
691 | - // don't use $query_params with count() |
|
692 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
693 | - return $count |
|
694 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
695 | - : $this->get_all($query_params); |
|
696 | - } |
|
697 | - |
|
698 | - |
|
699 | - /** |
|
700 | - * This only returns events that are expired. |
|
701 | - * They may still be published but all their datetimes have expired. |
|
702 | - * |
|
703 | - * @param array $query_params An array of query params to further filter on |
|
704 | - * (note that status and DTT_EVT_end will be overridden) |
|
705 | - * @param bool $count whether to return the count or not (default FALSE) |
|
706 | - * @return EE_Event[]|int |
|
707 | - * @throws \EE_Error |
|
708 | - * @throws ReflectionException |
|
709 | - */ |
|
710 | - public function get_expired_events($query_params, $count = false) |
|
711 | - { |
|
712 | - $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
713 | - // if we have count make sure we don't include group by |
|
714 | - if ($count && isset($query_params['group_by'])) { |
|
715 | - unset($query_params['group_by']); |
|
716 | - } |
|
717 | - // let's add specific query_params for active_events |
|
718 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
719 | - if (isset($where_params['status'])) { |
|
720 | - unset($where_params['status']); |
|
721 | - } |
|
722 | - $exclude_query = $query_params; |
|
723 | - if (isset($exclude_query[0])) { |
|
724 | - unset($exclude_query[0]); |
|
725 | - } |
|
726 | - $exclude_query[0] = array( |
|
727 | - 'Datetime.DTT_EVT_end' => array( |
|
728 | - '>', |
|
729 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
730 | - ), |
|
731 | - ); |
|
732 | - // first get all events that have datetimes where its not expired. |
|
733 | - $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID'); |
|
734 | - $event_ids = array_keys($event_ids); |
|
735 | - // if we have any additional query_params, let's add them to the 'AND' condition |
|
736 | - $and_condition = array( |
|
737 | - 'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')), |
|
738 | - 'EVT_ID' => array('NOT IN', $event_ids), |
|
739 | - ); |
|
740 | - if (isset($where_params['OR'])) { |
|
741 | - $and_condition['OR'] = $where_params['OR']; |
|
742 | - unset($where_params['OR']); |
|
743 | - } |
|
744 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
745 | - $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
746 | - unset($where_params['Datetime.DTT_EVT_end']); |
|
747 | - } |
|
748 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
749 | - $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
750 | - unset($where_params['Datetime.DTT_EVT_start']); |
|
751 | - } |
|
752 | - // merge remaining $where params with the and conditions. |
|
753 | - $where_params['AND'] = array_merge($and_condition, $where_params); |
|
754 | - $query_params[0] = $where_params; |
|
755 | - // don't use $query_params with count() |
|
756 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
757 | - return $count |
|
758 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
759 | - : $this->get_all($query_params); |
|
760 | - } |
|
761 | - |
|
762 | - |
|
763 | - /** |
|
764 | - * This basically just returns the events that do not have the publish status. |
|
765 | - * |
|
766 | - * @param array $query_params An array of query params to further filter on |
|
767 | - * (note that status will be overwritten) |
|
768 | - * @param boolean $count whether to return the count or not (default FALSE) |
|
769 | - * @return EE_Event[]|int |
|
770 | - * @throws \EE_Error |
|
771 | - * @throws ReflectionException |
|
772 | - */ |
|
773 | - public function get_inactive_events($query_params, $count = false) |
|
774 | - { |
|
775 | - $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
776 | - // let's add in specific query_params for inactive events. |
|
777 | - if (isset($where_params['status'])) { |
|
778 | - unset($where_params['status']); |
|
779 | - } |
|
780 | - // if we have count make sure we don't include group by |
|
781 | - if ($count && isset($query_params['group_by'])) { |
|
782 | - unset($query_params['group_by']); |
|
783 | - } |
|
784 | - // if we have any additional query_params, let's add them to the 'AND' condition |
|
785 | - $where_params['AND']['status'] = array('!=', 'publish'); |
|
786 | - if (isset($where_params['OR'])) { |
|
787 | - $where_params['AND']['OR'] = $where_params['OR']; |
|
788 | - unset($where_params['OR']); |
|
789 | - } |
|
790 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
791 | - $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
792 | - unset($where_params['Datetime.DTT_EVT_end']); |
|
793 | - } |
|
794 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
795 | - $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
796 | - unset($where_params['Datetime.DTT_EVT_start']); |
|
797 | - } |
|
798 | - $query_params[0] = $where_params; |
|
799 | - // don't use $query_params with count() |
|
800 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
801 | - return $count |
|
802 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
803 | - : $this->get_all($query_params); |
|
804 | - } |
|
805 | - |
|
806 | - |
|
807 | - /** |
|
808 | - * This is just injecting into the parent add_relationship_to so we do special handling on price relationships |
|
809 | - * because we don't want to override any existing global default prices but instead insert NEW prices that get |
|
810 | - * attached to the event. See parent for param descriptions |
|
811 | - * |
|
812 | - * @param $id_or_obj |
|
813 | - * @param $other_model_id_or_obj |
|
814 | - * @param string $relationName |
|
815 | - * @param array $where_query |
|
816 | - * @return EE_Base_Class |
|
817 | - * @throws EE_Error |
|
818 | - * @throws ReflectionException |
|
819 | - */ |
|
820 | - public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array()) |
|
821 | - { |
|
822 | - if ($relationName === 'Price') { |
|
823 | - // let's get the PRC object for the given ID to make sure that we aren't dealing with a default |
|
824 | - $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj); |
|
825 | - // if EVT_ID = 0, then this is a default |
|
826 | - if ((int) $prc_chk->get('EVT_ID') === 0) { |
|
827 | - // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation |
|
828 | - $prc_chk->set('PRC_ID', 0); |
|
829 | - } |
|
830 | - // run parent |
|
831 | - return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query); |
|
832 | - } |
|
833 | - // otherwise carry on as normal |
|
834 | - return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query); |
|
835 | - } |
|
836 | - |
|
837 | - |
|
838 | - |
|
839 | - /******************** DEPRECATED METHODS ********************/ |
|
840 | - |
|
841 | - |
|
842 | - /** |
|
843 | - * _get_question_target_db_column |
|
844 | - * |
|
845 | - * @param EE_Registration $registration (so existing answers for registration are included) |
|
846 | - * @param int $EVT_ID so all question groups are included for event (not just answers from |
|
847 | - * registration). |
|
848 | - * @return array |
|
849 | - * @throws ReflectionException |
|
850 | - * @throws EE_Error*@deprecated as of 4.8.32.rc.001. Instead consider using |
|
851 | - * EE_Registration_Custom_Questions_Form located in |
|
852 | - * admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php |
|
853 | - * @access public |
|
854 | - */ |
|
855 | - public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0) |
|
856 | - { |
|
857 | - if (empty($EVT_ID)) { |
|
858 | - throw new EE_Error(__( |
|
859 | - 'An error occurred. No EVT_ID is included. Needed to know which question groups to retrieve.', |
|
860 | - 'event_espresso' |
|
861 | - )); |
|
862 | - } |
|
863 | - $questions = array(); |
|
864 | - // get all question groups for event |
|
865 | - $qgs = $this->get_question_groups_for_event($EVT_ID, $registration); |
|
866 | - if (! empty($qgs)) { |
|
867 | - foreach ($qgs as $qg) { |
|
868 | - $qsts = $qg->questions(); |
|
869 | - $questions[ $qg->ID() ] = $qg->model_field_array(); |
|
870 | - $questions[ $qg->ID() ]['QSG_questions'] = array(); |
|
871 | - foreach ($qsts as $qst) { |
|
872 | - if ($qst->is_system_question()) { |
|
873 | - continue; |
|
874 | - } |
|
875 | - $answer = EEM_Answer::instance()->get_one(array( |
|
876 | - array( |
|
877 | - 'QST_ID' => $qst->ID(), |
|
878 | - 'REG_ID' => $registration->ID(), |
|
879 | - ), |
|
880 | - )); |
|
881 | - $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object(); |
|
882 | - $qst_name = $qstn_id = $qst->ID(); |
|
883 | - $ans_id = $answer->ID(); |
|
884 | - $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']'; |
|
885 | - $input_name = ''; |
|
886 | - $input_id = sanitize_key($qst->display_text()); |
|
887 | - $input_class = ''; |
|
888 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array(); |
|
889 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn' |
|
890 | - . $input_name |
|
891 | - . $qst_name; |
|
892 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id; |
|
893 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class; |
|
894 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array(); |
|
895 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst; |
|
896 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer; |
|
897 | - // leave responses as-is, don't convert stuff into html entities please! |
|
898 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false; |
|
899 | - if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') { |
|
900 | - $QSOs = $qst->options(true, $answer->value()); |
|
901 | - if (is_array($QSOs)) { |
|
902 | - foreach ($QSOs as $QSO_ID => $QSO) { |
|
903 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array(); |
|
904 | - } |
|
905 | - } |
|
906 | - } |
|
907 | - } |
|
908 | - } |
|
909 | - } |
|
910 | - return $questions; |
|
911 | - } |
|
912 | - |
|
913 | - |
|
914 | - /** |
|
915 | - * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value |
|
916 | - * or an stdClass where each property is the name of a column, |
|
917 | - * @return EE_Base_Class |
|
918 | - * @throws EE_Error |
|
919 | - * @throws ReflectionException |
|
920 | - */ |
|
921 | - public function instantiate_class_from_array_or_object($cols_n_values) |
|
922 | - { |
|
923 | - $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
924 | - if ($classInstance instanceof EE_Event) { |
|
925 | - // events have their timezone defined in the DB, so use it immediately |
|
926 | - $this->set_timezone($classInstance->get_timezone()); |
|
927 | - } |
|
928 | - return $classInstance; |
|
929 | - } |
|
18 | + /** |
|
19 | + * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the |
|
20 | + * event |
|
21 | + */ |
|
22 | + const sold_out = 'sold_out'; |
|
23 | + |
|
24 | + /** |
|
25 | + * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later |
|
26 | + * date) |
|
27 | + */ |
|
28 | + const postponed = 'postponed'; |
|
29 | + |
|
30 | + /** |
|
31 | + * constant used by status(), indicating that the event will no longer occur |
|
32 | + */ |
|
33 | + const cancelled = 'cancelled'; |
|
34 | + |
|
35 | + |
|
36 | + /** |
|
37 | + * @var string |
|
38 | + */ |
|
39 | + protected static $_default_reg_status; |
|
40 | + |
|
41 | + |
|
42 | + /** |
|
43 | + * This is the default for the additional limit field. |
|
44 | + * @var int |
|
45 | + */ |
|
46 | + protected static $_default_additional_limit = 10; |
|
47 | + |
|
48 | + |
|
49 | + /** |
|
50 | + * private instance of the Event object |
|
51 | + * |
|
52 | + * @var EEM_Event |
|
53 | + */ |
|
54 | + protected static $_instance; |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * Adds a relationship to Term_Taxonomy for each CPT_Base |
|
59 | + * |
|
60 | + * @param string $timezone |
|
61 | + * @throws \EE_Error |
|
62 | + * @throws ReflectionException |
|
63 | + */ |
|
64 | + protected function __construct($timezone = '') |
|
65 | + { |
|
66 | + EE_Registry::instance()->load_model('Registration'); |
|
67 | + $this->singular_item = esc_html__('Event', 'event_espresso'); |
|
68 | + $this->plural_item = esc_html__('Events', 'event_espresso'); |
|
69 | + // to remove Cancelled events from the frontend, copy the following filter to your functions.php file |
|
70 | + // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' ); |
|
71 | + // to remove Postponed events from the frontend, copy the following filter to your functions.php file |
|
72 | + // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' ); |
|
73 | + // to remove Sold Out events from the frontend, copy the following filter to your functions.php file |
|
74 | + // add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' ); |
|
75 | + $this->_custom_stati = apply_filters( |
|
76 | + 'AFEE__EEM_Event__construct___custom_stati', |
|
77 | + array( |
|
78 | + EEM_Event::cancelled => array( |
|
79 | + 'label' => esc_html__('Cancelled', 'event_espresso'), |
|
80 | + 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true), |
|
81 | + ), |
|
82 | + EEM_Event::postponed => array( |
|
83 | + 'label' => esc_html__('Postponed', 'event_espresso'), |
|
84 | + 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true), |
|
85 | + ), |
|
86 | + EEM_Event::sold_out => array( |
|
87 | + 'label' => esc_html__('Sold Out', 'event_espresso'), |
|
88 | + 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true), |
|
89 | + ), |
|
90 | + ) |
|
91 | + ); |
|
92 | + self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment |
|
93 | + : self::$_default_reg_status; |
|
94 | + $this->_tables = array( |
|
95 | + 'Event_CPT' => new EE_Primary_Table('posts', 'ID'), |
|
96 | + 'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'), |
|
97 | + ); |
|
98 | + $this->_fields = array( |
|
99 | + 'Event_CPT' => array( |
|
100 | + 'EVT_ID' => new EE_Primary_Key_Int_Field( |
|
101 | + 'ID', |
|
102 | + esc_html__('Post ID for Event', 'event_espresso') |
|
103 | + ), |
|
104 | + 'EVT_name' => new EE_Plain_Text_Field( |
|
105 | + 'post_title', |
|
106 | + esc_html__('Event Name', 'event_espresso'), |
|
107 | + false, |
|
108 | + '' |
|
109 | + ), |
|
110 | + 'EVT_desc' => new EE_Post_Content_Field( |
|
111 | + 'post_content', |
|
112 | + esc_html__('Event Description', 'event_espresso'), |
|
113 | + false, |
|
114 | + '' |
|
115 | + ), |
|
116 | + 'EVT_slug' => new EE_Slug_Field( |
|
117 | + 'post_name', |
|
118 | + esc_html__('Event Slug', 'event_espresso'), |
|
119 | + false, |
|
120 | + '' |
|
121 | + ), |
|
122 | + 'EVT_created' => new EE_Datetime_Field( |
|
123 | + 'post_date', |
|
124 | + esc_html__('Date/Time Event Created', 'event_espresso'), |
|
125 | + false, |
|
126 | + EE_Datetime_Field::now |
|
127 | + ), |
|
128 | + 'EVT_short_desc' => new EE_Simple_HTML_Field( |
|
129 | + 'post_excerpt', |
|
130 | + esc_html__('Event Short Description', 'event_espresso'), |
|
131 | + false, |
|
132 | + '' |
|
133 | + ), |
|
134 | + 'EVT_modified' => new EE_Datetime_Field( |
|
135 | + 'post_modified', |
|
136 | + esc_html__('Date/Time Event Modified', 'event_espresso'), |
|
137 | + false, |
|
138 | + EE_Datetime_Field::now |
|
139 | + ), |
|
140 | + 'EVT_wp_user' => new EE_WP_User_Field( |
|
141 | + 'post_author', |
|
142 | + esc_html__('Event Creator ID', 'event_espresso'), |
|
143 | + false |
|
144 | + ), |
|
145 | + 'parent' => new EE_Integer_Field( |
|
146 | + 'post_parent', |
|
147 | + esc_html__('Event Parent ID', 'event_espresso'), |
|
148 | + false, |
|
149 | + 0 |
|
150 | + ), |
|
151 | + 'EVT_order' => new EE_Integer_Field( |
|
152 | + 'menu_order', |
|
153 | + esc_html__('Event Menu Order', 'event_espresso'), |
|
154 | + false, |
|
155 | + 1 |
|
156 | + ), |
|
157 | + 'post_type' => new EE_WP_Post_Type_Field('espresso_events'), |
|
158 | + // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ), |
|
159 | + 'status' => new EE_WP_Post_Status_Field( |
|
160 | + 'post_status', |
|
161 | + esc_html__('Event Status', 'event_espresso'), |
|
162 | + false, |
|
163 | + 'draft', |
|
164 | + $this->_custom_stati |
|
165 | + ), |
|
166 | + 'password' => new EE_Password_Field( |
|
167 | + 'post_password', |
|
168 | + __('Password', 'event_espresso'), |
|
169 | + false, |
|
170 | + '', |
|
171 | + array( |
|
172 | + 'EVT_desc', |
|
173 | + 'EVT_short_desc', |
|
174 | + 'EVT_display_desc', |
|
175 | + 'EVT_display_ticket_selector', |
|
176 | + 'EVT_visible_on', |
|
177 | + 'EVT_additional_limit', |
|
178 | + 'EVT_default_registration_status', |
|
179 | + 'EVT_member_only', |
|
180 | + 'EVT_phone', |
|
181 | + 'EVT_allow_overflow', |
|
182 | + 'EVT_timezone_string', |
|
183 | + 'EVT_external_URL', |
|
184 | + 'EVT_donations' |
|
185 | + ) |
|
186 | + ) |
|
187 | + ), |
|
188 | + 'Event_Meta' => array( |
|
189 | + 'EVTM_ID' => new EE_DB_Only_Float_Field( |
|
190 | + 'EVTM_ID', |
|
191 | + esc_html__('Event Meta Row ID', 'event_espresso'), |
|
192 | + false |
|
193 | + ), |
|
194 | + 'EVT_ID_fk' => new EE_DB_Only_Int_Field( |
|
195 | + 'EVT_ID', |
|
196 | + esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'), |
|
197 | + false |
|
198 | + ), |
|
199 | + 'EVT_display_desc' => new EE_Boolean_Field( |
|
200 | + 'EVT_display_desc', |
|
201 | + esc_html__('Display Description Flag', 'event_espresso'), |
|
202 | + false, |
|
203 | + true |
|
204 | + ), |
|
205 | + 'EVT_display_ticket_selector' => new EE_Boolean_Field( |
|
206 | + 'EVT_display_ticket_selector', |
|
207 | + esc_html__('Display Ticket Selector Flag', 'event_espresso'), |
|
208 | + false, |
|
209 | + true |
|
210 | + ), |
|
211 | + 'EVT_visible_on' => new EE_Datetime_Field( |
|
212 | + 'EVT_visible_on', |
|
213 | + esc_html__('Event Visible Date', 'event_espresso'), |
|
214 | + true, |
|
215 | + EE_Datetime_Field::now |
|
216 | + ), |
|
217 | + 'EVT_additional_limit' => new EE_Integer_Field( |
|
218 | + 'EVT_additional_limit', |
|
219 | + esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
220 | + true, |
|
221 | + self::$_default_additional_limit |
|
222 | + ), |
|
223 | + 'EVT_default_registration_status' => new EE_Enum_Text_Field( |
|
224 | + 'EVT_default_registration_status', |
|
225 | + esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
226 | + false, |
|
227 | + EEM_Event::$_default_reg_status, |
|
228 | + EEM_Registration::reg_status_array() |
|
229 | + ), |
|
230 | + 'EVT_member_only' => new EE_Boolean_Field( |
|
231 | + 'EVT_member_only', |
|
232 | + esc_html__('Member-Only Event Flag', 'event_espresso'), |
|
233 | + false, |
|
234 | + false |
|
235 | + ), |
|
236 | + 'EVT_phone' => new EE_Plain_Text_Field( |
|
237 | + 'EVT_phone', |
|
238 | + esc_html__('Event Phone Number', 'event_espresso'), |
|
239 | + false, |
|
240 | + '' |
|
241 | + ), |
|
242 | + 'EVT_allow_overflow' => new EE_Boolean_Field( |
|
243 | + 'EVT_allow_overflow', |
|
244 | + esc_html__('Allow Overflow on Event', 'event_espresso'), |
|
245 | + false, |
|
246 | + false |
|
247 | + ), |
|
248 | + 'EVT_timezone_string' => new EE_Plain_Text_Field( |
|
249 | + 'EVT_timezone_string', |
|
250 | + esc_html__('Timezone (name) for Event times', 'event_espresso'), |
|
251 | + false, |
|
252 | + '' |
|
253 | + ), |
|
254 | + 'EVT_external_URL' => new EE_Plain_Text_Field( |
|
255 | + 'EVT_external_URL', |
|
256 | + esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'), |
|
257 | + true |
|
258 | + ), |
|
259 | + 'EVT_donations' => new EE_Boolean_Field( |
|
260 | + 'EVT_donations', |
|
261 | + esc_html__('Accept Donations?', 'event_espresso'), |
|
262 | + false, |
|
263 | + false |
|
264 | + ), |
|
265 | + ), |
|
266 | + ); |
|
267 | + $this->_model_relations = array( |
|
268 | + 'Registration' => new EE_Has_Many_Relation(), |
|
269 | + 'Datetime' => new EE_Has_Many_Relation(), |
|
270 | + 'Question_Group' => new EE_HABTM_Relation('Event_Question_Group'), |
|
271 | + 'Event_Question_Group' => new EE_Has_Many_Relation(), |
|
272 | + 'Venue' => new EE_HABTM_Relation('Event_Venue'), |
|
273 | + 'Term_Relationship' => new EE_Has_Many_Relation(), |
|
274 | + 'Term_Taxonomy' => new EE_HABTM_Relation('Term_Relationship'), |
|
275 | + 'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'), |
|
276 | + 'Attendee' => new EE_HABTM_Relation('Registration'), |
|
277 | + 'WP_User' => new EE_Belongs_To_Relation(), |
|
278 | + ); |
|
279 | + // this model is generally available for reading |
|
280 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public(); |
|
281 | + $this->model_chain_to_password = ''; |
|
282 | + parent::__construct($timezone); |
|
283 | + } |
|
284 | + |
|
285 | + |
|
286 | + /** |
|
287 | + * @param string $default_reg_status |
|
288 | + * @throws EE_Error |
|
289 | + * @throws EE_Error |
|
290 | + */ |
|
291 | + public static function set_default_reg_status($default_reg_status) |
|
292 | + { |
|
293 | + self::$_default_reg_status = $default_reg_status; |
|
294 | + // if EEM_Event has already been instantiated, |
|
295 | + // then we need to reset the `EVT_default_reg_status` field to use the new default. |
|
296 | + if (self::$_instance instanceof EEM_Event) { |
|
297 | + $default_reg_status = new EE_Enum_Text_Field( |
|
298 | + 'EVT_default_registration_status', |
|
299 | + esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
300 | + false, |
|
301 | + $default_reg_status, |
|
302 | + EEM_Registration::reg_status_array() |
|
303 | + ); |
|
304 | + $default_reg_status->_construct_finalize( |
|
305 | + 'Event_Meta', |
|
306 | + 'EVT_default_registration_status', |
|
307 | + 'EEM_Event' |
|
308 | + ); |
|
309 | + self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status; |
|
310 | + } |
|
311 | + } |
|
312 | + |
|
313 | + |
|
314 | + /** |
|
315 | + * Used to override the default for the additional limit field. |
|
316 | + * @param $additional_limit |
|
317 | + */ |
|
318 | + public static function set_default_additional_limit($additional_limit) |
|
319 | + { |
|
320 | + self::$_default_additional_limit = (int) $additional_limit; |
|
321 | + if (self::$_instance instanceof EEM_Event) { |
|
322 | + self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field( |
|
323 | + 'EVT_additional_limit', |
|
324 | + __('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
325 | + true, |
|
326 | + self::$_default_additional_limit |
|
327 | + ); |
|
328 | + self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize( |
|
329 | + 'Event_Meta', |
|
330 | + 'EVT_additional_limit', |
|
331 | + 'EEM_Event' |
|
332 | + ); |
|
333 | + } |
|
334 | + } |
|
335 | + |
|
336 | + |
|
337 | + /** |
|
338 | + * Return what is currently set as the default additional limit for the event. |
|
339 | + * @return int |
|
340 | + */ |
|
341 | + public static function get_default_additional_limit() |
|
342 | + { |
|
343 | + return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit); |
|
344 | + } |
|
345 | + |
|
346 | + |
|
347 | + /** |
|
348 | + * get_question_groups |
|
349 | + * |
|
350 | + * @return array |
|
351 | + * @throws \EE_Error |
|
352 | + * @throws ReflectionException |
|
353 | + */ |
|
354 | + public function get_all_question_groups() |
|
355 | + { |
|
356 | + return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
357 | + array( |
|
358 | + array('QSG_deleted' => false), |
|
359 | + 'order_by' => array('QSG_order' => 'ASC'), |
|
360 | + ) |
|
361 | + ); |
|
362 | + } |
|
363 | + |
|
364 | + |
|
365 | + /** |
|
366 | + * get_question_groups |
|
367 | + * |
|
368 | + * @param int $EVT_ID |
|
369 | + * @return array|bool |
|
370 | + * @throws \EE_Error |
|
371 | + * @throws ReflectionException |
|
372 | + */ |
|
373 | + public function get_all_event_question_groups($EVT_ID = 0) |
|
374 | + { |
|
375 | + if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
376 | + EE_Error::add_error( |
|
377 | + esc_html__( |
|
378 | + 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
379 | + 'event_espresso' |
|
380 | + ), |
|
381 | + __FILE__, |
|
382 | + __FUNCTION__, |
|
383 | + __LINE__ |
|
384 | + ); |
|
385 | + return false; |
|
386 | + } |
|
387 | + return EE_Registry::instance()->load_model('Event_Question_Group')->get_all( |
|
388 | + array( |
|
389 | + array('EVT_ID' => $EVT_ID), |
|
390 | + ) |
|
391 | + ); |
|
392 | + } |
|
393 | + |
|
394 | + |
|
395 | + /** |
|
396 | + * get_question_groups |
|
397 | + * |
|
398 | + * @param int $EVT_ID |
|
399 | + * @param boolean $for_primary_attendee |
|
400 | + * @return array|bool |
|
401 | + * @throws EE_Error |
|
402 | + * @throws InvalidArgumentException |
|
403 | + * @throws ReflectionException |
|
404 | + * @throws InvalidDataTypeException |
|
405 | + * @throws InvalidInterfaceException |
|
406 | + */ |
|
407 | + public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true) |
|
408 | + { |
|
409 | + if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
410 | + EE_Error::add_error( |
|
411 | + esc_html__( |
|
412 | + // @codingStandardsIgnoreStart |
|
413 | + 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
414 | + // @codingStandardsIgnoreEnd |
|
415 | + 'event_espresso' |
|
416 | + ), |
|
417 | + __FILE__, |
|
418 | + __FUNCTION__, |
|
419 | + __LINE__ |
|
420 | + ); |
|
421 | + return false; |
|
422 | + } |
|
423 | + $query_params = [ |
|
424 | + [ |
|
425 | + 'EVT_ID' => $EVT_ID, |
|
426 | + EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true |
|
427 | + ] |
|
428 | + ]; |
|
429 | + if ($for_primary_attendee) { |
|
430 | + $query_params[0]['EQG_primary'] = true; |
|
431 | + } else { |
|
432 | + $query_params[0]['EQG_additional'] = true; |
|
433 | + } |
|
434 | + return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params); |
|
435 | + } |
|
436 | + |
|
437 | + |
|
438 | + /** |
|
439 | + * get_question_groups |
|
440 | + * |
|
441 | + * @param int $EVT_ID |
|
442 | + * @param EE_Registration $registration |
|
443 | + * @return array|bool |
|
444 | + * @throws EE_Error |
|
445 | + * @throws InvalidArgumentException |
|
446 | + * @throws InvalidDataTypeException |
|
447 | + * @throws InvalidInterfaceException |
|
448 | + * @throws ReflectionException |
|
449 | + */ |
|
450 | + public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration) |
|
451 | + { |
|
452 | + if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
453 | + EE_Error::add_error( |
|
454 | + esc_html__( |
|
455 | + 'An error occurred. No Question Groups could be retrieved because an Event ID was not received.', |
|
456 | + 'event_espresso' |
|
457 | + ), |
|
458 | + __FILE__, |
|
459 | + __FUNCTION__, |
|
460 | + __LINE__ |
|
461 | + ); |
|
462 | + return false; |
|
463 | + } |
|
464 | + return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
465 | + [ |
|
466 | + [ |
|
467 | + 'Event_Question_Group.EVT_ID' => $EVT_ID, |
|
468 | + 'Event_Question_Group.' |
|
469 | + . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
470 | + $registration->is_primary_registrant() |
|
471 | + ) => true |
|
472 | + ], |
|
473 | + 'order_by' => ['QSG_order' => 'ASC'], |
|
474 | + ] |
|
475 | + ); |
|
476 | + } |
|
477 | + |
|
478 | + |
|
479 | + /** |
|
480 | + * get_question_target_db_column |
|
481 | + * |
|
482 | + * @param string $QSG_IDs csv list of $QSG IDs |
|
483 | + * @return array|bool |
|
484 | + * @throws \EE_Error |
|
485 | + * @throws ReflectionException |
|
486 | + */ |
|
487 | + public function get_questions_in_groups($QSG_IDs = '') |
|
488 | + { |
|
489 | + if (empty($QSG_IDs)) { |
|
490 | + EE_Error::add_error( |
|
491 | + esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'), |
|
492 | + __FILE__, |
|
493 | + __FUNCTION__, |
|
494 | + __LINE__ |
|
495 | + ); |
|
496 | + return false; |
|
497 | + } |
|
498 | + return EE_Registry::instance()->load_model('Question')->get_all( |
|
499 | + array( |
|
500 | + array( |
|
501 | + 'Question_Group.QSG_ID' => array('IN', $QSG_IDs), |
|
502 | + 'QST_deleted' => false, |
|
503 | + 'QST_admin_only' => is_admin(), |
|
504 | + ), |
|
505 | + 'order_by' => 'QST_order', |
|
506 | + ) |
|
507 | + ); |
|
508 | + } |
|
509 | + |
|
510 | + |
|
511 | + /** |
|
512 | + * get_options_for_question |
|
513 | + * |
|
514 | + * @param string $QST_IDs csv list of $QST IDs |
|
515 | + * @return array|bool |
|
516 | + * @throws \EE_Error |
|
517 | + * @throws ReflectionException |
|
518 | + */ |
|
519 | + public function get_options_for_question($QST_IDs) |
|
520 | + { |
|
521 | + if (empty($QST_IDs)) { |
|
522 | + EE_Error::add_error( |
|
523 | + esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'), |
|
524 | + __FILE__, |
|
525 | + __FUNCTION__, |
|
526 | + __LINE__ |
|
527 | + ); |
|
528 | + return false; |
|
529 | + } |
|
530 | + return EE_Registry::instance()->load_model('Question_Option')->get_all( |
|
531 | + array( |
|
532 | + array( |
|
533 | + 'Question.QST_ID' => array('IN', $QST_IDs), |
|
534 | + 'QSO_deleted' => false, |
|
535 | + ), |
|
536 | + 'order_by' => 'QSO_ID', |
|
537 | + ) |
|
538 | + ); |
|
539 | + } |
|
540 | + |
|
541 | + |
|
542 | + /** |
|
543 | + * Gets all events that are published |
|
544 | + * and have event start time earlier than now and an event end time later than now |
|
545 | + * |
|
546 | + * @param array $query_params An array of query params to further filter on |
|
547 | + * (note that status and DTT_EVT_start and DTT_EVT_end will be overridden) |
|
548 | + * @param bool $count whether to return the count or not (default FALSE) |
|
549 | + * @return EE_Event[]|int |
|
550 | + * @throws \EE_Error |
|
551 | + * @throws ReflectionException |
|
552 | + */ |
|
553 | + public function get_active_events($query_params, $count = false) |
|
554 | + { |
|
555 | + if (array_key_exists(0, $query_params)) { |
|
556 | + $where_params = $query_params[0]; |
|
557 | + unset($query_params[0]); |
|
558 | + } else { |
|
559 | + $where_params = array(); |
|
560 | + } |
|
561 | + // if we have count make sure we don't include group by |
|
562 | + if ($count && isset($query_params['group_by'])) { |
|
563 | + unset($query_params['group_by']); |
|
564 | + } |
|
565 | + // let's add specific query_params for active_events |
|
566 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
567 | + $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
568 | + // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions |
|
569 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
570 | + $where_params['Datetime.DTT_EVT_start******'] = array( |
|
571 | + '<', |
|
572 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
573 | + ); |
|
574 | + } else { |
|
575 | + $where_params['Datetime.DTT_EVT_start'] = array( |
|
576 | + '<', |
|
577 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
578 | + ); |
|
579 | + } |
|
580 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
581 | + $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
582 | + '>', |
|
583 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
584 | + ); |
|
585 | + } else { |
|
586 | + $where_params['Datetime.DTT_EVT_end'] = array( |
|
587 | + '>', |
|
588 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
589 | + ); |
|
590 | + } |
|
591 | + $query_params[0] = $where_params; |
|
592 | + // don't use $query_params with count() |
|
593 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
594 | + return $count |
|
595 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
596 | + : $this->get_all($query_params); |
|
597 | + } |
|
598 | + |
|
599 | + |
|
600 | + /** |
|
601 | + * get all events that are published and have an event start time later than now |
|
602 | + * |
|
603 | + * @param array $query_params An array of query params to further filter on |
|
604 | + * (Note that status and DTT_EVT_start will be overridden) |
|
605 | + * @param bool $count whether to return the count or not (default FALSE) |
|
606 | + * @return EE_Event[]|int |
|
607 | + * @throws \EE_Error |
|
608 | + * @throws ReflectionException |
|
609 | + */ |
|
610 | + public function get_upcoming_events($query_params, $count = false) |
|
611 | + { |
|
612 | + if (array_key_exists(0, $query_params)) { |
|
613 | + $where_params = $query_params[0]; |
|
614 | + unset($query_params[0]); |
|
615 | + } else { |
|
616 | + $where_params = array(); |
|
617 | + } |
|
618 | + // if we have count make sure we don't include group by |
|
619 | + if ($count && isset($query_params['group_by'])) { |
|
620 | + unset($query_params['group_by']); |
|
621 | + } |
|
622 | + // let's add specific query_params for active_events |
|
623 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
624 | + // we need to pull events with a status of publish and sold_out |
|
625 | + $event_status = array('publish', EEM_Event::sold_out); |
|
626 | + // check if the user can read private events and if so add the 'private status to the were params' |
|
627 | + if (EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_upcoming_events')) { |
|
628 | + $event_status[] = 'private'; |
|
629 | + } |
|
630 | + $where_params['status'] = array('IN', $event_status); |
|
631 | + // if there are already query_params matching DTT_EVT_start then we need to modify that to add them. |
|
632 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
633 | + $where_params['Datetime.DTT_EVT_start*****'] = array( |
|
634 | + '>', |
|
635 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
636 | + ); |
|
637 | + } else { |
|
638 | + $where_params['Datetime.DTT_EVT_start'] = array( |
|
639 | + '>', |
|
640 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
641 | + ); |
|
642 | + } |
|
643 | + $query_params[0] = $where_params; |
|
644 | + // don't use $query_params with count() |
|
645 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
646 | + return $count |
|
647 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
648 | + : $this->get_all($query_params); |
|
649 | + } |
|
650 | + |
|
651 | + |
|
652 | + /** |
|
653 | + * Gets all events that are published |
|
654 | + * and have an event end time later than now |
|
655 | + * |
|
656 | + * @param array $query_params An array of query params to further filter on |
|
657 | + * (note that status and DTT_EVT_end will be overridden) |
|
658 | + * @param bool $count whether to return the count or not (default FALSE) |
|
659 | + * @return EE_Event[]|int |
|
660 | + * @throws \EE_Error |
|
661 | + * @throws ReflectionException |
|
662 | + */ |
|
663 | + public function get_active_and_upcoming_events($query_params, $count = false) |
|
664 | + { |
|
665 | + if (array_key_exists(0, $query_params)) { |
|
666 | + $where_params = $query_params[0]; |
|
667 | + unset($query_params[0]); |
|
668 | + } else { |
|
669 | + $where_params = array(); |
|
670 | + } |
|
671 | + // if we have count make sure we don't include group by |
|
672 | + if ($count && isset($query_params['group_by'])) { |
|
673 | + unset($query_params['group_by']); |
|
674 | + } |
|
675 | + // let's add specific query_params for active_events |
|
676 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
677 | + $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
678 | + // add where params for DTT_EVT_end |
|
679 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
680 | + $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
681 | + '>', |
|
682 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
683 | + ); |
|
684 | + } else { |
|
685 | + $where_params['Datetime.DTT_EVT_end'] = array( |
|
686 | + '>', |
|
687 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
688 | + ); |
|
689 | + } |
|
690 | + $query_params[0] = $where_params; |
|
691 | + // don't use $query_params with count() |
|
692 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
693 | + return $count |
|
694 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
695 | + : $this->get_all($query_params); |
|
696 | + } |
|
697 | + |
|
698 | + |
|
699 | + /** |
|
700 | + * This only returns events that are expired. |
|
701 | + * They may still be published but all their datetimes have expired. |
|
702 | + * |
|
703 | + * @param array $query_params An array of query params to further filter on |
|
704 | + * (note that status and DTT_EVT_end will be overridden) |
|
705 | + * @param bool $count whether to return the count or not (default FALSE) |
|
706 | + * @return EE_Event[]|int |
|
707 | + * @throws \EE_Error |
|
708 | + * @throws ReflectionException |
|
709 | + */ |
|
710 | + public function get_expired_events($query_params, $count = false) |
|
711 | + { |
|
712 | + $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
713 | + // if we have count make sure we don't include group by |
|
714 | + if ($count && isset($query_params['group_by'])) { |
|
715 | + unset($query_params['group_by']); |
|
716 | + } |
|
717 | + // let's add specific query_params for active_events |
|
718 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
719 | + if (isset($where_params['status'])) { |
|
720 | + unset($where_params['status']); |
|
721 | + } |
|
722 | + $exclude_query = $query_params; |
|
723 | + if (isset($exclude_query[0])) { |
|
724 | + unset($exclude_query[0]); |
|
725 | + } |
|
726 | + $exclude_query[0] = array( |
|
727 | + 'Datetime.DTT_EVT_end' => array( |
|
728 | + '>', |
|
729 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
730 | + ), |
|
731 | + ); |
|
732 | + // first get all events that have datetimes where its not expired. |
|
733 | + $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID'); |
|
734 | + $event_ids = array_keys($event_ids); |
|
735 | + // if we have any additional query_params, let's add them to the 'AND' condition |
|
736 | + $and_condition = array( |
|
737 | + 'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')), |
|
738 | + 'EVT_ID' => array('NOT IN', $event_ids), |
|
739 | + ); |
|
740 | + if (isset($where_params['OR'])) { |
|
741 | + $and_condition['OR'] = $where_params['OR']; |
|
742 | + unset($where_params['OR']); |
|
743 | + } |
|
744 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
745 | + $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
746 | + unset($where_params['Datetime.DTT_EVT_end']); |
|
747 | + } |
|
748 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
749 | + $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
750 | + unset($where_params['Datetime.DTT_EVT_start']); |
|
751 | + } |
|
752 | + // merge remaining $where params with the and conditions. |
|
753 | + $where_params['AND'] = array_merge($and_condition, $where_params); |
|
754 | + $query_params[0] = $where_params; |
|
755 | + // don't use $query_params with count() |
|
756 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
757 | + return $count |
|
758 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
759 | + : $this->get_all($query_params); |
|
760 | + } |
|
761 | + |
|
762 | + |
|
763 | + /** |
|
764 | + * This basically just returns the events that do not have the publish status. |
|
765 | + * |
|
766 | + * @param array $query_params An array of query params to further filter on |
|
767 | + * (note that status will be overwritten) |
|
768 | + * @param boolean $count whether to return the count or not (default FALSE) |
|
769 | + * @return EE_Event[]|int |
|
770 | + * @throws \EE_Error |
|
771 | + * @throws ReflectionException |
|
772 | + */ |
|
773 | + public function get_inactive_events($query_params, $count = false) |
|
774 | + { |
|
775 | + $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
776 | + // let's add in specific query_params for inactive events. |
|
777 | + if (isset($where_params['status'])) { |
|
778 | + unset($where_params['status']); |
|
779 | + } |
|
780 | + // if we have count make sure we don't include group by |
|
781 | + if ($count && isset($query_params['group_by'])) { |
|
782 | + unset($query_params['group_by']); |
|
783 | + } |
|
784 | + // if we have any additional query_params, let's add them to the 'AND' condition |
|
785 | + $where_params['AND']['status'] = array('!=', 'publish'); |
|
786 | + if (isset($where_params['OR'])) { |
|
787 | + $where_params['AND']['OR'] = $where_params['OR']; |
|
788 | + unset($where_params['OR']); |
|
789 | + } |
|
790 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
791 | + $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
792 | + unset($where_params['Datetime.DTT_EVT_end']); |
|
793 | + } |
|
794 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
795 | + $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
796 | + unset($where_params['Datetime.DTT_EVT_start']); |
|
797 | + } |
|
798 | + $query_params[0] = $where_params; |
|
799 | + // don't use $query_params with count() |
|
800 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
801 | + return $count |
|
802 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
803 | + : $this->get_all($query_params); |
|
804 | + } |
|
805 | + |
|
806 | + |
|
807 | + /** |
|
808 | + * This is just injecting into the parent add_relationship_to so we do special handling on price relationships |
|
809 | + * because we don't want to override any existing global default prices but instead insert NEW prices that get |
|
810 | + * attached to the event. See parent for param descriptions |
|
811 | + * |
|
812 | + * @param $id_or_obj |
|
813 | + * @param $other_model_id_or_obj |
|
814 | + * @param string $relationName |
|
815 | + * @param array $where_query |
|
816 | + * @return EE_Base_Class |
|
817 | + * @throws EE_Error |
|
818 | + * @throws ReflectionException |
|
819 | + */ |
|
820 | + public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array()) |
|
821 | + { |
|
822 | + if ($relationName === 'Price') { |
|
823 | + // let's get the PRC object for the given ID to make sure that we aren't dealing with a default |
|
824 | + $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj); |
|
825 | + // if EVT_ID = 0, then this is a default |
|
826 | + if ((int) $prc_chk->get('EVT_ID') === 0) { |
|
827 | + // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation |
|
828 | + $prc_chk->set('PRC_ID', 0); |
|
829 | + } |
|
830 | + // run parent |
|
831 | + return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query); |
|
832 | + } |
|
833 | + // otherwise carry on as normal |
|
834 | + return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query); |
|
835 | + } |
|
836 | + |
|
837 | + |
|
838 | + |
|
839 | + /******************** DEPRECATED METHODS ********************/ |
|
840 | + |
|
841 | + |
|
842 | + /** |
|
843 | + * _get_question_target_db_column |
|
844 | + * |
|
845 | + * @param EE_Registration $registration (so existing answers for registration are included) |
|
846 | + * @param int $EVT_ID so all question groups are included for event (not just answers from |
|
847 | + * registration). |
|
848 | + * @return array |
|
849 | + * @throws ReflectionException |
|
850 | + * @throws EE_Error*@deprecated as of 4.8.32.rc.001. Instead consider using |
|
851 | + * EE_Registration_Custom_Questions_Form located in |
|
852 | + * admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php |
|
853 | + * @access public |
|
854 | + */ |
|
855 | + public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0) |
|
856 | + { |
|
857 | + if (empty($EVT_ID)) { |
|
858 | + throw new EE_Error(__( |
|
859 | + 'An error occurred. No EVT_ID is included. Needed to know which question groups to retrieve.', |
|
860 | + 'event_espresso' |
|
861 | + )); |
|
862 | + } |
|
863 | + $questions = array(); |
|
864 | + // get all question groups for event |
|
865 | + $qgs = $this->get_question_groups_for_event($EVT_ID, $registration); |
|
866 | + if (! empty($qgs)) { |
|
867 | + foreach ($qgs as $qg) { |
|
868 | + $qsts = $qg->questions(); |
|
869 | + $questions[ $qg->ID() ] = $qg->model_field_array(); |
|
870 | + $questions[ $qg->ID() ]['QSG_questions'] = array(); |
|
871 | + foreach ($qsts as $qst) { |
|
872 | + if ($qst->is_system_question()) { |
|
873 | + continue; |
|
874 | + } |
|
875 | + $answer = EEM_Answer::instance()->get_one(array( |
|
876 | + array( |
|
877 | + 'QST_ID' => $qst->ID(), |
|
878 | + 'REG_ID' => $registration->ID(), |
|
879 | + ), |
|
880 | + )); |
|
881 | + $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object(); |
|
882 | + $qst_name = $qstn_id = $qst->ID(); |
|
883 | + $ans_id = $answer->ID(); |
|
884 | + $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']'; |
|
885 | + $input_name = ''; |
|
886 | + $input_id = sanitize_key($qst->display_text()); |
|
887 | + $input_class = ''; |
|
888 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array(); |
|
889 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn' |
|
890 | + . $input_name |
|
891 | + . $qst_name; |
|
892 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id; |
|
893 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class; |
|
894 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array(); |
|
895 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst; |
|
896 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer; |
|
897 | + // leave responses as-is, don't convert stuff into html entities please! |
|
898 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false; |
|
899 | + if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') { |
|
900 | + $QSOs = $qst->options(true, $answer->value()); |
|
901 | + if (is_array($QSOs)) { |
|
902 | + foreach ($QSOs as $QSO_ID => $QSO) { |
|
903 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array(); |
|
904 | + } |
|
905 | + } |
|
906 | + } |
|
907 | + } |
|
908 | + } |
|
909 | + } |
|
910 | + return $questions; |
|
911 | + } |
|
912 | + |
|
913 | + |
|
914 | + /** |
|
915 | + * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value |
|
916 | + * or an stdClass where each property is the name of a column, |
|
917 | + * @return EE_Base_Class |
|
918 | + * @throws EE_Error |
|
919 | + * @throws ReflectionException |
|
920 | + */ |
|
921 | + public function instantiate_class_from_array_or_object($cols_n_values) |
|
922 | + { |
|
923 | + $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
924 | + if ($classInstance instanceof EE_Event) { |
|
925 | + // events have their timezone defined in the DB, so use it immediately |
|
926 | + $this->set_timezone($classInstance->get_timezone()); |
|
927 | + } |
|
928 | + return $classInstance; |
|
929 | + } |
|
930 | 930 | } |
@@ -27,365 +27,365 @@ |
||
27 | 27 | abstract class EEM_Soft_Delete_Base extends EEM_Base |
28 | 28 | { |
29 | 29 | |
30 | - /** |
|
31 | - * @param string $timezone |
|
32 | - * @throws EE_Error |
|
33 | - */ |
|
34 | - protected function __construct($timezone = '') |
|
35 | - { |
|
36 | - if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
37 | - $this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions(); |
|
38 | - } |
|
39 | - parent::__construct($timezone); |
|
40 | - } |
|
41 | - |
|
42 | - |
|
43 | - |
|
44 | - /** |
|
45 | - * Searches for field on this model of type 'deleted_flag'. if it is found, |
|
46 | - * returns it's name. |
|
47 | - * |
|
48 | - * @return string |
|
49 | - * @throws EE_Error |
|
50 | - */ |
|
51 | - public function deleted_field_name() |
|
52 | - { |
|
53 | - $field = $this->get_a_field_of_type('EE_Trashed_Flag_Field'); |
|
54 | - if ($field) { |
|
55 | - return $field->get_name(); |
|
56 | - } else { |
|
57 | - throw new EE_Error(sprintf(__( |
|
58 | - 'We are trying to find the deleted flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?', |
|
59 | - 'event_espresso' |
|
60 | - ), get_class($this), get_class($this))); |
|
61 | - } |
|
62 | - } |
|
63 | - |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * Gets one item that's been deleted, according to $query_params |
|
68 | - * |
|
69 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
70 | - * @return EE_Soft_Delete_Base_Class |
|
71 | - */ |
|
72 | - public function get_one_deleted($query_params = array()) |
|
73 | - { |
|
74 | - $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
75 | - return parent::get_one($query_params); |
|
76 | - } |
|
77 | - |
|
78 | - |
|
79 | - |
|
80 | - /** |
|
81 | - * Gets one item from the DB, regardless of whether it's been soft-deleted or not |
|
82 | - * |
|
83 | - * @param array $query_params like EEM_base::get_all's $query_params |
|
84 | - * @return EE_Soft_Delete_Base_Class |
|
85 | - */ |
|
86 | - public function get_one_deleted_or_undeleted($query_params = array()) |
|
87 | - { |
|
88 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
89 | - return parent::get_one($query_params); |
|
90 | - } |
|
91 | - |
|
92 | - |
|
93 | - |
|
94 | - /** |
|
95 | - * Gets the item indicated by its ID. But if it's soft-deleted, pretends it doesn't exist. |
|
96 | - * |
|
97 | - * @param int|string $id |
|
98 | - * @return EE_Soft_Delete_Base_Class |
|
99 | - */ |
|
100 | - public function get_one_by_ID_but_ignore_deleted($id) |
|
101 | - { |
|
102 | - return $this->get_one( |
|
103 | - $this->alter_query_params_to_restrict_by_ID( |
|
104 | - $id, |
|
105 | - array('default_where_conditions' => 'default') |
|
106 | - ) |
|
107 | - ); |
|
108 | - } |
|
109 | - |
|
110 | - |
|
111 | - |
|
112 | - /** |
|
113 | - * Counts all the deleted/trashed items |
|
114 | - * |
|
115 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
116 | - * @param string $field_to_count |
|
117 | - * @param bool $distinct if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE; |
|
118 | - * @return int |
|
119 | - */ |
|
120 | - public function count_deleted($query_params = null, $field_to_count = null, $distinct = false) |
|
121 | - { |
|
122 | - $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
123 | - return parent::count($query_params, $field_to_count, $distinct); |
|
124 | - } |
|
125 | - |
|
126 | - |
|
127 | - |
|
128 | - /** |
|
129 | - * Alters the query params so that only trashed/soft-deleted items are considered |
|
130 | - * |
|
131 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
132 | - * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
133 | - */ |
|
134 | - protected function _alter_query_params_so_only_trashed_items_included($query_params) |
|
135 | - { |
|
136 | - $deletedFlagFieldName = $this->deleted_field_name(); |
|
137 | - $query_params[0][ $deletedFlagFieldName ] = true; |
|
138 | - return $query_params; |
|
139 | - } |
|
140 | - |
|
141 | - |
|
142 | - |
|
143 | - /** |
|
144 | - * Alters the query params so that only trashed/soft-deleted items are considered |
|
145 | - * |
|
146 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
147 | - * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
148 | - */ |
|
149 | - public function alter_query_params_so_only_trashed_items_included($query_params) |
|
150 | - { |
|
151 | - return $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
152 | - } |
|
153 | - |
|
154 | - |
|
155 | - |
|
156 | - /** |
|
157 | - * Alters the query params so each item's deleted status is ignored. |
|
158 | - * |
|
159 | - * @param array $query_params |
|
160 | - * @return array |
|
161 | - */ |
|
162 | - public function alter_query_params_so_deleted_and_undeleted_items_included($query_params = array()) |
|
163 | - { |
|
164 | - return $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
165 | - } |
|
166 | - |
|
167 | - |
|
168 | - |
|
169 | - /** |
|
170 | - * Alters the query params so each item's deleted status is ignored. |
|
171 | - * |
|
172 | - * @param array $query_params |
|
173 | - * @return array |
|
174 | - */ |
|
175 | - protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params) |
|
176 | - { |
|
177 | - if (! isset($query_params['default_where_conditions'])) { |
|
178 | - $query_params['default_where_conditions'] = 'minimum'; |
|
179 | - } |
|
180 | - return $query_params; |
|
181 | - } |
|
182 | - |
|
183 | - |
|
184 | - |
|
185 | - /** |
|
186 | - * Counts all deleted and undeleted items |
|
187 | - * |
|
188 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
189 | - * @param string $field_to_count |
|
190 | - * @param bool $distinct if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE; |
|
191 | - * @return int |
|
192 | - */ |
|
193 | - public function count_deleted_and_undeleted($query_params = null, $field_to_count = null, $distinct = false) |
|
194 | - { |
|
195 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
196 | - return parent::count($query_params, $field_to_count, $distinct); |
|
197 | - } |
|
198 | - |
|
199 | - |
|
200 | - |
|
201 | - /** |
|
202 | - * Sum all the deleted items. |
|
203 | - * |
|
204 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
205 | - * @param string $field_to_sum |
|
206 | - * @return int |
|
207 | - */ |
|
208 | - public function sum_deleted($query_params = null, $field_to_sum = null) |
|
209 | - { |
|
210 | - $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
211 | - return parent::sum($query_params, $field_to_sum); |
|
212 | - } |
|
213 | - |
|
214 | - |
|
215 | - |
|
216 | - /** |
|
217 | - * Sums all the deleted and undeleted items. |
|
218 | - * |
|
219 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
220 | - * @param string $field_to_sum |
|
221 | - * @return int |
|
222 | - */ |
|
223 | - public function sum_deleted_and_undeleted($query_params = null, $field_to_sum = null) |
|
224 | - { |
|
225 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
226 | - parent::sum($query_params, $field_to_sum); |
|
227 | - } |
|
228 | - |
|
229 | - |
|
230 | - |
|
231 | - /** |
|
232 | - * Gets all deleted and undeleted mode objects from the db that meet the criteria, regardless of |
|
233 | - * whether they've been soft-deleted or not |
|
234 | - * |
|
235 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
236 | - * @return EE_Soft_Delete_Base_Class[] |
|
237 | - */ |
|
238 | - public function get_all_deleted_and_undeleted($query_params = array()) |
|
239 | - { |
|
240 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
241 | - return parent::get_all($query_params); |
|
242 | - } |
|
243 | - |
|
244 | - |
|
245 | - |
|
246 | - /** |
|
247 | - * For 'soft deletable' models, gets all which ARE deleted, according to conditions specified in $query_params. |
|
248 | - * |
|
249 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
250 | - * @return EE_Soft_Delete_Base_Class[] |
|
251 | - */ |
|
252 | - public function get_all_deleted($query_params = array()) |
|
253 | - { |
|
254 | - $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
255 | - return parent::get_all($query_params); |
|
256 | - } |
|
257 | - |
|
258 | - |
|
259 | - |
|
260 | - /** |
|
261 | - * Permanently deletes the selected rows. When selecting rows for deletion, ignores |
|
262 | - * whether they've been soft-deleted or not. (ie, you don't have to soft-delete objects |
|
263 | - * before you can permanently delete them). |
|
264 | - * Because this will cause a real deletion, related models may block this deletion (ie, add an error |
|
265 | - * and abort the delete) |
|
266 | - * |
|
267 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
268 | - * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info |
|
269 | - * that blocks it (ie, there' sno other data that depends on this data); if false, deletes regardless of other objects |
|
270 | - * which may depend on it. Its generally advisable to always leave this as TRUE, otherwise you could easily corrupt your DB |
|
271 | - * @return boolean success |
|
272 | - */ |
|
273 | - public function delete_permanently($query_params = array(), $allow_blocking = true) |
|
274 | - { |
|
275 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
276 | - return parent::delete_permanently($query_params, $allow_blocking); |
|
277 | - } |
|
278 | - |
|
279 | - |
|
280 | - |
|
281 | - /** |
|
282 | - * Restores a particular item by its ID (primary key). Ignores the fact whether the item |
|
283 | - * has been soft-deleted or not. |
|
284 | - * |
|
285 | - * @param mixed $ID int if primary key is an int, string otherwise |
|
286 | - * @return boolean success |
|
287 | - */ |
|
288 | - public function restore_by_ID($ID = false) |
|
289 | - { |
|
290 | - return $this->delete_or_restore_by_ID(false, $ID); |
|
291 | - } |
|
292 | - |
|
293 | - |
|
294 | - |
|
295 | - /** |
|
296 | - * For deleting or restoring a particular item. Note that this model is a SOFT-DELETABLE model! However, |
|
297 | - * this function will ignore whether the items have been soft-deleted or not. |
|
298 | - * |
|
299 | - * @param boolean $delete true for delete, false for restore |
|
300 | - * @param mixed $ID int if primary key is an int, string otherwise |
|
301 | - * @return boolean |
|
302 | - */ |
|
303 | - public function delete_or_restore_by_ID($delete = true, $ID = false) |
|
304 | - { |
|
305 | - if (! $ID) { |
|
306 | - return false; |
|
307 | - } |
|
308 | - if ( |
|
309 | - $this->delete_or_restore( |
|
310 | - $delete, |
|
311 | - $this->alter_query_params_to_restrict_by_ID($ID) |
|
312 | - ) |
|
313 | - ) { |
|
314 | - return true; |
|
315 | - } else { |
|
316 | - return false; |
|
317 | - } |
|
318 | - } |
|
319 | - |
|
320 | - |
|
321 | - |
|
322 | - /** |
|
323 | - * Overrides parent's 'delete' method to instead do a soft delete on all rows that |
|
324 | - * meet the criteria in $where_col_n_values. This particular function ignores whether the items have been soft-deleted or not. |
|
325 | - * Note: because this item will be soft-deleted only, |
|
326 | - * doesn't block because of model dependencies |
|
327 | - * |
|
328 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
329 | - * @param bool $block_deletes |
|
330 | - * @return boolean |
|
331 | - */ |
|
332 | - public function delete($query_params = array(), $block_deletes = false) |
|
333 | - { |
|
334 | - // no matter what, we WON'T block soft deletes. |
|
335 | - return $this->delete_or_restore(true, $query_params); |
|
336 | - } |
|
337 | - |
|
338 | - |
|
339 | - |
|
340 | - /** |
|
341 | - * 'Un-deletes' the chosen items. Note that this model is a SOFT-DELETABLE model! That means that, by default, trashed/soft-deleted |
|
342 | - * items are ignored in queries. However, this particular function ignores whether the items have been soft-deleted or not. |
|
343 | - * |
|
344 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
345 | - * @return boolean |
|
346 | - */ |
|
347 | - public function restore($query_params = array()) |
|
348 | - { |
|
349 | - return $this->delete_or_restore(false, $query_params); |
|
350 | - } |
|
351 | - |
|
352 | - |
|
353 | - |
|
354 | - /** |
|
355 | - * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered. |
|
356 | - * |
|
357 | - * @param boolean $delete true to indicate deletion, false to indicate restoration |
|
358 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
359 | - * @return boolean |
|
360 | - */ |
|
361 | - public function delete_or_restore($delete = true, $query_params = array()) |
|
362 | - { |
|
363 | - $deletedFlagFieldName = $this->deleted_field_name(); |
|
364 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
365 | - if ($this->update(array($deletedFlagFieldName => $delete), $query_params)) { |
|
366 | - return true; |
|
367 | - } else { |
|
368 | - return false; |
|
369 | - } |
|
370 | - } |
|
371 | - |
|
372 | - |
|
373 | - |
|
374 | - /** |
|
375 | - * Updates all the items of this model which match the $query params, regardless of whether |
|
376 | - * they've been soft-deleted or not |
|
377 | - * |
|
378 | - * @param array $fields_n_values like EEM_Base::update's $fields_n_value |
|
379 | - * @param array $query_params like EEM_base::get_all's $query_params |
|
380 | - * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects |
|
381 | - * in this model's entity map according to $fields_n_values that match $query_params. This |
|
382 | - * obviously has some overhead, so you can disable it by setting this to FALSE, but |
|
383 | - * be aware that model objects being used could get out-of-sync with the database |
|
384 | - * @return int number of items updated |
|
385 | - */ |
|
386 | - public function update_deleted_and_undeleted($fields_n_values, $query_params, $keep_model_objs_in_sync = true) |
|
387 | - { |
|
388 | - $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
389 | - return $this->update($fields_n_values, $query_params, $keep_model_objs_in_sync); |
|
390 | - } |
|
30 | + /** |
|
31 | + * @param string $timezone |
|
32 | + * @throws EE_Error |
|
33 | + */ |
|
34 | + protected function __construct($timezone = '') |
|
35 | + { |
|
36 | + if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
37 | + $this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions(); |
|
38 | + } |
|
39 | + parent::__construct($timezone); |
|
40 | + } |
|
41 | + |
|
42 | + |
|
43 | + |
|
44 | + /** |
|
45 | + * Searches for field on this model of type 'deleted_flag'. if it is found, |
|
46 | + * returns it's name. |
|
47 | + * |
|
48 | + * @return string |
|
49 | + * @throws EE_Error |
|
50 | + */ |
|
51 | + public function deleted_field_name() |
|
52 | + { |
|
53 | + $field = $this->get_a_field_of_type('EE_Trashed_Flag_Field'); |
|
54 | + if ($field) { |
|
55 | + return $field->get_name(); |
|
56 | + } else { |
|
57 | + throw new EE_Error(sprintf(__( |
|
58 | + 'We are trying to find the deleted flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?', |
|
59 | + 'event_espresso' |
|
60 | + ), get_class($this), get_class($this))); |
|
61 | + } |
|
62 | + } |
|
63 | + |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * Gets one item that's been deleted, according to $query_params |
|
68 | + * |
|
69 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
70 | + * @return EE_Soft_Delete_Base_Class |
|
71 | + */ |
|
72 | + public function get_one_deleted($query_params = array()) |
|
73 | + { |
|
74 | + $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
75 | + return parent::get_one($query_params); |
|
76 | + } |
|
77 | + |
|
78 | + |
|
79 | + |
|
80 | + /** |
|
81 | + * Gets one item from the DB, regardless of whether it's been soft-deleted or not |
|
82 | + * |
|
83 | + * @param array $query_params like EEM_base::get_all's $query_params |
|
84 | + * @return EE_Soft_Delete_Base_Class |
|
85 | + */ |
|
86 | + public function get_one_deleted_or_undeleted($query_params = array()) |
|
87 | + { |
|
88 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
89 | + return parent::get_one($query_params); |
|
90 | + } |
|
91 | + |
|
92 | + |
|
93 | + |
|
94 | + /** |
|
95 | + * Gets the item indicated by its ID. But if it's soft-deleted, pretends it doesn't exist. |
|
96 | + * |
|
97 | + * @param int|string $id |
|
98 | + * @return EE_Soft_Delete_Base_Class |
|
99 | + */ |
|
100 | + public function get_one_by_ID_but_ignore_deleted($id) |
|
101 | + { |
|
102 | + return $this->get_one( |
|
103 | + $this->alter_query_params_to_restrict_by_ID( |
|
104 | + $id, |
|
105 | + array('default_where_conditions' => 'default') |
|
106 | + ) |
|
107 | + ); |
|
108 | + } |
|
109 | + |
|
110 | + |
|
111 | + |
|
112 | + /** |
|
113 | + * Counts all the deleted/trashed items |
|
114 | + * |
|
115 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
116 | + * @param string $field_to_count |
|
117 | + * @param bool $distinct if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE; |
|
118 | + * @return int |
|
119 | + */ |
|
120 | + public function count_deleted($query_params = null, $field_to_count = null, $distinct = false) |
|
121 | + { |
|
122 | + $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
123 | + return parent::count($query_params, $field_to_count, $distinct); |
|
124 | + } |
|
125 | + |
|
126 | + |
|
127 | + |
|
128 | + /** |
|
129 | + * Alters the query params so that only trashed/soft-deleted items are considered |
|
130 | + * |
|
131 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
132 | + * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
133 | + */ |
|
134 | + protected function _alter_query_params_so_only_trashed_items_included($query_params) |
|
135 | + { |
|
136 | + $deletedFlagFieldName = $this->deleted_field_name(); |
|
137 | + $query_params[0][ $deletedFlagFieldName ] = true; |
|
138 | + return $query_params; |
|
139 | + } |
|
140 | + |
|
141 | + |
|
142 | + |
|
143 | + /** |
|
144 | + * Alters the query params so that only trashed/soft-deleted items are considered |
|
145 | + * |
|
146 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
147 | + * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
148 | + */ |
|
149 | + public function alter_query_params_so_only_trashed_items_included($query_params) |
|
150 | + { |
|
151 | + return $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
152 | + } |
|
153 | + |
|
154 | + |
|
155 | + |
|
156 | + /** |
|
157 | + * Alters the query params so each item's deleted status is ignored. |
|
158 | + * |
|
159 | + * @param array $query_params |
|
160 | + * @return array |
|
161 | + */ |
|
162 | + public function alter_query_params_so_deleted_and_undeleted_items_included($query_params = array()) |
|
163 | + { |
|
164 | + return $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
165 | + } |
|
166 | + |
|
167 | + |
|
168 | + |
|
169 | + /** |
|
170 | + * Alters the query params so each item's deleted status is ignored. |
|
171 | + * |
|
172 | + * @param array $query_params |
|
173 | + * @return array |
|
174 | + */ |
|
175 | + protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params) |
|
176 | + { |
|
177 | + if (! isset($query_params['default_where_conditions'])) { |
|
178 | + $query_params['default_where_conditions'] = 'minimum'; |
|
179 | + } |
|
180 | + return $query_params; |
|
181 | + } |
|
182 | + |
|
183 | + |
|
184 | + |
|
185 | + /** |
|
186 | + * Counts all deleted and undeleted items |
|
187 | + * |
|
188 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
189 | + * @param string $field_to_count |
|
190 | + * @param bool $distinct if we want to only count the distinct values for the column then you can trigger that by the setting $distinct to TRUE; |
|
191 | + * @return int |
|
192 | + */ |
|
193 | + public function count_deleted_and_undeleted($query_params = null, $field_to_count = null, $distinct = false) |
|
194 | + { |
|
195 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
196 | + return parent::count($query_params, $field_to_count, $distinct); |
|
197 | + } |
|
198 | + |
|
199 | + |
|
200 | + |
|
201 | + /** |
|
202 | + * Sum all the deleted items. |
|
203 | + * |
|
204 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
205 | + * @param string $field_to_sum |
|
206 | + * @return int |
|
207 | + */ |
|
208 | + public function sum_deleted($query_params = null, $field_to_sum = null) |
|
209 | + { |
|
210 | + $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
211 | + return parent::sum($query_params, $field_to_sum); |
|
212 | + } |
|
213 | + |
|
214 | + |
|
215 | + |
|
216 | + /** |
|
217 | + * Sums all the deleted and undeleted items. |
|
218 | + * |
|
219 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
220 | + * @param string $field_to_sum |
|
221 | + * @return int |
|
222 | + */ |
|
223 | + public function sum_deleted_and_undeleted($query_params = null, $field_to_sum = null) |
|
224 | + { |
|
225 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
226 | + parent::sum($query_params, $field_to_sum); |
|
227 | + } |
|
228 | + |
|
229 | + |
|
230 | + |
|
231 | + /** |
|
232 | + * Gets all deleted and undeleted mode objects from the db that meet the criteria, regardless of |
|
233 | + * whether they've been soft-deleted or not |
|
234 | + * |
|
235 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
236 | + * @return EE_Soft_Delete_Base_Class[] |
|
237 | + */ |
|
238 | + public function get_all_deleted_and_undeleted($query_params = array()) |
|
239 | + { |
|
240 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
241 | + return parent::get_all($query_params); |
|
242 | + } |
|
243 | + |
|
244 | + |
|
245 | + |
|
246 | + /** |
|
247 | + * For 'soft deletable' models, gets all which ARE deleted, according to conditions specified in $query_params. |
|
248 | + * |
|
249 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
250 | + * @return EE_Soft_Delete_Base_Class[] |
|
251 | + */ |
|
252 | + public function get_all_deleted($query_params = array()) |
|
253 | + { |
|
254 | + $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params); |
|
255 | + return parent::get_all($query_params); |
|
256 | + } |
|
257 | + |
|
258 | + |
|
259 | + |
|
260 | + /** |
|
261 | + * Permanently deletes the selected rows. When selecting rows for deletion, ignores |
|
262 | + * whether they've been soft-deleted or not. (ie, you don't have to soft-delete objects |
|
263 | + * before you can permanently delete them). |
|
264 | + * Because this will cause a real deletion, related models may block this deletion (ie, add an error |
|
265 | + * and abort the delete) |
|
266 | + * |
|
267 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
268 | + * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info |
|
269 | + * that blocks it (ie, there' sno other data that depends on this data); if false, deletes regardless of other objects |
|
270 | + * which may depend on it. Its generally advisable to always leave this as TRUE, otherwise you could easily corrupt your DB |
|
271 | + * @return boolean success |
|
272 | + */ |
|
273 | + public function delete_permanently($query_params = array(), $allow_blocking = true) |
|
274 | + { |
|
275 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
276 | + return parent::delete_permanently($query_params, $allow_blocking); |
|
277 | + } |
|
278 | + |
|
279 | + |
|
280 | + |
|
281 | + /** |
|
282 | + * Restores a particular item by its ID (primary key). Ignores the fact whether the item |
|
283 | + * has been soft-deleted or not. |
|
284 | + * |
|
285 | + * @param mixed $ID int if primary key is an int, string otherwise |
|
286 | + * @return boolean success |
|
287 | + */ |
|
288 | + public function restore_by_ID($ID = false) |
|
289 | + { |
|
290 | + return $this->delete_or_restore_by_ID(false, $ID); |
|
291 | + } |
|
292 | + |
|
293 | + |
|
294 | + |
|
295 | + /** |
|
296 | + * For deleting or restoring a particular item. Note that this model is a SOFT-DELETABLE model! However, |
|
297 | + * this function will ignore whether the items have been soft-deleted or not. |
|
298 | + * |
|
299 | + * @param boolean $delete true for delete, false for restore |
|
300 | + * @param mixed $ID int if primary key is an int, string otherwise |
|
301 | + * @return boolean |
|
302 | + */ |
|
303 | + public function delete_or_restore_by_ID($delete = true, $ID = false) |
|
304 | + { |
|
305 | + if (! $ID) { |
|
306 | + return false; |
|
307 | + } |
|
308 | + if ( |
|
309 | + $this->delete_or_restore( |
|
310 | + $delete, |
|
311 | + $this->alter_query_params_to_restrict_by_ID($ID) |
|
312 | + ) |
|
313 | + ) { |
|
314 | + return true; |
|
315 | + } else { |
|
316 | + return false; |
|
317 | + } |
|
318 | + } |
|
319 | + |
|
320 | + |
|
321 | + |
|
322 | + /** |
|
323 | + * Overrides parent's 'delete' method to instead do a soft delete on all rows that |
|
324 | + * meet the criteria in $where_col_n_values. This particular function ignores whether the items have been soft-deleted or not. |
|
325 | + * Note: because this item will be soft-deleted only, |
|
326 | + * doesn't block because of model dependencies |
|
327 | + * |
|
328 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
329 | + * @param bool $block_deletes |
|
330 | + * @return boolean |
|
331 | + */ |
|
332 | + public function delete($query_params = array(), $block_deletes = false) |
|
333 | + { |
|
334 | + // no matter what, we WON'T block soft deletes. |
|
335 | + return $this->delete_or_restore(true, $query_params); |
|
336 | + } |
|
337 | + |
|
338 | + |
|
339 | + |
|
340 | + /** |
|
341 | + * 'Un-deletes' the chosen items. Note that this model is a SOFT-DELETABLE model! That means that, by default, trashed/soft-deleted |
|
342 | + * items are ignored in queries. However, this particular function ignores whether the items have been soft-deleted or not. |
|
343 | + * |
|
344 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
345 | + * @return boolean |
|
346 | + */ |
|
347 | + public function restore($query_params = array()) |
|
348 | + { |
|
349 | + return $this->delete_or_restore(false, $query_params); |
|
350 | + } |
|
351 | + |
|
352 | + |
|
353 | + |
|
354 | + /** |
|
355 | + * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered. |
|
356 | + * |
|
357 | + * @param boolean $delete true to indicate deletion, false to indicate restoration |
|
358 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
359 | + * @return boolean |
|
360 | + */ |
|
361 | + public function delete_or_restore($delete = true, $query_params = array()) |
|
362 | + { |
|
363 | + $deletedFlagFieldName = $this->deleted_field_name(); |
|
364 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
365 | + if ($this->update(array($deletedFlagFieldName => $delete), $query_params)) { |
|
366 | + return true; |
|
367 | + } else { |
|
368 | + return false; |
|
369 | + } |
|
370 | + } |
|
371 | + |
|
372 | + |
|
373 | + |
|
374 | + /** |
|
375 | + * Updates all the items of this model which match the $query params, regardless of whether |
|
376 | + * they've been soft-deleted or not |
|
377 | + * |
|
378 | + * @param array $fields_n_values like EEM_Base::update's $fields_n_value |
|
379 | + * @param array $query_params like EEM_base::get_all's $query_params |
|
380 | + * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects |
|
381 | + * in this model's entity map according to $fields_n_values that match $query_params. This |
|
382 | + * obviously has some overhead, so you can disable it by setting this to FALSE, but |
|
383 | + * be aware that model objects being used could get out-of-sync with the database |
|
384 | + * @return int number of items updated |
|
385 | + */ |
|
386 | + public function update_deleted_and_undeleted($fields_n_values, $query_params, $keep_model_objs_in_sync = true) |
|
387 | + { |
|
388 | + $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params); |
|
389 | + return $this->update($fields_n_values, $query_params, $keep_model_objs_in_sync); |
|
390 | + } |
|
391 | 391 | } |
@@ -33,7 +33,7 @@ discard block |
||
33 | 33 | */ |
34 | 34 | protected function __construct($timezone = '') |
35 | 35 | { |
36 | - if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
36 | + if ( ! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) { |
|
37 | 37 | $this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions(); |
38 | 38 | } |
39 | 39 | parent::__construct($timezone); |
@@ -134,7 +134,7 @@ discard block |
||
134 | 134 | protected function _alter_query_params_so_only_trashed_items_included($query_params) |
135 | 135 | { |
136 | 136 | $deletedFlagFieldName = $this->deleted_field_name(); |
137 | - $query_params[0][ $deletedFlagFieldName ] = true; |
|
137 | + $query_params[0][$deletedFlagFieldName] = true; |
|
138 | 138 | return $query_params; |
139 | 139 | } |
140 | 140 | |
@@ -174,7 +174,7 @@ discard block |
||
174 | 174 | */ |
175 | 175 | protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params) |
176 | 176 | { |
177 | - if (! isset($query_params['default_where_conditions'])) { |
|
177 | + if ( ! isset($query_params['default_where_conditions'])) { |
|
178 | 178 | $query_params['default_where_conditions'] = 'minimum'; |
179 | 179 | } |
180 | 180 | return $query_params; |
@@ -302,7 +302,7 @@ discard block |
||
302 | 302 | */ |
303 | 303 | public function delete_or_restore_by_ID($delete = true, $ID = false) |
304 | 304 | { |
305 | - if (! $ID) { |
|
305 | + if ( ! $ID) { |
|
306 | 306 | return false; |
307 | 307 | } |
308 | 308 | if ( |
@@ -14,1748 +14,1748 @@ |
||
14 | 14 | class EE_Line_Item extends EE_Base_Class implements EEI_Line_Item |
15 | 15 | { |
16 | 16 | |
17 | - /** |
|
18 | - * for children line items (currently not a normal relation) |
|
19 | - * |
|
20 | - * @type EE_Line_Item[] |
|
21 | - */ |
|
22 | - protected $_children = array(); |
|
23 | - |
|
24 | - /** |
|
25 | - * for the parent line item |
|
26 | - * |
|
27 | - * @var EE_Line_Item |
|
28 | - */ |
|
29 | - protected $_parent; |
|
30 | - |
|
31 | - |
|
32 | - /** |
|
33 | - * @param array $props_n_values incoming values |
|
34 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
35 | - * used.) |
|
36 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
37 | - * date_format and the second value is the time format |
|
38 | - * @return EE_Line_Item |
|
39 | - * @throws EE_Error |
|
40 | - * @throws InvalidArgumentException |
|
41 | - * @throws InvalidDataTypeException |
|
42 | - * @throws InvalidInterfaceException |
|
43 | - * @throws ReflectionException |
|
44 | - */ |
|
45 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
46 | - { |
|
47 | - $has_object = parent::_check_for_object( |
|
48 | - $props_n_values, |
|
49 | - __CLASS__, |
|
50 | - $timezone, |
|
51 | - $date_formats |
|
52 | - ); |
|
53 | - return $has_object |
|
54 | - ? $has_object |
|
55 | - : new self($props_n_values, false, $timezone); |
|
56 | - } |
|
57 | - |
|
58 | - |
|
59 | - /** |
|
60 | - * @param array $props_n_values incoming values from the database |
|
61 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
62 | - * the website will be used. |
|
63 | - * @return EE_Line_Item |
|
64 | - * @throws EE_Error |
|
65 | - * @throws InvalidArgumentException |
|
66 | - * @throws InvalidDataTypeException |
|
67 | - * @throws InvalidInterfaceException |
|
68 | - * @throws ReflectionException |
|
69 | - */ |
|
70 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
71 | - { |
|
72 | - return new self($props_n_values, true, $timezone); |
|
73 | - } |
|
74 | - |
|
75 | - |
|
76 | - /** |
|
77 | - * Adds some defaults if they're not specified |
|
78 | - * |
|
79 | - * @param array $fieldValues |
|
80 | - * @param bool $bydb |
|
81 | - * @param string $timezone |
|
82 | - * @throws EE_Error |
|
83 | - * @throws InvalidArgumentException |
|
84 | - * @throws InvalidDataTypeException |
|
85 | - * @throws InvalidInterfaceException |
|
86 | - * @throws ReflectionException |
|
87 | - */ |
|
88 | - protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') |
|
89 | - { |
|
90 | - parent::__construct($fieldValues, $bydb, $timezone); |
|
91 | - if (! $this->get('LIN_code')) { |
|
92 | - $this->set_code($this->generate_code()); |
|
93 | - } |
|
94 | - } |
|
95 | - |
|
96 | - |
|
97 | - /** |
|
98 | - * Gets ID |
|
99 | - * |
|
100 | - * @return int |
|
101 | - * @throws EE_Error |
|
102 | - * @throws InvalidArgumentException |
|
103 | - * @throws InvalidDataTypeException |
|
104 | - * @throws InvalidInterfaceException |
|
105 | - * @throws ReflectionException |
|
106 | - */ |
|
107 | - public function ID() |
|
108 | - { |
|
109 | - return $this->get('LIN_ID'); |
|
110 | - } |
|
111 | - |
|
112 | - |
|
113 | - /** |
|
114 | - * Gets TXN_ID |
|
115 | - * |
|
116 | - * @return int |
|
117 | - * @throws EE_Error |
|
118 | - * @throws InvalidArgumentException |
|
119 | - * @throws InvalidDataTypeException |
|
120 | - * @throws InvalidInterfaceException |
|
121 | - * @throws ReflectionException |
|
122 | - */ |
|
123 | - public function TXN_ID() |
|
124 | - { |
|
125 | - return $this->get('TXN_ID'); |
|
126 | - } |
|
127 | - |
|
128 | - |
|
129 | - /** |
|
130 | - * Sets TXN_ID |
|
131 | - * |
|
132 | - * @param int $TXN_ID |
|
133 | - * @throws EE_Error |
|
134 | - * @throws InvalidArgumentException |
|
135 | - * @throws InvalidDataTypeException |
|
136 | - * @throws InvalidInterfaceException |
|
137 | - * @throws ReflectionException |
|
138 | - */ |
|
139 | - public function set_TXN_ID($TXN_ID) |
|
140 | - { |
|
141 | - $this->set('TXN_ID', $TXN_ID); |
|
142 | - } |
|
143 | - |
|
144 | - |
|
145 | - /** |
|
146 | - * Gets name |
|
147 | - * |
|
148 | - * @return string |
|
149 | - * @throws EE_Error |
|
150 | - * @throws InvalidArgumentException |
|
151 | - * @throws InvalidDataTypeException |
|
152 | - * @throws InvalidInterfaceException |
|
153 | - * @throws ReflectionException |
|
154 | - */ |
|
155 | - public function name() |
|
156 | - { |
|
157 | - $name = $this->get('LIN_name'); |
|
158 | - if (! $name) { |
|
159 | - $name = ucwords(str_replace('-', ' ', $this->type())); |
|
160 | - } |
|
161 | - return $name; |
|
162 | - } |
|
163 | - |
|
164 | - |
|
165 | - /** |
|
166 | - * Sets name |
|
167 | - * |
|
168 | - * @param string $name |
|
169 | - * @throws EE_Error |
|
170 | - * @throws InvalidArgumentException |
|
171 | - * @throws InvalidDataTypeException |
|
172 | - * @throws InvalidInterfaceException |
|
173 | - * @throws ReflectionException |
|
174 | - */ |
|
175 | - public function set_name($name) |
|
176 | - { |
|
177 | - $this->set('LIN_name', $name); |
|
178 | - } |
|
179 | - |
|
180 | - |
|
181 | - /** |
|
182 | - * Gets desc |
|
183 | - * |
|
184 | - * @return string |
|
185 | - * @throws EE_Error |
|
186 | - * @throws InvalidArgumentException |
|
187 | - * @throws InvalidDataTypeException |
|
188 | - * @throws InvalidInterfaceException |
|
189 | - * @throws ReflectionException |
|
190 | - */ |
|
191 | - public function desc() |
|
192 | - { |
|
193 | - return $this->get('LIN_desc'); |
|
194 | - } |
|
195 | - |
|
196 | - |
|
197 | - /** |
|
198 | - * Sets desc |
|
199 | - * |
|
200 | - * @param string $desc |
|
201 | - * @throws EE_Error |
|
202 | - * @throws InvalidArgumentException |
|
203 | - * @throws InvalidDataTypeException |
|
204 | - * @throws InvalidInterfaceException |
|
205 | - * @throws ReflectionException |
|
206 | - */ |
|
207 | - public function set_desc($desc) |
|
208 | - { |
|
209 | - $this->set('LIN_desc', $desc); |
|
210 | - } |
|
211 | - |
|
212 | - |
|
213 | - /** |
|
214 | - * Gets quantity |
|
215 | - * |
|
216 | - * @return int |
|
217 | - * @throws EE_Error |
|
218 | - * @throws InvalidArgumentException |
|
219 | - * @throws InvalidDataTypeException |
|
220 | - * @throws InvalidInterfaceException |
|
221 | - * @throws ReflectionException |
|
222 | - */ |
|
223 | - public function quantity() |
|
224 | - { |
|
225 | - return $this->get('LIN_quantity'); |
|
226 | - } |
|
227 | - |
|
228 | - |
|
229 | - /** |
|
230 | - * Sets quantity |
|
231 | - * |
|
232 | - * @param int $quantity |
|
233 | - * @throws EE_Error |
|
234 | - * @throws InvalidArgumentException |
|
235 | - * @throws InvalidDataTypeException |
|
236 | - * @throws InvalidInterfaceException |
|
237 | - * @throws ReflectionException |
|
238 | - */ |
|
239 | - public function set_quantity($quantity) |
|
240 | - { |
|
241 | - $this->set('LIN_quantity', max($quantity, 0)); |
|
242 | - } |
|
243 | - |
|
244 | - |
|
245 | - /** |
|
246 | - * Gets item_id |
|
247 | - * |
|
248 | - * @return string |
|
249 | - * @throws EE_Error |
|
250 | - * @throws InvalidArgumentException |
|
251 | - * @throws InvalidDataTypeException |
|
252 | - * @throws InvalidInterfaceException |
|
253 | - * @throws ReflectionException |
|
254 | - */ |
|
255 | - public function OBJ_ID() |
|
256 | - { |
|
257 | - return $this->get('OBJ_ID'); |
|
258 | - } |
|
259 | - |
|
260 | - |
|
261 | - /** |
|
262 | - * Sets item_id |
|
263 | - * |
|
264 | - * @param string $item_id |
|
265 | - * @throws EE_Error |
|
266 | - * @throws InvalidArgumentException |
|
267 | - * @throws InvalidDataTypeException |
|
268 | - * @throws InvalidInterfaceException |
|
269 | - * @throws ReflectionException |
|
270 | - */ |
|
271 | - public function set_OBJ_ID($item_id) |
|
272 | - { |
|
273 | - $this->set('OBJ_ID', $item_id); |
|
274 | - } |
|
275 | - |
|
276 | - |
|
277 | - /** |
|
278 | - * Gets item_type |
|
279 | - * |
|
280 | - * @return string |
|
281 | - * @throws EE_Error |
|
282 | - * @throws InvalidArgumentException |
|
283 | - * @throws InvalidDataTypeException |
|
284 | - * @throws InvalidInterfaceException |
|
285 | - * @throws ReflectionException |
|
286 | - */ |
|
287 | - public function OBJ_type() |
|
288 | - { |
|
289 | - return $this->get('OBJ_type'); |
|
290 | - } |
|
291 | - |
|
292 | - |
|
293 | - /** |
|
294 | - * Gets item_type |
|
295 | - * |
|
296 | - * @return string |
|
297 | - * @throws EE_Error |
|
298 | - * @throws InvalidArgumentException |
|
299 | - * @throws InvalidDataTypeException |
|
300 | - * @throws InvalidInterfaceException |
|
301 | - * @throws ReflectionException |
|
302 | - */ |
|
303 | - public function OBJ_type_i18n() |
|
304 | - { |
|
305 | - $obj_type = $this->OBJ_type(); |
|
306 | - switch ($obj_type) { |
|
307 | - case EEM_Line_Item::OBJ_TYPE_EVENT: |
|
308 | - $obj_type = esc_html__('Event', 'event_espresso'); |
|
309 | - break; |
|
310 | - case EEM_Line_Item::OBJ_TYPE_PRICE: |
|
311 | - $obj_type = esc_html__('Price', 'event_espresso'); |
|
312 | - break; |
|
313 | - case EEM_Line_Item::OBJ_TYPE_PROMOTION: |
|
314 | - $obj_type = esc_html__('Promotion', 'event_espresso'); |
|
315 | - break; |
|
316 | - case EEM_Line_Item::OBJ_TYPE_TICKET: |
|
317 | - $obj_type = esc_html__('Ticket', 'event_espresso'); |
|
318 | - break; |
|
319 | - case EEM_Line_Item::OBJ_TYPE_TRANSACTION: |
|
320 | - $obj_type = esc_html__('Transaction', 'event_espresso'); |
|
321 | - break; |
|
322 | - } |
|
323 | - return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this); |
|
324 | - } |
|
325 | - |
|
326 | - |
|
327 | - /** |
|
328 | - * Sets item_type |
|
329 | - * |
|
330 | - * @param string $OBJ_type |
|
331 | - * @throws EE_Error |
|
332 | - * @throws InvalidArgumentException |
|
333 | - * @throws InvalidDataTypeException |
|
334 | - * @throws InvalidInterfaceException |
|
335 | - * @throws ReflectionException |
|
336 | - */ |
|
337 | - public function set_OBJ_type($OBJ_type) |
|
338 | - { |
|
339 | - $this->set('OBJ_type', $OBJ_type); |
|
340 | - } |
|
341 | - |
|
342 | - |
|
343 | - /** |
|
344 | - * Gets unit_price |
|
345 | - * |
|
346 | - * @return float |
|
347 | - * @throws EE_Error |
|
348 | - * @throws InvalidArgumentException |
|
349 | - * @throws InvalidDataTypeException |
|
350 | - * @throws InvalidInterfaceException |
|
351 | - * @throws ReflectionException |
|
352 | - */ |
|
353 | - public function unit_price() |
|
354 | - { |
|
355 | - return $this->get('LIN_unit_price'); |
|
356 | - } |
|
357 | - |
|
358 | - |
|
359 | - /** |
|
360 | - * Sets unit_price |
|
361 | - * |
|
362 | - * @param float $unit_price |
|
363 | - * @throws EE_Error |
|
364 | - * @throws InvalidArgumentException |
|
365 | - * @throws InvalidDataTypeException |
|
366 | - * @throws InvalidInterfaceException |
|
367 | - * @throws ReflectionException |
|
368 | - */ |
|
369 | - public function set_unit_price($unit_price) |
|
370 | - { |
|
371 | - $this->set('LIN_unit_price', $unit_price); |
|
372 | - } |
|
373 | - |
|
374 | - |
|
375 | - /** |
|
376 | - * Checks if this item is a percentage modifier or not |
|
377 | - * |
|
378 | - * @return boolean |
|
379 | - * @throws EE_Error |
|
380 | - * @throws InvalidArgumentException |
|
381 | - * @throws InvalidDataTypeException |
|
382 | - * @throws InvalidInterfaceException |
|
383 | - * @throws ReflectionException |
|
384 | - */ |
|
385 | - public function is_percent() |
|
386 | - { |
|
387 | - if ($this->is_tax_sub_total()) { |
|
388 | - // tax subtotals HAVE a percent on them, that percentage only applies |
|
389 | - // to taxable items, so its' an exception. Treat it like a flat line item |
|
390 | - return false; |
|
391 | - } |
|
392 | - $unit_price = abs($this->get('LIN_unit_price')); |
|
393 | - $percent = abs($this->get('LIN_percent')); |
|
394 | - if ($unit_price < .001 && $percent) { |
|
395 | - return true; |
|
396 | - } |
|
397 | - if ($unit_price >= .001 && ! $percent) { |
|
398 | - return false; |
|
399 | - } |
|
400 | - if ($unit_price >= .001 && $percent) { |
|
401 | - throw new EE_Error( |
|
402 | - sprintf( |
|
403 | - esc_html__( |
|
404 | - 'A Line Item can not have a unit price of (%s) AND a percent (%s)!', |
|
405 | - 'event_espresso' |
|
406 | - ), |
|
407 | - $unit_price, |
|
408 | - $percent |
|
409 | - ) |
|
410 | - ); |
|
411 | - } |
|
412 | - // if they're both 0, assume its not a percent item |
|
413 | - return false; |
|
414 | - } |
|
415 | - |
|
416 | - |
|
417 | - /** |
|
418 | - * Gets percent (between 100-.001) |
|
419 | - * |
|
420 | - * @return float |
|
421 | - * @throws EE_Error |
|
422 | - * @throws InvalidArgumentException |
|
423 | - * @throws InvalidDataTypeException |
|
424 | - * @throws InvalidInterfaceException |
|
425 | - * @throws ReflectionException |
|
426 | - */ |
|
427 | - public function percent() |
|
428 | - { |
|
429 | - return $this->get('LIN_percent'); |
|
430 | - } |
|
431 | - |
|
432 | - |
|
433 | - /** |
|
434 | - * Sets percent (between 100-0.01) |
|
435 | - * |
|
436 | - * @param float $percent |
|
437 | - * @throws EE_Error |
|
438 | - * @throws InvalidArgumentException |
|
439 | - * @throws InvalidDataTypeException |
|
440 | - * @throws InvalidInterfaceException |
|
441 | - * @throws ReflectionException |
|
442 | - */ |
|
443 | - public function set_percent($percent) |
|
444 | - { |
|
445 | - $this->set('LIN_percent', $percent); |
|
446 | - } |
|
447 | - |
|
448 | - |
|
449 | - /** |
|
450 | - * Gets total |
|
451 | - * |
|
452 | - * @return float |
|
453 | - * @throws EE_Error |
|
454 | - * @throws InvalidArgumentException |
|
455 | - * @throws InvalidDataTypeException |
|
456 | - * @throws InvalidInterfaceException |
|
457 | - * @throws ReflectionException |
|
458 | - */ |
|
459 | - public function total() |
|
460 | - { |
|
461 | - return $this->get('LIN_total'); |
|
462 | - } |
|
463 | - |
|
464 | - |
|
465 | - /** |
|
466 | - * Sets total |
|
467 | - * |
|
468 | - * @param float $total |
|
469 | - * @throws EE_Error |
|
470 | - * @throws InvalidArgumentException |
|
471 | - * @throws InvalidDataTypeException |
|
472 | - * @throws InvalidInterfaceException |
|
473 | - * @throws ReflectionException |
|
474 | - */ |
|
475 | - public function set_total($total) |
|
476 | - { |
|
477 | - $this->set('LIN_total', $total); |
|
478 | - } |
|
479 | - |
|
480 | - |
|
481 | - /** |
|
482 | - * Gets order |
|
483 | - * |
|
484 | - * @return int |
|
485 | - * @throws EE_Error |
|
486 | - * @throws InvalidArgumentException |
|
487 | - * @throws InvalidDataTypeException |
|
488 | - * @throws InvalidInterfaceException |
|
489 | - * @throws ReflectionException |
|
490 | - */ |
|
491 | - public function order() |
|
492 | - { |
|
493 | - return $this->get('LIN_order'); |
|
494 | - } |
|
495 | - |
|
496 | - |
|
497 | - /** |
|
498 | - * Sets order |
|
499 | - * |
|
500 | - * @param int $order |
|
501 | - * @throws EE_Error |
|
502 | - * @throws InvalidArgumentException |
|
503 | - * @throws InvalidDataTypeException |
|
504 | - * @throws InvalidInterfaceException |
|
505 | - * @throws ReflectionException |
|
506 | - */ |
|
507 | - public function set_order($order) |
|
508 | - { |
|
509 | - $this->set('LIN_order', $order); |
|
510 | - } |
|
511 | - |
|
512 | - |
|
513 | - /** |
|
514 | - * Gets parent |
|
515 | - * |
|
516 | - * @return int |
|
517 | - * @throws EE_Error |
|
518 | - * @throws InvalidArgumentException |
|
519 | - * @throws InvalidDataTypeException |
|
520 | - * @throws InvalidInterfaceException |
|
521 | - * @throws ReflectionException |
|
522 | - */ |
|
523 | - public function parent_ID() |
|
524 | - { |
|
525 | - return $this->get('LIN_parent'); |
|
526 | - } |
|
527 | - |
|
528 | - |
|
529 | - /** |
|
530 | - * Sets parent |
|
531 | - * |
|
532 | - * @param int $parent |
|
533 | - * @throws EE_Error |
|
534 | - * @throws InvalidArgumentException |
|
535 | - * @throws InvalidDataTypeException |
|
536 | - * @throws InvalidInterfaceException |
|
537 | - * @throws ReflectionException |
|
538 | - */ |
|
539 | - public function set_parent_ID($parent) |
|
540 | - { |
|
541 | - $this->set('LIN_parent', $parent); |
|
542 | - } |
|
543 | - |
|
544 | - |
|
545 | - /** |
|
546 | - * Gets type |
|
547 | - * |
|
548 | - * @return string |
|
549 | - * @throws EE_Error |
|
550 | - * @throws InvalidArgumentException |
|
551 | - * @throws InvalidDataTypeException |
|
552 | - * @throws InvalidInterfaceException |
|
553 | - * @throws ReflectionException |
|
554 | - */ |
|
555 | - public function type() |
|
556 | - { |
|
557 | - return $this->get('LIN_type'); |
|
558 | - } |
|
559 | - |
|
560 | - |
|
561 | - /** |
|
562 | - * Sets type |
|
563 | - * |
|
564 | - * @param string $type |
|
565 | - * @throws EE_Error |
|
566 | - * @throws InvalidArgumentException |
|
567 | - * @throws InvalidDataTypeException |
|
568 | - * @throws InvalidInterfaceException |
|
569 | - * @throws ReflectionException |
|
570 | - */ |
|
571 | - public function set_type($type) |
|
572 | - { |
|
573 | - $this->set('LIN_type', $type); |
|
574 | - } |
|
575 | - |
|
576 | - |
|
577 | - /** |
|
578 | - * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\ |
|
579 | - * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB |
|
580 | - * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()` |
|
581 | - * or indirectly by `EE_Line_item::add_child_line_item()`) |
|
582 | - * |
|
583 | - * @return EE_Base_Class|EE_Line_Item |
|
584 | - * @throws EE_Error |
|
585 | - * @throws InvalidArgumentException |
|
586 | - * @throws InvalidDataTypeException |
|
587 | - * @throws InvalidInterfaceException |
|
588 | - * @throws ReflectionException |
|
589 | - */ |
|
590 | - public function parent() |
|
591 | - { |
|
592 | - return $this->ID() |
|
593 | - ? $this->get_model()->get_one_by_ID($this->parent_ID()) |
|
594 | - : $this->_parent; |
|
595 | - } |
|
596 | - |
|
597 | - |
|
598 | - /** |
|
599 | - * Gets ALL the children of this line item (ie, all the parts that contribute towards this total). |
|
600 | - * |
|
601 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
602 | - * @throws EE_Error |
|
603 | - * @throws InvalidArgumentException |
|
604 | - * @throws InvalidDataTypeException |
|
605 | - * @throws InvalidInterfaceException |
|
606 | - * @throws ReflectionException |
|
607 | - */ |
|
608 | - public function children() |
|
609 | - { |
|
610 | - if ($this->ID()) { |
|
611 | - return $this->get_model()->get_all( |
|
612 | - array( |
|
613 | - array('LIN_parent' => $this->ID()), |
|
614 | - 'order_by' => array('LIN_order' => 'ASC'), |
|
615 | - ) |
|
616 | - ); |
|
617 | - } |
|
618 | - if (! is_array($this->_children)) { |
|
619 | - $this->_children = array(); |
|
620 | - } |
|
621 | - return $this->_children; |
|
622 | - } |
|
623 | - |
|
624 | - |
|
625 | - /** |
|
626 | - * Gets code |
|
627 | - * |
|
628 | - * @return string |
|
629 | - * @throws EE_Error |
|
630 | - * @throws InvalidArgumentException |
|
631 | - * @throws InvalidDataTypeException |
|
632 | - * @throws InvalidInterfaceException |
|
633 | - * @throws ReflectionException |
|
634 | - */ |
|
635 | - public function code() |
|
636 | - { |
|
637 | - return $this->get('LIN_code'); |
|
638 | - } |
|
639 | - |
|
640 | - |
|
641 | - /** |
|
642 | - * Sets code |
|
643 | - * |
|
644 | - * @param string $code |
|
645 | - * @throws EE_Error |
|
646 | - * @throws InvalidArgumentException |
|
647 | - * @throws InvalidDataTypeException |
|
648 | - * @throws InvalidInterfaceException |
|
649 | - * @throws ReflectionException |
|
650 | - */ |
|
651 | - public function set_code($code) |
|
652 | - { |
|
653 | - $this->set('LIN_code', $code); |
|
654 | - } |
|
655 | - |
|
656 | - |
|
657 | - /** |
|
658 | - * Gets is_taxable |
|
659 | - * |
|
660 | - * @return boolean |
|
661 | - * @throws EE_Error |
|
662 | - * @throws InvalidArgumentException |
|
663 | - * @throws InvalidDataTypeException |
|
664 | - * @throws InvalidInterfaceException |
|
665 | - * @throws ReflectionException |
|
666 | - */ |
|
667 | - public function is_taxable() |
|
668 | - { |
|
669 | - return $this->get('LIN_is_taxable'); |
|
670 | - } |
|
671 | - |
|
672 | - |
|
673 | - /** |
|
674 | - * Sets is_taxable |
|
675 | - * |
|
676 | - * @param boolean $is_taxable |
|
677 | - * @throws EE_Error |
|
678 | - * @throws InvalidArgumentException |
|
679 | - * @throws InvalidDataTypeException |
|
680 | - * @throws InvalidInterfaceException |
|
681 | - * @throws ReflectionException |
|
682 | - */ |
|
683 | - public function set_is_taxable($is_taxable) |
|
684 | - { |
|
685 | - $this->set('LIN_is_taxable', $is_taxable); |
|
686 | - } |
|
687 | - |
|
688 | - |
|
689 | - /** |
|
690 | - * Gets the object that this model-joins-to. |
|
691 | - * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on |
|
692 | - * EEM_Promotion_Object |
|
693 | - * Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object |
|
694 | - * |
|
695 | - * @return EE_Base_Class | NULL |
|
696 | - * @throws EE_Error |
|
697 | - * @throws InvalidArgumentException |
|
698 | - * @throws InvalidDataTypeException |
|
699 | - * @throws InvalidInterfaceException |
|
700 | - * @throws ReflectionException |
|
701 | - */ |
|
702 | - public function get_object() |
|
703 | - { |
|
704 | - $model_name_of_related_obj = $this->OBJ_type(); |
|
705 | - return $this->get_model()->has_relation($model_name_of_related_obj) |
|
706 | - ? $this->get_first_related($model_name_of_related_obj) |
|
707 | - : null; |
|
708 | - } |
|
709 | - |
|
710 | - |
|
711 | - /** |
|
712 | - * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket. |
|
713 | - * (IE, if this line item is for a price or something else, will return NULL) |
|
714 | - * |
|
715 | - * @param array $query_params |
|
716 | - * @return EE_Base_Class|EE_Ticket |
|
717 | - * @throws EE_Error |
|
718 | - * @throws InvalidArgumentException |
|
719 | - * @throws InvalidDataTypeException |
|
720 | - * @throws InvalidInterfaceException |
|
721 | - * @throws ReflectionException |
|
722 | - */ |
|
723 | - public function ticket($query_params = array()) |
|
724 | - { |
|
725 | - // we're going to assume that when this method is called |
|
726 | - // we always want to receive the attached ticket EVEN if that ticket is archived. |
|
727 | - // This can be overridden via the incoming $query_params argument |
|
728 | - $remove_defaults = array('default_where_conditions' => 'none'); |
|
729 | - $query_params = array_merge($remove_defaults, $query_params); |
|
730 | - return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TICKET, $query_params); |
|
731 | - } |
|
732 | - |
|
733 | - |
|
734 | - /** |
|
735 | - * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket |
|
736 | - * |
|
737 | - * @return EE_Datetime | NULL |
|
738 | - * @throws EE_Error |
|
739 | - * @throws InvalidArgumentException |
|
740 | - * @throws InvalidDataTypeException |
|
741 | - * @throws InvalidInterfaceException |
|
742 | - * @throws ReflectionException |
|
743 | - */ |
|
744 | - public function get_ticket_datetime() |
|
745 | - { |
|
746 | - if ($this->OBJ_type() === EEM_Line_Item::OBJ_TYPE_TICKET) { |
|
747 | - $ticket = $this->ticket(); |
|
748 | - if ($ticket instanceof EE_Ticket) { |
|
749 | - $datetime = $ticket->first_datetime(); |
|
750 | - if ($datetime instanceof EE_Datetime) { |
|
751 | - return $datetime; |
|
752 | - } |
|
753 | - } |
|
754 | - } |
|
755 | - return null; |
|
756 | - } |
|
757 | - |
|
758 | - |
|
759 | - /** |
|
760 | - * Gets the event's name that's related to the ticket, if this is for |
|
761 | - * a ticket |
|
762 | - * |
|
763 | - * @return string |
|
764 | - * @throws EE_Error |
|
765 | - * @throws InvalidArgumentException |
|
766 | - * @throws InvalidDataTypeException |
|
767 | - * @throws InvalidInterfaceException |
|
768 | - * @throws ReflectionException |
|
769 | - */ |
|
770 | - public function ticket_event_name() |
|
771 | - { |
|
772 | - $event_name = esc_html__('Unknown', 'event_espresso'); |
|
773 | - $event = $this->ticket_event(); |
|
774 | - if ($event instanceof EE_Event) { |
|
775 | - $event_name = $event->name(); |
|
776 | - } |
|
777 | - return $event_name; |
|
778 | - } |
|
779 | - |
|
780 | - |
|
781 | - /** |
|
782 | - * Gets the event that's related to the ticket, if this line item represents a ticket. |
|
783 | - * |
|
784 | - * @return EE_Event|null |
|
785 | - * @throws EE_Error |
|
786 | - * @throws InvalidArgumentException |
|
787 | - * @throws InvalidDataTypeException |
|
788 | - * @throws InvalidInterfaceException |
|
789 | - * @throws ReflectionException |
|
790 | - */ |
|
791 | - public function ticket_event() |
|
792 | - { |
|
793 | - $event = null; |
|
794 | - $ticket = $this->ticket(); |
|
795 | - if ($ticket instanceof EE_Ticket) { |
|
796 | - $datetime = $ticket->first_datetime(); |
|
797 | - if ($datetime instanceof EE_Datetime) { |
|
798 | - $event = $datetime->event(); |
|
799 | - } |
|
800 | - } |
|
801 | - return $event; |
|
802 | - } |
|
803 | - |
|
804 | - |
|
805 | - /** |
|
806 | - * Gets the first datetime for this lien item, assuming it's for a ticket |
|
807 | - * |
|
808 | - * @param string $date_format |
|
809 | - * @param string $time_format |
|
810 | - * @return string |
|
811 | - * @throws EE_Error |
|
812 | - * @throws InvalidArgumentException |
|
813 | - * @throws InvalidDataTypeException |
|
814 | - * @throws InvalidInterfaceException |
|
815 | - * @throws ReflectionException |
|
816 | - */ |
|
817 | - public function ticket_datetime_start($date_format = '', $time_format = '') |
|
818 | - { |
|
819 | - $first_datetime_string = esc_html__('Unknown', 'event_espresso'); |
|
820 | - $datetime = $this->get_ticket_datetime(); |
|
821 | - if ($datetime) { |
|
822 | - $first_datetime_string = $datetime->start_date_and_time($date_format, $time_format); |
|
823 | - } |
|
824 | - return $first_datetime_string; |
|
825 | - } |
|
826 | - |
|
827 | - |
|
828 | - /** |
|
829 | - * Adds the line item as a child to this line item. If there is another child line |
|
830 | - * item with the same LIN_code, it is overwritten by this new one |
|
831 | - * |
|
832 | - * @param EEI_Line_Item $line_item |
|
833 | - * @param bool $set_order |
|
834 | - * @return bool success |
|
835 | - * @throws EE_Error |
|
836 | - * @throws InvalidArgumentException |
|
837 | - * @throws InvalidDataTypeException |
|
838 | - * @throws InvalidInterfaceException |
|
839 | - * @throws ReflectionException |
|
840 | - */ |
|
841 | - public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true) |
|
842 | - { |
|
843 | - // should we calculate the LIN_order for this line item ? |
|
844 | - if ($set_order || $line_item->order() === null) { |
|
845 | - $line_item->set_order(count($this->children())); |
|
846 | - } |
|
847 | - if ($this->ID()) { |
|
848 | - // check for any duplicate line items (with the same code), if so, this replaces it |
|
849 | - $line_item_with_same_code = $this->get_child_line_item($line_item->code()); |
|
850 | - if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) { |
|
851 | - $this->delete_child_line_item($line_item_with_same_code->code()); |
|
852 | - } |
|
853 | - $line_item->set_parent_ID($this->ID()); |
|
854 | - if ($this->TXN_ID()) { |
|
855 | - $line_item->set_TXN_ID($this->TXN_ID()); |
|
856 | - } |
|
857 | - return $line_item->save(); |
|
858 | - } |
|
859 | - $this->_children[ $line_item->code() ] = $line_item; |
|
860 | - if ($line_item->parent() !== $this) { |
|
861 | - $line_item->set_parent($this); |
|
862 | - } |
|
863 | - return true; |
|
864 | - } |
|
865 | - |
|
866 | - |
|
867 | - /** |
|
868 | - * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation. |
|
869 | - * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save() |
|
870 | - * However, if this line item is NOT saved to the DB, this just caches the parent on |
|
871 | - * the EE_Line_Item::_parent property. |
|
872 | - * |
|
873 | - * @param EE_Line_Item $line_item |
|
874 | - * @throws EE_Error |
|
875 | - * @throws InvalidArgumentException |
|
876 | - * @throws InvalidDataTypeException |
|
877 | - * @throws InvalidInterfaceException |
|
878 | - * @throws ReflectionException |
|
879 | - */ |
|
880 | - public function set_parent($line_item) |
|
881 | - { |
|
882 | - if ($this->ID()) { |
|
883 | - if (! $line_item->ID()) { |
|
884 | - $line_item->save(); |
|
885 | - } |
|
886 | - $this->set_parent_ID($line_item->ID()); |
|
887 | - $this->save(); |
|
888 | - } else { |
|
889 | - $this->_parent = $line_item; |
|
890 | - $this->set_parent_ID($line_item->ID()); |
|
891 | - } |
|
892 | - } |
|
893 | - |
|
894 | - |
|
895 | - /** |
|
896 | - * Gets the child line item as specified by its code. Because this returns an object (by reference) |
|
897 | - * you can modify this child line item and the parent (this object) can know about them |
|
898 | - * because it also has a reference to that line item |
|
899 | - * |
|
900 | - * @param string $code |
|
901 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
902 | - * @throws EE_Error |
|
903 | - * @throws InvalidArgumentException |
|
904 | - * @throws InvalidDataTypeException |
|
905 | - * @throws InvalidInterfaceException |
|
906 | - * @throws ReflectionException |
|
907 | - */ |
|
908 | - public function get_child_line_item($code) |
|
909 | - { |
|
910 | - if ($this->ID()) { |
|
911 | - return $this->get_model()->get_one( |
|
912 | - array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code)) |
|
913 | - ); |
|
914 | - } |
|
915 | - return isset($this->_children[ $code ]) |
|
916 | - ? $this->_children[ $code ] |
|
917 | - : null; |
|
918 | - } |
|
919 | - |
|
920 | - |
|
921 | - /** |
|
922 | - * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD |
|
923 | - * cached on it) |
|
924 | - * |
|
925 | - * @return int |
|
926 | - * @throws EE_Error |
|
927 | - * @throws InvalidArgumentException |
|
928 | - * @throws InvalidDataTypeException |
|
929 | - * @throws InvalidInterfaceException |
|
930 | - * @throws ReflectionException |
|
931 | - */ |
|
932 | - public function delete_children_line_items() |
|
933 | - { |
|
934 | - if ($this->ID()) { |
|
935 | - return $this->get_model()->delete(array(array('LIN_parent' => $this->ID()))); |
|
936 | - } |
|
937 | - $count = count($this->_children); |
|
938 | - $this->_children = array(); |
|
939 | - return $count; |
|
940 | - } |
|
941 | - |
|
942 | - |
|
943 | - /** |
|
944 | - * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line |
|
945 | - * HAS NOT been saved to the DB, removes the child line item with index $code. |
|
946 | - * Also searches through the child's children for a matching line item. However, once a line item has been found |
|
947 | - * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be |
|
948 | - * deleted) |
|
949 | - * |
|
950 | - * @param string $code |
|
951 | - * @param bool $stop_search_once_found |
|
952 | - * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to |
|
953 | - * the DB yet) |
|
954 | - * @throws EE_Error |
|
955 | - * @throws InvalidArgumentException |
|
956 | - * @throws InvalidDataTypeException |
|
957 | - * @throws InvalidInterfaceException |
|
958 | - * @throws ReflectionException |
|
959 | - */ |
|
960 | - public function delete_child_line_item($code, $stop_search_once_found = true) |
|
961 | - { |
|
962 | - if ($this->ID()) { |
|
963 | - $items_deleted = 0; |
|
964 | - if ($this->code() === $code) { |
|
965 | - $items_deleted += EEH_Line_Item::delete_all_child_items($this); |
|
966 | - $items_deleted += (int) $this->delete(); |
|
967 | - if ($stop_search_once_found) { |
|
968 | - return $items_deleted; |
|
969 | - } |
|
970 | - } |
|
971 | - foreach ($this->children() as $child_line_item) { |
|
972 | - $items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found); |
|
973 | - } |
|
974 | - return $items_deleted; |
|
975 | - } |
|
976 | - if (isset($this->_children[ $code ])) { |
|
977 | - unset($this->_children[ $code ]); |
|
978 | - return 1; |
|
979 | - } |
|
980 | - return 0; |
|
981 | - } |
|
982 | - |
|
983 | - |
|
984 | - /** |
|
985 | - * If this line item is in the database, is of the type subtotal, and |
|
986 | - * has no children, why do we have it? It should be deleted so this function |
|
987 | - * does that |
|
988 | - * |
|
989 | - * @return boolean |
|
990 | - * @throws EE_Error |
|
991 | - * @throws InvalidArgumentException |
|
992 | - * @throws InvalidDataTypeException |
|
993 | - * @throws InvalidInterfaceException |
|
994 | - * @throws ReflectionException |
|
995 | - */ |
|
996 | - public function delete_if_childless_subtotal() |
|
997 | - { |
|
998 | - if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) { |
|
999 | - return $this->delete(); |
|
1000 | - } |
|
1001 | - return false; |
|
1002 | - } |
|
1003 | - |
|
1004 | - |
|
1005 | - /** |
|
1006 | - * Creates a code and returns a string. doesn't assign the code to this model object |
|
1007 | - * |
|
1008 | - * @return string |
|
1009 | - * @throws EE_Error |
|
1010 | - * @throws InvalidArgumentException |
|
1011 | - * @throws InvalidDataTypeException |
|
1012 | - * @throws InvalidInterfaceException |
|
1013 | - * @throws ReflectionException |
|
1014 | - */ |
|
1015 | - public function generate_code() |
|
1016 | - { |
|
1017 | - // each line item in the cart requires a unique identifier |
|
1018 | - return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime()); |
|
1019 | - } |
|
1020 | - |
|
1021 | - |
|
1022 | - /** |
|
1023 | - * @return bool |
|
1024 | - * @throws EE_Error |
|
1025 | - * @throws InvalidArgumentException |
|
1026 | - * @throws InvalidDataTypeException |
|
1027 | - * @throws InvalidInterfaceException |
|
1028 | - * @throws ReflectionException |
|
1029 | - */ |
|
1030 | - public function is_tax() |
|
1031 | - { |
|
1032 | - return $this->type() === EEM_Line_Item::type_tax; |
|
1033 | - } |
|
1034 | - |
|
1035 | - |
|
1036 | - /** |
|
1037 | - * @return bool |
|
1038 | - * @throws EE_Error |
|
1039 | - * @throws InvalidArgumentException |
|
1040 | - * @throws InvalidDataTypeException |
|
1041 | - * @throws InvalidInterfaceException |
|
1042 | - * @throws ReflectionException |
|
1043 | - */ |
|
1044 | - public function is_tax_sub_total() |
|
1045 | - { |
|
1046 | - return $this->type() === EEM_Line_Item::type_tax_sub_total; |
|
1047 | - } |
|
1048 | - |
|
1049 | - |
|
1050 | - /** |
|
1051 | - * @return bool |
|
1052 | - * @throws EE_Error |
|
1053 | - * @throws InvalidArgumentException |
|
1054 | - * @throws InvalidDataTypeException |
|
1055 | - * @throws InvalidInterfaceException |
|
1056 | - * @throws ReflectionException |
|
1057 | - */ |
|
1058 | - public function is_line_item() |
|
1059 | - { |
|
1060 | - return $this->type() === EEM_Line_Item::type_line_item; |
|
1061 | - } |
|
1062 | - |
|
1063 | - |
|
1064 | - /** |
|
1065 | - * @return bool |
|
1066 | - * @throws EE_Error |
|
1067 | - * @throws InvalidArgumentException |
|
1068 | - * @throws InvalidDataTypeException |
|
1069 | - * @throws InvalidInterfaceException |
|
1070 | - * @throws ReflectionException |
|
1071 | - */ |
|
1072 | - public function is_sub_line_item() |
|
1073 | - { |
|
1074 | - return $this->type() === EEM_Line_Item::type_sub_line_item; |
|
1075 | - } |
|
1076 | - |
|
1077 | - |
|
1078 | - /** |
|
1079 | - * @return bool |
|
1080 | - * @throws EE_Error |
|
1081 | - * @throws InvalidArgumentException |
|
1082 | - * @throws InvalidDataTypeException |
|
1083 | - * @throws InvalidInterfaceException |
|
1084 | - * @throws ReflectionException |
|
1085 | - */ |
|
1086 | - public function is_sub_total() |
|
1087 | - { |
|
1088 | - return $this->type() === EEM_Line_Item::type_sub_total; |
|
1089 | - } |
|
1090 | - |
|
1091 | - |
|
1092 | - /** |
|
1093 | - * Whether or not this line item is a cancellation line item |
|
1094 | - * |
|
1095 | - * @return boolean |
|
1096 | - * @throws EE_Error |
|
1097 | - * @throws InvalidArgumentException |
|
1098 | - * @throws InvalidDataTypeException |
|
1099 | - * @throws InvalidInterfaceException |
|
1100 | - * @throws ReflectionException |
|
1101 | - */ |
|
1102 | - public function is_cancellation() |
|
1103 | - { |
|
1104 | - return EEM_Line_Item::type_cancellation === $this->type(); |
|
1105 | - } |
|
1106 | - |
|
1107 | - |
|
1108 | - /** |
|
1109 | - * @return bool |
|
1110 | - * @throws EE_Error |
|
1111 | - * @throws InvalidArgumentException |
|
1112 | - * @throws InvalidDataTypeException |
|
1113 | - * @throws InvalidInterfaceException |
|
1114 | - * @throws ReflectionException |
|
1115 | - */ |
|
1116 | - public function is_total() |
|
1117 | - { |
|
1118 | - return $this->type() === EEM_Line_Item::type_total; |
|
1119 | - } |
|
1120 | - |
|
1121 | - |
|
1122 | - /** |
|
1123 | - * @return bool |
|
1124 | - * @throws EE_Error |
|
1125 | - * @throws InvalidArgumentException |
|
1126 | - * @throws InvalidDataTypeException |
|
1127 | - * @throws InvalidInterfaceException |
|
1128 | - * @throws ReflectionException |
|
1129 | - */ |
|
1130 | - public function is_cancelled() |
|
1131 | - { |
|
1132 | - return $this->type() === EEM_Line_Item::type_cancellation; |
|
1133 | - } |
|
1134 | - |
|
1135 | - |
|
1136 | - /** |
|
1137 | - * @return string like '2, 004.00', formatted according to the localized currency |
|
1138 | - * @throws EE_Error |
|
1139 | - * @throws InvalidArgumentException |
|
1140 | - * @throws InvalidDataTypeException |
|
1141 | - * @throws InvalidInterfaceException |
|
1142 | - * @throws ReflectionException |
|
1143 | - */ |
|
1144 | - public function unit_price_no_code() |
|
1145 | - { |
|
1146 | - return $this->get_pretty('LIN_unit_price', 'no_currency_code'); |
|
1147 | - } |
|
1148 | - |
|
1149 | - |
|
1150 | - /** |
|
1151 | - * @return string like '2, 004.00', formatted according to the localized currency |
|
1152 | - * @throws EE_Error |
|
1153 | - * @throws InvalidArgumentException |
|
1154 | - * @throws InvalidDataTypeException |
|
1155 | - * @throws InvalidInterfaceException |
|
1156 | - * @throws ReflectionException |
|
1157 | - */ |
|
1158 | - public function total_no_code() |
|
1159 | - { |
|
1160 | - return $this->get_pretty('LIN_total', 'no_currency_code'); |
|
1161 | - } |
|
1162 | - |
|
1163 | - |
|
1164 | - /** |
|
1165 | - * Gets the final total on this item, taking taxes into account. |
|
1166 | - * Has the side-effect of setting the sub-total as it was just calculated. |
|
1167 | - * If this is used on a grand-total line item, also updates the transaction's |
|
1168 | - * TXN_total (provided this line item is allowed to persist, otherwise we don't |
|
1169 | - * want to change a persistable transaction with info from a non-persistent line item) |
|
1170 | - * |
|
1171 | - * @param bool $update_txn_status |
|
1172 | - * @return float |
|
1173 | - * @throws EE_Error |
|
1174 | - * @throws InvalidArgumentException |
|
1175 | - * @throws InvalidDataTypeException |
|
1176 | - * @throws InvalidInterfaceException |
|
1177 | - * @throws ReflectionException |
|
1178 | - * @throws RuntimeException |
|
1179 | - */ |
|
1180 | - public function recalculate_total_including_taxes($update_txn_status = false) |
|
1181 | - { |
|
1182 | - $pre_tax_total = $this->recalculate_pre_tax_total(); |
|
1183 | - $tax_total = $this->recalculate_taxes_and_tax_total(); |
|
1184 | - $total = $pre_tax_total + $tax_total; |
|
1185 | - // no negative totals plz |
|
1186 | - $total = max($total, 0); |
|
1187 | - $this->set_total($total); |
|
1188 | - // only update the related transaction's total |
|
1189 | - // if we intend to save this line item and its a grand total |
|
1190 | - if ( |
|
1191 | - $this->allow_persist() && $this->type() === EEM_Line_Item::type_total |
|
1192 | - && $this->transaction() |
|
1193 | - instanceof |
|
1194 | - EE_Transaction |
|
1195 | - ) { |
|
1196 | - $this->transaction()->set_total($total); |
|
1197 | - if ($update_txn_status) { |
|
1198 | - // don't save the TXN because that will be done below |
|
1199 | - // and the following method only saves if the status changes |
|
1200 | - $this->transaction()->update_status_based_on_total_paid(false); |
|
1201 | - } |
|
1202 | - if ($this->transaction()->ID()) { |
|
1203 | - $this->transaction()->save(); |
|
1204 | - } |
|
1205 | - } |
|
1206 | - $this->maybe_save(); |
|
1207 | - return $total; |
|
1208 | - } |
|
1209 | - |
|
1210 | - |
|
1211 | - /** |
|
1212 | - * Recursively goes through all the children and recalculates sub-totals EXCEPT for |
|
1213 | - * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its |
|
1214 | - * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and |
|
1215 | - * when this is called on the grand total |
|
1216 | - * |
|
1217 | - * @return float |
|
1218 | - * @throws EE_Error |
|
1219 | - * @throws InvalidArgumentException |
|
1220 | - * @throws InvalidDataTypeException |
|
1221 | - * @throws InvalidInterfaceException |
|
1222 | - * @throws ReflectionException |
|
1223 | - */ |
|
1224 | - public function recalculate_pre_tax_total() |
|
1225 | - { |
|
1226 | - $total = 0; |
|
1227 | - $my_children = $this->children(); |
|
1228 | - $has_children = ! empty($my_children); |
|
1229 | - if ($has_children && $this->is_line_item()) { |
|
1230 | - $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children); |
|
1231 | - } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
1232 | - $total = $this->unit_price() * $this->quantity(); |
|
1233 | - } elseif ($this->is_sub_total() || $this->is_total()) { |
|
1234 | - $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children); |
|
1235 | - } elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) { |
|
1236 | - // completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total |
|
1237 | - return 0; |
|
1238 | - } |
|
1239 | - // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events) |
|
1240 | - if (! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()) { |
|
1241 | - if ($this->OBJ_type() !== EEM_Line_Item::OBJ_TYPE_EVENT) { |
|
1242 | - $this->set_quantity(1); |
|
1243 | - } |
|
1244 | - if (! $this->is_percent()) { |
|
1245 | - $this->set_unit_price($total); |
|
1246 | - } |
|
1247 | - } |
|
1248 | - // we don't want to bother saving grand totals, because that needs to factor in taxes anyways |
|
1249 | - // so it ought to be |
|
1250 | - if (! $this->is_total()) { |
|
1251 | - $this->set_total($total); |
|
1252 | - // if not a percent line item, make sure we keep the unit price in sync |
|
1253 | - if ( |
|
1254 | - $has_children |
|
1255 | - && $this->is_line_item() |
|
1256 | - && ! $this->is_percent() |
|
1257 | - ) { |
|
1258 | - if ($this->quantity() === 0) { |
|
1259 | - $new_unit_price = 0; |
|
1260 | - } else { |
|
1261 | - $new_unit_price = $this->total() / $this->quantity(); |
|
1262 | - } |
|
1263 | - $this->set_unit_price($new_unit_price); |
|
1264 | - } |
|
1265 | - $this->maybe_save(); |
|
1266 | - } |
|
1267 | - return $total; |
|
1268 | - } |
|
1269 | - |
|
1270 | - |
|
1271 | - /** |
|
1272 | - * Calculates the pretax total when this line item is a subtotal or total line item. |
|
1273 | - * Basically does a sum-then-round approach (ie, any percent line item that are children |
|
1274 | - * will calculate their total based on the un-rounded total we're working with so far, and |
|
1275 | - * THEN round the result; instead of rounding as we go like with sub-line-items) |
|
1276 | - * |
|
1277 | - * @param float $calculated_total_so_far |
|
1278 | - * @param EE_Line_Item[] $my_children |
|
1279 | - * @return float |
|
1280 | - * @throws EE_Error |
|
1281 | - * @throws InvalidArgumentException |
|
1282 | - * @throws InvalidDataTypeException |
|
1283 | - * @throws InvalidInterfaceException |
|
1284 | - * @throws ReflectionException |
|
1285 | - */ |
|
1286 | - protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null) |
|
1287 | - { |
|
1288 | - if ($my_children === null) { |
|
1289 | - $my_children = $this->children(); |
|
1290 | - } |
|
1291 | - $subtotal_quantity = 0; |
|
1292 | - // get the total of all its children |
|
1293 | - foreach ($my_children as $child_line_item) { |
|
1294 | - if ($child_line_item instanceof EE_Line_Item) { |
|
1295 | - // skip line item if it is cancelled or is a tax |
|
1296 | - if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
1297 | - continue; |
|
1298 | - } |
|
1299 | - // percentage line items are based on total so far |
|
1300 | - if ($child_line_item->is_percent()) { |
|
1301 | - // round as we go so that the line items add up ok |
|
1302 | - $percent_total = round( |
|
1303 | - $calculated_total_so_far * $child_line_item->percent() / 100, |
|
1304 | - EE_Registry::instance()->CFG->currency->dec_plc |
|
1305 | - ); |
|
1306 | - $child_line_item->set_total($percent_total); |
|
1307 | - // so far all percent line items should have a quantity of 1 |
|
1308 | - // (ie, no double percent discounts. Although that might be requested someday) |
|
1309 | - $child_line_item->set_quantity(1); |
|
1310 | - $child_line_item->maybe_save(); |
|
1311 | - $calculated_total_so_far += $percent_total; |
|
1312 | - } else { |
|
1313 | - // verify flat sub-line-item quantities match their parent |
|
1314 | - if ($child_line_item->is_sub_line_item()) { |
|
1315 | - $child_line_item->set_quantity($this->quantity()); |
|
1316 | - } |
|
1317 | - $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
1318 | - $subtotal_quantity += $child_line_item->quantity(); |
|
1319 | - } |
|
1320 | - } |
|
1321 | - } |
|
1322 | - if ($this->is_sub_total()) { |
|
1323 | - // no negative totals plz |
|
1324 | - $calculated_total_so_far = max($calculated_total_so_far, 0); |
|
1325 | - $subtotal_quantity = $subtotal_quantity > 0 ? 1 : 0; |
|
1326 | - $this->set_quantity($subtotal_quantity); |
|
1327 | - $this->maybe_save(); |
|
1328 | - } |
|
1329 | - return $calculated_total_so_far; |
|
1330 | - } |
|
1331 | - |
|
1332 | - |
|
1333 | - /** |
|
1334 | - * Calculates the pretax total for a normal line item, in a round-then-sum approach |
|
1335 | - * (where each sub-line-item is applied to the base price for the line item |
|
1336 | - * and the result is immediately rounded, rather than summing all the sub-line-items |
|
1337 | - * then rounding, like we do when recalculating pretax totals on totals and subtotals). |
|
1338 | - * |
|
1339 | - * @param float $calculated_total_so_far |
|
1340 | - * @param EE_Line_Item[] $my_children |
|
1341 | - * @return float |
|
1342 | - * @throws EE_Error |
|
1343 | - * @throws InvalidArgumentException |
|
1344 | - * @throws InvalidDataTypeException |
|
1345 | - * @throws InvalidInterfaceException |
|
1346 | - * @throws ReflectionException |
|
1347 | - */ |
|
1348 | - protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null) |
|
1349 | - { |
|
1350 | - if ($my_children === null) { |
|
1351 | - $my_children = $this->children(); |
|
1352 | - } |
|
1353 | - // we need to keep track of the running total for a single item, |
|
1354 | - // because we need to round as we go |
|
1355 | - $unit_price_for_total = 0; |
|
1356 | - $quantity_for_total = 1; |
|
1357 | - // get the total of all its children |
|
1358 | - foreach ($my_children as $child_line_item) { |
|
1359 | - if ($child_line_item instanceof EE_Line_Item) { |
|
1360 | - // skip line item if it is cancelled or is a tax |
|
1361 | - if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
1362 | - continue; |
|
1363 | - } |
|
1364 | - if ($child_line_item->is_percent()) { |
|
1365 | - // it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity |
|
1366 | - // not total multiplied by percent, because that ignores rounding along-the-way |
|
1367 | - $percent_unit_price = round( |
|
1368 | - $unit_price_for_total * $child_line_item->percent() / 100, |
|
1369 | - EE_Registry::instance()->CFG->currency->dec_plc |
|
1370 | - ); |
|
1371 | - $percent_total = $percent_unit_price * $quantity_for_total; |
|
1372 | - $child_line_item->set_total($percent_total); |
|
1373 | - // so far all percent line items should have a quantity of 1 |
|
1374 | - // (ie, no double percent discounts. Although that might be requested someday) |
|
1375 | - $child_line_item->set_quantity(1); |
|
1376 | - $child_line_item->maybe_save(); |
|
1377 | - $calculated_total_so_far += $percent_total; |
|
1378 | - $unit_price_for_total += $percent_unit_price; |
|
1379 | - } else { |
|
1380 | - // verify flat sub-line-item quantities match their parent |
|
1381 | - if ($child_line_item->is_sub_line_item()) { |
|
1382 | - $child_line_item->set_quantity($this->quantity()); |
|
1383 | - } |
|
1384 | - $quantity_for_total = $child_line_item->quantity(); |
|
1385 | - $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
1386 | - $unit_price_for_total += $child_line_item->unit_price(); |
|
1387 | - } |
|
1388 | - } |
|
1389 | - } |
|
1390 | - return $calculated_total_so_far; |
|
1391 | - } |
|
1392 | - |
|
1393 | - |
|
1394 | - /** |
|
1395 | - * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets |
|
1396 | - * the totals on each tax calculated, and returns the final tax total. Re-saves tax line items |
|
1397 | - * and tax sub-total if already in the DB |
|
1398 | - * |
|
1399 | - * @return float |
|
1400 | - * @throws EE_Error |
|
1401 | - * @throws InvalidArgumentException |
|
1402 | - * @throws InvalidDataTypeException |
|
1403 | - * @throws InvalidInterfaceException |
|
1404 | - * @throws ReflectionException |
|
1405 | - */ |
|
1406 | - public function recalculate_taxes_and_tax_total() |
|
1407 | - { |
|
1408 | - // get all taxes |
|
1409 | - $taxes = $this->tax_descendants(); |
|
1410 | - // calculate the pretax total |
|
1411 | - $taxable_total = $this->taxable_total(); |
|
1412 | - $tax_total = 0; |
|
1413 | - foreach ($taxes as $tax) { |
|
1414 | - $total_on_this_tax = $taxable_total * $tax->percent() / 100; |
|
1415 | - // remember the total on this line item |
|
1416 | - $tax->set_total($total_on_this_tax); |
|
1417 | - $tax->maybe_save(); |
|
1418 | - $tax_total += $tax->total(); |
|
1419 | - } |
|
1420 | - $this->_recalculate_tax_sub_total(); |
|
1421 | - return $tax_total; |
|
1422 | - } |
|
1423 | - |
|
1424 | - |
|
1425 | - /** |
|
1426 | - * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated |
|
1427 | - * |
|
1428 | - * @return void |
|
1429 | - * @throws EE_Error |
|
1430 | - * @throws InvalidArgumentException |
|
1431 | - * @throws InvalidDataTypeException |
|
1432 | - * @throws InvalidInterfaceException |
|
1433 | - * @throws ReflectionException |
|
1434 | - */ |
|
1435 | - private function _recalculate_tax_sub_total() |
|
1436 | - { |
|
1437 | - if ($this->is_tax_sub_total()) { |
|
1438 | - $total = 0; |
|
1439 | - $total_percent = 0; |
|
1440 | - // simply loop through all its children (which should be taxes) and sum their total |
|
1441 | - foreach ($this->children() as $child_tax) { |
|
1442 | - if ($child_tax instanceof EE_Line_Item) { |
|
1443 | - $total += $child_tax->total(); |
|
1444 | - $total_percent += $child_tax->percent(); |
|
1445 | - } |
|
1446 | - } |
|
1447 | - $this->set_total($total); |
|
1448 | - $this->set_percent($total_percent); |
|
1449 | - $this->maybe_save(); |
|
1450 | - } elseif ($this->is_total()) { |
|
1451 | - foreach ($this->children() as $maybe_tax_subtotal) { |
|
1452 | - if ($maybe_tax_subtotal instanceof EE_Line_Item) { |
|
1453 | - $maybe_tax_subtotal->_recalculate_tax_sub_total(); |
|
1454 | - } |
|
1455 | - } |
|
1456 | - } |
|
1457 | - } |
|
1458 | - |
|
1459 | - |
|
1460 | - /** |
|
1461 | - * Gets the total tax on this line item. Assumes taxes have already been calculated using |
|
1462 | - * recalculate_taxes_and_total |
|
1463 | - * |
|
1464 | - * @return float |
|
1465 | - * @throws EE_Error |
|
1466 | - * @throws InvalidArgumentException |
|
1467 | - * @throws InvalidDataTypeException |
|
1468 | - * @throws InvalidInterfaceException |
|
1469 | - * @throws ReflectionException |
|
1470 | - */ |
|
1471 | - public function get_total_tax() |
|
1472 | - { |
|
1473 | - $this->_recalculate_tax_sub_total(); |
|
1474 | - $total = 0; |
|
1475 | - foreach ($this->tax_descendants() as $tax_line_item) { |
|
1476 | - if ($tax_line_item instanceof EE_Line_Item) { |
|
1477 | - $total += $tax_line_item->total(); |
|
1478 | - } |
|
1479 | - } |
|
1480 | - return $total; |
|
1481 | - } |
|
1482 | - |
|
1483 | - |
|
1484 | - /** |
|
1485 | - * Gets the total for all the items purchased only |
|
1486 | - * |
|
1487 | - * @return float |
|
1488 | - * @throws EE_Error |
|
1489 | - * @throws InvalidArgumentException |
|
1490 | - * @throws InvalidDataTypeException |
|
1491 | - * @throws InvalidInterfaceException |
|
1492 | - * @throws ReflectionException |
|
1493 | - */ |
|
1494 | - public function get_items_total() |
|
1495 | - { |
|
1496 | - // by default, let's make sure we're consistent with the existing line item |
|
1497 | - if ($this->is_total()) { |
|
1498 | - $pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this); |
|
1499 | - if ($pretax_subtotal_li instanceof EE_Line_Item) { |
|
1500 | - return $pretax_subtotal_li->total(); |
|
1501 | - } |
|
1502 | - } |
|
1503 | - $total = 0; |
|
1504 | - foreach ($this->get_items() as $item) { |
|
1505 | - if ($item instanceof EE_Line_Item) { |
|
1506 | - $total += $item->total(); |
|
1507 | - } |
|
1508 | - } |
|
1509 | - return $total; |
|
1510 | - } |
|
1511 | - |
|
1512 | - |
|
1513 | - /** |
|
1514 | - * Gets all the descendants (ie, children or children of children etc) that |
|
1515 | - * are of the type 'tax' |
|
1516 | - * |
|
1517 | - * @return EE_Line_Item[] |
|
1518 | - * @throws EE_Error |
|
1519 | - */ |
|
1520 | - public function tax_descendants() |
|
1521 | - { |
|
1522 | - return EEH_Line_Item::get_tax_descendants($this); |
|
1523 | - } |
|
1524 | - |
|
1525 | - |
|
1526 | - /** |
|
1527 | - * Gets all the real items purchased which are children of this item |
|
1528 | - * |
|
1529 | - * @return EE_Line_Item[] |
|
1530 | - * @throws EE_Error |
|
1531 | - */ |
|
1532 | - public function get_items() |
|
1533 | - { |
|
1534 | - return EEH_Line_Item::get_line_item_descendants($this); |
|
1535 | - } |
|
1536 | - |
|
1537 | - |
|
1538 | - /** |
|
1539 | - * Returns the amount taxable among this line item's children (or if it has no children, |
|
1540 | - * how much of it is taxable). Does not recalculate totals or subtotals. |
|
1541 | - * If the taxable total is negative, (eg, if none of the tickets were taxable, |
|
1542 | - * but there is a "Taxable" discount), returns 0. |
|
1543 | - * |
|
1544 | - * @return float |
|
1545 | - * @throws EE_Error |
|
1546 | - * @throws InvalidArgumentException |
|
1547 | - * @throws InvalidDataTypeException |
|
1548 | - * @throws InvalidInterfaceException |
|
1549 | - * @throws ReflectionException |
|
1550 | - */ |
|
1551 | - public function taxable_total() |
|
1552 | - { |
|
1553 | - $total = 0; |
|
1554 | - if ($this->children()) { |
|
1555 | - foreach ($this->children() as $child_line_item) { |
|
1556 | - if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) { |
|
1557 | - // if it's a percent item, only take into account the percent |
|
1558 | - // that's taxable too (the taxable total so far) |
|
1559 | - if ($child_line_item->is_percent()) { |
|
1560 | - $total += ($total * $child_line_item->percent() / 100); |
|
1561 | - } else { |
|
1562 | - $total += $child_line_item->total(); |
|
1563 | - } |
|
1564 | - } elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) { |
|
1565 | - $total += $child_line_item->taxable_total(); |
|
1566 | - } |
|
1567 | - } |
|
1568 | - } |
|
1569 | - return max($total, 0); |
|
1570 | - } |
|
1571 | - |
|
1572 | - |
|
1573 | - /** |
|
1574 | - * Gets the transaction for this line item |
|
1575 | - * |
|
1576 | - * @return EE_Base_Class|EE_Transaction |
|
1577 | - * @throws EE_Error |
|
1578 | - * @throws InvalidArgumentException |
|
1579 | - * @throws InvalidDataTypeException |
|
1580 | - * @throws InvalidInterfaceException |
|
1581 | - * @throws ReflectionException |
|
1582 | - */ |
|
1583 | - public function transaction() |
|
1584 | - { |
|
1585 | - return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TRANSACTION); |
|
1586 | - } |
|
1587 | - |
|
1588 | - |
|
1589 | - /** |
|
1590 | - * Saves this line item to the DB, and recursively saves its descendants. |
|
1591 | - * Because there currently is no proper parent-child relation on the model, |
|
1592 | - * save_this_and_cached() will NOT save the descendants. |
|
1593 | - * Also sets the transaction on this line item and all its descendants before saving |
|
1594 | - * |
|
1595 | - * @param int $txn_id if none is provided, assumes $this->TXN_ID() |
|
1596 | - * @return int count of items saved |
|
1597 | - * @throws EE_Error |
|
1598 | - * @throws InvalidArgumentException |
|
1599 | - * @throws InvalidDataTypeException |
|
1600 | - * @throws InvalidInterfaceException |
|
1601 | - * @throws ReflectionException |
|
1602 | - */ |
|
1603 | - public function save_this_and_descendants_to_txn($txn_id = null) |
|
1604 | - { |
|
1605 | - $count = 0; |
|
1606 | - if (! $txn_id) { |
|
1607 | - $txn_id = $this->TXN_ID(); |
|
1608 | - } |
|
1609 | - $this->set_TXN_ID($txn_id); |
|
1610 | - $children = $this->children(); |
|
1611 | - $count += $this->save() |
|
1612 | - ? 1 |
|
1613 | - : 0; |
|
1614 | - foreach ($children as $child_line_item) { |
|
1615 | - if ($child_line_item instanceof EE_Line_Item) { |
|
1616 | - $child_line_item->set_parent_ID($this->ID()); |
|
1617 | - $count += $child_line_item->save_this_and_descendants_to_txn($txn_id); |
|
1618 | - } |
|
1619 | - } |
|
1620 | - return $count; |
|
1621 | - } |
|
1622 | - |
|
1623 | - |
|
1624 | - /** |
|
1625 | - * Saves this line item to the DB, and recursively saves its descendants. |
|
1626 | - * |
|
1627 | - * @return int count of items saved |
|
1628 | - * @throws EE_Error |
|
1629 | - * @throws InvalidArgumentException |
|
1630 | - * @throws InvalidDataTypeException |
|
1631 | - * @throws InvalidInterfaceException |
|
1632 | - * @throws ReflectionException |
|
1633 | - */ |
|
1634 | - public function save_this_and_descendants() |
|
1635 | - { |
|
1636 | - $count = 0; |
|
1637 | - $children = $this->children(); |
|
1638 | - $count += $this->save() |
|
1639 | - ? 1 |
|
1640 | - : 0; |
|
1641 | - foreach ($children as $child_line_item) { |
|
1642 | - if ($child_line_item instanceof EE_Line_Item) { |
|
1643 | - $child_line_item->set_parent_ID($this->ID()); |
|
1644 | - $count += $child_line_item->save_this_and_descendants(); |
|
1645 | - } |
|
1646 | - } |
|
1647 | - return $count; |
|
1648 | - } |
|
1649 | - |
|
1650 | - |
|
1651 | - /** |
|
1652 | - * returns the cancellation line item if this item was cancelled |
|
1653 | - * |
|
1654 | - * @return EE_Line_Item[] |
|
1655 | - * @throws InvalidArgumentException |
|
1656 | - * @throws InvalidInterfaceException |
|
1657 | - * @throws InvalidDataTypeException |
|
1658 | - * @throws ReflectionException |
|
1659 | - * @throws EE_Error |
|
1660 | - */ |
|
1661 | - public function get_cancellations() |
|
1662 | - { |
|
1663 | - EE_Registry::instance()->load_helper('Line_Item'); |
|
1664 | - return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation); |
|
1665 | - } |
|
1666 | - |
|
1667 | - |
|
1668 | - /** |
|
1669 | - * If this item has an ID, then this saves it again to update the db |
|
1670 | - * |
|
1671 | - * @return int count of items saved |
|
1672 | - * @throws EE_Error |
|
1673 | - * @throws InvalidArgumentException |
|
1674 | - * @throws InvalidDataTypeException |
|
1675 | - * @throws InvalidInterfaceException |
|
1676 | - * @throws ReflectionException |
|
1677 | - */ |
|
1678 | - public function maybe_save() |
|
1679 | - { |
|
1680 | - if ($this->ID()) { |
|
1681 | - return $this->save(); |
|
1682 | - } |
|
1683 | - return false; |
|
1684 | - } |
|
1685 | - |
|
1686 | - |
|
1687 | - /** |
|
1688 | - * clears the cached children and parent from the line item |
|
1689 | - * |
|
1690 | - * @return void |
|
1691 | - */ |
|
1692 | - public function clear_related_line_item_cache() |
|
1693 | - { |
|
1694 | - $this->_children = array(); |
|
1695 | - $this->_parent = null; |
|
1696 | - } |
|
1697 | - |
|
1698 | - |
|
1699 | - /** |
|
1700 | - * @param bool $raw |
|
1701 | - * @return int |
|
1702 | - * @throws EE_Error |
|
1703 | - * @throws InvalidArgumentException |
|
1704 | - * @throws InvalidDataTypeException |
|
1705 | - * @throws InvalidInterfaceException |
|
1706 | - * @throws ReflectionException |
|
1707 | - */ |
|
1708 | - public function timestamp($raw = false) |
|
1709 | - { |
|
1710 | - return $raw |
|
1711 | - ? $this->get_raw('LIN_timestamp') |
|
1712 | - : $this->get('LIN_timestamp'); |
|
1713 | - } |
|
1714 | - |
|
1715 | - |
|
1716 | - |
|
1717 | - |
|
1718 | - /************************* DEPRECATED *************************/ |
|
1719 | - /** |
|
1720 | - * @deprecated 4.6.0 |
|
1721 | - * @param string $type one of the constants on EEM_Line_Item |
|
1722 | - * @return EE_Line_Item[] |
|
1723 | - * @throws EE_Error |
|
1724 | - */ |
|
1725 | - protected function _get_descendants_of_type($type) |
|
1726 | - { |
|
1727 | - EE_Error::doing_it_wrong( |
|
1728 | - 'EE_Line_Item::_get_descendants_of_type()', |
|
1729 | - sprintf( |
|
1730 | - esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
1731 | - 'EEH_Line_Item::get_descendants_of_type()' |
|
1732 | - ), |
|
1733 | - '4.6.0' |
|
1734 | - ); |
|
1735 | - return EEH_Line_Item::get_descendants_of_type($this, $type); |
|
1736 | - } |
|
1737 | - |
|
1738 | - |
|
1739 | - /** |
|
1740 | - * @deprecated 4.6.0 |
|
1741 | - * @param string $type like one of the EEM_Line_Item::type_* |
|
1742 | - * @return EE_Line_Item |
|
1743 | - * @throws EE_Error |
|
1744 | - * @throws InvalidArgumentException |
|
1745 | - * @throws InvalidDataTypeException |
|
1746 | - * @throws InvalidInterfaceException |
|
1747 | - * @throws ReflectionException |
|
1748 | - */ |
|
1749 | - public function get_nearest_descendant_of_type($type) |
|
1750 | - { |
|
1751 | - EE_Error::doing_it_wrong( |
|
1752 | - 'EE_Line_Item::get_nearest_descendant_of_type()', |
|
1753 | - sprintf( |
|
1754 | - esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
1755 | - 'EEH_Line_Item::get_nearest_descendant_of_type()' |
|
1756 | - ), |
|
1757 | - '4.6.0' |
|
1758 | - ); |
|
1759 | - return EEH_Line_Item::get_nearest_descendant_of_type($this, $type); |
|
1760 | - } |
|
17 | + /** |
|
18 | + * for children line items (currently not a normal relation) |
|
19 | + * |
|
20 | + * @type EE_Line_Item[] |
|
21 | + */ |
|
22 | + protected $_children = array(); |
|
23 | + |
|
24 | + /** |
|
25 | + * for the parent line item |
|
26 | + * |
|
27 | + * @var EE_Line_Item |
|
28 | + */ |
|
29 | + protected $_parent; |
|
30 | + |
|
31 | + |
|
32 | + /** |
|
33 | + * @param array $props_n_values incoming values |
|
34 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
35 | + * used.) |
|
36 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
37 | + * date_format and the second value is the time format |
|
38 | + * @return EE_Line_Item |
|
39 | + * @throws EE_Error |
|
40 | + * @throws InvalidArgumentException |
|
41 | + * @throws InvalidDataTypeException |
|
42 | + * @throws InvalidInterfaceException |
|
43 | + * @throws ReflectionException |
|
44 | + */ |
|
45 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
46 | + { |
|
47 | + $has_object = parent::_check_for_object( |
|
48 | + $props_n_values, |
|
49 | + __CLASS__, |
|
50 | + $timezone, |
|
51 | + $date_formats |
|
52 | + ); |
|
53 | + return $has_object |
|
54 | + ? $has_object |
|
55 | + : new self($props_n_values, false, $timezone); |
|
56 | + } |
|
57 | + |
|
58 | + |
|
59 | + /** |
|
60 | + * @param array $props_n_values incoming values from the database |
|
61 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
62 | + * the website will be used. |
|
63 | + * @return EE_Line_Item |
|
64 | + * @throws EE_Error |
|
65 | + * @throws InvalidArgumentException |
|
66 | + * @throws InvalidDataTypeException |
|
67 | + * @throws InvalidInterfaceException |
|
68 | + * @throws ReflectionException |
|
69 | + */ |
|
70 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
71 | + { |
|
72 | + return new self($props_n_values, true, $timezone); |
|
73 | + } |
|
74 | + |
|
75 | + |
|
76 | + /** |
|
77 | + * Adds some defaults if they're not specified |
|
78 | + * |
|
79 | + * @param array $fieldValues |
|
80 | + * @param bool $bydb |
|
81 | + * @param string $timezone |
|
82 | + * @throws EE_Error |
|
83 | + * @throws InvalidArgumentException |
|
84 | + * @throws InvalidDataTypeException |
|
85 | + * @throws InvalidInterfaceException |
|
86 | + * @throws ReflectionException |
|
87 | + */ |
|
88 | + protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') |
|
89 | + { |
|
90 | + parent::__construct($fieldValues, $bydb, $timezone); |
|
91 | + if (! $this->get('LIN_code')) { |
|
92 | + $this->set_code($this->generate_code()); |
|
93 | + } |
|
94 | + } |
|
95 | + |
|
96 | + |
|
97 | + /** |
|
98 | + * Gets ID |
|
99 | + * |
|
100 | + * @return int |
|
101 | + * @throws EE_Error |
|
102 | + * @throws InvalidArgumentException |
|
103 | + * @throws InvalidDataTypeException |
|
104 | + * @throws InvalidInterfaceException |
|
105 | + * @throws ReflectionException |
|
106 | + */ |
|
107 | + public function ID() |
|
108 | + { |
|
109 | + return $this->get('LIN_ID'); |
|
110 | + } |
|
111 | + |
|
112 | + |
|
113 | + /** |
|
114 | + * Gets TXN_ID |
|
115 | + * |
|
116 | + * @return int |
|
117 | + * @throws EE_Error |
|
118 | + * @throws InvalidArgumentException |
|
119 | + * @throws InvalidDataTypeException |
|
120 | + * @throws InvalidInterfaceException |
|
121 | + * @throws ReflectionException |
|
122 | + */ |
|
123 | + public function TXN_ID() |
|
124 | + { |
|
125 | + return $this->get('TXN_ID'); |
|
126 | + } |
|
127 | + |
|
128 | + |
|
129 | + /** |
|
130 | + * Sets TXN_ID |
|
131 | + * |
|
132 | + * @param int $TXN_ID |
|
133 | + * @throws EE_Error |
|
134 | + * @throws InvalidArgumentException |
|
135 | + * @throws InvalidDataTypeException |
|
136 | + * @throws InvalidInterfaceException |
|
137 | + * @throws ReflectionException |
|
138 | + */ |
|
139 | + public function set_TXN_ID($TXN_ID) |
|
140 | + { |
|
141 | + $this->set('TXN_ID', $TXN_ID); |
|
142 | + } |
|
143 | + |
|
144 | + |
|
145 | + /** |
|
146 | + * Gets name |
|
147 | + * |
|
148 | + * @return string |
|
149 | + * @throws EE_Error |
|
150 | + * @throws InvalidArgumentException |
|
151 | + * @throws InvalidDataTypeException |
|
152 | + * @throws InvalidInterfaceException |
|
153 | + * @throws ReflectionException |
|
154 | + */ |
|
155 | + public function name() |
|
156 | + { |
|
157 | + $name = $this->get('LIN_name'); |
|
158 | + if (! $name) { |
|
159 | + $name = ucwords(str_replace('-', ' ', $this->type())); |
|
160 | + } |
|
161 | + return $name; |
|
162 | + } |
|
163 | + |
|
164 | + |
|
165 | + /** |
|
166 | + * Sets name |
|
167 | + * |
|
168 | + * @param string $name |
|
169 | + * @throws EE_Error |
|
170 | + * @throws InvalidArgumentException |
|
171 | + * @throws InvalidDataTypeException |
|
172 | + * @throws InvalidInterfaceException |
|
173 | + * @throws ReflectionException |
|
174 | + */ |
|
175 | + public function set_name($name) |
|
176 | + { |
|
177 | + $this->set('LIN_name', $name); |
|
178 | + } |
|
179 | + |
|
180 | + |
|
181 | + /** |
|
182 | + * Gets desc |
|
183 | + * |
|
184 | + * @return string |
|
185 | + * @throws EE_Error |
|
186 | + * @throws InvalidArgumentException |
|
187 | + * @throws InvalidDataTypeException |
|
188 | + * @throws InvalidInterfaceException |
|
189 | + * @throws ReflectionException |
|
190 | + */ |
|
191 | + public function desc() |
|
192 | + { |
|
193 | + return $this->get('LIN_desc'); |
|
194 | + } |
|
195 | + |
|
196 | + |
|
197 | + /** |
|
198 | + * Sets desc |
|
199 | + * |
|
200 | + * @param string $desc |
|
201 | + * @throws EE_Error |
|
202 | + * @throws InvalidArgumentException |
|
203 | + * @throws InvalidDataTypeException |
|
204 | + * @throws InvalidInterfaceException |
|
205 | + * @throws ReflectionException |
|
206 | + */ |
|
207 | + public function set_desc($desc) |
|
208 | + { |
|
209 | + $this->set('LIN_desc', $desc); |
|
210 | + } |
|
211 | + |
|
212 | + |
|
213 | + /** |
|
214 | + * Gets quantity |
|
215 | + * |
|
216 | + * @return int |
|
217 | + * @throws EE_Error |
|
218 | + * @throws InvalidArgumentException |
|
219 | + * @throws InvalidDataTypeException |
|
220 | + * @throws InvalidInterfaceException |
|
221 | + * @throws ReflectionException |
|
222 | + */ |
|
223 | + public function quantity() |
|
224 | + { |
|
225 | + return $this->get('LIN_quantity'); |
|
226 | + } |
|
227 | + |
|
228 | + |
|
229 | + /** |
|
230 | + * Sets quantity |
|
231 | + * |
|
232 | + * @param int $quantity |
|
233 | + * @throws EE_Error |
|
234 | + * @throws InvalidArgumentException |
|
235 | + * @throws InvalidDataTypeException |
|
236 | + * @throws InvalidInterfaceException |
|
237 | + * @throws ReflectionException |
|
238 | + */ |
|
239 | + public function set_quantity($quantity) |
|
240 | + { |
|
241 | + $this->set('LIN_quantity', max($quantity, 0)); |
|
242 | + } |
|
243 | + |
|
244 | + |
|
245 | + /** |
|
246 | + * Gets item_id |
|
247 | + * |
|
248 | + * @return string |
|
249 | + * @throws EE_Error |
|
250 | + * @throws InvalidArgumentException |
|
251 | + * @throws InvalidDataTypeException |
|
252 | + * @throws InvalidInterfaceException |
|
253 | + * @throws ReflectionException |
|
254 | + */ |
|
255 | + public function OBJ_ID() |
|
256 | + { |
|
257 | + return $this->get('OBJ_ID'); |
|
258 | + } |
|
259 | + |
|
260 | + |
|
261 | + /** |
|
262 | + * Sets item_id |
|
263 | + * |
|
264 | + * @param string $item_id |
|
265 | + * @throws EE_Error |
|
266 | + * @throws InvalidArgumentException |
|
267 | + * @throws InvalidDataTypeException |
|
268 | + * @throws InvalidInterfaceException |
|
269 | + * @throws ReflectionException |
|
270 | + */ |
|
271 | + public function set_OBJ_ID($item_id) |
|
272 | + { |
|
273 | + $this->set('OBJ_ID', $item_id); |
|
274 | + } |
|
275 | + |
|
276 | + |
|
277 | + /** |
|
278 | + * Gets item_type |
|
279 | + * |
|
280 | + * @return string |
|
281 | + * @throws EE_Error |
|
282 | + * @throws InvalidArgumentException |
|
283 | + * @throws InvalidDataTypeException |
|
284 | + * @throws InvalidInterfaceException |
|
285 | + * @throws ReflectionException |
|
286 | + */ |
|
287 | + public function OBJ_type() |
|
288 | + { |
|
289 | + return $this->get('OBJ_type'); |
|
290 | + } |
|
291 | + |
|
292 | + |
|
293 | + /** |
|
294 | + * Gets item_type |
|
295 | + * |
|
296 | + * @return string |
|
297 | + * @throws EE_Error |
|
298 | + * @throws InvalidArgumentException |
|
299 | + * @throws InvalidDataTypeException |
|
300 | + * @throws InvalidInterfaceException |
|
301 | + * @throws ReflectionException |
|
302 | + */ |
|
303 | + public function OBJ_type_i18n() |
|
304 | + { |
|
305 | + $obj_type = $this->OBJ_type(); |
|
306 | + switch ($obj_type) { |
|
307 | + case EEM_Line_Item::OBJ_TYPE_EVENT: |
|
308 | + $obj_type = esc_html__('Event', 'event_espresso'); |
|
309 | + break; |
|
310 | + case EEM_Line_Item::OBJ_TYPE_PRICE: |
|
311 | + $obj_type = esc_html__('Price', 'event_espresso'); |
|
312 | + break; |
|
313 | + case EEM_Line_Item::OBJ_TYPE_PROMOTION: |
|
314 | + $obj_type = esc_html__('Promotion', 'event_espresso'); |
|
315 | + break; |
|
316 | + case EEM_Line_Item::OBJ_TYPE_TICKET: |
|
317 | + $obj_type = esc_html__('Ticket', 'event_espresso'); |
|
318 | + break; |
|
319 | + case EEM_Line_Item::OBJ_TYPE_TRANSACTION: |
|
320 | + $obj_type = esc_html__('Transaction', 'event_espresso'); |
|
321 | + break; |
|
322 | + } |
|
323 | + return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this); |
|
324 | + } |
|
325 | + |
|
326 | + |
|
327 | + /** |
|
328 | + * Sets item_type |
|
329 | + * |
|
330 | + * @param string $OBJ_type |
|
331 | + * @throws EE_Error |
|
332 | + * @throws InvalidArgumentException |
|
333 | + * @throws InvalidDataTypeException |
|
334 | + * @throws InvalidInterfaceException |
|
335 | + * @throws ReflectionException |
|
336 | + */ |
|
337 | + public function set_OBJ_type($OBJ_type) |
|
338 | + { |
|
339 | + $this->set('OBJ_type', $OBJ_type); |
|
340 | + } |
|
341 | + |
|
342 | + |
|
343 | + /** |
|
344 | + * Gets unit_price |
|
345 | + * |
|
346 | + * @return float |
|
347 | + * @throws EE_Error |
|
348 | + * @throws InvalidArgumentException |
|
349 | + * @throws InvalidDataTypeException |
|
350 | + * @throws InvalidInterfaceException |
|
351 | + * @throws ReflectionException |
|
352 | + */ |
|
353 | + public function unit_price() |
|
354 | + { |
|
355 | + return $this->get('LIN_unit_price'); |
|
356 | + } |
|
357 | + |
|
358 | + |
|
359 | + /** |
|
360 | + * Sets unit_price |
|
361 | + * |
|
362 | + * @param float $unit_price |
|
363 | + * @throws EE_Error |
|
364 | + * @throws InvalidArgumentException |
|
365 | + * @throws InvalidDataTypeException |
|
366 | + * @throws InvalidInterfaceException |
|
367 | + * @throws ReflectionException |
|
368 | + */ |
|
369 | + public function set_unit_price($unit_price) |
|
370 | + { |
|
371 | + $this->set('LIN_unit_price', $unit_price); |
|
372 | + } |
|
373 | + |
|
374 | + |
|
375 | + /** |
|
376 | + * Checks if this item is a percentage modifier or not |
|
377 | + * |
|
378 | + * @return boolean |
|
379 | + * @throws EE_Error |
|
380 | + * @throws InvalidArgumentException |
|
381 | + * @throws InvalidDataTypeException |
|
382 | + * @throws InvalidInterfaceException |
|
383 | + * @throws ReflectionException |
|
384 | + */ |
|
385 | + public function is_percent() |
|
386 | + { |
|
387 | + if ($this->is_tax_sub_total()) { |
|
388 | + // tax subtotals HAVE a percent on them, that percentage only applies |
|
389 | + // to taxable items, so its' an exception. Treat it like a flat line item |
|
390 | + return false; |
|
391 | + } |
|
392 | + $unit_price = abs($this->get('LIN_unit_price')); |
|
393 | + $percent = abs($this->get('LIN_percent')); |
|
394 | + if ($unit_price < .001 && $percent) { |
|
395 | + return true; |
|
396 | + } |
|
397 | + if ($unit_price >= .001 && ! $percent) { |
|
398 | + return false; |
|
399 | + } |
|
400 | + if ($unit_price >= .001 && $percent) { |
|
401 | + throw new EE_Error( |
|
402 | + sprintf( |
|
403 | + esc_html__( |
|
404 | + 'A Line Item can not have a unit price of (%s) AND a percent (%s)!', |
|
405 | + 'event_espresso' |
|
406 | + ), |
|
407 | + $unit_price, |
|
408 | + $percent |
|
409 | + ) |
|
410 | + ); |
|
411 | + } |
|
412 | + // if they're both 0, assume its not a percent item |
|
413 | + return false; |
|
414 | + } |
|
415 | + |
|
416 | + |
|
417 | + /** |
|
418 | + * Gets percent (between 100-.001) |
|
419 | + * |
|
420 | + * @return float |
|
421 | + * @throws EE_Error |
|
422 | + * @throws InvalidArgumentException |
|
423 | + * @throws InvalidDataTypeException |
|
424 | + * @throws InvalidInterfaceException |
|
425 | + * @throws ReflectionException |
|
426 | + */ |
|
427 | + public function percent() |
|
428 | + { |
|
429 | + return $this->get('LIN_percent'); |
|
430 | + } |
|
431 | + |
|
432 | + |
|
433 | + /** |
|
434 | + * Sets percent (between 100-0.01) |
|
435 | + * |
|
436 | + * @param float $percent |
|
437 | + * @throws EE_Error |
|
438 | + * @throws InvalidArgumentException |
|
439 | + * @throws InvalidDataTypeException |
|
440 | + * @throws InvalidInterfaceException |
|
441 | + * @throws ReflectionException |
|
442 | + */ |
|
443 | + public function set_percent($percent) |
|
444 | + { |
|
445 | + $this->set('LIN_percent', $percent); |
|
446 | + } |
|
447 | + |
|
448 | + |
|
449 | + /** |
|
450 | + * Gets total |
|
451 | + * |
|
452 | + * @return float |
|
453 | + * @throws EE_Error |
|
454 | + * @throws InvalidArgumentException |
|
455 | + * @throws InvalidDataTypeException |
|
456 | + * @throws InvalidInterfaceException |
|
457 | + * @throws ReflectionException |
|
458 | + */ |
|
459 | + public function total() |
|
460 | + { |
|
461 | + return $this->get('LIN_total'); |
|
462 | + } |
|
463 | + |
|
464 | + |
|
465 | + /** |
|
466 | + * Sets total |
|
467 | + * |
|
468 | + * @param float $total |
|
469 | + * @throws EE_Error |
|
470 | + * @throws InvalidArgumentException |
|
471 | + * @throws InvalidDataTypeException |
|
472 | + * @throws InvalidInterfaceException |
|
473 | + * @throws ReflectionException |
|
474 | + */ |
|
475 | + public function set_total($total) |
|
476 | + { |
|
477 | + $this->set('LIN_total', $total); |
|
478 | + } |
|
479 | + |
|
480 | + |
|
481 | + /** |
|
482 | + * Gets order |
|
483 | + * |
|
484 | + * @return int |
|
485 | + * @throws EE_Error |
|
486 | + * @throws InvalidArgumentException |
|
487 | + * @throws InvalidDataTypeException |
|
488 | + * @throws InvalidInterfaceException |
|
489 | + * @throws ReflectionException |
|
490 | + */ |
|
491 | + public function order() |
|
492 | + { |
|
493 | + return $this->get('LIN_order'); |
|
494 | + } |
|
495 | + |
|
496 | + |
|
497 | + /** |
|
498 | + * Sets order |
|
499 | + * |
|
500 | + * @param int $order |
|
501 | + * @throws EE_Error |
|
502 | + * @throws InvalidArgumentException |
|
503 | + * @throws InvalidDataTypeException |
|
504 | + * @throws InvalidInterfaceException |
|
505 | + * @throws ReflectionException |
|
506 | + */ |
|
507 | + public function set_order($order) |
|
508 | + { |
|
509 | + $this->set('LIN_order', $order); |
|
510 | + } |
|
511 | + |
|
512 | + |
|
513 | + /** |
|
514 | + * Gets parent |
|
515 | + * |
|
516 | + * @return int |
|
517 | + * @throws EE_Error |
|
518 | + * @throws InvalidArgumentException |
|
519 | + * @throws InvalidDataTypeException |
|
520 | + * @throws InvalidInterfaceException |
|
521 | + * @throws ReflectionException |
|
522 | + */ |
|
523 | + public function parent_ID() |
|
524 | + { |
|
525 | + return $this->get('LIN_parent'); |
|
526 | + } |
|
527 | + |
|
528 | + |
|
529 | + /** |
|
530 | + * Sets parent |
|
531 | + * |
|
532 | + * @param int $parent |
|
533 | + * @throws EE_Error |
|
534 | + * @throws InvalidArgumentException |
|
535 | + * @throws InvalidDataTypeException |
|
536 | + * @throws InvalidInterfaceException |
|
537 | + * @throws ReflectionException |
|
538 | + */ |
|
539 | + public function set_parent_ID($parent) |
|
540 | + { |
|
541 | + $this->set('LIN_parent', $parent); |
|
542 | + } |
|
543 | + |
|
544 | + |
|
545 | + /** |
|
546 | + * Gets type |
|
547 | + * |
|
548 | + * @return string |
|
549 | + * @throws EE_Error |
|
550 | + * @throws InvalidArgumentException |
|
551 | + * @throws InvalidDataTypeException |
|
552 | + * @throws InvalidInterfaceException |
|
553 | + * @throws ReflectionException |
|
554 | + */ |
|
555 | + public function type() |
|
556 | + { |
|
557 | + return $this->get('LIN_type'); |
|
558 | + } |
|
559 | + |
|
560 | + |
|
561 | + /** |
|
562 | + * Sets type |
|
563 | + * |
|
564 | + * @param string $type |
|
565 | + * @throws EE_Error |
|
566 | + * @throws InvalidArgumentException |
|
567 | + * @throws InvalidDataTypeException |
|
568 | + * @throws InvalidInterfaceException |
|
569 | + * @throws ReflectionException |
|
570 | + */ |
|
571 | + public function set_type($type) |
|
572 | + { |
|
573 | + $this->set('LIN_type', $type); |
|
574 | + } |
|
575 | + |
|
576 | + |
|
577 | + /** |
|
578 | + * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\ |
|
579 | + * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB |
|
580 | + * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()` |
|
581 | + * or indirectly by `EE_Line_item::add_child_line_item()`) |
|
582 | + * |
|
583 | + * @return EE_Base_Class|EE_Line_Item |
|
584 | + * @throws EE_Error |
|
585 | + * @throws InvalidArgumentException |
|
586 | + * @throws InvalidDataTypeException |
|
587 | + * @throws InvalidInterfaceException |
|
588 | + * @throws ReflectionException |
|
589 | + */ |
|
590 | + public function parent() |
|
591 | + { |
|
592 | + return $this->ID() |
|
593 | + ? $this->get_model()->get_one_by_ID($this->parent_ID()) |
|
594 | + : $this->_parent; |
|
595 | + } |
|
596 | + |
|
597 | + |
|
598 | + /** |
|
599 | + * Gets ALL the children of this line item (ie, all the parts that contribute towards this total). |
|
600 | + * |
|
601 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
602 | + * @throws EE_Error |
|
603 | + * @throws InvalidArgumentException |
|
604 | + * @throws InvalidDataTypeException |
|
605 | + * @throws InvalidInterfaceException |
|
606 | + * @throws ReflectionException |
|
607 | + */ |
|
608 | + public function children() |
|
609 | + { |
|
610 | + if ($this->ID()) { |
|
611 | + return $this->get_model()->get_all( |
|
612 | + array( |
|
613 | + array('LIN_parent' => $this->ID()), |
|
614 | + 'order_by' => array('LIN_order' => 'ASC'), |
|
615 | + ) |
|
616 | + ); |
|
617 | + } |
|
618 | + if (! is_array($this->_children)) { |
|
619 | + $this->_children = array(); |
|
620 | + } |
|
621 | + return $this->_children; |
|
622 | + } |
|
623 | + |
|
624 | + |
|
625 | + /** |
|
626 | + * Gets code |
|
627 | + * |
|
628 | + * @return string |
|
629 | + * @throws EE_Error |
|
630 | + * @throws InvalidArgumentException |
|
631 | + * @throws InvalidDataTypeException |
|
632 | + * @throws InvalidInterfaceException |
|
633 | + * @throws ReflectionException |
|
634 | + */ |
|
635 | + public function code() |
|
636 | + { |
|
637 | + return $this->get('LIN_code'); |
|
638 | + } |
|
639 | + |
|
640 | + |
|
641 | + /** |
|
642 | + * Sets code |
|
643 | + * |
|
644 | + * @param string $code |
|
645 | + * @throws EE_Error |
|
646 | + * @throws InvalidArgumentException |
|
647 | + * @throws InvalidDataTypeException |
|
648 | + * @throws InvalidInterfaceException |
|
649 | + * @throws ReflectionException |
|
650 | + */ |
|
651 | + public function set_code($code) |
|
652 | + { |
|
653 | + $this->set('LIN_code', $code); |
|
654 | + } |
|
655 | + |
|
656 | + |
|
657 | + /** |
|
658 | + * Gets is_taxable |
|
659 | + * |
|
660 | + * @return boolean |
|
661 | + * @throws EE_Error |
|
662 | + * @throws InvalidArgumentException |
|
663 | + * @throws InvalidDataTypeException |
|
664 | + * @throws InvalidInterfaceException |
|
665 | + * @throws ReflectionException |
|
666 | + */ |
|
667 | + public function is_taxable() |
|
668 | + { |
|
669 | + return $this->get('LIN_is_taxable'); |
|
670 | + } |
|
671 | + |
|
672 | + |
|
673 | + /** |
|
674 | + * Sets is_taxable |
|
675 | + * |
|
676 | + * @param boolean $is_taxable |
|
677 | + * @throws EE_Error |
|
678 | + * @throws InvalidArgumentException |
|
679 | + * @throws InvalidDataTypeException |
|
680 | + * @throws InvalidInterfaceException |
|
681 | + * @throws ReflectionException |
|
682 | + */ |
|
683 | + public function set_is_taxable($is_taxable) |
|
684 | + { |
|
685 | + $this->set('LIN_is_taxable', $is_taxable); |
|
686 | + } |
|
687 | + |
|
688 | + |
|
689 | + /** |
|
690 | + * Gets the object that this model-joins-to. |
|
691 | + * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on |
|
692 | + * EEM_Promotion_Object |
|
693 | + * Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object |
|
694 | + * |
|
695 | + * @return EE_Base_Class | NULL |
|
696 | + * @throws EE_Error |
|
697 | + * @throws InvalidArgumentException |
|
698 | + * @throws InvalidDataTypeException |
|
699 | + * @throws InvalidInterfaceException |
|
700 | + * @throws ReflectionException |
|
701 | + */ |
|
702 | + public function get_object() |
|
703 | + { |
|
704 | + $model_name_of_related_obj = $this->OBJ_type(); |
|
705 | + return $this->get_model()->has_relation($model_name_of_related_obj) |
|
706 | + ? $this->get_first_related($model_name_of_related_obj) |
|
707 | + : null; |
|
708 | + } |
|
709 | + |
|
710 | + |
|
711 | + /** |
|
712 | + * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket. |
|
713 | + * (IE, if this line item is for a price or something else, will return NULL) |
|
714 | + * |
|
715 | + * @param array $query_params |
|
716 | + * @return EE_Base_Class|EE_Ticket |
|
717 | + * @throws EE_Error |
|
718 | + * @throws InvalidArgumentException |
|
719 | + * @throws InvalidDataTypeException |
|
720 | + * @throws InvalidInterfaceException |
|
721 | + * @throws ReflectionException |
|
722 | + */ |
|
723 | + public function ticket($query_params = array()) |
|
724 | + { |
|
725 | + // we're going to assume that when this method is called |
|
726 | + // we always want to receive the attached ticket EVEN if that ticket is archived. |
|
727 | + // This can be overridden via the incoming $query_params argument |
|
728 | + $remove_defaults = array('default_where_conditions' => 'none'); |
|
729 | + $query_params = array_merge($remove_defaults, $query_params); |
|
730 | + return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TICKET, $query_params); |
|
731 | + } |
|
732 | + |
|
733 | + |
|
734 | + /** |
|
735 | + * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket |
|
736 | + * |
|
737 | + * @return EE_Datetime | NULL |
|
738 | + * @throws EE_Error |
|
739 | + * @throws InvalidArgumentException |
|
740 | + * @throws InvalidDataTypeException |
|
741 | + * @throws InvalidInterfaceException |
|
742 | + * @throws ReflectionException |
|
743 | + */ |
|
744 | + public function get_ticket_datetime() |
|
745 | + { |
|
746 | + if ($this->OBJ_type() === EEM_Line_Item::OBJ_TYPE_TICKET) { |
|
747 | + $ticket = $this->ticket(); |
|
748 | + if ($ticket instanceof EE_Ticket) { |
|
749 | + $datetime = $ticket->first_datetime(); |
|
750 | + if ($datetime instanceof EE_Datetime) { |
|
751 | + return $datetime; |
|
752 | + } |
|
753 | + } |
|
754 | + } |
|
755 | + return null; |
|
756 | + } |
|
757 | + |
|
758 | + |
|
759 | + /** |
|
760 | + * Gets the event's name that's related to the ticket, if this is for |
|
761 | + * a ticket |
|
762 | + * |
|
763 | + * @return string |
|
764 | + * @throws EE_Error |
|
765 | + * @throws InvalidArgumentException |
|
766 | + * @throws InvalidDataTypeException |
|
767 | + * @throws InvalidInterfaceException |
|
768 | + * @throws ReflectionException |
|
769 | + */ |
|
770 | + public function ticket_event_name() |
|
771 | + { |
|
772 | + $event_name = esc_html__('Unknown', 'event_espresso'); |
|
773 | + $event = $this->ticket_event(); |
|
774 | + if ($event instanceof EE_Event) { |
|
775 | + $event_name = $event->name(); |
|
776 | + } |
|
777 | + return $event_name; |
|
778 | + } |
|
779 | + |
|
780 | + |
|
781 | + /** |
|
782 | + * Gets the event that's related to the ticket, if this line item represents a ticket. |
|
783 | + * |
|
784 | + * @return EE_Event|null |
|
785 | + * @throws EE_Error |
|
786 | + * @throws InvalidArgumentException |
|
787 | + * @throws InvalidDataTypeException |
|
788 | + * @throws InvalidInterfaceException |
|
789 | + * @throws ReflectionException |
|
790 | + */ |
|
791 | + public function ticket_event() |
|
792 | + { |
|
793 | + $event = null; |
|
794 | + $ticket = $this->ticket(); |
|
795 | + if ($ticket instanceof EE_Ticket) { |
|
796 | + $datetime = $ticket->first_datetime(); |
|
797 | + if ($datetime instanceof EE_Datetime) { |
|
798 | + $event = $datetime->event(); |
|
799 | + } |
|
800 | + } |
|
801 | + return $event; |
|
802 | + } |
|
803 | + |
|
804 | + |
|
805 | + /** |
|
806 | + * Gets the first datetime for this lien item, assuming it's for a ticket |
|
807 | + * |
|
808 | + * @param string $date_format |
|
809 | + * @param string $time_format |
|
810 | + * @return string |
|
811 | + * @throws EE_Error |
|
812 | + * @throws InvalidArgumentException |
|
813 | + * @throws InvalidDataTypeException |
|
814 | + * @throws InvalidInterfaceException |
|
815 | + * @throws ReflectionException |
|
816 | + */ |
|
817 | + public function ticket_datetime_start($date_format = '', $time_format = '') |
|
818 | + { |
|
819 | + $first_datetime_string = esc_html__('Unknown', 'event_espresso'); |
|
820 | + $datetime = $this->get_ticket_datetime(); |
|
821 | + if ($datetime) { |
|
822 | + $first_datetime_string = $datetime->start_date_and_time($date_format, $time_format); |
|
823 | + } |
|
824 | + return $first_datetime_string; |
|
825 | + } |
|
826 | + |
|
827 | + |
|
828 | + /** |
|
829 | + * Adds the line item as a child to this line item. If there is another child line |
|
830 | + * item with the same LIN_code, it is overwritten by this new one |
|
831 | + * |
|
832 | + * @param EEI_Line_Item $line_item |
|
833 | + * @param bool $set_order |
|
834 | + * @return bool success |
|
835 | + * @throws EE_Error |
|
836 | + * @throws InvalidArgumentException |
|
837 | + * @throws InvalidDataTypeException |
|
838 | + * @throws InvalidInterfaceException |
|
839 | + * @throws ReflectionException |
|
840 | + */ |
|
841 | + public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true) |
|
842 | + { |
|
843 | + // should we calculate the LIN_order for this line item ? |
|
844 | + if ($set_order || $line_item->order() === null) { |
|
845 | + $line_item->set_order(count($this->children())); |
|
846 | + } |
|
847 | + if ($this->ID()) { |
|
848 | + // check for any duplicate line items (with the same code), if so, this replaces it |
|
849 | + $line_item_with_same_code = $this->get_child_line_item($line_item->code()); |
|
850 | + if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) { |
|
851 | + $this->delete_child_line_item($line_item_with_same_code->code()); |
|
852 | + } |
|
853 | + $line_item->set_parent_ID($this->ID()); |
|
854 | + if ($this->TXN_ID()) { |
|
855 | + $line_item->set_TXN_ID($this->TXN_ID()); |
|
856 | + } |
|
857 | + return $line_item->save(); |
|
858 | + } |
|
859 | + $this->_children[ $line_item->code() ] = $line_item; |
|
860 | + if ($line_item->parent() !== $this) { |
|
861 | + $line_item->set_parent($this); |
|
862 | + } |
|
863 | + return true; |
|
864 | + } |
|
865 | + |
|
866 | + |
|
867 | + /** |
|
868 | + * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation. |
|
869 | + * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save() |
|
870 | + * However, if this line item is NOT saved to the DB, this just caches the parent on |
|
871 | + * the EE_Line_Item::_parent property. |
|
872 | + * |
|
873 | + * @param EE_Line_Item $line_item |
|
874 | + * @throws EE_Error |
|
875 | + * @throws InvalidArgumentException |
|
876 | + * @throws InvalidDataTypeException |
|
877 | + * @throws InvalidInterfaceException |
|
878 | + * @throws ReflectionException |
|
879 | + */ |
|
880 | + public function set_parent($line_item) |
|
881 | + { |
|
882 | + if ($this->ID()) { |
|
883 | + if (! $line_item->ID()) { |
|
884 | + $line_item->save(); |
|
885 | + } |
|
886 | + $this->set_parent_ID($line_item->ID()); |
|
887 | + $this->save(); |
|
888 | + } else { |
|
889 | + $this->_parent = $line_item; |
|
890 | + $this->set_parent_ID($line_item->ID()); |
|
891 | + } |
|
892 | + } |
|
893 | + |
|
894 | + |
|
895 | + /** |
|
896 | + * Gets the child line item as specified by its code. Because this returns an object (by reference) |
|
897 | + * you can modify this child line item and the parent (this object) can know about them |
|
898 | + * because it also has a reference to that line item |
|
899 | + * |
|
900 | + * @param string $code |
|
901 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
902 | + * @throws EE_Error |
|
903 | + * @throws InvalidArgumentException |
|
904 | + * @throws InvalidDataTypeException |
|
905 | + * @throws InvalidInterfaceException |
|
906 | + * @throws ReflectionException |
|
907 | + */ |
|
908 | + public function get_child_line_item($code) |
|
909 | + { |
|
910 | + if ($this->ID()) { |
|
911 | + return $this->get_model()->get_one( |
|
912 | + array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code)) |
|
913 | + ); |
|
914 | + } |
|
915 | + return isset($this->_children[ $code ]) |
|
916 | + ? $this->_children[ $code ] |
|
917 | + : null; |
|
918 | + } |
|
919 | + |
|
920 | + |
|
921 | + /** |
|
922 | + * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD |
|
923 | + * cached on it) |
|
924 | + * |
|
925 | + * @return int |
|
926 | + * @throws EE_Error |
|
927 | + * @throws InvalidArgumentException |
|
928 | + * @throws InvalidDataTypeException |
|
929 | + * @throws InvalidInterfaceException |
|
930 | + * @throws ReflectionException |
|
931 | + */ |
|
932 | + public function delete_children_line_items() |
|
933 | + { |
|
934 | + if ($this->ID()) { |
|
935 | + return $this->get_model()->delete(array(array('LIN_parent' => $this->ID()))); |
|
936 | + } |
|
937 | + $count = count($this->_children); |
|
938 | + $this->_children = array(); |
|
939 | + return $count; |
|
940 | + } |
|
941 | + |
|
942 | + |
|
943 | + /** |
|
944 | + * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line |
|
945 | + * HAS NOT been saved to the DB, removes the child line item with index $code. |
|
946 | + * Also searches through the child's children for a matching line item. However, once a line item has been found |
|
947 | + * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be |
|
948 | + * deleted) |
|
949 | + * |
|
950 | + * @param string $code |
|
951 | + * @param bool $stop_search_once_found |
|
952 | + * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to |
|
953 | + * the DB yet) |
|
954 | + * @throws EE_Error |
|
955 | + * @throws InvalidArgumentException |
|
956 | + * @throws InvalidDataTypeException |
|
957 | + * @throws InvalidInterfaceException |
|
958 | + * @throws ReflectionException |
|
959 | + */ |
|
960 | + public function delete_child_line_item($code, $stop_search_once_found = true) |
|
961 | + { |
|
962 | + if ($this->ID()) { |
|
963 | + $items_deleted = 0; |
|
964 | + if ($this->code() === $code) { |
|
965 | + $items_deleted += EEH_Line_Item::delete_all_child_items($this); |
|
966 | + $items_deleted += (int) $this->delete(); |
|
967 | + if ($stop_search_once_found) { |
|
968 | + return $items_deleted; |
|
969 | + } |
|
970 | + } |
|
971 | + foreach ($this->children() as $child_line_item) { |
|
972 | + $items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found); |
|
973 | + } |
|
974 | + return $items_deleted; |
|
975 | + } |
|
976 | + if (isset($this->_children[ $code ])) { |
|
977 | + unset($this->_children[ $code ]); |
|
978 | + return 1; |
|
979 | + } |
|
980 | + return 0; |
|
981 | + } |
|
982 | + |
|
983 | + |
|
984 | + /** |
|
985 | + * If this line item is in the database, is of the type subtotal, and |
|
986 | + * has no children, why do we have it? It should be deleted so this function |
|
987 | + * does that |
|
988 | + * |
|
989 | + * @return boolean |
|
990 | + * @throws EE_Error |
|
991 | + * @throws InvalidArgumentException |
|
992 | + * @throws InvalidDataTypeException |
|
993 | + * @throws InvalidInterfaceException |
|
994 | + * @throws ReflectionException |
|
995 | + */ |
|
996 | + public function delete_if_childless_subtotal() |
|
997 | + { |
|
998 | + if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) { |
|
999 | + return $this->delete(); |
|
1000 | + } |
|
1001 | + return false; |
|
1002 | + } |
|
1003 | + |
|
1004 | + |
|
1005 | + /** |
|
1006 | + * Creates a code and returns a string. doesn't assign the code to this model object |
|
1007 | + * |
|
1008 | + * @return string |
|
1009 | + * @throws EE_Error |
|
1010 | + * @throws InvalidArgumentException |
|
1011 | + * @throws InvalidDataTypeException |
|
1012 | + * @throws InvalidInterfaceException |
|
1013 | + * @throws ReflectionException |
|
1014 | + */ |
|
1015 | + public function generate_code() |
|
1016 | + { |
|
1017 | + // each line item in the cart requires a unique identifier |
|
1018 | + return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime()); |
|
1019 | + } |
|
1020 | + |
|
1021 | + |
|
1022 | + /** |
|
1023 | + * @return bool |
|
1024 | + * @throws EE_Error |
|
1025 | + * @throws InvalidArgumentException |
|
1026 | + * @throws InvalidDataTypeException |
|
1027 | + * @throws InvalidInterfaceException |
|
1028 | + * @throws ReflectionException |
|
1029 | + */ |
|
1030 | + public function is_tax() |
|
1031 | + { |
|
1032 | + return $this->type() === EEM_Line_Item::type_tax; |
|
1033 | + } |
|
1034 | + |
|
1035 | + |
|
1036 | + /** |
|
1037 | + * @return bool |
|
1038 | + * @throws EE_Error |
|
1039 | + * @throws InvalidArgumentException |
|
1040 | + * @throws InvalidDataTypeException |
|
1041 | + * @throws InvalidInterfaceException |
|
1042 | + * @throws ReflectionException |
|
1043 | + */ |
|
1044 | + public function is_tax_sub_total() |
|
1045 | + { |
|
1046 | + return $this->type() === EEM_Line_Item::type_tax_sub_total; |
|
1047 | + } |
|
1048 | + |
|
1049 | + |
|
1050 | + /** |
|
1051 | + * @return bool |
|
1052 | + * @throws EE_Error |
|
1053 | + * @throws InvalidArgumentException |
|
1054 | + * @throws InvalidDataTypeException |
|
1055 | + * @throws InvalidInterfaceException |
|
1056 | + * @throws ReflectionException |
|
1057 | + */ |
|
1058 | + public function is_line_item() |
|
1059 | + { |
|
1060 | + return $this->type() === EEM_Line_Item::type_line_item; |
|
1061 | + } |
|
1062 | + |
|
1063 | + |
|
1064 | + /** |
|
1065 | + * @return bool |
|
1066 | + * @throws EE_Error |
|
1067 | + * @throws InvalidArgumentException |
|
1068 | + * @throws InvalidDataTypeException |
|
1069 | + * @throws InvalidInterfaceException |
|
1070 | + * @throws ReflectionException |
|
1071 | + */ |
|
1072 | + public function is_sub_line_item() |
|
1073 | + { |
|
1074 | + return $this->type() === EEM_Line_Item::type_sub_line_item; |
|
1075 | + } |
|
1076 | + |
|
1077 | + |
|
1078 | + /** |
|
1079 | + * @return bool |
|
1080 | + * @throws EE_Error |
|
1081 | + * @throws InvalidArgumentException |
|
1082 | + * @throws InvalidDataTypeException |
|
1083 | + * @throws InvalidInterfaceException |
|
1084 | + * @throws ReflectionException |
|
1085 | + */ |
|
1086 | + public function is_sub_total() |
|
1087 | + { |
|
1088 | + return $this->type() === EEM_Line_Item::type_sub_total; |
|
1089 | + } |
|
1090 | + |
|
1091 | + |
|
1092 | + /** |
|
1093 | + * Whether or not this line item is a cancellation line item |
|
1094 | + * |
|
1095 | + * @return boolean |
|
1096 | + * @throws EE_Error |
|
1097 | + * @throws InvalidArgumentException |
|
1098 | + * @throws InvalidDataTypeException |
|
1099 | + * @throws InvalidInterfaceException |
|
1100 | + * @throws ReflectionException |
|
1101 | + */ |
|
1102 | + public function is_cancellation() |
|
1103 | + { |
|
1104 | + return EEM_Line_Item::type_cancellation === $this->type(); |
|
1105 | + } |
|
1106 | + |
|
1107 | + |
|
1108 | + /** |
|
1109 | + * @return bool |
|
1110 | + * @throws EE_Error |
|
1111 | + * @throws InvalidArgumentException |
|
1112 | + * @throws InvalidDataTypeException |
|
1113 | + * @throws InvalidInterfaceException |
|
1114 | + * @throws ReflectionException |
|
1115 | + */ |
|
1116 | + public function is_total() |
|
1117 | + { |
|
1118 | + return $this->type() === EEM_Line_Item::type_total; |
|
1119 | + } |
|
1120 | + |
|
1121 | + |
|
1122 | + /** |
|
1123 | + * @return bool |
|
1124 | + * @throws EE_Error |
|
1125 | + * @throws InvalidArgumentException |
|
1126 | + * @throws InvalidDataTypeException |
|
1127 | + * @throws InvalidInterfaceException |
|
1128 | + * @throws ReflectionException |
|
1129 | + */ |
|
1130 | + public function is_cancelled() |
|
1131 | + { |
|
1132 | + return $this->type() === EEM_Line_Item::type_cancellation; |
|
1133 | + } |
|
1134 | + |
|
1135 | + |
|
1136 | + /** |
|
1137 | + * @return string like '2, 004.00', formatted according to the localized currency |
|
1138 | + * @throws EE_Error |
|
1139 | + * @throws InvalidArgumentException |
|
1140 | + * @throws InvalidDataTypeException |
|
1141 | + * @throws InvalidInterfaceException |
|
1142 | + * @throws ReflectionException |
|
1143 | + */ |
|
1144 | + public function unit_price_no_code() |
|
1145 | + { |
|
1146 | + return $this->get_pretty('LIN_unit_price', 'no_currency_code'); |
|
1147 | + } |
|
1148 | + |
|
1149 | + |
|
1150 | + /** |
|
1151 | + * @return string like '2, 004.00', formatted according to the localized currency |
|
1152 | + * @throws EE_Error |
|
1153 | + * @throws InvalidArgumentException |
|
1154 | + * @throws InvalidDataTypeException |
|
1155 | + * @throws InvalidInterfaceException |
|
1156 | + * @throws ReflectionException |
|
1157 | + */ |
|
1158 | + public function total_no_code() |
|
1159 | + { |
|
1160 | + return $this->get_pretty('LIN_total', 'no_currency_code'); |
|
1161 | + } |
|
1162 | + |
|
1163 | + |
|
1164 | + /** |
|
1165 | + * Gets the final total on this item, taking taxes into account. |
|
1166 | + * Has the side-effect of setting the sub-total as it was just calculated. |
|
1167 | + * If this is used on a grand-total line item, also updates the transaction's |
|
1168 | + * TXN_total (provided this line item is allowed to persist, otherwise we don't |
|
1169 | + * want to change a persistable transaction with info from a non-persistent line item) |
|
1170 | + * |
|
1171 | + * @param bool $update_txn_status |
|
1172 | + * @return float |
|
1173 | + * @throws EE_Error |
|
1174 | + * @throws InvalidArgumentException |
|
1175 | + * @throws InvalidDataTypeException |
|
1176 | + * @throws InvalidInterfaceException |
|
1177 | + * @throws ReflectionException |
|
1178 | + * @throws RuntimeException |
|
1179 | + */ |
|
1180 | + public function recalculate_total_including_taxes($update_txn_status = false) |
|
1181 | + { |
|
1182 | + $pre_tax_total = $this->recalculate_pre_tax_total(); |
|
1183 | + $tax_total = $this->recalculate_taxes_and_tax_total(); |
|
1184 | + $total = $pre_tax_total + $tax_total; |
|
1185 | + // no negative totals plz |
|
1186 | + $total = max($total, 0); |
|
1187 | + $this->set_total($total); |
|
1188 | + // only update the related transaction's total |
|
1189 | + // if we intend to save this line item and its a grand total |
|
1190 | + if ( |
|
1191 | + $this->allow_persist() && $this->type() === EEM_Line_Item::type_total |
|
1192 | + && $this->transaction() |
|
1193 | + instanceof |
|
1194 | + EE_Transaction |
|
1195 | + ) { |
|
1196 | + $this->transaction()->set_total($total); |
|
1197 | + if ($update_txn_status) { |
|
1198 | + // don't save the TXN because that will be done below |
|
1199 | + // and the following method only saves if the status changes |
|
1200 | + $this->transaction()->update_status_based_on_total_paid(false); |
|
1201 | + } |
|
1202 | + if ($this->transaction()->ID()) { |
|
1203 | + $this->transaction()->save(); |
|
1204 | + } |
|
1205 | + } |
|
1206 | + $this->maybe_save(); |
|
1207 | + return $total; |
|
1208 | + } |
|
1209 | + |
|
1210 | + |
|
1211 | + /** |
|
1212 | + * Recursively goes through all the children and recalculates sub-totals EXCEPT for |
|
1213 | + * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its |
|
1214 | + * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and |
|
1215 | + * when this is called on the grand total |
|
1216 | + * |
|
1217 | + * @return float |
|
1218 | + * @throws EE_Error |
|
1219 | + * @throws InvalidArgumentException |
|
1220 | + * @throws InvalidDataTypeException |
|
1221 | + * @throws InvalidInterfaceException |
|
1222 | + * @throws ReflectionException |
|
1223 | + */ |
|
1224 | + public function recalculate_pre_tax_total() |
|
1225 | + { |
|
1226 | + $total = 0; |
|
1227 | + $my_children = $this->children(); |
|
1228 | + $has_children = ! empty($my_children); |
|
1229 | + if ($has_children && $this->is_line_item()) { |
|
1230 | + $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children); |
|
1231 | + } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
1232 | + $total = $this->unit_price() * $this->quantity(); |
|
1233 | + } elseif ($this->is_sub_total() || $this->is_total()) { |
|
1234 | + $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children); |
|
1235 | + } elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) { |
|
1236 | + // completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total |
|
1237 | + return 0; |
|
1238 | + } |
|
1239 | + // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events) |
|
1240 | + if (! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()) { |
|
1241 | + if ($this->OBJ_type() !== EEM_Line_Item::OBJ_TYPE_EVENT) { |
|
1242 | + $this->set_quantity(1); |
|
1243 | + } |
|
1244 | + if (! $this->is_percent()) { |
|
1245 | + $this->set_unit_price($total); |
|
1246 | + } |
|
1247 | + } |
|
1248 | + // we don't want to bother saving grand totals, because that needs to factor in taxes anyways |
|
1249 | + // so it ought to be |
|
1250 | + if (! $this->is_total()) { |
|
1251 | + $this->set_total($total); |
|
1252 | + // if not a percent line item, make sure we keep the unit price in sync |
|
1253 | + if ( |
|
1254 | + $has_children |
|
1255 | + && $this->is_line_item() |
|
1256 | + && ! $this->is_percent() |
|
1257 | + ) { |
|
1258 | + if ($this->quantity() === 0) { |
|
1259 | + $new_unit_price = 0; |
|
1260 | + } else { |
|
1261 | + $new_unit_price = $this->total() / $this->quantity(); |
|
1262 | + } |
|
1263 | + $this->set_unit_price($new_unit_price); |
|
1264 | + } |
|
1265 | + $this->maybe_save(); |
|
1266 | + } |
|
1267 | + return $total; |
|
1268 | + } |
|
1269 | + |
|
1270 | + |
|
1271 | + /** |
|
1272 | + * Calculates the pretax total when this line item is a subtotal or total line item. |
|
1273 | + * Basically does a sum-then-round approach (ie, any percent line item that are children |
|
1274 | + * will calculate their total based on the un-rounded total we're working with so far, and |
|
1275 | + * THEN round the result; instead of rounding as we go like with sub-line-items) |
|
1276 | + * |
|
1277 | + * @param float $calculated_total_so_far |
|
1278 | + * @param EE_Line_Item[] $my_children |
|
1279 | + * @return float |
|
1280 | + * @throws EE_Error |
|
1281 | + * @throws InvalidArgumentException |
|
1282 | + * @throws InvalidDataTypeException |
|
1283 | + * @throws InvalidInterfaceException |
|
1284 | + * @throws ReflectionException |
|
1285 | + */ |
|
1286 | + protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null) |
|
1287 | + { |
|
1288 | + if ($my_children === null) { |
|
1289 | + $my_children = $this->children(); |
|
1290 | + } |
|
1291 | + $subtotal_quantity = 0; |
|
1292 | + // get the total of all its children |
|
1293 | + foreach ($my_children as $child_line_item) { |
|
1294 | + if ($child_line_item instanceof EE_Line_Item) { |
|
1295 | + // skip line item if it is cancelled or is a tax |
|
1296 | + if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
1297 | + continue; |
|
1298 | + } |
|
1299 | + // percentage line items are based on total so far |
|
1300 | + if ($child_line_item->is_percent()) { |
|
1301 | + // round as we go so that the line items add up ok |
|
1302 | + $percent_total = round( |
|
1303 | + $calculated_total_so_far * $child_line_item->percent() / 100, |
|
1304 | + EE_Registry::instance()->CFG->currency->dec_plc |
|
1305 | + ); |
|
1306 | + $child_line_item->set_total($percent_total); |
|
1307 | + // so far all percent line items should have a quantity of 1 |
|
1308 | + // (ie, no double percent discounts. Although that might be requested someday) |
|
1309 | + $child_line_item->set_quantity(1); |
|
1310 | + $child_line_item->maybe_save(); |
|
1311 | + $calculated_total_so_far += $percent_total; |
|
1312 | + } else { |
|
1313 | + // verify flat sub-line-item quantities match their parent |
|
1314 | + if ($child_line_item->is_sub_line_item()) { |
|
1315 | + $child_line_item->set_quantity($this->quantity()); |
|
1316 | + } |
|
1317 | + $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
1318 | + $subtotal_quantity += $child_line_item->quantity(); |
|
1319 | + } |
|
1320 | + } |
|
1321 | + } |
|
1322 | + if ($this->is_sub_total()) { |
|
1323 | + // no negative totals plz |
|
1324 | + $calculated_total_so_far = max($calculated_total_so_far, 0); |
|
1325 | + $subtotal_quantity = $subtotal_quantity > 0 ? 1 : 0; |
|
1326 | + $this->set_quantity($subtotal_quantity); |
|
1327 | + $this->maybe_save(); |
|
1328 | + } |
|
1329 | + return $calculated_total_so_far; |
|
1330 | + } |
|
1331 | + |
|
1332 | + |
|
1333 | + /** |
|
1334 | + * Calculates the pretax total for a normal line item, in a round-then-sum approach |
|
1335 | + * (where each sub-line-item is applied to the base price for the line item |
|
1336 | + * and the result is immediately rounded, rather than summing all the sub-line-items |
|
1337 | + * then rounding, like we do when recalculating pretax totals on totals and subtotals). |
|
1338 | + * |
|
1339 | + * @param float $calculated_total_so_far |
|
1340 | + * @param EE_Line_Item[] $my_children |
|
1341 | + * @return float |
|
1342 | + * @throws EE_Error |
|
1343 | + * @throws InvalidArgumentException |
|
1344 | + * @throws InvalidDataTypeException |
|
1345 | + * @throws InvalidInterfaceException |
|
1346 | + * @throws ReflectionException |
|
1347 | + */ |
|
1348 | + protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null) |
|
1349 | + { |
|
1350 | + if ($my_children === null) { |
|
1351 | + $my_children = $this->children(); |
|
1352 | + } |
|
1353 | + // we need to keep track of the running total for a single item, |
|
1354 | + // because we need to round as we go |
|
1355 | + $unit_price_for_total = 0; |
|
1356 | + $quantity_for_total = 1; |
|
1357 | + // get the total of all its children |
|
1358 | + foreach ($my_children as $child_line_item) { |
|
1359 | + if ($child_line_item instanceof EE_Line_Item) { |
|
1360 | + // skip line item if it is cancelled or is a tax |
|
1361 | + if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
1362 | + continue; |
|
1363 | + } |
|
1364 | + if ($child_line_item->is_percent()) { |
|
1365 | + // it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity |
|
1366 | + // not total multiplied by percent, because that ignores rounding along-the-way |
|
1367 | + $percent_unit_price = round( |
|
1368 | + $unit_price_for_total * $child_line_item->percent() / 100, |
|
1369 | + EE_Registry::instance()->CFG->currency->dec_plc |
|
1370 | + ); |
|
1371 | + $percent_total = $percent_unit_price * $quantity_for_total; |
|
1372 | + $child_line_item->set_total($percent_total); |
|
1373 | + // so far all percent line items should have a quantity of 1 |
|
1374 | + // (ie, no double percent discounts. Although that might be requested someday) |
|
1375 | + $child_line_item->set_quantity(1); |
|
1376 | + $child_line_item->maybe_save(); |
|
1377 | + $calculated_total_so_far += $percent_total; |
|
1378 | + $unit_price_for_total += $percent_unit_price; |
|
1379 | + } else { |
|
1380 | + // verify flat sub-line-item quantities match their parent |
|
1381 | + if ($child_line_item->is_sub_line_item()) { |
|
1382 | + $child_line_item->set_quantity($this->quantity()); |
|
1383 | + } |
|
1384 | + $quantity_for_total = $child_line_item->quantity(); |
|
1385 | + $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
1386 | + $unit_price_for_total += $child_line_item->unit_price(); |
|
1387 | + } |
|
1388 | + } |
|
1389 | + } |
|
1390 | + return $calculated_total_so_far; |
|
1391 | + } |
|
1392 | + |
|
1393 | + |
|
1394 | + /** |
|
1395 | + * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets |
|
1396 | + * the totals on each tax calculated, and returns the final tax total. Re-saves tax line items |
|
1397 | + * and tax sub-total if already in the DB |
|
1398 | + * |
|
1399 | + * @return float |
|
1400 | + * @throws EE_Error |
|
1401 | + * @throws InvalidArgumentException |
|
1402 | + * @throws InvalidDataTypeException |
|
1403 | + * @throws InvalidInterfaceException |
|
1404 | + * @throws ReflectionException |
|
1405 | + */ |
|
1406 | + public function recalculate_taxes_and_tax_total() |
|
1407 | + { |
|
1408 | + // get all taxes |
|
1409 | + $taxes = $this->tax_descendants(); |
|
1410 | + // calculate the pretax total |
|
1411 | + $taxable_total = $this->taxable_total(); |
|
1412 | + $tax_total = 0; |
|
1413 | + foreach ($taxes as $tax) { |
|
1414 | + $total_on_this_tax = $taxable_total * $tax->percent() / 100; |
|
1415 | + // remember the total on this line item |
|
1416 | + $tax->set_total($total_on_this_tax); |
|
1417 | + $tax->maybe_save(); |
|
1418 | + $tax_total += $tax->total(); |
|
1419 | + } |
|
1420 | + $this->_recalculate_tax_sub_total(); |
|
1421 | + return $tax_total; |
|
1422 | + } |
|
1423 | + |
|
1424 | + |
|
1425 | + /** |
|
1426 | + * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated |
|
1427 | + * |
|
1428 | + * @return void |
|
1429 | + * @throws EE_Error |
|
1430 | + * @throws InvalidArgumentException |
|
1431 | + * @throws InvalidDataTypeException |
|
1432 | + * @throws InvalidInterfaceException |
|
1433 | + * @throws ReflectionException |
|
1434 | + */ |
|
1435 | + private function _recalculate_tax_sub_total() |
|
1436 | + { |
|
1437 | + if ($this->is_tax_sub_total()) { |
|
1438 | + $total = 0; |
|
1439 | + $total_percent = 0; |
|
1440 | + // simply loop through all its children (which should be taxes) and sum their total |
|
1441 | + foreach ($this->children() as $child_tax) { |
|
1442 | + if ($child_tax instanceof EE_Line_Item) { |
|
1443 | + $total += $child_tax->total(); |
|
1444 | + $total_percent += $child_tax->percent(); |
|
1445 | + } |
|
1446 | + } |
|
1447 | + $this->set_total($total); |
|
1448 | + $this->set_percent($total_percent); |
|
1449 | + $this->maybe_save(); |
|
1450 | + } elseif ($this->is_total()) { |
|
1451 | + foreach ($this->children() as $maybe_tax_subtotal) { |
|
1452 | + if ($maybe_tax_subtotal instanceof EE_Line_Item) { |
|
1453 | + $maybe_tax_subtotal->_recalculate_tax_sub_total(); |
|
1454 | + } |
|
1455 | + } |
|
1456 | + } |
|
1457 | + } |
|
1458 | + |
|
1459 | + |
|
1460 | + /** |
|
1461 | + * Gets the total tax on this line item. Assumes taxes have already been calculated using |
|
1462 | + * recalculate_taxes_and_total |
|
1463 | + * |
|
1464 | + * @return float |
|
1465 | + * @throws EE_Error |
|
1466 | + * @throws InvalidArgumentException |
|
1467 | + * @throws InvalidDataTypeException |
|
1468 | + * @throws InvalidInterfaceException |
|
1469 | + * @throws ReflectionException |
|
1470 | + */ |
|
1471 | + public function get_total_tax() |
|
1472 | + { |
|
1473 | + $this->_recalculate_tax_sub_total(); |
|
1474 | + $total = 0; |
|
1475 | + foreach ($this->tax_descendants() as $tax_line_item) { |
|
1476 | + if ($tax_line_item instanceof EE_Line_Item) { |
|
1477 | + $total += $tax_line_item->total(); |
|
1478 | + } |
|
1479 | + } |
|
1480 | + return $total; |
|
1481 | + } |
|
1482 | + |
|
1483 | + |
|
1484 | + /** |
|
1485 | + * Gets the total for all the items purchased only |
|
1486 | + * |
|
1487 | + * @return float |
|
1488 | + * @throws EE_Error |
|
1489 | + * @throws InvalidArgumentException |
|
1490 | + * @throws InvalidDataTypeException |
|
1491 | + * @throws InvalidInterfaceException |
|
1492 | + * @throws ReflectionException |
|
1493 | + */ |
|
1494 | + public function get_items_total() |
|
1495 | + { |
|
1496 | + // by default, let's make sure we're consistent with the existing line item |
|
1497 | + if ($this->is_total()) { |
|
1498 | + $pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this); |
|
1499 | + if ($pretax_subtotal_li instanceof EE_Line_Item) { |
|
1500 | + return $pretax_subtotal_li->total(); |
|
1501 | + } |
|
1502 | + } |
|
1503 | + $total = 0; |
|
1504 | + foreach ($this->get_items() as $item) { |
|
1505 | + if ($item instanceof EE_Line_Item) { |
|
1506 | + $total += $item->total(); |
|
1507 | + } |
|
1508 | + } |
|
1509 | + return $total; |
|
1510 | + } |
|
1511 | + |
|
1512 | + |
|
1513 | + /** |
|
1514 | + * Gets all the descendants (ie, children or children of children etc) that |
|
1515 | + * are of the type 'tax' |
|
1516 | + * |
|
1517 | + * @return EE_Line_Item[] |
|
1518 | + * @throws EE_Error |
|
1519 | + */ |
|
1520 | + public function tax_descendants() |
|
1521 | + { |
|
1522 | + return EEH_Line_Item::get_tax_descendants($this); |
|
1523 | + } |
|
1524 | + |
|
1525 | + |
|
1526 | + /** |
|
1527 | + * Gets all the real items purchased which are children of this item |
|
1528 | + * |
|
1529 | + * @return EE_Line_Item[] |
|
1530 | + * @throws EE_Error |
|
1531 | + */ |
|
1532 | + public function get_items() |
|
1533 | + { |
|
1534 | + return EEH_Line_Item::get_line_item_descendants($this); |
|
1535 | + } |
|
1536 | + |
|
1537 | + |
|
1538 | + /** |
|
1539 | + * Returns the amount taxable among this line item's children (or if it has no children, |
|
1540 | + * how much of it is taxable). Does not recalculate totals or subtotals. |
|
1541 | + * If the taxable total is negative, (eg, if none of the tickets were taxable, |
|
1542 | + * but there is a "Taxable" discount), returns 0. |
|
1543 | + * |
|
1544 | + * @return float |
|
1545 | + * @throws EE_Error |
|
1546 | + * @throws InvalidArgumentException |
|
1547 | + * @throws InvalidDataTypeException |
|
1548 | + * @throws InvalidInterfaceException |
|
1549 | + * @throws ReflectionException |
|
1550 | + */ |
|
1551 | + public function taxable_total() |
|
1552 | + { |
|
1553 | + $total = 0; |
|
1554 | + if ($this->children()) { |
|
1555 | + foreach ($this->children() as $child_line_item) { |
|
1556 | + if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) { |
|
1557 | + // if it's a percent item, only take into account the percent |
|
1558 | + // that's taxable too (the taxable total so far) |
|
1559 | + if ($child_line_item->is_percent()) { |
|
1560 | + $total += ($total * $child_line_item->percent() / 100); |
|
1561 | + } else { |
|
1562 | + $total += $child_line_item->total(); |
|
1563 | + } |
|
1564 | + } elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) { |
|
1565 | + $total += $child_line_item->taxable_total(); |
|
1566 | + } |
|
1567 | + } |
|
1568 | + } |
|
1569 | + return max($total, 0); |
|
1570 | + } |
|
1571 | + |
|
1572 | + |
|
1573 | + /** |
|
1574 | + * Gets the transaction for this line item |
|
1575 | + * |
|
1576 | + * @return EE_Base_Class|EE_Transaction |
|
1577 | + * @throws EE_Error |
|
1578 | + * @throws InvalidArgumentException |
|
1579 | + * @throws InvalidDataTypeException |
|
1580 | + * @throws InvalidInterfaceException |
|
1581 | + * @throws ReflectionException |
|
1582 | + */ |
|
1583 | + public function transaction() |
|
1584 | + { |
|
1585 | + return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TRANSACTION); |
|
1586 | + } |
|
1587 | + |
|
1588 | + |
|
1589 | + /** |
|
1590 | + * Saves this line item to the DB, and recursively saves its descendants. |
|
1591 | + * Because there currently is no proper parent-child relation on the model, |
|
1592 | + * save_this_and_cached() will NOT save the descendants. |
|
1593 | + * Also sets the transaction on this line item and all its descendants before saving |
|
1594 | + * |
|
1595 | + * @param int $txn_id if none is provided, assumes $this->TXN_ID() |
|
1596 | + * @return int count of items saved |
|
1597 | + * @throws EE_Error |
|
1598 | + * @throws InvalidArgumentException |
|
1599 | + * @throws InvalidDataTypeException |
|
1600 | + * @throws InvalidInterfaceException |
|
1601 | + * @throws ReflectionException |
|
1602 | + */ |
|
1603 | + public function save_this_and_descendants_to_txn($txn_id = null) |
|
1604 | + { |
|
1605 | + $count = 0; |
|
1606 | + if (! $txn_id) { |
|
1607 | + $txn_id = $this->TXN_ID(); |
|
1608 | + } |
|
1609 | + $this->set_TXN_ID($txn_id); |
|
1610 | + $children = $this->children(); |
|
1611 | + $count += $this->save() |
|
1612 | + ? 1 |
|
1613 | + : 0; |
|
1614 | + foreach ($children as $child_line_item) { |
|
1615 | + if ($child_line_item instanceof EE_Line_Item) { |
|
1616 | + $child_line_item->set_parent_ID($this->ID()); |
|
1617 | + $count += $child_line_item->save_this_and_descendants_to_txn($txn_id); |
|
1618 | + } |
|
1619 | + } |
|
1620 | + return $count; |
|
1621 | + } |
|
1622 | + |
|
1623 | + |
|
1624 | + /** |
|
1625 | + * Saves this line item to the DB, and recursively saves its descendants. |
|
1626 | + * |
|
1627 | + * @return int count of items saved |
|
1628 | + * @throws EE_Error |
|
1629 | + * @throws InvalidArgumentException |
|
1630 | + * @throws InvalidDataTypeException |
|
1631 | + * @throws InvalidInterfaceException |
|
1632 | + * @throws ReflectionException |
|
1633 | + */ |
|
1634 | + public function save_this_and_descendants() |
|
1635 | + { |
|
1636 | + $count = 0; |
|
1637 | + $children = $this->children(); |
|
1638 | + $count += $this->save() |
|
1639 | + ? 1 |
|
1640 | + : 0; |
|
1641 | + foreach ($children as $child_line_item) { |
|
1642 | + if ($child_line_item instanceof EE_Line_Item) { |
|
1643 | + $child_line_item->set_parent_ID($this->ID()); |
|
1644 | + $count += $child_line_item->save_this_and_descendants(); |
|
1645 | + } |
|
1646 | + } |
|
1647 | + return $count; |
|
1648 | + } |
|
1649 | + |
|
1650 | + |
|
1651 | + /** |
|
1652 | + * returns the cancellation line item if this item was cancelled |
|
1653 | + * |
|
1654 | + * @return EE_Line_Item[] |
|
1655 | + * @throws InvalidArgumentException |
|
1656 | + * @throws InvalidInterfaceException |
|
1657 | + * @throws InvalidDataTypeException |
|
1658 | + * @throws ReflectionException |
|
1659 | + * @throws EE_Error |
|
1660 | + */ |
|
1661 | + public function get_cancellations() |
|
1662 | + { |
|
1663 | + EE_Registry::instance()->load_helper('Line_Item'); |
|
1664 | + return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation); |
|
1665 | + } |
|
1666 | + |
|
1667 | + |
|
1668 | + /** |
|
1669 | + * If this item has an ID, then this saves it again to update the db |
|
1670 | + * |
|
1671 | + * @return int count of items saved |
|
1672 | + * @throws EE_Error |
|
1673 | + * @throws InvalidArgumentException |
|
1674 | + * @throws InvalidDataTypeException |
|
1675 | + * @throws InvalidInterfaceException |
|
1676 | + * @throws ReflectionException |
|
1677 | + */ |
|
1678 | + public function maybe_save() |
|
1679 | + { |
|
1680 | + if ($this->ID()) { |
|
1681 | + return $this->save(); |
|
1682 | + } |
|
1683 | + return false; |
|
1684 | + } |
|
1685 | + |
|
1686 | + |
|
1687 | + /** |
|
1688 | + * clears the cached children and parent from the line item |
|
1689 | + * |
|
1690 | + * @return void |
|
1691 | + */ |
|
1692 | + public function clear_related_line_item_cache() |
|
1693 | + { |
|
1694 | + $this->_children = array(); |
|
1695 | + $this->_parent = null; |
|
1696 | + } |
|
1697 | + |
|
1698 | + |
|
1699 | + /** |
|
1700 | + * @param bool $raw |
|
1701 | + * @return int |
|
1702 | + * @throws EE_Error |
|
1703 | + * @throws InvalidArgumentException |
|
1704 | + * @throws InvalidDataTypeException |
|
1705 | + * @throws InvalidInterfaceException |
|
1706 | + * @throws ReflectionException |
|
1707 | + */ |
|
1708 | + public function timestamp($raw = false) |
|
1709 | + { |
|
1710 | + return $raw |
|
1711 | + ? $this->get_raw('LIN_timestamp') |
|
1712 | + : $this->get('LIN_timestamp'); |
|
1713 | + } |
|
1714 | + |
|
1715 | + |
|
1716 | + |
|
1717 | + |
|
1718 | + /************************* DEPRECATED *************************/ |
|
1719 | + /** |
|
1720 | + * @deprecated 4.6.0 |
|
1721 | + * @param string $type one of the constants on EEM_Line_Item |
|
1722 | + * @return EE_Line_Item[] |
|
1723 | + * @throws EE_Error |
|
1724 | + */ |
|
1725 | + protected function _get_descendants_of_type($type) |
|
1726 | + { |
|
1727 | + EE_Error::doing_it_wrong( |
|
1728 | + 'EE_Line_Item::_get_descendants_of_type()', |
|
1729 | + sprintf( |
|
1730 | + esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
1731 | + 'EEH_Line_Item::get_descendants_of_type()' |
|
1732 | + ), |
|
1733 | + '4.6.0' |
|
1734 | + ); |
|
1735 | + return EEH_Line_Item::get_descendants_of_type($this, $type); |
|
1736 | + } |
|
1737 | + |
|
1738 | + |
|
1739 | + /** |
|
1740 | + * @deprecated 4.6.0 |
|
1741 | + * @param string $type like one of the EEM_Line_Item::type_* |
|
1742 | + * @return EE_Line_Item |
|
1743 | + * @throws EE_Error |
|
1744 | + * @throws InvalidArgumentException |
|
1745 | + * @throws InvalidDataTypeException |
|
1746 | + * @throws InvalidInterfaceException |
|
1747 | + * @throws ReflectionException |
|
1748 | + */ |
|
1749 | + public function get_nearest_descendant_of_type($type) |
|
1750 | + { |
|
1751 | + EE_Error::doing_it_wrong( |
|
1752 | + 'EE_Line_Item::get_nearest_descendant_of_type()', |
|
1753 | + sprintf( |
|
1754 | + esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
1755 | + 'EEH_Line_Item::get_nearest_descendant_of_type()' |
|
1756 | + ), |
|
1757 | + '4.6.0' |
|
1758 | + ); |
|
1759 | + return EEH_Line_Item::get_nearest_descendant_of_type($this, $type); |
|
1760 | + } |
|
1761 | 1761 | } |