Completed
Branch FET-9856-direct-instantiation (d3e084)
by
unknown
57:58 queued 46:07
created
core/db_classes/EE_Base_Class.class.php 2 patches
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -155,8 +155,8 @@  discard block
 block discarded – undo
155 155
             list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
156 156
         } else {
157 157
             //set default formats for date and time
158
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
159
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
158
+            $this->_dt_frmt = (string) get_option('date_format', 'Y-m-d');
159
+            $this->_tm_frmt = (string) get_option('time_format', 'g:i a');
160 160
         }
161 161
         //if db model is instantiating
162 162
         if ($bydb) {
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
      */
479 479
     public function get_format($full = true)
480 480
     {
481
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
481
+        return $full ? $this->_dt_frmt.' '.$this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
482 482
     }
483 483
 
484 484
 
@@ -587,7 +587,7 @@  discard block
 block discarded – undo
587 587
         $model = $this->get_model();
588 588
         $model->field_settings_for($fieldname);
589 589
         $cache_type = $pretty ? 'pretty' : 'standard';
590
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
590
+        $cache_type .= ! empty($extra_cache_ref) ? '_'.$extra_cache_ref : '';
591 591
         if (isset($this->_cached_properties[$fieldname][$cache_type])) {
592 592
             return $this->_cached_properties[$fieldname][$cache_type];
593 593
         }
@@ -802,7 +802,7 @@  discard block
 block discarded – undo
802 802
         $current_cache_id = ''
803 803
     ) {
804 804
         // verify that incoming object is of the correct type
805
-        $obj_class = 'EE_' . $relationName;
805
+        $obj_class = 'EE_'.$relationName;
806 806
         if ($newly_saved_object instanceof $obj_class) {
807 807
             /* @type EE_Base_Class $newly_saved_object */
808 808
             // now get the type of relation
@@ -1288,7 +1288,7 @@  discard block
 block discarded – undo
1288 1288
      */
1289 1289
     public function get_i18n_datetime($field_name, $format = '')
1290 1290
     {
1291
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1291
+        $format = empty($format) ? $this->_dt_frmt.' '.$this->_tm_frmt : $format;
1292 1292
         return date_i18n(
1293 1293
             $format,
1294 1294
             EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
@@ -1426,8 +1426,8 @@  discard block
 block discarded – undo
1426 1426
         }
1427 1427
         $original_timezone = $this->_timezone;
1428 1428
         $this->set_timezone($timezone);
1429
-        $fn = (array)$field_name;
1430
-        $args = array_merge($fn, (array)$args);
1429
+        $fn = (array) $field_name;
1430
+        $args = array_merge($fn, (array) $args);
1431 1431
         if ( ! method_exists($this, $callback)) {
1432 1432
             throw new EE_Error(
1433 1433
                 sprintf(
@@ -1439,8 +1439,8 @@  discard block
 block discarded – undo
1439 1439
                 )
1440 1440
             );
1441 1441
         }
1442
-        $args = (array)$args;
1443
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1442
+        $args = (array) $args;
1443
+        $return = $prepend.call_user_func_array(array($this, $callback), $args).$append;
1444 1444
         $this->set_timezone($original_timezone);
1445 1445
         return $return;
1446 1446
     }
@@ -1579,14 +1579,14 @@  discard block
 block discarded – undo
1579 1579
          * @param array         $set_cols_n_values
1580 1580
          * @param EE_Base_Class $model_object
1581 1581
          */
1582
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1582
+        $set_cols_n_values = (array) apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1583 1583
             $this);
1584 1584
         //set attributes as provided in $set_cols_n_values
1585 1585
         foreach ($set_cols_n_values as $column => $value) {
1586 1586
             $this->set($column, $value);
1587 1587
         }
1588 1588
         // no changes ? then don't do anything
1589
-        if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1589
+        if ( ! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1590 1590
             return 0;
1591 1591
         }
1592 1592
         /**
@@ -1638,8 +1638,8 @@  discard block
 block discarded – undo
1638 1638
                                 __('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1639 1639
                                     'event_espresso'),
1640 1640
                                 get_class($this),
1641
-                                get_class($model) . '::instance()->add_to_entity_map()',
1642
-                                get_class($model) . '::instance()->get_one_by_ID()',
1641
+                                get_class($model).'::instance()->add_to_entity_map()',
1642
+                                get_class($model).'::instance()->get_one_by_ID()',
1643 1643
                                 '<br />'
1644 1644
                             )
1645 1645
                         );
@@ -1772,7 +1772,7 @@  discard block
 block discarded – undo
1772 1772
      */
1773 1773
     public function get_model()
1774 1774
     {
1775
-        if( ! $this->_model){
1775
+        if ( ! $this->_model) {
1776 1776
             $modelName = self::_get_model_classname(get_class($this));
1777 1777
             $this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
1778 1778
         } else {
@@ -1915,7 +1915,7 @@  discard block
 block discarded – undo
1915 1915
         if (strpos($model_name, "EE_") === 0) {
1916 1916
             $model_classname = str_replace("EE_", "EEM_", $model_name);
1917 1917
         } else {
1918
-            $model_classname = "EEM_" . $model_name;
1918
+            $model_classname = "EEM_".$model_name;
1919 1919
         }
1920 1920
         return $model_classname;
1921 1921
     }
@@ -2302,7 +2302,7 @@  discard block
 block discarded – undo
2302 2302
      */
2303 2303
     protected function _property_exists($properties)
2304 2304
     {
2305
-        foreach ((array)$properties as $property_name) {
2305
+        foreach ((array) $properties as $property_name) {
2306 2306
             //first make sure this property exists
2307 2307
             if ( ! $this->_fields[$property_name]) {
2308 2308
                 throw new EE_Error(
@@ -2632,8 +2632,8 @@  discard block
 block discarded – undo
2632 2632
                         __('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2633 2633
                             'event_espresso'),
2634 2634
                         $this->ID(),
2635
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2636
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2635
+                        get_class($this->get_model()).'::instance()->add_to_entity_map()',
2636
+                        get_class($this->get_model()).'::instance()->refresh_entity_map()'
2637 2637
                     )
2638 2638
                 );
2639 2639
             }
@@ -2693,7 +2693,7 @@  discard block
 block discarded – undo
2693 2693
         $model = $this->get_model();
2694 2694
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
2695 2695
             if ($relation_obj instanceof EE_Belongs_To_Relation) {
2696
-                $classname = 'EE_' . $model->get_this_model_name();
2696
+                $classname = 'EE_'.$model->get_this_model_name();
2697 2697
                 if (
2698 2698
                     $this->get_one_from_cache($relation_name) instanceof $classname
2699 2699
                     && $this->get_one_from_cache($relation_name)->ID()
Please login to merge, or discard this patch.
Indentation   +2749 added lines, -2749 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 do_action('AHEE_log', __FILE__, ' FILE LOADED', '');
5 5
 
@@ -25,2754 +25,2754 @@  discard block
 block discarded – undo
25 25
 abstract class EE_Base_Class
26 26
 {
27 27
 
28
-    /**
29
-     * This is an array of the original properties and values provided during construction
30
-     * of this model object. (keys are model field names, values are their values).
31
-     * This list is important to remember so that when we are merging data from the db, we know
32
-     * which values to override and which to not override.
33
-     *
34
-     * @var array
35
-     */
36
-    protected $_props_n_values_provided_in_constructor;
37
-
38
-    /**
39
-     * Timezone
40
-     * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
-     * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
-     * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
-     * access to it.
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_timezone;
48
-
49
-
50
-
51
-    /**
52
-     * date format
53
-     * pattern or format for displaying dates
54
-     *
55
-     * @var string $_dt_frmt
56
-     */
57
-    protected $_dt_frmt;
58
-
59
-
60
-
61
-    /**
62
-     * time format
63
-     * pattern or format for displaying time
64
-     *
65
-     * @var string $_tm_frmt
66
-     */
67
-    protected $_tm_frmt;
68
-
69
-
70
-
71
-    /**
72
-     * This property is for holding a cached array of object properties indexed by property name as the key.
73
-     * The purpose of this is for setting a cache on properties that may have calculated values after a
74
-     * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
-     * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
-     *
77
-     * @var array
78
-     */
79
-    protected $_cached_properties = array();
80
-
81
-    /**
82
-     * An array containing keys of the related model, and values are either an array of related mode objects or a
83
-     * single
84
-     * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
-     * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
-     * all others have an array)
87
-     *
88
-     * @var array
89
-     */
90
-    protected $_model_relations = array();
91
-
92
-    /**
93
-     * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
-     * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
-     *
96
-     * @var array
97
-     */
98
-    protected $_fields = array();
99
-
100
-    /**
101
-     * @var boolean indicating whether or not this model object is intended to ever be saved
102
-     * For example, we might create model objects intended to only be used for the duration
103
-     * of this request and to be thrown away, and if they were accidentally saved
104
-     * it would be a bug.
105
-     */
106
-    protected $_allow_persist = true;
107
-
108
-    /**
109
-     * @var boolean indicating whether or not this model object's properties have changed since construction
110
-     */
111
-    protected $_has_changes = false;
112
-
113
-    /**
114
-     * @var EEM_Base
115
-     */
116
-    protected $_model;
117
-
118
-
119
-
120
-    /**
121
-     * @param array  $fieldValues
122
-     * @param string $timezone
123
-     * @param array  $date_formats
124
-     * @param bool   $bydb
125
-     * @return \EE_Base_Class
126
-     * @throws \EE_Error
127
-     */
128
-    public static function new_instance(
129
-        array $fieldValues = array(),
130
-        $timezone = '',
131
-        array $date_formats = array(),
132
-        $bydb = false
133
-    )
134
-    {
135
-        $className = get_called_class();
136
-        if ( ! $bydb) {
137
-            $cached_object = \EE_Base_Class::_check_for_object($fieldValues, $className, $timezone, $date_formats);
138
-            if ($cached_object) {
139
-                return $cached_object;
140
-            }
141
-        }
142
-        return new static($fieldValues, $bydb, $timezone, $date_formats);
143
-    }
144
-
145
-
146
-
147
-    /**
148
-     * @deprecated
149
-     * @param array  $fieldValues
150
-     * @param string $timezone
151
-     * @param array  $date_formats
152
-     * @return \EE_Base_Class
153
-     * @throws \EE_Error
154
-     */
155
-    public static function new_instance_from_db(array $fieldValues = array(), $timezone = '', array $date_formats = array())
156
-    {
157
-        return static::new_instance($fieldValues, $timezone, $date_formats, true);
158
-    }
159
-
160
-
161
-    /**
162
-     * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children play nice
163
-     *
164
-     * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
165
-     *                                                         layer of the model's _fields array, (eg, EVT_ID,
166
-     *                                                         TXN_amount, QST_name, etc) and values are their values
167
-     * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
168
-     *                                                         corresponding db model or not.
169
-     * @param string  $timezone                                indicate what timezone you want any datetime fields to
170
-     *                                                         be in when instantiating a EE_Base_Class object.
171
-     * @param array   $date_formats                            An array of date formats to set on construct where first
172
-     *                                                         value is the date_format and second value is the time
173
-     *                                                         format.
174
-     * @throws EE_Error
175
-     */
176
-    protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
177
-    {
178
-        $className = get_class($this);
179
-        do_action("AHEE__{$className}__construct", $this, $fieldValues);
180
-        $model = $this->get_model();
181
-        $model_fields = $model->field_settings(false);
182
-        // ensure $fieldValues is an array
183
-        $fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
184
-        // EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
185
-        // verify client code has not passed any invalid field names
186
-        foreach ($fieldValues as $field_name => $field_value) {
187
-            if ( ! isset($model_fields[$field_name])) {
188
-                throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
189
-                    "event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
190
-            }
191
-        }
192
-        // EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
193
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
194
-        if ( ! empty($date_formats) && is_array($date_formats)) {
195
-            list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
196
-        } else {
197
-            //set default formats for date and time
198
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
199
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
200
-        }
201
-        //if db model is instantiating
202
-        if ($bydb) {
203
-            //client code has indicated these field values are from the database
204
-            foreach ($model_fields as $fieldName => $field) {
205
-                $this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
206
-            }
207
-        } else {
208
-            //we're constructing a brand
209
-            //new instance of the model object. Generally, this means we'll need to do more field validation
210
-            foreach ($model_fields as $fieldName => $field) {
211
-                $this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
212
-            }
213
-        }
214
-        //remember what values were passed to this constructor
215
-        $this->_props_n_values_provided_in_constructor = $fieldValues;
216
-        //remember in entity mapper
217
-        if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
218
-            $model->add_to_entity_map($this);
219
-        }
220
-        //setup all the relations
221
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
222
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
223
-                $this->_model_relations[$relation_name] = null;
224
-            } else {
225
-                $this->_model_relations[$relation_name] = array();
226
-            }
227
-        }
228
-        /**
229
-         * Action done at the end of each model object construction
230
-         *
231
-         * @param EE_Base_Class $this the model object just created
232
-         */
233
-        do_action('AHEE__EE_Base_Class__construct__finished', $this);
234
-    }
235
-
236
-
237
-
238
-    /**
239
-     * Gets whether or not this model object is allowed to persist/be saved to the database.
240
-     *
241
-     * @return boolean
242
-     */
243
-    public function allow_persist()
244
-    {
245
-        return $this->_allow_persist;
246
-    }
247
-
248
-
249
-
250
-    /**
251
-     * Sets whether or not this model object should be allowed to be saved to the DB.
252
-     * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
253
-     * you got new information that somehow made you change your mind.
254
-     *
255
-     * @param boolean $allow_persist
256
-     * @return boolean
257
-     */
258
-    public function set_allow_persist($allow_persist)
259
-    {
260
-        return $this->_allow_persist = $allow_persist;
261
-    }
262
-
263
-
264
-
265
-    /**
266
-     * Gets the field's original value when this object was constructed during this request.
267
-     * This can be helpful when determining if a model object has changed or not
268
-     *
269
-     * @param string $field_name
270
-     * @return mixed|null
271
-     * @throws \EE_Error
272
-     */
273
-    public function get_original($field_name)
274
-    {
275
-        if (isset($this->_props_n_values_provided_in_constructor[$field_name])
276
-            && $field_settings = $this->get_model()->field_settings_for($field_name)
277
-        ) {
278
-            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
279
-        } else {
280
-            return null;
281
-        }
282
-    }
283
-
284
-
285
-
286
-    /**
287
-     * @param EE_Base_Class $obj
288
-     * @return string
289
-     */
290
-    public function get_class($obj)
291
-    {
292
-        return get_class($obj);
293
-    }
294
-
295
-
296
-
297
-    /**
298
-     * Overrides parent because parent expects old models.
299
-     * This also doesn't do any validation, and won't work for serialized arrays
300
-     *
301
-     * @param    string $field_name
302
-     * @param    mixed  $field_value
303
-     * @param bool      $use_default
304
-     * @throws \EE_Error
305
-     */
306
-    public function set($field_name, $field_value, $use_default = false)
307
-    {
308
-        // if not using default and nothing has changed, and object has already been setup (has ID),
309
-        // then don't do anything
310
-        if (
311
-            ! $use_default
312
-            && $this->_fields[$field_name] === $field_value
313
-            && $this->ID()
314
-        ) {
315
-            return;
316
-        }
317
-        $model = $this->get_model();
318
-        $this->_has_changes = true;
319
-        $field_obj = $model->field_settings_for($field_name);
320
-        if ($field_obj instanceof EE_Model_Field_Base) {
321
-            //			if ( method_exists( $field_obj, 'set_timezone' )) {
322
-            if ($field_obj instanceof EE_Datetime_Field) {
323
-                $field_obj->set_timezone($this->_timezone);
324
-                $field_obj->set_date_format($this->_dt_frmt);
325
-                $field_obj->set_time_format($this->_tm_frmt);
326
-            }
327
-            $holder_of_value = $field_obj->prepare_for_set($field_value);
328
-            //should the value be null?
329
-            if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
330
-                $this->_fields[$field_name] = $field_obj->get_default_value();
331
-                /**
332
-                 * To save having to refactor all the models, if a default value is used for a
333
-                 * EE_Datetime_Field, and that value is not null nor is it a DateTime
334
-                 * object.  Then let's do a set again to ensure that it becomes a DateTime
335
-                 * object.
336
-                 *
337
-                 * @since 4.6.10+
338
-                 */
339
-                if (
340
-                    $field_obj instanceof EE_Datetime_Field
341
-                    && $this->_fields[$field_name] !== null
342
-                    && ! $this->_fields[$field_name] instanceof DateTime
343
-                ) {
344
-                    empty($this->_fields[$field_name])
345
-                        ? $this->set($field_name, time())
346
-                        : $this->set($field_name, $this->_fields[$field_name]);
347
-                }
348
-            } else {
349
-                $this->_fields[$field_name] = $holder_of_value;
350
-            }
351
-            //if we're not in the constructor...
352
-            //now check if what we set was a primary key
353
-            if (
354
-                //note: props_n_values_provided_in_constructor is only set at the END of the constructor
355
-                $this->_props_n_values_provided_in_constructor
356
-                && $field_value
357
-                && $field_name === $model->primary_key_name()
358
-            ) {
359
-                //if so, we want all this object's fields to be filled either with
360
-                //what we've explicitly set on this model
361
-                //or what we have in the db
362
-                // echo "setting primary key!";
363
-                $fields_on_model = self::_get_model(get_class($this))->field_settings();
364
-                $obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
365
-                foreach ($fields_on_model as $field_obj) {
366
-                    if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
367
-                         && $field_obj->get_name() !== $field_name
368
-                    ) {
369
-                        $this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
370
-                    }
371
-                }
372
-                //oh this model object has an ID? well make sure its in the entity mapper
373
-                $model->add_to_entity_map($this);
374
-            }
375
-            //let's unset any cache for this field_name from the $_cached_properties property.
376
-            $this->_clear_cached_property($field_name);
377
-        } else {
378
-            throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
379
-                "event_espresso"), $field_name));
380
-        }
381
-    }
382
-
383
-
384
-
385
-    /**
386
-     * This sets the field value on the db column if it exists for the given $column_name or
387
-     * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
388
-     *
389
-     * @see EE_message::get_column_value for related documentation on the necessity of this method.
390
-     * @param string $field_name  Must be the exact column name.
391
-     * @param mixed  $field_value The value to set.
392
-     * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
393
-     * @throws \EE_Error
394
-     */
395
-    public function set_field_or_extra_meta($field_name, $field_value)
396
-    {
397
-        if ($this->get_model()->has_field($field_name)) {
398
-            $this->set($field_name, $field_value);
399
-            return true;
400
-        } else {
401
-            //ensure this object is saved first so that extra meta can be properly related.
402
-            $this->save();
403
-            return $this->update_extra_meta($field_name, $field_value);
404
-        }
405
-    }
406
-
407
-
408
-
409
-    /**
410
-     * This retrieves the value of the db column set on this class or if that's not present
411
-     * it will attempt to retrieve from extra_meta if found.
412
-     * Example Usage:
413
-     * Via EE_Message child class:
414
-     * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
415
-     * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
416
-     * also have additional main fields specific to the messenger.  The system accommodates those extra
417
-     * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
418
-     * value for those extra fields dynamically via the EE_message object.
419
-     *
420
-     * @param  string $field_name expecting the fully qualified field name.
421
-     * @return mixed|null  value for the field if found.  null if not found.
422
-     * @throws \EE_Error
423
-     */
424
-    public function get_field_or_extra_meta($field_name)
425
-    {
426
-        if ($this->get_model()->has_field($field_name)) {
427
-            $column_value = $this->get($field_name);
428
-        } else {
429
-            //This isn't a column in the main table, let's see if it is in the extra meta.
430
-            $column_value = $this->get_extra_meta($field_name, true, null);
431
-        }
432
-        return $column_value;
433
-    }
434
-
435
-
436
-
437
-    /**
438
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
439
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
440
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
441
-     * available to all child classes that may be using the EE_Datetime_Field for a field data type.
442
-     *
443
-     * @access public
444
-     * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
445
-     * @return void
446
-     * @throws \EE_Error
447
-     */
448
-    public function set_timezone($timezone = '')
449
-    {
450
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
451
-        //make sure we clear all cached properties because they won't be relevant now
452
-        $this->_clear_cached_properties();
453
-        //make sure we update field settings and the date for all EE_Datetime_Fields
454
-        $model_fields = $this->get_model()->field_settings(false);
455
-        foreach ($model_fields as $field_name => $field_obj) {
456
-            if ($field_obj instanceof EE_Datetime_Field) {
457
-                $field_obj->set_timezone($this->_timezone);
458
-                if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
459
-                    $this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
460
-                }
461
-            }
462
-        }
463
-    }
464
-
465
-
466
-
467
-    /**
468
-     * This just returns whatever is set for the current timezone.
469
-     *
470
-     * @access public
471
-     * @return string timezone string
472
-     */
473
-    public function get_timezone()
474
-    {
475
-        return $this->_timezone;
476
-    }
477
-
478
-
479
-
480
-    /**
481
-     * This sets the internal date format to what is sent in to be used as the new default for the class
482
-     * internally instead of wp set date format options
483
-     *
484
-     * @since 4.6
485
-     * @param string $format should be a format recognizable by PHP date() functions.
486
-     */
487
-    public function set_date_format($format)
488
-    {
489
-        $this->_dt_frmt = $format;
490
-        //clear cached_properties because they won't be relevant now.
491
-        $this->_clear_cached_properties();
492
-    }
493
-
494
-
495
-
496
-    /**
497
-     * This sets the internal time format string to what is sent in to be used as the new default for the
498
-     * class internally instead of wp set time format options.
499
-     *
500
-     * @since 4.6
501
-     * @param string $format should be a format recognizable by PHP date() functions.
502
-     */
503
-    public function set_time_format($format)
504
-    {
505
-        $this->_tm_frmt = $format;
506
-        //clear cached_properties because they won't be relevant now.
507
-        $this->_clear_cached_properties();
508
-    }
509
-
510
-
511
-
512
-    /**
513
-     * This returns the current internal set format for the date and time formats.
514
-     *
515
-     * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
516
-     *                             where the first value is the date format and the second value is the time format.
517
-     * @return mixed string|array
518
-     */
519
-    public function get_format($full = true)
520
-    {
521
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
522
-    }
523
-
524
-
525
-
526
-    /**
527
-     * cache
528
-     * stores the passed model object on the current model object.
529
-     * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
530
-     *
531
-     * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
532
-     *                                       'Registration' associated with this model object
533
-     * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
534
-     *                                       that could be a payment or a registration)
535
-     * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
536
-     *                                       items which will be stored in an array on this object
537
-     * @throws EE_Error
538
-     * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
539
-     *                  related thing, no array)
540
-     */
541
-    public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
542
-    {
543
-        // its entirely possible that there IS no related object yet in which case there is nothing to cache.
544
-        if ( ! $object_to_cache instanceof EE_Base_Class) {
545
-            return false;
546
-        }
547
-        // also get "how" the object is related, or throw an error
548
-        if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
549
-            throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
550
-                $relationName, get_class($this)));
551
-        }
552
-        // how many things are related ?
553
-        if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
554
-            // if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
555
-            // so for these model objects just set it to be cached
556
-            $this->_model_relations[$relationName] = $object_to_cache;
557
-            $return = true;
558
-        } else {
559
-            // otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
560
-            // eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
561
-            if ( ! is_array($this->_model_relations[$relationName])) {
562
-                // if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
563
-                $this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
564
-                    ? array($this->_model_relations[$relationName]) : array();
565
-            }
566
-            // first check for a cache_id which is normally empty
567
-            if ( ! empty($cache_id)) {
568
-                // if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
569
-                $this->_model_relations[$relationName][$cache_id] = $object_to_cache;
570
-                $return = $cache_id;
571
-            } elseif ($object_to_cache->ID()) {
572
-                // OR the cached object originally came from the db, so let's just use it's PK for an ID
573
-                $this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
574
-                $return = $object_to_cache->ID();
575
-            } else {
576
-                // OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
577
-                $this->_model_relations[$relationName][] = $object_to_cache;
578
-                // move the internal pointer to the end of the array
579
-                end($this->_model_relations[$relationName]);
580
-                // and grab the key so that we can return it
581
-                $return = key($this->_model_relations[$relationName]);
582
-            }
583
-        }
584
-        return $return;
585
-    }
586
-
587
-
588
-
589
-    /**
590
-     * For adding an item to the cached_properties property.
591
-     *
592
-     * @access protected
593
-     * @param string      $fieldname the property item the corresponding value is for.
594
-     * @param mixed       $value     The value we are caching.
595
-     * @param string|null $cache_type
596
-     * @return void
597
-     * @throws \EE_Error
598
-     */
599
-    protected function _set_cached_property($fieldname, $value, $cache_type = null)
600
-    {
601
-        //first make sure this property exists
602
-        $this->get_model()->field_settings_for($fieldname);
603
-        $cache_type = empty($cache_type) ? 'standard' : $cache_type;
604
-        $this->_cached_properties[$fieldname][$cache_type] = $value;
605
-    }
606
-
607
-
608
-
609
-    /**
610
-     * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
611
-     * This also SETS the cache if we return the actual property!
612
-     *
613
-     * @param string $fieldname        the name of the property we're trying to retrieve
614
-     * @param bool   $pretty
615
-     * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
616
-     *                                 (in cases where the same property may be used for different outputs
617
-     *                                 - i.e. datetime, money etc.)
618
-     *                                 It can also accept certain pre-defined "schema" strings
619
-     *                                 to define how to output the property.
620
-     *                                 see the field's prepare_for_pretty_echoing for what strings can be used
621
-     * @return mixed                   whatever the value for the property is we're retrieving
622
-     * @throws \EE_Error
623
-     */
624
-    protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
625
-    {
626
-        //verify the field exists
627
-        $model = $this->get_model();
628
-        $model->field_settings_for($fieldname);
629
-        $cache_type = $pretty ? 'pretty' : 'standard';
630
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
631
-        if (isset($this->_cached_properties[$fieldname][$cache_type])) {
632
-            return $this->_cached_properties[$fieldname][$cache_type];
633
-        }
634
-        $value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
635
-        $this->_set_cached_property($fieldname, $value, $cache_type);
636
-        return $value;
637
-    }
638
-
639
-
640
-
641
-    /**
642
-     * If the cache didn't fetch the needed item, this fetches it.
643
-     * @param string $fieldname
644
-     * @param bool $pretty
645
-     * @param string $extra_cache_ref
646
-     * @return mixed
647
-     */
648
-    protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
649
-    {
650
-        $field_obj = $this->get_model()->field_settings_for($fieldname);
651
-        // If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
652
-        if ($field_obj instanceof EE_Datetime_Field) {
653
-            $this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
654
-        }
655
-        if ( ! isset($this->_fields[$fieldname])) {
656
-            $this->_fields[$fieldname] = null;
657
-        }
658
-        $value = $pretty
659
-            ? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
660
-            : $field_obj->prepare_for_get($this->_fields[$fieldname]);
661
-        return $value;
662
-    }
663
-
664
-
665
-
666
-    /**
667
-     * set timezone, formats, and output for EE_Datetime_Field objects
668
-     *
669
-     * @param \EE_Datetime_Field $datetime_field
670
-     * @param bool               $pretty
671
-     * @param null $date_or_time
672
-     * @return void
673
-     * @throws \EE_Error
674
-     */
675
-    protected function _prepare_datetime_field(
676
-        EE_Datetime_Field $datetime_field,
677
-        $pretty = false,
678
-        $date_or_time = null
679
-    ) {
680
-        $datetime_field->set_timezone($this->_timezone);
681
-        $datetime_field->set_date_format($this->_dt_frmt, $pretty);
682
-        $datetime_field->set_time_format($this->_tm_frmt, $pretty);
683
-        //set the output returned
684
-        switch ($date_or_time) {
685
-            case 'D' :
686
-                $datetime_field->set_date_time_output('date');
687
-                break;
688
-            case 'T' :
689
-                $datetime_field->set_date_time_output('time');
690
-                break;
691
-            default :
692
-                $datetime_field->set_date_time_output();
693
-        }
694
-    }
695
-
696
-
697
-
698
-    /**
699
-     * This just takes care of clearing out the cached_properties
700
-     *
701
-     * @return void
702
-     */
703
-    protected function _clear_cached_properties()
704
-    {
705
-        $this->_cached_properties = array();
706
-    }
707
-
708
-
709
-
710
-    /**
711
-     * This just clears out ONE property if it exists in the cache
712
-     *
713
-     * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
714
-     * @return void
715
-     */
716
-    protected function _clear_cached_property($property_name)
717
-    {
718
-        if (isset($this->_cached_properties[$property_name])) {
719
-            unset($this->_cached_properties[$property_name]);
720
-        }
721
-    }
722
-
723
-
724
-
725
-    /**
726
-     * Ensures that this related thing is a model object.
727
-     *
728
-     * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
729
-     * @param string $model_name   name of the related thing, eg 'Attendee',
730
-     * @return EE_Base_Class
731
-     * @throws \EE_Error
732
-     */
733
-    protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
734
-    {
735
-        $other_model_instance = self::_get_model_instance_with_name(
736
-            self::_get_model_classname($model_name),
737
-            $this->_timezone
738
-        );
739
-        return $other_model_instance->ensure_is_obj($object_or_id);
740
-    }
741
-
742
-
743
-
744
-    /**
745
-     * Forgets the cached model of the given relation Name. So the next time we request it,
746
-     * we will fetch it again from the database. (Handy if you know it's changed somehow).
747
-     * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
748
-     * then only remove that one object from our cached array. Otherwise, clear the entire list
749
-     *
750
-     * @param string $relationName                         one of the keys in the _model_relations array on the model.
751
-     *                                                     Eg 'Registration'
752
-     * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
753
-     *                                                     if you intend to use $clear_all = TRUE, or the relation only
754
-     *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
755
-     * @param bool   $clear_all                            This flags clearing the entire cache relation property if
756
-     *                                                     this is HasMany or HABTM.
757
-     * @throws EE_Error
758
-     * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
759
-     *                       relation from all
760
-     */
761
-    public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
762
-    {
763
-        $relationship_to_model = $this->get_model()->related_settings_for($relationName);
764
-        $index_in_cache = '';
765
-        if ( ! $relationship_to_model) {
766
-            throw new EE_Error(
767
-                sprintf(
768
-                    __("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
769
-                    $relationName,
770
-                    get_class($this)
771
-                )
772
-            );
773
-        }
774
-        if ($clear_all) {
775
-            $obj_removed = true;
776
-            $this->_model_relations[$relationName] = null;
777
-        } elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
778
-            $obj_removed = $this->_model_relations[$relationName];
779
-            $this->_model_relations[$relationName] = null;
780
-        } else {
781
-            if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
782
-                && $object_to_remove_or_index_into_array->ID()
783
-            ) {
784
-                $index_in_cache = $object_to_remove_or_index_into_array->ID();
785
-                if (is_array($this->_model_relations[$relationName])
786
-                    && ! isset($this->_model_relations[$relationName][$index_in_cache])
787
-                ) {
788
-                    $index_found_at = null;
789
-                    //find this object in the array even though it has a different key
790
-                    foreach ($this->_model_relations[$relationName] as $index => $obj) {
791
-                        if (
792
-                            $obj instanceof EE_Base_Class
793
-                            && (
794
-                                $obj == $object_to_remove_or_index_into_array
795
-                                || $obj->ID() === $object_to_remove_or_index_into_array->ID()
796
-                            )
797
-                        ) {
798
-                            $index_found_at = $index;
799
-                            break;
800
-                        }
801
-                    }
802
-                    if ($index_found_at) {
803
-                        $index_in_cache = $index_found_at;
804
-                    } else {
805
-                        //it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
806
-                        //if it wasn't in it to begin with. So we're done
807
-                        return $object_to_remove_or_index_into_array;
808
-                    }
809
-                }
810
-            } elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
811
-                //so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
812
-                foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
813
-                    if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
814
-                        $index_in_cache = $index;
815
-                    }
816
-                }
817
-            } else {
818
-                $index_in_cache = $object_to_remove_or_index_into_array;
819
-            }
820
-            //supposedly we've found it. But it could just be that the client code
821
-            //provided a bad index/object
822
-            if (
823
-            isset(
824
-                $this->_model_relations[$relationName],
825
-                $this->_model_relations[$relationName][$index_in_cache]
826
-            )
827
-            ) {
828
-                $obj_removed = $this->_model_relations[$relationName][$index_in_cache];
829
-                unset($this->_model_relations[$relationName][$index_in_cache]);
830
-            } else {
831
-                //that thing was never cached anyways.
832
-                $obj_removed = null;
833
-            }
834
-        }
835
-        return $obj_removed;
836
-    }
837
-
838
-
839
-
840
-    /**
841
-     * update_cache_after_object_save
842
-     * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
843
-     * obtained after being saved to the db
844
-     *
845
-     * @param string         $relationName       - the type of object that is cached
846
-     * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
847
-     * @param string         $current_cache_id   - the ID that was used when originally caching the object
848
-     * @return boolean TRUE on success, FALSE on fail
849
-     * @throws \EE_Error
850
-     */
851
-    public function update_cache_after_object_save(
852
-        $relationName,
853
-        EE_Base_Class $newly_saved_object,
854
-        $current_cache_id = ''
855
-    ) {
856
-        // verify that incoming object is of the correct type
857
-        $obj_class = 'EE_' . $relationName;
858
-        if ($newly_saved_object instanceof $obj_class) {
859
-            /* @type EE_Base_Class $newly_saved_object */
860
-            // now get the type of relation
861
-            $relationship_to_model = $this->get_model()->related_settings_for($relationName);
862
-            // if this is a 1:1 relationship
863
-            if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
864
-                // then just replace the cached object with the newly saved object
865
-                $this->_model_relations[$relationName] = $newly_saved_object;
866
-                return true;
867
-                // or if it's some kind of sordid feral polyamorous relationship...
868
-            } elseif (is_array($this->_model_relations[$relationName])
869
-                      && isset($this->_model_relations[$relationName][$current_cache_id])
870
-            ) {
871
-                // then remove the current cached item
872
-                unset($this->_model_relations[$relationName][$current_cache_id]);
873
-                // and cache the newly saved object using it's new ID
874
-                $this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
875
-                return true;
876
-            }
877
-        }
878
-        return false;
879
-    }
880
-
881
-
882
-
883
-    /**
884
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
885
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
886
-     *
887
-     * @param string $relationName
888
-     * @return EE_Base_Class
889
-     */
890
-    public function get_one_from_cache($relationName)
891
-    {
892
-        $cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
893
-            : null;
894
-        if (is_array($cached_array_or_object)) {
895
-            return array_shift($cached_array_or_object);
896
-        } else {
897
-            return $cached_array_or_object;
898
-        }
899
-    }
900
-
901
-
902
-
903
-    /**
904
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
905
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
906
-     *
907
-     * @param string $relationName
908
-     * @throws \EE_Error
909
-     * @return EE_Base_Class[] NOT necessarily indexed by primary keys
910
-     */
911
-    public function get_all_from_cache($relationName)
912
-    {
913
-        $objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
914
-        // if the result is not an array, but exists, make it an array
915
-        $objects = is_array($objects) ? $objects : array($objects);
916
-        //bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
917
-        //basically, if this model object was stored in the session, and these cached model objects
918
-        //already have IDs, let's make sure they're in their model's entity mapper
919
-        //otherwise we will have duplicates next time we call
920
-        // EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
921
-        $model = EE_Registry::instance()->load_model($relationName);
922
-        foreach ($objects as $model_object) {
923
-            if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
924
-                //ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
925
-                if ($model_object->ID()) {
926
-                    $model->add_to_entity_map($model_object);
927
-                }
928
-            } else {
929
-                throw new EE_Error(
930
-                    sprintf(
931
-                        __(
932
-                            'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
933
-                            'event_espresso'
934
-                        ),
935
-                        $relationName,
936
-                        gettype($model_object)
937
-                    )
938
-                );
939
-            }
940
-        }
941
-        return $objects;
942
-    }
943
-
944
-
945
-
946
-    /**
947
-     * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
948
-     * matching the given query conditions.
949
-     *
950
-     * @param null  $field_to_order_by  What field is being used as the reference point.
951
-     * @param int   $limit              How many objects to return.
952
-     * @param array $query_params       Any additional conditions on the query.
953
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
954
-     *                                  you can indicate just the columns you want returned
955
-     * @return array|EE_Base_Class[]
956
-     * @throws \EE_Error
957
-     */
958
-    public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
959
-    {
960
-        $model = $this->get_model();
961
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
962
-            ? $model->get_primary_key_field()->get_name()
963
-            : $field_to_order_by;
964
-        $current_value = ! empty($field) ? $this->get($field) : null;
965
-        if (empty($field) || empty($current_value)) {
966
-            return array();
967
-        }
968
-        return $model->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
969
-    }
970
-
971
-
972
-
973
-    /**
974
-     * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
975
-     * matching the given query conditions.
976
-     *
977
-     * @param null  $field_to_order_by  What field is being used as the reference point.
978
-     * @param int   $limit              How many objects to return.
979
-     * @param array $query_params       Any additional conditions on the query.
980
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
981
-     *                                  you can indicate just the columns you want returned
982
-     * @return array|EE_Base_Class[]
983
-     * @throws \EE_Error
984
-     */
985
-    public function previous_x(
986
-        $field_to_order_by = null,
987
-        $limit = 1,
988
-        $query_params = array(),
989
-        $columns_to_select = null
990
-    ) {
991
-        $model = $this->get_model();
992
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
993
-            ? $model->get_primary_key_field()->get_name()
994
-            : $field_to_order_by;
995
-        $current_value = ! empty($field) ? $this->get($field) : null;
996
-        if (empty($field) || empty($current_value)) {
997
-            return array();
998
-        }
999
-        return $model->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
1000
-    }
1001
-
1002
-
1003
-
1004
-    /**
1005
-     * Returns the next EE_Base_Class object in sequence from this object as found in the database
1006
-     * matching the given query conditions.
1007
-     *
1008
-     * @param null  $field_to_order_by  What field is being used as the reference point.
1009
-     * @param array $query_params       Any additional conditions on the query.
1010
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1011
-     *                                  you can indicate just the columns you want returned
1012
-     * @return array|EE_Base_Class
1013
-     * @throws \EE_Error
1014
-     */
1015
-    public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1016
-    {
1017
-        $model = $this->get_model();
1018
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
1019
-            ? $model->get_primary_key_field()->get_name()
1020
-            : $field_to_order_by;
1021
-        $current_value = ! empty($field) ? $this->get($field) : null;
1022
-        if (empty($field) || empty($current_value)) {
1023
-            return array();
1024
-        }
1025
-        return $model->next($current_value, $field, $query_params, $columns_to_select);
1026
-    }
1027
-
1028
-
1029
-
1030
-    /**
1031
-     * Returns the previous EE_Base_Class object in sequence from this object as found in the database
1032
-     * matching the given query conditions.
1033
-     *
1034
-     * @param null  $field_to_order_by  What field is being used as the reference point.
1035
-     * @param array $query_params       Any additional conditions on the query.
1036
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1037
-     *                                  you can indicate just the column you want returned
1038
-     * @return array|EE_Base_Class
1039
-     * @throws \EE_Error
1040
-     */
1041
-    public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1042
-    {
1043
-        $model = $this->get_model();
1044
-        $field = empty($field_to_order_by) && $model->has_primary_key_field()
1045
-            ? $model->get_primary_key_field()->get_name()
1046
-            : $field_to_order_by;
1047
-        $current_value = ! empty($field) ? $this->get($field) : null;
1048
-        if (empty($field) || empty($current_value)) {
1049
-            return array();
1050
-        }
1051
-        return $model->previous($current_value, $field, $query_params, $columns_to_select);
1052
-    }
1053
-
1054
-
1055
-
1056
-    /**
1057
-     * Overrides parent because parent expects old models.
1058
-     * This also doesn't do any validation, and won't work for serialized arrays
1059
-     *
1060
-     * @param string $field_name
1061
-     * @param mixed  $field_value_from_db
1062
-     * @throws \EE_Error
1063
-     */
1064
-    public function set_from_db($field_name, $field_value_from_db)
1065
-    {
1066
-        $field_obj = $this->get_model()->field_settings_for($field_name);
1067
-        if ($field_obj instanceof EE_Model_Field_Base) {
1068
-            //you would think the DB has no NULLs for non-null label fields right? wrong!
1069
-            //eg, a CPT model object could have an entry in the posts table, but no
1070
-            //entry in the meta table. Meaning that all its columns in the meta table
1071
-            //are null! yikes! so when we find one like that, use defaults for its meta columns
1072
-            if ($field_value_from_db === null) {
1073
-                if ($field_obj->is_nullable()) {
1074
-                    //if the field allows nulls, then let it be null
1075
-                    $field_value = null;
1076
-                } else {
1077
-                    $field_value = $field_obj->get_default_value();
1078
-                }
1079
-            } else {
1080
-                $field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1081
-            }
1082
-            $this->_fields[$field_name] = $field_value;
1083
-            $this->_clear_cached_property($field_name);
1084
-        }
1085
-    }
1086
-
1087
-
1088
-
1089
-    /**
1090
-     * verifies that the specified field is of the correct type
1091
-     *
1092
-     * @param string $field_name
1093
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1094
-     *                                (in cases where the same property may be used for different outputs
1095
-     *                                - i.e. datetime, money etc.)
1096
-     * @return mixed
1097
-     * @throws \EE_Error
1098
-     */
1099
-    public function get($field_name, $extra_cache_ref = null)
1100
-    {
1101
-        return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1102
-    }
1103
-
1104
-
1105
-
1106
-    /**
1107
-     * This method simply returns the RAW unprocessed value for the given property in this class
1108
-     *
1109
-     * @param  string $field_name A valid fieldname
1110
-     * @return mixed              Whatever the raw value stored on the property is.
1111
-     * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1112
-     */
1113
-    public function get_raw($field_name)
1114
-    {
1115
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1116
-        return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1117
-            ? $this->_fields[$field_name]->format('U')
1118
-            : $this->_fields[$field_name];
1119
-    }
1120
-
1121
-
1122
-
1123
-    /**
1124
-     * This is used to return the internal DateTime object used for a field that is a
1125
-     * EE_Datetime_Field.
1126
-     *
1127
-     * @param string $field_name               The field name retrieving the DateTime object.
1128
-     * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1129
-     * @throws \EE_Error
1130
-     *                                         an error is set and false returned.  If the field IS an
1131
-     *                                         EE_Datetime_Field and but the field value is null, then
1132
-     *                                         just null is returned (because that indicates that likely
1133
-     *                                         this field is nullable).
1134
-     */
1135
-    public function get_DateTime_object($field_name)
1136
-    {
1137
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1138
-        if ( ! $field_settings instanceof EE_Datetime_Field) {
1139
-            EE_Error::add_error(
1140
-                sprintf(
1141
-                    __(
1142
-                        'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1143
-                        'event_espresso'
1144
-                    ),
1145
-                    $field_name
1146
-                ),
1147
-                __FILE__,
1148
-                __FUNCTION__,
1149
-                __LINE__
1150
-            );
1151
-            return false;
1152
-        }
1153
-        return $this->_fields[$field_name];
1154
-    }
1155
-
1156
-
1157
-
1158
-    /**
1159
-     * To be used in template to immediately echo out the value, and format it for output.
1160
-     * Eg, should call stripslashes and whatnot before echoing
1161
-     *
1162
-     * @param string $field_name      the name of the field as it appears in the DB
1163
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1164
-     *                                (in cases where the same property may be used for different outputs
1165
-     *                                - i.e. datetime, money etc.)
1166
-     * @return void
1167
-     * @throws \EE_Error
1168
-     */
1169
-    public function e($field_name, $extra_cache_ref = null)
1170
-    {
1171
-        echo $this->get_pretty($field_name, $extra_cache_ref);
1172
-    }
1173
-
1174
-
1175
-
1176
-    /**
1177
-     * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1178
-     * can be easily used as the value of form input.
1179
-     *
1180
-     * @param string $field_name
1181
-     * @return void
1182
-     * @throws \EE_Error
1183
-     */
1184
-    public function f($field_name)
1185
-    {
1186
-        $this->e($field_name, 'form_input');
1187
-    }
1188
-
1189
-
1190
-
1191
-    /**
1192
-     * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1193
-     * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1194
-     * to see what options are available.
1195
-     * @param string $field_name
1196
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1197
-     *                                (in cases where the same property may be used for different outputs
1198
-     *                                - i.e. datetime, money etc.)
1199
-     * @return mixed
1200
-     * @throws \EE_Error
1201
-     */
1202
-    public function get_pretty($field_name, $extra_cache_ref = null)
1203
-    {
1204
-        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1205
-    }
1206
-
1207
-
1208
-
1209
-    /**
1210
-     * This simply returns the datetime for the given field name
1211
-     * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1212
-     * (and the equivalent e_date, e_time, e_datetime).
1213
-     *
1214
-     * @access   protected
1215
-     * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1216
-     * @param string   $dt_frmt      valid datetime format used for date
1217
-     *                               (if '' then we just use the default on the field,
1218
-     *                               if NULL we use the last-used format)
1219
-     * @param string   $tm_frmt      Same as above except this is for time format
1220
-     * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1221
-     * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1222
-     * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1223
-     *                               if field is not a valid dtt field, or void if echoing
1224
-     * @throws \EE_Error
1225
-     */
1226
-    protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1227
-    {
1228
-        // clear cached property
1229
-        $this->_clear_cached_property($field_name);
1230
-        //reset format properties because they are used in get()
1231
-        $this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1232
-        $this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1233
-        if ($echo) {
1234
-            $this->e($field_name, $date_or_time);
1235
-            return '';
1236
-        }
1237
-        return $this->get($field_name, $date_or_time);
1238
-    }
1239
-
1240
-
1241
-
1242
-    /**
1243
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1244
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1245
-     * other echoes the pretty value for dtt)
1246
-     *
1247
-     * @param  string $field_name name of model object datetime field holding the value
1248
-     * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1249
-     * @return string            datetime value formatted
1250
-     * @throws \EE_Error
1251
-     */
1252
-    public function get_date($field_name, $format = '')
1253
-    {
1254
-        return $this->_get_datetime($field_name, $format, null, 'D');
1255
-    }
1256
-
1257
-
1258
-
1259
-    /**
1260
-     * @param      $field_name
1261
-     * @param string $format
1262
-     * @throws \EE_Error
1263
-     */
1264
-    public function e_date($field_name, $format = '')
1265
-    {
1266
-        $this->_get_datetime($field_name, $format, null, 'D', true);
1267
-    }
1268
-
1269
-
1270
-
1271
-    /**
1272
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1273
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1274
-     * other echoes the pretty value for dtt)
1275
-     *
1276
-     * @param  string $field_name name of model object datetime field holding the value
1277
-     * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1278
-     * @return string             datetime value formatted
1279
-     * @throws \EE_Error
1280
-     */
1281
-    public function get_time($field_name, $format = '')
1282
-    {
1283
-        return $this->_get_datetime($field_name, null, $format, 'T');
1284
-    }
1285
-
1286
-
1287
-
1288
-    /**
1289
-     * @param      $field_name
1290
-     * @param string $format
1291
-     * @throws \EE_Error
1292
-     */
1293
-    public function e_time($field_name, $format = '')
1294
-    {
1295
-        $this->_get_datetime($field_name, null, $format, 'T', true);
1296
-    }
1297
-
1298
-
1299
-
1300
-    /**
1301
-     * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1302
-     * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1303
-     * other echoes the pretty value for dtt)
1304
-     *
1305
-     * @param  string $field_name name of model object datetime field holding the value
1306
-     * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1307
-     * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1308
-     * @return string             datetime value formatted
1309
-     * @throws \EE_Error
1310
-     */
1311
-    public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1312
-    {
1313
-        return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1314
-    }
1315
-
1316
-
1317
-
1318
-    /**
1319
-     * @param string $field_name
1320
-     * @param string $dt_frmt
1321
-     * @param string $tm_frmt
1322
-     * @throws \EE_Error
1323
-     */
1324
-    public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1325
-    {
1326
-        $this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1327
-    }
1328
-
1329
-
1330
-
1331
-    /**
1332
-     * Get the i8ln value for a date using the WordPress @see date_i18n function.
1333
-     *
1334
-     * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1335
-     * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1336
-     *                           on the object will be used.
1337
-     * @return string Date and time string in set locale or false if no field exists for the given
1338
-     * @throws \EE_Error
1339
-     *                           field name.
1340
-     */
1341
-    public function get_i18n_datetime($field_name, $format = '')
1342
-    {
1343
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1344
-        return date_i18n(
1345
-            $format,
1346
-            EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1347
-        );
1348
-    }
1349
-
1350
-
1351
-
1352
-    /**
1353
-     * This method validates whether the given field name is a valid field on the model object as well as it is of a
1354
-     * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1355
-     * thrown.
1356
-     *
1357
-     * @param  string $field_name The field name being checked
1358
-     * @throws EE_Error
1359
-     * @return EE_Datetime_Field
1360
-     */
1361
-    protected function _get_dtt_field_settings($field_name)
1362
-    {
1363
-        $field = $this->get_model()->field_settings_for($field_name);
1364
-        //check if field is dtt
1365
-        if ($field instanceof EE_Datetime_Field) {
1366
-            return $field;
1367
-        } else {
1368
-            throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1369
-                'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1370
-        }
1371
-    }
1372
-
1373
-
1374
-
1375
-
1376
-    /**
1377
-     * NOTE ABOUT BELOW:
1378
-     * These convenience date and time setters are for setting date and time independently.  In other words you might
1379
-     * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1380
-     * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1381
-     * method and make sure you send the entire datetime value for setting.
1382
-     */
1383
-    /**
1384
-     * sets the time on a datetime property
1385
-     *
1386
-     * @access protected
1387
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1388
-     * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1389
-     * @throws \EE_Error
1390
-     */
1391
-    protected function _set_time_for($time, $fieldname)
1392
-    {
1393
-        $this->_set_date_time('T', $time, $fieldname);
1394
-    }
1395
-
1396
-
1397
-
1398
-    /**
1399
-     * sets the date on a datetime property
1400
-     *
1401
-     * @access protected
1402
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1403
-     * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1404
-     * @throws \EE_Error
1405
-     */
1406
-    protected function _set_date_for($date, $fieldname)
1407
-    {
1408
-        $this->_set_date_time('D', $date, $fieldname);
1409
-    }
1410
-
1411
-
1412
-
1413
-    /**
1414
-     * This takes care of setting a date or time independently on a given model object property. This method also
1415
-     * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1416
-     *
1417
-     * @access protected
1418
-     * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1419
-     * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1420
-     * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1421
-     *                                        EE_Datetime_Field property)
1422
-     * @throws \EE_Error
1423
-     */
1424
-    protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1425
-    {
1426
-        $field = $this->_get_dtt_field_settings($fieldname);
1427
-        $field->set_timezone($this->_timezone);
1428
-        $field->set_date_format($this->_dt_frmt);
1429
-        $field->set_time_format($this->_tm_frmt);
1430
-        switch ($what) {
1431
-            case 'T' :
1432
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1433
-                    $datetime_value,
1434
-                    $this->_fields[$fieldname]
1435
-                );
1436
-                break;
1437
-            case 'D' :
1438
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1439
-                    $datetime_value,
1440
-                    $this->_fields[$fieldname]
1441
-                );
1442
-                break;
1443
-            case 'B' :
1444
-                $this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1445
-                break;
1446
-        }
1447
-        $this->_clear_cached_property($fieldname);
1448
-    }
1449
-
1450
-
1451
-
1452
-    /**
1453
-     * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1454
-     * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1455
-     * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1456
-     * that could lead to some unexpected results!
1457
-     *
1458
-     * @access public
1459
-     * @param string               $field_name This is the name of the field on the object that contains the date/time
1460
-     *                                         value being returned.
1461
-     * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1462
-     * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1463
-     * @param string               $prepend    You can include something to prepend on the timestamp
1464
-     * @param string               $append     You can include something to append on the timestamp
1465
-     * @throws EE_Error
1466
-     * @return string timestamp
1467
-     */
1468
-    public function display_in_my_timezone(
1469
-        $field_name,
1470
-        $callback = 'get_datetime',
1471
-        $args = null,
1472
-        $prepend = '',
1473
-        $append = ''
1474
-    ) {
1475
-        $timezone = EEH_DTT_Helper::get_timezone();
1476
-        if ($timezone === $this->_timezone) {
1477
-            return '';
1478
-        }
1479
-        $original_timezone = $this->_timezone;
1480
-        $this->set_timezone($timezone);
1481
-        $fn = (array)$field_name;
1482
-        $args = array_merge($fn, (array)$args);
1483
-        if ( ! method_exists($this, $callback)) {
1484
-            throw new EE_Error(
1485
-                sprintf(
1486
-                    __(
1487
-                        'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1488
-                        'event_espresso'
1489
-                    ),
1490
-                    $callback
1491
-                )
1492
-            );
1493
-        }
1494
-        $args = (array)$args;
1495
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1496
-        $this->set_timezone($original_timezone);
1497
-        return $return;
1498
-    }
1499
-
1500
-
1501
-
1502
-    /**
1503
-     * Deletes this model object.
1504
-     * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1505
-     * override
1506
-     * `EE_Base_Class::_delete` NOT this class.
1507
-     *
1508
-     * @return boolean | int
1509
-     * @throws \EE_Error
1510
-     */
1511
-    public function delete()
1512
-    {
1513
-        /**
1514
-         * Called just before the `EE_Base_Class::_delete` method call.
1515
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1516
-         * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1517
-         * soft deletes (trash) the object and does not permanently delete it.
1518
-         *
1519
-         * @param EE_Base_Class $model_object about to be 'deleted'
1520
-         */
1521
-        do_action('AHEE__EE_Base_Class__delete__before', $this);
1522
-        $result = $this->_delete();
1523
-        /**
1524
-         * Called just after the `EE_Base_Class::_delete` method call.
1525
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1526
-         * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1527
-         * soft deletes (trash) the object and does not permanently delete it.
1528
-         *
1529
-         * @param EE_Base_Class $model_object that was just 'deleted'
1530
-         * @param boolean       $result
1531
-         */
1532
-        do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1533
-        return $result;
1534
-    }
1535
-
1536
-
1537
-
1538
-    /**
1539
-     * Calls the specific delete method for the instantiated class.
1540
-     * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1541
-     * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1542
-     * `EE_Base_Class::delete`
1543
-     *
1544
-     * @return bool|int
1545
-     * @throws \EE_Error
1546
-     */
1547
-    protected function _delete()
1548
-    {
1549
-        return $this->delete_permanently();
1550
-    }
1551
-
1552
-
1553
-
1554
-    /**
1555
-     * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1556
-     * error)
1557
-     *
1558
-     * @return bool | int
1559
-     * @throws \EE_Error
1560
-     */
1561
-    public function delete_permanently()
1562
-    {
1563
-        /**
1564
-         * Called just before HARD deleting a model object
1565
-         *
1566
-         * @param EE_Base_Class $model_object about to be 'deleted'
1567
-         */
1568
-        do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1569
-        $model = $this->get_model();
1570
-        $result = $model->delete_permanently_by_ID($this->ID());
1571
-        $this->refresh_cache_of_related_objects();
1572
-        /**
1573
-         * Called just after HARD deleting a model object
1574
-         *
1575
-         * @param EE_Base_Class $model_object that was just 'deleted'
1576
-         * @param boolean       $result
1577
-         */
1578
-        do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1579
-        return $result;
1580
-    }
1581
-
1582
-
1583
-
1584
-    /**
1585
-     * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1586
-     * related model objects
1587
-     *
1588
-     * @throws \EE_Error
1589
-     */
1590
-    public function refresh_cache_of_related_objects()
1591
-    {
1592
-        $model = $this->get_model();
1593
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1594
-            if ( ! empty($this->_model_relations[$relation_name])) {
1595
-                $related_objects = $this->_model_relations[$relation_name];
1596
-                if ($relation_obj instanceof EE_Belongs_To_Relation) {
1597
-                    //this relation only stores a single model object, not an array
1598
-                    //but let's make it consistent
1599
-                    $related_objects = array($related_objects);
1600
-                }
1601
-                foreach ($related_objects as $related_object) {
1602
-                    //only refresh their cache if they're in memory
1603
-                    if ($related_object instanceof EE_Base_Class) {
1604
-                        $related_object->clear_cache($model->get_this_model_name(), $this);
1605
-                    }
1606
-                }
1607
-            }
1608
-        }
1609
-    }
1610
-
1611
-
1612
-
1613
-    /**
1614
-     *        Saves this object to the database. An array may be supplied to set some values on this
1615
-     * object just before saving.
1616
-     *
1617
-     * @access public
1618
-     * @param array $set_cols_n_values keys are field names, values are their new values,
1619
-     *                                 if provided during the save() method (often client code will change the fields'
1620
-     *                                 values before calling save)
1621
-     * @throws \EE_Error
1622
-     * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1623
-     *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1624
-     */
1625
-    public function save($set_cols_n_values = array())
1626
-    {
1627
-        $model = $this->get_model();
1628
-        /**
1629
-         * Filters the fields we're about to save on the model object
1630
-         *
1631
-         * @param array         $set_cols_n_values
1632
-         * @param EE_Base_Class $model_object
1633
-         */
1634
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1635
-            $this);
1636
-        //set attributes as provided in $set_cols_n_values
1637
-        foreach ($set_cols_n_values as $column => $value) {
1638
-            $this->set($column, $value);
1639
-        }
1640
-        // no changes ? then don't do anything
1641
-        if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1642
-            return 0;
1643
-        }
1644
-        /**
1645
-         * Saving a model object.
1646
-         * Before we perform a save, this action is fired.
1647
-         *
1648
-         * @param EE_Base_Class $model_object the model object about to be saved.
1649
-         */
1650
-        do_action('AHEE__EE_Base_Class__save__begin', $this);
1651
-        if ( ! $this->allow_persist()) {
1652
-            return 0;
1653
-        }
1654
-        //now get current attribute values
1655
-        $save_cols_n_values = $this->_fields;
1656
-        //if the object already has an ID, update it. Otherwise, insert it
1657
-        //also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1658
-        $old_assumption_concerning_value_preparation = $model
1659
-                                                            ->get_assumption_concerning_values_already_prepared_by_model_object();
1660
-        $model->assume_values_already_prepared_by_model_object(true);
1661
-        //does this model have an autoincrement PK?
1662
-        if ($model->has_primary_key_field()) {
1663
-            if ($model->get_primary_key_field()->is_auto_increment()) {
1664
-                //ok check if it's set, if so: update; if not, insert
1665
-                if ( ! empty($save_cols_n_values[$model->primary_key_name()])) {
1666
-                    $results = $model->update_by_ID($save_cols_n_values, $this->ID());
1667
-                } else {
1668
-                    unset($save_cols_n_values[$model->primary_key_name()]);
1669
-                    $results = $model->insert($save_cols_n_values);
1670
-                    if ($results) {
1671
-                        //if successful, set the primary key
1672
-                        //but don't use the normal SET method, because it will check if
1673
-                        //an item with the same ID exists in the mapper & db, then
1674
-                        //will find it in the db (because we just added it) and THAT object
1675
-                        //will get added to the mapper before we can add this one!
1676
-                        //but if we just avoid using the SET method, all that headache can be avoided
1677
-                        $pk_field_name = $model->primary_key_name();
1678
-                        $this->_fields[$pk_field_name] = $results;
1679
-                        $this->_clear_cached_property($pk_field_name);
1680
-                        $model->add_to_entity_map($this);
1681
-                        $this->_update_cached_related_model_objs_fks();
1682
-                    }
1683
-                }
1684
-            } else {//PK is NOT auto-increment
1685
-                //so check if one like it already exists in the db
1686
-                if ($model->exists_by_ID($this->ID())) {
1687
-                    if (WP_DEBUG && ! $this->in_entity_map()) {
1688
-                        throw new EE_Error(
1689
-                            sprintf(
1690
-                                __('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1691
-                                    'event_espresso'),
1692
-                                get_class($this),
1693
-                                get_class($model) . '::instance()->add_to_entity_map()',
1694
-                                get_class($model) . '::instance()->get_one_by_ID()',
1695
-                                '<br />'
1696
-                            )
1697
-                        );
1698
-                    }
1699
-                    $results = $model->update_by_ID($save_cols_n_values, $this->ID());
1700
-                } else {
1701
-                    $results = $model->insert($save_cols_n_values);
1702
-                    $this->_update_cached_related_model_objs_fks();
1703
-                }
1704
-            }
1705
-        } else {//there is NO primary key
1706
-            $already_in_db = false;
1707
-            foreach ($model->unique_indexes() as $index) {
1708
-                $uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1709
-                if ($model->exists(array($uniqueness_where_params))) {
1710
-                    $already_in_db = true;
1711
-                }
1712
-            }
1713
-            if ($already_in_db) {
1714
-                $combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1715
-                    $model->get_combined_primary_key_fields());
1716
-                $results = $model->update($save_cols_n_values, $combined_pk_fields_n_values);
1717
-            } else {
1718
-                $results = $model->insert($save_cols_n_values);
1719
-            }
1720
-        }
1721
-        //restore the old assumption about values being prepared by the model object
1722
-        $model
1723
-             ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1724
-        /**
1725
-         * After saving the model object this action is called
1726
-         *
1727
-         * @param EE_Base_Class $model_object which was just saved
1728
-         * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1729
-         *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1730
-         */
1731
-        do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1732
-        $this->_has_changes = false;
1733
-        return $results;
1734
-    }
1735
-
1736
-
1737
-
1738
-    /**
1739
-     * Updates the foreign key on related models objects pointing to this to have this model object's ID
1740
-     * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1741
-     * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1742
-     * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1743
-     * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1744
-     * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1745
-     * or not they exist in the DB (if they do, their DB records will be automatically updated)
1746
-     *
1747
-     * @return void
1748
-     * @throws \EE_Error
1749
-     */
1750
-    protected function _update_cached_related_model_objs_fks()
1751
-    {
1752
-        $model = $this->get_model();
1753
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1754
-            if ($relation_obj instanceof EE_Has_Many_Relation) {
1755
-                foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1756
-                    $fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1757
-                        $model->get_this_model_name()
1758
-                    );
1759
-                    $related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1760
-                    if ($related_model_obj_in_cache->ID()) {
1761
-                        $related_model_obj_in_cache->save();
1762
-                    }
1763
-                }
1764
-            }
1765
-        }
1766
-    }
1767
-
1768
-
1769
-
1770
-    /**
1771
-     * Saves this model object and its NEW cached relations to the database.
1772
-     * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1773
-     * In order for that to work, we would need to mark model objects as dirty/clean...
1774
-     * because otherwise, there's a potential for infinite looping of saving
1775
-     * Saves the cached related model objects, and ensures the relation between them
1776
-     * and this object and properly setup
1777
-     *
1778
-     * @return int ID of new model object on save; 0 on failure+
1779
-     * @throws \EE_Error
1780
-     */
1781
-    public function save_new_cached_related_model_objs()
1782
-    {
1783
-        //make sure this has been saved
1784
-        if ( ! $this->ID()) {
1785
-            $id = $this->save();
1786
-        } else {
1787
-            $id = $this->ID();
1788
-        }
1789
-        //now save all the NEW cached model objects  (ie they don't exist in the DB)
1790
-        foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1791
-            if ($this->_model_relations[$relationName]) {
1792
-                //is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1793
-                //or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1794
-                if ($relationObj instanceof EE_Belongs_To_Relation) {
1795
-                    //add a relation to that relation type (which saves the appropriate thing in the process)
1796
-                    //but ONLY if it DOES NOT exist in the DB
1797
-                    /* @var $related_model_obj EE_Base_Class */
1798
-                    $related_model_obj = $this->_model_relations[$relationName];
1799
-                    //					if( ! $related_model_obj->ID()){
1800
-                    $this->_add_relation_to($related_model_obj, $relationName);
1801
-                    $related_model_obj->save_new_cached_related_model_objs();
1802
-                    //					}
1803
-                } else {
1804
-                    foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1805
-                        //add a relation to that relation type (which saves the appropriate thing in the process)
1806
-                        //but ONLY if it DOES NOT exist in the DB
1807
-                        //						if( ! $related_model_obj->ID()){
1808
-                        $this->_add_relation_to($related_model_obj, $relationName);
1809
-                        $related_model_obj->save_new_cached_related_model_objs();
1810
-                        //						}
1811
-                    }
1812
-                }
1813
-            }
1814
-        }
1815
-        return $id;
1816
-    }
1817
-
1818
-
1819
-
1820
-    /**
1821
-     * for getting a model while instantiated.
1822
-     *
1823
-     * @return \EEM_Base | \EEM_CPT_Base
1824
-     */
1825
-    public function get_model()
1826
-    {
1827
-        if( ! $this->_model){
1828
-            $modelName = self::_get_model_classname(get_class($this));
1829
-            $this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
1830
-        } else {
1831
-            $this->_model->set_timezone($this->_timezone);
1832
-        }
1833
-
1834
-        return $this->_model;
1835
-    }
1836
-
1837
-
1838
-
1839
-    /**
1840
-     * @param $props_n_values
1841
-     * @param $classname
1842
-     * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1843
-     * @throws \EE_Error
1844
-     */
1845
-    protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1846
-    {
1847
-        //TODO: will not work for Term_Relationships because they have no PK!
1848
-        $primary_id_ref = self::_get_primary_key_name($classname);
1849
-        if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1850
-            $id = $props_n_values[$primary_id_ref];
1851
-            return self::_get_model($classname)->get_from_entity_map($id);
1852
-        }
1853
-        return false;
1854
-    }
1855
-
1856
-
1857
-
1858
-    /**
1859
-     * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1860
-     * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1861
-     * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1862
-     * we return false.
1863
-     *
1864
-     * @param  array  $props_n_values   incoming array of properties and their values
1865
-     * @param  string $classname        the classname of the child class
1866
-     * @param null    $timezone
1867
-     * @param array   $date_formats     incoming date_formats in an array where the first value is the
1868
-     *                                  date_format and the second value is the time format
1869
-     * @return mixed (EE_Base_Class|bool)
1870
-     * @throws \EE_Error
1871
-     */
1872
-    protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1873
-    {
1874
-        $existing = null;
1875
-        $model = self::_get_model($classname, $timezone);
1876
-        if ($model->has_primary_key_field()) {
1877
-            $primary_id_ref = self::_get_primary_key_name($classname);
1878
-            if (array_key_exists($primary_id_ref, $props_n_values)
1879
-                && ! empty($props_n_values[$primary_id_ref])
1880
-            ) {
1881
-                $existing = $model->get_one_by_ID(
1882
-                    $props_n_values[$primary_id_ref]
1883
-                );
1884
-            }
1885
-        } elseif ($model->has_all_combined_primary_key_fields($props_n_values)) {
1886
-            //no primary key on this model, but there's still a matching item in the DB
1887
-            $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1888
-                self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1889
-            );
1890
-        }
1891
-        if ($existing) {
1892
-            //set date formats if present before setting values
1893
-            if ( ! empty($date_formats) && is_array($date_formats)) {
1894
-                $existing->set_date_format($date_formats[0]);
1895
-                $existing->set_time_format($date_formats[1]);
1896
-            } else {
1897
-                //set default formats for date and time
1898
-                $existing->set_date_format(get_option('date_format'));
1899
-                $existing->set_time_format(get_option('time_format'));
1900
-            }
1901
-            foreach ($props_n_values as $property => $field_value) {
1902
-                $existing->set($property, $field_value);
1903
-            }
1904
-            return $existing;
1905
-        } else {
1906
-            return false;
1907
-        }
1908
-    }
1909
-
1910
-
1911
-
1912
-    /**
1913
-     * Gets the EEM_*_Model for this class
1914
-     *
1915
-     * @access public now, as this is more convenient
1916
-     * @param      $classname
1917
-     * @param null $timezone
1918
-     * @throws EE_Error
1919
-     * @return EEM_Base
1920
-     */
1921
-    protected static function _get_model($classname, $timezone = null)
1922
-    {
1923
-        //find model for this class
1924
-        if ( ! $classname) {
1925
-            throw new EE_Error(
1926
-                sprintf(
1927
-                    __(
1928
-                        "What were you thinking calling _get_model(%s)?? You need to specify the class name",
1929
-                        "event_espresso"
1930
-                    ),
1931
-                    $classname
1932
-                )
1933
-            );
1934
-        }
1935
-        $modelName = self::_get_model_classname($classname);
1936
-        return self::_get_model_instance_with_name($modelName, $timezone);
1937
-    }
1938
-
1939
-
1940
-
1941
-    /**
1942
-     * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1943
-     *
1944
-     * @param string $model_classname
1945
-     * @param null   $timezone
1946
-     * @return EEM_Base
1947
-     */
1948
-    protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1949
-    {
1950
-        $model_classname = str_replace('EEM_', '', $model_classname);
1951
-        $model = EE_Registry::instance()->load_model($model_classname);
1952
-        $model->set_timezone($timezone);
1953
-        return $model;
1954
-    }
1955
-
1956
-
1957
-
1958
-    /**
1959
-     * If a model name is provided (eg Registration), gets the model classname for that model.
1960
-     * Also works if a model class's classname is provided (eg EE_Registration).
1961
-     *
1962
-     * @param null $model_name
1963
-     * @return string like EEM_Attendee
1964
-     */
1965
-    private static function _get_model_classname($model_name = null)
1966
-    {
1967
-        if (strpos($model_name, "EE_") === 0) {
1968
-            $model_classname = str_replace("EE_", "EEM_", $model_name);
1969
-        } else {
1970
-            $model_classname = "EEM_" . $model_name;
1971
-        }
1972
-        return $model_classname;
1973
-    }
1974
-
1975
-
1976
-
1977
-    /**
1978
-     * returns the name of the primary key attribute
1979
-     *
1980
-     * @param null $classname
1981
-     * @throws EE_Error
1982
-     * @return string
1983
-     */
1984
-    protected static function _get_primary_key_name($classname = null)
1985
-    {
1986
-        if ( ! $classname) {
1987
-            throw new EE_Error(
1988
-                sprintf(
1989
-                    __("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1990
-                    $classname
1991
-                )
1992
-            );
1993
-        }
1994
-        return self::_get_model($classname)->get_primary_key_field()->get_name();
1995
-    }
1996
-
1997
-
1998
-
1999
-    /**
2000
-     * Gets the value of the primary key.
2001
-     * If the object hasn't yet been saved, it should be whatever the model field's default was
2002
-     * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
2003
-     * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
2004
-     *
2005
-     * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
2006
-     * @throws \EE_Error
2007
-     */
2008
-    public function ID()
2009
-    {
2010
-        $model = $this->get_model();
2011
-        //now that we know the name of the variable, use a variable variable to get its value and return its
2012
-        if ($model->has_primary_key_field()) {
2013
-            return $this->_fields[$model->primary_key_name()];
2014
-        } else {
2015
-            return $model->get_index_primary_key_string($this->_fields);
2016
-        }
2017
-    }
2018
-
2019
-
2020
-
2021
-    /**
2022
-     * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
2023
-     * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
2024
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
2025
-     *
2026
-     * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
2027
-     * @param string $relationName                     eg 'Events','Question',etc.
2028
-     *                                                 an attendee to a group, you also want to specify which role they
2029
-     *                                                 will have in that group. So you would use this parameter to
2030
-     *                                                 specify array('role-column-name'=>'role-id')
2031
-     * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
2032
-     *                                                 allow you to further constrict the relation to being added.
2033
-     *                                                 However, keep in mind that the columns (keys) given must match a
2034
-     *                                                 column on the JOIN table and currently only the HABTM models
2035
-     *                                                 accept these additional conditions.  Also remember that if an
2036
-     *                                                 exact match isn't found for these extra cols/val pairs, then a
2037
-     *                                                 NEW row is created in the join table.
2038
-     * @param null   $cache_id
2039
-     * @throws EE_Error
2040
-     * @return EE_Base_Class the object the relation was added to
2041
-     */
2042
-    public function _add_relation_to(
2043
-        $otherObjectModelObjectOrID,
2044
-        $relationName,
2045
-        $extra_join_model_fields_n_values = array(),
2046
-        $cache_id = null
2047
-    ) {
2048
-        $model = $this->get_model();
2049
-        //if this thing exists in the DB, save the relation to the DB
2050
-        if ($this->ID()) {
2051
-            $otherObject = $model
2052
-                                ->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2053
-                                    $extra_join_model_fields_n_values);
2054
-            //clear cache so future get_many_related and get_first_related() return new results.
2055
-            $this->clear_cache($relationName, $otherObject, true);
2056
-            if ($otherObject instanceof EE_Base_Class) {
2057
-                $otherObject->clear_cache($model->get_this_model_name(), $this);
2058
-            }
2059
-        } else {
2060
-            //this thing doesn't exist in the DB,  so just cache it
2061
-            if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2062
-                throw new EE_Error(sprintf(
2063
-                    __('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2064
-                        'event_espresso'),
2065
-                    $otherObjectModelObjectOrID,
2066
-                    get_class($this)
2067
-                ));
2068
-            } else {
2069
-                $otherObject = $otherObjectModelObjectOrID;
2070
-            }
2071
-            $this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2072
-        }
2073
-        if ($otherObject instanceof EE_Base_Class) {
2074
-            //fix the reciprocal relation too
2075
-            if ($otherObject->ID()) {
2076
-                //its saved so assumed relations exist in the DB, so we can just
2077
-                //clear the cache so future queries use the updated info in the DB
2078
-                $otherObject->clear_cache($model->get_this_model_name(), null, true);
2079
-            } else {
2080
-                //it's not saved, so it caches relations like this
2081
-                $otherObject->cache($model->get_this_model_name(), $this);
2082
-            }
2083
-        }
2084
-        return $otherObject;
2085
-    }
2086
-
2087
-
2088
-
2089
-    /**
2090
-     * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2091
-     * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2092
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2093
-     * from the cache
2094
-     *
2095
-     * @param mixed  $otherObjectModelObjectOrID
2096
-     *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2097
-     *                to the DB yet
2098
-     * @param string $relationName
2099
-     * @param array  $where_query
2100
-     *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2101
-     *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2102
-     *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2103
-     *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2104
-     *                created in the join table.
2105
-     * @return EE_Base_Class the relation was removed from
2106
-     * @throws \EE_Error
2107
-     */
2108
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2109
-    {
2110
-        if ($this->ID()) {
2111
-            //if this exists in the DB, save the relation change to the DB too
2112
-            $otherObject = $this->get_model()
2113
-                                ->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2114
-                                    $where_query);
2115
-            $this->clear_cache($relationName, $otherObject);
2116
-        } else {
2117
-            //this doesn't exist in the DB, just remove it from the cache
2118
-            $otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2119
-        }
2120
-        if ($otherObject instanceof EE_Base_Class) {
2121
-            $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2122
-        }
2123
-        return $otherObject;
2124
-    }
2125
-
2126
-
2127
-
2128
-    /**
2129
-     * Removes ALL the related things for the $relationName.
2130
-     *
2131
-     * @param string $relationName
2132
-     * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2133
-     * @return EE_Base_Class
2134
-     * @throws \EE_Error
2135
-     */
2136
-    public function _remove_relations($relationName, $where_query_params = array())
2137
-    {
2138
-        if ($this->ID()) {
2139
-            //if this exists in the DB, save the relation change to the DB too
2140
-            $otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2141
-            $this->clear_cache($relationName, null, true);
2142
-        } else {
2143
-            //this doesn't exist in the DB, just remove it from the cache
2144
-            $otherObjects = $this->clear_cache($relationName, null, true);
2145
-        }
2146
-        if (is_array($otherObjects)) {
2147
-            foreach ($otherObjects as $otherObject) {
2148
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2149
-            }
2150
-        }
2151
-        return $otherObjects;
2152
-    }
2153
-
2154
-
2155
-
2156
-    /**
2157
-     * Gets all the related model objects of the specified type. Eg, if the current class if
2158
-     * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2159
-     * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2160
-     * because we want to get even deleted items etc.
2161
-     *
2162
-     * @param string $relationName key in the model's _model_relations array
2163
-     * @param array  $query_params like EEM_Base::get_all
2164
-     * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2165
-     * @throws \EE_Error
2166
-     *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2167
-     *                             you want IDs
2168
-     */
2169
-    public function get_many_related($relationName, $query_params = array())
2170
-    {
2171
-        if ($this->ID()) {
2172
-            //this exists in the DB, so get the related things from either the cache or the DB
2173
-            //if there are query parameters, forget about caching the related model objects.
2174
-            if ($query_params) {
2175
-                $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2176
-            } else {
2177
-                //did we already cache the result of this query?
2178
-                $cached_results = $this->get_all_from_cache($relationName);
2179
-                if ( ! $cached_results) {
2180
-                    $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2181
-                    //if no query parameters were passed, then we got all the related model objects
2182
-                    //for that relation. We can cache them then.
2183
-                    foreach ($related_model_objects as $related_model_object) {
2184
-                        $this->cache($relationName, $related_model_object);
2185
-                    }
2186
-                } else {
2187
-                    $related_model_objects = $cached_results;
2188
-                }
2189
-            }
2190
-        } else {
2191
-            //this doesn't exist in the DB, so just get the related things from the cache
2192
-            $related_model_objects = $this->get_all_from_cache($relationName);
2193
-        }
2194
-        return $related_model_objects;
2195
-    }
2196
-
2197
-
2198
-
2199
-    /**
2200
-     * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2201
-     * unless otherwise specified in the $query_params
2202
-     *
2203
-     * @param string $relation_name  model_name like 'Event', or 'Registration'
2204
-     * @param array  $query_params   like EEM_Base::get_all's
2205
-     * @param string $field_to_count name of field to count by. By default, uses primary key
2206
-     * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2207
-     *                               that by the setting $distinct to TRUE;
2208
-     * @return int
2209
-     */
2210
-    public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2211
-    {
2212
-        return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2213
-    }
2214
-
2215
-
2216
-
2217
-    /**
2218
-     * Instead of getting the related model objects, simply sums up the values of the specified field.
2219
-     * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2220
-     *
2221
-     * @param string $relation_name model_name like 'Event', or 'Registration'
2222
-     * @param array  $query_params  like EEM_Base::get_all's
2223
-     * @param string $field_to_sum  name of field to count by.
2224
-     *                              By default, uses primary key (which doesn't make much sense, so you should probably
2225
-     *                              change it)
2226
-     * @return int
2227
-     */
2228
-    public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2229
-    {
2230
-        return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2231
-    }
2232
-
2233
-
2234
-
2235
-    /**
2236
-     * Gets the first (ie, one) related model object of the specified type.
2237
-     *
2238
-     * @param string $relationName key in the model's _model_relations array
2239
-     * @param array  $query_params like EEM_Base::get_all
2240
-     * @return EE_Base_Class (not an array, a single object)
2241
-     * @throws \EE_Error
2242
-     */
2243
-    public function get_first_related($relationName, $query_params = array())
2244
-    {
2245
-        $model = $this->get_model();
2246
-        if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2247
-            //if they've provided some query parameters, don't bother trying to cache the result
2248
-            //also make sure we're not caching the result of get_first_related
2249
-            //on a relation which should have an array of objects (because the cache might have an array of objects)
2250
-            if ($query_params
2251
-                || ! $model->related_settings_for($relationName)
2252
-                     instanceof
2253
-                     EE_Belongs_To_Relation
2254
-            ) {
2255
-                $related_model_object = $model->get_first_related($this, $relationName, $query_params);
2256
-            } else {
2257
-                //first, check if we've already cached the result of this query
2258
-                $cached_result = $this->get_one_from_cache($relationName);
2259
-                if ( ! $cached_result) {
2260
-                    $related_model_object = $model->get_first_related($this, $relationName, $query_params);
2261
-                    $this->cache($relationName, $related_model_object);
2262
-                } else {
2263
-                    $related_model_object = $cached_result;
2264
-                }
2265
-            }
2266
-        } else {
2267
-            $related_model_object = null;
2268
-            //this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2269
-            if ($model->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2270
-                $related_model_object = $model->get_first_related($this, $relationName, $query_params);
2271
-            }
2272
-            //this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2273
-            if ( ! $related_model_object) {
2274
-                $related_model_object = $this->get_one_from_cache($relationName);
2275
-            }
2276
-        }
2277
-        return $related_model_object;
2278
-    }
2279
-
2280
-
2281
-
2282
-    /**
2283
-     * Does a delete on all related objects of type $relationName and removes
2284
-     * the current model object's relation to them. If they can't be deleted (because
2285
-     * of blocking related model objects) does nothing. If the related model objects are
2286
-     * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2287
-     * If this model object doesn't exist yet in the DB, just removes its related things
2288
-     *
2289
-     * @param string $relationName
2290
-     * @param array  $query_params like EEM_Base::get_all's
2291
-     * @return int how many deleted
2292
-     * @throws \EE_Error
2293
-     */
2294
-    public function delete_related($relationName, $query_params = array())
2295
-    {
2296
-        if ($this->ID()) {
2297
-            $count = $this->get_model()->delete_related($this, $relationName, $query_params);
2298
-        } else {
2299
-            $count = count($this->get_all_from_cache($relationName));
2300
-            $this->clear_cache($relationName, null, true);
2301
-        }
2302
-        return $count;
2303
-    }
2304
-
2305
-
2306
-
2307
-    /**
2308
-     * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2309
-     * the current model object's relation to them. If they can't be deleted (because
2310
-     * of blocking related model objects) just does a soft delete on it instead, if possible.
2311
-     * If the related thing isn't a soft-deletable model object, this function is identical
2312
-     * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2313
-     *
2314
-     * @param string $relationName
2315
-     * @param array  $query_params like EEM_Base::get_all's
2316
-     * @return int how many deleted (including those soft deleted)
2317
-     * @throws \EE_Error
2318
-     */
2319
-    public function delete_related_permanently($relationName, $query_params = array())
2320
-    {
2321
-        if ($this->ID()) {
2322
-            $count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2323
-        } else {
2324
-            $count = count($this->get_all_from_cache($relationName));
2325
-        }
2326
-        $this->clear_cache($relationName, null, true);
2327
-        return $count;
2328
-    }
2329
-
2330
-
2331
-
2332
-    /**
2333
-     * is_set
2334
-     * Just a simple utility function children can use for checking if property exists
2335
-     *
2336
-     * @access  public
2337
-     * @param  string $field_name property to check
2338
-     * @return bool                              TRUE if existing,FALSE if not.
2339
-     */
2340
-    public function is_set($field_name)
2341
-    {
2342
-        return isset($this->_fields[$field_name]);
2343
-    }
2344
-
2345
-
2346
-
2347
-    /**
2348
-     * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2349
-     * EE_Error exception if they don't
2350
-     *
2351
-     * @param  mixed (string|array) $properties properties to check
2352
-     * @throws EE_Error
2353
-     * @return bool                              TRUE if existing, throw EE_Error if not.
2354
-     */
2355
-    protected function _property_exists($properties)
2356
-    {
2357
-        foreach ((array)$properties as $property_name) {
2358
-            //first make sure this property exists
2359
-            if ( ! $this->_fields[$property_name]) {
2360
-                throw new EE_Error(
2361
-                    sprintf(
2362
-                        __(
2363
-                            'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2364
-                            'event_espresso'
2365
-                        ),
2366
-                        $property_name
2367
-                    )
2368
-                );
2369
-            }
2370
-        }
2371
-        return true;
2372
-    }
2373
-
2374
-
2375
-
2376
-    /**
2377
-     * This simply returns an array of model fields for this object
2378
-     *
2379
-     * @return array
2380
-     * @throws \EE_Error
2381
-     */
2382
-    public function model_field_array()
2383
-    {
2384
-        $fields = $this->get_model()->field_settings(false);
2385
-        $properties = array();
2386
-        //remove prepended underscore
2387
-        foreach ($fields as $field_name => $settings) {
2388
-            $properties[$field_name] = $this->get($field_name);
2389
-        }
2390
-        return $properties;
2391
-    }
2392
-
2393
-
2394
-
2395
-    /**
2396
-     * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2397
-     * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2398
-     * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2399
-     * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2400
-     * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2401
-     * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2402
-     * was called, and an array of the original arguments passed to the function. Whatever their callback function
2403
-     * returns will be returned by this function. Example: in functions.php (or in a plugin):
2404
-     * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2405
-     * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2406
-     * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2407
-     *        return $previousReturnValue.$returnString;
2408
-     * }
2409
-     * require('EE_Answer.class.php');
2410
-     * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2411
-     * echo $answer->my_callback('monkeys',100);
2412
-     * //will output "you called my_callback! and passed args:monkeys,100"
2413
-     *
2414
-     * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2415
-     * @param array  $args       array of original arguments passed to the function
2416
-     * @throws EE_Error
2417
-     * @return mixed whatever the plugin which calls add_filter decides
2418
-     */
2419
-    public function __call($methodName, $args)
2420
-    {
2421
-        $className = get_class($this);
2422
-        $tagName = "FHEE__{$className}__{$methodName}";
2423
-        if ( ! has_filter($tagName)) {
2424
-            throw new EE_Error(
2425
-                sprintf(
2426
-                    __(
2427
-                        "Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2428
-                        "event_espresso"
2429
-                    ),
2430
-                    $methodName,
2431
-                    $className,
2432
-                    $tagName
2433
-                )
2434
-            );
2435
-        }
2436
-        return apply_filters($tagName, null, $this, $args);
2437
-    }
2438
-
2439
-
2440
-
2441
-    /**
2442
-     * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2443
-     * A $previous_value can be specified in case there are many meta rows with the same key
2444
-     *
2445
-     * @param string $meta_key
2446
-     * @param mixed  $meta_value
2447
-     * @param mixed  $previous_value
2448
-     * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2449
-     * @throws \EE_Error
2450
-     * NOTE: if the values haven't changed, returns 0
2451
-     */
2452
-    public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2453
-    {
2454
-        $query_params = array(
2455
-            array(
2456
-                'EXM_key'  => $meta_key,
2457
-                'OBJ_ID'   => $this->ID(),
2458
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2459
-            ),
2460
-        );
2461
-        if ($previous_value !== null) {
2462
-            $query_params[0]['EXM_value'] = $meta_value;
2463
-        }
2464
-        $existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2465
-        if ( ! $existing_rows_like_that) {
2466
-            return $this->add_extra_meta($meta_key, $meta_value);
2467
-        }
2468
-        foreach ($existing_rows_like_that as $existing_row) {
2469
-            $existing_row->save(array('EXM_value' => $meta_value));
2470
-        }
2471
-        return count($existing_rows_like_that);
2472
-    }
2473
-
2474
-
2475
-
2476
-    /**
2477
-     * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2478
-     * no other extra meta for this model object have the same key. Returns TRUE if the
2479
-     * extra meta row was entered, false if not
2480
-     *
2481
-     * @param string  $meta_key
2482
-     * @param string  $meta_value
2483
-     * @param boolean $unique
2484
-     * @return boolean
2485
-     * @throws \EE_Error
2486
-     */
2487
-    public function add_extra_meta($meta_key, $meta_value, $unique = false)
2488
-    {
2489
-        if ($unique) {
2490
-            $existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2491
-                array(
2492
-                    array(
2493
-                        'EXM_key'  => $meta_key,
2494
-                        'OBJ_ID'   => $this->ID(),
2495
-                        'EXM_type' => $this->get_model()->get_this_model_name(),
2496
-                    ),
2497
-                )
2498
-            );
2499
-            if ($existing_extra_meta) {
2500
-                return false;
2501
-            }
2502
-        }
2503
-        $new_extra_meta = EE_Extra_Meta::new_instance(
2504
-            array(
2505
-                'EXM_key'   => $meta_key,
2506
-                'EXM_value' => $meta_value,
2507
-                'OBJ_ID'    => $this->ID(),
2508
-                'EXM_type'  => $this->get_model()->get_this_model_name(),
2509
-            )
2510
-        );
2511
-        $new_extra_meta->save();
2512
-        return true;
2513
-    }
2514
-
2515
-
2516
-
2517
-    /**
2518
-     * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2519
-     * is specified, only deletes extra meta records with that value.
2520
-     *
2521
-     * @param string $meta_key
2522
-     * @param string $meta_value
2523
-     * @return int number of extra meta rows deleted
2524
-     * @throws \EE_Error
2525
-     */
2526
-    public function delete_extra_meta($meta_key, $meta_value = null)
2527
-    {
2528
-        $query_params = array(
2529
-            array(
2530
-                'EXM_key'  => $meta_key,
2531
-                'OBJ_ID'   => $this->ID(),
2532
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2533
-            ),
2534
-        );
2535
-        if ($meta_value !== null) {
2536
-            $query_params[0]['EXM_value'] = $meta_value;
2537
-        }
2538
-        return EEM_Extra_Meta::instance()->delete($query_params);
2539
-    }
2540
-
2541
-
2542
-
2543
-    /**
2544
-     * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2545
-     * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2546
-     * You can specify $default is case you haven't found the extra meta
2547
-     *
2548
-     * @param string  $meta_key
2549
-     * @param boolean $single
2550
-     * @param mixed   $default if we don't find anything, what should we return?
2551
-     * @return mixed single value if $single; array if ! $single
2552
-     * @throws \EE_Error
2553
-     */
2554
-    public function get_extra_meta($meta_key, $single = false, $default = null)
2555
-    {
2556
-        if ($single) {
2557
-            $result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2558
-            if ($result instanceof EE_Extra_Meta) {
2559
-                return $result->value();
2560
-            } else {
2561
-                return $default;
2562
-            }
2563
-        } else {
2564
-            $results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2565
-            if ($results) {
2566
-                $values = array();
2567
-                foreach ($results as $result) {
2568
-                    if ($result instanceof EE_Extra_Meta) {
2569
-                        $values[$result->ID()] = $result->value();
2570
-                    }
2571
-                }
2572
-                return $values;
2573
-            } else {
2574
-                return $default;
2575
-            }
2576
-        }
2577
-    }
2578
-
2579
-
2580
-
2581
-    /**
2582
-     * Returns a simple array of all the extra meta associated with this model object.
2583
-     * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2584
-     * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2585
-     * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2586
-     * If $one_of_each_key is false, it will return an array with the top-level keys being
2587
-     * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2588
-     * finally the extra meta's value as each sub-value. (eg
2589
-     * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2590
-     *
2591
-     * @param boolean $one_of_each_key
2592
-     * @return array
2593
-     * @throws \EE_Error
2594
-     */
2595
-    public function all_extra_meta_array($one_of_each_key = true)
2596
-    {
2597
-        $return_array = array();
2598
-        if ($one_of_each_key) {
2599
-            $extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2600
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2601
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2602
-                    $return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2603
-                }
2604
-            }
2605
-        } else {
2606
-            $extra_meta_objs = $this->get_many_related('Extra_Meta');
2607
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2608
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2609
-                    if ( ! isset($return_array[$extra_meta_obj->key()])) {
2610
-                        $return_array[$extra_meta_obj->key()] = array();
2611
-                    }
2612
-                    $return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2613
-                }
2614
-            }
2615
-        }
2616
-        return $return_array;
2617
-    }
2618
-
2619
-
2620
-
2621
-    /**
2622
-     * Gets a pretty nice displayable nice for this model object. Often overridden
2623
-     *
2624
-     * @return string
2625
-     * @throws \EE_Error
2626
-     */
2627
-    public function name()
2628
-    {
2629
-        //find a field that's not a text field
2630
-        $field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2631
-        if ($field_we_can_use) {
2632
-            return $this->get($field_we_can_use->get_name());
2633
-        } else {
2634
-            $first_few_properties = $this->model_field_array();
2635
-            $first_few_properties = array_slice($first_few_properties, 0, 3);
2636
-            $name_parts = array();
2637
-            foreach ($first_few_properties as $name => $value) {
2638
-                $name_parts[] = "$name:$value";
2639
-            }
2640
-            return implode(",", $name_parts);
2641
-        }
2642
-    }
2643
-
2644
-
2645
-
2646
-    /**
2647
-     * in_entity_map
2648
-     * Checks if this model object has been proven to already be in the entity map
2649
-     *
2650
-     * @return boolean
2651
-     * @throws \EE_Error
2652
-     */
2653
-    public function in_entity_map()
2654
-    {
2655
-        if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2656
-            //well, if we looked, did we find it in the entity map?
2657
-            return true;
2658
-        } else {
2659
-            return false;
2660
-        }
2661
-    }
2662
-
2663
-
2664
-
2665
-    /**
2666
-     * refresh_from_db
2667
-     * Makes sure the fields and values on this model object are in-sync with what's in the database.
2668
-     *
2669
-     * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2670
-     * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2671
-     */
2672
-    public function refresh_from_db()
2673
-    {
2674
-        if ($this->ID() && $this->in_entity_map()) {
2675
-            $this->get_model()->refresh_entity_map_from_db($this->ID());
2676
-        } else {
2677
-            //if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2678
-            //if it has an ID but it's not in the map, and you're asking me to refresh it
2679
-            //that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2680
-            //absolutely nothing in it for this ID
2681
-            if (WP_DEBUG) {
2682
-                throw new EE_Error(
2683
-                    sprintf(
2684
-                        __('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2685
-                            'event_espresso'),
2686
-                        $this->ID(),
2687
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2688
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2689
-                    )
2690
-                );
2691
-            }
2692
-        }
2693
-    }
2694
-
2695
-
2696
-
2697
-    /**
2698
-     * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2699
-     * (probably a bad assumption they have made, oh well)
2700
-     *
2701
-     * @return string
2702
-     */
2703
-    public function __toString()
2704
-    {
2705
-        try {
2706
-            return sprintf('%s (%s)', $this->name(), $this->ID());
2707
-        } catch (Exception $e) {
2708
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2709
-            return '';
2710
-        }
2711
-    }
2712
-
2713
-
2714
-
2715
-    /**
2716
-     * Clear related model objects if they're already in the DB, because otherwise when we
2717
-     * UN-serialize this model object we'll need to be careful to add them to the entity map.
2718
-     * This means if we have made changes to those related model objects, and want to unserialize
2719
-     * the this model object on a subsequent request, changes to those related model objects will be lost.
2720
-     * Instead, those related model objects should be directly serialized and stored.
2721
-     * Eg, the following won't work:
2722
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2723
-     * $att = $reg->attendee();
2724
-     * $att->set( 'ATT_fname', 'Dirk' );
2725
-     * update_option( 'my_option', serialize( $reg ) );
2726
-     * //END REQUEST
2727
-     * //START NEXT REQUEST
2728
-     * $reg = get_option( 'my_option' );
2729
-     * $reg->attendee()->save();
2730
-     * And would need to be replace with:
2731
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2732
-     * $att = $reg->attendee();
2733
-     * $att->set( 'ATT_fname', 'Dirk' );
2734
-     * update_option( 'my_option', serialize( $reg ) );
2735
-     * //END REQUEST
2736
-     * //START NEXT REQUEST
2737
-     * $att = get_option( 'my_option' );
2738
-     * $att->save();
2739
-     *
2740
-     * @return array
2741
-     * @throws \EE_Error
2742
-     */
2743
-    public function __sleep()
2744
-    {
2745
-        $model = $this->get_model();
2746
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
2747
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
2748
-                $classname = 'EE_' . $model->get_this_model_name();
2749
-                if (
2750
-                    $this->get_one_from_cache($relation_name) instanceof $classname
2751
-                    && $this->get_one_from_cache($relation_name)->ID()
2752
-                ) {
2753
-                    $this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2754
-                }
2755
-            }
2756
-        }
2757
-        $this->_props_n_values_provided_in_constructor = array();
2758
-        $properties_to_serialize = get_object_vars($this);
2759
-        //don't serialize the model. It's big and that risks recursion
2760
-        unset($properties_to_serialize['_model']);
2761
-        return array_keys($properties_to_serialize);
2762
-    }
2763
-
2764
-
2765
-
2766
-    /**
2767
-     * restore _props_n_values_provided_in_constructor
2768
-     * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2769
-     * and therefore should NOT be used to determine if state change has occurred since initial construction.
2770
-     * At best, you would only be able to detect if state change has occurred during THIS request.
2771
-     */
2772
-    public function __wakeup()
2773
-    {
2774
-        $this->_props_n_values_provided_in_constructor = $this->_fields;
2775
-    }
28
+	/**
29
+	 * This is an array of the original properties and values provided during construction
30
+	 * of this model object. (keys are model field names, values are their values).
31
+	 * This list is important to remember so that when we are merging data from the db, we know
32
+	 * which values to override and which to not override.
33
+	 *
34
+	 * @var array
35
+	 */
36
+	protected $_props_n_values_provided_in_constructor;
37
+
38
+	/**
39
+	 * Timezone
40
+	 * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
+	 * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
+	 * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
+	 * access to it.
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_timezone;
48
+
49
+
50
+
51
+	/**
52
+	 * date format
53
+	 * pattern or format for displaying dates
54
+	 *
55
+	 * @var string $_dt_frmt
56
+	 */
57
+	protected $_dt_frmt;
58
+
59
+
60
+
61
+	/**
62
+	 * time format
63
+	 * pattern or format for displaying time
64
+	 *
65
+	 * @var string $_tm_frmt
66
+	 */
67
+	protected $_tm_frmt;
68
+
69
+
70
+
71
+	/**
72
+	 * This property is for holding a cached array of object properties indexed by property name as the key.
73
+	 * The purpose of this is for setting a cache on properties that may have calculated values after a
74
+	 * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
+	 * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
+	 *
77
+	 * @var array
78
+	 */
79
+	protected $_cached_properties = array();
80
+
81
+	/**
82
+	 * An array containing keys of the related model, and values are either an array of related mode objects or a
83
+	 * single
84
+	 * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
+	 * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
+	 * all others have an array)
87
+	 *
88
+	 * @var array
89
+	 */
90
+	protected $_model_relations = array();
91
+
92
+	/**
93
+	 * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
+	 * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
+	 *
96
+	 * @var array
97
+	 */
98
+	protected $_fields = array();
99
+
100
+	/**
101
+	 * @var boolean indicating whether or not this model object is intended to ever be saved
102
+	 * For example, we might create model objects intended to only be used for the duration
103
+	 * of this request and to be thrown away, and if they were accidentally saved
104
+	 * it would be a bug.
105
+	 */
106
+	protected $_allow_persist = true;
107
+
108
+	/**
109
+	 * @var boolean indicating whether or not this model object's properties have changed since construction
110
+	 */
111
+	protected $_has_changes = false;
112
+
113
+	/**
114
+	 * @var EEM_Base
115
+	 */
116
+	protected $_model;
117
+
118
+
119
+
120
+	/**
121
+	 * @param array  $fieldValues
122
+	 * @param string $timezone
123
+	 * @param array  $date_formats
124
+	 * @param bool   $bydb
125
+	 * @return \EE_Base_Class
126
+	 * @throws \EE_Error
127
+	 */
128
+	public static function new_instance(
129
+		array $fieldValues = array(),
130
+		$timezone = '',
131
+		array $date_formats = array(),
132
+		$bydb = false
133
+	)
134
+	{
135
+		$className = get_called_class();
136
+		if ( ! $bydb) {
137
+			$cached_object = \EE_Base_Class::_check_for_object($fieldValues, $className, $timezone, $date_formats);
138
+			if ($cached_object) {
139
+				return $cached_object;
140
+			}
141
+		}
142
+		return new static($fieldValues, $bydb, $timezone, $date_formats);
143
+	}
144
+
145
+
146
+
147
+	/**
148
+	 * @deprecated
149
+	 * @param array  $fieldValues
150
+	 * @param string $timezone
151
+	 * @param array  $date_formats
152
+	 * @return \EE_Base_Class
153
+	 * @throws \EE_Error
154
+	 */
155
+	public static function new_instance_from_db(array $fieldValues = array(), $timezone = '', array $date_formats = array())
156
+	{
157
+		return static::new_instance($fieldValues, $timezone, $date_formats, true);
158
+	}
159
+
160
+
161
+	/**
162
+	 * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children play nice
163
+	 *
164
+	 * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
165
+	 *                                                         layer of the model's _fields array, (eg, EVT_ID,
166
+	 *                                                         TXN_amount, QST_name, etc) and values are their values
167
+	 * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
168
+	 *                                                         corresponding db model or not.
169
+	 * @param string  $timezone                                indicate what timezone you want any datetime fields to
170
+	 *                                                         be in when instantiating a EE_Base_Class object.
171
+	 * @param array   $date_formats                            An array of date formats to set on construct where first
172
+	 *                                                         value is the date_format and second value is the time
173
+	 *                                                         format.
174
+	 * @throws EE_Error
175
+	 */
176
+	protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
177
+	{
178
+		$className = get_class($this);
179
+		do_action("AHEE__{$className}__construct", $this, $fieldValues);
180
+		$model = $this->get_model();
181
+		$model_fields = $model->field_settings(false);
182
+		// ensure $fieldValues is an array
183
+		$fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
184
+		// EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
185
+		// verify client code has not passed any invalid field names
186
+		foreach ($fieldValues as $field_name => $field_value) {
187
+			if ( ! isset($model_fields[$field_name])) {
188
+				throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
189
+					"event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
190
+			}
191
+		}
192
+		// EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
193
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
194
+		if ( ! empty($date_formats) && is_array($date_formats)) {
195
+			list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
196
+		} else {
197
+			//set default formats for date and time
198
+			$this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
199
+			$this->_tm_frmt = (string)get_option('time_format', 'g:i a');
200
+		}
201
+		//if db model is instantiating
202
+		if ($bydb) {
203
+			//client code has indicated these field values are from the database
204
+			foreach ($model_fields as $fieldName => $field) {
205
+				$this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
206
+			}
207
+		} else {
208
+			//we're constructing a brand
209
+			//new instance of the model object. Generally, this means we'll need to do more field validation
210
+			foreach ($model_fields as $fieldName => $field) {
211
+				$this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
212
+			}
213
+		}
214
+		//remember what values were passed to this constructor
215
+		$this->_props_n_values_provided_in_constructor = $fieldValues;
216
+		//remember in entity mapper
217
+		if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
218
+			$model->add_to_entity_map($this);
219
+		}
220
+		//setup all the relations
221
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
222
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
223
+				$this->_model_relations[$relation_name] = null;
224
+			} else {
225
+				$this->_model_relations[$relation_name] = array();
226
+			}
227
+		}
228
+		/**
229
+		 * Action done at the end of each model object construction
230
+		 *
231
+		 * @param EE_Base_Class $this the model object just created
232
+		 */
233
+		do_action('AHEE__EE_Base_Class__construct__finished', $this);
234
+	}
235
+
236
+
237
+
238
+	/**
239
+	 * Gets whether or not this model object is allowed to persist/be saved to the database.
240
+	 *
241
+	 * @return boolean
242
+	 */
243
+	public function allow_persist()
244
+	{
245
+		return $this->_allow_persist;
246
+	}
247
+
248
+
249
+
250
+	/**
251
+	 * Sets whether or not this model object should be allowed to be saved to the DB.
252
+	 * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
253
+	 * you got new information that somehow made you change your mind.
254
+	 *
255
+	 * @param boolean $allow_persist
256
+	 * @return boolean
257
+	 */
258
+	public function set_allow_persist($allow_persist)
259
+	{
260
+		return $this->_allow_persist = $allow_persist;
261
+	}
262
+
263
+
264
+
265
+	/**
266
+	 * Gets the field's original value when this object was constructed during this request.
267
+	 * This can be helpful when determining if a model object has changed or not
268
+	 *
269
+	 * @param string $field_name
270
+	 * @return mixed|null
271
+	 * @throws \EE_Error
272
+	 */
273
+	public function get_original($field_name)
274
+	{
275
+		if (isset($this->_props_n_values_provided_in_constructor[$field_name])
276
+			&& $field_settings = $this->get_model()->field_settings_for($field_name)
277
+		) {
278
+			return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
279
+		} else {
280
+			return null;
281
+		}
282
+	}
283
+
284
+
285
+
286
+	/**
287
+	 * @param EE_Base_Class $obj
288
+	 * @return string
289
+	 */
290
+	public function get_class($obj)
291
+	{
292
+		return get_class($obj);
293
+	}
294
+
295
+
296
+
297
+	/**
298
+	 * Overrides parent because parent expects old models.
299
+	 * This also doesn't do any validation, and won't work for serialized arrays
300
+	 *
301
+	 * @param    string $field_name
302
+	 * @param    mixed  $field_value
303
+	 * @param bool      $use_default
304
+	 * @throws \EE_Error
305
+	 */
306
+	public function set($field_name, $field_value, $use_default = false)
307
+	{
308
+		// if not using default and nothing has changed, and object has already been setup (has ID),
309
+		// then don't do anything
310
+		if (
311
+			! $use_default
312
+			&& $this->_fields[$field_name] === $field_value
313
+			&& $this->ID()
314
+		) {
315
+			return;
316
+		}
317
+		$model = $this->get_model();
318
+		$this->_has_changes = true;
319
+		$field_obj = $model->field_settings_for($field_name);
320
+		if ($field_obj instanceof EE_Model_Field_Base) {
321
+			//			if ( method_exists( $field_obj, 'set_timezone' )) {
322
+			if ($field_obj instanceof EE_Datetime_Field) {
323
+				$field_obj->set_timezone($this->_timezone);
324
+				$field_obj->set_date_format($this->_dt_frmt);
325
+				$field_obj->set_time_format($this->_tm_frmt);
326
+			}
327
+			$holder_of_value = $field_obj->prepare_for_set($field_value);
328
+			//should the value be null?
329
+			if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
330
+				$this->_fields[$field_name] = $field_obj->get_default_value();
331
+				/**
332
+				 * To save having to refactor all the models, if a default value is used for a
333
+				 * EE_Datetime_Field, and that value is not null nor is it a DateTime
334
+				 * object.  Then let's do a set again to ensure that it becomes a DateTime
335
+				 * object.
336
+				 *
337
+				 * @since 4.6.10+
338
+				 */
339
+				if (
340
+					$field_obj instanceof EE_Datetime_Field
341
+					&& $this->_fields[$field_name] !== null
342
+					&& ! $this->_fields[$field_name] instanceof DateTime
343
+				) {
344
+					empty($this->_fields[$field_name])
345
+						? $this->set($field_name, time())
346
+						: $this->set($field_name, $this->_fields[$field_name]);
347
+				}
348
+			} else {
349
+				$this->_fields[$field_name] = $holder_of_value;
350
+			}
351
+			//if we're not in the constructor...
352
+			//now check if what we set was a primary key
353
+			if (
354
+				//note: props_n_values_provided_in_constructor is only set at the END of the constructor
355
+				$this->_props_n_values_provided_in_constructor
356
+				&& $field_value
357
+				&& $field_name === $model->primary_key_name()
358
+			) {
359
+				//if so, we want all this object's fields to be filled either with
360
+				//what we've explicitly set on this model
361
+				//or what we have in the db
362
+				// echo "setting primary key!";
363
+				$fields_on_model = self::_get_model(get_class($this))->field_settings();
364
+				$obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
365
+				foreach ($fields_on_model as $field_obj) {
366
+					if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
367
+						 && $field_obj->get_name() !== $field_name
368
+					) {
369
+						$this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
370
+					}
371
+				}
372
+				//oh this model object has an ID? well make sure its in the entity mapper
373
+				$model->add_to_entity_map($this);
374
+			}
375
+			//let's unset any cache for this field_name from the $_cached_properties property.
376
+			$this->_clear_cached_property($field_name);
377
+		} else {
378
+			throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
379
+				"event_espresso"), $field_name));
380
+		}
381
+	}
382
+
383
+
384
+
385
+	/**
386
+	 * This sets the field value on the db column if it exists for the given $column_name or
387
+	 * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
388
+	 *
389
+	 * @see EE_message::get_column_value for related documentation on the necessity of this method.
390
+	 * @param string $field_name  Must be the exact column name.
391
+	 * @param mixed  $field_value The value to set.
392
+	 * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
393
+	 * @throws \EE_Error
394
+	 */
395
+	public function set_field_or_extra_meta($field_name, $field_value)
396
+	{
397
+		if ($this->get_model()->has_field($field_name)) {
398
+			$this->set($field_name, $field_value);
399
+			return true;
400
+		} else {
401
+			//ensure this object is saved first so that extra meta can be properly related.
402
+			$this->save();
403
+			return $this->update_extra_meta($field_name, $field_value);
404
+		}
405
+	}
406
+
407
+
408
+
409
+	/**
410
+	 * This retrieves the value of the db column set on this class or if that's not present
411
+	 * it will attempt to retrieve from extra_meta if found.
412
+	 * Example Usage:
413
+	 * Via EE_Message child class:
414
+	 * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
415
+	 * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
416
+	 * also have additional main fields specific to the messenger.  The system accommodates those extra
417
+	 * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
418
+	 * value for those extra fields dynamically via the EE_message object.
419
+	 *
420
+	 * @param  string $field_name expecting the fully qualified field name.
421
+	 * @return mixed|null  value for the field if found.  null if not found.
422
+	 * @throws \EE_Error
423
+	 */
424
+	public function get_field_or_extra_meta($field_name)
425
+	{
426
+		if ($this->get_model()->has_field($field_name)) {
427
+			$column_value = $this->get($field_name);
428
+		} else {
429
+			//This isn't a column in the main table, let's see if it is in the extra meta.
430
+			$column_value = $this->get_extra_meta($field_name, true, null);
431
+		}
432
+		return $column_value;
433
+	}
434
+
435
+
436
+
437
+	/**
438
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
439
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
440
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
441
+	 * available to all child classes that may be using the EE_Datetime_Field for a field data type.
442
+	 *
443
+	 * @access public
444
+	 * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
445
+	 * @return void
446
+	 * @throws \EE_Error
447
+	 */
448
+	public function set_timezone($timezone = '')
449
+	{
450
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
451
+		//make sure we clear all cached properties because they won't be relevant now
452
+		$this->_clear_cached_properties();
453
+		//make sure we update field settings and the date for all EE_Datetime_Fields
454
+		$model_fields = $this->get_model()->field_settings(false);
455
+		foreach ($model_fields as $field_name => $field_obj) {
456
+			if ($field_obj instanceof EE_Datetime_Field) {
457
+				$field_obj->set_timezone($this->_timezone);
458
+				if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
459
+					$this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
460
+				}
461
+			}
462
+		}
463
+	}
464
+
465
+
466
+
467
+	/**
468
+	 * This just returns whatever is set for the current timezone.
469
+	 *
470
+	 * @access public
471
+	 * @return string timezone string
472
+	 */
473
+	public function get_timezone()
474
+	{
475
+		return $this->_timezone;
476
+	}
477
+
478
+
479
+
480
+	/**
481
+	 * This sets the internal date format to what is sent in to be used as the new default for the class
482
+	 * internally instead of wp set date format options
483
+	 *
484
+	 * @since 4.6
485
+	 * @param string $format should be a format recognizable by PHP date() functions.
486
+	 */
487
+	public function set_date_format($format)
488
+	{
489
+		$this->_dt_frmt = $format;
490
+		//clear cached_properties because they won't be relevant now.
491
+		$this->_clear_cached_properties();
492
+	}
493
+
494
+
495
+
496
+	/**
497
+	 * This sets the internal time format string to what is sent in to be used as the new default for the
498
+	 * class internally instead of wp set time format options.
499
+	 *
500
+	 * @since 4.6
501
+	 * @param string $format should be a format recognizable by PHP date() functions.
502
+	 */
503
+	public function set_time_format($format)
504
+	{
505
+		$this->_tm_frmt = $format;
506
+		//clear cached_properties because they won't be relevant now.
507
+		$this->_clear_cached_properties();
508
+	}
509
+
510
+
511
+
512
+	/**
513
+	 * This returns the current internal set format for the date and time formats.
514
+	 *
515
+	 * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
516
+	 *                             where the first value is the date format and the second value is the time format.
517
+	 * @return mixed string|array
518
+	 */
519
+	public function get_format($full = true)
520
+	{
521
+		return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
522
+	}
523
+
524
+
525
+
526
+	/**
527
+	 * cache
528
+	 * stores the passed model object on the current model object.
529
+	 * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
530
+	 *
531
+	 * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
532
+	 *                                       'Registration' associated with this model object
533
+	 * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
534
+	 *                                       that could be a payment or a registration)
535
+	 * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
536
+	 *                                       items which will be stored in an array on this object
537
+	 * @throws EE_Error
538
+	 * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
539
+	 *                  related thing, no array)
540
+	 */
541
+	public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
542
+	{
543
+		// its entirely possible that there IS no related object yet in which case there is nothing to cache.
544
+		if ( ! $object_to_cache instanceof EE_Base_Class) {
545
+			return false;
546
+		}
547
+		// also get "how" the object is related, or throw an error
548
+		if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
549
+			throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
550
+				$relationName, get_class($this)));
551
+		}
552
+		// how many things are related ?
553
+		if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
554
+			// if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
555
+			// so for these model objects just set it to be cached
556
+			$this->_model_relations[$relationName] = $object_to_cache;
557
+			$return = true;
558
+		} else {
559
+			// otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
560
+			// eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
561
+			if ( ! is_array($this->_model_relations[$relationName])) {
562
+				// if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
563
+				$this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
564
+					? array($this->_model_relations[$relationName]) : array();
565
+			}
566
+			// first check for a cache_id which is normally empty
567
+			if ( ! empty($cache_id)) {
568
+				// if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
569
+				$this->_model_relations[$relationName][$cache_id] = $object_to_cache;
570
+				$return = $cache_id;
571
+			} elseif ($object_to_cache->ID()) {
572
+				// OR the cached object originally came from the db, so let's just use it's PK for an ID
573
+				$this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
574
+				$return = $object_to_cache->ID();
575
+			} else {
576
+				// OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
577
+				$this->_model_relations[$relationName][] = $object_to_cache;
578
+				// move the internal pointer to the end of the array
579
+				end($this->_model_relations[$relationName]);
580
+				// and grab the key so that we can return it
581
+				$return = key($this->_model_relations[$relationName]);
582
+			}
583
+		}
584
+		return $return;
585
+	}
586
+
587
+
588
+
589
+	/**
590
+	 * For adding an item to the cached_properties property.
591
+	 *
592
+	 * @access protected
593
+	 * @param string      $fieldname the property item the corresponding value is for.
594
+	 * @param mixed       $value     The value we are caching.
595
+	 * @param string|null $cache_type
596
+	 * @return void
597
+	 * @throws \EE_Error
598
+	 */
599
+	protected function _set_cached_property($fieldname, $value, $cache_type = null)
600
+	{
601
+		//first make sure this property exists
602
+		$this->get_model()->field_settings_for($fieldname);
603
+		$cache_type = empty($cache_type) ? 'standard' : $cache_type;
604
+		$this->_cached_properties[$fieldname][$cache_type] = $value;
605
+	}
606
+
607
+
608
+
609
+	/**
610
+	 * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
611
+	 * This also SETS the cache if we return the actual property!
612
+	 *
613
+	 * @param string $fieldname        the name of the property we're trying to retrieve
614
+	 * @param bool   $pretty
615
+	 * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
616
+	 *                                 (in cases where the same property may be used for different outputs
617
+	 *                                 - i.e. datetime, money etc.)
618
+	 *                                 It can also accept certain pre-defined "schema" strings
619
+	 *                                 to define how to output the property.
620
+	 *                                 see the field's prepare_for_pretty_echoing for what strings can be used
621
+	 * @return mixed                   whatever the value for the property is we're retrieving
622
+	 * @throws \EE_Error
623
+	 */
624
+	protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
625
+	{
626
+		//verify the field exists
627
+		$model = $this->get_model();
628
+		$model->field_settings_for($fieldname);
629
+		$cache_type = $pretty ? 'pretty' : 'standard';
630
+		$cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
631
+		if (isset($this->_cached_properties[$fieldname][$cache_type])) {
632
+			return $this->_cached_properties[$fieldname][$cache_type];
633
+		}
634
+		$value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
635
+		$this->_set_cached_property($fieldname, $value, $cache_type);
636
+		return $value;
637
+	}
638
+
639
+
640
+
641
+	/**
642
+	 * If the cache didn't fetch the needed item, this fetches it.
643
+	 * @param string $fieldname
644
+	 * @param bool $pretty
645
+	 * @param string $extra_cache_ref
646
+	 * @return mixed
647
+	 */
648
+	protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
649
+	{
650
+		$field_obj = $this->get_model()->field_settings_for($fieldname);
651
+		// If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
652
+		if ($field_obj instanceof EE_Datetime_Field) {
653
+			$this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
654
+		}
655
+		if ( ! isset($this->_fields[$fieldname])) {
656
+			$this->_fields[$fieldname] = null;
657
+		}
658
+		$value = $pretty
659
+			? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
660
+			: $field_obj->prepare_for_get($this->_fields[$fieldname]);
661
+		return $value;
662
+	}
663
+
664
+
665
+
666
+	/**
667
+	 * set timezone, formats, and output for EE_Datetime_Field objects
668
+	 *
669
+	 * @param \EE_Datetime_Field $datetime_field
670
+	 * @param bool               $pretty
671
+	 * @param null $date_or_time
672
+	 * @return void
673
+	 * @throws \EE_Error
674
+	 */
675
+	protected function _prepare_datetime_field(
676
+		EE_Datetime_Field $datetime_field,
677
+		$pretty = false,
678
+		$date_or_time = null
679
+	) {
680
+		$datetime_field->set_timezone($this->_timezone);
681
+		$datetime_field->set_date_format($this->_dt_frmt, $pretty);
682
+		$datetime_field->set_time_format($this->_tm_frmt, $pretty);
683
+		//set the output returned
684
+		switch ($date_or_time) {
685
+			case 'D' :
686
+				$datetime_field->set_date_time_output('date');
687
+				break;
688
+			case 'T' :
689
+				$datetime_field->set_date_time_output('time');
690
+				break;
691
+			default :
692
+				$datetime_field->set_date_time_output();
693
+		}
694
+	}
695
+
696
+
697
+
698
+	/**
699
+	 * This just takes care of clearing out the cached_properties
700
+	 *
701
+	 * @return void
702
+	 */
703
+	protected function _clear_cached_properties()
704
+	{
705
+		$this->_cached_properties = array();
706
+	}
707
+
708
+
709
+
710
+	/**
711
+	 * This just clears out ONE property if it exists in the cache
712
+	 *
713
+	 * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
714
+	 * @return void
715
+	 */
716
+	protected function _clear_cached_property($property_name)
717
+	{
718
+		if (isset($this->_cached_properties[$property_name])) {
719
+			unset($this->_cached_properties[$property_name]);
720
+		}
721
+	}
722
+
723
+
724
+
725
+	/**
726
+	 * Ensures that this related thing is a model object.
727
+	 *
728
+	 * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
729
+	 * @param string $model_name   name of the related thing, eg 'Attendee',
730
+	 * @return EE_Base_Class
731
+	 * @throws \EE_Error
732
+	 */
733
+	protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
734
+	{
735
+		$other_model_instance = self::_get_model_instance_with_name(
736
+			self::_get_model_classname($model_name),
737
+			$this->_timezone
738
+		);
739
+		return $other_model_instance->ensure_is_obj($object_or_id);
740
+	}
741
+
742
+
743
+
744
+	/**
745
+	 * Forgets the cached model of the given relation Name. So the next time we request it,
746
+	 * we will fetch it again from the database. (Handy if you know it's changed somehow).
747
+	 * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
748
+	 * then only remove that one object from our cached array. Otherwise, clear the entire list
749
+	 *
750
+	 * @param string $relationName                         one of the keys in the _model_relations array on the model.
751
+	 *                                                     Eg 'Registration'
752
+	 * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
753
+	 *                                                     if you intend to use $clear_all = TRUE, or the relation only
754
+	 *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
755
+	 * @param bool   $clear_all                            This flags clearing the entire cache relation property if
756
+	 *                                                     this is HasMany or HABTM.
757
+	 * @throws EE_Error
758
+	 * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
759
+	 *                       relation from all
760
+	 */
761
+	public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
762
+	{
763
+		$relationship_to_model = $this->get_model()->related_settings_for($relationName);
764
+		$index_in_cache = '';
765
+		if ( ! $relationship_to_model) {
766
+			throw new EE_Error(
767
+				sprintf(
768
+					__("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
769
+					$relationName,
770
+					get_class($this)
771
+				)
772
+			);
773
+		}
774
+		if ($clear_all) {
775
+			$obj_removed = true;
776
+			$this->_model_relations[$relationName] = null;
777
+		} elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
778
+			$obj_removed = $this->_model_relations[$relationName];
779
+			$this->_model_relations[$relationName] = null;
780
+		} else {
781
+			if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
782
+				&& $object_to_remove_or_index_into_array->ID()
783
+			) {
784
+				$index_in_cache = $object_to_remove_or_index_into_array->ID();
785
+				if (is_array($this->_model_relations[$relationName])
786
+					&& ! isset($this->_model_relations[$relationName][$index_in_cache])
787
+				) {
788
+					$index_found_at = null;
789
+					//find this object in the array even though it has a different key
790
+					foreach ($this->_model_relations[$relationName] as $index => $obj) {
791
+						if (
792
+							$obj instanceof EE_Base_Class
793
+							&& (
794
+								$obj == $object_to_remove_or_index_into_array
795
+								|| $obj->ID() === $object_to_remove_or_index_into_array->ID()
796
+							)
797
+						) {
798
+							$index_found_at = $index;
799
+							break;
800
+						}
801
+					}
802
+					if ($index_found_at) {
803
+						$index_in_cache = $index_found_at;
804
+					} else {
805
+						//it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
806
+						//if it wasn't in it to begin with. So we're done
807
+						return $object_to_remove_or_index_into_array;
808
+					}
809
+				}
810
+			} elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
811
+				//so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
812
+				foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
813
+					if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
814
+						$index_in_cache = $index;
815
+					}
816
+				}
817
+			} else {
818
+				$index_in_cache = $object_to_remove_or_index_into_array;
819
+			}
820
+			//supposedly we've found it. But it could just be that the client code
821
+			//provided a bad index/object
822
+			if (
823
+			isset(
824
+				$this->_model_relations[$relationName],
825
+				$this->_model_relations[$relationName][$index_in_cache]
826
+			)
827
+			) {
828
+				$obj_removed = $this->_model_relations[$relationName][$index_in_cache];
829
+				unset($this->_model_relations[$relationName][$index_in_cache]);
830
+			} else {
831
+				//that thing was never cached anyways.
832
+				$obj_removed = null;
833
+			}
834
+		}
835
+		return $obj_removed;
836
+	}
837
+
838
+
839
+
840
+	/**
841
+	 * update_cache_after_object_save
842
+	 * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
843
+	 * obtained after being saved to the db
844
+	 *
845
+	 * @param string         $relationName       - the type of object that is cached
846
+	 * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
847
+	 * @param string         $current_cache_id   - the ID that was used when originally caching the object
848
+	 * @return boolean TRUE on success, FALSE on fail
849
+	 * @throws \EE_Error
850
+	 */
851
+	public function update_cache_after_object_save(
852
+		$relationName,
853
+		EE_Base_Class $newly_saved_object,
854
+		$current_cache_id = ''
855
+	) {
856
+		// verify that incoming object is of the correct type
857
+		$obj_class = 'EE_' . $relationName;
858
+		if ($newly_saved_object instanceof $obj_class) {
859
+			/* @type EE_Base_Class $newly_saved_object */
860
+			// now get the type of relation
861
+			$relationship_to_model = $this->get_model()->related_settings_for($relationName);
862
+			// if this is a 1:1 relationship
863
+			if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
864
+				// then just replace the cached object with the newly saved object
865
+				$this->_model_relations[$relationName] = $newly_saved_object;
866
+				return true;
867
+				// or if it's some kind of sordid feral polyamorous relationship...
868
+			} elseif (is_array($this->_model_relations[$relationName])
869
+					  && isset($this->_model_relations[$relationName][$current_cache_id])
870
+			) {
871
+				// then remove the current cached item
872
+				unset($this->_model_relations[$relationName][$current_cache_id]);
873
+				// and cache the newly saved object using it's new ID
874
+				$this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
875
+				return true;
876
+			}
877
+		}
878
+		return false;
879
+	}
880
+
881
+
882
+
883
+	/**
884
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
885
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
886
+	 *
887
+	 * @param string $relationName
888
+	 * @return EE_Base_Class
889
+	 */
890
+	public function get_one_from_cache($relationName)
891
+	{
892
+		$cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
893
+			: null;
894
+		if (is_array($cached_array_or_object)) {
895
+			return array_shift($cached_array_or_object);
896
+		} else {
897
+			return $cached_array_or_object;
898
+		}
899
+	}
900
+
901
+
902
+
903
+	/**
904
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
905
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
906
+	 *
907
+	 * @param string $relationName
908
+	 * @throws \EE_Error
909
+	 * @return EE_Base_Class[] NOT necessarily indexed by primary keys
910
+	 */
911
+	public function get_all_from_cache($relationName)
912
+	{
913
+		$objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
914
+		// if the result is not an array, but exists, make it an array
915
+		$objects = is_array($objects) ? $objects : array($objects);
916
+		//bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
917
+		//basically, if this model object was stored in the session, and these cached model objects
918
+		//already have IDs, let's make sure they're in their model's entity mapper
919
+		//otherwise we will have duplicates next time we call
920
+		// EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
921
+		$model = EE_Registry::instance()->load_model($relationName);
922
+		foreach ($objects as $model_object) {
923
+			if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
924
+				//ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
925
+				if ($model_object->ID()) {
926
+					$model->add_to_entity_map($model_object);
927
+				}
928
+			} else {
929
+				throw new EE_Error(
930
+					sprintf(
931
+						__(
932
+							'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
933
+							'event_espresso'
934
+						),
935
+						$relationName,
936
+						gettype($model_object)
937
+					)
938
+				);
939
+			}
940
+		}
941
+		return $objects;
942
+	}
943
+
944
+
945
+
946
+	/**
947
+	 * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
948
+	 * matching the given query conditions.
949
+	 *
950
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
951
+	 * @param int   $limit              How many objects to return.
952
+	 * @param array $query_params       Any additional conditions on the query.
953
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
954
+	 *                                  you can indicate just the columns you want returned
955
+	 * @return array|EE_Base_Class[]
956
+	 * @throws \EE_Error
957
+	 */
958
+	public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
959
+	{
960
+		$model = $this->get_model();
961
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
962
+			? $model->get_primary_key_field()->get_name()
963
+			: $field_to_order_by;
964
+		$current_value = ! empty($field) ? $this->get($field) : null;
965
+		if (empty($field) || empty($current_value)) {
966
+			return array();
967
+		}
968
+		return $model->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
969
+	}
970
+
971
+
972
+
973
+	/**
974
+	 * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
975
+	 * matching the given query conditions.
976
+	 *
977
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
978
+	 * @param int   $limit              How many objects to return.
979
+	 * @param array $query_params       Any additional conditions on the query.
980
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
981
+	 *                                  you can indicate just the columns you want returned
982
+	 * @return array|EE_Base_Class[]
983
+	 * @throws \EE_Error
984
+	 */
985
+	public function previous_x(
986
+		$field_to_order_by = null,
987
+		$limit = 1,
988
+		$query_params = array(),
989
+		$columns_to_select = null
990
+	) {
991
+		$model = $this->get_model();
992
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
993
+			? $model->get_primary_key_field()->get_name()
994
+			: $field_to_order_by;
995
+		$current_value = ! empty($field) ? $this->get($field) : null;
996
+		if (empty($field) || empty($current_value)) {
997
+			return array();
998
+		}
999
+		return $model->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
1000
+	}
1001
+
1002
+
1003
+
1004
+	/**
1005
+	 * Returns the next EE_Base_Class object in sequence from this object as found in the database
1006
+	 * matching the given query conditions.
1007
+	 *
1008
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
1009
+	 * @param array $query_params       Any additional conditions on the query.
1010
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
1011
+	 *                                  you can indicate just the columns you want returned
1012
+	 * @return array|EE_Base_Class
1013
+	 * @throws \EE_Error
1014
+	 */
1015
+	public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1016
+	{
1017
+		$model = $this->get_model();
1018
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
1019
+			? $model->get_primary_key_field()->get_name()
1020
+			: $field_to_order_by;
1021
+		$current_value = ! empty($field) ? $this->get($field) : null;
1022
+		if (empty($field) || empty($current_value)) {
1023
+			return array();
1024
+		}
1025
+		return $model->next($current_value, $field, $query_params, $columns_to_select);
1026
+	}
1027
+
1028
+
1029
+
1030
+	/**
1031
+	 * Returns the previous EE_Base_Class object in sequence from this object as found in the database
1032
+	 * matching the given query conditions.
1033
+	 *
1034
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
1035
+	 * @param array $query_params       Any additional conditions on the query.
1036
+	 * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
1037
+	 *                                  you can indicate just the column you want returned
1038
+	 * @return array|EE_Base_Class
1039
+	 * @throws \EE_Error
1040
+	 */
1041
+	public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
1042
+	{
1043
+		$model = $this->get_model();
1044
+		$field = empty($field_to_order_by) && $model->has_primary_key_field()
1045
+			? $model->get_primary_key_field()->get_name()
1046
+			: $field_to_order_by;
1047
+		$current_value = ! empty($field) ? $this->get($field) : null;
1048
+		if (empty($field) || empty($current_value)) {
1049
+			return array();
1050
+		}
1051
+		return $model->previous($current_value, $field, $query_params, $columns_to_select);
1052
+	}
1053
+
1054
+
1055
+
1056
+	/**
1057
+	 * Overrides parent because parent expects old models.
1058
+	 * This also doesn't do any validation, and won't work for serialized arrays
1059
+	 *
1060
+	 * @param string $field_name
1061
+	 * @param mixed  $field_value_from_db
1062
+	 * @throws \EE_Error
1063
+	 */
1064
+	public function set_from_db($field_name, $field_value_from_db)
1065
+	{
1066
+		$field_obj = $this->get_model()->field_settings_for($field_name);
1067
+		if ($field_obj instanceof EE_Model_Field_Base) {
1068
+			//you would think the DB has no NULLs for non-null label fields right? wrong!
1069
+			//eg, a CPT model object could have an entry in the posts table, but no
1070
+			//entry in the meta table. Meaning that all its columns in the meta table
1071
+			//are null! yikes! so when we find one like that, use defaults for its meta columns
1072
+			if ($field_value_from_db === null) {
1073
+				if ($field_obj->is_nullable()) {
1074
+					//if the field allows nulls, then let it be null
1075
+					$field_value = null;
1076
+				} else {
1077
+					$field_value = $field_obj->get_default_value();
1078
+				}
1079
+			} else {
1080
+				$field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1081
+			}
1082
+			$this->_fields[$field_name] = $field_value;
1083
+			$this->_clear_cached_property($field_name);
1084
+		}
1085
+	}
1086
+
1087
+
1088
+
1089
+	/**
1090
+	 * verifies that the specified field is of the correct type
1091
+	 *
1092
+	 * @param string $field_name
1093
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1094
+	 *                                (in cases where the same property may be used for different outputs
1095
+	 *                                - i.e. datetime, money etc.)
1096
+	 * @return mixed
1097
+	 * @throws \EE_Error
1098
+	 */
1099
+	public function get($field_name, $extra_cache_ref = null)
1100
+	{
1101
+		return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1102
+	}
1103
+
1104
+
1105
+
1106
+	/**
1107
+	 * This method simply returns the RAW unprocessed value for the given property in this class
1108
+	 *
1109
+	 * @param  string $field_name A valid fieldname
1110
+	 * @return mixed              Whatever the raw value stored on the property is.
1111
+	 * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1112
+	 */
1113
+	public function get_raw($field_name)
1114
+	{
1115
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1116
+		return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1117
+			? $this->_fields[$field_name]->format('U')
1118
+			: $this->_fields[$field_name];
1119
+	}
1120
+
1121
+
1122
+
1123
+	/**
1124
+	 * This is used to return the internal DateTime object used for a field that is a
1125
+	 * EE_Datetime_Field.
1126
+	 *
1127
+	 * @param string $field_name               The field name retrieving the DateTime object.
1128
+	 * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1129
+	 * @throws \EE_Error
1130
+	 *                                         an error is set and false returned.  If the field IS an
1131
+	 *                                         EE_Datetime_Field and but the field value is null, then
1132
+	 *                                         just null is returned (because that indicates that likely
1133
+	 *                                         this field is nullable).
1134
+	 */
1135
+	public function get_DateTime_object($field_name)
1136
+	{
1137
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1138
+		if ( ! $field_settings instanceof EE_Datetime_Field) {
1139
+			EE_Error::add_error(
1140
+				sprintf(
1141
+					__(
1142
+						'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1143
+						'event_espresso'
1144
+					),
1145
+					$field_name
1146
+				),
1147
+				__FILE__,
1148
+				__FUNCTION__,
1149
+				__LINE__
1150
+			);
1151
+			return false;
1152
+		}
1153
+		return $this->_fields[$field_name];
1154
+	}
1155
+
1156
+
1157
+
1158
+	/**
1159
+	 * To be used in template to immediately echo out the value, and format it for output.
1160
+	 * Eg, should call stripslashes and whatnot before echoing
1161
+	 *
1162
+	 * @param string $field_name      the name of the field as it appears in the DB
1163
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1164
+	 *                                (in cases where the same property may be used for different outputs
1165
+	 *                                - i.e. datetime, money etc.)
1166
+	 * @return void
1167
+	 * @throws \EE_Error
1168
+	 */
1169
+	public function e($field_name, $extra_cache_ref = null)
1170
+	{
1171
+		echo $this->get_pretty($field_name, $extra_cache_ref);
1172
+	}
1173
+
1174
+
1175
+
1176
+	/**
1177
+	 * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1178
+	 * can be easily used as the value of form input.
1179
+	 *
1180
+	 * @param string $field_name
1181
+	 * @return void
1182
+	 * @throws \EE_Error
1183
+	 */
1184
+	public function f($field_name)
1185
+	{
1186
+		$this->e($field_name, 'form_input');
1187
+	}
1188
+
1189
+
1190
+
1191
+	/**
1192
+	 * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1193
+	 * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1194
+	 * to see what options are available.
1195
+	 * @param string $field_name
1196
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1197
+	 *                                (in cases where the same property may be used for different outputs
1198
+	 *                                - i.e. datetime, money etc.)
1199
+	 * @return mixed
1200
+	 * @throws \EE_Error
1201
+	 */
1202
+	public function get_pretty($field_name, $extra_cache_ref = null)
1203
+	{
1204
+		return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1205
+	}
1206
+
1207
+
1208
+
1209
+	/**
1210
+	 * This simply returns the datetime for the given field name
1211
+	 * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1212
+	 * (and the equivalent e_date, e_time, e_datetime).
1213
+	 *
1214
+	 * @access   protected
1215
+	 * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1216
+	 * @param string   $dt_frmt      valid datetime format used for date
1217
+	 *                               (if '' then we just use the default on the field,
1218
+	 *                               if NULL we use the last-used format)
1219
+	 * @param string   $tm_frmt      Same as above except this is for time format
1220
+	 * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1221
+	 * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1222
+	 * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1223
+	 *                               if field is not a valid dtt field, or void if echoing
1224
+	 * @throws \EE_Error
1225
+	 */
1226
+	protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1227
+	{
1228
+		// clear cached property
1229
+		$this->_clear_cached_property($field_name);
1230
+		//reset format properties because they are used in get()
1231
+		$this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1232
+		$this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1233
+		if ($echo) {
1234
+			$this->e($field_name, $date_or_time);
1235
+			return '';
1236
+		}
1237
+		return $this->get($field_name, $date_or_time);
1238
+	}
1239
+
1240
+
1241
+
1242
+	/**
1243
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1244
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1245
+	 * other echoes the pretty value for dtt)
1246
+	 *
1247
+	 * @param  string $field_name name of model object datetime field holding the value
1248
+	 * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1249
+	 * @return string            datetime value formatted
1250
+	 * @throws \EE_Error
1251
+	 */
1252
+	public function get_date($field_name, $format = '')
1253
+	{
1254
+		return $this->_get_datetime($field_name, $format, null, 'D');
1255
+	}
1256
+
1257
+
1258
+
1259
+	/**
1260
+	 * @param      $field_name
1261
+	 * @param string $format
1262
+	 * @throws \EE_Error
1263
+	 */
1264
+	public function e_date($field_name, $format = '')
1265
+	{
1266
+		$this->_get_datetime($field_name, $format, null, 'D', true);
1267
+	}
1268
+
1269
+
1270
+
1271
+	/**
1272
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1273
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1274
+	 * other echoes the pretty value for dtt)
1275
+	 *
1276
+	 * @param  string $field_name name of model object datetime field holding the value
1277
+	 * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1278
+	 * @return string             datetime value formatted
1279
+	 * @throws \EE_Error
1280
+	 */
1281
+	public function get_time($field_name, $format = '')
1282
+	{
1283
+		return $this->_get_datetime($field_name, null, $format, 'T');
1284
+	}
1285
+
1286
+
1287
+
1288
+	/**
1289
+	 * @param      $field_name
1290
+	 * @param string $format
1291
+	 * @throws \EE_Error
1292
+	 */
1293
+	public function e_time($field_name, $format = '')
1294
+	{
1295
+		$this->_get_datetime($field_name, null, $format, 'T', true);
1296
+	}
1297
+
1298
+
1299
+
1300
+	/**
1301
+	 * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1302
+	 * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1303
+	 * other echoes the pretty value for dtt)
1304
+	 *
1305
+	 * @param  string $field_name name of model object datetime field holding the value
1306
+	 * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1307
+	 * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1308
+	 * @return string             datetime value formatted
1309
+	 * @throws \EE_Error
1310
+	 */
1311
+	public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1312
+	{
1313
+		return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1314
+	}
1315
+
1316
+
1317
+
1318
+	/**
1319
+	 * @param string $field_name
1320
+	 * @param string $dt_frmt
1321
+	 * @param string $tm_frmt
1322
+	 * @throws \EE_Error
1323
+	 */
1324
+	public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1325
+	{
1326
+		$this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1327
+	}
1328
+
1329
+
1330
+
1331
+	/**
1332
+	 * Get the i8ln value for a date using the WordPress @see date_i18n function.
1333
+	 *
1334
+	 * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1335
+	 * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1336
+	 *                           on the object will be used.
1337
+	 * @return string Date and time string in set locale or false if no field exists for the given
1338
+	 * @throws \EE_Error
1339
+	 *                           field name.
1340
+	 */
1341
+	public function get_i18n_datetime($field_name, $format = '')
1342
+	{
1343
+		$format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1344
+		return date_i18n(
1345
+			$format,
1346
+			EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1347
+		);
1348
+	}
1349
+
1350
+
1351
+
1352
+	/**
1353
+	 * This method validates whether the given field name is a valid field on the model object as well as it is of a
1354
+	 * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1355
+	 * thrown.
1356
+	 *
1357
+	 * @param  string $field_name The field name being checked
1358
+	 * @throws EE_Error
1359
+	 * @return EE_Datetime_Field
1360
+	 */
1361
+	protected function _get_dtt_field_settings($field_name)
1362
+	{
1363
+		$field = $this->get_model()->field_settings_for($field_name);
1364
+		//check if field is dtt
1365
+		if ($field instanceof EE_Datetime_Field) {
1366
+			return $field;
1367
+		} else {
1368
+			throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1369
+				'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1370
+		}
1371
+	}
1372
+
1373
+
1374
+
1375
+
1376
+	/**
1377
+	 * NOTE ABOUT BELOW:
1378
+	 * These convenience date and time setters are for setting date and time independently.  In other words you might
1379
+	 * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1380
+	 * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1381
+	 * method and make sure you send the entire datetime value for setting.
1382
+	 */
1383
+	/**
1384
+	 * sets the time on a datetime property
1385
+	 *
1386
+	 * @access protected
1387
+	 * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1388
+	 * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1389
+	 * @throws \EE_Error
1390
+	 */
1391
+	protected function _set_time_for($time, $fieldname)
1392
+	{
1393
+		$this->_set_date_time('T', $time, $fieldname);
1394
+	}
1395
+
1396
+
1397
+
1398
+	/**
1399
+	 * sets the date on a datetime property
1400
+	 *
1401
+	 * @access protected
1402
+	 * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1403
+	 * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1404
+	 * @throws \EE_Error
1405
+	 */
1406
+	protected function _set_date_for($date, $fieldname)
1407
+	{
1408
+		$this->_set_date_time('D', $date, $fieldname);
1409
+	}
1410
+
1411
+
1412
+
1413
+	/**
1414
+	 * This takes care of setting a date or time independently on a given model object property. This method also
1415
+	 * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1416
+	 *
1417
+	 * @access protected
1418
+	 * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1419
+	 * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1420
+	 * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1421
+	 *                                        EE_Datetime_Field property)
1422
+	 * @throws \EE_Error
1423
+	 */
1424
+	protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1425
+	{
1426
+		$field = $this->_get_dtt_field_settings($fieldname);
1427
+		$field->set_timezone($this->_timezone);
1428
+		$field->set_date_format($this->_dt_frmt);
1429
+		$field->set_time_format($this->_tm_frmt);
1430
+		switch ($what) {
1431
+			case 'T' :
1432
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1433
+					$datetime_value,
1434
+					$this->_fields[$fieldname]
1435
+				);
1436
+				break;
1437
+			case 'D' :
1438
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1439
+					$datetime_value,
1440
+					$this->_fields[$fieldname]
1441
+				);
1442
+				break;
1443
+			case 'B' :
1444
+				$this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1445
+				break;
1446
+		}
1447
+		$this->_clear_cached_property($fieldname);
1448
+	}
1449
+
1450
+
1451
+
1452
+	/**
1453
+	 * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1454
+	 * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1455
+	 * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1456
+	 * that could lead to some unexpected results!
1457
+	 *
1458
+	 * @access public
1459
+	 * @param string               $field_name This is the name of the field on the object that contains the date/time
1460
+	 *                                         value being returned.
1461
+	 * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1462
+	 * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1463
+	 * @param string               $prepend    You can include something to prepend on the timestamp
1464
+	 * @param string               $append     You can include something to append on the timestamp
1465
+	 * @throws EE_Error
1466
+	 * @return string timestamp
1467
+	 */
1468
+	public function display_in_my_timezone(
1469
+		$field_name,
1470
+		$callback = 'get_datetime',
1471
+		$args = null,
1472
+		$prepend = '',
1473
+		$append = ''
1474
+	) {
1475
+		$timezone = EEH_DTT_Helper::get_timezone();
1476
+		if ($timezone === $this->_timezone) {
1477
+			return '';
1478
+		}
1479
+		$original_timezone = $this->_timezone;
1480
+		$this->set_timezone($timezone);
1481
+		$fn = (array)$field_name;
1482
+		$args = array_merge($fn, (array)$args);
1483
+		if ( ! method_exists($this, $callback)) {
1484
+			throw new EE_Error(
1485
+				sprintf(
1486
+					__(
1487
+						'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1488
+						'event_espresso'
1489
+					),
1490
+					$callback
1491
+				)
1492
+			);
1493
+		}
1494
+		$args = (array)$args;
1495
+		$return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1496
+		$this->set_timezone($original_timezone);
1497
+		return $return;
1498
+	}
1499
+
1500
+
1501
+
1502
+	/**
1503
+	 * Deletes this model object.
1504
+	 * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1505
+	 * override
1506
+	 * `EE_Base_Class::_delete` NOT this class.
1507
+	 *
1508
+	 * @return boolean | int
1509
+	 * @throws \EE_Error
1510
+	 */
1511
+	public function delete()
1512
+	{
1513
+		/**
1514
+		 * Called just before the `EE_Base_Class::_delete` method call.
1515
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1516
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1517
+		 * soft deletes (trash) the object and does not permanently delete it.
1518
+		 *
1519
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1520
+		 */
1521
+		do_action('AHEE__EE_Base_Class__delete__before', $this);
1522
+		$result = $this->_delete();
1523
+		/**
1524
+		 * Called just after the `EE_Base_Class::_delete` method call.
1525
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1526
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1527
+		 * soft deletes (trash) the object and does not permanently delete it.
1528
+		 *
1529
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1530
+		 * @param boolean       $result
1531
+		 */
1532
+		do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1533
+		return $result;
1534
+	}
1535
+
1536
+
1537
+
1538
+	/**
1539
+	 * Calls the specific delete method for the instantiated class.
1540
+	 * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1541
+	 * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1542
+	 * `EE_Base_Class::delete`
1543
+	 *
1544
+	 * @return bool|int
1545
+	 * @throws \EE_Error
1546
+	 */
1547
+	protected function _delete()
1548
+	{
1549
+		return $this->delete_permanently();
1550
+	}
1551
+
1552
+
1553
+
1554
+	/**
1555
+	 * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1556
+	 * error)
1557
+	 *
1558
+	 * @return bool | int
1559
+	 * @throws \EE_Error
1560
+	 */
1561
+	public function delete_permanently()
1562
+	{
1563
+		/**
1564
+		 * Called just before HARD deleting a model object
1565
+		 *
1566
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1567
+		 */
1568
+		do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1569
+		$model = $this->get_model();
1570
+		$result = $model->delete_permanently_by_ID($this->ID());
1571
+		$this->refresh_cache_of_related_objects();
1572
+		/**
1573
+		 * Called just after HARD deleting a model object
1574
+		 *
1575
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1576
+		 * @param boolean       $result
1577
+		 */
1578
+		do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1579
+		return $result;
1580
+	}
1581
+
1582
+
1583
+
1584
+	/**
1585
+	 * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1586
+	 * related model objects
1587
+	 *
1588
+	 * @throws \EE_Error
1589
+	 */
1590
+	public function refresh_cache_of_related_objects()
1591
+	{
1592
+		$model = $this->get_model();
1593
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1594
+			if ( ! empty($this->_model_relations[$relation_name])) {
1595
+				$related_objects = $this->_model_relations[$relation_name];
1596
+				if ($relation_obj instanceof EE_Belongs_To_Relation) {
1597
+					//this relation only stores a single model object, not an array
1598
+					//but let's make it consistent
1599
+					$related_objects = array($related_objects);
1600
+				}
1601
+				foreach ($related_objects as $related_object) {
1602
+					//only refresh their cache if they're in memory
1603
+					if ($related_object instanceof EE_Base_Class) {
1604
+						$related_object->clear_cache($model->get_this_model_name(), $this);
1605
+					}
1606
+				}
1607
+			}
1608
+		}
1609
+	}
1610
+
1611
+
1612
+
1613
+	/**
1614
+	 *        Saves this object to the database. An array may be supplied to set some values on this
1615
+	 * object just before saving.
1616
+	 *
1617
+	 * @access public
1618
+	 * @param array $set_cols_n_values keys are field names, values are their new values,
1619
+	 *                                 if provided during the save() method (often client code will change the fields'
1620
+	 *                                 values before calling save)
1621
+	 * @throws \EE_Error
1622
+	 * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1623
+	 *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1624
+	 */
1625
+	public function save($set_cols_n_values = array())
1626
+	{
1627
+		$model = $this->get_model();
1628
+		/**
1629
+		 * Filters the fields we're about to save on the model object
1630
+		 *
1631
+		 * @param array         $set_cols_n_values
1632
+		 * @param EE_Base_Class $model_object
1633
+		 */
1634
+		$set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1635
+			$this);
1636
+		//set attributes as provided in $set_cols_n_values
1637
+		foreach ($set_cols_n_values as $column => $value) {
1638
+			$this->set($column, $value);
1639
+		}
1640
+		// no changes ? then don't do anything
1641
+		if (! $this->_has_changes && $this->ID() && $model->get_primary_key_field()->is_auto_increment()) {
1642
+			return 0;
1643
+		}
1644
+		/**
1645
+		 * Saving a model object.
1646
+		 * Before we perform a save, this action is fired.
1647
+		 *
1648
+		 * @param EE_Base_Class $model_object the model object about to be saved.
1649
+		 */
1650
+		do_action('AHEE__EE_Base_Class__save__begin', $this);
1651
+		if ( ! $this->allow_persist()) {
1652
+			return 0;
1653
+		}
1654
+		//now get current attribute values
1655
+		$save_cols_n_values = $this->_fields;
1656
+		//if the object already has an ID, update it. Otherwise, insert it
1657
+		//also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1658
+		$old_assumption_concerning_value_preparation = $model
1659
+															->get_assumption_concerning_values_already_prepared_by_model_object();
1660
+		$model->assume_values_already_prepared_by_model_object(true);
1661
+		//does this model have an autoincrement PK?
1662
+		if ($model->has_primary_key_field()) {
1663
+			if ($model->get_primary_key_field()->is_auto_increment()) {
1664
+				//ok check if it's set, if so: update; if not, insert
1665
+				if ( ! empty($save_cols_n_values[$model->primary_key_name()])) {
1666
+					$results = $model->update_by_ID($save_cols_n_values, $this->ID());
1667
+				} else {
1668
+					unset($save_cols_n_values[$model->primary_key_name()]);
1669
+					$results = $model->insert($save_cols_n_values);
1670
+					if ($results) {
1671
+						//if successful, set the primary key
1672
+						//but don't use the normal SET method, because it will check if
1673
+						//an item with the same ID exists in the mapper & db, then
1674
+						//will find it in the db (because we just added it) and THAT object
1675
+						//will get added to the mapper before we can add this one!
1676
+						//but if we just avoid using the SET method, all that headache can be avoided
1677
+						$pk_field_name = $model->primary_key_name();
1678
+						$this->_fields[$pk_field_name] = $results;
1679
+						$this->_clear_cached_property($pk_field_name);
1680
+						$model->add_to_entity_map($this);
1681
+						$this->_update_cached_related_model_objs_fks();
1682
+					}
1683
+				}
1684
+			} else {//PK is NOT auto-increment
1685
+				//so check if one like it already exists in the db
1686
+				if ($model->exists_by_ID($this->ID())) {
1687
+					if (WP_DEBUG && ! $this->in_entity_map()) {
1688
+						throw new EE_Error(
1689
+							sprintf(
1690
+								__('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1691
+									'event_espresso'),
1692
+								get_class($this),
1693
+								get_class($model) . '::instance()->add_to_entity_map()',
1694
+								get_class($model) . '::instance()->get_one_by_ID()',
1695
+								'<br />'
1696
+							)
1697
+						);
1698
+					}
1699
+					$results = $model->update_by_ID($save_cols_n_values, $this->ID());
1700
+				} else {
1701
+					$results = $model->insert($save_cols_n_values);
1702
+					$this->_update_cached_related_model_objs_fks();
1703
+				}
1704
+			}
1705
+		} else {//there is NO primary key
1706
+			$already_in_db = false;
1707
+			foreach ($model->unique_indexes() as $index) {
1708
+				$uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1709
+				if ($model->exists(array($uniqueness_where_params))) {
1710
+					$already_in_db = true;
1711
+				}
1712
+			}
1713
+			if ($already_in_db) {
1714
+				$combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1715
+					$model->get_combined_primary_key_fields());
1716
+				$results = $model->update($save_cols_n_values, $combined_pk_fields_n_values);
1717
+			} else {
1718
+				$results = $model->insert($save_cols_n_values);
1719
+			}
1720
+		}
1721
+		//restore the old assumption about values being prepared by the model object
1722
+		$model
1723
+			 ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1724
+		/**
1725
+		 * After saving the model object this action is called
1726
+		 *
1727
+		 * @param EE_Base_Class $model_object which was just saved
1728
+		 * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1729
+		 *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1730
+		 */
1731
+		do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1732
+		$this->_has_changes = false;
1733
+		return $results;
1734
+	}
1735
+
1736
+
1737
+
1738
+	/**
1739
+	 * Updates the foreign key on related models objects pointing to this to have this model object's ID
1740
+	 * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1741
+	 * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1742
+	 * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1743
+	 * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1744
+	 * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1745
+	 * or not they exist in the DB (if they do, their DB records will be automatically updated)
1746
+	 *
1747
+	 * @return void
1748
+	 * @throws \EE_Error
1749
+	 */
1750
+	protected function _update_cached_related_model_objs_fks()
1751
+	{
1752
+		$model = $this->get_model();
1753
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
1754
+			if ($relation_obj instanceof EE_Has_Many_Relation) {
1755
+				foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1756
+					$fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1757
+						$model->get_this_model_name()
1758
+					);
1759
+					$related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1760
+					if ($related_model_obj_in_cache->ID()) {
1761
+						$related_model_obj_in_cache->save();
1762
+					}
1763
+				}
1764
+			}
1765
+		}
1766
+	}
1767
+
1768
+
1769
+
1770
+	/**
1771
+	 * Saves this model object and its NEW cached relations to the database.
1772
+	 * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1773
+	 * In order for that to work, we would need to mark model objects as dirty/clean...
1774
+	 * because otherwise, there's a potential for infinite looping of saving
1775
+	 * Saves the cached related model objects, and ensures the relation between them
1776
+	 * and this object and properly setup
1777
+	 *
1778
+	 * @return int ID of new model object on save; 0 on failure+
1779
+	 * @throws \EE_Error
1780
+	 */
1781
+	public function save_new_cached_related_model_objs()
1782
+	{
1783
+		//make sure this has been saved
1784
+		if ( ! $this->ID()) {
1785
+			$id = $this->save();
1786
+		} else {
1787
+			$id = $this->ID();
1788
+		}
1789
+		//now save all the NEW cached model objects  (ie they don't exist in the DB)
1790
+		foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1791
+			if ($this->_model_relations[$relationName]) {
1792
+				//is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1793
+				//or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1794
+				if ($relationObj instanceof EE_Belongs_To_Relation) {
1795
+					//add a relation to that relation type (which saves the appropriate thing in the process)
1796
+					//but ONLY if it DOES NOT exist in the DB
1797
+					/* @var $related_model_obj EE_Base_Class */
1798
+					$related_model_obj = $this->_model_relations[$relationName];
1799
+					//					if( ! $related_model_obj->ID()){
1800
+					$this->_add_relation_to($related_model_obj, $relationName);
1801
+					$related_model_obj->save_new_cached_related_model_objs();
1802
+					//					}
1803
+				} else {
1804
+					foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1805
+						//add a relation to that relation type (which saves the appropriate thing in the process)
1806
+						//but ONLY if it DOES NOT exist in the DB
1807
+						//						if( ! $related_model_obj->ID()){
1808
+						$this->_add_relation_to($related_model_obj, $relationName);
1809
+						$related_model_obj->save_new_cached_related_model_objs();
1810
+						//						}
1811
+					}
1812
+				}
1813
+			}
1814
+		}
1815
+		return $id;
1816
+	}
1817
+
1818
+
1819
+
1820
+	/**
1821
+	 * for getting a model while instantiated.
1822
+	 *
1823
+	 * @return \EEM_Base | \EEM_CPT_Base
1824
+	 */
1825
+	public function get_model()
1826
+	{
1827
+		if( ! $this->_model){
1828
+			$modelName = self::_get_model_classname(get_class($this));
1829
+			$this->_model = self::_get_model_instance_with_name($modelName, $this->_timezone);
1830
+		} else {
1831
+			$this->_model->set_timezone($this->_timezone);
1832
+		}
1833
+
1834
+		return $this->_model;
1835
+	}
1836
+
1837
+
1838
+
1839
+	/**
1840
+	 * @param $props_n_values
1841
+	 * @param $classname
1842
+	 * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1843
+	 * @throws \EE_Error
1844
+	 */
1845
+	protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1846
+	{
1847
+		//TODO: will not work for Term_Relationships because they have no PK!
1848
+		$primary_id_ref = self::_get_primary_key_name($classname);
1849
+		if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1850
+			$id = $props_n_values[$primary_id_ref];
1851
+			return self::_get_model($classname)->get_from_entity_map($id);
1852
+		}
1853
+		return false;
1854
+	}
1855
+
1856
+
1857
+
1858
+	/**
1859
+	 * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1860
+	 * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1861
+	 * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1862
+	 * we return false.
1863
+	 *
1864
+	 * @param  array  $props_n_values   incoming array of properties and their values
1865
+	 * @param  string $classname        the classname of the child class
1866
+	 * @param null    $timezone
1867
+	 * @param array   $date_formats     incoming date_formats in an array where the first value is the
1868
+	 *                                  date_format and the second value is the time format
1869
+	 * @return mixed (EE_Base_Class|bool)
1870
+	 * @throws \EE_Error
1871
+	 */
1872
+	protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1873
+	{
1874
+		$existing = null;
1875
+		$model = self::_get_model($classname, $timezone);
1876
+		if ($model->has_primary_key_field()) {
1877
+			$primary_id_ref = self::_get_primary_key_name($classname);
1878
+			if (array_key_exists($primary_id_ref, $props_n_values)
1879
+				&& ! empty($props_n_values[$primary_id_ref])
1880
+			) {
1881
+				$existing = $model->get_one_by_ID(
1882
+					$props_n_values[$primary_id_ref]
1883
+				);
1884
+			}
1885
+		} elseif ($model->has_all_combined_primary_key_fields($props_n_values)) {
1886
+			//no primary key on this model, but there's still a matching item in the DB
1887
+			$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1888
+				self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1889
+			);
1890
+		}
1891
+		if ($existing) {
1892
+			//set date formats if present before setting values
1893
+			if ( ! empty($date_formats) && is_array($date_formats)) {
1894
+				$existing->set_date_format($date_formats[0]);
1895
+				$existing->set_time_format($date_formats[1]);
1896
+			} else {
1897
+				//set default formats for date and time
1898
+				$existing->set_date_format(get_option('date_format'));
1899
+				$existing->set_time_format(get_option('time_format'));
1900
+			}
1901
+			foreach ($props_n_values as $property => $field_value) {
1902
+				$existing->set($property, $field_value);
1903
+			}
1904
+			return $existing;
1905
+		} else {
1906
+			return false;
1907
+		}
1908
+	}
1909
+
1910
+
1911
+
1912
+	/**
1913
+	 * Gets the EEM_*_Model for this class
1914
+	 *
1915
+	 * @access public now, as this is more convenient
1916
+	 * @param      $classname
1917
+	 * @param null $timezone
1918
+	 * @throws EE_Error
1919
+	 * @return EEM_Base
1920
+	 */
1921
+	protected static function _get_model($classname, $timezone = null)
1922
+	{
1923
+		//find model for this class
1924
+		if ( ! $classname) {
1925
+			throw new EE_Error(
1926
+				sprintf(
1927
+					__(
1928
+						"What were you thinking calling _get_model(%s)?? You need to specify the class name",
1929
+						"event_espresso"
1930
+					),
1931
+					$classname
1932
+				)
1933
+			);
1934
+		}
1935
+		$modelName = self::_get_model_classname($classname);
1936
+		return self::_get_model_instance_with_name($modelName, $timezone);
1937
+	}
1938
+
1939
+
1940
+
1941
+	/**
1942
+	 * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1943
+	 *
1944
+	 * @param string $model_classname
1945
+	 * @param null   $timezone
1946
+	 * @return EEM_Base
1947
+	 */
1948
+	protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1949
+	{
1950
+		$model_classname = str_replace('EEM_', '', $model_classname);
1951
+		$model = EE_Registry::instance()->load_model($model_classname);
1952
+		$model->set_timezone($timezone);
1953
+		return $model;
1954
+	}
1955
+
1956
+
1957
+
1958
+	/**
1959
+	 * If a model name is provided (eg Registration), gets the model classname for that model.
1960
+	 * Also works if a model class's classname is provided (eg EE_Registration).
1961
+	 *
1962
+	 * @param null $model_name
1963
+	 * @return string like EEM_Attendee
1964
+	 */
1965
+	private static function _get_model_classname($model_name = null)
1966
+	{
1967
+		if (strpos($model_name, "EE_") === 0) {
1968
+			$model_classname = str_replace("EE_", "EEM_", $model_name);
1969
+		} else {
1970
+			$model_classname = "EEM_" . $model_name;
1971
+		}
1972
+		return $model_classname;
1973
+	}
1974
+
1975
+
1976
+
1977
+	/**
1978
+	 * returns the name of the primary key attribute
1979
+	 *
1980
+	 * @param null $classname
1981
+	 * @throws EE_Error
1982
+	 * @return string
1983
+	 */
1984
+	protected static function _get_primary_key_name($classname = null)
1985
+	{
1986
+		if ( ! $classname) {
1987
+			throw new EE_Error(
1988
+				sprintf(
1989
+					__("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1990
+					$classname
1991
+				)
1992
+			);
1993
+		}
1994
+		return self::_get_model($classname)->get_primary_key_field()->get_name();
1995
+	}
1996
+
1997
+
1998
+
1999
+	/**
2000
+	 * Gets the value of the primary key.
2001
+	 * If the object hasn't yet been saved, it should be whatever the model field's default was
2002
+	 * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
2003
+	 * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
2004
+	 *
2005
+	 * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
2006
+	 * @throws \EE_Error
2007
+	 */
2008
+	public function ID()
2009
+	{
2010
+		$model = $this->get_model();
2011
+		//now that we know the name of the variable, use a variable variable to get its value and return its
2012
+		if ($model->has_primary_key_field()) {
2013
+			return $this->_fields[$model->primary_key_name()];
2014
+		} else {
2015
+			return $model->get_index_primary_key_string($this->_fields);
2016
+		}
2017
+	}
2018
+
2019
+
2020
+
2021
+	/**
2022
+	 * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
2023
+	 * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
2024
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
2025
+	 *
2026
+	 * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
2027
+	 * @param string $relationName                     eg 'Events','Question',etc.
2028
+	 *                                                 an attendee to a group, you also want to specify which role they
2029
+	 *                                                 will have in that group. So you would use this parameter to
2030
+	 *                                                 specify array('role-column-name'=>'role-id')
2031
+	 * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
2032
+	 *                                                 allow you to further constrict the relation to being added.
2033
+	 *                                                 However, keep in mind that the columns (keys) given must match a
2034
+	 *                                                 column on the JOIN table and currently only the HABTM models
2035
+	 *                                                 accept these additional conditions.  Also remember that if an
2036
+	 *                                                 exact match isn't found for these extra cols/val pairs, then a
2037
+	 *                                                 NEW row is created in the join table.
2038
+	 * @param null   $cache_id
2039
+	 * @throws EE_Error
2040
+	 * @return EE_Base_Class the object the relation was added to
2041
+	 */
2042
+	public function _add_relation_to(
2043
+		$otherObjectModelObjectOrID,
2044
+		$relationName,
2045
+		$extra_join_model_fields_n_values = array(),
2046
+		$cache_id = null
2047
+	) {
2048
+		$model = $this->get_model();
2049
+		//if this thing exists in the DB, save the relation to the DB
2050
+		if ($this->ID()) {
2051
+			$otherObject = $model
2052
+								->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2053
+									$extra_join_model_fields_n_values);
2054
+			//clear cache so future get_many_related and get_first_related() return new results.
2055
+			$this->clear_cache($relationName, $otherObject, true);
2056
+			if ($otherObject instanceof EE_Base_Class) {
2057
+				$otherObject->clear_cache($model->get_this_model_name(), $this);
2058
+			}
2059
+		} else {
2060
+			//this thing doesn't exist in the DB,  so just cache it
2061
+			if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
2062
+				throw new EE_Error(sprintf(
2063
+					__('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2064
+						'event_espresso'),
2065
+					$otherObjectModelObjectOrID,
2066
+					get_class($this)
2067
+				));
2068
+			} else {
2069
+				$otherObject = $otherObjectModelObjectOrID;
2070
+			}
2071
+			$this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2072
+		}
2073
+		if ($otherObject instanceof EE_Base_Class) {
2074
+			//fix the reciprocal relation too
2075
+			if ($otherObject->ID()) {
2076
+				//its saved so assumed relations exist in the DB, so we can just
2077
+				//clear the cache so future queries use the updated info in the DB
2078
+				$otherObject->clear_cache($model->get_this_model_name(), null, true);
2079
+			} else {
2080
+				//it's not saved, so it caches relations like this
2081
+				$otherObject->cache($model->get_this_model_name(), $this);
2082
+			}
2083
+		}
2084
+		return $otherObject;
2085
+	}
2086
+
2087
+
2088
+
2089
+	/**
2090
+	 * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2091
+	 * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2092
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2093
+	 * from the cache
2094
+	 *
2095
+	 * @param mixed  $otherObjectModelObjectOrID
2096
+	 *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2097
+	 *                to the DB yet
2098
+	 * @param string $relationName
2099
+	 * @param array  $where_query
2100
+	 *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2101
+	 *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2102
+	 *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2103
+	 *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2104
+	 *                created in the join table.
2105
+	 * @return EE_Base_Class the relation was removed from
2106
+	 * @throws \EE_Error
2107
+	 */
2108
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2109
+	{
2110
+		if ($this->ID()) {
2111
+			//if this exists in the DB, save the relation change to the DB too
2112
+			$otherObject = $this->get_model()
2113
+								->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2114
+									$where_query);
2115
+			$this->clear_cache($relationName, $otherObject);
2116
+		} else {
2117
+			//this doesn't exist in the DB, just remove it from the cache
2118
+			$otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2119
+		}
2120
+		if ($otherObject instanceof EE_Base_Class) {
2121
+			$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2122
+		}
2123
+		return $otherObject;
2124
+	}
2125
+
2126
+
2127
+
2128
+	/**
2129
+	 * Removes ALL the related things for the $relationName.
2130
+	 *
2131
+	 * @param string $relationName
2132
+	 * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2133
+	 * @return EE_Base_Class
2134
+	 * @throws \EE_Error
2135
+	 */
2136
+	public function _remove_relations($relationName, $where_query_params = array())
2137
+	{
2138
+		if ($this->ID()) {
2139
+			//if this exists in the DB, save the relation change to the DB too
2140
+			$otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2141
+			$this->clear_cache($relationName, null, true);
2142
+		} else {
2143
+			//this doesn't exist in the DB, just remove it from the cache
2144
+			$otherObjects = $this->clear_cache($relationName, null, true);
2145
+		}
2146
+		if (is_array($otherObjects)) {
2147
+			foreach ($otherObjects as $otherObject) {
2148
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2149
+			}
2150
+		}
2151
+		return $otherObjects;
2152
+	}
2153
+
2154
+
2155
+
2156
+	/**
2157
+	 * Gets all the related model objects of the specified type. Eg, if the current class if
2158
+	 * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2159
+	 * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2160
+	 * because we want to get even deleted items etc.
2161
+	 *
2162
+	 * @param string $relationName key in the model's _model_relations array
2163
+	 * @param array  $query_params like EEM_Base::get_all
2164
+	 * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2165
+	 * @throws \EE_Error
2166
+	 *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2167
+	 *                             you want IDs
2168
+	 */
2169
+	public function get_many_related($relationName, $query_params = array())
2170
+	{
2171
+		if ($this->ID()) {
2172
+			//this exists in the DB, so get the related things from either the cache or the DB
2173
+			//if there are query parameters, forget about caching the related model objects.
2174
+			if ($query_params) {
2175
+				$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2176
+			} else {
2177
+				//did we already cache the result of this query?
2178
+				$cached_results = $this->get_all_from_cache($relationName);
2179
+				if ( ! $cached_results) {
2180
+					$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2181
+					//if no query parameters were passed, then we got all the related model objects
2182
+					//for that relation. We can cache them then.
2183
+					foreach ($related_model_objects as $related_model_object) {
2184
+						$this->cache($relationName, $related_model_object);
2185
+					}
2186
+				} else {
2187
+					$related_model_objects = $cached_results;
2188
+				}
2189
+			}
2190
+		} else {
2191
+			//this doesn't exist in the DB, so just get the related things from the cache
2192
+			$related_model_objects = $this->get_all_from_cache($relationName);
2193
+		}
2194
+		return $related_model_objects;
2195
+	}
2196
+
2197
+
2198
+
2199
+	/**
2200
+	 * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2201
+	 * unless otherwise specified in the $query_params
2202
+	 *
2203
+	 * @param string $relation_name  model_name like 'Event', or 'Registration'
2204
+	 * @param array  $query_params   like EEM_Base::get_all's
2205
+	 * @param string $field_to_count name of field to count by. By default, uses primary key
2206
+	 * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2207
+	 *                               that by the setting $distinct to TRUE;
2208
+	 * @return int
2209
+	 */
2210
+	public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2211
+	{
2212
+		return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2213
+	}
2214
+
2215
+
2216
+
2217
+	/**
2218
+	 * Instead of getting the related model objects, simply sums up the values of the specified field.
2219
+	 * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2220
+	 *
2221
+	 * @param string $relation_name model_name like 'Event', or 'Registration'
2222
+	 * @param array  $query_params  like EEM_Base::get_all's
2223
+	 * @param string $field_to_sum  name of field to count by.
2224
+	 *                              By default, uses primary key (which doesn't make much sense, so you should probably
2225
+	 *                              change it)
2226
+	 * @return int
2227
+	 */
2228
+	public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2229
+	{
2230
+		return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2231
+	}
2232
+
2233
+
2234
+
2235
+	/**
2236
+	 * Gets the first (ie, one) related model object of the specified type.
2237
+	 *
2238
+	 * @param string $relationName key in the model's _model_relations array
2239
+	 * @param array  $query_params like EEM_Base::get_all
2240
+	 * @return EE_Base_Class (not an array, a single object)
2241
+	 * @throws \EE_Error
2242
+	 */
2243
+	public function get_first_related($relationName, $query_params = array())
2244
+	{
2245
+		$model = $this->get_model();
2246
+		if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2247
+			//if they've provided some query parameters, don't bother trying to cache the result
2248
+			//also make sure we're not caching the result of get_first_related
2249
+			//on a relation which should have an array of objects (because the cache might have an array of objects)
2250
+			if ($query_params
2251
+				|| ! $model->related_settings_for($relationName)
2252
+					 instanceof
2253
+					 EE_Belongs_To_Relation
2254
+			) {
2255
+				$related_model_object = $model->get_first_related($this, $relationName, $query_params);
2256
+			} else {
2257
+				//first, check if we've already cached the result of this query
2258
+				$cached_result = $this->get_one_from_cache($relationName);
2259
+				if ( ! $cached_result) {
2260
+					$related_model_object = $model->get_first_related($this, $relationName, $query_params);
2261
+					$this->cache($relationName, $related_model_object);
2262
+				} else {
2263
+					$related_model_object = $cached_result;
2264
+				}
2265
+			}
2266
+		} else {
2267
+			$related_model_object = null;
2268
+			//this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2269
+			if ($model->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2270
+				$related_model_object = $model->get_first_related($this, $relationName, $query_params);
2271
+			}
2272
+			//this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2273
+			if ( ! $related_model_object) {
2274
+				$related_model_object = $this->get_one_from_cache($relationName);
2275
+			}
2276
+		}
2277
+		return $related_model_object;
2278
+	}
2279
+
2280
+
2281
+
2282
+	/**
2283
+	 * Does a delete on all related objects of type $relationName and removes
2284
+	 * the current model object's relation to them. If they can't be deleted (because
2285
+	 * of blocking related model objects) does nothing. If the related model objects are
2286
+	 * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2287
+	 * If this model object doesn't exist yet in the DB, just removes its related things
2288
+	 *
2289
+	 * @param string $relationName
2290
+	 * @param array  $query_params like EEM_Base::get_all's
2291
+	 * @return int how many deleted
2292
+	 * @throws \EE_Error
2293
+	 */
2294
+	public function delete_related($relationName, $query_params = array())
2295
+	{
2296
+		if ($this->ID()) {
2297
+			$count = $this->get_model()->delete_related($this, $relationName, $query_params);
2298
+		} else {
2299
+			$count = count($this->get_all_from_cache($relationName));
2300
+			$this->clear_cache($relationName, null, true);
2301
+		}
2302
+		return $count;
2303
+	}
2304
+
2305
+
2306
+
2307
+	/**
2308
+	 * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2309
+	 * the current model object's relation to them. If they can't be deleted (because
2310
+	 * of blocking related model objects) just does a soft delete on it instead, if possible.
2311
+	 * If the related thing isn't a soft-deletable model object, this function is identical
2312
+	 * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2313
+	 *
2314
+	 * @param string $relationName
2315
+	 * @param array  $query_params like EEM_Base::get_all's
2316
+	 * @return int how many deleted (including those soft deleted)
2317
+	 * @throws \EE_Error
2318
+	 */
2319
+	public function delete_related_permanently($relationName, $query_params = array())
2320
+	{
2321
+		if ($this->ID()) {
2322
+			$count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2323
+		} else {
2324
+			$count = count($this->get_all_from_cache($relationName));
2325
+		}
2326
+		$this->clear_cache($relationName, null, true);
2327
+		return $count;
2328
+	}
2329
+
2330
+
2331
+
2332
+	/**
2333
+	 * is_set
2334
+	 * Just a simple utility function children can use for checking if property exists
2335
+	 *
2336
+	 * @access  public
2337
+	 * @param  string $field_name property to check
2338
+	 * @return bool                              TRUE if existing,FALSE if not.
2339
+	 */
2340
+	public function is_set($field_name)
2341
+	{
2342
+		return isset($this->_fields[$field_name]);
2343
+	}
2344
+
2345
+
2346
+
2347
+	/**
2348
+	 * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2349
+	 * EE_Error exception if they don't
2350
+	 *
2351
+	 * @param  mixed (string|array) $properties properties to check
2352
+	 * @throws EE_Error
2353
+	 * @return bool                              TRUE if existing, throw EE_Error if not.
2354
+	 */
2355
+	protected function _property_exists($properties)
2356
+	{
2357
+		foreach ((array)$properties as $property_name) {
2358
+			//first make sure this property exists
2359
+			if ( ! $this->_fields[$property_name]) {
2360
+				throw new EE_Error(
2361
+					sprintf(
2362
+						__(
2363
+							'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2364
+							'event_espresso'
2365
+						),
2366
+						$property_name
2367
+					)
2368
+				);
2369
+			}
2370
+		}
2371
+		return true;
2372
+	}
2373
+
2374
+
2375
+
2376
+	/**
2377
+	 * This simply returns an array of model fields for this object
2378
+	 *
2379
+	 * @return array
2380
+	 * @throws \EE_Error
2381
+	 */
2382
+	public function model_field_array()
2383
+	{
2384
+		$fields = $this->get_model()->field_settings(false);
2385
+		$properties = array();
2386
+		//remove prepended underscore
2387
+		foreach ($fields as $field_name => $settings) {
2388
+			$properties[$field_name] = $this->get($field_name);
2389
+		}
2390
+		return $properties;
2391
+	}
2392
+
2393
+
2394
+
2395
+	/**
2396
+	 * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2397
+	 * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2398
+	 * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2399
+	 * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2400
+	 * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2401
+	 * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2402
+	 * was called, and an array of the original arguments passed to the function. Whatever their callback function
2403
+	 * returns will be returned by this function. Example: in functions.php (or in a plugin):
2404
+	 * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2405
+	 * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2406
+	 * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2407
+	 *        return $previousReturnValue.$returnString;
2408
+	 * }
2409
+	 * require('EE_Answer.class.php');
2410
+	 * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2411
+	 * echo $answer->my_callback('monkeys',100);
2412
+	 * //will output "you called my_callback! and passed args:monkeys,100"
2413
+	 *
2414
+	 * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2415
+	 * @param array  $args       array of original arguments passed to the function
2416
+	 * @throws EE_Error
2417
+	 * @return mixed whatever the plugin which calls add_filter decides
2418
+	 */
2419
+	public function __call($methodName, $args)
2420
+	{
2421
+		$className = get_class($this);
2422
+		$tagName = "FHEE__{$className}__{$methodName}";
2423
+		if ( ! has_filter($tagName)) {
2424
+			throw new EE_Error(
2425
+				sprintf(
2426
+					__(
2427
+						"Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2428
+						"event_espresso"
2429
+					),
2430
+					$methodName,
2431
+					$className,
2432
+					$tagName
2433
+				)
2434
+			);
2435
+		}
2436
+		return apply_filters($tagName, null, $this, $args);
2437
+	}
2438
+
2439
+
2440
+
2441
+	/**
2442
+	 * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2443
+	 * A $previous_value can be specified in case there are many meta rows with the same key
2444
+	 *
2445
+	 * @param string $meta_key
2446
+	 * @param mixed  $meta_value
2447
+	 * @param mixed  $previous_value
2448
+	 * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2449
+	 * @throws \EE_Error
2450
+	 * NOTE: if the values haven't changed, returns 0
2451
+	 */
2452
+	public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2453
+	{
2454
+		$query_params = array(
2455
+			array(
2456
+				'EXM_key'  => $meta_key,
2457
+				'OBJ_ID'   => $this->ID(),
2458
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2459
+			),
2460
+		);
2461
+		if ($previous_value !== null) {
2462
+			$query_params[0]['EXM_value'] = $meta_value;
2463
+		}
2464
+		$existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2465
+		if ( ! $existing_rows_like_that) {
2466
+			return $this->add_extra_meta($meta_key, $meta_value);
2467
+		}
2468
+		foreach ($existing_rows_like_that as $existing_row) {
2469
+			$existing_row->save(array('EXM_value' => $meta_value));
2470
+		}
2471
+		return count($existing_rows_like_that);
2472
+	}
2473
+
2474
+
2475
+
2476
+	/**
2477
+	 * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2478
+	 * no other extra meta for this model object have the same key. Returns TRUE if the
2479
+	 * extra meta row was entered, false if not
2480
+	 *
2481
+	 * @param string  $meta_key
2482
+	 * @param string  $meta_value
2483
+	 * @param boolean $unique
2484
+	 * @return boolean
2485
+	 * @throws \EE_Error
2486
+	 */
2487
+	public function add_extra_meta($meta_key, $meta_value, $unique = false)
2488
+	{
2489
+		if ($unique) {
2490
+			$existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2491
+				array(
2492
+					array(
2493
+						'EXM_key'  => $meta_key,
2494
+						'OBJ_ID'   => $this->ID(),
2495
+						'EXM_type' => $this->get_model()->get_this_model_name(),
2496
+					),
2497
+				)
2498
+			);
2499
+			if ($existing_extra_meta) {
2500
+				return false;
2501
+			}
2502
+		}
2503
+		$new_extra_meta = EE_Extra_Meta::new_instance(
2504
+			array(
2505
+				'EXM_key'   => $meta_key,
2506
+				'EXM_value' => $meta_value,
2507
+				'OBJ_ID'    => $this->ID(),
2508
+				'EXM_type'  => $this->get_model()->get_this_model_name(),
2509
+			)
2510
+		);
2511
+		$new_extra_meta->save();
2512
+		return true;
2513
+	}
2514
+
2515
+
2516
+
2517
+	/**
2518
+	 * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2519
+	 * is specified, only deletes extra meta records with that value.
2520
+	 *
2521
+	 * @param string $meta_key
2522
+	 * @param string $meta_value
2523
+	 * @return int number of extra meta rows deleted
2524
+	 * @throws \EE_Error
2525
+	 */
2526
+	public function delete_extra_meta($meta_key, $meta_value = null)
2527
+	{
2528
+		$query_params = array(
2529
+			array(
2530
+				'EXM_key'  => $meta_key,
2531
+				'OBJ_ID'   => $this->ID(),
2532
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2533
+			),
2534
+		);
2535
+		if ($meta_value !== null) {
2536
+			$query_params[0]['EXM_value'] = $meta_value;
2537
+		}
2538
+		return EEM_Extra_Meta::instance()->delete($query_params);
2539
+	}
2540
+
2541
+
2542
+
2543
+	/**
2544
+	 * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2545
+	 * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2546
+	 * You can specify $default is case you haven't found the extra meta
2547
+	 *
2548
+	 * @param string  $meta_key
2549
+	 * @param boolean $single
2550
+	 * @param mixed   $default if we don't find anything, what should we return?
2551
+	 * @return mixed single value if $single; array if ! $single
2552
+	 * @throws \EE_Error
2553
+	 */
2554
+	public function get_extra_meta($meta_key, $single = false, $default = null)
2555
+	{
2556
+		if ($single) {
2557
+			$result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2558
+			if ($result instanceof EE_Extra_Meta) {
2559
+				return $result->value();
2560
+			} else {
2561
+				return $default;
2562
+			}
2563
+		} else {
2564
+			$results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2565
+			if ($results) {
2566
+				$values = array();
2567
+				foreach ($results as $result) {
2568
+					if ($result instanceof EE_Extra_Meta) {
2569
+						$values[$result->ID()] = $result->value();
2570
+					}
2571
+				}
2572
+				return $values;
2573
+			} else {
2574
+				return $default;
2575
+			}
2576
+		}
2577
+	}
2578
+
2579
+
2580
+
2581
+	/**
2582
+	 * Returns a simple array of all the extra meta associated with this model object.
2583
+	 * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2584
+	 * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2585
+	 * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2586
+	 * If $one_of_each_key is false, it will return an array with the top-level keys being
2587
+	 * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2588
+	 * finally the extra meta's value as each sub-value. (eg
2589
+	 * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2590
+	 *
2591
+	 * @param boolean $one_of_each_key
2592
+	 * @return array
2593
+	 * @throws \EE_Error
2594
+	 */
2595
+	public function all_extra_meta_array($one_of_each_key = true)
2596
+	{
2597
+		$return_array = array();
2598
+		if ($one_of_each_key) {
2599
+			$extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2600
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2601
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2602
+					$return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2603
+				}
2604
+			}
2605
+		} else {
2606
+			$extra_meta_objs = $this->get_many_related('Extra_Meta');
2607
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2608
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2609
+					if ( ! isset($return_array[$extra_meta_obj->key()])) {
2610
+						$return_array[$extra_meta_obj->key()] = array();
2611
+					}
2612
+					$return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2613
+				}
2614
+			}
2615
+		}
2616
+		return $return_array;
2617
+	}
2618
+
2619
+
2620
+
2621
+	/**
2622
+	 * Gets a pretty nice displayable nice for this model object. Often overridden
2623
+	 *
2624
+	 * @return string
2625
+	 * @throws \EE_Error
2626
+	 */
2627
+	public function name()
2628
+	{
2629
+		//find a field that's not a text field
2630
+		$field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2631
+		if ($field_we_can_use) {
2632
+			return $this->get($field_we_can_use->get_name());
2633
+		} else {
2634
+			$first_few_properties = $this->model_field_array();
2635
+			$first_few_properties = array_slice($first_few_properties, 0, 3);
2636
+			$name_parts = array();
2637
+			foreach ($first_few_properties as $name => $value) {
2638
+				$name_parts[] = "$name:$value";
2639
+			}
2640
+			return implode(",", $name_parts);
2641
+		}
2642
+	}
2643
+
2644
+
2645
+
2646
+	/**
2647
+	 * in_entity_map
2648
+	 * Checks if this model object has been proven to already be in the entity map
2649
+	 *
2650
+	 * @return boolean
2651
+	 * @throws \EE_Error
2652
+	 */
2653
+	public function in_entity_map()
2654
+	{
2655
+		if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2656
+			//well, if we looked, did we find it in the entity map?
2657
+			return true;
2658
+		} else {
2659
+			return false;
2660
+		}
2661
+	}
2662
+
2663
+
2664
+
2665
+	/**
2666
+	 * refresh_from_db
2667
+	 * Makes sure the fields and values on this model object are in-sync with what's in the database.
2668
+	 *
2669
+	 * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2670
+	 * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2671
+	 */
2672
+	public function refresh_from_db()
2673
+	{
2674
+		if ($this->ID() && $this->in_entity_map()) {
2675
+			$this->get_model()->refresh_entity_map_from_db($this->ID());
2676
+		} else {
2677
+			//if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2678
+			//if it has an ID but it's not in the map, and you're asking me to refresh it
2679
+			//that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2680
+			//absolutely nothing in it for this ID
2681
+			if (WP_DEBUG) {
2682
+				throw new EE_Error(
2683
+					sprintf(
2684
+						__('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2685
+							'event_espresso'),
2686
+						$this->ID(),
2687
+						get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2688
+						get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2689
+					)
2690
+				);
2691
+			}
2692
+		}
2693
+	}
2694
+
2695
+
2696
+
2697
+	/**
2698
+	 * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2699
+	 * (probably a bad assumption they have made, oh well)
2700
+	 *
2701
+	 * @return string
2702
+	 */
2703
+	public function __toString()
2704
+	{
2705
+		try {
2706
+			return sprintf('%s (%s)', $this->name(), $this->ID());
2707
+		} catch (Exception $e) {
2708
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2709
+			return '';
2710
+		}
2711
+	}
2712
+
2713
+
2714
+
2715
+	/**
2716
+	 * Clear related model objects if they're already in the DB, because otherwise when we
2717
+	 * UN-serialize this model object we'll need to be careful to add them to the entity map.
2718
+	 * This means if we have made changes to those related model objects, and want to unserialize
2719
+	 * the this model object on a subsequent request, changes to those related model objects will be lost.
2720
+	 * Instead, those related model objects should be directly serialized and stored.
2721
+	 * Eg, the following won't work:
2722
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2723
+	 * $att = $reg->attendee();
2724
+	 * $att->set( 'ATT_fname', 'Dirk' );
2725
+	 * update_option( 'my_option', serialize( $reg ) );
2726
+	 * //END REQUEST
2727
+	 * //START NEXT REQUEST
2728
+	 * $reg = get_option( 'my_option' );
2729
+	 * $reg->attendee()->save();
2730
+	 * And would need to be replace with:
2731
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2732
+	 * $att = $reg->attendee();
2733
+	 * $att->set( 'ATT_fname', 'Dirk' );
2734
+	 * update_option( 'my_option', serialize( $reg ) );
2735
+	 * //END REQUEST
2736
+	 * //START NEXT REQUEST
2737
+	 * $att = get_option( 'my_option' );
2738
+	 * $att->save();
2739
+	 *
2740
+	 * @return array
2741
+	 * @throws \EE_Error
2742
+	 */
2743
+	public function __sleep()
2744
+	{
2745
+		$model = $this->get_model();
2746
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
2747
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
2748
+				$classname = 'EE_' . $model->get_this_model_name();
2749
+				if (
2750
+					$this->get_one_from_cache($relation_name) instanceof $classname
2751
+					&& $this->get_one_from_cache($relation_name)->ID()
2752
+				) {
2753
+					$this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2754
+				}
2755
+			}
2756
+		}
2757
+		$this->_props_n_values_provided_in_constructor = array();
2758
+		$properties_to_serialize = get_object_vars($this);
2759
+		//don't serialize the model. It's big and that risks recursion
2760
+		unset($properties_to_serialize['_model']);
2761
+		return array_keys($properties_to_serialize);
2762
+	}
2763
+
2764
+
2765
+
2766
+	/**
2767
+	 * restore _props_n_values_provided_in_constructor
2768
+	 * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2769
+	 * and therefore should NOT be used to determine if state change has occurred since initial construction.
2770
+	 * At best, you would only be able to detect if state change has occurred during THIS request.
2771
+	 */
2772
+	public function __wakeup()
2773
+	{
2774
+		$this->_props_n_values_provided_in_constructor = $this->_fields;
2775
+	}
2776 2776
 
2777 2777
 
2778 2778
 
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_List_Table.class.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -152,7 +152,7 @@
 block discarded – undo
152 152
 
153 153
     /**
154 154
      * @param EE_Event $item
155
-     * @return mixed|string
155
+     * @return string
156 156
      * @throws EE_Error
157 157
      */
158 158
     public function column_id(EE_Event $item)
Please login to merge, or discard this patch.
Indentation   +508 added lines, -508 removed lines patch added patch discarded remove patch
@@ -13,512 +13,512 @@
 block discarded – undo
13 13
 class Events_Admin_List_Table extends EE_Admin_List_Table
14 14
 {
15 15
 
16
-    /**
17
-     * @var EE_Datetime
18
-     */
19
-    private $_dtt;
20
-
21
-
22
-    /**
23
-     * Initial setup of data properties for the list table.
24
-     */
25
-    protected function _setup_data()
26
-    {
27
-        $this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
28
-        $this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
29
-    }
30
-
31
-
32
-    /**
33
-     * Set up of additional properties for the list table.
34
-     */
35
-    protected function _set_properties()
36
-    {
37
-        $this->_wp_list_args = array(
38
-            'singular' => esc_html__('event', 'event_espresso'),
39
-            'plural'   => esc_html__('events', 'event_espresso'),
40
-            'ajax'     => true, //for now
41
-            'screen'   => $this->_admin_page->get_current_screen()->id,
42
-        );
43
-
44
-
45
-        $this->_columns = array(
46
-            'cb'              => '<input type="checkbox" />',
47
-            'id'              => esc_html__('ID', 'event_espresso'),
48
-            'name'            => esc_html__('Name', 'event_espresso'),
49
-            'author'          => esc_html__('Author', 'event_espresso'),
50
-            'venue'           => esc_html__('Venue', 'event_espresso'),
51
-            'start_date_time' => esc_html__('Event Start', 'event_espresso'),
52
-            'reg_begins'      => esc_html__('On Sale', 'event_espresso'),
53
-            'attendees'       => '<span class="dashicons dashicons-groups ee-icon-color-ee-green ee-icon-size-20">'
54
-                                 . '</span>',
55
-            //'tkts_sold' => esc_html__('Tickets Sold', 'event_espresso'),
56
-            'actions'         => esc_html__('Actions', 'event_espresso'),
57
-        );
58
-
59
-
60
-        $this->_sortable_columns = array(
61
-            'id'              => array('EVT_ID' => true),
62
-            'name'            => array('EVT_name' => false),
63
-            'author'          => array('EVT_wp_user' => false),
64
-            'venue'           => array('Venue.VNU_name' => false),
65
-            'start_date_time' => array('Datetime.DTT_EVT_start' => false),
66
-            'reg_begins'      => array('Datetime.Ticket.TKT_start_date' => false),
67
-        );
68
-
69
-        $this->_primary_column = 'id';
70
-
71
-        $this->_hidden_columns = array('author');
72
-    }
73
-
74
-
75
-    /**
76
-     * @return array
77
-     */
78
-    protected function _get_table_filters()
79
-    {
80
-        return array(); //no filters with decaf
81
-    }
82
-
83
-
84
-    /**
85
-     * Setup of views properties.
86
-     */
87
-    protected function _add_view_counts()
88
-    {
89
-        $this->_views['all']['count']   = $this->_admin_page->total_events();
90
-        $this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
91
-        if (EE_Registry::instance()->CAP->current_user_can(
92
-            'ee_delete_events',
93
-            'espresso_events_trash_events'
94
-        )) {
95
-            $this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
96
-        }
97
-    }
98
-
99
-
100
-    /**
101
-     * @param EE_Event $item
102
-     * @return string
103
-     * @throws EE_Error
104
-     */
105
-    protected function _get_row_class($item)
106
-    {
107
-        $class = parent::_get_row_class($item);
108
-        //add status class
109
-        $class .= $item instanceof EE_Event ? ' ee-status-strip event-status-' . $item->get_active_status() : '';
110
-        if ($this->_has_checkbox_column) {
111
-            $class .= ' has-checkbox-column';
112
-        }
113
-        return $class;
114
-    }
115
-
116
-
117
-    /**
118
-     * @param EE_Event $item
119
-     * @return string
120
-     * @throws EE_Error
121
-     */
122
-    public function column_status(EE_Event $item)
123
-    {
124
-        return '<span class="ee-status-strip ee-status-strip-td event-status-'
125
-               . $item->get_active_status()
126
-               . '"></span>';
127
-    }
128
-
129
-
130
-    /**
131
-     * @param  EE_Event $item
132
-     * @return string
133
-     * @throws EE_Error
134
-     */
135
-    public function column_cb($item)
136
-    {
137
-        if (! $item instanceof EE_Event) {
138
-            return '';
139
-        }
140
-        $this->_dtt = $item->primary_datetime(); //set this for use in other columns
141
-
142
-        //does event have any attached registrations?
143
-        $regs = $item->count_related('Registration');
144
-        return $regs > 0 && $this->_view == 'trash'
145
-            ? '<span class="ee-lock-icon"></span>'
146
-            : sprintf(
147
-                '<input type="checkbox" name="EVT_IDs[]" value="%s" />',
148
-                $item->ID()
149
-            );
150
-    }
151
-
152
-
153
-    /**
154
-     * @param EE_Event $item
155
-     * @return mixed|string
156
-     * @throws EE_Error
157
-     */
158
-    public function column_id(EE_Event $item)
159
-    {
160
-        $content = $item->ID();
161
-        $content .= '  <span class="show-on-mobile-view-only">' . $item->name() . '</span>';
162
-        return $content;
163
-    }
164
-
165
-
166
-    /**
167
-     * @param EE_Event $item
168
-     * @return string
169
-     * @throws EE_Error
170
-     */
171
-    public function column_name(EE_Event $item)
172
-    {
173
-        $edit_query_args = array(
174
-            'action' => 'edit',
175
-            'post'   => $item->ID(),
176
-        );
177
-        $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
178
-        $actions         = $this->_column_name_action_setup($item);
179
-        $status          = ''; //$item->status() !== 'publish' ? ' (' . $item->status() . ')' : '';
180
-        $content         = '<strong><a class="row-title" href="'
181
-                           . $edit_link . '">'
182
-                           . $item->name()
183
-                           . '</a></strong>'
184
-                           . $status;
185
-        $content         .= '<br><span class="ee-status-text-small">'
186
-                            . EEH_Template::pretty_status(
187
-                                $item->get_active_status(),
188
-                                false,
189
-                                'sentence'
190
-                            )
191
-                            . '</span>';
192
-        $content         .= $this->row_actions($actions);
193
-        return $content;
194
-    }
195
-
196
-
197
-    /**
198
-     * Just a method for setting up the actions for the name column
199
-     *
200
-     * @param EE_Event $item
201
-     * @return array array of actions
202
-     * @throws EE_Error
203
-     */
204
-    protected function _column_name_action_setup(EE_Event $item)
205
-    {
206
-        //todo: remove when attendees is active
207
-        if (! defined('REG_ADMIN_URL')) {
208
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
209
-        }
210
-
211
-        $actions = array();
212
-
213
-        if (EE_Registry::instance()->CAP->current_user_can(
214
-            'ee_edit_event',
215
-            'espresso_events_edit',
216
-            $item->ID()
217
-        )) {
218
-            $edit_query_args = array(
219
-                'action' => 'edit',
220
-                'post'   => $item->ID(),
221
-            );
222
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
223
-            $actions['edit'] = '<a href="' . $edit_link . '"'
224
-                               . ' title="' . esc_attr__('Edit Event', 'event_espresso') . '">'
225
-                               . esc_html__('Edit', 'event_espresso')
226
-                               . '</a>';
227
-
228
-        }
229
-
230
-        if (EE_Registry::instance()->CAP->current_user_can(
231
-            'ee_read_event',
232
-            'espresso_registrations_view_registration',
233
-            $item->ID()
234
-        )
235
-            && EE_Registry::instance()->CAP->current_user_can(
236
-                'ee_read_registrations',
237
-                'espresso_registrations_view_registration'
238
-            )
239
-        ) {
240
-            $attendees_query_args = array(
241
-                'action'   => 'default',
242
-                'event_id' => $item->ID(),
243
-            );
244
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
245
-            $actions['attendees'] = '<a href="' . $attendees_link . '"'
246
-                                    . ' title="' . esc_attr__('View Registrations', 'event_espresso') . '">'
247
-                                    . esc_html__('Registrations', 'event_espresso')
248
-                                    . '</a>';
249
-        }
250
-
251
-        if (EE_Registry::instance()->CAP->current_user_can(
252
-            'ee_delete_event',
253
-            'espresso_events_trash_event',
254
-            $item->ID()
255
-        )) {
256
-            $trash_event_query_args = array(
257
-                'action' => 'trash_event',
258
-                'EVT_ID' => $item->ID(),
259
-            );
260
-            $trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
261
-                $trash_event_query_args,
262
-                EVENTS_ADMIN_URL
263
-            );
264
-        }
265
-
266
-        if (EE_Registry::instance()->CAP->current_user_can(
267
-            'ee_delete_event',
268
-            'espresso_events_restore_event',
269
-            $item->ID()
270
-        )) {
271
-            $restore_event_query_args = array(
272
-                'action' => 'restore_event',
273
-                'EVT_ID' => $item->ID(),
274
-            );
275
-            $restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
276
-                $restore_event_query_args,
277
-                EVENTS_ADMIN_URL
278
-            );
279
-        }
280
-
281
-        if (EE_Registry::instance()->CAP->current_user_can(
282
-            'ee_delete_event',
283
-            'espresso_events_delete_event',
284
-            $item->ID()
285
-        )) {
286
-            $delete_event_query_args = array(
287
-                'action' => 'delete_event',
288
-                'EVT_ID' => $item->ID(),
289
-            );
290
-            $delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
291
-                $delete_event_query_args,
292
-                EVENTS_ADMIN_URL
293
-            );
294
-        }
295
-
296
-        $view_link = get_permalink($item->ID());
297
-
298
-        $actions['view'] = '<a href="' . $view_link . '"'
299
-                           . ' title="' . esc_attr__('View Event', 'event_espresso') . '">'
300
-                           . esc_html__('View', 'event_espresso')
301
-                           . '</a>';
302
-
303
-        switch ($item->get('status')) {
304
-            case 'trash':
305
-                if (EE_Registry::instance()->CAP->current_user_can(
306
-                    'ee_delete_event',
307
-                    'espresso_events_restore_event',
308
-                    $item->ID()
309
-                )) {
310
-                    $actions['restore_from_trash'] = '<a href="' . $restore_event_link . '"'
311
-                                                     . ' title="' . esc_attr__('Restore from Trash', 'event_espresso')
312
-                                                     . '">'
313
-                                                     . esc_html__('Restore from Trash', 'event_espresso')
314
-                                                     . '</a>';
315
-                }
316
-                if ($item->count_related('Registration') === 0
317
-                    && EE_Registry::instance()->CAP->current_user_can(
318
-                        'ee_delete_event',
319
-                        'espresso_events_delete_event',
320
-                        $item->ID()
321
-                    )) {
322
-                    $actions['delete'] = '<a href="' . $delete_event_link . '"'
323
-                                         . ' title="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
324
-                                         . esc_html__('Delete Permanently', 'event_espresso')
325
-                                         . '</a>';
326
-                }
327
-                break;
328
-            default:
329
-                if (EE_Registry::instance()->CAP->current_user_can(
330
-                    'ee_delete_event',
331
-                    'espresso_events_trash_event',
332
-                    $item->ID()
333
-                )) {
334
-                    $actions['move to trash'] = '<a href="' . $trash_event_link . '"'
335
-                                                . ' title="' . esc_attr__('Trash Event', 'event_espresso') . '">'
336
-                                                . esc_html__('Trash', 'event_espresso')
337
-                                                . '</a>';
338
-                }
339
-        }
340
-        return $actions;
341
-    }
342
-
343
-
344
-    /**
345
-     * @param EE_Event $item
346
-     * @return string
347
-     * @throws EE_Error
348
-     */
349
-    public function column_author(EE_Event $item)
350
-    {
351
-        //user author info
352
-        $event_author = get_userdata($item->wp_user());
353
-        $gravatar     = get_avatar($item->wp_user(), '15');
354
-        //filter link
355
-        $query_args = array(
356
-            'action'      => 'default',
357
-            'EVT_wp_user' => $item->wp_user(),
358
-        );
359
-        $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
360
-        return $gravatar . '  <a href="' . $filter_url . '"'
361
-               . ' title="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
362
-               . $event_author->display_name
363
-               . '</a>';
364
-    }
365
-
366
-
367
-    /**
368
-     * @param EE_Event $item
369
-     * @return string
370
-     * @throws EE_Error
371
-     */
372
-    public function column_venue(EE_Event $item)
373
-    {
374
-        $venue = $item->get_first_related('Venue');
375
-        return ! empty($venue) ? $venue->name() : '';
376
-    }
377
-
378
-
379
-    /**
380
-     * @param EE_Event $item
381
-     * @throws EE_Error
382
-     */
383
-    public function column_start_date_time(EE_Event $item)
384
-    {
385
-        echo ! empty($this->_dtt)
386
-            ? $this->_dtt->get_i18n_datetime('DTT_EVT_start')
387
-            : esc_html__('No Date was saved for this Event', 'event_espresso');
388
-        //display in user's timezone?
389
-        echo ! empty($this->_dtt)
390
-            ? $this->_dtt->display_in_my_timezone(
391
-                'DTT_EVT_start',
392
-                'get_i18n_datetime',
393
-                '',
394
-                'My Timezone: '
395
-            )
396
-            : '';
397
-    }
398
-
399
-
400
-    /**
401
-     * @param EE_Event $item
402
-     * @throws EE_Error
403
-     */
404
-    public function column_reg_begins(EE_Event $item)
405
-    {
406
-        $reg_start = $item->get_ticket_with_earliest_start_time();
407
-        echo ! empty($reg_start)
408
-            ? $reg_start->get_i18n_datetime('TKT_start_date')
409
-            : esc_html__('No Tickets have been setup for this Event', 'event_espresso');
410
-        //display in user's timezone?
411
-        echo ! empty($reg_start)
412
-            ? $reg_start->display_in_my_timezone(
413
-                'TKT_start_date',
414
-                'get_i18n_datetime',
415
-                '',
416
-                'My Timezone: '
417
-            )
418
-            : '';
419
-    }
420
-
421
-
422
-    /**
423
-     * @param EE_Event $item
424
-     * @return int|string
425
-     * @throws EE_Error
426
-     */
427
-    public function column_attendees(EE_Event $item)
428
-    {
429
-        $attendees_query_args = array(
430
-            'action'   => 'default',
431
-            'event_id' => $item->ID(),
432
-        );
433
-        $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
434
-        $registered_attendees = EEM_Registration::instance()->get_event_registration_count($item->ID());
435
-        return EE_Registry::instance()->CAP->current_user_can(
436
-            'ee_read_event',
437
-            'espresso_registrations_view_registration',
438
-            $item->ID()
439
-        )
440
-            && EE_Registry::instance()->CAP->current_user_can(
441
-                'ee_read_registrations',
442
-                'espresso_registrations_view_registration'
443
-            )
444
-            ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
445
-            : $registered_attendees;
446
-    }
447
-
448
-
449
-    /**
450
-     * @param EE_Event $item
451
-     * @return float
452
-     * @throws EE_Error
453
-     */
454
-    public function column_tkts_sold(EE_Event $item)
455
-    {
456
-        return EEM_Ticket::instance()->sum(array(array('Datetime.EVT_ID' => $item->ID())), 'TKT_sold');
457
-    }
458
-
459
-
460
-    /**
461
-     * @param EE_Event $item
462
-     * @return string
463
-     * @throws EE_Error
464
-     */
465
-    public function column_actions(EE_Event $item)
466
-    {
467
-        //todo: remove when attendees is active
468
-        if (! defined('REG_ADMIN_URL')) {
469
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
470
-        }
471
-        $actionlinks = array();
472
-
473
-        $view_link = get_permalink($item->ID());
474
-
475
-        $actionlinks[] = '<a href="' . $view_link . '"'
476
-                         . ' title="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">';
477
-        $actionlinks[] = '<div class="dashicons dashicons-search"></div></a>';
478
-
479
-        if (EE_Registry::instance()->CAP->current_user_can(
480
-            'ee_edit_event',
481
-            'espresso_events_edit',
482
-            $item->ID()
483
-        )) {
484
-            $edit_query_args = array(
485
-                'action' => 'edit',
486
-                'post'   => $item->ID(),
487
-            );
488
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
489
-            $actionlinks[]   = '<a href="' . $edit_link . '"'
490
-                               . ' title="' . esc_attr__('Edit Event', 'event_espresso') . '">'
491
-                               . '<div class="ee-icon ee-icon-calendar-edit"></div>'
492
-                               . '</a>';
493
-        }
494
-
495
-        if (EE_Registry::instance()->CAP->current_user_can(
496
-            'ee_read_event',
497
-            'espresso_registrations_view_registration',
498
-            $item->ID()
499
-        )
500
-            && EE_Registry::instance()->CAP->current_user_can(
501
-                'ee_read_registrations',
502
-                'espresso_registrations_view_registration'
503
-            )
504
-        ) {
505
-            $attendees_query_args = array(
506
-                'action'   => 'default',
507
-                'event_id' => $item->ID(),
508
-            );
509
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
510
-            $actionlinks[]        = '<a href="' . $attendees_link . '"'
511
-                                    . ' title="' . esc_attr__('View Registrants', 'event_espresso') . '">'
512
-                                    . '<div class="dashicons dashicons-groups"></div>'
513
-                                    . '</a>';
514
-        }
515
-
516
-        $actionlinks = apply_filters(
517
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
518
-            $actionlinks,
519
-            $item
520
-        );
521
-
522
-        return $this->_action_string(implode("\n\t", $actionlinks), $item, 'div');
523
-    }
16
+	/**
17
+	 * @var EE_Datetime
18
+	 */
19
+	private $_dtt;
20
+
21
+
22
+	/**
23
+	 * Initial setup of data properties for the list table.
24
+	 */
25
+	protected function _setup_data()
26
+	{
27
+		$this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
28
+		$this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
29
+	}
30
+
31
+
32
+	/**
33
+	 * Set up of additional properties for the list table.
34
+	 */
35
+	protected function _set_properties()
36
+	{
37
+		$this->_wp_list_args = array(
38
+			'singular' => esc_html__('event', 'event_espresso'),
39
+			'plural'   => esc_html__('events', 'event_espresso'),
40
+			'ajax'     => true, //for now
41
+			'screen'   => $this->_admin_page->get_current_screen()->id,
42
+		);
43
+
44
+
45
+		$this->_columns = array(
46
+			'cb'              => '<input type="checkbox" />',
47
+			'id'              => esc_html__('ID', 'event_espresso'),
48
+			'name'            => esc_html__('Name', 'event_espresso'),
49
+			'author'          => esc_html__('Author', 'event_espresso'),
50
+			'venue'           => esc_html__('Venue', 'event_espresso'),
51
+			'start_date_time' => esc_html__('Event Start', 'event_espresso'),
52
+			'reg_begins'      => esc_html__('On Sale', 'event_espresso'),
53
+			'attendees'       => '<span class="dashicons dashicons-groups ee-icon-color-ee-green ee-icon-size-20">'
54
+								 . '</span>',
55
+			//'tkts_sold' => esc_html__('Tickets Sold', 'event_espresso'),
56
+			'actions'         => esc_html__('Actions', 'event_espresso'),
57
+		);
58
+
59
+
60
+		$this->_sortable_columns = array(
61
+			'id'              => array('EVT_ID' => true),
62
+			'name'            => array('EVT_name' => false),
63
+			'author'          => array('EVT_wp_user' => false),
64
+			'venue'           => array('Venue.VNU_name' => false),
65
+			'start_date_time' => array('Datetime.DTT_EVT_start' => false),
66
+			'reg_begins'      => array('Datetime.Ticket.TKT_start_date' => false),
67
+		);
68
+
69
+		$this->_primary_column = 'id';
70
+
71
+		$this->_hidden_columns = array('author');
72
+	}
73
+
74
+
75
+	/**
76
+	 * @return array
77
+	 */
78
+	protected function _get_table_filters()
79
+	{
80
+		return array(); //no filters with decaf
81
+	}
82
+
83
+
84
+	/**
85
+	 * Setup of views properties.
86
+	 */
87
+	protected function _add_view_counts()
88
+	{
89
+		$this->_views['all']['count']   = $this->_admin_page->total_events();
90
+		$this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
91
+		if (EE_Registry::instance()->CAP->current_user_can(
92
+			'ee_delete_events',
93
+			'espresso_events_trash_events'
94
+		)) {
95
+			$this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
96
+		}
97
+	}
98
+
99
+
100
+	/**
101
+	 * @param EE_Event $item
102
+	 * @return string
103
+	 * @throws EE_Error
104
+	 */
105
+	protected function _get_row_class($item)
106
+	{
107
+		$class = parent::_get_row_class($item);
108
+		//add status class
109
+		$class .= $item instanceof EE_Event ? ' ee-status-strip event-status-' . $item->get_active_status() : '';
110
+		if ($this->_has_checkbox_column) {
111
+			$class .= ' has-checkbox-column';
112
+		}
113
+		return $class;
114
+	}
115
+
116
+
117
+	/**
118
+	 * @param EE_Event $item
119
+	 * @return string
120
+	 * @throws EE_Error
121
+	 */
122
+	public function column_status(EE_Event $item)
123
+	{
124
+		return '<span class="ee-status-strip ee-status-strip-td event-status-'
125
+			   . $item->get_active_status()
126
+			   . '"></span>';
127
+	}
128
+
129
+
130
+	/**
131
+	 * @param  EE_Event $item
132
+	 * @return string
133
+	 * @throws EE_Error
134
+	 */
135
+	public function column_cb($item)
136
+	{
137
+		if (! $item instanceof EE_Event) {
138
+			return '';
139
+		}
140
+		$this->_dtt = $item->primary_datetime(); //set this for use in other columns
141
+
142
+		//does event have any attached registrations?
143
+		$regs = $item->count_related('Registration');
144
+		return $regs > 0 && $this->_view == 'trash'
145
+			? '<span class="ee-lock-icon"></span>'
146
+			: sprintf(
147
+				'<input type="checkbox" name="EVT_IDs[]" value="%s" />',
148
+				$item->ID()
149
+			);
150
+	}
151
+
152
+
153
+	/**
154
+	 * @param EE_Event $item
155
+	 * @return mixed|string
156
+	 * @throws EE_Error
157
+	 */
158
+	public function column_id(EE_Event $item)
159
+	{
160
+		$content = $item->ID();
161
+		$content .= '  <span class="show-on-mobile-view-only">' . $item->name() . '</span>';
162
+		return $content;
163
+	}
164
+
165
+
166
+	/**
167
+	 * @param EE_Event $item
168
+	 * @return string
169
+	 * @throws EE_Error
170
+	 */
171
+	public function column_name(EE_Event $item)
172
+	{
173
+		$edit_query_args = array(
174
+			'action' => 'edit',
175
+			'post'   => $item->ID(),
176
+		);
177
+		$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
178
+		$actions         = $this->_column_name_action_setup($item);
179
+		$status          = ''; //$item->status() !== 'publish' ? ' (' . $item->status() . ')' : '';
180
+		$content         = '<strong><a class="row-title" href="'
181
+						   . $edit_link . '">'
182
+						   . $item->name()
183
+						   . '</a></strong>'
184
+						   . $status;
185
+		$content         .= '<br><span class="ee-status-text-small">'
186
+							. EEH_Template::pretty_status(
187
+								$item->get_active_status(),
188
+								false,
189
+								'sentence'
190
+							)
191
+							. '</span>';
192
+		$content         .= $this->row_actions($actions);
193
+		return $content;
194
+	}
195
+
196
+
197
+	/**
198
+	 * Just a method for setting up the actions for the name column
199
+	 *
200
+	 * @param EE_Event $item
201
+	 * @return array array of actions
202
+	 * @throws EE_Error
203
+	 */
204
+	protected function _column_name_action_setup(EE_Event $item)
205
+	{
206
+		//todo: remove when attendees is active
207
+		if (! defined('REG_ADMIN_URL')) {
208
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
209
+		}
210
+
211
+		$actions = array();
212
+
213
+		if (EE_Registry::instance()->CAP->current_user_can(
214
+			'ee_edit_event',
215
+			'espresso_events_edit',
216
+			$item->ID()
217
+		)) {
218
+			$edit_query_args = array(
219
+				'action' => 'edit',
220
+				'post'   => $item->ID(),
221
+			);
222
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
223
+			$actions['edit'] = '<a href="' . $edit_link . '"'
224
+							   . ' title="' . esc_attr__('Edit Event', 'event_espresso') . '">'
225
+							   . esc_html__('Edit', 'event_espresso')
226
+							   . '</a>';
227
+
228
+		}
229
+
230
+		if (EE_Registry::instance()->CAP->current_user_can(
231
+			'ee_read_event',
232
+			'espresso_registrations_view_registration',
233
+			$item->ID()
234
+		)
235
+			&& EE_Registry::instance()->CAP->current_user_can(
236
+				'ee_read_registrations',
237
+				'espresso_registrations_view_registration'
238
+			)
239
+		) {
240
+			$attendees_query_args = array(
241
+				'action'   => 'default',
242
+				'event_id' => $item->ID(),
243
+			);
244
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
245
+			$actions['attendees'] = '<a href="' . $attendees_link . '"'
246
+									. ' title="' . esc_attr__('View Registrations', 'event_espresso') . '">'
247
+									. esc_html__('Registrations', 'event_espresso')
248
+									. '</a>';
249
+		}
250
+
251
+		if (EE_Registry::instance()->CAP->current_user_can(
252
+			'ee_delete_event',
253
+			'espresso_events_trash_event',
254
+			$item->ID()
255
+		)) {
256
+			$trash_event_query_args = array(
257
+				'action' => 'trash_event',
258
+				'EVT_ID' => $item->ID(),
259
+			);
260
+			$trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
261
+				$trash_event_query_args,
262
+				EVENTS_ADMIN_URL
263
+			);
264
+		}
265
+
266
+		if (EE_Registry::instance()->CAP->current_user_can(
267
+			'ee_delete_event',
268
+			'espresso_events_restore_event',
269
+			$item->ID()
270
+		)) {
271
+			$restore_event_query_args = array(
272
+				'action' => 'restore_event',
273
+				'EVT_ID' => $item->ID(),
274
+			);
275
+			$restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
276
+				$restore_event_query_args,
277
+				EVENTS_ADMIN_URL
278
+			);
279
+		}
280
+
281
+		if (EE_Registry::instance()->CAP->current_user_can(
282
+			'ee_delete_event',
283
+			'espresso_events_delete_event',
284
+			$item->ID()
285
+		)) {
286
+			$delete_event_query_args = array(
287
+				'action' => 'delete_event',
288
+				'EVT_ID' => $item->ID(),
289
+			);
290
+			$delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
291
+				$delete_event_query_args,
292
+				EVENTS_ADMIN_URL
293
+			);
294
+		}
295
+
296
+		$view_link = get_permalink($item->ID());
297
+
298
+		$actions['view'] = '<a href="' . $view_link . '"'
299
+						   . ' title="' . esc_attr__('View Event', 'event_espresso') . '">'
300
+						   . esc_html__('View', 'event_espresso')
301
+						   . '</a>';
302
+
303
+		switch ($item->get('status')) {
304
+			case 'trash':
305
+				if (EE_Registry::instance()->CAP->current_user_can(
306
+					'ee_delete_event',
307
+					'espresso_events_restore_event',
308
+					$item->ID()
309
+				)) {
310
+					$actions['restore_from_trash'] = '<a href="' . $restore_event_link . '"'
311
+													 . ' title="' . esc_attr__('Restore from Trash', 'event_espresso')
312
+													 . '">'
313
+													 . esc_html__('Restore from Trash', 'event_espresso')
314
+													 . '</a>';
315
+				}
316
+				if ($item->count_related('Registration') === 0
317
+					&& EE_Registry::instance()->CAP->current_user_can(
318
+						'ee_delete_event',
319
+						'espresso_events_delete_event',
320
+						$item->ID()
321
+					)) {
322
+					$actions['delete'] = '<a href="' . $delete_event_link . '"'
323
+										 . ' title="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
324
+										 . esc_html__('Delete Permanently', 'event_espresso')
325
+										 . '</a>';
326
+				}
327
+				break;
328
+			default:
329
+				if (EE_Registry::instance()->CAP->current_user_can(
330
+					'ee_delete_event',
331
+					'espresso_events_trash_event',
332
+					$item->ID()
333
+				)) {
334
+					$actions['move to trash'] = '<a href="' . $trash_event_link . '"'
335
+												. ' title="' . esc_attr__('Trash Event', 'event_espresso') . '">'
336
+												. esc_html__('Trash', 'event_espresso')
337
+												. '</a>';
338
+				}
339
+		}
340
+		return $actions;
341
+	}
342
+
343
+
344
+	/**
345
+	 * @param EE_Event $item
346
+	 * @return string
347
+	 * @throws EE_Error
348
+	 */
349
+	public function column_author(EE_Event $item)
350
+	{
351
+		//user author info
352
+		$event_author = get_userdata($item->wp_user());
353
+		$gravatar     = get_avatar($item->wp_user(), '15');
354
+		//filter link
355
+		$query_args = array(
356
+			'action'      => 'default',
357
+			'EVT_wp_user' => $item->wp_user(),
358
+		);
359
+		$filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
360
+		return $gravatar . '  <a href="' . $filter_url . '"'
361
+			   . ' title="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
362
+			   . $event_author->display_name
363
+			   . '</a>';
364
+	}
365
+
366
+
367
+	/**
368
+	 * @param EE_Event $item
369
+	 * @return string
370
+	 * @throws EE_Error
371
+	 */
372
+	public function column_venue(EE_Event $item)
373
+	{
374
+		$venue = $item->get_first_related('Venue');
375
+		return ! empty($venue) ? $venue->name() : '';
376
+	}
377
+
378
+
379
+	/**
380
+	 * @param EE_Event $item
381
+	 * @throws EE_Error
382
+	 */
383
+	public function column_start_date_time(EE_Event $item)
384
+	{
385
+		echo ! empty($this->_dtt)
386
+			? $this->_dtt->get_i18n_datetime('DTT_EVT_start')
387
+			: esc_html__('No Date was saved for this Event', 'event_espresso');
388
+		//display in user's timezone?
389
+		echo ! empty($this->_dtt)
390
+			? $this->_dtt->display_in_my_timezone(
391
+				'DTT_EVT_start',
392
+				'get_i18n_datetime',
393
+				'',
394
+				'My Timezone: '
395
+			)
396
+			: '';
397
+	}
398
+
399
+
400
+	/**
401
+	 * @param EE_Event $item
402
+	 * @throws EE_Error
403
+	 */
404
+	public function column_reg_begins(EE_Event $item)
405
+	{
406
+		$reg_start = $item->get_ticket_with_earliest_start_time();
407
+		echo ! empty($reg_start)
408
+			? $reg_start->get_i18n_datetime('TKT_start_date')
409
+			: esc_html__('No Tickets have been setup for this Event', 'event_espresso');
410
+		//display in user's timezone?
411
+		echo ! empty($reg_start)
412
+			? $reg_start->display_in_my_timezone(
413
+				'TKT_start_date',
414
+				'get_i18n_datetime',
415
+				'',
416
+				'My Timezone: '
417
+			)
418
+			: '';
419
+	}
420
+
421
+
422
+	/**
423
+	 * @param EE_Event $item
424
+	 * @return int|string
425
+	 * @throws EE_Error
426
+	 */
427
+	public function column_attendees(EE_Event $item)
428
+	{
429
+		$attendees_query_args = array(
430
+			'action'   => 'default',
431
+			'event_id' => $item->ID(),
432
+		);
433
+		$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
434
+		$registered_attendees = EEM_Registration::instance()->get_event_registration_count($item->ID());
435
+		return EE_Registry::instance()->CAP->current_user_can(
436
+			'ee_read_event',
437
+			'espresso_registrations_view_registration',
438
+			$item->ID()
439
+		)
440
+			&& EE_Registry::instance()->CAP->current_user_can(
441
+				'ee_read_registrations',
442
+				'espresso_registrations_view_registration'
443
+			)
444
+			? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
445
+			: $registered_attendees;
446
+	}
447
+
448
+
449
+	/**
450
+	 * @param EE_Event $item
451
+	 * @return float
452
+	 * @throws EE_Error
453
+	 */
454
+	public function column_tkts_sold(EE_Event $item)
455
+	{
456
+		return EEM_Ticket::instance()->sum(array(array('Datetime.EVT_ID' => $item->ID())), 'TKT_sold');
457
+	}
458
+
459
+
460
+	/**
461
+	 * @param EE_Event $item
462
+	 * @return string
463
+	 * @throws EE_Error
464
+	 */
465
+	public function column_actions(EE_Event $item)
466
+	{
467
+		//todo: remove when attendees is active
468
+		if (! defined('REG_ADMIN_URL')) {
469
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
470
+		}
471
+		$actionlinks = array();
472
+
473
+		$view_link = get_permalink($item->ID());
474
+
475
+		$actionlinks[] = '<a href="' . $view_link . '"'
476
+						 . ' title="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">';
477
+		$actionlinks[] = '<div class="dashicons dashicons-search"></div></a>';
478
+
479
+		if (EE_Registry::instance()->CAP->current_user_can(
480
+			'ee_edit_event',
481
+			'espresso_events_edit',
482
+			$item->ID()
483
+		)) {
484
+			$edit_query_args = array(
485
+				'action' => 'edit',
486
+				'post'   => $item->ID(),
487
+			);
488
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
489
+			$actionlinks[]   = '<a href="' . $edit_link . '"'
490
+							   . ' title="' . esc_attr__('Edit Event', 'event_espresso') . '">'
491
+							   . '<div class="ee-icon ee-icon-calendar-edit"></div>'
492
+							   . '</a>';
493
+		}
494
+
495
+		if (EE_Registry::instance()->CAP->current_user_can(
496
+			'ee_read_event',
497
+			'espresso_registrations_view_registration',
498
+			$item->ID()
499
+		)
500
+			&& EE_Registry::instance()->CAP->current_user_can(
501
+				'ee_read_registrations',
502
+				'espresso_registrations_view_registration'
503
+			)
504
+		) {
505
+			$attendees_query_args = array(
506
+				'action'   => 'default',
507
+				'event_id' => $item->ID(),
508
+			);
509
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
510
+			$actionlinks[]        = '<a href="' . $attendees_link . '"'
511
+									. ' title="' . esc_attr__('View Registrants', 'event_espresso') . '">'
512
+									. '<div class="dashicons dashicons-groups"></div>'
513
+									. '</a>';
514
+		}
515
+
516
+		$actionlinks = apply_filters(
517
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
518
+			$actionlinks,
519
+			$item
520
+		);
521
+
522
+		return $this->_action_string(implode("\n\t", $actionlinks), $item, 'div');
523
+	}
524 524
 }
Please login to merge, or discard this patch.
Spacing   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
     {
107 107
         $class = parent::_get_row_class($item);
108 108
         //add status class
109
-        $class .= $item instanceof EE_Event ? ' ee-status-strip event-status-' . $item->get_active_status() : '';
109
+        $class .= $item instanceof EE_Event ? ' ee-status-strip event-status-'.$item->get_active_status() : '';
110 110
         if ($this->_has_checkbox_column) {
111 111
             $class .= ' has-checkbox-column';
112 112
         }
@@ -134,7 +134,7 @@  discard block
 block discarded – undo
134 134
      */
135 135
     public function column_cb($item)
136 136
     {
137
-        if (! $item instanceof EE_Event) {
137
+        if ( ! $item instanceof EE_Event) {
138 138
             return '';
139 139
         }
140 140
         $this->_dtt = $item->primary_datetime(); //set this for use in other columns
@@ -158,7 +158,7 @@  discard block
 block discarded – undo
158 158
     public function column_id(EE_Event $item)
159 159
     {
160 160
         $content = $item->ID();
161
-        $content .= '  <span class="show-on-mobile-view-only">' . $item->name() . '</span>';
161
+        $content .= '  <span class="show-on-mobile-view-only">'.$item->name().'</span>';
162 162
         return $content;
163 163
     }
164 164
 
@@ -178,18 +178,18 @@  discard block
 block discarded – undo
178 178
         $actions         = $this->_column_name_action_setup($item);
179 179
         $status          = ''; //$item->status() !== 'publish' ? ' (' . $item->status() . ')' : '';
180 180
         $content         = '<strong><a class="row-title" href="'
181
-                           . $edit_link . '">'
181
+                           . $edit_link.'">'
182 182
                            . $item->name()
183 183
                            . '</a></strong>'
184 184
                            . $status;
185
-        $content         .= '<br><span class="ee-status-text-small">'
185
+        $content .= '<br><span class="ee-status-text-small">'
186 186
                             . EEH_Template::pretty_status(
187 187
                                 $item->get_active_status(),
188 188
                                 false,
189 189
                                 'sentence'
190 190
                             )
191 191
                             . '</span>';
192
-        $content         .= $this->row_actions($actions);
192
+        $content .= $this->row_actions($actions);
193 193
         return $content;
194 194
     }
195 195
 
@@ -204,7 +204,7 @@  discard block
 block discarded – undo
204 204
     protected function _column_name_action_setup(EE_Event $item)
205 205
     {
206 206
         //todo: remove when attendees is active
207
-        if (! defined('REG_ADMIN_URL')) {
207
+        if ( ! defined('REG_ADMIN_URL')) {
208 208
             define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
209 209
         }
210 210
 
@@ -220,8 +220,8 @@  discard block
 block discarded – undo
220 220
                 'post'   => $item->ID(),
221 221
             );
222 222
             $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
223
-            $actions['edit'] = '<a href="' . $edit_link . '"'
224
-                               . ' title="' . esc_attr__('Edit Event', 'event_espresso') . '">'
223
+            $actions['edit'] = '<a href="'.$edit_link.'"'
224
+                               . ' title="'.esc_attr__('Edit Event', 'event_espresso').'">'
225 225
                                . esc_html__('Edit', 'event_espresso')
226 226
                                . '</a>';
227 227
 
@@ -242,8 +242,8 @@  discard block
 block discarded – undo
242 242
                 'event_id' => $item->ID(),
243 243
             );
244 244
             $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
245
-            $actions['attendees'] = '<a href="' . $attendees_link . '"'
246
-                                    . ' title="' . esc_attr__('View Registrations', 'event_espresso') . '">'
245
+            $actions['attendees'] = '<a href="'.$attendees_link.'"'
246
+                                    . ' title="'.esc_attr__('View Registrations', 'event_espresso').'">'
247 247
                                     . esc_html__('Registrations', 'event_espresso')
248 248
                                     . '</a>';
249 249
         }
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
                 'action' => 'trash_event',
258 258
                 'EVT_ID' => $item->ID(),
259 259
             );
260
-            $trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
260
+            $trash_event_link = EE_Admin_Page::add_query_args_and_nonce(
261 261
                 $trash_event_query_args,
262 262
                 EVENTS_ADMIN_URL
263 263
             );
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
                 'action' => 'restore_event',
273 273
                 'EVT_ID' => $item->ID(),
274 274
             );
275
-            $restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
275
+            $restore_event_link = EE_Admin_Page::add_query_args_and_nonce(
276 276
                 $restore_event_query_args,
277 277
                 EVENTS_ADMIN_URL
278 278
             );
@@ -287,7 +287,7 @@  discard block
 block discarded – undo
287 287
                 'action' => 'delete_event',
288 288
                 'EVT_ID' => $item->ID(),
289 289
             );
290
-            $delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
290
+            $delete_event_link = EE_Admin_Page::add_query_args_and_nonce(
291 291
                 $delete_event_query_args,
292 292
                 EVENTS_ADMIN_URL
293 293
             );
@@ -295,8 +295,8 @@  discard block
 block discarded – undo
295 295
 
296 296
         $view_link = get_permalink($item->ID());
297 297
 
298
-        $actions['view'] = '<a href="' . $view_link . '"'
299
-                           . ' title="' . esc_attr__('View Event', 'event_espresso') . '">'
298
+        $actions['view'] = '<a href="'.$view_link.'"'
299
+                           . ' title="'.esc_attr__('View Event', 'event_espresso').'">'
300 300
                            . esc_html__('View', 'event_espresso')
301 301
                            . '</a>';
302 302
 
@@ -307,8 +307,8 @@  discard block
 block discarded – undo
307 307
                     'espresso_events_restore_event',
308 308
                     $item->ID()
309 309
                 )) {
310
-                    $actions['restore_from_trash'] = '<a href="' . $restore_event_link . '"'
311
-                                                     . ' title="' . esc_attr__('Restore from Trash', 'event_espresso')
310
+                    $actions['restore_from_trash'] = '<a href="'.$restore_event_link.'"'
311
+                                                     . ' title="'.esc_attr__('Restore from Trash', 'event_espresso')
312 312
                                                      . '">'
313 313
                                                      . esc_html__('Restore from Trash', 'event_espresso')
314 314
                                                      . '</a>';
@@ -319,8 +319,8 @@  discard block
 block discarded – undo
319 319
                         'espresso_events_delete_event',
320 320
                         $item->ID()
321 321
                     )) {
322
-                    $actions['delete'] = '<a href="' . $delete_event_link . '"'
323
-                                         . ' title="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
322
+                    $actions['delete'] = '<a href="'.$delete_event_link.'"'
323
+                                         . ' title="'.esc_attr__('Delete Permanently', 'event_espresso').'">'
324 324
                                          . esc_html__('Delete Permanently', 'event_espresso')
325 325
                                          . '</a>';
326 326
                 }
@@ -331,8 +331,8 @@  discard block
 block discarded – undo
331 331
                     'espresso_events_trash_event',
332 332
                     $item->ID()
333 333
                 )) {
334
-                    $actions['move to trash'] = '<a href="' . $trash_event_link . '"'
335
-                                                . ' title="' . esc_attr__('Trash Event', 'event_espresso') . '">'
334
+                    $actions['move to trash'] = '<a href="'.$trash_event_link.'"'
335
+                                                . ' title="'.esc_attr__('Trash Event', 'event_espresso').'">'
336 336
                                                 . esc_html__('Trash', 'event_espresso')
337 337
                                                 . '</a>';
338 338
                 }
@@ -357,8 +357,8 @@  discard block
 block discarded – undo
357 357
             'EVT_wp_user' => $item->wp_user(),
358 358
         );
359 359
         $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
360
-        return $gravatar . '  <a href="' . $filter_url . '"'
361
-               . ' title="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
360
+        return $gravatar.'  <a href="'.$filter_url.'"'
361
+               . ' title="'.esc_attr__('Click to filter events by this author.', 'event_espresso').'">'
362 362
                . $event_author->display_name
363 363
                . '</a>';
364 364
     }
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
                 'ee_read_registrations',
442 442
                 'espresso_registrations_view_registration'
443 443
             )
444
-            ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
444
+            ? '<a href="'.$attendees_link.'">'.$registered_attendees.'</a>'
445 445
             : $registered_attendees;
446 446
     }
447 447
 
@@ -465,15 +465,15 @@  discard block
 block discarded – undo
465 465
     public function column_actions(EE_Event $item)
466 466
     {
467 467
         //todo: remove when attendees is active
468
-        if (! defined('REG_ADMIN_URL')) {
468
+        if ( ! defined('REG_ADMIN_URL')) {
469 469
             define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
470 470
         }
471 471
         $actionlinks = array();
472 472
 
473 473
         $view_link = get_permalink($item->ID());
474 474
 
475
-        $actionlinks[] = '<a href="' . $view_link . '"'
476
-                         . ' title="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">';
475
+        $actionlinks[] = '<a href="'.$view_link.'"'
476
+                         . ' title="'.esc_attr__('View Event', 'event_espresso').'" target="_blank">';
477 477
         $actionlinks[] = '<div class="dashicons dashicons-search"></div></a>';
478 478
 
479 479
         if (EE_Registry::instance()->CAP->current_user_can(
@@ -486,8 +486,8 @@  discard block
 block discarded – undo
486 486
                 'post'   => $item->ID(),
487 487
             );
488 488
             $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
489
-            $actionlinks[]   = '<a href="' . $edit_link . '"'
490
-                               . ' title="' . esc_attr__('Edit Event', 'event_espresso') . '">'
489
+            $actionlinks[]   = '<a href="'.$edit_link.'"'
490
+                               . ' title="'.esc_attr__('Edit Event', 'event_espresso').'">'
491 491
                                . '<div class="ee-icon ee-icon-calendar-edit"></div>'
492 492
                                . '</a>';
493 493
         }
@@ -507,8 +507,8 @@  discard block
 block discarded – undo
507 507
                 'event_id' => $item->ID(),
508 508
             );
509 509
             $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
510
-            $actionlinks[]        = '<a href="' . $attendees_link . '"'
511
-                                    . ' title="' . esc_attr__('View Registrants', 'event_espresso') . '">'
510
+            $actionlinks[]        = '<a href="'.$attendees_link.'"'
511
+                                    . ' title="'.esc_attr__('View Registrants', 'event_espresso').'">'
512 512
                                     . '<div class="dashicons dashicons-groups"></div>'
513 513
                                     . '</a>';
514 514
         }
Please login to merge, or discard this patch.
core/EE_Capabilities.core.php 2 patches
Indentation   +1368 added lines, -1368 removed lines patch added patch discarded remove patch
@@ -18,980 +18,980 @@  discard block
 block discarded – undo
18 18
 final class EE_Capabilities extends EE_Base
19 19
 {
20 20
 
21
-    /**
22
-     * the name of the wp option used to store caps previously initialized
23
-     */
24
-    const option_name = 'ee_caps_initialized';
25
-
26
-    /**
27
-     * instance of EE_Capabilities object
28
-     *
29
-     * @var EE_Capabilities
30
-     */
31
-    private static $_instance;
32
-
33
-
34
-    /**
35
-     * This is a map of caps that correspond to a default WP_Role.
36
-     * Array is indexed by Role and values are ee capabilities.
37
-     *
38
-     * @since 4.5.0
39
-     *
40
-     * @var array
41
-     */
42
-    private $capabilities_map = array();
43
-
44
-    /**
45
-     * This used to hold an array of EE_Meta_Capability_Map objects
46
-     * that define the granular capabilities mapped to for a user depending on context.
47
-     *
48
-     * @var EE_Meta_Capability_Map[]
49
-     */
50
-    private $_meta_caps = array();
51
-
52
-    /**
53
-     * The internal $capabilities_map needs to be initialized before it can be used.
54
-     * This flag tracks whether that has happened or not.
55
-     * But for this to work, we need three states to indicate:
56
-     *      initialization has not occurred at all
57
-     *      initialization has started but is not complete
58
-     *      initialization is complete
59
-     * The reason this is needed is because the addCaps() method
60
-     * normally requires the $capabilities_map to be initialized,
61
-     * but is also used during the initialization process.
62
-     * So:
63
-     *      If initialized === null, init_caps() will be called before any other methods will run.
64
-     *      If initialized === false, then init_caps() is in the process of running it's logic.
65
-     *      If initialized === true, then init_caps() has completed the initialization process.
66
-     *
67
-     * @var boolean|null $initialized
68
-     */
69
-    private $initialized;
70
-
71
-    /**
72
-     * @var boolean $reset
73
-     */
74
-    private $reset = false;
75
-
76
-
77
-
78
-    /**
79
-     * singleton method used to instantiate class object
80
-     *
81
-     * @since 4.5.0
82
-     *
83
-     * @return EE_Capabilities
84
-     */
85
-    public static function instance()
86
-    {
87
-        //check if instantiated, and if not do so.
88
-        if (! self::$_instance instanceof EE_Capabilities) {
89
-            self::$_instance = new self();
90
-        }
91
-        return self::$_instance;
92
-    }
93
-
94
-
95
-
96
-    /**
97
-     * private constructor
98
-     *
99
-     * @since 4.5.0
100
-     */
101
-    private function __construct()
102
-    {
103
-    }
104
-
105
-
106
-
107
-    /**
108
-     * This delays the initialization of the capabilities class until EE_System core is loaded and ready.
109
-     *
110
-     * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't
111
-     *                    actually REMOVE any capabilities from existing roles, it just resaves defaults roles and
112
-     *                    ensures that they are up to date.
113
-     *
114
-     * @since 4.5.0
115
-     * @return bool
116
-     * @throws EE_Error
117
-     */
118
-    public function init_caps($reset = false)
119
-    {
120
-        if(! EE_Maintenance_Mode::instance()->models_can_query()){
121
-            return false;
122
-        }
123
-        $this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
124
-        // if reset, then completely delete the cache option and clear the $capabilities_map property.
125
-        if ($this->reset) {
126
-            $this->initialized = null;
127
-            $this->capabilities_map = array();
128
-            delete_option(self::option_name);
129
-        }
130
-        if ($this->initialized === null) {
131
-            $this->initialized = false;
132
-            do_action(
133
-                'AHEE__EE_Capabilities__init_caps__before_initialization',
134
-                $this->reset
135
-            );
136
-            $this->addCaps($this->_init_caps_map());
137
-            $this->_set_meta_caps();
138
-            do_action(
139
-                'AHEE__EE_Capabilities__init_caps__after_initialization',
140
-                $this->capabilities_map
141
-            );
142
-            $this->initialized = true;
143
-        }
144
-        // reset $this->reset so that it's not stuck on true if init_caps() gets called again
145
-        $this->reset = false;
146
-        return true;
147
-    }
148
-
149
-
150
-
151
-    /**
152
-     * This sets the meta caps property.
153
-     *
154
-     * @since 4.5.0
155
-     * @return void
156
-     * @throws EE_Error
157
-     */
158
-    private function _set_meta_caps()
159
-    {
160
-        // get default meta caps and filter the returned array
161
-        $this->_meta_caps = apply_filters(
162
-            'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
163
-            $this->_get_default_meta_caps_array()
164
-        );
165
-        //add filter for map_meta_caps but only if models can query.
166
-        if (! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
167
-            add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
168
-        }
169
-    }
170
-
171
-
172
-
173
-    /**
174
-     * This builds and returns the default meta_caps array only once.
175
-     *
176
-     * @since  4.8.28.rc.012
177
-     * @return array
178
-     * @throws EE_Error
179
-     */
180
-    private function _get_default_meta_caps_array()
181
-    {
182
-        static $default_meta_caps = array();
183
-        // make sure we're only ever initializing the default _meta_caps array once if it's empty.
184
-        if (empty($default_meta_caps)) {
185
-            $default_meta_caps = array(
186
-                //edits
187
-                new EE_Meta_Capability_Map_Edit(
188
-                    'ee_edit_event',
189
-                    array('Event', 'ee_edit_published_events', 'ee_edit_others_events', 'ee_edit_private_events')
190
-                ),
191
-                new EE_Meta_Capability_Map_Edit(
192
-                    'ee_edit_venue',
193
-                    array('Venue', 'ee_edit_published_venues', 'ee_edit_others_venues', 'ee_edit_private_venues')
194
-                ),
195
-                new EE_Meta_Capability_Map_Edit(
196
-                    'ee_edit_registration',
197
-                    array('Registration', '', 'ee_edit_others_registrations', '')
198
-                ),
199
-                new EE_Meta_Capability_Map_Edit(
200
-                    'ee_edit_checkin',
201
-                    array('Registration', '', 'ee_edit_others_checkins', '')
202
-                ),
203
-                new EE_Meta_Capability_Map_Messages_Cap(
204
-                    'ee_edit_message',
205
-                    array('Message_Template_Group', '', 'ee_edit_others_messages', 'ee_edit_global_messages')
206
-                ),
207
-                new EE_Meta_Capability_Map_Edit(
208
-                    'ee_edit_default_ticket',
209
-                    array('Ticket', '', 'ee_edit_others_default_tickets', '')
210
-                ),
211
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
212
-                    'ee_edit_question',
213
-                    array('Question', '', '', 'ee_edit_system_questions')
214
-                ),
215
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
216
-                    'ee_edit_question_group',
217
-                    array('Question_Group', '', '', 'ee_edit_system_question_groups')
218
-                ),
219
-                new EE_Meta_Capability_Map_Edit(
220
-                    'ee_edit_payment_method',
221
-                    array('Payment_Method', '', 'ee_edit_others_payment_methods', '')
222
-                ),
223
-                //reads
224
-                new EE_Meta_Capability_Map_Read(
225
-                    'ee_read_event',
226
-                    array('Event', '', 'ee_read_others_events', 'ee_read_private_events')
227
-                ),
228
-                new EE_Meta_Capability_Map_Read(
229
-                    'ee_read_venue',
230
-                    array('Venue', '', 'ee_read_others_venues', 'ee_read_private_venues')
231
-                ),
232
-                new EE_Meta_Capability_Map_Read(
233
-                    'ee_read_registration',
234
-                    array('Registration', '', 'ee_read_others_registrations', '')
235
-                ),
236
-                new EE_Meta_Capability_Map_Read(
237
-                    'ee_read_checkin',
238
-                    array('Registration', '', 'ee_read_others_checkins', '')
239
-                ),
240
-                new EE_Meta_Capability_Map_Messages_Cap(
241
-                    'ee_read_message',
242
-                    array('Message_Template_Group', '', 'ee_read_others_messages', 'ee_read_global_messages')
243
-                ),
244
-                new EE_Meta_Capability_Map_Read(
245
-                    'ee_read_default_ticket',
246
-                    array('Ticket', '', 'ee_read_others_default_tickets', '')
247
-                ),
248
-                new EE_Meta_Capability_Map_Read(
249
-                    'ee_read_payment_method',
250
-                    array('Payment_Method', '', 'ee_read_others_payment_methods', '')
251
-                ),
252
-                //deletes
253
-                new EE_Meta_Capability_Map_Delete(
254
-                    'ee_delete_event',
255
-                    array(
256
-                        'Event',
257
-                        'ee_delete_published_events',
258
-                        'ee_delete_others_events',
259
-                        'ee_delete_private_events',
260
-                    )
261
-                ),
262
-                new EE_Meta_Capability_Map_Delete(
263
-                    'ee_delete_venue',
264
-                    array(
265
-                        'Venue',
266
-                        'ee_delete_published_venues',
267
-                        'ee_delete_others_venues',
268
-                        'ee_delete_private_venues',
269
-                    )
270
-                ),
271
-                new EE_Meta_Capability_Map_Delete(
272
-                    'ee_delete_registration',
273
-                    array('Registration', '', 'ee_delete_others_registrations', '')
274
-                ),
275
-                new EE_Meta_Capability_Map_Delete(
276
-                    'ee_delete_checkin',
277
-                    array('Registration', '', 'ee_delete_others_checkins', '')
278
-                ),
279
-                new EE_Meta_Capability_Map_Messages_Cap(
280
-                    'ee_delete_message',
281
-                    array('Message_Template_Group', '', 'ee_delete_others_messages', 'ee_delete_global_messages')
282
-                ),
283
-                new EE_Meta_Capability_Map_Delete(
284
-                    'ee_delete_default_ticket',
285
-                    array('Ticket', '', 'ee_delete_others_default_tickets', '')
286
-                ),
287
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
288
-                    'ee_delete_question',
289
-                    array('Question', '', '', 'delete_system_questions')
290
-                ),
291
-                new EE_Meta_Capability_Map_Registration_Form_Cap(
292
-                    'ee_delete_question_group',
293
-                    array('Question_Group', '', '', 'delete_system_question_groups')
294
-                ),
295
-                new EE_Meta_Capability_Map_Delete(
296
-                    'ee_delete_payment_method',
297
-                    array('Payment_Method', '', 'ee_delete_others_payment_methods', '')
298
-                ),
299
-            );
300
-        }
301
-        return $default_meta_caps;
302
-    }
303
-
304
-
305
-
306
-    /**
307
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
308
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
309
-     *
310
-     * The actual logic is carried out by implementer classes in their definition of _map_meta_caps.
311
-     *
312
-     * @since 4.5.0
313
-     * @see   wp-includes/capabilities.php
314
-     *
315
-     * @param array  $caps    actual users capabilities
316
-     * @param string $cap     initial capability name that is being checked (the "map" key)
317
-     * @param int    $user_id The user id
318
-     * @param array  $args    Adds context to the cap. Typically the object ID.
319
-     * @return array actual users capabilities
320
-     * @throws EE_Error
321
-     */
322
-    public function map_meta_caps($caps, $cap, $user_id, $args)
323
-    {
324
-        if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
325
-            //loop through our _meta_caps array
326
-            foreach ($this->_meta_caps as $meta_map) {
327
-                if (! $meta_map instanceof EE_Meta_Capability_Map) {
328
-                    continue;
329
-                }
330
-                // don't load models if there is no object ID in the args
331
-                if (! empty($args[0])) {
332
-                    $meta_map->ensure_is_model();
333
-                }
334
-                $caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
335
-            }
336
-        }
337
-        return $caps;
338
-    }
339
-
340
-
341
-
342
-    /**
343
-     * This sets up and returns the initial capabilities map for Event Espresso
344
-     * Note this array is filtered.
345
-     * It is assumed that all available EE capabilities are assigned to the administrator role.
346
-     *
347
-     * @since 4.5.0
348
-     *
349
-     * @return array
350
-     */
351
-    private function _init_caps_map()
352
-    {
353
-        return apply_filters(
354
-            'FHEE__EE_Capabilities__init_caps_map__caps',
355
-            array(
356
-                'administrator'           => array(
357
-                    //basic access
358
-                    'ee_read_ee',
359
-                    //gateways
360
-                    /**
361
-                     * note that with payment method capabilities, although we've implemented
362
-                     * capability mapping which will be used for accessing payment methods owned by
363
-                     * other users.  This is not fully implemented yet in the payment method ui.
364
-                     * Currently only the "plural" caps are in active use.
365
-                     * (Specific payment method caps are in use as well).
366
-                     **/
367
-                    'ee_manage_gateways',
368
-                    'ee_read_payment_methods',
369
-                    'ee_read_others_payment_methods',
370
-                    'ee_edit_payment_methods',
371
-                    'ee_edit_others_payment_methods',
372
-                    'ee_delete_payment_methods',
373
-                    //events
374
-                    'ee_publish_events',
375
-                    'ee_read_private_events',
376
-                    'ee_read_others_events',
377
-                    'ee_read_events',
378
-                    'ee_edit_events',
379
-                    'ee_edit_published_events',
380
-                    'ee_edit_others_events',
381
-                    'ee_edit_private_events',
382
-                    'ee_delete_published_events',
383
-                    'ee_delete_private_events',
384
-                    'ee_delete_events',
385
-                    'ee_delete_others_events',
386
-                    //event categories
387
-                    'ee_manage_event_categories',
388
-                    'ee_edit_event_category',
389
-                    'ee_delete_event_category',
390
-                    'ee_assign_event_category',
391
-                    //venues
392
-                    'ee_publish_venues',
393
-                    'ee_read_venues',
394
-                    'ee_read_others_venues',
395
-                    'ee_read_private_venues',
396
-                    'ee_edit_venues',
397
-                    'ee_edit_others_venues',
398
-                    'ee_edit_published_venues',
399
-                    'ee_edit_private_venues',
400
-                    'ee_delete_venues',
401
-                    'ee_delete_others_venues',
402
-                    'ee_delete_private_venues',
403
-                    'ee_delete_published_venues',
404
-                    //venue categories
405
-                    'ee_manage_venue_categories',
406
-                    'ee_edit_venue_category',
407
-                    'ee_delete_venue_category',
408
-                    'ee_assign_venue_category',
409
-                    //contacts
410
-                    'ee_read_contacts',
411
-                    'ee_edit_contacts',
412
-                    'ee_delete_contacts',
413
-                    //registrations
414
-                    'ee_read_registrations',
415
-                    'ee_read_others_registrations',
416
-                    'ee_edit_registrations',
417
-                    'ee_edit_others_registrations',
418
-                    'ee_delete_registrations',
419
-                    //checkins
420
-                    'ee_read_others_checkins',
421
-                    'ee_read_checkins',
422
-                    'ee_edit_checkins',
423
-                    'ee_edit_others_checkins',
424
-                    'ee_delete_checkins',
425
-                    'ee_delete_others_checkins',
426
-                    //transactions && payments
427
-                    'ee_read_transaction',
428
-                    'ee_read_transactions',
429
-                    'ee_edit_payments',
430
-                    'ee_delete_payments',
431
-                    //messages
432
-                    'ee_read_messages',
433
-                    'ee_read_others_messages',
434
-                    'ee_read_global_messages',
435
-                    'ee_edit_global_messages',
436
-                    'ee_edit_messages',
437
-                    'ee_edit_others_messages',
438
-                    'ee_delete_messages',
439
-                    'ee_delete_others_messages',
440
-                    'ee_delete_global_messages',
441
-                    'ee_send_message',
442
-                    //tickets
443
-                    'ee_read_default_tickets',
444
-                    'ee_read_others_default_tickets',
445
-                    'ee_edit_default_tickets',
446
-                    'ee_edit_others_default_tickets',
447
-                    'ee_delete_default_tickets',
448
-                    'ee_delete_others_default_tickets',
449
-                    //prices
450
-                    'ee_edit_default_price',
451
-                    'ee_edit_default_prices',
452
-                    'ee_delete_default_price',
453
-                    'ee_delete_default_prices',
454
-                    'ee_edit_default_price_type',
455
-                    'ee_edit_default_price_types',
456
-                    'ee_delete_default_price_type',
457
-                    'ee_delete_default_price_types',
458
-                    'ee_read_default_prices',
459
-                    'ee_read_default_price_types',
460
-                    //registration form
461
-                    'ee_edit_questions',
462
-                    'ee_edit_system_questions',
463
-                    'ee_read_questions',
464
-                    'ee_delete_questions',
465
-                    'ee_edit_question_groups',
466
-                    'ee_read_question_groups',
467
-                    'ee_edit_system_question_groups',
468
-                    'ee_delete_question_groups',
469
-                    //event_type taxonomy
470
-                    'ee_assign_event_type',
471
-                    'ee_manage_event_types',
472
-                    'ee_edit_event_type',
473
-                    'ee_delete_event_type',
474
-                ),
475
-                'ee_events_administrator' => array(
476
-                    //core wp caps
477
-                    'read',
478
-                    'read_private_pages',
479
-                    'read_private_posts',
480
-                    'edit_users',
481
-                    'edit_posts',
482
-                    'edit_pages',
483
-                    'edit_published_posts',
484
-                    'edit_published_pages',
485
-                    'edit_private_pages',
486
-                    'edit_private_posts',
487
-                    'edit_others_posts',
488
-                    'edit_others_pages',
489
-                    'publish_posts',
490
-                    'publish_pages',
491
-                    'delete_posts',
492
-                    'delete_pages',
493
-                    'delete_private_pages',
494
-                    'delete_private_posts',
495
-                    'delete_published_pages',
496
-                    'delete_published_posts',
497
-                    'delete_others_posts',
498
-                    'delete_others_pages',
499
-                    'manage_categories',
500
-                    'manage_links',
501
-                    'moderate_comments',
502
-                    'unfiltered_html',
503
-                    'upload_files',
504
-                    'export',
505
-                    'import',
506
-                    'list_users',
507
-                    'level_1', //required if user with this role shows up in author dropdowns
508
-                    //basic ee access
509
-                    'ee_read_ee',
510
-                    //events
511
-                    'ee_publish_events',
512
-                    'ee_read_private_events',
513
-                    'ee_read_others_events',
514
-                    'ee_read_event',
515
-                    'ee_read_events',
516
-                    'ee_edit_event',
517
-                    'ee_edit_events',
518
-                    'ee_edit_published_events',
519
-                    'ee_edit_others_events',
520
-                    'ee_edit_private_events',
521
-                    'ee_delete_published_events',
522
-                    'ee_delete_private_events',
523
-                    'ee_delete_event',
524
-                    'ee_delete_events',
525
-                    'ee_delete_others_events',
526
-                    //event categories
527
-                    'ee_manage_event_categories',
528
-                    'ee_edit_event_category',
529
-                    'ee_delete_event_category',
530
-                    'ee_assign_event_category',
531
-                    //venues
532
-                    'ee_publish_venues',
533
-                    'ee_read_venue',
534
-                    'ee_read_venues',
535
-                    'ee_read_others_venues',
536
-                    'ee_read_private_venues',
537
-                    'ee_edit_venue',
538
-                    'ee_edit_venues',
539
-                    'ee_edit_others_venues',
540
-                    'ee_edit_published_venues',
541
-                    'ee_edit_private_venues',
542
-                    'ee_delete_venue',
543
-                    'ee_delete_venues',
544
-                    'ee_delete_others_venues',
545
-                    'ee_delete_private_venues',
546
-                    'ee_delete_published_venues',
547
-                    //venue categories
548
-                    'ee_manage_venue_categories',
549
-                    'ee_edit_venue_category',
550
-                    'ee_delete_venue_category',
551
-                    'ee_assign_venue_category',
552
-                    //contacts
553
-                    'ee_read_contacts',
554
-                    'ee_edit_contacts',
555
-                    'ee_delete_contacts',
556
-                    //registrations
557
-                    'ee_read_registrations',
558
-                    'ee_read_others_registrations',
559
-                    'ee_edit_registration',
560
-                    'ee_edit_registrations',
561
-                    'ee_edit_others_registrations',
562
-                    'ee_delete_registration',
563
-                    'ee_delete_registrations',
564
-                    //checkins
565
-                    'ee_read_others_checkins',
566
-                    'ee_read_checkins',
567
-                    'ee_edit_checkins',
568
-                    'ee_edit_others_checkins',
569
-                    'ee_delete_checkins',
570
-                    'ee_delete_others_checkins',
571
-                    //transactions && payments
572
-                    'ee_read_transaction',
573
-                    'ee_read_transactions',
574
-                    'ee_edit_payments',
575
-                    'ee_delete_payments',
576
-                    //messages
577
-                    'ee_read_messages',
578
-                    'ee_read_others_messages',
579
-                    'ee_read_global_messages',
580
-                    'ee_edit_global_messages',
581
-                    'ee_edit_messages',
582
-                    'ee_edit_others_messages',
583
-                    'ee_delete_messages',
584
-                    'ee_delete_others_messages',
585
-                    'ee_delete_global_messages',
586
-                    'ee_send_message',
587
-                    //tickets
588
-                    'ee_read_default_tickets',
589
-                    'ee_read_others_default_tickets',
590
-                    'ee_edit_default_tickets',
591
-                    'ee_edit_others_default_tickets',
592
-                    'ee_delete_default_tickets',
593
-                    'ee_delete_others_default_tickets',
594
-                    //prices
595
-                    'ee_edit_default_price',
596
-                    'ee_edit_default_prices',
597
-                    'ee_delete_default_price',
598
-                    'ee_delete_default_prices',
599
-                    'ee_edit_default_price_type',
600
-                    'ee_edit_default_price_types',
601
-                    'ee_delete_default_price_type',
602
-                    'ee_delete_default_price_types',
603
-                    'ee_read_default_prices',
604
-                    'ee_read_default_price_types',
605
-                    //registration form
606
-                    'ee_edit_questions',
607
-                    'ee_edit_system_questions',
608
-                    'ee_read_questions',
609
-                    'ee_delete_questions',
610
-                    'ee_edit_question_groups',
611
-                    'ee_read_question_groups',
612
-                    'ee_edit_system_question_groups',
613
-                    'ee_delete_question_groups',
614
-                    //event_type taxonomy
615
-                    'ee_assign_event_type',
616
-                    'ee_manage_event_types',
617
-                    'ee_edit_event_type',
618
-                    'ee_delete_event_type',
619
-                )
620
-            )
621
-        );
622
-    }
623
-
624
-
625
-
626
-    /**
627
-     * @return bool
628
-     * @throws EE_Error
629
-     */
630
-    private function setupCapabilitiesMap()
631
-    {
632
-        // if the initialization process hasn't even started, then we need to call init_caps()
633
-        if($this->initialized === null) {
634
-            return $this->init_caps();
635
-        }
636
-        // unless resetting, get caps from db if we haven't already
637
-        $this->capabilities_map = $this->reset || ! empty($this->capabilities_map)
638
-            ? $this->capabilities_map
639
-            : get_option(self::option_name, array());
640
-        return true;
641
-    }
642
-
643
-
644
-
645
-    /**
646
-     * @param bool $update
647
-     * @return bool
648
-     */
649
-    private function updateCapabilitiesMap($update = true)
650
-    {
651
-        return $update ? update_option(self::option_name, $this->capabilities_map) : false;
652
-    }
653
-
654
-
655
-
656
-    /**
657
-     * Adds capabilities to roles.
658
-     *
659
-     * @since 4.9.42
660
-     * @param array $capabilities_to_add array of capabilities to add, indexed by roles.
661
-     *                                   Note that this should ONLY be called on activation hook
662
-     *                                   otherwise the caps will be added on every request.
663
-     * @return bool
664
-     * @throws \EE_Error
665
-     */
666
-    public function addCaps(array $capabilities_to_add)
667
-    {
668
-        // don't do anything if the capabilities map can not be initialized
669
-        if (! $this->setupCapabilitiesMap()) {
670
-            return false;
671
-        }
672
-        // and filter the array so others can get in on the fun during resets
673
-        $capabilities_to_add = apply_filters(
674
-            'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
675
-            $capabilities_to_add,
676
-            $this->reset,
677
-            $this->capabilities_map
678
-        );
679
-        $update_capabilities_map = false;
680
-        // if not reset, see what caps are new for each role. if they're new, add them.
681
-        foreach ($capabilities_to_add as $role => $caps_for_role) {
682
-            if (is_array($caps_for_role)) {
683
-                foreach ($caps_for_role as $cap) {
684
-                    if (
685
-                        ! $this->capHasBeenAddedToRole($role, $cap)
686
-                        && $this->add_cap_to_role($role, $cap, true, false)
687
-                    ) {
688
-                        $update_capabilities_map = true;
689
-                    }
690
-                }
691
-            }
692
-        }
693
-        // now let's just save the cap that has been set but only if there's been a change.
694
-        $updated = $this->updateCapabilitiesMap($update_capabilities_map);
695
-        do_action('AHEE__EE_Capabilities__addCaps__complete', $this->capabilities_map, $updated);
696
-        return $updated;
697
-    }
698
-
699
-
700
-
701
-    /**
702
-     * Loops through the capabilities map and removes the role caps specified by the incoming array
703
-     *
704
-     * @param array $caps_map map of capabilities to be removed (indexed by roles)
705
-     * @return bool
706
-     * @throws \EE_Error
707
-     */
708
-    public function removeCaps($caps_map)
709
-    {
710
-        // don't do anything if the capabilities map can not be initialized
711
-        if (! $this->setupCapabilitiesMap()) {
712
-            return false;
713
-        }
714
-        $update_capabilities_map = false;
715
-        foreach ($caps_map as $role => $caps_for_role) {
716
-            if (is_array($caps_for_role)) {
717
-                foreach ($caps_for_role as $cap) {
718
-                    if (
719
-                        $this->capHasBeenAddedToRole($role, $cap)
720
-                        && $this->remove_cap_from_role($role, $cap, false)
721
-                    ) {
722
-                        $update_capabilities_map = true;
723
-                    }
724
-                }
725
-            }
726
-        }
727
-        // maybe resave the caps
728
-        return $this->updateCapabilitiesMap($update_capabilities_map);
729
-    }
730
-
731
-
732
-
733
-    /**
734
-     * This method sets a capability on a role.  Note this should only be done on activation, or if you have something
735
-     * specific to prevent the cap from being added on every page load (adding caps are persistent to the db). Note.
736
-     * this is a wrapper for $wp_role->add_cap()
737
-     *
738
-     * @see   wp-includes/capabilities.php
739
-     * @since 4.5.0
740
-     * @param string|WP_Role $role  A WordPress role the capability is being added to
741
-     * @param string         $cap   The capability being added to the role
742
-     * @param bool           $grant Whether to grant access to this cap on this role.
743
-     * @param bool           $update_capabilities_map
744
-     * @return bool
745
-     * @throws \EE_Error
746
-     */
747
-    public function add_cap_to_role($role, $cap, $grant = true, $update_capabilities_map = true)
748
-    {
749
-        // capture incoming value for $role because we may need it to create a new WP_Role
750
-        $orig_role = $role;
751
-        $role = $role instanceof WP_Role ? $role : get_role($role);
752
-        //if the role isn't available then we create it.
753
-        if (! $role instanceof WP_Role) {
754
-            // if a plugin wants to create a specific role name then they should create the role before
755
-            // EE_Capabilities does.  Otherwise this function will create the role name from the slug:
756
-            // - removes any `ee_` namespacing from the start of the slug.
757
-            // - replaces `_` with ` ` (empty space).
758
-            // - sentence case on the resulting string.
759
-            $role_label = ucwords(str_replace(array('ee_', '_'), array('', ' '), $orig_role));
760
-            $role = add_role($orig_role, $role_label);
761
-        }
762
-        if ($role instanceof WP_Role) {
763
-            // don't do anything if the capabilities map can not be initialized
764
-            if (! $this->setupCapabilitiesMap()) {
765
-                return false;
766
-            }
767
-            if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
768
-                $role->add_cap($cap, $grant);
769
-                $this->capabilities_map[ $role->name ][] = $cap;
770
-                $this->updateCapabilitiesMap($update_capabilities_map);
771
-                return true;
772
-            }
773
-        }
774
-        return false;
775
-    }
776
-
777
-
778
-
779
-    /**
780
-     * Functions similarly to add_cap_to_role except removes cap from given role.
781
-     * Wrapper for $wp_role->remove_cap()
782
-     *
783
-     * @see   wp-includes/capabilities.php
784
-     * @since 4.5.0
785
-     * @param string|WP_Role $role A WordPress role the capability is being removed from.
786
-     * @param string         $cap  The capability being removed
787
-     * @param bool           $update_capabilities_map
788
-     * @return bool
789
-     * @throws \EE_Error
790
-     */
791
-    public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
792
-    {
793
-        // don't do anything if the capabilities map can not be initialized
794
-        if (! $this->setupCapabilitiesMap()) {
795
-            return false;
796
-        }
797
-        $role = $role instanceof WP_Role ? $role :get_role($role);
798
-        if ($index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
799
-            $role->remove_cap($cap);
800
-            unset($this->capabilities_map[ $role->name ][ $index ]);
801
-            $this->updateCapabilitiesMap($update_capabilities_map);
802
-            return true;
803
-        }
804
-        return false;
805
-    }
806
-
807
-
808
-
809
-    /**
810
-     * @param string $role_name
811
-     * @param string $cap
812
-     * @param bool   $get_index
813
-     * @return bool|mixed
814
-     */
815
-    private function capHasBeenAddedToRole($role_name='', $cap='', $get_index = false)
816
-    {
817
-        if (
818
-            isset($this->capabilities_map[$role_name])
819
-            && ($index = array_search($cap, $this->capabilities_map[$role_name], true)) !== false
820
-        ) {
821
-            return $get_index ? $index : true;
822
-        }
823
-        return false;
824
-    }
825
-
826
-
827
-
828
-    /**
829
-     * Wrapper for the native WP current_user_can() method.
830
-     * This is provided as a handy method for a couple things:
831
-     * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
832
-     * write those filters wherever current_user_can is called).
833
-     * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
834
-     *
835
-     * @since 4.5.0
836
-     *
837
-     * @param string $cap     The cap being checked.
838
-     * @param string $context The context where the current_user_can is being called from.
839
-     * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
840
-     *                        filters.
841
-     *
842
-     * @return bool  Whether user can or not.
843
-     */
844
-    public function current_user_can($cap, $context, $id = 0)
845
-    {
846
-        //apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
847
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
848
-        $filtered_cap = apply_filters(
849
-            'FHEE__EE_Capabilities__current_user_can__cap',
850
-            $filtered_cap,
851
-            $context,
852
-            $cap,
853
-            $id
854
-        );
855
-        return ! empty($id)
856
-            ? current_user_can($filtered_cap, $id)
857
-            : current_user_can($filtered_cap);
858
-    }
859
-
860
-
861
-
862
-    /**
863
-     * This is a wrapper for the WP user_can() function and follows the same style as the other wrappers in this class.
864
-     *
865
-     * @param int|WP_User $user    Either the user_id or a WP_User object
866
-     * @param string      $cap     The capability string being checked
867
-     * @param string      $context The context where the user_can is being called from (used in filters).
868
-     * @param int         $id      Optional. Id for item where user_can is being called from ( used in map_meta_cap()
869
-     *                             filters)
870
-     *
871
-     * @return bool Whether user can or not.
872
-     */
873
-    public function user_can($user, $cap, $context, $id = 0)
874
-    {
875
-        //apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
876
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
877
-        $filtered_cap = apply_filters(
878
-            'FHEE__EE_Capabilities__user_can__cap',
879
-            $filtered_cap,
880
-            $context,
881
-            $cap,
882
-            $user,
883
-            $id
884
-        );
885
-        return ! empty($id)
886
-            ? user_can($user, $filtered_cap, $id)
887
-            : user_can($user, $filtered_cap);
888
-    }
889
-
890
-
891
-
892
-    /**
893
-     * Wrapper for the native WP current_user_can_for_blog() method.
894
-     * This is provided as a handy method for a couple things:
895
-     * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
896
-     * write those filters wherever current_user_can is called).
897
-     * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
898
-     *
899
-     * @since 4.5.0
900
-     *
901
-     * @param int    $blog_id The blog id that is being checked for.
902
-     * @param string $cap     The cap being checked.
903
-     * @param string $context The context where the current_user_can is being called from.
904
-     * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
905
-     *                        filters.
906
-     *
907
-     * @return bool  Whether user can or not.
908
-     */
909
-    public function current_user_can_for_blog($blog_id, $cap, $context, $id = 0)
910
-    {
911
-        $user_can = ! empty($id)
912
-            ? current_user_can_for_blog($blog_id, $cap, $id)
913
-            : current_user_can($blog_id, $cap);
914
-        //apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
915
-        $user_can = apply_filters(
916
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
917
-            $user_can,
918
-            $blog_id,
919
-            $cap,
920
-            $id
921
-        );
922
-        $user_can = apply_filters(
923
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can',
924
-            $user_can,
925
-            $context,
926
-            $blog_id,
927
-            $cap,
928
-            $id
929
-        );
930
-        return $user_can;
931
-    }
932
-
933
-
934
-
935
-    /**
936
-     * This helper method just returns an array of registered EE capabilities.
937
-     *
938
-     * @since 4.5.0
939
-     * @param string $role If empty then the entire role/capability map is returned.
940
-     *                     Otherwise just the capabilities for the given role are returned.
941
-     * @return array
942
-     * @throws EE_Error
943
-     */
944
-    public function get_ee_capabilities($role = 'administrator')
945
-    {
946
-        if (! $this->initialized) {
947
-            $this->init_caps();
948
-        }
949
-        if (empty($role)) {
950
-            return $this->capabilities_map;
951
-        }
952
-        return isset($this->capabilities_map[ $role ])
953
-            ? $this->capabilities_map[ $role ]
954
-            : array();
955
-    }
956
-
957
-
958
-
959
-    /**
960
-     * @deprecated 4.9.42
961
-     * @param bool  $reset      If you need to reset Event Espresso's capabilities,
962
-     *                          then please use the init_caps() method with the "$reset" parameter set to "true"
963
-     * @param array $caps_map   Optional.
964
-     *                          Can be used to send a custom map of roles and capabilities for setting them up.
965
-     *                          Note that this should ONLY be called on activation hook or some other one-time
966
-     *                          task otherwise the caps will be added on every request.
967
-     * @return void
968
-     * @throws EE_Error
969
-     */
970
-    public function init_role_caps($reset = false, $caps_map = array())
971
-    {
972
-        // If this method is called directly and reset is set as 'true',
973
-        // then display a doing it wrong notice, because we want resets to go through init_caps()
974
-        // to guarantee that everything is set up correctly.
975
-        // This prevents the capabilities map getting reset incorrectly by direct calls to this method.
976
-        if ($reset) {
977
-            EE_Error::doing_it_wrong(
978
-                __METHOD__,
979
-                sprintf(
980
-                    esc_html__(
981
-                        'The "%1$s" parameter for the "%2$s" method is deprecated. If you need to reset Event Espresso\'s capabilities, then please use the "%3$s" method with the "%1$s" parameter set to "%4$s".',
982
-                        'event_espresso'
983
-                    ),
984
-                    '$reset',
985
-                    __METHOD__ . '()',
986
-                    'EE_Capabilities::init_caps()',
987
-                    'true'
988
-                ),
989
-                '4.9.42',
990
-                '5.0.0'
991
-            );
992
-        }
993
-        $this->addCaps($caps_map);
994
-    }
21
+	/**
22
+	 * the name of the wp option used to store caps previously initialized
23
+	 */
24
+	const option_name = 'ee_caps_initialized';
25
+
26
+	/**
27
+	 * instance of EE_Capabilities object
28
+	 *
29
+	 * @var EE_Capabilities
30
+	 */
31
+	private static $_instance;
32
+
33
+
34
+	/**
35
+	 * This is a map of caps that correspond to a default WP_Role.
36
+	 * Array is indexed by Role and values are ee capabilities.
37
+	 *
38
+	 * @since 4.5.0
39
+	 *
40
+	 * @var array
41
+	 */
42
+	private $capabilities_map = array();
43
+
44
+	/**
45
+	 * This used to hold an array of EE_Meta_Capability_Map objects
46
+	 * that define the granular capabilities mapped to for a user depending on context.
47
+	 *
48
+	 * @var EE_Meta_Capability_Map[]
49
+	 */
50
+	private $_meta_caps = array();
51
+
52
+	/**
53
+	 * The internal $capabilities_map needs to be initialized before it can be used.
54
+	 * This flag tracks whether that has happened or not.
55
+	 * But for this to work, we need three states to indicate:
56
+	 *      initialization has not occurred at all
57
+	 *      initialization has started but is not complete
58
+	 *      initialization is complete
59
+	 * The reason this is needed is because the addCaps() method
60
+	 * normally requires the $capabilities_map to be initialized,
61
+	 * but is also used during the initialization process.
62
+	 * So:
63
+	 *      If initialized === null, init_caps() will be called before any other methods will run.
64
+	 *      If initialized === false, then init_caps() is in the process of running it's logic.
65
+	 *      If initialized === true, then init_caps() has completed the initialization process.
66
+	 *
67
+	 * @var boolean|null $initialized
68
+	 */
69
+	private $initialized;
70
+
71
+	/**
72
+	 * @var boolean $reset
73
+	 */
74
+	private $reset = false;
75
+
76
+
77
+
78
+	/**
79
+	 * singleton method used to instantiate class object
80
+	 *
81
+	 * @since 4.5.0
82
+	 *
83
+	 * @return EE_Capabilities
84
+	 */
85
+	public static function instance()
86
+	{
87
+		//check if instantiated, and if not do so.
88
+		if (! self::$_instance instanceof EE_Capabilities) {
89
+			self::$_instance = new self();
90
+		}
91
+		return self::$_instance;
92
+	}
93
+
94
+
95
+
96
+	/**
97
+	 * private constructor
98
+	 *
99
+	 * @since 4.5.0
100
+	 */
101
+	private function __construct()
102
+	{
103
+	}
104
+
105
+
106
+
107
+	/**
108
+	 * This delays the initialization of the capabilities class until EE_System core is loaded and ready.
109
+	 *
110
+	 * @param bool $reset allows for resetting the default capabilities saved on roles.  Note that this doesn't
111
+	 *                    actually REMOVE any capabilities from existing roles, it just resaves defaults roles and
112
+	 *                    ensures that they are up to date.
113
+	 *
114
+	 * @since 4.5.0
115
+	 * @return bool
116
+	 * @throws EE_Error
117
+	 */
118
+	public function init_caps($reset = false)
119
+	{
120
+		if(! EE_Maintenance_Mode::instance()->models_can_query()){
121
+			return false;
122
+		}
123
+		$this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
124
+		// if reset, then completely delete the cache option and clear the $capabilities_map property.
125
+		if ($this->reset) {
126
+			$this->initialized = null;
127
+			$this->capabilities_map = array();
128
+			delete_option(self::option_name);
129
+		}
130
+		if ($this->initialized === null) {
131
+			$this->initialized = false;
132
+			do_action(
133
+				'AHEE__EE_Capabilities__init_caps__before_initialization',
134
+				$this->reset
135
+			);
136
+			$this->addCaps($this->_init_caps_map());
137
+			$this->_set_meta_caps();
138
+			do_action(
139
+				'AHEE__EE_Capabilities__init_caps__after_initialization',
140
+				$this->capabilities_map
141
+			);
142
+			$this->initialized = true;
143
+		}
144
+		// reset $this->reset so that it's not stuck on true if init_caps() gets called again
145
+		$this->reset = false;
146
+		return true;
147
+	}
148
+
149
+
150
+
151
+	/**
152
+	 * This sets the meta caps property.
153
+	 *
154
+	 * @since 4.5.0
155
+	 * @return void
156
+	 * @throws EE_Error
157
+	 */
158
+	private function _set_meta_caps()
159
+	{
160
+		// get default meta caps and filter the returned array
161
+		$this->_meta_caps = apply_filters(
162
+			'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
163
+			$this->_get_default_meta_caps_array()
164
+		);
165
+		//add filter for map_meta_caps but only if models can query.
166
+		if (! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
167
+			add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
168
+		}
169
+	}
170
+
171
+
172
+
173
+	/**
174
+	 * This builds and returns the default meta_caps array only once.
175
+	 *
176
+	 * @since  4.8.28.rc.012
177
+	 * @return array
178
+	 * @throws EE_Error
179
+	 */
180
+	private function _get_default_meta_caps_array()
181
+	{
182
+		static $default_meta_caps = array();
183
+		// make sure we're only ever initializing the default _meta_caps array once if it's empty.
184
+		if (empty($default_meta_caps)) {
185
+			$default_meta_caps = array(
186
+				//edits
187
+				new EE_Meta_Capability_Map_Edit(
188
+					'ee_edit_event',
189
+					array('Event', 'ee_edit_published_events', 'ee_edit_others_events', 'ee_edit_private_events')
190
+				),
191
+				new EE_Meta_Capability_Map_Edit(
192
+					'ee_edit_venue',
193
+					array('Venue', 'ee_edit_published_venues', 'ee_edit_others_venues', 'ee_edit_private_venues')
194
+				),
195
+				new EE_Meta_Capability_Map_Edit(
196
+					'ee_edit_registration',
197
+					array('Registration', '', 'ee_edit_others_registrations', '')
198
+				),
199
+				new EE_Meta_Capability_Map_Edit(
200
+					'ee_edit_checkin',
201
+					array('Registration', '', 'ee_edit_others_checkins', '')
202
+				),
203
+				new EE_Meta_Capability_Map_Messages_Cap(
204
+					'ee_edit_message',
205
+					array('Message_Template_Group', '', 'ee_edit_others_messages', 'ee_edit_global_messages')
206
+				),
207
+				new EE_Meta_Capability_Map_Edit(
208
+					'ee_edit_default_ticket',
209
+					array('Ticket', '', 'ee_edit_others_default_tickets', '')
210
+				),
211
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
212
+					'ee_edit_question',
213
+					array('Question', '', '', 'ee_edit_system_questions')
214
+				),
215
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
216
+					'ee_edit_question_group',
217
+					array('Question_Group', '', '', 'ee_edit_system_question_groups')
218
+				),
219
+				new EE_Meta_Capability_Map_Edit(
220
+					'ee_edit_payment_method',
221
+					array('Payment_Method', '', 'ee_edit_others_payment_methods', '')
222
+				),
223
+				//reads
224
+				new EE_Meta_Capability_Map_Read(
225
+					'ee_read_event',
226
+					array('Event', '', 'ee_read_others_events', 'ee_read_private_events')
227
+				),
228
+				new EE_Meta_Capability_Map_Read(
229
+					'ee_read_venue',
230
+					array('Venue', '', 'ee_read_others_venues', 'ee_read_private_venues')
231
+				),
232
+				new EE_Meta_Capability_Map_Read(
233
+					'ee_read_registration',
234
+					array('Registration', '', 'ee_read_others_registrations', '')
235
+				),
236
+				new EE_Meta_Capability_Map_Read(
237
+					'ee_read_checkin',
238
+					array('Registration', '', 'ee_read_others_checkins', '')
239
+				),
240
+				new EE_Meta_Capability_Map_Messages_Cap(
241
+					'ee_read_message',
242
+					array('Message_Template_Group', '', 'ee_read_others_messages', 'ee_read_global_messages')
243
+				),
244
+				new EE_Meta_Capability_Map_Read(
245
+					'ee_read_default_ticket',
246
+					array('Ticket', '', 'ee_read_others_default_tickets', '')
247
+				),
248
+				new EE_Meta_Capability_Map_Read(
249
+					'ee_read_payment_method',
250
+					array('Payment_Method', '', 'ee_read_others_payment_methods', '')
251
+				),
252
+				//deletes
253
+				new EE_Meta_Capability_Map_Delete(
254
+					'ee_delete_event',
255
+					array(
256
+						'Event',
257
+						'ee_delete_published_events',
258
+						'ee_delete_others_events',
259
+						'ee_delete_private_events',
260
+					)
261
+				),
262
+				new EE_Meta_Capability_Map_Delete(
263
+					'ee_delete_venue',
264
+					array(
265
+						'Venue',
266
+						'ee_delete_published_venues',
267
+						'ee_delete_others_venues',
268
+						'ee_delete_private_venues',
269
+					)
270
+				),
271
+				new EE_Meta_Capability_Map_Delete(
272
+					'ee_delete_registration',
273
+					array('Registration', '', 'ee_delete_others_registrations', '')
274
+				),
275
+				new EE_Meta_Capability_Map_Delete(
276
+					'ee_delete_checkin',
277
+					array('Registration', '', 'ee_delete_others_checkins', '')
278
+				),
279
+				new EE_Meta_Capability_Map_Messages_Cap(
280
+					'ee_delete_message',
281
+					array('Message_Template_Group', '', 'ee_delete_others_messages', 'ee_delete_global_messages')
282
+				),
283
+				new EE_Meta_Capability_Map_Delete(
284
+					'ee_delete_default_ticket',
285
+					array('Ticket', '', 'ee_delete_others_default_tickets', '')
286
+				),
287
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
288
+					'ee_delete_question',
289
+					array('Question', '', '', 'delete_system_questions')
290
+				),
291
+				new EE_Meta_Capability_Map_Registration_Form_Cap(
292
+					'ee_delete_question_group',
293
+					array('Question_Group', '', '', 'delete_system_question_groups')
294
+				),
295
+				new EE_Meta_Capability_Map_Delete(
296
+					'ee_delete_payment_method',
297
+					array('Payment_Method', '', 'ee_delete_others_payment_methods', '')
298
+				),
299
+			);
300
+		}
301
+		return $default_meta_caps;
302
+	}
303
+
304
+
305
+
306
+	/**
307
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
308
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
309
+	 *
310
+	 * The actual logic is carried out by implementer classes in their definition of _map_meta_caps.
311
+	 *
312
+	 * @since 4.5.0
313
+	 * @see   wp-includes/capabilities.php
314
+	 *
315
+	 * @param array  $caps    actual users capabilities
316
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
317
+	 * @param int    $user_id The user id
318
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
319
+	 * @return array actual users capabilities
320
+	 * @throws EE_Error
321
+	 */
322
+	public function map_meta_caps($caps, $cap, $user_id, $args)
323
+	{
324
+		if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
325
+			//loop through our _meta_caps array
326
+			foreach ($this->_meta_caps as $meta_map) {
327
+				if (! $meta_map instanceof EE_Meta_Capability_Map) {
328
+					continue;
329
+				}
330
+				// don't load models if there is no object ID in the args
331
+				if (! empty($args[0])) {
332
+					$meta_map->ensure_is_model();
333
+				}
334
+				$caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
335
+			}
336
+		}
337
+		return $caps;
338
+	}
339
+
340
+
341
+
342
+	/**
343
+	 * This sets up and returns the initial capabilities map for Event Espresso
344
+	 * Note this array is filtered.
345
+	 * It is assumed that all available EE capabilities are assigned to the administrator role.
346
+	 *
347
+	 * @since 4.5.0
348
+	 *
349
+	 * @return array
350
+	 */
351
+	private function _init_caps_map()
352
+	{
353
+		return apply_filters(
354
+			'FHEE__EE_Capabilities__init_caps_map__caps',
355
+			array(
356
+				'administrator'           => array(
357
+					//basic access
358
+					'ee_read_ee',
359
+					//gateways
360
+					/**
361
+					 * note that with payment method capabilities, although we've implemented
362
+					 * capability mapping which will be used for accessing payment methods owned by
363
+					 * other users.  This is not fully implemented yet in the payment method ui.
364
+					 * Currently only the "plural" caps are in active use.
365
+					 * (Specific payment method caps are in use as well).
366
+					 **/
367
+					'ee_manage_gateways',
368
+					'ee_read_payment_methods',
369
+					'ee_read_others_payment_methods',
370
+					'ee_edit_payment_methods',
371
+					'ee_edit_others_payment_methods',
372
+					'ee_delete_payment_methods',
373
+					//events
374
+					'ee_publish_events',
375
+					'ee_read_private_events',
376
+					'ee_read_others_events',
377
+					'ee_read_events',
378
+					'ee_edit_events',
379
+					'ee_edit_published_events',
380
+					'ee_edit_others_events',
381
+					'ee_edit_private_events',
382
+					'ee_delete_published_events',
383
+					'ee_delete_private_events',
384
+					'ee_delete_events',
385
+					'ee_delete_others_events',
386
+					//event categories
387
+					'ee_manage_event_categories',
388
+					'ee_edit_event_category',
389
+					'ee_delete_event_category',
390
+					'ee_assign_event_category',
391
+					//venues
392
+					'ee_publish_venues',
393
+					'ee_read_venues',
394
+					'ee_read_others_venues',
395
+					'ee_read_private_venues',
396
+					'ee_edit_venues',
397
+					'ee_edit_others_venues',
398
+					'ee_edit_published_venues',
399
+					'ee_edit_private_venues',
400
+					'ee_delete_venues',
401
+					'ee_delete_others_venues',
402
+					'ee_delete_private_venues',
403
+					'ee_delete_published_venues',
404
+					//venue categories
405
+					'ee_manage_venue_categories',
406
+					'ee_edit_venue_category',
407
+					'ee_delete_venue_category',
408
+					'ee_assign_venue_category',
409
+					//contacts
410
+					'ee_read_contacts',
411
+					'ee_edit_contacts',
412
+					'ee_delete_contacts',
413
+					//registrations
414
+					'ee_read_registrations',
415
+					'ee_read_others_registrations',
416
+					'ee_edit_registrations',
417
+					'ee_edit_others_registrations',
418
+					'ee_delete_registrations',
419
+					//checkins
420
+					'ee_read_others_checkins',
421
+					'ee_read_checkins',
422
+					'ee_edit_checkins',
423
+					'ee_edit_others_checkins',
424
+					'ee_delete_checkins',
425
+					'ee_delete_others_checkins',
426
+					//transactions && payments
427
+					'ee_read_transaction',
428
+					'ee_read_transactions',
429
+					'ee_edit_payments',
430
+					'ee_delete_payments',
431
+					//messages
432
+					'ee_read_messages',
433
+					'ee_read_others_messages',
434
+					'ee_read_global_messages',
435
+					'ee_edit_global_messages',
436
+					'ee_edit_messages',
437
+					'ee_edit_others_messages',
438
+					'ee_delete_messages',
439
+					'ee_delete_others_messages',
440
+					'ee_delete_global_messages',
441
+					'ee_send_message',
442
+					//tickets
443
+					'ee_read_default_tickets',
444
+					'ee_read_others_default_tickets',
445
+					'ee_edit_default_tickets',
446
+					'ee_edit_others_default_tickets',
447
+					'ee_delete_default_tickets',
448
+					'ee_delete_others_default_tickets',
449
+					//prices
450
+					'ee_edit_default_price',
451
+					'ee_edit_default_prices',
452
+					'ee_delete_default_price',
453
+					'ee_delete_default_prices',
454
+					'ee_edit_default_price_type',
455
+					'ee_edit_default_price_types',
456
+					'ee_delete_default_price_type',
457
+					'ee_delete_default_price_types',
458
+					'ee_read_default_prices',
459
+					'ee_read_default_price_types',
460
+					//registration form
461
+					'ee_edit_questions',
462
+					'ee_edit_system_questions',
463
+					'ee_read_questions',
464
+					'ee_delete_questions',
465
+					'ee_edit_question_groups',
466
+					'ee_read_question_groups',
467
+					'ee_edit_system_question_groups',
468
+					'ee_delete_question_groups',
469
+					//event_type taxonomy
470
+					'ee_assign_event_type',
471
+					'ee_manage_event_types',
472
+					'ee_edit_event_type',
473
+					'ee_delete_event_type',
474
+				),
475
+				'ee_events_administrator' => array(
476
+					//core wp caps
477
+					'read',
478
+					'read_private_pages',
479
+					'read_private_posts',
480
+					'edit_users',
481
+					'edit_posts',
482
+					'edit_pages',
483
+					'edit_published_posts',
484
+					'edit_published_pages',
485
+					'edit_private_pages',
486
+					'edit_private_posts',
487
+					'edit_others_posts',
488
+					'edit_others_pages',
489
+					'publish_posts',
490
+					'publish_pages',
491
+					'delete_posts',
492
+					'delete_pages',
493
+					'delete_private_pages',
494
+					'delete_private_posts',
495
+					'delete_published_pages',
496
+					'delete_published_posts',
497
+					'delete_others_posts',
498
+					'delete_others_pages',
499
+					'manage_categories',
500
+					'manage_links',
501
+					'moderate_comments',
502
+					'unfiltered_html',
503
+					'upload_files',
504
+					'export',
505
+					'import',
506
+					'list_users',
507
+					'level_1', //required if user with this role shows up in author dropdowns
508
+					//basic ee access
509
+					'ee_read_ee',
510
+					//events
511
+					'ee_publish_events',
512
+					'ee_read_private_events',
513
+					'ee_read_others_events',
514
+					'ee_read_event',
515
+					'ee_read_events',
516
+					'ee_edit_event',
517
+					'ee_edit_events',
518
+					'ee_edit_published_events',
519
+					'ee_edit_others_events',
520
+					'ee_edit_private_events',
521
+					'ee_delete_published_events',
522
+					'ee_delete_private_events',
523
+					'ee_delete_event',
524
+					'ee_delete_events',
525
+					'ee_delete_others_events',
526
+					//event categories
527
+					'ee_manage_event_categories',
528
+					'ee_edit_event_category',
529
+					'ee_delete_event_category',
530
+					'ee_assign_event_category',
531
+					//venues
532
+					'ee_publish_venues',
533
+					'ee_read_venue',
534
+					'ee_read_venues',
535
+					'ee_read_others_venues',
536
+					'ee_read_private_venues',
537
+					'ee_edit_venue',
538
+					'ee_edit_venues',
539
+					'ee_edit_others_venues',
540
+					'ee_edit_published_venues',
541
+					'ee_edit_private_venues',
542
+					'ee_delete_venue',
543
+					'ee_delete_venues',
544
+					'ee_delete_others_venues',
545
+					'ee_delete_private_venues',
546
+					'ee_delete_published_venues',
547
+					//venue categories
548
+					'ee_manage_venue_categories',
549
+					'ee_edit_venue_category',
550
+					'ee_delete_venue_category',
551
+					'ee_assign_venue_category',
552
+					//contacts
553
+					'ee_read_contacts',
554
+					'ee_edit_contacts',
555
+					'ee_delete_contacts',
556
+					//registrations
557
+					'ee_read_registrations',
558
+					'ee_read_others_registrations',
559
+					'ee_edit_registration',
560
+					'ee_edit_registrations',
561
+					'ee_edit_others_registrations',
562
+					'ee_delete_registration',
563
+					'ee_delete_registrations',
564
+					//checkins
565
+					'ee_read_others_checkins',
566
+					'ee_read_checkins',
567
+					'ee_edit_checkins',
568
+					'ee_edit_others_checkins',
569
+					'ee_delete_checkins',
570
+					'ee_delete_others_checkins',
571
+					//transactions && payments
572
+					'ee_read_transaction',
573
+					'ee_read_transactions',
574
+					'ee_edit_payments',
575
+					'ee_delete_payments',
576
+					//messages
577
+					'ee_read_messages',
578
+					'ee_read_others_messages',
579
+					'ee_read_global_messages',
580
+					'ee_edit_global_messages',
581
+					'ee_edit_messages',
582
+					'ee_edit_others_messages',
583
+					'ee_delete_messages',
584
+					'ee_delete_others_messages',
585
+					'ee_delete_global_messages',
586
+					'ee_send_message',
587
+					//tickets
588
+					'ee_read_default_tickets',
589
+					'ee_read_others_default_tickets',
590
+					'ee_edit_default_tickets',
591
+					'ee_edit_others_default_tickets',
592
+					'ee_delete_default_tickets',
593
+					'ee_delete_others_default_tickets',
594
+					//prices
595
+					'ee_edit_default_price',
596
+					'ee_edit_default_prices',
597
+					'ee_delete_default_price',
598
+					'ee_delete_default_prices',
599
+					'ee_edit_default_price_type',
600
+					'ee_edit_default_price_types',
601
+					'ee_delete_default_price_type',
602
+					'ee_delete_default_price_types',
603
+					'ee_read_default_prices',
604
+					'ee_read_default_price_types',
605
+					//registration form
606
+					'ee_edit_questions',
607
+					'ee_edit_system_questions',
608
+					'ee_read_questions',
609
+					'ee_delete_questions',
610
+					'ee_edit_question_groups',
611
+					'ee_read_question_groups',
612
+					'ee_edit_system_question_groups',
613
+					'ee_delete_question_groups',
614
+					//event_type taxonomy
615
+					'ee_assign_event_type',
616
+					'ee_manage_event_types',
617
+					'ee_edit_event_type',
618
+					'ee_delete_event_type',
619
+				)
620
+			)
621
+		);
622
+	}
623
+
624
+
625
+
626
+	/**
627
+	 * @return bool
628
+	 * @throws EE_Error
629
+	 */
630
+	private function setupCapabilitiesMap()
631
+	{
632
+		// if the initialization process hasn't even started, then we need to call init_caps()
633
+		if($this->initialized === null) {
634
+			return $this->init_caps();
635
+		}
636
+		// unless resetting, get caps from db if we haven't already
637
+		$this->capabilities_map = $this->reset || ! empty($this->capabilities_map)
638
+			? $this->capabilities_map
639
+			: get_option(self::option_name, array());
640
+		return true;
641
+	}
642
+
643
+
644
+
645
+	/**
646
+	 * @param bool $update
647
+	 * @return bool
648
+	 */
649
+	private function updateCapabilitiesMap($update = true)
650
+	{
651
+		return $update ? update_option(self::option_name, $this->capabilities_map) : false;
652
+	}
653
+
654
+
655
+
656
+	/**
657
+	 * Adds capabilities to roles.
658
+	 *
659
+	 * @since 4.9.42
660
+	 * @param array $capabilities_to_add array of capabilities to add, indexed by roles.
661
+	 *                                   Note that this should ONLY be called on activation hook
662
+	 *                                   otherwise the caps will be added on every request.
663
+	 * @return bool
664
+	 * @throws \EE_Error
665
+	 */
666
+	public function addCaps(array $capabilities_to_add)
667
+	{
668
+		// don't do anything if the capabilities map can not be initialized
669
+		if (! $this->setupCapabilitiesMap()) {
670
+			return false;
671
+		}
672
+		// and filter the array so others can get in on the fun during resets
673
+		$capabilities_to_add = apply_filters(
674
+			'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
675
+			$capabilities_to_add,
676
+			$this->reset,
677
+			$this->capabilities_map
678
+		);
679
+		$update_capabilities_map = false;
680
+		// if not reset, see what caps are new for each role. if they're new, add them.
681
+		foreach ($capabilities_to_add as $role => $caps_for_role) {
682
+			if (is_array($caps_for_role)) {
683
+				foreach ($caps_for_role as $cap) {
684
+					if (
685
+						! $this->capHasBeenAddedToRole($role, $cap)
686
+						&& $this->add_cap_to_role($role, $cap, true, false)
687
+					) {
688
+						$update_capabilities_map = true;
689
+					}
690
+				}
691
+			}
692
+		}
693
+		// now let's just save the cap that has been set but only if there's been a change.
694
+		$updated = $this->updateCapabilitiesMap($update_capabilities_map);
695
+		do_action('AHEE__EE_Capabilities__addCaps__complete', $this->capabilities_map, $updated);
696
+		return $updated;
697
+	}
698
+
699
+
700
+
701
+	/**
702
+	 * Loops through the capabilities map and removes the role caps specified by the incoming array
703
+	 *
704
+	 * @param array $caps_map map of capabilities to be removed (indexed by roles)
705
+	 * @return bool
706
+	 * @throws \EE_Error
707
+	 */
708
+	public function removeCaps($caps_map)
709
+	{
710
+		// don't do anything if the capabilities map can not be initialized
711
+		if (! $this->setupCapabilitiesMap()) {
712
+			return false;
713
+		}
714
+		$update_capabilities_map = false;
715
+		foreach ($caps_map as $role => $caps_for_role) {
716
+			if (is_array($caps_for_role)) {
717
+				foreach ($caps_for_role as $cap) {
718
+					if (
719
+						$this->capHasBeenAddedToRole($role, $cap)
720
+						&& $this->remove_cap_from_role($role, $cap, false)
721
+					) {
722
+						$update_capabilities_map = true;
723
+					}
724
+				}
725
+			}
726
+		}
727
+		// maybe resave the caps
728
+		return $this->updateCapabilitiesMap($update_capabilities_map);
729
+	}
730
+
731
+
732
+
733
+	/**
734
+	 * This method sets a capability on a role.  Note this should only be done on activation, or if you have something
735
+	 * specific to prevent the cap from being added on every page load (adding caps are persistent to the db). Note.
736
+	 * this is a wrapper for $wp_role->add_cap()
737
+	 *
738
+	 * @see   wp-includes/capabilities.php
739
+	 * @since 4.5.0
740
+	 * @param string|WP_Role $role  A WordPress role the capability is being added to
741
+	 * @param string         $cap   The capability being added to the role
742
+	 * @param bool           $grant Whether to grant access to this cap on this role.
743
+	 * @param bool           $update_capabilities_map
744
+	 * @return bool
745
+	 * @throws \EE_Error
746
+	 */
747
+	public function add_cap_to_role($role, $cap, $grant = true, $update_capabilities_map = true)
748
+	{
749
+		// capture incoming value for $role because we may need it to create a new WP_Role
750
+		$orig_role = $role;
751
+		$role = $role instanceof WP_Role ? $role : get_role($role);
752
+		//if the role isn't available then we create it.
753
+		if (! $role instanceof WP_Role) {
754
+			// if a plugin wants to create a specific role name then they should create the role before
755
+			// EE_Capabilities does.  Otherwise this function will create the role name from the slug:
756
+			// - removes any `ee_` namespacing from the start of the slug.
757
+			// - replaces `_` with ` ` (empty space).
758
+			// - sentence case on the resulting string.
759
+			$role_label = ucwords(str_replace(array('ee_', '_'), array('', ' '), $orig_role));
760
+			$role = add_role($orig_role, $role_label);
761
+		}
762
+		if ($role instanceof WP_Role) {
763
+			// don't do anything if the capabilities map can not be initialized
764
+			if (! $this->setupCapabilitiesMap()) {
765
+				return false;
766
+			}
767
+			if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
768
+				$role->add_cap($cap, $grant);
769
+				$this->capabilities_map[ $role->name ][] = $cap;
770
+				$this->updateCapabilitiesMap($update_capabilities_map);
771
+				return true;
772
+			}
773
+		}
774
+		return false;
775
+	}
776
+
777
+
778
+
779
+	/**
780
+	 * Functions similarly to add_cap_to_role except removes cap from given role.
781
+	 * Wrapper for $wp_role->remove_cap()
782
+	 *
783
+	 * @see   wp-includes/capabilities.php
784
+	 * @since 4.5.0
785
+	 * @param string|WP_Role $role A WordPress role the capability is being removed from.
786
+	 * @param string         $cap  The capability being removed
787
+	 * @param bool           $update_capabilities_map
788
+	 * @return bool
789
+	 * @throws \EE_Error
790
+	 */
791
+	public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
792
+	{
793
+		// don't do anything if the capabilities map can not be initialized
794
+		if (! $this->setupCapabilitiesMap()) {
795
+			return false;
796
+		}
797
+		$role = $role instanceof WP_Role ? $role :get_role($role);
798
+		if ($index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
799
+			$role->remove_cap($cap);
800
+			unset($this->capabilities_map[ $role->name ][ $index ]);
801
+			$this->updateCapabilitiesMap($update_capabilities_map);
802
+			return true;
803
+		}
804
+		return false;
805
+	}
806
+
807
+
808
+
809
+	/**
810
+	 * @param string $role_name
811
+	 * @param string $cap
812
+	 * @param bool   $get_index
813
+	 * @return bool|mixed
814
+	 */
815
+	private function capHasBeenAddedToRole($role_name='', $cap='', $get_index = false)
816
+	{
817
+		if (
818
+			isset($this->capabilities_map[$role_name])
819
+			&& ($index = array_search($cap, $this->capabilities_map[$role_name], true)) !== false
820
+		) {
821
+			return $get_index ? $index : true;
822
+		}
823
+		return false;
824
+	}
825
+
826
+
827
+
828
+	/**
829
+	 * Wrapper for the native WP current_user_can() method.
830
+	 * This is provided as a handy method for a couple things:
831
+	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
832
+	 * write those filters wherever current_user_can is called).
833
+	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
834
+	 *
835
+	 * @since 4.5.0
836
+	 *
837
+	 * @param string $cap     The cap being checked.
838
+	 * @param string $context The context where the current_user_can is being called from.
839
+	 * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
840
+	 *                        filters.
841
+	 *
842
+	 * @return bool  Whether user can or not.
843
+	 */
844
+	public function current_user_can($cap, $context, $id = 0)
845
+	{
846
+		//apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
847
+		$filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
848
+		$filtered_cap = apply_filters(
849
+			'FHEE__EE_Capabilities__current_user_can__cap',
850
+			$filtered_cap,
851
+			$context,
852
+			$cap,
853
+			$id
854
+		);
855
+		return ! empty($id)
856
+			? current_user_can($filtered_cap, $id)
857
+			: current_user_can($filtered_cap);
858
+	}
859
+
860
+
861
+
862
+	/**
863
+	 * This is a wrapper for the WP user_can() function and follows the same style as the other wrappers in this class.
864
+	 *
865
+	 * @param int|WP_User $user    Either the user_id or a WP_User object
866
+	 * @param string      $cap     The capability string being checked
867
+	 * @param string      $context The context where the user_can is being called from (used in filters).
868
+	 * @param int         $id      Optional. Id for item where user_can is being called from ( used in map_meta_cap()
869
+	 *                             filters)
870
+	 *
871
+	 * @return bool Whether user can or not.
872
+	 */
873
+	public function user_can($user, $cap, $context, $id = 0)
874
+	{
875
+		//apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
876
+		$filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
877
+		$filtered_cap = apply_filters(
878
+			'FHEE__EE_Capabilities__user_can__cap',
879
+			$filtered_cap,
880
+			$context,
881
+			$cap,
882
+			$user,
883
+			$id
884
+		);
885
+		return ! empty($id)
886
+			? user_can($user, $filtered_cap, $id)
887
+			: user_can($user, $filtered_cap);
888
+	}
889
+
890
+
891
+
892
+	/**
893
+	 * Wrapper for the native WP current_user_can_for_blog() method.
894
+	 * This is provided as a handy method for a couple things:
895
+	 * 1. Using the context string it allows for targeted filtering by addons for a specific check (without having to
896
+	 * write those filters wherever current_user_can is called).
897
+	 * 2. Explicit passing of $id from a given context ( useful in the cases of map_meta_cap filters )
898
+	 *
899
+	 * @since 4.5.0
900
+	 *
901
+	 * @param int    $blog_id The blog id that is being checked for.
902
+	 * @param string $cap     The cap being checked.
903
+	 * @param string $context The context where the current_user_can is being called from.
904
+	 * @param int    $id      Optional. Id for item where current_user_can is being called from (used in map_meta_cap()
905
+	 *                        filters.
906
+	 *
907
+	 * @return bool  Whether user can or not.
908
+	 */
909
+	public function current_user_can_for_blog($blog_id, $cap, $context, $id = 0)
910
+	{
911
+		$user_can = ! empty($id)
912
+			? current_user_can_for_blog($blog_id, $cap, $id)
913
+			: current_user_can($blog_id, $cap);
914
+		//apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
915
+		$user_can = apply_filters(
916
+			'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
917
+			$user_can,
918
+			$blog_id,
919
+			$cap,
920
+			$id
921
+		);
922
+		$user_can = apply_filters(
923
+			'FHEE__EE_Capabilities__current_user_can_for_blog__user_can',
924
+			$user_can,
925
+			$context,
926
+			$blog_id,
927
+			$cap,
928
+			$id
929
+		);
930
+		return $user_can;
931
+	}
932
+
933
+
934
+
935
+	/**
936
+	 * This helper method just returns an array of registered EE capabilities.
937
+	 *
938
+	 * @since 4.5.0
939
+	 * @param string $role If empty then the entire role/capability map is returned.
940
+	 *                     Otherwise just the capabilities for the given role are returned.
941
+	 * @return array
942
+	 * @throws EE_Error
943
+	 */
944
+	public function get_ee_capabilities($role = 'administrator')
945
+	{
946
+		if (! $this->initialized) {
947
+			$this->init_caps();
948
+		}
949
+		if (empty($role)) {
950
+			return $this->capabilities_map;
951
+		}
952
+		return isset($this->capabilities_map[ $role ])
953
+			? $this->capabilities_map[ $role ]
954
+			: array();
955
+	}
956
+
957
+
958
+
959
+	/**
960
+	 * @deprecated 4.9.42
961
+	 * @param bool  $reset      If you need to reset Event Espresso's capabilities,
962
+	 *                          then please use the init_caps() method with the "$reset" parameter set to "true"
963
+	 * @param array $caps_map   Optional.
964
+	 *                          Can be used to send a custom map of roles and capabilities for setting them up.
965
+	 *                          Note that this should ONLY be called on activation hook or some other one-time
966
+	 *                          task otherwise the caps will be added on every request.
967
+	 * @return void
968
+	 * @throws EE_Error
969
+	 */
970
+	public function init_role_caps($reset = false, $caps_map = array())
971
+	{
972
+		// If this method is called directly and reset is set as 'true',
973
+		// then display a doing it wrong notice, because we want resets to go through init_caps()
974
+		// to guarantee that everything is set up correctly.
975
+		// This prevents the capabilities map getting reset incorrectly by direct calls to this method.
976
+		if ($reset) {
977
+			EE_Error::doing_it_wrong(
978
+				__METHOD__,
979
+				sprintf(
980
+					esc_html__(
981
+						'The "%1$s" parameter for the "%2$s" method is deprecated. If you need to reset Event Espresso\'s capabilities, then please use the "%3$s" method with the "%1$s" parameter set to "%4$s".',
982
+						'event_espresso'
983
+					),
984
+					'$reset',
985
+					__METHOD__ . '()',
986
+					'EE_Capabilities::init_caps()',
987
+					'true'
988
+				),
989
+				'4.9.42',
990
+				'5.0.0'
991
+			);
992
+		}
993
+		$this->addCaps($caps_map);
994
+	}
995 995
 
996 996
 
997 997
 
@@ -1012,142 +1012,142 @@  discard block
 block discarded – undo
1012 1012
 abstract class EE_Meta_Capability_Map
1013 1013
 {
1014 1014
 
1015
-    public $meta_cap;
1016
-
1017
-    /**
1018
-     * @var EEM_Base
1019
-     */
1020
-    protected $_model;
1021
-
1022
-    protected $_model_name;
1023
-
1024
-    public $published_cap = '';
1025
-
1026
-    public $others_cap = '';
1027
-
1028
-    public $private_cap = '';
1029
-
1030
-
1031
-    /**
1032
-     * constructor.
1033
-     * Receives the setup arguments for the map.
1034
-     *
1035
-     * @since                        4.5.0
1036
-     *
1037
-     * @param string $meta_cap   What meta capability is this mapping.
1038
-     * @param array  $map_values array {
1039
-     *                           //array of values that MUST match a count of 4.  It's okay to send an empty string for
1040
-     *                           capabilities that don't get mapped to.
1041
-     *
1042
-     * @type         $map_values [0] string A string representing the model name. Required.  String's
1043
-     *                               should always be used when Menu Maps are registered via the
1044
-     *                               plugin API as models are not allowed to be instantiated when
1045
-     *                               in maintenance mode 2 (migrations).
1046
-     * @type         $map_values [1] string represents the capability used for published. Optional.
1047
-     * @type         $map_values [2] string represents the capability used for "others". Optional.
1048
-     * @type         $map_values [3] string represents the capability used for private. Optional.
1049
-     *                               }
1050
-     * @throws EE_Error
1051
-     */
1052
-    public function __construct($meta_cap, $map_values)
1053
-    {
1054
-        $this->meta_cap = $meta_cap;
1055
-        //verify there are four args in the $map_values array;
1056
-        if (count($map_values) !== 4) {
1057
-            throw new EE_Error(
1058
-                sprintf(
1059
-                    __(
1060
-                        'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1061
-                        'event_espresso'
1062
-                    ),
1063
-                    '<br>' . print_r($map_values, true)
1064
-                )
1065
-            );
1066
-        }
1067
-        //set properties
1068
-        $this->_model = null;
1069
-        $this->_model_name = $map_values[0];
1070
-        $this->published_cap = (string)$map_values[1];
1071
-        $this->others_cap = (string)$map_values[2];
1072
-        $this->private_cap = (string)$map_values[3];
1073
-    }
1074
-
1075
-    /**
1076
-     * Makes it so this object stops filtering caps
1077
-     */
1078
-    public function remove_filters()
1079
-    {
1080
-        remove_filter('map_meta_cap', array($this, 'map_meta_caps'), 10);
1081
-    }
1082
-
1083
-
1084
-    /**
1085
-     * This method ensures that the $model property is converted from the model name string to a proper EEM_Base class
1086
-     *
1087
-     * @since 4.5.0
1088
-     * @throws EE_Error
1089
-     *
1090
-     * @return void
1091
-     */
1092
-    public function ensure_is_model()
1093
-    {
1094
-        //is it already instantiated?
1095
-        if ($this->_model instanceof EEM_Base) {
1096
-            return;
1097
-        }
1098
-        //ensure model name is string
1099
-        $this->_model_name = (string)$this->_model_name;
1100
-        //error proof if the name has EEM in it
1101
-        $this->_model_name = str_replace('EEM', '', $this->_model_name);
1102
-        $this->_model = EE_Registry::instance()->load_model($this->_model_name);
1103
-        if (! $this->_model instanceof EEM_Base) {
1104
-            throw new EE_Error(
1105
-                sprintf(
1106
-                    __(
1107
-                        'This string passed in to %s to represent a EEM_Base model class was not able to be used to instantiate the class.   Please ensure that the string is a match for the EEM_Base model name (not including the EEM_ part). This was given: %s',
1108
-                        'event_espresso'
1109
-                    ),
1110
-                    get_class($this),
1111
-                    $this->_model
1112
-                )
1113
-            );
1114
-        }
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     *
1120
-     * @see   EE_Meta_Capability_Map::_map_meta_caps() for docs on params.
1121
-     * @since 4.6.x
1122
-     *
1123
-     * @param $caps
1124
-     * @param $cap
1125
-     * @param $user_id
1126
-     * @param $args
1127
-     *
1128
-     * @return array
1129
-     */
1130
-    public function map_meta_caps($caps, $cap, $user_id, $args)
1131
-    {
1132
-        return $this->_map_meta_caps($caps, $cap, $user_id, $args);
1133
-    }
1134
-
1135
-
1136
-    /**
1137
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1138
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1139
-     *
1140
-     * @since 4.5.0
1141
-     * @see   wp-includes/capabilities.php
1142
-     *
1143
-     * @param array  $caps    actual users capabilities
1144
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1145
-     * @param int    $user_id The user id
1146
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1147
-     *
1148
-     * @return array   actual users capabilities
1149
-     */
1150
-    abstract protected function _map_meta_caps($caps, $cap, $user_id, $args);
1015
+	public $meta_cap;
1016
+
1017
+	/**
1018
+	 * @var EEM_Base
1019
+	 */
1020
+	protected $_model;
1021
+
1022
+	protected $_model_name;
1023
+
1024
+	public $published_cap = '';
1025
+
1026
+	public $others_cap = '';
1027
+
1028
+	public $private_cap = '';
1029
+
1030
+
1031
+	/**
1032
+	 * constructor.
1033
+	 * Receives the setup arguments for the map.
1034
+	 *
1035
+	 * @since                        4.5.0
1036
+	 *
1037
+	 * @param string $meta_cap   What meta capability is this mapping.
1038
+	 * @param array  $map_values array {
1039
+	 *                           //array of values that MUST match a count of 4.  It's okay to send an empty string for
1040
+	 *                           capabilities that don't get mapped to.
1041
+	 *
1042
+	 * @type         $map_values [0] string A string representing the model name. Required.  String's
1043
+	 *                               should always be used when Menu Maps are registered via the
1044
+	 *                               plugin API as models are not allowed to be instantiated when
1045
+	 *                               in maintenance mode 2 (migrations).
1046
+	 * @type         $map_values [1] string represents the capability used for published. Optional.
1047
+	 * @type         $map_values [2] string represents the capability used for "others". Optional.
1048
+	 * @type         $map_values [3] string represents the capability used for private. Optional.
1049
+	 *                               }
1050
+	 * @throws EE_Error
1051
+	 */
1052
+	public function __construct($meta_cap, $map_values)
1053
+	{
1054
+		$this->meta_cap = $meta_cap;
1055
+		//verify there are four args in the $map_values array;
1056
+		if (count($map_values) !== 4) {
1057
+			throw new EE_Error(
1058
+				sprintf(
1059
+					__(
1060
+						'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1061
+						'event_espresso'
1062
+					),
1063
+					'<br>' . print_r($map_values, true)
1064
+				)
1065
+			);
1066
+		}
1067
+		//set properties
1068
+		$this->_model = null;
1069
+		$this->_model_name = $map_values[0];
1070
+		$this->published_cap = (string)$map_values[1];
1071
+		$this->others_cap = (string)$map_values[2];
1072
+		$this->private_cap = (string)$map_values[3];
1073
+	}
1074
+
1075
+	/**
1076
+	 * Makes it so this object stops filtering caps
1077
+	 */
1078
+	public function remove_filters()
1079
+	{
1080
+		remove_filter('map_meta_cap', array($this, 'map_meta_caps'), 10);
1081
+	}
1082
+
1083
+
1084
+	/**
1085
+	 * This method ensures that the $model property is converted from the model name string to a proper EEM_Base class
1086
+	 *
1087
+	 * @since 4.5.0
1088
+	 * @throws EE_Error
1089
+	 *
1090
+	 * @return void
1091
+	 */
1092
+	public function ensure_is_model()
1093
+	{
1094
+		//is it already instantiated?
1095
+		if ($this->_model instanceof EEM_Base) {
1096
+			return;
1097
+		}
1098
+		//ensure model name is string
1099
+		$this->_model_name = (string)$this->_model_name;
1100
+		//error proof if the name has EEM in it
1101
+		$this->_model_name = str_replace('EEM', '', $this->_model_name);
1102
+		$this->_model = EE_Registry::instance()->load_model($this->_model_name);
1103
+		if (! $this->_model instanceof EEM_Base) {
1104
+			throw new EE_Error(
1105
+				sprintf(
1106
+					__(
1107
+						'This string passed in to %s to represent a EEM_Base model class was not able to be used to instantiate the class.   Please ensure that the string is a match for the EEM_Base model name (not including the EEM_ part). This was given: %s',
1108
+						'event_espresso'
1109
+					),
1110
+					get_class($this),
1111
+					$this->_model
1112
+				)
1113
+			);
1114
+		}
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 *
1120
+	 * @see   EE_Meta_Capability_Map::_map_meta_caps() for docs on params.
1121
+	 * @since 4.6.x
1122
+	 *
1123
+	 * @param $caps
1124
+	 * @param $cap
1125
+	 * @param $user_id
1126
+	 * @param $args
1127
+	 *
1128
+	 * @return array
1129
+	 */
1130
+	public function map_meta_caps($caps, $cap, $user_id, $args)
1131
+	{
1132
+		return $this->_map_meta_caps($caps, $cap, $user_id, $args);
1133
+	}
1134
+
1135
+
1136
+	/**
1137
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1138
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1139
+	 *
1140
+	 * @since 4.5.0
1141
+	 * @see   wp-includes/capabilities.php
1142
+	 *
1143
+	 * @param array  $caps    actual users capabilities
1144
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1145
+	 * @param int    $user_id The user id
1146
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1147
+	 *
1148
+	 * @return array   actual users capabilities
1149
+	 */
1150
+	abstract protected function _map_meta_caps($caps, $cap, $user_id, $args);
1151 1151
 }
1152 1152
 
1153 1153
 
@@ -1163,81 +1163,81 @@  discard block
 block discarded – undo
1163 1163
 class EE_Meta_Capability_Map_Edit extends EE_Meta_Capability_Map
1164 1164
 {
1165 1165
 
1166
-    /**
1167
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1168
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1169
-     *
1170
-     * @since 4.5.0
1171
-     * @see   wp-includes/capabilities.php
1172
-     *
1173
-     * @param array  $caps    actual users capabilities
1174
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1175
-     * @param int    $user_id The user id
1176
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1177
-     *
1178
-     * @return array   actual users capabilities
1179
-     */
1180
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1181
-    {
1182
-        //only process if we're checking our mapped_cap
1183
-        if ($cap !== $this->meta_cap) {
1184
-            return $caps;
1185
-        }
1186
-
1187
-        //okay it is a meta cap so let's first remove that cap from the $caps array.
1188
-        if (($key = array_search($cap, $caps)) !== false) {
1189
-            unset($caps[$key]);
1190
-        }
1191
-
1192
-        //cast $user_id to int for later explicit comparisons
1193
-        $user_id = (int) $user_id;
1194
-
1195
-        /** @var EE_Base_Class $obj */
1196
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1197
-        //if no obj then let's just do cap
1198
-        if (! $obj instanceof EE_Base_Class) {
1199
-            $caps[] = 'do_not_allow';
1200
-            return $caps;
1201
-        }
1202
-        $caps[] = $cap . 's';
1203
-        if ($obj instanceof EE_CPT_Base) {
1204
-            //if the item author is set and the user is the author...
1205
-            if ($obj->wp_user() && $user_id === $obj->wp_user()) {
1206
-                //if obj is published...
1207
-                if ($obj->status() === 'publish') {
1208
-                    $caps[] = $this->published_cap;
1209
-                }
1210
-            } else {
1211
-                //the user is trying to edit someone else's obj
1212
-                if (! empty($this->others_cap)) {
1213
-                    $caps[] = $this->others_cap;
1214
-                }
1215
-                if (! empty($this->published_cap) && $obj->status() === 'publish') {
1216
-                    $caps[] = $this->published_cap;
1217
-                } elseif (! empty($this->private_cap) && $obj->status() === 'private') {
1218
-                    $caps[] = $this->private_cap;
1219
-                }
1220
-            }
1221
-        } else {
1222
-            //not a cpt object so handled differently
1223
-            $has_cap = false;
1224
-            try {
1225
-                $has_cap = method_exists($obj, 'wp_user')
1226
-                    && $obj->wp_user()
1227
-                    && $obj->wp_user() === $user_id;
1228
-            } catch (Exception $e) {
1229
-                if (WP_DEBUG) {
1230
-                    EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1231
-                }
1232
-            }
1233
-            if (! $has_cap) {
1234
-                if (! empty($this->others_cap)) {
1235
-                    $caps[] = $this->others_cap;
1236
-                }
1237
-            }
1238
-        }
1239
-        return $caps;
1240
-    }
1166
+	/**
1167
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1168
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1169
+	 *
1170
+	 * @since 4.5.0
1171
+	 * @see   wp-includes/capabilities.php
1172
+	 *
1173
+	 * @param array  $caps    actual users capabilities
1174
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1175
+	 * @param int    $user_id The user id
1176
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1177
+	 *
1178
+	 * @return array   actual users capabilities
1179
+	 */
1180
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1181
+	{
1182
+		//only process if we're checking our mapped_cap
1183
+		if ($cap !== $this->meta_cap) {
1184
+			return $caps;
1185
+		}
1186
+
1187
+		//okay it is a meta cap so let's first remove that cap from the $caps array.
1188
+		if (($key = array_search($cap, $caps)) !== false) {
1189
+			unset($caps[$key]);
1190
+		}
1191
+
1192
+		//cast $user_id to int for later explicit comparisons
1193
+		$user_id = (int) $user_id;
1194
+
1195
+		/** @var EE_Base_Class $obj */
1196
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1197
+		//if no obj then let's just do cap
1198
+		if (! $obj instanceof EE_Base_Class) {
1199
+			$caps[] = 'do_not_allow';
1200
+			return $caps;
1201
+		}
1202
+		$caps[] = $cap . 's';
1203
+		if ($obj instanceof EE_CPT_Base) {
1204
+			//if the item author is set and the user is the author...
1205
+			if ($obj->wp_user() && $user_id === $obj->wp_user()) {
1206
+				//if obj is published...
1207
+				if ($obj->status() === 'publish') {
1208
+					$caps[] = $this->published_cap;
1209
+				}
1210
+			} else {
1211
+				//the user is trying to edit someone else's obj
1212
+				if (! empty($this->others_cap)) {
1213
+					$caps[] = $this->others_cap;
1214
+				}
1215
+				if (! empty($this->published_cap) && $obj->status() === 'publish') {
1216
+					$caps[] = $this->published_cap;
1217
+				} elseif (! empty($this->private_cap) && $obj->status() === 'private') {
1218
+					$caps[] = $this->private_cap;
1219
+				}
1220
+			}
1221
+		} else {
1222
+			//not a cpt object so handled differently
1223
+			$has_cap = false;
1224
+			try {
1225
+				$has_cap = method_exists($obj, 'wp_user')
1226
+					&& $obj->wp_user()
1227
+					&& $obj->wp_user() === $user_id;
1228
+			} catch (Exception $e) {
1229
+				if (WP_DEBUG) {
1230
+					EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1231
+				}
1232
+			}
1233
+			if (! $has_cap) {
1234
+				if (! empty($this->others_cap)) {
1235
+					$caps[] = $this->others_cap;
1236
+				}
1237
+			}
1238
+		}
1239
+		return $caps;
1240
+	}
1241 1241
 }
1242 1242
 
1243 1243
 
@@ -1254,24 +1254,24 @@  discard block
 block discarded – undo
1254 1254
 class EE_Meta_Capability_Map_Delete extends EE_Meta_Capability_Map_Edit
1255 1255
 {
1256 1256
 
1257
-    /**
1258
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1259
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1260
-     *
1261
-     * @since 4.5.0
1262
-     * @see   wp-includes/capabilities.php
1263
-     *
1264
-     * @param array  $caps    actual users capabilities
1265
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1266
-     * @param int    $user_id The user id
1267
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1268
-     *
1269
-     * @return array   actual users capabilities
1270
-     */
1271
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1272
-    {
1273
-        return parent::_map_meta_caps($caps, $cap, $user_id, $args);
1274
-    }
1257
+	/**
1258
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1259
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1260
+	 *
1261
+	 * @since 4.5.0
1262
+	 * @see   wp-includes/capabilities.php
1263
+	 *
1264
+	 * @param array  $caps    actual users capabilities
1265
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1266
+	 * @param int    $user_id The user id
1267
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1268
+	 *
1269
+	 * @return array   actual users capabilities
1270
+	 */
1271
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1272
+	{
1273
+		return parent::_map_meta_caps($caps, $cap, $user_id, $args);
1274
+	}
1275 1275
 }
1276 1276
 
1277 1277
 
@@ -1287,85 +1287,85 @@  discard block
 block discarded – undo
1287 1287
 class EE_Meta_Capability_Map_Read extends EE_Meta_Capability_Map
1288 1288
 {
1289 1289
 
1290
-    /**
1291
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1292
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1293
-     *
1294
-     * @since 4.5.0
1295
-     * @see   wp-includes/capabilities.php
1296
-     *
1297
-     * @param array  $caps    actual users capabilities
1298
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1299
-     * @param int    $user_id The user id
1300
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1301
-     *
1302
-     * @return array   actual users capabilities
1303
-     */
1304
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1305
-    {
1306
-        //only process if we're checking our mapped cap;
1307
-        if ($cap !== $this->meta_cap) {
1308
-            return $caps;
1309
-        }
1310
-
1311
-        //okay it is a meta cap so let's first remove that cap from the $caps array.
1312
-        if (($key = array_search($cap, $caps)) !== false) {
1313
-            unset($caps[$key]);
1314
-        }
1315
-
1316
-        //cast $user_id to int for later explicit comparisons
1317
-        $user_id = (int) $user_id;
1318
-
1319
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1320
-        //if no obj then let's just do cap
1321
-        if (! $obj instanceof EE_Base_Class) {
1322
-            $caps[] = 'do_not_allow';
1323
-            return $caps;
1324
-        }
1325
-
1326
-        $caps[] = $cap . 's';
1327
-        if ($obj instanceof EE_CPT_Base) {
1328
-            $status_obj = get_post_status_object($obj->status());
1329
-            if ($status_obj->public) {
1330
-                return $caps;
1331
-            }
1332
-            //if the item author is set and the user is not the author...
1333
-            if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1334
-                if (! empty($this->others_cap)) {
1335
-                    $caps[] = $this->others_cap;
1336
-                }
1337
-            }
1338
-            //yes this means that if users created the private post, they are able to see it regardless of private cap.
1339
-            if ($status_obj->private
1340
-                && ! empty($this->private_cap)
1341
-                && $obj->wp_user() !== $user_id
1342
-            ) {
1343
-                //the user is trying to view a private object for an object they don't own.
1344
-                $caps[] = $this->private_cap;
1345
-            }
1346
-        } else {
1347
-            //not a cpt object so handled differently
1348
-            $has_cap = false;
1349
-            try {
1350
-                $has_cap = method_exists($obj, 'wp_user')
1351
-                           && $obj->wp_user()
1352
-                           && $obj->wp_user() === $user_id;
1353
-            } catch (Exception $e) {
1354
-                if (WP_DEBUG) {
1355
-                    EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1356
-                }
1357
-            }
1358
-            if (! $has_cap) {
1359
-                if (! empty($this->private_cap)) {
1360
-                    $caps[] = $this->private_cap;
1361
-                }
1362
-                if (! empty($this->others_cap)) {
1363
-                    $caps[] = $this->others_cap;
1364
-                }
1365
-            }
1366
-        }
1367
-        return $caps;
1368
-    }
1290
+	/**
1291
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1292
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1293
+	 *
1294
+	 * @since 4.5.0
1295
+	 * @see   wp-includes/capabilities.php
1296
+	 *
1297
+	 * @param array  $caps    actual users capabilities
1298
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1299
+	 * @param int    $user_id The user id
1300
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1301
+	 *
1302
+	 * @return array   actual users capabilities
1303
+	 */
1304
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1305
+	{
1306
+		//only process if we're checking our mapped cap;
1307
+		if ($cap !== $this->meta_cap) {
1308
+			return $caps;
1309
+		}
1310
+
1311
+		//okay it is a meta cap so let's first remove that cap from the $caps array.
1312
+		if (($key = array_search($cap, $caps)) !== false) {
1313
+			unset($caps[$key]);
1314
+		}
1315
+
1316
+		//cast $user_id to int for later explicit comparisons
1317
+		$user_id = (int) $user_id;
1318
+
1319
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1320
+		//if no obj then let's just do cap
1321
+		if (! $obj instanceof EE_Base_Class) {
1322
+			$caps[] = 'do_not_allow';
1323
+			return $caps;
1324
+		}
1325
+
1326
+		$caps[] = $cap . 's';
1327
+		if ($obj instanceof EE_CPT_Base) {
1328
+			$status_obj = get_post_status_object($obj->status());
1329
+			if ($status_obj->public) {
1330
+				return $caps;
1331
+			}
1332
+			//if the item author is set and the user is not the author...
1333
+			if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1334
+				if (! empty($this->others_cap)) {
1335
+					$caps[] = $this->others_cap;
1336
+				}
1337
+			}
1338
+			//yes this means that if users created the private post, they are able to see it regardless of private cap.
1339
+			if ($status_obj->private
1340
+				&& ! empty($this->private_cap)
1341
+				&& $obj->wp_user() !== $user_id
1342
+			) {
1343
+				//the user is trying to view a private object for an object they don't own.
1344
+				$caps[] = $this->private_cap;
1345
+			}
1346
+		} else {
1347
+			//not a cpt object so handled differently
1348
+			$has_cap = false;
1349
+			try {
1350
+				$has_cap = method_exists($obj, 'wp_user')
1351
+						   && $obj->wp_user()
1352
+						   && $obj->wp_user() === $user_id;
1353
+			} catch (Exception $e) {
1354
+				if (WP_DEBUG) {
1355
+					EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1356
+				}
1357
+			}
1358
+			if (! $has_cap) {
1359
+				if (! empty($this->private_cap)) {
1360
+					$caps[] = $this->private_cap;
1361
+				}
1362
+				if (! empty($this->others_cap)) {
1363
+					$caps[] = $this->others_cap;
1364
+				}
1365
+			}
1366
+		}
1367
+		return $caps;
1368
+	}
1369 1369
 }
1370 1370
 
1371 1371
 
@@ -1382,56 +1382,56 @@  discard block
 block discarded – undo
1382 1382
 class EE_Meta_Capability_Map_Messages_Cap extends EE_Meta_Capability_Map
1383 1383
 {
1384 1384
 
1385
-    /**
1386
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1387
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1388
-     *
1389
-     * @since 4.5.0
1390
-     * @see   wp-includes/capabilities.php
1391
-     *
1392
-     * @param array  $caps    actual users capabilities
1393
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1394
-     * @param int    $user_id The user id
1395
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1396
-     *
1397
-     * @return array   actual users capabilities
1398
-     */
1399
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1400
-    {
1401
-        //only process if we're checking our mapped_cap
1402
-        if ($cap !== $this->meta_cap) {
1403
-            return $caps;
1404
-        }
1405
-
1406
-        //okay it is a meta cap so let's first remove that cap from the $caps array.
1407
-        if (($key = array_search($cap, $caps)) !== false) {
1408
-            unset($caps[$key]);
1409
-        }
1410
-
1411
-        //cast $user_id to int for later explicit comparisons
1412
-        $user_id = (int) $user_id;
1413
-
1414
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1415
-        //if no obj then let's just do cap
1416
-        if (! $obj instanceof EE_Message_Template_Group) {
1417
-            $caps[] = 'do_not_allow';
1418
-            return $caps;
1419
-        }
1420
-        $caps[] = $cap . 's';
1421
-        $is_global = $obj->is_global();
1422
-        if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1423
-            if ($is_global) {
1424
-                $caps[] = $this->private_cap;
1425
-            }
1426
-        } else {
1427
-            if ($is_global) {
1428
-                $caps[] = $this->private_cap;
1429
-            } else {
1430
-                $caps[] = $this->others_cap;
1431
-            }
1432
-        }
1433
-        return $caps;
1434
-    }
1385
+	/**
1386
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1387
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1388
+	 *
1389
+	 * @since 4.5.0
1390
+	 * @see   wp-includes/capabilities.php
1391
+	 *
1392
+	 * @param array  $caps    actual users capabilities
1393
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1394
+	 * @param int    $user_id The user id
1395
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1396
+	 *
1397
+	 * @return array   actual users capabilities
1398
+	 */
1399
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1400
+	{
1401
+		//only process if we're checking our mapped_cap
1402
+		if ($cap !== $this->meta_cap) {
1403
+			return $caps;
1404
+		}
1405
+
1406
+		//okay it is a meta cap so let's first remove that cap from the $caps array.
1407
+		if (($key = array_search($cap, $caps)) !== false) {
1408
+			unset($caps[$key]);
1409
+		}
1410
+
1411
+		//cast $user_id to int for later explicit comparisons
1412
+		$user_id = (int) $user_id;
1413
+
1414
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1415
+		//if no obj then let's just do cap
1416
+		if (! $obj instanceof EE_Message_Template_Group) {
1417
+			$caps[] = 'do_not_allow';
1418
+			return $caps;
1419
+		}
1420
+		$caps[] = $cap . 's';
1421
+		$is_global = $obj->is_global();
1422
+		if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1423
+			if ($is_global) {
1424
+				$caps[] = $this->private_cap;
1425
+			}
1426
+		} else {
1427
+			if ($is_global) {
1428
+				$caps[] = $this->private_cap;
1429
+			} else {
1430
+				$caps[] = $this->others_cap;
1431
+			}
1432
+		}
1433
+		return $caps;
1434
+	}
1435 1435
 }
1436 1436
 
1437 1437
 
@@ -1448,40 +1448,40 @@  discard block
 block discarded – undo
1448 1448
 class EE_Meta_Capability_Map_Registration_Form_Cap extends EE_Meta_Capability_Map
1449 1449
 {
1450 1450
 
1451
-    /**
1452
-     * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1453
-     * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1454
-     *
1455
-     * @since 4.5.0
1456
-     * @see   wp-includes/capabilities.php
1457
-     * @param array  $caps    actual users capabilities
1458
-     * @param string $cap     initial capability name that is being checked (the "map" key)
1459
-     * @param int    $user_id The user id
1460
-     * @param array  $args    Adds context to the cap. Typically the object ID.
1461
-     * @return array   actual users capabilities
1462
-     */
1463
-    protected function _map_meta_caps($caps, $cap, $user_id, $args)
1464
-    {
1465
-        //only process if we're checking our mapped_cap
1466
-        if ($cap !== $this->meta_cap) {
1467
-            return $caps;
1468
-        }
1469
-        //okay it is a meta cap so let's first remove that cap from the $caps array.
1470
-        if (($key = array_search($cap, $caps)) !== false) {
1471
-            unset($caps[$key]);
1472
-        }
1473
-        $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1474
-        //if no obj then let's just do cap
1475
-        if (! $obj instanceof EE_Base_Class) {
1476
-            $caps[] = 'do_not_allow';
1477
-            return $caps;
1478
-        }
1479
-        $caps[]    = $cap . 's';
1480
-        $is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1481
-        $is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1482
-        if ($is_system) {
1483
-            $caps[] = $this->private_cap;
1484
-        }
1485
-        return $caps;
1486
-    }
1451
+	/**
1452
+	 * This is the callback for the wp map_meta_caps() function which allows for ensuring certain caps that act as a
1453
+	 * "meta" for other caps ( i.e. ee_edit_event is a meta for ee_edit_others_events ) work as expected.
1454
+	 *
1455
+	 * @since 4.5.0
1456
+	 * @see   wp-includes/capabilities.php
1457
+	 * @param array  $caps    actual users capabilities
1458
+	 * @param string $cap     initial capability name that is being checked (the "map" key)
1459
+	 * @param int    $user_id The user id
1460
+	 * @param array  $args    Adds context to the cap. Typically the object ID.
1461
+	 * @return array   actual users capabilities
1462
+	 */
1463
+	protected function _map_meta_caps($caps, $cap, $user_id, $args)
1464
+	{
1465
+		//only process if we're checking our mapped_cap
1466
+		if ($cap !== $this->meta_cap) {
1467
+			return $caps;
1468
+		}
1469
+		//okay it is a meta cap so let's first remove that cap from the $caps array.
1470
+		if (($key = array_search($cap, $caps)) !== false) {
1471
+			unset($caps[$key]);
1472
+		}
1473
+		$obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1474
+		//if no obj then let's just do cap
1475
+		if (! $obj instanceof EE_Base_Class) {
1476
+			$caps[] = 'do_not_allow';
1477
+			return $caps;
1478
+		}
1479
+		$caps[]    = $cap . 's';
1480
+		$is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1481
+		$is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1482
+		if ($is_system) {
1483
+			$caps[] = $this->private_cap;
1484
+		}
1485
+		return $caps;
1486
+	}
1487 1487
 }
Please login to merge, or discard this patch.
Spacing   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -85,7 +85,7 @@  discard block
 block discarded – undo
85 85
     public static function instance()
86 86
     {
87 87
         //check if instantiated, and if not do so.
88
-        if (! self::$_instance instanceof EE_Capabilities) {
88
+        if ( ! self::$_instance instanceof EE_Capabilities) {
89 89
             self::$_instance = new self();
90 90
         }
91 91
         return self::$_instance;
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
      */
118 118
     public function init_caps($reset = false)
119 119
     {
120
-        if(! EE_Maintenance_Mode::instance()->models_can_query()){
120
+        if ( ! EE_Maintenance_Mode::instance()->models_can_query()) {
121 121
             return false;
122 122
         }
123 123
         $this->reset = filter_var($reset, FILTER_VALIDATE_BOOLEAN);
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
             $this->_get_default_meta_caps_array()
164 164
         );
165 165
         //add filter for map_meta_caps but only if models can query.
166
-        if (! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
166
+        if ( ! has_filter('map_meta_cap', array($this, 'map_meta_caps'))) {
167 167
             add_filter('map_meta_cap', array($this, 'map_meta_caps'), 10, 4);
168 168
         }
169 169
     }
@@ -324,11 +324,11 @@  discard block
 block discarded – undo
324 324
         if (did_action('AHEE__EE_System__load_espresso_addons__complete')) {
325 325
             //loop through our _meta_caps array
326 326
             foreach ($this->_meta_caps as $meta_map) {
327
-                if (! $meta_map instanceof EE_Meta_Capability_Map) {
327
+                if ( ! $meta_map instanceof EE_Meta_Capability_Map) {
328 328
                     continue;
329 329
                 }
330 330
                 // don't load models if there is no object ID in the args
331
-                if (! empty($args[0])) {
331
+                if ( ! empty($args[0])) {
332 332
                     $meta_map->ensure_is_model();
333 333
                 }
334 334
                 $caps = $meta_map->map_meta_caps($caps, $cap, $user_id, $args);
@@ -630,7 +630,7 @@  discard block
 block discarded – undo
630 630
     private function setupCapabilitiesMap()
631 631
     {
632 632
         // if the initialization process hasn't even started, then we need to call init_caps()
633
-        if($this->initialized === null) {
633
+        if ($this->initialized === null) {
634 634
             return $this->init_caps();
635 635
         }
636 636
         // unless resetting, get caps from db if we haven't already
@@ -666,7 +666,7 @@  discard block
 block discarded – undo
666 666
     public function addCaps(array $capabilities_to_add)
667 667
     {
668 668
         // don't do anything if the capabilities map can not be initialized
669
-        if (! $this->setupCapabilitiesMap()) {
669
+        if ( ! $this->setupCapabilitiesMap()) {
670 670
             return false;
671 671
         }
672 672
         // and filter the array so others can get in on the fun during resets
@@ -708,7 +708,7 @@  discard block
 block discarded – undo
708 708
     public function removeCaps($caps_map)
709 709
     {
710 710
         // don't do anything if the capabilities map can not be initialized
711
-        if (! $this->setupCapabilitiesMap()) {
711
+        if ( ! $this->setupCapabilitiesMap()) {
712 712
             return false;
713 713
         }
714 714
         $update_capabilities_map = false;
@@ -750,7 +750,7 @@  discard block
 block discarded – undo
750 750
         $orig_role = $role;
751 751
         $role = $role instanceof WP_Role ? $role : get_role($role);
752 752
         //if the role isn't available then we create it.
753
-        if (! $role instanceof WP_Role) {
753
+        if ( ! $role instanceof WP_Role) {
754 754
             // if a plugin wants to create a specific role name then they should create the role before
755 755
             // EE_Capabilities does.  Otherwise this function will create the role name from the slug:
756 756
             // - removes any `ee_` namespacing from the start of the slug.
@@ -761,12 +761,12 @@  discard block
 block discarded – undo
761 761
         }
762 762
         if ($role instanceof WP_Role) {
763 763
             // don't do anything if the capabilities map can not be initialized
764
-            if (! $this->setupCapabilitiesMap()) {
764
+            if ( ! $this->setupCapabilitiesMap()) {
765 765
                 return false;
766 766
             }
767
-            if (! $this->capHasBeenAddedToRole($role->name, $cap)) {
767
+            if ( ! $this->capHasBeenAddedToRole($role->name, $cap)) {
768 768
                 $role->add_cap($cap, $grant);
769
-                $this->capabilities_map[ $role->name ][] = $cap;
769
+                $this->capabilities_map[$role->name][] = $cap;
770 770
                 $this->updateCapabilitiesMap($update_capabilities_map);
771 771
                 return true;
772 772
             }
@@ -791,13 +791,13 @@  discard block
 block discarded – undo
791 791
     public function remove_cap_from_role($role, $cap, $update_capabilities_map = true)
792 792
     {
793 793
         // don't do anything if the capabilities map can not be initialized
794
-        if (! $this->setupCapabilitiesMap()) {
794
+        if ( ! $this->setupCapabilitiesMap()) {
795 795
             return false;
796 796
         }
797
-        $role = $role instanceof WP_Role ? $role :get_role($role);
797
+        $role = $role instanceof WP_Role ? $role : get_role($role);
798 798
         if ($index = $this->capHasBeenAddedToRole($role->name, $cap, true)) {
799 799
             $role->remove_cap($cap);
800
-            unset($this->capabilities_map[ $role->name ][ $index ]);
800
+            unset($this->capabilities_map[$role->name][$index]);
801 801
             $this->updateCapabilitiesMap($update_capabilities_map);
802 802
             return true;
803 803
         }
@@ -812,7 +812,7 @@  discard block
 block discarded – undo
812 812
      * @param bool   $get_index
813 813
      * @return bool|mixed
814 814
      */
815
-    private function capHasBeenAddedToRole($role_name='', $cap='', $get_index = false)
815
+    private function capHasBeenAddedToRole($role_name = '', $cap = '', $get_index = false)
816 816
     {
817 817
         if (
818 818
             isset($this->capabilities_map[$role_name])
@@ -844,7 +844,7 @@  discard block
 block discarded – undo
844 844
     public function current_user_can($cap, $context, $id = 0)
845 845
     {
846 846
         //apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
847
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__' . $context, $cap, $id);
847
+        $filtered_cap = apply_filters('FHEE__EE_Capabilities__current_user_can__cap__'.$context, $cap, $id);
848 848
         $filtered_cap = apply_filters(
849 849
             'FHEE__EE_Capabilities__current_user_can__cap',
850 850
             $filtered_cap,
@@ -873,7 +873,7 @@  discard block
 block discarded – undo
873 873
     public function user_can($user, $cap, $context, $id = 0)
874 874
     {
875 875
         //apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
876
-        $filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__' . $context, $cap, $user, $id);
876
+        $filtered_cap = apply_filters('FHEE__EE_Capabilities__user_can__cap__'.$context, $cap, $user, $id);
877 877
         $filtered_cap = apply_filters(
878 878
             'FHEE__EE_Capabilities__user_can__cap',
879 879
             $filtered_cap,
@@ -913,7 +913,7 @@  discard block
 block discarded – undo
913 913
             : current_user_can($blog_id, $cap);
914 914
         //apply filters (both a global on just the cap, and context specific.  Global overrides context specific)
915 915
         $user_can = apply_filters(
916
-            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__' . $context,
916
+            'FHEE__EE_Capabilities__current_user_can_for_blog__user_can__'.$context,
917 917
             $user_can,
918 918
             $blog_id,
919 919
             $cap,
@@ -943,14 +943,14 @@  discard block
 block discarded – undo
943 943
      */
944 944
     public function get_ee_capabilities($role = 'administrator')
945 945
     {
946
-        if (! $this->initialized) {
946
+        if ( ! $this->initialized) {
947 947
             $this->init_caps();
948 948
         }
949 949
         if (empty($role)) {
950 950
             return $this->capabilities_map;
951 951
         }
952
-        return isset($this->capabilities_map[ $role ])
953
-            ? $this->capabilities_map[ $role ]
952
+        return isset($this->capabilities_map[$role])
953
+            ? $this->capabilities_map[$role]
954 954
             : array();
955 955
     }
956 956
 
@@ -982,7 +982,7 @@  discard block
 block discarded – undo
982 982
                         'event_espresso'
983 983
                     ),
984 984
                     '$reset',
985
-                    __METHOD__ . '()',
985
+                    __METHOD__.'()',
986 986
                     'EE_Capabilities::init_caps()',
987 987
                     'true'
988 988
                 ),
@@ -1060,16 +1060,16 @@  discard block
 block discarded – undo
1060 1060
                         'Incoming $map_values array should have a count of four values in it.  This is what was given: %s',
1061 1061
                         'event_espresso'
1062 1062
                     ),
1063
-                    '<br>' . print_r($map_values, true)
1063
+                    '<br>'.print_r($map_values, true)
1064 1064
                 )
1065 1065
             );
1066 1066
         }
1067 1067
         //set properties
1068 1068
         $this->_model = null;
1069 1069
         $this->_model_name = $map_values[0];
1070
-        $this->published_cap = (string)$map_values[1];
1071
-        $this->others_cap = (string)$map_values[2];
1072
-        $this->private_cap = (string)$map_values[3];
1070
+        $this->published_cap = (string) $map_values[1];
1071
+        $this->others_cap = (string) $map_values[2];
1072
+        $this->private_cap = (string) $map_values[3];
1073 1073
     }
1074 1074
 
1075 1075
     /**
@@ -1096,11 +1096,11 @@  discard block
 block discarded – undo
1096 1096
             return;
1097 1097
         }
1098 1098
         //ensure model name is string
1099
-        $this->_model_name = (string)$this->_model_name;
1099
+        $this->_model_name = (string) $this->_model_name;
1100 1100
         //error proof if the name has EEM in it
1101 1101
         $this->_model_name = str_replace('EEM', '', $this->_model_name);
1102 1102
         $this->_model = EE_Registry::instance()->load_model($this->_model_name);
1103
-        if (! $this->_model instanceof EEM_Base) {
1103
+        if ( ! $this->_model instanceof EEM_Base) {
1104 1104
             throw new EE_Error(
1105 1105
                 sprintf(
1106 1106
                     __(
@@ -1195,11 +1195,11 @@  discard block
 block discarded – undo
1195 1195
         /** @var EE_Base_Class $obj */
1196 1196
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1197 1197
         //if no obj then let's just do cap
1198
-        if (! $obj instanceof EE_Base_Class) {
1198
+        if ( ! $obj instanceof EE_Base_Class) {
1199 1199
             $caps[] = 'do_not_allow';
1200 1200
             return $caps;
1201 1201
         }
1202
-        $caps[] = $cap . 's';
1202
+        $caps[] = $cap.'s';
1203 1203
         if ($obj instanceof EE_CPT_Base) {
1204 1204
             //if the item author is set and the user is the author...
1205 1205
             if ($obj->wp_user() && $user_id === $obj->wp_user()) {
@@ -1209,12 +1209,12 @@  discard block
 block discarded – undo
1209 1209
                 }
1210 1210
             } else {
1211 1211
                 //the user is trying to edit someone else's obj
1212
-                if (! empty($this->others_cap)) {
1212
+                if ( ! empty($this->others_cap)) {
1213 1213
                     $caps[] = $this->others_cap;
1214 1214
                 }
1215
-                if (! empty($this->published_cap) && $obj->status() === 'publish') {
1215
+                if ( ! empty($this->published_cap) && $obj->status() === 'publish') {
1216 1216
                     $caps[] = $this->published_cap;
1217
-                } elseif (! empty($this->private_cap) && $obj->status() === 'private') {
1217
+                } elseif ( ! empty($this->private_cap) && $obj->status() === 'private') {
1218 1218
                     $caps[] = $this->private_cap;
1219 1219
                 }
1220 1220
             }
@@ -1230,8 +1230,8 @@  discard block
 block discarded – undo
1230 1230
                     EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1231 1231
                 }
1232 1232
             }
1233
-            if (! $has_cap) {
1234
-                if (! empty($this->others_cap)) {
1233
+            if ( ! $has_cap) {
1234
+                if ( ! empty($this->others_cap)) {
1235 1235
                     $caps[] = $this->others_cap;
1236 1236
                 }
1237 1237
             }
@@ -1318,12 +1318,12 @@  discard block
 block discarded – undo
1318 1318
 
1319 1319
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1320 1320
         //if no obj then let's just do cap
1321
-        if (! $obj instanceof EE_Base_Class) {
1321
+        if ( ! $obj instanceof EE_Base_Class) {
1322 1322
             $caps[] = 'do_not_allow';
1323 1323
             return $caps;
1324 1324
         }
1325 1325
 
1326
-        $caps[] = $cap . 's';
1326
+        $caps[] = $cap.'s';
1327 1327
         if ($obj instanceof EE_CPT_Base) {
1328 1328
             $status_obj = get_post_status_object($obj->status());
1329 1329
             if ($status_obj->public) {
@@ -1331,7 +1331,7 @@  discard block
 block discarded – undo
1331 1331
             }
1332 1332
             //if the item author is set and the user is not the author...
1333 1333
             if ($obj->wp_user() && $obj->wp_user() !== $user_id) {
1334
-                if (! empty($this->others_cap)) {
1334
+                if ( ! empty($this->others_cap)) {
1335 1335
                     $caps[] = $this->others_cap;
1336 1336
                 }
1337 1337
             }
@@ -1355,11 +1355,11 @@  discard block
 block discarded – undo
1355 1355
                     EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1356 1356
                 }
1357 1357
             }
1358
-            if (! $has_cap) {
1359
-                if (! empty($this->private_cap)) {
1358
+            if ( ! $has_cap) {
1359
+                if ( ! empty($this->private_cap)) {
1360 1360
                     $caps[] = $this->private_cap;
1361 1361
                 }
1362
-                if (! empty($this->others_cap)) {
1362
+                if ( ! empty($this->others_cap)) {
1363 1363
                     $caps[] = $this->others_cap;
1364 1364
                 }
1365 1365
             }
@@ -1413,11 +1413,11 @@  discard block
 block discarded – undo
1413 1413
 
1414 1414
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1415 1415
         //if no obj then let's just do cap
1416
-        if (! $obj instanceof EE_Message_Template_Group) {
1416
+        if ( ! $obj instanceof EE_Message_Template_Group) {
1417 1417
             $caps[] = 'do_not_allow';
1418 1418
             return $caps;
1419 1419
         }
1420
-        $caps[] = $cap . 's';
1420
+        $caps[] = $cap.'s';
1421 1421
         $is_global = $obj->is_global();
1422 1422
         if ($obj->wp_user() && $obj->wp_user() === $user_id) {
1423 1423
             if ($is_global) {
@@ -1472,11 +1472,11 @@  discard block
 block discarded – undo
1472 1472
         }
1473 1473
         $obj = ! empty($args[0]) ? $this->_model->get_one_by_ID($args[0]) : null;
1474 1474
         //if no obj then let's just do cap
1475
-        if (! $obj instanceof EE_Base_Class) {
1475
+        if ( ! $obj instanceof EE_Base_Class) {
1476 1476
             $caps[] = 'do_not_allow';
1477 1477
             return $caps;
1478 1478
         }
1479
-        $caps[]    = $cap . 's';
1479
+        $caps[]    = $cap.'s';
1480 1480
         $is_system = $obj instanceof EE_Question_Group ? $obj->system_group() : false;
1481 1481
         $is_system = $obj instanceof EE_Question ? $obj->is_system_question() : $is_system;
1482 1482
         if ($is_system) {
Please login to merge, or discard this patch.
admin/extend/registrations/Extend_EE_Registrations_List_Table.class.php 2 patches
Indentation   +97 added lines, -97 removed lines patch added patch discarded remove patch
@@ -11,104 +11,104 @@
 block discarded – undo
11 11
  */
12 12
 class Extend_EE_Registrations_List_Table extends EE_Registrations_List_Table
13 13
 {
14
-    /**
15
-     * REG_date
16
-     */
17
-    function column__REG_date(EE_Registration $item)
18
-    {
19
-        $date_linked = parent::column__REG_date($item);
20
-        $actions = array();
21
-        //Build row actions
22
-        $check_in_url        = EE_Admin_Page::add_query_args_and_nonce(array(
23
-            'action'   => 'event_registrations',
24
-            'event_id' => $item->event_ID(),
25
-        ), REG_ADMIN_URL);
26
-        $actions['check_in'] = EE_Registry::instance()->CAP->current_user_can(
27
-            'ee_read_registration',
28
-            'espresso_registrations_registration_checkins',
29
-            $item->ID()
30
-        )
31
-            && EE_Registry::instance()->CAP->current_user_can(
32
-                'ee_read_checkins',
33
-                'espresso_registrations_registration_checkins'
34
-            )
35
-            ? '<a href="' . $check_in_url . '"'
36
-              . ' title="' . esc_attr__(
37
-                  'The Check-In List allows you to easily toggle check-in status for this event',
38
-                  'event_espresso'
39
-              )
40
-              . '">' .  esc_html__('View Check-ins', 'event_espresso') . '</a>'
41
-            :  esc_html__('View Check-ins', 'event_espresso');
14
+	/**
15
+	 * REG_date
16
+	 */
17
+	function column__REG_date(EE_Registration $item)
18
+	{
19
+		$date_linked = parent::column__REG_date($item);
20
+		$actions = array();
21
+		//Build row actions
22
+		$check_in_url        = EE_Admin_Page::add_query_args_and_nonce(array(
23
+			'action'   => 'event_registrations',
24
+			'event_id' => $item->event_ID(),
25
+		), REG_ADMIN_URL);
26
+		$actions['check_in'] = EE_Registry::instance()->CAP->current_user_can(
27
+			'ee_read_registration',
28
+			'espresso_registrations_registration_checkins',
29
+			$item->ID()
30
+		)
31
+			&& EE_Registry::instance()->CAP->current_user_can(
32
+				'ee_read_checkins',
33
+				'espresso_registrations_registration_checkins'
34
+			)
35
+			? '<a href="' . $check_in_url . '"'
36
+			  . ' title="' . esc_attr__(
37
+				  'The Check-In List allows you to easily toggle check-in status for this event',
38
+				  'event_espresso'
39
+			  )
40
+			  . '">' .  esc_html__('View Check-ins', 'event_espresso') . '</a>'
41
+			:  esc_html__('View Check-ins', 'event_espresso');
42 42
 
43
-        return sprintf('%1$s %2$s', $date_linked, $this->row_actions($actions));
44
-    }
43
+		return sprintf('%1$s %2$s', $date_linked, $this->row_actions($actions));
44
+	}
45 45
 
46 46
 
47
-    /**
48
-     *        column_default
49
-     *
50
-     * @param \EE_Registration $item
51
-     * @return string
52
-     * @throws EE_Error
53
-     */
54
-    public function column_DTT_EVT_start(EE_Registration $item)
55
-    {
56
-        $remove_defaults = array('default_where_conditions' => 'none');
57
-        $ticket          = $item->ticket();
58
-        $datetimes       = $ticket instanceof EE_Ticket ? $ticket->datetimes($remove_defaults) : array();
59
-        $EVT_ID          = $item->event_ID();
60
-        $datetime_string = '';
61
-        foreach ($datetimes as $datetime) {
62
-            if (EE_Registry::instance()->CAP->current_user_can(
63
-                'ee_read_checkin',
64
-                'espresso_registrations_registration_checkins',
65
-                $item->ID()
66
-            )) {
67
-                // open "a" tag and "href"
68
-                $datetime_string .= '<a href="';
69
-                // checkin URL
70
-                $datetime_string .= EE_Admin_Page::add_query_args_and_nonce(
71
-                    array(
72
-                        'action'   => 'event_registrations',
73
-                        'event_id' => $EVT_ID,
74
-                        'DTT_ID'   => $datetime->ID(),
75
-                    ),
76
-                    REG_ADMIN_URL
77
-                );
78
-                // close "href"
79
-                $datetime_string .= '"';
80
-                // open "title" tag
81
-                $datetime_string .= ' title="';
82
-                // link title text
83
-                $datetime_string .= esc_attr__('View Checkins for this Event', 'event_espresso');
84
-                // close "title" tag and end of "a" tag opening
85
-                $datetime_string .= '">';
86
-                // link text
87
-                $datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
88
-                // close "a" tag
89
-                $datetime_string .= '</a>';
90
-            } else {
91
-                $datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
92
-            }
93
-            // add a "View Registrations" link that filters list by event AND datetime
94
-            $datetime_string .= $this->row_actions(
95
-                array(
96
-                    'event_datetime_filter' => '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
97
-                        array('event_id' => $EVT_ID, 'datetime_id' => $datetime->ID()),
98
-                        REG_ADMIN_URL
99
-                    )
100
-                                               . '" title="' . sprintf(
101
-                                                   esc_attr__(
102
-                                                       'Filter this list to only show registrations for this datetime %s',
103
-                                                       'event_espresso'
104
-                                                   ),
105
-                                                   $datetime->name()
106
-                                               ) . '">'
107
-                                               . esc_html__('View Registrations', 'event_espresso')
108
-                                               . '</a>',
109
-                )
110
-            );
111
-        }
112
-        return $datetime_string;
113
-    }
47
+	/**
48
+	 *        column_default
49
+	 *
50
+	 * @param \EE_Registration $item
51
+	 * @return string
52
+	 * @throws EE_Error
53
+	 */
54
+	public function column_DTT_EVT_start(EE_Registration $item)
55
+	{
56
+		$remove_defaults = array('default_where_conditions' => 'none');
57
+		$ticket          = $item->ticket();
58
+		$datetimes       = $ticket instanceof EE_Ticket ? $ticket->datetimes($remove_defaults) : array();
59
+		$EVT_ID          = $item->event_ID();
60
+		$datetime_string = '';
61
+		foreach ($datetimes as $datetime) {
62
+			if (EE_Registry::instance()->CAP->current_user_can(
63
+				'ee_read_checkin',
64
+				'espresso_registrations_registration_checkins',
65
+				$item->ID()
66
+			)) {
67
+				// open "a" tag and "href"
68
+				$datetime_string .= '<a href="';
69
+				// checkin URL
70
+				$datetime_string .= EE_Admin_Page::add_query_args_and_nonce(
71
+					array(
72
+						'action'   => 'event_registrations',
73
+						'event_id' => $EVT_ID,
74
+						'DTT_ID'   => $datetime->ID(),
75
+					),
76
+					REG_ADMIN_URL
77
+				);
78
+				// close "href"
79
+				$datetime_string .= '"';
80
+				// open "title" tag
81
+				$datetime_string .= ' title="';
82
+				// link title text
83
+				$datetime_string .= esc_attr__('View Checkins for this Event', 'event_espresso');
84
+				// close "title" tag and end of "a" tag opening
85
+				$datetime_string .= '">';
86
+				// link text
87
+				$datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
88
+				// close "a" tag
89
+				$datetime_string .= '</a>';
90
+			} else {
91
+				$datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
92
+			}
93
+			// add a "View Registrations" link that filters list by event AND datetime
94
+			$datetime_string .= $this->row_actions(
95
+				array(
96
+					'event_datetime_filter' => '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
97
+						array('event_id' => $EVT_ID, 'datetime_id' => $datetime->ID()),
98
+						REG_ADMIN_URL
99
+					)
100
+											   . '" title="' . sprintf(
101
+												   esc_attr__(
102
+													   'Filter this list to only show registrations for this datetime %s',
103
+													   'event_espresso'
104
+												   ),
105
+												   $datetime->name()
106
+											   ) . '">'
107
+											   . esc_html__('View Registrations', 'event_espresso')
108
+											   . '</a>',
109
+				)
110
+			);
111
+		}
112
+		return $datetime_string;
113
+	}
114 114
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
         $date_linked = parent::column__REG_date($item);
20 20
         $actions = array();
21 21
         //Build row actions
22
-        $check_in_url        = EE_Admin_Page::add_query_args_and_nonce(array(
22
+        $check_in_url = EE_Admin_Page::add_query_args_and_nonce(array(
23 23
             'action'   => 'event_registrations',
24 24
             'event_id' => $item->event_ID(),
25 25
         ), REG_ADMIN_URL);
@@ -32,12 +32,12 @@  discard block
 block discarded – undo
32 32
                 'ee_read_checkins',
33 33
                 'espresso_registrations_registration_checkins'
34 34
             )
35
-            ? '<a href="' . $check_in_url . '"'
36
-              . ' title="' . esc_attr__(
35
+            ? '<a href="'.$check_in_url.'"'
36
+              . ' title="'.esc_attr__(
37 37
                   'The Check-In List allows you to easily toggle check-in status for this event',
38 38
                   'event_espresso'
39 39
               )
40
-              . '">' .  esc_html__('View Check-ins', 'event_espresso') . '</a>'
40
+              . '">'.esc_html__('View Check-ins', 'event_espresso').'</a>'
41 41
             :  esc_html__('View Check-ins', 'event_espresso');
42 42
 
43 43
         return sprintf('%1$s %2$s', $date_linked, $this->row_actions($actions));
@@ -93,17 +93,17 @@  discard block
 block discarded – undo
93 93
             // add a "View Registrations" link that filters list by event AND datetime
94 94
             $datetime_string .= $this->row_actions(
95 95
                 array(
96
-                    'event_datetime_filter' => '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
96
+                    'event_datetime_filter' => '<a href="'.EE_Admin_Page::add_query_args_and_nonce(
97 97
                         array('event_id' => $EVT_ID, 'datetime_id' => $datetime->ID()),
98 98
                         REG_ADMIN_URL
99 99
                     )
100
-                                               . '" title="' . sprintf(
100
+                                               . '" title="'.sprintf(
101 101
                                                    esc_attr__(
102 102
                                                        'Filter this list to only show registrations for this datetime %s',
103 103
                                                        'event_espresso'
104 104
                                                    ),
105 105
                                                    $datetime->name()
106
-                                               ) . '">'
106
+                                               ).'">'
107 107
                                                . esc_html__('View Registrations', 'event_espresso')
108 108
                                                . '</a>',
109 109
                 )
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 2 patches
Spacing   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
         // when adding a new registration...
70 70
         if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
71 71
             EE_System::do_not_cache();
72
-            if (! isset($this->_req_data['processing_registration'])
72
+            if ( ! isset($this->_req_data['processing_registration'])
73 73
                  || absint($this->_req_data['processing_registration']) !== 1
74 74
             ) {
75 75
                 // and it's NOT the attendee information reg step
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
     public function _set_page_routes()
165 165
     {
166 166
         $this->_get_registration_status_array();
167
-        $reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
167
+        $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
168 168
             ? $this->_req_data['_REG_ID'] : 0;
169 169
         $reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
170 170
             ? $this->_req_data['reg_status_change_form']['REG_ID']
@@ -646,7 +646,7 @@  discard block
 block discarded – undo
646 646
         //style
647 647
         wp_register_style(
648 648
             'espresso_reg',
649
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
649
+            REG_ASSETS_URL.'espresso_registrations_admin.css',
650 650
             array('ee-admin-css'),
651 651
             EVENT_ESPRESSO_VERSION
652 652
         );
@@ -654,7 +654,7 @@  discard block
 block discarded – undo
654 654
         //script
655 655
         wp_register_script(
656 656
             'espresso_reg',
657
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
657
+            REG_ASSETS_URL.'espresso_registrations_admin.js',
658 658
             array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
659 659
             EVENT_ESPRESSO_VERSION,
660 660
             true
@@ -692,7 +692,7 @@  discard block
 block discarded – undo
692 692
         wp_deregister_style('espresso_reg');
693 693
         wp_register_style(
694 694
             'espresso_att',
695
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
695
+            REG_ASSETS_URL.'espresso_attendees_admin.css',
696 696
             array('ee-admin-css'),
697 697
             EVENT_ESPRESSO_VERSION
698 698
         );
@@ -704,7 +704,7 @@  discard block
 block discarded – undo
704 704
     {
705 705
         wp_register_script(
706 706
             'ee-spco-for-admin',
707
-            REG_ASSETS_URL . 'spco_for_admin.js',
707
+            REG_ASSETS_URL.'spco_for_admin.js',
708 708
             array('underscore', 'jquery'),
709 709
             EVENT_ESPRESSO_VERSION,
710 710
             true
@@ -837,7 +837,7 @@  discard block
 block discarded – undo
837 837
                     'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
838 838
                 ),
839 839
             );
840
-            $this->_views['trash']      = array(
840
+            $this->_views['trash'] = array(
841 841
                 'slug'        => 'trash',
842 842
                 'label'       => esc_html__('Trash', 'event_espresso'),
843 843
                 'count'       => 0,
@@ -926,7 +926,7 @@  discard block
 block discarded – undo
926 926
         }
927 927
         $sc_items = array(
928 928
             'approved_status'   => array(
929
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
929
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_approved,
930 930
                 'desc'  => EEH_Template::pretty_status(
931 931
                     EEM_Registration::status_id_approved,
932 932
                     false,
@@ -934,7 +934,7 @@  discard block
 block discarded – undo
934 934
                 ),
935 935
             ),
936 936
             'pending_status'    => array(
937
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
937
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_pending_payment,
938 938
                 'desc'  => EEH_Template::pretty_status(
939 939
                     EEM_Registration::status_id_pending_payment,
940 940
                     false,
@@ -942,7 +942,7 @@  discard block
 block discarded – undo
942 942
                 ),
943 943
             ),
944 944
             'wait_list'         => array(
945
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
945
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_wait_list,
946 946
                 'desc'  => EEH_Template::pretty_status(
947 947
                     EEM_Registration::status_id_wait_list,
948 948
                     false,
@@ -950,7 +950,7 @@  discard block
 block discarded – undo
950 950
                 ),
951 951
             ),
952 952
             'incomplete_status' => array(
953
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
953
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_incomplete,
954 954
                 'desc'  => EEH_Template::pretty_status(
955 955
                     EEM_Registration::status_id_incomplete,
956 956
                     false,
@@ -958,7 +958,7 @@  discard block
 block discarded – undo
958 958
                 ),
959 959
             ),
960 960
             'not_approved'      => array(
961
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
961
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_not_approved,
962 962
                 'desc'  => EEH_Template::pretty_status(
963 963
                     EEM_Registration::status_id_not_approved,
964 964
                     false,
@@ -966,7 +966,7 @@  discard block
 block discarded – undo
966 966
                 ),
967 967
             ),
968 968
             'declined_status'   => array(
969
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
969
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_declined,
970 970
                 'desc'  => EEH_Template::pretty_status(
971 971
                     EEM_Registration::status_id_declined,
972 972
                     false,
@@ -974,7 +974,7 @@  discard block
 block discarded – undo
974 974
                 ),
975 975
             ),
976 976
             'cancelled_status'  => array(
977
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
977
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_cancelled,
978 978
                 'desc'  => EEH_Template::pretty_status(
979 979
                     EEM_Registration::status_id_cancelled,
980 980
                     false,
@@ -1003,7 +1003,7 @@  discard block
 block discarded – undo
1003 1003
                 'espresso_registrations_new_registration',
1004 1004
                 $EVT_ID
1005 1005
             )) {
1006
-                $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1006
+                $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1007 1007
                     'new_registration',
1008 1008
                     'add-registrant',
1009 1009
                     array('event_id' => $EVT_ID),
@@ -1043,7 +1043,7 @@  discard block
 block discarded – undo
1043 1043
                 $this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1044 1044
                 $this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1045 1045
                 $this->_template_args['admin_page_header'] .= $datetime->name();
1046
-                $this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1046
+                $this->_template_args['admin_page_header'] .= ' ( '.$datetime->start_date().' )';
1047 1047
                 $this->_template_args['admin_page_header'] .= '</span></h3>';
1048 1048
             }
1049 1049
         }
@@ -1143,7 +1143,7 @@  discard block
 block discarded – undo
1143 1143
             'caps'                     => EEM_Registration::caps_read_admin,
1144 1144
             'default_where_conditions' => 'this_model_only',
1145 1145
         );
1146
-        if (! $count) {
1146
+        if ( ! $count) {
1147 1147
             $query_params = array_merge(
1148 1148
                 $query_params,
1149 1149
                 $this->_get_orderby_for_registrations_query(),
@@ -1164,7 +1164,7 @@  discard block
 block discarded – undo
1164 1164
     protected function _add_event_id_to_where_conditions(array $request)
1165 1165
     {
1166 1166
         $where = array();
1167
-        if (! empty($request['event_id'])) {
1167
+        if ( ! empty($request['event_id'])) {
1168 1168
             $where['EVT_ID'] = absint($request['event_id']);
1169 1169
         }
1170 1170
         return $where;
@@ -1180,7 +1180,7 @@  discard block
 block discarded – undo
1180 1180
     protected function _add_category_id_to_where_conditions(array $request)
1181 1181
     {
1182 1182
         $where = array();
1183
-        if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1183
+        if ( ! empty($request['EVT_CAT']) && (int) $request['EVT_CAT'] !== -1) {
1184 1184
             $where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1185 1185
         }
1186 1186
         return $where;
@@ -1196,10 +1196,10 @@  discard block
 block discarded – undo
1196 1196
     protected function _add_datetime_id_to_where_conditions(array $request)
1197 1197
     {
1198 1198
         $where = array();
1199
-        if (! empty($request['datetime_id'])) {
1199
+        if ( ! empty($request['datetime_id'])) {
1200 1200
             $where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1201 1201
         }
1202
-        if (! empty($request['DTT_ID'])) {
1202
+        if ( ! empty($request['DTT_ID'])) {
1203 1203
             $where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1204 1204
         }
1205 1205
         return $where;
@@ -1225,7 +1225,7 @@  discard block
 block discarded – undo
1225 1225
          * If not filtering by specified status, then we show all registrations excluding incomplete registrations
1226 1226
          * UNLESS viewing trashed registrations.
1227 1227
          */
1228
-        if (! empty($registration_status)) {
1228
+        if ( ! empty($registration_status)) {
1229 1229
             $where['STS_ID'] = $registration_status;
1230 1230
         } else {
1231 1231
             //make sure we exclude incomplete registrations, but only if not trashed.
@@ -1265,12 +1265,12 @@  discard block
 block discarded – undo
1265 1265
                 array(
1266 1266
                     EEM_Registration::instance()->convert_datetime_for_query(
1267 1267
                         'REG_date',
1268
-                        $now . ' 00:00:00',
1268
+                        $now.' 00:00:00',
1269 1269
                         'Y-m-d H:i:s'
1270 1270
                     ),
1271 1271
                     EEM_Registration::instance()->convert_datetime_for_query(
1272 1272
                         'REG_date',
1273
-                        $now . ' 23:59:59',
1273
+                        $now.' 23:59:59',
1274 1274
                         'Y-m-d H:i:s'
1275 1275
                     ),
1276 1276
                 ),
@@ -1283,12 +1283,12 @@  discard block
 block discarded – undo
1283 1283
                 array(
1284 1284
                     EEM_Registration::instance()->convert_datetime_for_query(
1285 1285
                         'REG_date',
1286
-                        $current_year_and_month . '-01 00:00:00',
1286
+                        $current_year_and_month.'-01 00:00:00',
1287 1287
                         'Y-m-d H:i:s'
1288 1288
                     ),
1289 1289
                     EEM_Registration::instance()->convert_datetime_for_query(
1290 1290
                         'REG_date',
1291
-                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1291
+                        $current_year_and_month.'-'.$days_this_month.' 23:59:59',
1292 1292
                         'Y-m-d H:i:s'
1293 1293
                     ),
1294 1294
                 ),
@@ -1303,18 +1303,18 @@  discard block
 block discarded – undo
1303 1303
                 : '';
1304 1304
             //if there is not a month or year then we can't go further
1305 1305
             if ($month_requested && $year_requested) {
1306
-                $days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1306
+                $days_in_month     = date('t', strtotime($year_requested.'-'.$month_requested.'-'.'01'));
1307 1307
                 $where['REG_date'] = array(
1308 1308
                     'BETWEEN',
1309 1309
                     array(
1310 1310
                         EEM_Registration::instance()->convert_datetime_for_query(
1311 1311
                             'REG_date',
1312
-                            $year_requested . '-' . $month_requested . '-01 00:00:00',
1312
+                            $year_requested.'-'.$month_requested.'-01 00:00:00',
1313 1313
                             'Y-m-d H:i:s'
1314 1314
                         ),
1315 1315
                         EEM_Registration::instance()->convert_datetime_for_query(
1316 1316
                             'REG_date',
1317
-                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1317
+                            $year_requested.'-'.$month_requested.'-'.$days_in_month.' 23:59:59',
1318 1318
                             'Y-m-d H:i:s'
1319 1319
                         ),
1320 1320
                     ),
@@ -1334,8 +1334,8 @@  discard block
 block discarded – undo
1334 1334
     protected function _add_search_to_where_conditions(array $request)
1335 1335
     {
1336 1336
         $where = array();
1337
-        if (! empty($request['s'])) {
1338
-            $search_string = '%' . sanitize_text_field($request['s']) . '%';
1337
+        if ( ! empty($request['s'])) {
1338
+            $search_string = '%'.sanitize_text_field($request['s']).'%';
1339 1339
             $where['OR*search_conditions'] = array(
1340 1340
                 'Event.EVT_name'                          => array('LIKE', $search_string),
1341 1341
                 'Event.EVT_desc'                          => array('LIKE', $search_string),
@@ -1448,7 +1448,7 @@  discard block
 block discarded – undo
1448 1448
             : $per_page;
1449 1449
 
1450 1450
         //-1 means return all results so get out if that's set.
1451
-        if ((int)$per_page === -1) {
1451
+        if ((int) $per_page === -1) {
1452 1452
             return array();
1453 1453
         }
1454 1454
         $per_page = absint($per_page);
@@ -1501,7 +1501,7 @@  discard block
 block discarded – undo
1501 1501
                 ),
1502 1502
                 REG_ADMIN_URL
1503 1503
             );
1504
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1504
+            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1505 1505
                 array(
1506 1506
                     'action' => 'default',
1507 1507
                     'EVT_ID' => $event_id,
@@ -1509,7 +1509,7 @@  discard block
 block discarded – undo
1509 1509
                 ),
1510 1510
                 admin_url('admin.php')
1511 1511
             );
1512
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1512
+            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1513 1513
                 array(
1514 1514
                     'page'   => 'espresso_events',
1515 1515
                     'action' => 'edit',
@@ -1518,12 +1518,12 @@  discard block
 block discarded – undo
1518 1518
                 admin_url('admin.php')
1519 1519
             );
1520 1520
             //next and previous links
1521
-            $next_reg                                      = $this->_registration->next(
1521
+            $next_reg = $this->_registration->next(
1522 1522
                 null,
1523 1523
                 array(),
1524 1524
                 'REG_ID'
1525 1525
             );
1526
-            $this->_template_args['next_registration']     = $next_reg
1526
+            $this->_template_args['next_registration'] = $next_reg
1527 1527
                 ? $this->_next_link(
1528 1528
                     EE_Admin_Page::add_query_args_and_nonce(
1529 1529
                         array(
@@ -1535,7 +1535,7 @@  discard block
 block discarded – undo
1535 1535
                     'dashicons dashicons-arrow-right ee-icon-size-22'
1536 1536
                 )
1537 1537
                 : '';
1538
-            $previous_reg                                  = $this->_registration->previous(
1538
+            $previous_reg = $this->_registration->previous(
1539 1539
                 null,
1540 1540
                 array(),
1541 1541
                 'REG_ID'
@@ -1553,7 +1553,7 @@  discard block
 block discarded – undo
1553 1553
                 )
1554 1554
                 : '';
1555 1555
             // grab header
1556
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1556
+            $template_path                             = REG_TEMPLATE_PATH.'reg_admin_details_header.template.php';
1557 1557
             $this->_template_args['REG_ID']            = $this->_registration->ID();
1558 1558
             $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1559 1559
                 $template_path,
@@ -1669,7 +1669,7 @@  discard block
 block discarded – undo
1669 1669
                             EEH_HTML::strong(
1670 1670
                                 $this->_registration->pretty_status(),
1671 1671
                                 '',
1672
-                                'status-' . $this->_registration->status_ID(),
1672
+                                'status-'.$this->_registration->status_ID(),
1673 1673
                                 'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1674 1674
                             )
1675 1675
                         )
@@ -1741,9 +1741,9 @@  discard block
 block discarded – undo
1741 1741
     {
1742 1742
         if (isset($this->_req_data['reg_status_change_form'])) {
1743 1743
             $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1744
-                ? (array)$this->_req_data['reg_status_change_form']['REG_ID'] : array();
1744
+                ? (array) $this->_req_data['reg_status_change_form']['REG_ID'] : array();
1745 1745
         } else {
1746
-            $REG_IDs = isset($this->_req_data['_REG_ID']) ? (array)$this->_req_data['_REG_ID'] : array();
1746
+            $REG_IDs = isset($this->_req_data['_REG_ID']) ? (array) $this->_req_data['_REG_ID'] : array();
1747 1747
         }
1748 1748
         $success = $this->_set_registration_status($REG_IDs, $status);
1749 1749
         //notify?
@@ -1778,7 +1778,7 @@  discard block
 block discarded – undo
1778 1778
     {
1779 1779
         $success = false;
1780 1780
         // typecast $REG_IDs
1781
-        $REG_IDs = (array)$REG_IDs;
1781
+        $REG_IDs = (array) $REG_IDs;
1782 1782
         if ( ! empty($REG_IDs)) {
1783 1783
             $success = true;
1784 1784
             // set default status if none is passed
@@ -1917,7 +1917,7 @@  discard block
 block discarded – undo
1917 1917
             $action,
1918 1918
             $notify
1919 1919
         );
1920
-        $method = $action . '_registration';
1920
+        $method = $action.'_registration';
1921 1921
         if (method_exists($this, $method)) {
1922 1922
             $this->$method($notify);
1923 1923
         }
@@ -2031,7 +2031,7 @@  discard block
 block discarded – undo
2031 2031
             $filtered_line_item_tree,
2032 2032
             array('EE_Registration' => $this->_registration)
2033 2033
         );
2034
-        $attendee                                = $this->_registration->attendee();
2034
+        $attendee = $this->_registration->attendee();
2035 2035
         if (EE_Registry::instance()->CAP->current_user_can(
2036 2036
             'ee_read_transaction',
2037 2037
             'espresso_transactions_view_transaction'
@@ -2110,7 +2110,7 @@  discard block
 block discarded – undo
2110 2110
                 'Payment method response',
2111 2111
                 'event_espresso'
2112 2112
             );
2113
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2113
+            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2114 2114
         }
2115 2115
         $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2116 2116
         $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
@@ -2138,7 +2138,7 @@  discard block
 block discarded – undo
2138 2138
         $this->_template_args['REG_ID']                                       = $this->_registration->ID();
2139 2139
         $this->_template_args['event_id']                                     = $this->_registration->event_ID();
2140 2140
         $template_path                                                        =
2141
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2141
+            REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_details.template.php';
2142 2142
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2143 2143
     }
2144 2144
 
@@ -2167,7 +2167,7 @@  discard block
 block discarded – undo
2167 2167
             $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2168 2168
             $this->_template_args['REG_ID']                    = $this->_registration->ID();
2169 2169
             $template_path                                     =
2170
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2170
+                REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
2171 2171
             echo EEH_Template::display_template($template_path, $this->_template_args, true);
2172 2172
         }
2173 2173
     }
@@ -2184,7 +2184,7 @@  discard block
 block discarded – undo
2184 2184
     public function form_before_question_group($output)
2185 2185
     {
2186 2186
         EE_Error::doing_it_wrong(
2187
-            __CLASS__ . '::' . __FUNCTION__,
2187
+            __CLASS__.'::'.__FUNCTION__,
2188 2188
             esc_html__(
2189 2189
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2190 2190
                 'event_espresso'
@@ -2209,7 +2209,7 @@  discard block
 block discarded – undo
2209 2209
     public function form_after_question_group($output)
2210 2210
     {
2211 2211
         EE_Error::doing_it_wrong(
2212
-            __CLASS__ . '::' . __FUNCTION__,
2212
+            __CLASS__.'::'.__FUNCTION__,
2213 2213
             esc_html__(
2214 2214
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2215 2215
                 'event_espresso'
@@ -2247,7 +2247,7 @@  discard block
 block discarded – undo
2247 2247
     public function form_form_field_label_wrap($label)
2248 2248
     {
2249 2249
         EE_Error::doing_it_wrong(
2250
-            __CLASS__ . '::' . __FUNCTION__,
2250
+            __CLASS__.'::'.__FUNCTION__,
2251 2251
             esc_html__(
2252 2252
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2253 2253
                 'event_espresso'
@@ -2257,7 +2257,7 @@  discard block
 block discarded – undo
2257 2257
         return '
2258 2258
 			<tr>
2259 2259
 				<th>
2260
-					' . $label . '
2260
+					' . $label.'
2261 2261
 				</th>';
2262 2262
     }
2263 2263
 
@@ -2273,7 +2273,7 @@  discard block
 block discarded – undo
2273 2273
     public function form_form_field_input__wrap($input)
2274 2274
     {
2275 2275
         EE_Error::doing_it_wrong(
2276
-            __CLASS__ . '::' . __FUNCTION__,
2276
+            __CLASS__.'::'.__FUNCTION__,
2277 2277
             esc_html__(
2278 2278
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2279 2279
                 'event_espresso'
@@ -2282,7 +2282,7 @@  discard block
 block discarded – undo
2282 2282
         );
2283 2283
         return '
2284 2284
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2285
-					' . $input . '
2285
+					' . $input.'
2286 2286
 				</td>
2287 2287
 			</tr>';
2288 2288
     }
@@ -2324,7 +2324,7 @@  discard block
 block discarded – undo
2324 2324
     protected function _get_reg_custom_questions_form($REG_ID)
2325 2325
     {
2326 2326
         if ( ! $this->_reg_custom_questions_form) {
2327
-            require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2327
+            require_once(REG_ADMIN.'form_sections'.DS.'EE_Registration_Custom_Questions_Form.form.php');
2328 2328
             $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2329 2329
                 EEM_Registration::instance()->get_one_by_ID($REG_ID)
2330 2330
             );
@@ -2357,7 +2357,7 @@  discard block
 block discarded – undo
2357 2357
         if ($form->is_valid()) {
2358 2358
             foreach ($form->subforms() as $question_group_id => $question_group_form) {
2359 2359
                 foreach ($question_group_form->inputs() as $question_id => $input) {
2360
-                    $where_conditions    = array(
2360
+                    $where_conditions = array(
2361 2361
                         'QST_ID' => $question_id,
2362 2362
                         'REG_ID' => $REG_ID,
2363 2363
                     );
@@ -2395,7 +2395,7 @@  discard block
 block discarded – undo
2395 2395
         $REG = EEM_Registration::instance();
2396 2396
         //get all other registrations on this transaction, and cache
2397 2397
         //the attendees for them so we don't have to run another query using force_join
2398
-        $registrations                           = $REG->get_all(array(
2398
+        $registrations = $REG->get_all(array(
2399 2399
             array(
2400 2400
                 'TXN_ID' => $this->_registration->transaction_ID(),
2401 2401
                 'REG_ID' => array('!=', $this->_registration->ID()),
@@ -2419,7 +2419,7 @@  discard block
 block discarded – undo
2419 2419
             $att_nmbr = 1;
2420 2420
             foreach ($registrations as $registration) {
2421 2421
                 /* @var $registration EE_Registration */
2422
-                $attendee                                                    = $registration->attendee()
2422
+                $attendee = $registration->attendee()
2423 2423
                     ? $registration->attendee()
2424 2424
                     : EEM_Attendee::instance()
2425 2425
                                   ->create_default_object();
@@ -2432,19 +2432,19 @@  discard block
 block discarded – undo
2432 2432
                     ', ',
2433 2433
                     $attendee->full_address_as_array()
2434 2434
                 );
2435
-                $this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2435
+                $this->_template_args['attendees'][$att_nmbr]['att_link'] = self::add_query_args_and_nonce(
2436 2436
                     array(
2437 2437
                         'action' => 'edit_attendee',
2438 2438
                         'post'   => $attendee->ID(),
2439 2439
                     ),
2440 2440
                     REG_ADMIN_URL
2441 2441
                 );
2442
-                $this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2442
+                $this->_template_args['attendees'][$att_nmbr]['event_name'] = $registration->event_obj()->name();
2443 2443
                 $att_nmbr++;
2444 2444
             }
2445 2445
             $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2446 2446
         }
2447
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2447
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_attendees.template.php';
2448 2448
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2449 2449
     }
2450 2450
 
@@ -2484,20 +2484,20 @@  discard block
 block discarded – undo
2484 2484
         $this->_template_args['phone']             = $attendee->phone();
2485 2485
         $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2486 2486
         //edit link
2487
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2487
+        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(array(
2488 2488
             'action' => 'edit_attendee',
2489 2489
             'post'   => $attendee->ID(),
2490 2490
         ), REG_ADMIN_URL);
2491 2491
         $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2492 2492
         //create link
2493
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2493
+        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2494 2494
             ? EE_Admin_Page::add_query_args_and_nonce(array(
2495 2495
                 'action'  => 'duplicate_attendee',
2496 2496
                 '_REG_ID' => $this->_registration->ID(),
2497 2497
             ), REG_ADMIN_URL) : '';
2498 2498
         $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2499 2499
         $this->_template_args['att_check']    = $att_check;
2500
-        $template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2500
+        $template_path                        = REG_TEMPLATE_PATH.'reg_admin_details_side_meta_box_registrant.template.php';
2501 2501
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2502 2502
     }
2503 2503
 
@@ -2539,7 +2539,7 @@  discard block
 block discarded – undo
2539 2539
             /** @var EE_Registration $REG */
2540 2540
             $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2541 2541
             $payments = $REG->registration_payments();
2542
-            if (! empty($payments)) {
2542
+            if ( ! empty($payments)) {
2543 2543
                 $name = $REG->attendee() instanceof EE_Attendee
2544 2544
                     ? $REG->attendee()->full_name()
2545 2545
                     : esc_html__('Unknown Attendee', 'event_espresso');
@@ -2732,7 +2732,7 @@  discard block
 block discarded – undo
2732 2732
                 'action' => 'edit',
2733 2733
                 'post'   => $this->_reg_event->ID(),
2734 2734
             ), EVENTS_ADMIN_URL);
2735
-            $edit_event_lnk                     = '<a href="'
2735
+            $edit_event_lnk = '<a href="'
2736 2736
                                                   . $edit_event_url
2737 2737
                                                   . '" title="'
2738 2738
                                                   . esc_attr__('Edit ', 'event_espresso')
@@ -2750,7 +2750,7 @@  discard block
 block discarded – undo
2750 2750
         }
2751 2751
         // grab header
2752 2752
         $template_path                              =
2753
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2753
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee.template.php';
2754 2754
         $this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2755 2755
             $this->_template_args, true);
2756 2756
         //$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
@@ -2785,7 +2785,7 @@  discard block
 block discarded – undo
2785 2785
                 '</b>'
2786 2786
             );
2787 2787
             return '
2788
-	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2788
+	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg.'</p></div>
2789 2789
 	<script >
2790 2790
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2791 2791
 		// after just adding a new registration... we gotta try to put a stop to that !!!
@@ -2853,7 +2853,7 @@  discard block
 block discarded – undo
2853 2853
         //we come back to the process_registration_step route.
2854 2854
         $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2855 2855
         return EEH_Template::display_template(
2856
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2856
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee_step_content.template.php',
2857 2857
             $template_args,
2858 2858
             true
2859 2859
         );
@@ -2872,7 +2872,7 @@  discard block
 block discarded – undo
2872 2872
         if (is_object($this->_reg_event)) {
2873 2873
             return true;
2874 2874
         }
2875
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2875
+        $EVT_ID = ( ! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2876 2876
         if ( ! $EVT_ID) {
2877 2877
             return false;
2878 2878
         }
@@ -2938,7 +2938,7 @@  discard block
 block discarded – undo
2938 2938
                 }
2939 2939
                 break;
2940 2940
             case 'questions' :
2941
-                if (! isset(
2941
+                if ( ! isset(
2942 2942
                     $this->_req_data['txn_reg_status_change'],
2943 2943
                     $this->_req_data['txn_reg_status_change']['send_notifications'])
2944 2944
                 ) {
@@ -3052,7 +3052,7 @@  discard block
 block discarded – undo
3052 3052
     public function get_attendees($per_page, $count = false, $trash = false)
3053 3053
     {
3054 3054
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3055
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3055
+        require_once(REG_ADMIN.'EE_Attendee_Contact_List_Table.class.php');
3056 3056
         $ATT_MDL                    = EEM_Attendee::instance();
3057 3057
         $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3058 3058
         switch ($this->_req_data['orderby']) {
@@ -3089,7 +3089,7 @@  discard block
 block discarded – undo
3089 3089
             : $per_page;
3090 3090
         $_where       = array();
3091 3091
         if ( ! empty($this->_req_data['s'])) {
3092
-            $sstr         = '%' . $this->_req_data['s'] . '%';
3092
+            $sstr         = '%'.$this->_req_data['s'].'%';
3093 3093
             $_where['OR'] = array(
3094 3094
                 'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3095 3095
                 'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
@@ -3165,9 +3165,9 @@  discard block
 block discarded – undo
3165 3165
      *                                                     the query parameters from the request
3166 3166
      * @return void ends the request with a redirect or download
3167 3167
      */
3168
-    public function _registrations_report_base( $method_name_for_getting_query_params )
3168
+    public function _registrations_report_base($method_name_for_getting_query_params)
3169 3169
     {
3170
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3170
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3171 3171
             wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3172 3172
                 array(
3173 3173
                     'page'        => 'espresso_batch',
@@ -3176,7 +3176,7 @@  discard block
 block discarded – undo
3176 3176
                     'filters'     => urlencode(
3177 3177
                         serialize(
3178 3178
                             call_user_func(
3179
-                                array( $this, $method_name_for_getting_query_params ),
3179
+                                array($this, $method_name_for_getting_query_params),
3180 3180
                                 EEH_Array::is_set(
3181 3181
                                     $this->_req_data,
3182 3182
                                     'filters',
@@ -3196,8 +3196,8 @@  discard block
 block discarded – undo
3196 3196
                 'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3197 3197
             );
3198 3198
             $this->_req_data = array_merge($this->_req_data, $new_request_args);
3199
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3200
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3199
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3200
+                require_once(EE_CLASSES.'EE_Export.class.php');
3201 3201
                 $EE_Export = EE_Export::instance($this->_req_data);
3202 3202
                 $EE_Export->export();
3203 3203
             }
@@ -3218,8 +3218,8 @@  discard block
 block discarded – undo
3218 3218
 
3219 3219
     public function _contact_list_export()
3220 3220
     {
3221
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3222
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3221
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3222
+            require_once(EE_CLASSES.'EE_Export.class.php');
3223 3223
             $EE_Export = EE_Export::instance($this->_req_data);
3224 3224
             $EE_Export->export_attendees();
3225 3225
         }
@@ -3236,8 +3236,8 @@  discard block
 block discarded – undo
3236 3236
                 'return_url'  => urlencode($this->_req_data['return_url']),
3237 3237
             )));
3238 3238
         } else {
3239
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3240
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3239
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3240
+                require_once(EE_CLASSES.'EE_Export.class.php');
3241 3241
                 $EE_Export = EE_Export::instance($this->_req_data);
3242 3242
                 $EE_Export->report_attendees();
3243 3243
             }
@@ -3303,7 +3303,7 @@  discard block
 block discarded – undo
3303 3303
             $updated_fields = array(
3304 3304
                 'ATT_fname'     => $this->_req_data['ATT_fname'],
3305 3305
                 'ATT_lname'     => $this->_req_data['ATT_lname'],
3306
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3306
+                'ATT_full_name' => $this->_req_data['ATT_fname'].' '.$this->_req_data['ATT_lname'],
3307 3307
                 'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3308 3308
                 'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3309 3309
                 'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
@@ -3436,7 +3436,7 @@  discard block
 block discarded – undo
3436 3436
     {
3437 3437
         //get attendee object ( should already have it )
3438 3438
         $this->_template_args['attendee'] = $this->_cpt_model_obj;
3439
-        $template                         = REG_TEMPLATE_PATH . 'attendee_contact_info_metabox_content.template.php';
3439
+        $template                         = REG_TEMPLATE_PATH.'attendee_contact_info_metabox_content.template.php';
3440 3440
         EEH_Template::display_template($template, $this->_template_args);
3441 3441
     }
3442 3442
 
@@ -3498,8 +3498,8 @@  discard block
 block discarded – undo
3498 3498
                 )
3499 3499
             )
3500 3500
         );
3501
-        $template                             =
3502
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3501
+        $template =
3502
+            REG_TEMPLATE_PATH.'attendee_address_details_metabox_content.template.php';
3503 3503
         EEH_Template::display_template($template, $this->_template_args);
3504 3504
     }
3505 3505
 
@@ -3518,7 +3518,7 @@  discard block
 block discarded – undo
3518 3518
         $this->_template_args['attendee']      = $this->_cpt_model_obj;
3519 3519
         $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3520 3520
         $template                              =
3521
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3521
+            REG_TEMPLATE_PATH.'attendee_registrations_main_meta_box.template.php';
3522 3522
         EEH_Template::display_template($template, $this->_template_args);
3523 3523
     }
3524 3524
 
@@ -3533,7 +3533,7 @@  discard block
 block discarded – undo
3533 3533
     public function after_title_form_fields($post)
3534 3534
     {
3535 3535
         if ($post->post_type == 'espresso_attendees') {
3536
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3536
+            $template                  = REG_TEMPLATE_PATH.'attendee_details_after_title_form_fields.template.php';
3537 3537
             $template_args['attendee'] = $this->_cpt_model_obj;
3538 3538
             EEH_Template::display_template($template, $template_args);
3539 3539
         }
Please login to merge, or discard this patch.
Indentation   +3531 added lines, -3531 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -23,2217 +23,2217 @@  discard block
 block discarded – undo
23 23
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
24 24
 {
25 25
 
26
-    /**
27
-     * @var EE_Registration
28
-     */
29
-    private $_registration;
30
-
31
-    /**
32
-     * @var EE_Event
33
-     */
34
-    private $_reg_event;
35
-
36
-    /**
37
-     * @var EE_Session
38
-     */
39
-    private $_session;
40
-
41
-    private static $_reg_status;
42
-
43
-    /**
44
-     * Form for displaying the custom questions for this registration.
45
-     * This gets used a few times throughout the request so its best to cache it
46
-     *
47
-     * @var EE_Registration_Custom_Questions_Form
48
-     */
49
-    protected $_reg_custom_questions_form = null;
50
-
51
-
52
-    /**
53
-     *        constructor
54
-     *
55
-     * @Constructor
56
-     * @access public
57
-     * @param bool $routing
58
-     * @return Registrations_Admin_Page
59
-     */
60
-    public function __construct($routing = true)
61
-    {
62
-        parent::__construct($routing);
63
-        add_action('wp_loaded', array($this, 'wp_loaded'));
64
-    }
65
-
66
-
67
-    public function wp_loaded()
68
-    {
69
-        // when adding a new registration...
70
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
71
-            EE_System::do_not_cache();
72
-            if (! isset($this->_req_data['processing_registration'])
73
-                 || absint($this->_req_data['processing_registration']) !== 1
74
-            ) {
75
-                // and it's NOT the attendee information reg step
76
-                // force cookie expiration by setting time to last week
77
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
78
-                // and update the global
79
-                $_COOKIE['ee_registration_added'] = 0;
80
-            }
81
-        }
82
-    }
83
-
84
-
85
-    protected function _init_page_props()
86
-    {
87
-        $this->page_slug        = REG_PG_SLUG;
88
-        $this->_admin_base_url  = REG_ADMIN_URL;
89
-        $this->_admin_base_path = REG_ADMIN;
90
-        $this->page_label       = esc_html__('Registrations', 'event_espresso');
91
-        $this->_cpt_routes      = array(
92
-            'add_new_attendee' => 'espresso_attendees',
93
-            'edit_attendee'    => 'espresso_attendees',
94
-            'insert_attendee'  => 'espresso_attendees',
95
-            'update_attendee'  => 'espresso_attendees',
96
-        );
97
-        $this->_cpt_model_names = array(
98
-            'add_new_attendee' => 'EEM_Attendee',
99
-            'edit_attendee'    => 'EEM_Attendee',
100
-        );
101
-        $this->_cpt_edit_routes = array(
102
-            'espresso_attendees' => 'edit_attendee',
103
-        );
104
-        $this->_pagenow_map     = array(
105
-            'add_new_attendee' => 'post-new.php',
106
-            'edit_attendee'    => 'post.php',
107
-            'trash'            => 'post.php',
108
-        );
109
-        add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
110
-        //add filters so that the comment urls don't take users to a confusing 404 page
111
-        add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
112
-    }
113
-
114
-
115
-    public function clear_comment_link($link, $comment, $args)
116
-    {
117
-        //gotta make sure this only happens on this route
118
-        $post_type = get_post_type($comment->comment_post_ID);
119
-        if ($post_type === 'espresso_attendees') {
120
-            return '#commentsdiv';
121
-        }
122
-        return $link;
123
-    }
124
-
125
-
126
-    protected function _ajax_hooks()
127
-    {
128
-        //todo: all hooks for registrations ajax goes in here
129
-        add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
130
-    }
131
-
132
-
133
-    protected function _define_page_props()
134
-    {
135
-        $this->_admin_page_title = $this->page_label;
136
-        $this->_labels           = array(
137
-            'buttons'                      => array(
138
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
139
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
140
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
141
-                'report'              => esc_html__("Event Registrations CSV Report", "event_espresso"),
142
-                'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
143
-                'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
144
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
145
-                'contact_list_export' => esc_html__("Export Data", "event_espresso"),
146
-            ),
147
-            'publishbox'                   => array(
148
-                'add_new_attendee' => esc_html__("Add Contact Record", 'event_espresso'),
149
-                'edit_attendee'    => esc_html__("Update Contact Record", 'event_espresso'),
150
-            ),
151
-            'hide_add_button_on_cpt_route' => array(
152
-                'edit_attendee' => true,
153
-            ),
154
-        );
155
-    }
156
-
157
-
158
-    /**
159
-     *        grab url requests and route them
160
-     *
161
-     * @access private
162
-     * @return void
163
-     */
164
-    public function _set_page_routes()
165
-    {
166
-        $this->_get_registration_status_array();
167
-        $reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
168
-            ? $this->_req_data['_REG_ID'] : 0;
169
-        $reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
170
-            ? $this->_req_data['reg_status_change_form']['REG_ID']
171
-            : $reg_id;
172
-        $att_id             = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
173
-            ? $this->_req_data['ATT_ID'] : 0;
174
-        $att_id             = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
175
-            ? $this->_req_data['post']
176
-            : $att_id;
177
-        $this->_page_routes = array(
178
-            'default'                            => array(
179
-                'func'       => '_registrations_overview_list_table',
180
-                'capability' => 'ee_read_registrations',
181
-            ),
182
-            'view_registration'                  => array(
183
-                'func'       => '_registration_details',
184
-                'capability' => 'ee_read_registration',
185
-                'obj_id'     => $reg_id,
186
-            ),
187
-            'edit_registration'                  => array(
188
-                'func'               => '_update_attendee_registration_form',
189
-                'noheader'           => true,
190
-                'headers_sent_route' => 'view_registration',
191
-                'capability'         => 'ee_edit_registration',
192
-                'obj_id'             => $reg_id,
193
-                '_REG_ID'            => $reg_id,
194
-            ),
195
-            'trash_registrations'                => array(
196
-                'func'       => '_trash_or_restore_registrations',
197
-                'args'       => array('trash' => true),
198
-                'noheader'   => true,
199
-                'capability' => 'ee_delete_registrations',
200
-            ),
201
-            'restore_registrations'              => array(
202
-                'func'       => '_trash_or_restore_registrations',
203
-                'args'       => array('trash' => false),
204
-                'noheader'   => true,
205
-                'capability' => 'ee_delete_registrations',
206
-            ),
207
-            'delete_registrations'               => array(
208
-                'func'       => '_delete_registrations',
209
-                'noheader'   => true,
210
-                'capability' => 'ee_delete_registrations',
211
-            ),
212
-            'new_registration'                   => array(
213
-                'func'       => 'new_registration',
214
-                'capability' => 'ee_edit_registrations',
215
-            ),
216
-            'process_reg_step'                   => array(
217
-                'func'       => 'process_reg_step',
218
-                'noheader'   => true,
219
-                'capability' => 'ee_edit_registrations',
220
-            ),
221
-            'redirect_to_txn'                    => array(
222
-                'func'       => 'redirect_to_txn',
223
-                'noheader'   => true,
224
-                'capability' => 'ee_edit_registrations',
225
-            ),
226
-            'change_reg_status'                  => array(
227
-                'func'       => '_change_reg_status',
228
-                'noheader'   => true,
229
-                'capability' => 'ee_edit_registration',
230
-                'obj_id'     => $reg_id,
231
-            ),
232
-            'approve_registration'               => array(
233
-                'func'       => 'approve_registration',
234
-                'noheader'   => true,
235
-                'capability' => 'ee_edit_registration',
236
-                'obj_id'     => $reg_id,
237
-            ),
238
-            'approve_and_notify_registration'    => array(
239
-                'func'       => 'approve_registration',
240
-                'noheader'   => true,
241
-                'args'       => array(true),
242
-                'capability' => 'ee_edit_registration',
243
-                'obj_id'     => $reg_id,
244
-            ),
245
-            'approve_registrations'               => array(
246
-                'func'       => 'bulk_action_on_registrations',
247
-                'noheader'   => true,
248
-                'capability' => 'ee_edit_registrations',
249
-                'args' => array('approve')
250
-            ),
251
-            'approve_and_notify_registrations'               => array(
252
-                'func'       => 'bulk_action_on_registrations',
253
-                'noheader'   => true,
254
-                'capability' => 'ee_edit_registrations',
255
-                'args' => array('approve', true)
256
-            ),
257
-            'decline_registration'               => array(
258
-                'func'       => 'decline_registration',
259
-                'noheader'   => true,
260
-                'capability' => 'ee_edit_registration',
261
-                'obj_id'     => $reg_id,
262
-            ),
263
-            'decline_and_notify_registration'    => array(
264
-                'func'       => 'decline_registration',
265
-                'noheader'   => true,
266
-                'args'       => array(true),
267
-                'capability' => 'ee_edit_registration',
268
-                'obj_id'     => $reg_id,
269
-            ),
270
-            'decline_registrations'               => array(
271
-                'func'       => 'bulk_action_on_registrations',
272
-                'noheader'   => true,
273
-                'capability' => 'ee_edit_registrations',
274
-                'args' => array('decline')
275
-            ),
276
-            'decline_and_notify_registrations'    => array(
277
-                'func'       => 'bulk_action_on_registrations',
278
-                'noheader'   => true,
279
-                'capability' => 'ee_edit_registrations',
280
-                'args' => array('decline', true)
281
-            ),
282
-            'pending_registration'               => array(
283
-                'func'       => 'pending_registration',
284
-                'noheader'   => true,
285
-                'capability' => 'ee_edit_registration',
286
-                'obj_id'     => $reg_id,
287
-            ),
288
-            'pending_and_notify_registration'    => array(
289
-                'func'       => 'pending_registration',
290
-                'noheader'   => true,
291
-                'args'       => array(true),
292
-                'capability' => 'ee_edit_registration',
293
-                'obj_id'     => $reg_id,
294
-            ),
295
-            'pending_registrations'               => array(
296
-                'func'       => 'bulk_action_on_registrations',
297
-                'noheader'   => true,
298
-                'capability' => 'ee_edit_registrations',
299
-                'args' => array('pending')
300
-            ),
301
-            'pending_and_notify_registrations'    => array(
302
-                'func'       => 'bulk_action_on_registrations',
303
-                'noheader'   => true,
304
-                'capability' => 'ee_edit_registrations',
305
-                'args' => array('pending', true)
306
-            ),
307
-            'no_approve_registration'            => array(
308
-                'func'       => 'not_approve_registration',
309
-                'noheader'   => true,
310
-                'capability' => 'ee_edit_registration',
311
-                'obj_id'     => $reg_id,
312
-            ),
313
-            'no_approve_and_notify_registration' => array(
314
-                'func'       => 'not_approve_registration',
315
-                'noheader'   => true,
316
-                'args'       => array(true),
317
-                'capability' => 'ee_edit_registration',
318
-                'obj_id'     => $reg_id,
319
-            ),
320
-            'no_approve_registrations'            => array(
321
-                'func'       => 'bulk_action_on_registrations',
322
-                'noheader'   => true,
323
-                'capability' => 'ee_edit_registrations',
324
-                'args' => array('no_approve')
325
-            ),
326
-            'no_approve_and_notify_registrations' => array(
327
-                'func'       => 'bulk_action_on_registrations',
328
-                'noheader'   => true,
329
-                'capability' => 'ee_edit_registrations',
330
-                'args' => array('no_approve', true)
331
-            ),
332
-            'cancel_registration'                => array(
333
-                'func'       => 'cancel_registration',
334
-                'noheader'   => true,
335
-                'capability' => 'ee_edit_registration',
336
-                'obj_id'     => $reg_id,
337
-            ),
338
-            'cancel_and_notify_registration'     => array(
339
-                'func'       => 'cancel_registration',
340
-                'noheader'   => true,
341
-                'args'       => array(true),
342
-                'capability' => 'ee_edit_registration',
343
-                'obj_id'     => $reg_id,
344
-            ),
345
-            'cancel_registrations'                => array(
346
-                'func'       => 'bulk_action_on_registrations',
347
-                'noheader'   => true,
348
-                'capability' => 'ee_edit_registrations',
349
-                'args' => array('cancel')
350
-            ),
351
-            'cancel_and_notify_registrations'     => array(
352
-                'func'       => 'bulk_action_on_registrations',
353
-                'noheader'   => true,
354
-                'capability' => 'ee_edit_registrations',
355
-                'args' => array('cancel', true)
356
-            ),
357
-            'wait_list_registration' => array(
358
-                'func'       => 'wait_list_registration',
359
-                'noheader'   => true,
360
-                'capability' => 'ee_edit_registration',
361
-                'obj_id'     => $reg_id,
362
-            ),
363
-            'contact_list'                       => array(
364
-                'func'       => '_attendee_contact_list_table',
365
-                'capability' => 'ee_read_contacts',
366
-            ),
367
-            'add_new_attendee'                   => array(
368
-                'func' => '_create_new_cpt_item',
369
-                'args' => array(
370
-                    'new_attendee' => true,
371
-                    'capability'   => 'ee_edit_contacts',
372
-                ),
373
-            ),
374
-            'edit_attendee'                      => array(
375
-                'func'       => '_edit_cpt_item',
376
-                'capability' => 'ee_edit_contacts',
377
-                'obj_id'     => $att_id,
378
-            ),
379
-            'duplicate_attendee'                 => array(
380
-                'func'       => '_duplicate_attendee',
381
-                'noheader'   => true,
382
-                'capability' => 'ee_edit_contacts',
383
-                'obj_id'     => $att_id,
384
-            ),
385
-            'insert_attendee'                    => array(
386
-                'func'       => '_insert_or_update_attendee',
387
-                'args'       => array(
388
-                    'new_attendee' => true,
389
-                ),
390
-                'noheader'   => true,
391
-                'capability' => 'ee_edit_contacts',
392
-            ),
393
-            'update_attendee'                    => array(
394
-                'func'       => '_insert_or_update_attendee',
395
-                'args'       => array(
396
-                    'new_attendee' => false,
397
-                ),
398
-                'noheader'   => true,
399
-                'capability' => 'ee_edit_contacts',
400
-                'obj_id'     => $att_id,
401
-            ),
402
-            'trash_attendees' => array(
403
-                'func' => '_trash_or_restore_attendees',
404
-                'args' => array(
405
-                    'trash' => 'true'
406
-                ),
407
-                'noheader' => true,
408
-                'capability' => 'ee_delete_contacts'
409
-            ),
410
-            'trash_attendee'                    => array(
411
-                'func'       => '_trash_or_restore_attendees',
412
-                'args'       => array(
413
-                    'trash' => true,
414
-                ),
415
-                'noheader'   => true,
416
-                'capability' => 'ee_delete_contacts',
417
-                'obj_id'     => $att_id,
418
-            ),
419
-            'restore_attendees'                  => array(
420
-                'func'       => '_trash_or_restore_attendees',
421
-                'args'       => array(
422
-                    'trash' => false,
423
-                ),
424
-                'noheader'   => true,
425
-                'capability' => 'ee_delete_contacts',
426
-                'obj_id'     => $att_id,
427
-            ),
428
-            'resend_registration'                => array(
429
-                'func'       => '_resend_registration',
430
-                'noheader'   => true,
431
-                'capability' => 'ee_send_message',
432
-            ),
433
-            'registrations_report'               => array(
434
-                'func'       => '_registrations_report',
435
-                'noheader'   => true,
436
-                'capability' => 'ee_read_registrations',
437
-            ),
438
-            'contact_list_export'                => array(
439
-                'func'       => '_contact_list_export',
440
-                'noheader'   => true,
441
-                'capability' => 'export',
442
-            ),
443
-            'contact_list_report'                => array(
444
-                'func'       => '_contact_list_report',
445
-                'noheader'   => true,
446
-                'capability' => 'ee_read_contacts',
447
-            ),
448
-        );
449
-    }
450
-
451
-
452
-    protected function _set_page_config()
453
-    {
454
-        $this->_page_config = array(
455
-            'default'           => array(
456
-                'nav'           => array(
457
-                    'label' => esc_html__('Overview', 'event_espresso'),
458
-                    'order' => 5,
459
-                ),
460
-                'help_tabs'     => array(
461
-                    'registrations_overview_help_tab'                       => array(
462
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
463
-                        'filename' => 'registrations_overview',
464
-                    ),
465
-                    'registrations_overview_table_column_headings_help_tab' => array(
466
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
467
-                        'filename' => 'registrations_overview_table_column_headings',
468
-                    ),
469
-                    'registrations_overview_filters_help_tab'               => array(
470
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
471
-                        'filename' => 'registrations_overview_filters',
472
-                    ),
473
-                    'registrations_overview_views_help_tab'                 => array(
474
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
475
-                        'filename' => 'registrations_overview_views',
476
-                    ),
477
-                    'registrations_regoverview_other_help_tab'              => array(
478
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
479
-                        'filename' => 'registrations_overview_other',
480
-                    ),
481
-                ),
482
-                'help_tour'     => array('Registration_Overview_Help_Tour'),
483
-                'qtips'         => array('Registration_List_Table_Tips'),
484
-                'list_table'    => 'EE_Registrations_List_Table',
485
-                'require_nonce' => false,
486
-            ),
487
-            'view_registration' => array(
488
-                'nav'           => array(
489
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
490
-                    'order'      => 15,
491
-                    'url'        => isset($this->_req_data['_REG_ID'])
492
-                        ? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
493
-                        : $this->_admin_base_url,
494
-                    'persistent' => false,
495
-                ),
496
-                'help_tabs'     => array(
497
-                    'registrations_details_help_tab'                    => array(
498
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
499
-                        'filename' => 'registrations_details',
500
-                    ),
501
-                    'registrations_details_table_help_tab'              => array(
502
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
503
-                        'filename' => 'registrations_details_table',
504
-                    ),
505
-                    'registrations_details_form_answers_help_tab'       => array(
506
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
507
-                        'filename' => 'registrations_details_form_answers',
508
-                    ),
509
-                    'registrations_details_registrant_details_help_tab' => array(
510
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
511
-                        'filename' => 'registrations_details_registrant_details',
512
-                    ),
513
-                ),
514
-                'help_tour'     => array('Registration_Details_Help_Tour'),
515
-                'metaboxes'     => array_merge(
516
-                    $this->_default_espresso_metaboxes,
517
-                    array('_registration_details_metaboxes')
518
-                ),
519
-                'require_nonce' => false,
520
-            ),
521
-            'new_registration'  => array(
522
-                'nav'           => array(
523
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
524
-                    'url'        => '#',
525
-                    'order'      => 15,
526
-                    'persistent' => false,
527
-                ),
528
-                'metaboxes'     => $this->_default_espresso_metaboxes,
529
-                'labels'        => array(
530
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
531
-                ),
532
-                'require_nonce' => false,
533
-            ),
534
-            'add_new_attendee'  => array(
535
-                'nav'           => array(
536
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
537
-                    'order'      => 15,
538
-                    'persistent' => false,
539
-                ),
540
-                'metaboxes'     => array_merge(
541
-                    $this->_default_espresso_metaboxes,
542
-                    array('_publish_post_box', 'attendee_editor_metaboxes')
543
-                ),
544
-                'require_nonce' => false,
545
-            ),
546
-            'edit_attendee'     => array(
547
-                'nav'           => array(
548
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
549
-                    'order'      => 15,
550
-                    'persistent' => false,
551
-                    'url'        => isset($this->_req_data['ATT_ID'])
552
-                        ? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
553
-                        : $this->_admin_base_url,
554
-                ),
555
-                'metaboxes'     => array('attendee_editor_metaboxes'),
556
-                'require_nonce' => false,
557
-            ),
558
-            'contact_list'      => array(
559
-                'nav'           => array(
560
-                    'label' => esc_html__('Contact List', 'event_espresso'),
561
-                    'order' => 20,
562
-                ),
563
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
564
-                'help_tabs'     => array(
565
-                    'registrations_contact_list_help_tab'                       => array(
566
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
567
-                        'filename' => 'registrations_contact_list',
568
-                    ),
569
-                    'registrations_contact-list_table_column_headings_help_tab' => array(
570
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
571
-                        'filename' => 'registrations_contact_list_table_column_headings',
572
-                    ),
573
-                    'registrations_contact_list_views_help_tab'                 => array(
574
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
575
-                        'filename' => 'registrations_contact_list_views',
576
-                    ),
577
-                    'registrations_contact_list_other_help_tab'                 => array(
578
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
579
-                        'filename' => 'registrations_contact_list_other',
580
-                    ),
581
-                ),
582
-                'help_tour'     => array('Contact_List_Help_Tour'),
583
-                'metaboxes'     => array(),
584
-                'require_nonce' => false,
585
-            ),
586
-            //override default cpt routes
587
-            'create_new'        => '',
588
-            'edit'              => '',
589
-        );
590
-    }
591
-
592
-
593
-    /**
594
-     * The below methods aren't used by this class currently
595
-     */
596
-    protected function _add_screen_options()
597
-    {
598
-    }
599
-
600
-
601
-    protected function _add_feature_pointers()
602
-    {
603
-    }
604
-
605
-
606
-    public function admin_init()
607
-    {
608
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
609
-            'click "Update Registration Questions" to save your changes',
610
-            'event_espresso'
611
-        );
612
-    }
613
-
614
-
615
-    public function admin_notices()
616
-    {
617
-    }
618
-
619
-
620
-    public function admin_footer_scripts()
621
-    {
622
-    }
623
-
624
-
625
-    /**
626
-     *        get list of registration statuses
627
-     *
628
-     * @access private
629
-     * @return void
630
-     */
631
-    private function _get_registration_status_array()
632
-    {
633
-        self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
634
-    }
635
-
636
-
637
-    protected function _add_screen_options_default()
638
-    {
639
-        $this->_per_page_screen_option();
640
-    }
641
-
642
-
643
-    protected function _add_screen_options_contact_list()
644
-    {
645
-        $page_title              = $this->_admin_page_title;
646
-        $this->_admin_page_title = esc_html__("Contacts", 'event_espresso');
647
-        $this->_per_page_screen_option();
648
-        $this->_admin_page_title = $page_title;
649
-    }
650
-
651
-
652
-    public function load_scripts_styles()
653
-    {
654
-        //style
655
-        wp_register_style(
656
-            'espresso_reg',
657
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
658
-            array('ee-admin-css'),
659
-            EVENT_ESPRESSO_VERSION
660
-        );
661
-        wp_enqueue_style('espresso_reg');
662
-        //script
663
-        wp_register_script(
664
-            'espresso_reg',
665
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
666
-            array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
667
-            EVENT_ESPRESSO_VERSION,
668
-            true
669
-        );
670
-        wp_enqueue_script('espresso_reg');
671
-    }
672
-
673
-
674
-    public function load_scripts_styles_edit_attendee()
675
-    {
676
-        //stuff to only show up on our attendee edit details page.
677
-        $attendee_details_translations = array(
678
-            'att_publish_text' => sprintf(
679
-                esc_html__('Created on: <b>%1$s</b>', 'event_espresso'),
680
-                $this->_cpt_model_obj->get_datetime('ATT_created')
681
-            ),
682
-        );
683
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
684
-        wp_enqueue_script('jquery-validate');
685
-    }
686
-
687
-
688
-    public function load_scripts_styles_view_registration()
689
-    {
690
-        //styles
691
-        wp_enqueue_style('espresso-ui-theme');
692
-        //scripts
693
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
694
-        $this->_reg_custom_questions_form->wp_enqueue_scripts(true);
695
-    }
696
-
697
-
698
-    public function load_scripts_styles_contact_list()
699
-    {
700
-        wp_deregister_style('espresso_reg');
701
-        wp_register_style(
702
-            'espresso_att',
703
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
704
-            array('ee-admin-css'),
705
-            EVENT_ESPRESSO_VERSION
706
-        );
707
-        wp_enqueue_style('espresso_att');
708
-    }
709
-
710
-
711
-    public function load_scripts_styles_new_registration()
712
-    {
713
-        wp_register_script(
714
-            'ee-spco-for-admin',
715
-            REG_ASSETS_URL . 'spco_for_admin.js',
716
-            array('underscore', 'jquery'),
717
-            EVENT_ESPRESSO_VERSION,
718
-            true
719
-        );
720
-        wp_enqueue_script('ee-spco-for-admin');
721
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
722
-        EE_Form_Section_Proper::wp_enqueue_scripts();
723
-        EED_Ticket_Selector::load_tckt_slctr_assets();
724
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
725
-    }
726
-
727
-
728
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
729
-    {
730
-        add_filter('FHEE_load_EE_messages', '__return_true');
731
-    }
732
-
733
-
734
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
735
-    {
736
-        add_filter('FHEE_load_EE_messages', '__return_true');
737
-    }
738
-
739
-
740
-    protected function _set_list_table_views_default()
741
-    {
742
-        //for notification related bulk actions we need to make sure only active messengers have an option.
743
-        EED_Messages::set_autoloaders();
744
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
745
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
746
-        $active_mts               = $message_resource_manager->list_of_active_message_types();
747
-        //key= bulk_action_slug, value= message type.
748
-        $match_array = array(
749
-            'approve_registrations'    => 'registration',
750
-            'decline_registrations'    => 'declined_registration',
751
-            'pending_registrations'    => 'pending_approval',
752
-            'no_approve_registrations' => 'not_approved_registration',
753
-            'cancel_registrations'     => 'cancelled_registration',
754
-        );
755
-        $can_send = EE_Registry::instance()->CAP->current_user_can(
756
-            'ee_send_message',
757
-            'batch_send_messages'
758
-        );
759
-        /** setup reg status bulk actions **/
760
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
761
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
762
-                $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
763
-                    'Approve and Notify Registrations',
764
-                    'event_espresso'
765
-                );
766
-        }
767
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
768
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
769
-                $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
770
-                    'Decline and Notify Registrations',
771
-                    'event_espresso'
772
-                );
773
-        }
774
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
775
-            'Set Registrations to Pending Payment',
776
-            'event_espresso'
777
-        );
778
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
779
-                $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
780
-                    'Set Registrations to Pending Payment and Notify',
781
-                    'event_espresso'
782
-                );
783
-        }
784
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
785
-            'Set Registrations to Not Approved',
786
-            'event_espresso'
787
-        );
788
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
789
-                $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
790
-                    'Set Registrations to Not Approved and Notify',
791
-                    'event_espresso'
792
-                );
793
-        }
794
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
795
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
796
-                $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
797
-                    'Cancel Registrations and Notify',
798
-                    'event_espresso'
799
-                );
800
-        }
801
-        $def_reg_status_actions = apply_filters(
802
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
803
-            $def_reg_status_actions,
804
-            $active_mts
805
-        );
806
-
807
-        $this->_views = array(
808
-            'all'   => array(
809
-                'slug'        => 'all',
810
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
811
-                'count'       => 0,
812
-                'bulk_action' => array_merge($def_reg_status_actions, array(
813
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
814
-                )),
815
-            ),
816
-            'month' => array(
817
-                'slug'        => 'month',
818
-                'label'       => esc_html__('This Month', 'event_espresso'),
819
-                'count'       => 0,
820
-                'bulk_action' => array_merge($def_reg_status_actions, array(
821
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
822
-                )),
823
-            ),
824
-            'today' => array(
825
-                'slug'        => 'today',
826
-                'label'       => sprintf(
827
-                    esc_html__('Today - %s', 'event_espresso'),
828
-                    date('M d, Y', current_time('timestamp'))
829
-                ),
830
-                'count'       => 0,
831
-                'bulk_action' => array_merge($def_reg_status_actions, array(
832
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
833
-                )),
834
-            ),
835
-        );
836
-        if (EE_Registry::instance()->CAP->current_user_can(
837
-            'ee_delete_registrations',
838
-            'espresso_registrations_delete_registration'
839
-        )) {
840
-            $this->_views['incomplete'] = array(
841
-                'slug'        => 'incomplete',
842
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
843
-                'count'       => 0,
844
-                'bulk_action' => array(
845
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
846
-                ),
847
-            );
848
-            $this->_views['trash']      = array(
849
-                'slug'        => 'trash',
850
-                'label'       => esc_html__('Trash', 'event_espresso'),
851
-                'count'       => 0,
852
-                'bulk_action' => array(
853
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
854
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
855
-                ),
856
-            );
857
-        }
858
-    }
859
-
860
-
861
-    protected function _set_list_table_views_contact_list()
862
-    {
863
-        $this->_views = array(
864
-            'in_use' => array(
865
-                'slug'        => 'in_use',
866
-                'label'       => esc_html__('In Use', 'event_espresso'),
867
-                'count'       => 0,
868
-                'bulk_action' => array(
869
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
870
-                ),
871
-            ),
872
-        );
873
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_contacts',
874
-            'espresso_registrations_trash_attendees')
875
-        ) {
876
-            $this->_views['trash'] = array(
877
-                'slug'        => 'trash',
878
-                'label'       => esc_html__('Trash', 'event_espresso'),
879
-                'count'       => 0,
880
-                'bulk_action' => array(
881
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
882
-                ),
883
-            );
884
-        }
885
-    }
886
-
887
-
888
-    protected function _registration_legend_items()
889
-    {
890
-        $fc_items = array(
891
-            'star-icon'        => array(
892
-                'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
893
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
894
-            ),
895
-            'view_details'     => array(
896
-                'class' => 'dashicons dashicons-clipboard',
897
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
898
-            ),
899
-            'edit_attendee'    => array(
900
-                'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
901
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
902
-            ),
903
-            'view_transaction' => array(
904
-                'class' => 'dashicons dashicons-cart',
905
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
906
-            ),
907
-            'view_invoice'     => array(
908
-                'class' => 'dashicons dashicons-media-spreadsheet',
909
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
910
-            ),
911
-        );
912
-        if (EE_Registry::instance()->CAP->current_user_can(
913
-            'ee_send_message',
914
-            'espresso_registrations_resend_registration'
915
-        )) {
916
-            $fc_items['resend_registration'] = array(
917
-                'class' => 'dashicons dashicons-email-alt',
918
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
919
-            );
920
-        } else {
921
-            $fc_items['blank'] = array('class' => 'blank', 'desc' => '');
922
-        }
923
-        if (EE_Registry::instance()->CAP->current_user_can(
924
-            'ee_read_global_messages',
925
-            'view_filtered_messages'
926
-        )) {
927
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
928
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
929
-                $fc_items['view_related_messages'] = array(
930
-                    'class' => $related_for_icon['css_class'],
931
-                    'desc'  => $related_for_icon['label'],
932
-                );
933
-            }
934
-        }
935
-        $sc_items = array(
936
-            'approved_status'   => array(
937
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
938
-                'desc'  => EEH_Template::pretty_status(
939
-                    EEM_Registration::status_id_approved,
940
-                    false,
941
-                    'sentence'
942
-                ),
943
-            ),
944
-            'pending_status'    => array(
945
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
946
-                'desc'  => EEH_Template::pretty_status(
947
-                    EEM_Registration::status_id_pending_payment,
948
-                    false,
949
-                    'sentence'
950
-                ),
951
-            ),
952
-            'wait_list'         => array(
953
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
954
-                'desc'  => EEH_Template::pretty_status(
955
-                    EEM_Registration::status_id_wait_list,
956
-                    false,
957
-                    'sentence'
958
-                ),
959
-            ),
960
-            'incomplete_status' => array(
961
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
962
-                'desc'  => EEH_Template::pretty_status(
963
-                    EEM_Registration::status_id_incomplete,
964
-                    false,
965
-                    'sentence'
966
-                ),
967
-            ),
968
-            'not_approved'      => array(
969
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
970
-                'desc'  => EEH_Template::pretty_status(
971
-                    EEM_Registration::status_id_not_approved,
972
-                    false,
973
-                    'sentence'
974
-                ),
975
-            ),
976
-            'declined_status'   => array(
977
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
978
-                'desc'  => EEH_Template::pretty_status(
979
-                    EEM_Registration::status_id_declined,
980
-                    false,
981
-                    'sentence'
982
-                ),
983
-            ),
984
-            'cancelled_status'  => array(
985
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
986
-                'desc'  => EEH_Template::pretty_status(
987
-                    EEM_Registration::status_id_cancelled,
988
-                    false,
989
-                    'sentence'
990
-                ),
991
-            ),
992
-        );
993
-        return array_merge($fc_items, $sc_items);
994
-    }
995
-
996
-
997
-
998
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
999
-    /**
1000
-     * @throws \EE_Error
1001
-     */
1002
-    protected function _registrations_overview_list_table()
1003
-    {
1004
-        $this->_template_args['admin_page_header'] = '';
1005
-        $EVT_ID                                    = ! empty($this->_req_data['event_id'])
1006
-            ? absint($this->_req_data['event_id'])
1007
-            : 0;
1008
-        if ($EVT_ID) {
1009
-            if (EE_Registry::instance()->CAP->current_user_can(
1010
-                'ee_edit_registrations',
1011
-                'espresso_registrations_new_registration',
1012
-                $EVT_ID
1013
-            )) {
1014
-                $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1015
-                    'new_registration',
1016
-                    'add-registrant',
1017
-                    array('event_id' => $EVT_ID),
1018
-                    'add-new-h2'
1019
-                );
1020
-            }
1021
-            $event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
1022
-            if ($event instanceof EE_Event) {
1023
-                $this->_template_args['admin_page_header'] = sprintf(
1024
-                    esc_html__(
1025
-                        '%s Viewing registrations for the event: %s%s',
1026
-                        'event_espresso'
1027
-                    ),
1028
-                    '<h3 style="line-height:1.5em;">',
1029
-                    '<br /><a href="'
1030
-                        . EE_Admin_Page::add_query_args_and_nonce(
1031
-                            array(
1032
-                                'action' => 'edit',
1033
-                                'post'   => $event->ID(),
1034
-                            ),
1035
-                            EVENTS_ADMIN_URL
1036
-                        )
1037
-                        . '">&nbsp;'
1038
-                        . $event->get('EVT_name')
1039
-                        . '&nbsp;</a>&nbsp;',
1040
-                    '</h3>'
1041
-                );
1042
-            }
1043
-            $DTT_ID   = ! empty($this->_req_data['datetime_id']) ? absint($this->_req_data['datetime_id']) : 0;
1044
-            $datetime = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1045
-            if ($datetime instanceof EE_Datetime && $this->_template_args['admin_page_header'] !== '') {
1046
-                $this->_template_args['admin_page_header'] = substr(
1047
-                    $this->_template_args['admin_page_header'],
1048
-                    0,
1049
-                    -5
1050
-                );
1051
-                $this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1052
-                $this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1053
-                $this->_template_args['admin_page_header'] .= $datetime->name();
1054
-                $this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1055
-                $this->_template_args['admin_page_header'] .= '</span></h3>';
1056
-            }
1057
-        }
1058
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1059
-        $this->display_admin_list_table_page_with_no_sidebar();
1060
-    }
1061
-
1062
-
1063
-    /**
1064
-     * This sets the _registration property for the registration details screen
1065
-     *
1066
-     * @access private
1067
-     * @return bool
1068
-     */
1069
-    private function _set_registration_object()
1070
-    {
1071
-        //get out if we've already set the object
1072
-        if (is_object($this->_registration)) {
1073
-            return true;
1074
-        }
1075
-        $REG    = EEM_Registration::instance();
1076
-        $REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1077
-        if ($this->_registration = $REG->get_one_by_ID($REG_ID)) {
1078
-            return true;
1079
-        } else {
1080
-            $error_msg = sprintf(
1081
-                esc_html__(
1082
-                    'An error occurred and the details for Registration ID #%s could not be retrieved.',
1083
-                    'event_espresso'
1084
-                ),
1085
-                $REG_ID
1086
-            );
1087
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1088
-            $this->_registration = null;
1089
-            return false;
1090
-        }
1091
-    }
1092
-
1093
-
1094
-    /**
1095
-     * Used to retrieve registrations for the list table.
1096
-     *
1097
-     * @param int  $per_page
1098
-     * @param bool $count
1099
-     * @param bool $this_month
1100
-     * @param bool $today
1101
-     * @return EE_Registration[]|int
1102
-     * @throws EE_Error
1103
-     */
1104
-    public function get_registrations(
1105
-        $per_page = 10,
1106
-        $count = false,
1107
-        $this_month = false,
1108
-        $today = false
1109
-    ) {
1110
-        if ($this_month) {
1111
-            $this->_req_data['status'] = 'month';
1112
-        }
1113
-        if ($today) {
1114
-            $this->_req_data['status'] = 'today';
1115
-        }
1116
-        $query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1117
-        /**
1118
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1119
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1120
-         * @see EEM_Base::get_all()
1121
-         */
1122
-        $query_params['group_by'] = '';
1123
-
1124
-        return $count
1125
-            ? EEM_Registration::instance()->count($query_params)
1126
-            /** @type EE_Registration[] */
1127
-            : EEM_Registration::instance()->get_all($query_params);
1128
-    }
1129
-
1130
-
1131
-
1132
-    /**
1133
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1134
-     * Note: this listens to values on the request for some of the query parameters.
1135
-     *
1136
-     * @param array $request
1137
-     * @param int    $per_page
1138
-     * @param bool   $count
1139
-     * @return array
1140
-     */
1141
-    protected function _get_registration_query_parameters(
1142
-        $request = array(),
1143
-        $per_page = 10,
1144
-        $count = false
1145
-    ) {
1146
-
1147
-        $query_params = array(
1148
-            0                          => $this->_get_where_conditions_for_registrations_query(
1149
-                $request
1150
-            ),
1151
-            'caps'                     => EEM_Registration::caps_read_admin,
1152
-            'default_where_conditions' => 'this_model_only',
1153
-        );
1154
-        if (! $count) {
1155
-            $query_params = array_merge(
1156
-                $query_params,
1157
-                $this->_get_orderby_for_registrations_query(),
1158
-                $this->_get_limit($per_page)
1159
-            );
1160
-        }
1161
-
1162
-        return $query_params;
1163
-    }
1164
-
1165
-
1166
-    /**
1167
-     * This will add EVT_ID to the provided $where array for EE model query parameters.
1168
-     *
1169
-     * @param array $request usually the same as $this->_req_data but not necessarily
1170
-     * @return array
1171
-     */
1172
-    protected function _add_event_id_to_where_conditions(array $request)
1173
-    {
1174
-        $where = array();
1175
-        if (! empty($request['event_id'])) {
1176
-            $where['EVT_ID'] = absint($request['event_id']);
1177
-        }
1178
-        return $where;
1179
-    }
1180
-
1181
-
1182
-    /**
1183
-     * Adds category ID if it exists in the request to the where conditions for the registrations query.
1184
-     *
1185
-     * @param array $request usually the same as $this->_req_data but not necessarily
1186
-     * @return array
1187
-     */
1188
-    protected function _add_category_id_to_where_conditions(array $request)
1189
-    {
1190
-        $where = array();
1191
-        if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1192
-            $where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1193
-        }
1194
-        return $where;
1195
-    }
1196
-
1197
-
1198
-    /**
1199
-     * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
1200
-     *
1201
-     * @param array $request usually the same as $this->_req_data but not necessarily
1202
-     * @return array
1203
-     */
1204
-    protected function _add_datetime_id_to_where_conditions(array $request)
1205
-    {
1206
-        $where = array();
1207
-        if (! empty($request['datetime_id'])) {
1208
-            $where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1209
-        }
1210
-        if (! empty($request['DTT_ID'])) {
1211
-            $where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1212
-        }
1213
-        return $where;
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * Adds the correct registration status to the where conditions for the registrations query.
1219
-     *
1220
-     * @param array $request usually the same as $this->_req_data but not necessarily
1221
-     * @return array
1222
-     */
1223
-    protected function _add_registration_status_to_where_conditions(array $request)
1224
-    {
1225
-        $where = array();
1226
-        $view = EEH_Array::is_set($request, 'status', '');
1227
-        $registration_status = ! empty($request['_reg_status'])
1228
-            ? sanitize_text_field($request['_reg_status'])
1229
-            : '';
1230
-
1231
-        /*
26
+	/**
27
+	 * @var EE_Registration
28
+	 */
29
+	private $_registration;
30
+
31
+	/**
32
+	 * @var EE_Event
33
+	 */
34
+	private $_reg_event;
35
+
36
+	/**
37
+	 * @var EE_Session
38
+	 */
39
+	private $_session;
40
+
41
+	private static $_reg_status;
42
+
43
+	/**
44
+	 * Form for displaying the custom questions for this registration.
45
+	 * This gets used a few times throughout the request so its best to cache it
46
+	 *
47
+	 * @var EE_Registration_Custom_Questions_Form
48
+	 */
49
+	protected $_reg_custom_questions_form = null;
50
+
51
+
52
+	/**
53
+	 *        constructor
54
+	 *
55
+	 * @Constructor
56
+	 * @access public
57
+	 * @param bool $routing
58
+	 * @return Registrations_Admin_Page
59
+	 */
60
+	public function __construct($routing = true)
61
+	{
62
+		parent::__construct($routing);
63
+		add_action('wp_loaded', array($this, 'wp_loaded'));
64
+	}
65
+
66
+
67
+	public function wp_loaded()
68
+	{
69
+		// when adding a new registration...
70
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
71
+			EE_System::do_not_cache();
72
+			if (! isset($this->_req_data['processing_registration'])
73
+				 || absint($this->_req_data['processing_registration']) !== 1
74
+			) {
75
+				// and it's NOT the attendee information reg step
76
+				// force cookie expiration by setting time to last week
77
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
78
+				// and update the global
79
+				$_COOKIE['ee_registration_added'] = 0;
80
+			}
81
+		}
82
+	}
83
+
84
+
85
+	protected function _init_page_props()
86
+	{
87
+		$this->page_slug        = REG_PG_SLUG;
88
+		$this->_admin_base_url  = REG_ADMIN_URL;
89
+		$this->_admin_base_path = REG_ADMIN;
90
+		$this->page_label       = esc_html__('Registrations', 'event_espresso');
91
+		$this->_cpt_routes      = array(
92
+			'add_new_attendee' => 'espresso_attendees',
93
+			'edit_attendee'    => 'espresso_attendees',
94
+			'insert_attendee'  => 'espresso_attendees',
95
+			'update_attendee'  => 'espresso_attendees',
96
+		);
97
+		$this->_cpt_model_names = array(
98
+			'add_new_attendee' => 'EEM_Attendee',
99
+			'edit_attendee'    => 'EEM_Attendee',
100
+		);
101
+		$this->_cpt_edit_routes = array(
102
+			'espresso_attendees' => 'edit_attendee',
103
+		);
104
+		$this->_pagenow_map     = array(
105
+			'add_new_attendee' => 'post-new.php',
106
+			'edit_attendee'    => 'post.php',
107
+			'trash'            => 'post.php',
108
+		);
109
+		add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
110
+		//add filters so that the comment urls don't take users to a confusing 404 page
111
+		add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
112
+	}
113
+
114
+
115
+	public function clear_comment_link($link, $comment, $args)
116
+	{
117
+		//gotta make sure this only happens on this route
118
+		$post_type = get_post_type($comment->comment_post_ID);
119
+		if ($post_type === 'espresso_attendees') {
120
+			return '#commentsdiv';
121
+		}
122
+		return $link;
123
+	}
124
+
125
+
126
+	protected function _ajax_hooks()
127
+	{
128
+		//todo: all hooks for registrations ajax goes in here
129
+		add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
130
+	}
131
+
132
+
133
+	protected function _define_page_props()
134
+	{
135
+		$this->_admin_page_title = $this->page_label;
136
+		$this->_labels           = array(
137
+			'buttons'                      => array(
138
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
139
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
140
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
141
+				'report'              => esc_html__("Event Registrations CSV Report", "event_espresso"),
142
+				'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
143
+				'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
144
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
145
+				'contact_list_export' => esc_html__("Export Data", "event_espresso"),
146
+			),
147
+			'publishbox'                   => array(
148
+				'add_new_attendee' => esc_html__("Add Contact Record", 'event_espresso'),
149
+				'edit_attendee'    => esc_html__("Update Contact Record", 'event_espresso'),
150
+			),
151
+			'hide_add_button_on_cpt_route' => array(
152
+				'edit_attendee' => true,
153
+			),
154
+		);
155
+	}
156
+
157
+
158
+	/**
159
+	 *        grab url requests and route them
160
+	 *
161
+	 * @access private
162
+	 * @return void
163
+	 */
164
+	public function _set_page_routes()
165
+	{
166
+		$this->_get_registration_status_array();
167
+		$reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
168
+			? $this->_req_data['_REG_ID'] : 0;
169
+		$reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
170
+			? $this->_req_data['reg_status_change_form']['REG_ID']
171
+			: $reg_id;
172
+		$att_id             = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
173
+			? $this->_req_data['ATT_ID'] : 0;
174
+		$att_id             = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
175
+			? $this->_req_data['post']
176
+			: $att_id;
177
+		$this->_page_routes = array(
178
+			'default'                            => array(
179
+				'func'       => '_registrations_overview_list_table',
180
+				'capability' => 'ee_read_registrations',
181
+			),
182
+			'view_registration'                  => array(
183
+				'func'       => '_registration_details',
184
+				'capability' => 'ee_read_registration',
185
+				'obj_id'     => $reg_id,
186
+			),
187
+			'edit_registration'                  => array(
188
+				'func'               => '_update_attendee_registration_form',
189
+				'noheader'           => true,
190
+				'headers_sent_route' => 'view_registration',
191
+				'capability'         => 'ee_edit_registration',
192
+				'obj_id'             => $reg_id,
193
+				'_REG_ID'            => $reg_id,
194
+			),
195
+			'trash_registrations'                => array(
196
+				'func'       => '_trash_or_restore_registrations',
197
+				'args'       => array('trash' => true),
198
+				'noheader'   => true,
199
+				'capability' => 'ee_delete_registrations',
200
+			),
201
+			'restore_registrations'              => array(
202
+				'func'       => '_trash_or_restore_registrations',
203
+				'args'       => array('trash' => false),
204
+				'noheader'   => true,
205
+				'capability' => 'ee_delete_registrations',
206
+			),
207
+			'delete_registrations'               => array(
208
+				'func'       => '_delete_registrations',
209
+				'noheader'   => true,
210
+				'capability' => 'ee_delete_registrations',
211
+			),
212
+			'new_registration'                   => array(
213
+				'func'       => 'new_registration',
214
+				'capability' => 'ee_edit_registrations',
215
+			),
216
+			'process_reg_step'                   => array(
217
+				'func'       => 'process_reg_step',
218
+				'noheader'   => true,
219
+				'capability' => 'ee_edit_registrations',
220
+			),
221
+			'redirect_to_txn'                    => array(
222
+				'func'       => 'redirect_to_txn',
223
+				'noheader'   => true,
224
+				'capability' => 'ee_edit_registrations',
225
+			),
226
+			'change_reg_status'                  => array(
227
+				'func'       => '_change_reg_status',
228
+				'noheader'   => true,
229
+				'capability' => 'ee_edit_registration',
230
+				'obj_id'     => $reg_id,
231
+			),
232
+			'approve_registration'               => array(
233
+				'func'       => 'approve_registration',
234
+				'noheader'   => true,
235
+				'capability' => 'ee_edit_registration',
236
+				'obj_id'     => $reg_id,
237
+			),
238
+			'approve_and_notify_registration'    => array(
239
+				'func'       => 'approve_registration',
240
+				'noheader'   => true,
241
+				'args'       => array(true),
242
+				'capability' => 'ee_edit_registration',
243
+				'obj_id'     => $reg_id,
244
+			),
245
+			'approve_registrations'               => array(
246
+				'func'       => 'bulk_action_on_registrations',
247
+				'noheader'   => true,
248
+				'capability' => 'ee_edit_registrations',
249
+				'args' => array('approve')
250
+			),
251
+			'approve_and_notify_registrations'               => array(
252
+				'func'       => 'bulk_action_on_registrations',
253
+				'noheader'   => true,
254
+				'capability' => 'ee_edit_registrations',
255
+				'args' => array('approve', true)
256
+			),
257
+			'decline_registration'               => array(
258
+				'func'       => 'decline_registration',
259
+				'noheader'   => true,
260
+				'capability' => 'ee_edit_registration',
261
+				'obj_id'     => $reg_id,
262
+			),
263
+			'decline_and_notify_registration'    => array(
264
+				'func'       => 'decline_registration',
265
+				'noheader'   => true,
266
+				'args'       => array(true),
267
+				'capability' => 'ee_edit_registration',
268
+				'obj_id'     => $reg_id,
269
+			),
270
+			'decline_registrations'               => array(
271
+				'func'       => 'bulk_action_on_registrations',
272
+				'noheader'   => true,
273
+				'capability' => 'ee_edit_registrations',
274
+				'args' => array('decline')
275
+			),
276
+			'decline_and_notify_registrations'    => array(
277
+				'func'       => 'bulk_action_on_registrations',
278
+				'noheader'   => true,
279
+				'capability' => 'ee_edit_registrations',
280
+				'args' => array('decline', true)
281
+			),
282
+			'pending_registration'               => array(
283
+				'func'       => 'pending_registration',
284
+				'noheader'   => true,
285
+				'capability' => 'ee_edit_registration',
286
+				'obj_id'     => $reg_id,
287
+			),
288
+			'pending_and_notify_registration'    => array(
289
+				'func'       => 'pending_registration',
290
+				'noheader'   => true,
291
+				'args'       => array(true),
292
+				'capability' => 'ee_edit_registration',
293
+				'obj_id'     => $reg_id,
294
+			),
295
+			'pending_registrations'               => array(
296
+				'func'       => 'bulk_action_on_registrations',
297
+				'noheader'   => true,
298
+				'capability' => 'ee_edit_registrations',
299
+				'args' => array('pending')
300
+			),
301
+			'pending_and_notify_registrations'    => array(
302
+				'func'       => 'bulk_action_on_registrations',
303
+				'noheader'   => true,
304
+				'capability' => 'ee_edit_registrations',
305
+				'args' => array('pending', true)
306
+			),
307
+			'no_approve_registration'            => array(
308
+				'func'       => 'not_approve_registration',
309
+				'noheader'   => true,
310
+				'capability' => 'ee_edit_registration',
311
+				'obj_id'     => $reg_id,
312
+			),
313
+			'no_approve_and_notify_registration' => array(
314
+				'func'       => 'not_approve_registration',
315
+				'noheader'   => true,
316
+				'args'       => array(true),
317
+				'capability' => 'ee_edit_registration',
318
+				'obj_id'     => $reg_id,
319
+			),
320
+			'no_approve_registrations'            => array(
321
+				'func'       => 'bulk_action_on_registrations',
322
+				'noheader'   => true,
323
+				'capability' => 'ee_edit_registrations',
324
+				'args' => array('no_approve')
325
+			),
326
+			'no_approve_and_notify_registrations' => array(
327
+				'func'       => 'bulk_action_on_registrations',
328
+				'noheader'   => true,
329
+				'capability' => 'ee_edit_registrations',
330
+				'args' => array('no_approve', true)
331
+			),
332
+			'cancel_registration'                => array(
333
+				'func'       => 'cancel_registration',
334
+				'noheader'   => true,
335
+				'capability' => 'ee_edit_registration',
336
+				'obj_id'     => $reg_id,
337
+			),
338
+			'cancel_and_notify_registration'     => array(
339
+				'func'       => 'cancel_registration',
340
+				'noheader'   => true,
341
+				'args'       => array(true),
342
+				'capability' => 'ee_edit_registration',
343
+				'obj_id'     => $reg_id,
344
+			),
345
+			'cancel_registrations'                => array(
346
+				'func'       => 'bulk_action_on_registrations',
347
+				'noheader'   => true,
348
+				'capability' => 'ee_edit_registrations',
349
+				'args' => array('cancel')
350
+			),
351
+			'cancel_and_notify_registrations'     => array(
352
+				'func'       => 'bulk_action_on_registrations',
353
+				'noheader'   => true,
354
+				'capability' => 'ee_edit_registrations',
355
+				'args' => array('cancel', true)
356
+			),
357
+			'wait_list_registration' => array(
358
+				'func'       => 'wait_list_registration',
359
+				'noheader'   => true,
360
+				'capability' => 'ee_edit_registration',
361
+				'obj_id'     => $reg_id,
362
+			),
363
+			'contact_list'                       => array(
364
+				'func'       => '_attendee_contact_list_table',
365
+				'capability' => 'ee_read_contacts',
366
+			),
367
+			'add_new_attendee'                   => array(
368
+				'func' => '_create_new_cpt_item',
369
+				'args' => array(
370
+					'new_attendee' => true,
371
+					'capability'   => 'ee_edit_contacts',
372
+				),
373
+			),
374
+			'edit_attendee'                      => array(
375
+				'func'       => '_edit_cpt_item',
376
+				'capability' => 'ee_edit_contacts',
377
+				'obj_id'     => $att_id,
378
+			),
379
+			'duplicate_attendee'                 => array(
380
+				'func'       => '_duplicate_attendee',
381
+				'noheader'   => true,
382
+				'capability' => 'ee_edit_contacts',
383
+				'obj_id'     => $att_id,
384
+			),
385
+			'insert_attendee'                    => array(
386
+				'func'       => '_insert_or_update_attendee',
387
+				'args'       => array(
388
+					'new_attendee' => true,
389
+				),
390
+				'noheader'   => true,
391
+				'capability' => 'ee_edit_contacts',
392
+			),
393
+			'update_attendee'                    => array(
394
+				'func'       => '_insert_or_update_attendee',
395
+				'args'       => array(
396
+					'new_attendee' => false,
397
+				),
398
+				'noheader'   => true,
399
+				'capability' => 'ee_edit_contacts',
400
+				'obj_id'     => $att_id,
401
+			),
402
+			'trash_attendees' => array(
403
+				'func' => '_trash_or_restore_attendees',
404
+				'args' => array(
405
+					'trash' => 'true'
406
+				),
407
+				'noheader' => true,
408
+				'capability' => 'ee_delete_contacts'
409
+			),
410
+			'trash_attendee'                    => array(
411
+				'func'       => '_trash_or_restore_attendees',
412
+				'args'       => array(
413
+					'trash' => true,
414
+				),
415
+				'noheader'   => true,
416
+				'capability' => 'ee_delete_contacts',
417
+				'obj_id'     => $att_id,
418
+			),
419
+			'restore_attendees'                  => array(
420
+				'func'       => '_trash_or_restore_attendees',
421
+				'args'       => array(
422
+					'trash' => false,
423
+				),
424
+				'noheader'   => true,
425
+				'capability' => 'ee_delete_contacts',
426
+				'obj_id'     => $att_id,
427
+			),
428
+			'resend_registration'                => array(
429
+				'func'       => '_resend_registration',
430
+				'noheader'   => true,
431
+				'capability' => 'ee_send_message',
432
+			),
433
+			'registrations_report'               => array(
434
+				'func'       => '_registrations_report',
435
+				'noheader'   => true,
436
+				'capability' => 'ee_read_registrations',
437
+			),
438
+			'contact_list_export'                => array(
439
+				'func'       => '_contact_list_export',
440
+				'noheader'   => true,
441
+				'capability' => 'export',
442
+			),
443
+			'contact_list_report'                => array(
444
+				'func'       => '_contact_list_report',
445
+				'noheader'   => true,
446
+				'capability' => 'ee_read_contacts',
447
+			),
448
+		);
449
+	}
450
+
451
+
452
+	protected function _set_page_config()
453
+	{
454
+		$this->_page_config = array(
455
+			'default'           => array(
456
+				'nav'           => array(
457
+					'label' => esc_html__('Overview', 'event_espresso'),
458
+					'order' => 5,
459
+				),
460
+				'help_tabs'     => array(
461
+					'registrations_overview_help_tab'                       => array(
462
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
463
+						'filename' => 'registrations_overview',
464
+					),
465
+					'registrations_overview_table_column_headings_help_tab' => array(
466
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
467
+						'filename' => 'registrations_overview_table_column_headings',
468
+					),
469
+					'registrations_overview_filters_help_tab'               => array(
470
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
471
+						'filename' => 'registrations_overview_filters',
472
+					),
473
+					'registrations_overview_views_help_tab'                 => array(
474
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
475
+						'filename' => 'registrations_overview_views',
476
+					),
477
+					'registrations_regoverview_other_help_tab'              => array(
478
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
479
+						'filename' => 'registrations_overview_other',
480
+					),
481
+				),
482
+				'help_tour'     => array('Registration_Overview_Help_Tour'),
483
+				'qtips'         => array('Registration_List_Table_Tips'),
484
+				'list_table'    => 'EE_Registrations_List_Table',
485
+				'require_nonce' => false,
486
+			),
487
+			'view_registration' => array(
488
+				'nav'           => array(
489
+					'label'      => esc_html__('REG Details', 'event_espresso'),
490
+					'order'      => 15,
491
+					'url'        => isset($this->_req_data['_REG_ID'])
492
+						? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
493
+						: $this->_admin_base_url,
494
+					'persistent' => false,
495
+				),
496
+				'help_tabs'     => array(
497
+					'registrations_details_help_tab'                    => array(
498
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
499
+						'filename' => 'registrations_details',
500
+					),
501
+					'registrations_details_table_help_tab'              => array(
502
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
503
+						'filename' => 'registrations_details_table',
504
+					),
505
+					'registrations_details_form_answers_help_tab'       => array(
506
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
507
+						'filename' => 'registrations_details_form_answers',
508
+					),
509
+					'registrations_details_registrant_details_help_tab' => array(
510
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
511
+						'filename' => 'registrations_details_registrant_details',
512
+					),
513
+				),
514
+				'help_tour'     => array('Registration_Details_Help_Tour'),
515
+				'metaboxes'     => array_merge(
516
+					$this->_default_espresso_metaboxes,
517
+					array('_registration_details_metaboxes')
518
+				),
519
+				'require_nonce' => false,
520
+			),
521
+			'new_registration'  => array(
522
+				'nav'           => array(
523
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
524
+					'url'        => '#',
525
+					'order'      => 15,
526
+					'persistent' => false,
527
+				),
528
+				'metaboxes'     => $this->_default_espresso_metaboxes,
529
+				'labels'        => array(
530
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
531
+				),
532
+				'require_nonce' => false,
533
+			),
534
+			'add_new_attendee'  => array(
535
+				'nav'           => array(
536
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
537
+					'order'      => 15,
538
+					'persistent' => false,
539
+				),
540
+				'metaboxes'     => array_merge(
541
+					$this->_default_espresso_metaboxes,
542
+					array('_publish_post_box', 'attendee_editor_metaboxes')
543
+				),
544
+				'require_nonce' => false,
545
+			),
546
+			'edit_attendee'     => array(
547
+				'nav'           => array(
548
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
549
+					'order'      => 15,
550
+					'persistent' => false,
551
+					'url'        => isset($this->_req_data['ATT_ID'])
552
+						? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
553
+						: $this->_admin_base_url,
554
+				),
555
+				'metaboxes'     => array('attendee_editor_metaboxes'),
556
+				'require_nonce' => false,
557
+			),
558
+			'contact_list'      => array(
559
+				'nav'           => array(
560
+					'label' => esc_html__('Contact List', 'event_espresso'),
561
+					'order' => 20,
562
+				),
563
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
564
+				'help_tabs'     => array(
565
+					'registrations_contact_list_help_tab'                       => array(
566
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
567
+						'filename' => 'registrations_contact_list',
568
+					),
569
+					'registrations_contact-list_table_column_headings_help_tab' => array(
570
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
571
+						'filename' => 'registrations_contact_list_table_column_headings',
572
+					),
573
+					'registrations_contact_list_views_help_tab'                 => array(
574
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
575
+						'filename' => 'registrations_contact_list_views',
576
+					),
577
+					'registrations_contact_list_other_help_tab'                 => array(
578
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
579
+						'filename' => 'registrations_contact_list_other',
580
+					),
581
+				),
582
+				'help_tour'     => array('Contact_List_Help_Tour'),
583
+				'metaboxes'     => array(),
584
+				'require_nonce' => false,
585
+			),
586
+			//override default cpt routes
587
+			'create_new'        => '',
588
+			'edit'              => '',
589
+		);
590
+	}
591
+
592
+
593
+	/**
594
+	 * The below methods aren't used by this class currently
595
+	 */
596
+	protected function _add_screen_options()
597
+	{
598
+	}
599
+
600
+
601
+	protected function _add_feature_pointers()
602
+	{
603
+	}
604
+
605
+
606
+	public function admin_init()
607
+	{
608
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
609
+			'click "Update Registration Questions" to save your changes',
610
+			'event_espresso'
611
+		);
612
+	}
613
+
614
+
615
+	public function admin_notices()
616
+	{
617
+	}
618
+
619
+
620
+	public function admin_footer_scripts()
621
+	{
622
+	}
623
+
624
+
625
+	/**
626
+	 *        get list of registration statuses
627
+	 *
628
+	 * @access private
629
+	 * @return void
630
+	 */
631
+	private function _get_registration_status_array()
632
+	{
633
+		self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
634
+	}
635
+
636
+
637
+	protected function _add_screen_options_default()
638
+	{
639
+		$this->_per_page_screen_option();
640
+	}
641
+
642
+
643
+	protected function _add_screen_options_contact_list()
644
+	{
645
+		$page_title              = $this->_admin_page_title;
646
+		$this->_admin_page_title = esc_html__("Contacts", 'event_espresso');
647
+		$this->_per_page_screen_option();
648
+		$this->_admin_page_title = $page_title;
649
+	}
650
+
651
+
652
+	public function load_scripts_styles()
653
+	{
654
+		//style
655
+		wp_register_style(
656
+			'espresso_reg',
657
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
658
+			array('ee-admin-css'),
659
+			EVENT_ESPRESSO_VERSION
660
+		);
661
+		wp_enqueue_style('espresso_reg');
662
+		//script
663
+		wp_register_script(
664
+			'espresso_reg',
665
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
666
+			array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
667
+			EVENT_ESPRESSO_VERSION,
668
+			true
669
+		);
670
+		wp_enqueue_script('espresso_reg');
671
+	}
672
+
673
+
674
+	public function load_scripts_styles_edit_attendee()
675
+	{
676
+		//stuff to only show up on our attendee edit details page.
677
+		$attendee_details_translations = array(
678
+			'att_publish_text' => sprintf(
679
+				esc_html__('Created on: <b>%1$s</b>', 'event_espresso'),
680
+				$this->_cpt_model_obj->get_datetime('ATT_created')
681
+			),
682
+		);
683
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
684
+		wp_enqueue_script('jquery-validate');
685
+	}
686
+
687
+
688
+	public function load_scripts_styles_view_registration()
689
+	{
690
+		//styles
691
+		wp_enqueue_style('espresso-ui-theme');
692
+		//scripts
693
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
694
+		$this->_reg_custom_questions_form->wp_enqueue_scripts(true);
695
+	}
696
+
697
+
698
+	public function load_scripts_styles_contact_list()
699
+	{
700
+		wp_deregister_style('espresso_reg');
701
+		wp_register_style(
702
+			'espresso_att',
703
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
704
+			array('ee-admin-css'),
705
+			EVENT_ESPRESSO_VERSION
706
+		);
707
+		wp_enqueue_style('espresso_att');
708
+	}
709
+
710
+
711
+	public function load_scripts_styles_new_registration()
712
+	{
713
+		wp_register_script(
714
+			'ee-spco-for-admin',
715
+			REG_ASSETS_URL . 'spco_for_admin.js',
716
+			array('underscore', 'jquery'),
717
+			EVENT_ESPRESSO_VERSION,
718
+			true
719
+		);
720
+		wp_enqueue_script('ee-spco-for-admin');
721
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
722
+		EE_Form_Section_Proper::wp_enqueue_scripts();
723
+		EED_Ticket_Selector::load_tckt_slctr_assets();
724
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
725
+	}
726
+
727
+
728
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
729
+	{
730
+		add_filter('FHEE_load_EE_messages', '__return_true');
731
+	}
732
+
733
+
734
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
735
+	{
736
+		add_filter('FHEE_load_EE_messages', '__return_true');
737
+	}
738
+
739
+
740
+	protected function _set_list_table_views_default()
741
+	{
742
+		//for notification related bulk actions we need to make sure only active messengers have an option.
743
+		EED_Messages::set_autoloaders();
744
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
745
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
746
+		$active_mts               = $message_resource_manager->list_of_active_message_types();
747
+		//key= bulk_action_slug, value= message type.
748
+		$match_array = array(
749
+			'approve_registrations'    => 'registration',
750
+			'decline_registrations'    => 'declined_registration',
751
+			'pending_registrations'    => 'pending_approval',
752
+			'no_approve_registrations' => 'not_approved_registration',
753
+			'cancel_registrations'     => 'cancelled_registration',
754
+		);
755
+		$can_send = EE_Registry::instance()->CAP->current_user_can(
756
+			'ee_send_message',
757
+			'batch_send_messages'
758
+		);
759
+		/** setup reg status bulk actions **/
760
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
761
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
762
+				$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
763
+					'Approve and Notify Registrations',
764
+					'event_espresso'
765
+				);
766
+		}
767
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
768
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
769
+				$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
770
+					'Decline and Notify Registrations',
771
+					'event_espresso'
772
+				);
773
+		}
774
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
775
+			'Set Registrations to Pending Payment',
776
+			'event_espresso'
777
+		);
778
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
779
+				$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
780
+					'Set Registrations to Pending Payment and Notify',
781
+					'event_espresso'
782
+				);
783
+		}
784
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
785
+			'Set Registrations to Not Approved',
786
+			'event_espresso'
787
+		);
788
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
789
+				$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
790
+					'Set Registrations to Not Approved and Notify',
791
+					'event_espresso'
792
+				);
793
+		}
794
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
795
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
796
+				$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
797
+					'Cancel Registrations and Notify',
798
+					'event_espresso'
799
+				);
800
+		}
801
+		$def_reg_status_actions = apply_filters(
802
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
803
+			$def_reg_status_actions,
804
+			$active_mts
805
+		);
806
+
807
+		$this->_views = array(
808
+			'all'   => array(
809
+				'slug'        => 'all',
810
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
811
+				'count'       => 0,
812
+				'bulk_action' => array_merge($def_reg_status_actions, array(
813
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
814
+				)),
815
+			),
816
+			'month' => array(
817
+				'slug'        => 'month',
818
+				'label'       => esc_html__('This Month', 'event_espresso'),
819
+				'count'       => 0,
820
+				'bulk_action' => array_merge($def_reg_status_actions, array(
821
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
822
+				)),
823
+			),
824
+			'today' => array(
825
+				'slug'        => 'today',
826
+				'label'       => sprintf(
827
+					esc_html__('Today - %s', 'event_espresso'),
828
+					date('M d, Y', current_time('timestamp'))
829
+				),
830
+				'count'       => 0,
831
+				'bulk_action' => array_merge($def_reg_status_actions, array(
832
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
833
+				)),
834
+			),
835
+		);
836
+		if (EE_Registry::instance()->CAP->current_user_can(
837
+			'ee_delete_registrations',
838
+			'espresso_registrations_delete_registration'
839
+		)) {
840
+			$this->_views['incomplete'] = array(
841
+				'slug'        => 'incomplete',
842
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
843
+				'count'       => 0,
844
+				'bulk_action' => array(
845
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
846
+				),
847
+			);
848
+			$this->_views['trash']      = array(
849
+				'slug'        => 'trash',
850
+				'label'       => esc_html__('Trash', 'event_espresso'),
851
+				'count'       => 0,
852
+				'bulk_action' => array(
853
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
854
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
855
+				),
856
+			);
857
+		}
858
+	}
859
+
860
+
861
+	protected function _set_list_table_views_contact_list()
862
+	{
863
+		$this->_views = array(
864
+			'in_use' => array(
865
+				'slug'        => 'in_use',
866
+				'label'       => esc_html__('In Use', 'event_espresso'),
867
+				'count'       => 0,
868
+				'bulk_action' => array(
869
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
870
+				),
871
+			),
872
+		);
873
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_contacts',
874
+			'espresso_registrations_trash_attendees')
875
+		) {
876
+			$this->_views['trash'] = array(
877
+				'slug'        => 'trash',
878
+				'label'       => esc_html__('Trash', 'event_espresso'),
879
+				'count'       => 0,
880
+				'bulk_action' => array(
881
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
882
+				),
883
+			);
884
+		}
885
+	}
886
+
887
+
888
+	protected function _registration_legend_items()
889
+	{
890
+		$fc_items = array(
891
+			'star-icon'        => array(
892
+				'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
893
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
894
+			),
895
+			'view_details'     => array(
896
+				'class' => 'dashicons dashicons-clipboard',
897
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
898
+			),
899
+			'edit_attendee'    => array(
900
+				'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
901
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
902
+			),
903
+			'view_transaction' => array(
904
+				'class' => 'dashicons dashicons-cart',
905
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
906
+			),
907
+			'view_invoice'     => array(
908
+				'class' => 'dashicons dashicons-media-spreadsheet',
909
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
910
+			),
911
+		);
912
+		if (EE_Registry::instance()->CAP->current_user_can(
913
+			'ee_send_message',
914
+			'espresso_registrations_resend_registration'
915
+		)) {
916
+			$fc_items['resend_registration'] = array(
917
+				'class' => 'dashicons dashicons-email-alt',
918
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
919
+			);
920
+		} else {
921
+			$fc_items['blank'] = array('class' => 'blank', 'desc' => '');
922
+		}
923
+		if (EE_Registry::instance()->CAP->current_user_can(
924
+			'ee_read_global_messages',
925
+			'view_filtered_messages'
926
+		)) {
927
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
928
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
929
+				$fc_items['view_related_messages'] = array(
930
+					'class' => $related_for_icon['css_class'],
931
+					'desc'  => $related_for_icon['label'],
932
+				);
933
+			}
934
+		}
935
+		$sc_items = array(
936
+			'approved_status'   => array(
937
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
938
+				'desc'  => EEH_Template::pretty_status(
939
+					EEM_Registration::status_id_approved,
940
+					false,
941
+					'sentence'
942
+				),
943
+			),
944
+			'pending_status'    => array(
945
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
946
+				'desc'  => EEH_Template::pretty_status(
947
+					EEM_Registration::status_id_pending_payment,
948
+					false,
949
+					'sentence'
950
+				),
951
+			),
952
+			'wait_list'         => array(
953
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
954
+				'desc'  => EEH_Template::pretty_status(
955
+					EEM_Registration::status_id_wait_list,
956
+					false,
957
+					'sentence'
958
+				),
959
+			),
960
+			'incomplete_status' => array(
961
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
962
+				'desc'  => EEH_Template::pretty_status(
963
+					EEM_Registration::status_id_incomplete,
964
+					false,
965
+					'sentence'
966
+				),
967
+			),
968
+			'not_approved'      => array(
969
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
970
+				'desc'  => EEH_Template::pretty_status(
971
+					EEM_Registration::status_id_not_approved,
972
+					false,
973
+					'sentence'
974
+				),
975
+			),
976
+			'declined_status'   => array(
977
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
978
+				'desc'  => EEH_Template::pretty_status(
979
+					EEM_Registration::status_id_declined,
980
+					false,
981
+					'sentence'
982
+				),
983
+			),
984
+			'cancelled_status'  => array(
985
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
986
+				'desc'  => EEH_Template::pretty_status(
987
+					EEM_Registration::status_id_cancelled,
988
+					false,
989
+					'sentence'
990
+				),
991
+			),
992
+		);
993
+		return array_merge($fc_items, $sc_items);
994
+	}
995
+
996
+
997
+
998
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
999
+	/**
1000
+	 * @throws \EE_Error
1001
+	 */
1002
+	protected function _registrations_overview_list_table()
1003
+	{
1004
+		$this->_template_args['admin_page_header'] = '';
1005
+		$EVT_ID                                    = ! empty($this->_req_data['event_id'])
1006
+			? absint($this->_req_data['event_id'])
1007
+			: 0;
1008
+		if ($EVT_ID) {
1009
+			if (EE_Registry::instance()->CAP->current_user_can(
1010
+				'ee_edit_registrations',
1011
+				'espresso_registrations_new_registration',
1012
+				$EVT_ID
1013
+			)) {
1014
+				$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1015
+					'new_registration',
1016
+					'add-registrant',
1017
+					array('event_id' => $EVT_ID),
1018
+					'add-new-h2'
1019
+				);
1020
+			}
1021
+			$event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
1022
+			if ($event instanceof EE_Event) {
1023
+				$this->_template_args['admin_page_header'] = sprintf(
1024
+					esc_html__(
1025
+						'%s Viewing registrations for the event: %s%s',
1026
+						'event_espresso'
1027
+					),
1028
+					'<h3 style="line-height:1.5em;">',
1029
+					'<br /><a href="'
1030
+						. EE_Admin_Page::add_query_args_and_nonce(
1031
+							array(
1032
+								'action' => 'edit',
1033
+								'post'   => $event->ID(),
1034
+							),
1035
+							EVENTS_ADMIN_URL
1036
+						)
1037
+						. '">&nbsp;'
1038
+						. $event->get('EVT_name')
1039
+						. '&nbsp;</a>&nbsp;',
1040
+					'</h3>'
1041
+				);
1042
+			}
1043
+			$DTT_ID   = ! empty($this->_req_data['datetime_id']) ? absint($this->_req_data['datetime_id']) : 0;
1044
+			$datetime = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1045
+			if ($datetime instanceof EE_Datetime && $this->_template_args['admin_page_header'] !== '') {
1046
+				$this->_template_args['admin_page_header'] = substr(
1047
+					$this->_template_args['admin_page_header'],
1048
+					0,
1049
+					-5
1050
+				);
1051
+				$this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1052
+				$this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1053
+				$this->_template_args['admin_page_header'] .= $datetime->name();
1054
+				$this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1055
+				$this->_template_args['admin_page_header'] .= '</span></h3>';
1056
+			}
1057
+		}
1058
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1059
+		$this->display_admin_list_table_page_with_no_sidebar();
1060
+	}
1061
+
1062
+
1063
+	/**
1064
+	 * This sets the _registration property for the registration details screen
1065
+	 *
1066
+	 * @access private
1067
+	 * @return bool
1068
+	 */
1069
+	private function _set_registration_object()
1070
+	{
1071
+		//get out if we've already set the object
1072
+		if (is_object($this->_registration)) {
1073
+			return true;
1074
+		}
1075
+		$REG    = EEM_Registration::instance();
1076
+		$REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1077
+		if ($this->_registration = $REG->get_one_by_ID($REG_ID)) {
1078
+			return true;
1079
+		} else {
1080
+			$error_msg = sprintf(
1081
+				esc_html__(
1082
+					'An error occurred and the details for Registration ID #%s could not be retrieved.',
1083
+					'event_espresso'
1084
+				),
1085
+				$REG_ID
1086
+			);
1087
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1088
+			$this->_registration = null;
1089
+			return false;
1090
+		}
1091
+	}
1092
+
1093
+
1094
+	/**
1095
+	 * Used to retrieve registrations for the list table.
1096
+	 *
1097
+	 * @param int  $per_page
1098
+	 * @param bool $count
1099
+	 * @param bool $this_month
1100
+	 * @param bool $today
1101
+	 * @return EE_Registration[]|int
1102
+	 * @throws EE_Error
1103
+	 */
1104
+	public function get_registrations(
1105
+		$per_page = 10,
1106
+		$count = false,
1107
+		$this_month = false,
1108
+		$today = false
1109
+	) {
1110
+		if ($this_month) {
1111
+			$this->_req_data['status'] = 'month';
1112
+		}
1113
+		if ($today) {
1114
+			$this->_req_data['status'] = 'today';
1115
+		}
1116
+		$query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1117
+		/**
1118
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1119
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1120
+		 * @see EEM_Base::get_all()
1121
+		 */
1122
+		$query_params['group_by'] = '';
1123
+
1124
+		return $count
1125
+			? EEM_Registration::instance()->count($query_params)
1126
+			/** @type EE_Registration[] */
1127
+			: EEM_Registration::instance()->get_all($query_params);
1128
+	}
1129
+
1130
+
1131
+
1132
+	/**
1133
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1134
+	 * Note: this listens to values on the request for some of the query parameters.
1135
+	 *
1136
+	 * @param array $request
1137
+	 * @param int    $per_page
1138
+	 * @param bool   $count
1139
+	 * @return array
1140
+	 */
1141
+	protected function _get_registration_query_parameters(
1142
+		$request = array(),
1143
+		$per_page = 10,
1144
+		$count = false
1145
+	) {
1146
+
1147
+		$query_params = array(
1148
+			0                          => $this->_get_where_conditions_for_registrations_query(
1149
+				$request
1150
+			),
1151
+			'caps'                     => EEM_Registration::caps_read_admin,
1152
+			'default_where_conditions' => 'this_model_only',
1153
+		);
1154
+		if (! $count) {
1155
+			$query_params = array_merge(
1156
+				$query_params,
1157
+				$this->_get_orderby_for_registrations_query(),
1158
+				$this->_get_limit($per_page)
1159
+			);
1160
+		}
1161
+
1162
+		return $query_params;
1163
+	}
1164
+
1165
+
1166
+	/**
1167
+	 * This will add EVT_ID to the provided $where array for EE model query parameters.
1168
+	 *
1169
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1170
+	 * @return array
1171
+	 */
1172
+	protected function _add_event_id_to_where_conditions(array $request)
1173
+	{
1174
+		$where = array();
1175
+		if (! empty($request['event_id'])) {
1176
+			$where['EVT_ID'] = absint($request['event_id']);
1177
+		}
1178
+		return $where;
1179
+	}
1180
+
1181
+
1182
+	/**
1183
+	 * Adds category ID if it exists in the request to the where conditions for the registrations query.
1184
+	 *
1185
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1186
+	 * @return array
1187
+	 */
1188
+	protected function _add_category_id_to_where_conditions(array $request)
1189
+	{
1190
+		$where = array();
1191
+		if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1192
+			$where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1193
+		}
1194
+		return $where;
1195
+	}
1196
+
1197
+
1198
+	/**
1199
+	 * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
1200
+	 *
1201
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1202
+	 * @return array
1203
+	 */
1204
+	protected function _add_datetime_id_to_where_conditions(array $request)
1205
+	{
1206
+		$where = array();
1207
+		if (! empty($request['datetime_id'])) {
1208
+			$where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1209
+		}
1210
+		if (! empty($request['DTT_ID'])) {
1211
+			$where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1212
+		}
1213
+		return $where;
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * Adds the correct registration status to the where conditions for the registrations query.
1219
+	 *
1220
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1221
+	 * @return array
1222
+	 */
1223
+	protected function _add_registration_status_to_where_conditions(array $request)
1224
+	{
1225
+		$where = array();
1226
+		$view = EEH_Array::is_set($request, 'status', '');
1227
+		$registration_status = ! empty($request['_reg_status'])
1228
+			? sanitize_text_field($request['_reg_status'])
1229
+			: '';
1230
+
1231
+		/*
1232 1232
          * If filtering by registration status, then we show registrations matching that status.
1233 1233
          * If not filtering by specified status, then we show all registrations excluding incomplete registrations
1234 1234
          * UNLESS viewing trashed registrations.
1235 1235
          */
1236
-        if (! empty($registration_status)) {
1237
-            $where['STS_ID'] = $registration_status;
1238
-        } else {
1239
-            //make sure we exclude incomplete registrations, but only if not trashed.
1240
-            if ($view === 'trash') {
1241
-                $where['REG_deleted'] = true;
1242
-            } elseif ($view === 'incomplete') {
1243
-                $where['STS_ID'] = EEM_Registration::status_id_incomplete;
1244
-            } else {
1245
-                $where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
1246
-            }
1247
-        }
1248
-        return $where;
1249
-    }
1250
-
1251
-
1252
-    /**
1253
-     * Adds any provided date restraints to the where conditions for the registrations query.
1254
-     *
1255
-     * @param array $request usually the same as $this->_req_data but not necessarily
1256
-     * @return array
1257
-     * @throws EE_Error
1258
-     */
1259
-    protected function _add_date_to_where_conditions(array $request)
1260
-    {
1261
-        $where = array();
1262
-        $view = EEH_Array::is_set($request, 'status', '');
1263
-        $month_range             = ! empty($request['month_range'])
1264
-            ? sanitize_text_field($request['month_range'])
1265
-            : '';
1266
-        $retrieve_for_today      = $view === 'today';
1267
-        $retrieve_for_this_month = $view === 'month';
1268
-
1269
-        if ($retrieve_for_today) {
1270
-            $now               = date('Y-m-d', current_time('timestamp'));
1271
-            $where['REG_date'] = array(
1272
-                'BETWEEN',
1273
-                array(
1274
-                    EEM_Registration::instance()->convert_datetime_for_query(
1275
-                        'REG_date',
1276
-                        $now . ' 00:00:00',
1277
-                        'Y-m-d H:i:s'
1278
-                    ),
1279
-                    EEM_Registration::instance()->convert_datetime_for_query(
1280
-                        'REG_date',
1281
-                        $now . ' 23:59:59',
1282
-                        'Y-m-d H:i:s'
1283
-                    ),
1284
-                ),
1285
-            );
1286
-        } elseif ($retrieve_for_this_month) {
1287
-            $current_year_and_month = date('Y-m', current_time('timestamp'));
1288
-            $days_this_month        = date('t', current_time('timestamp'));
1289
-            $where['REG_date']      = array(
1290
-                'BETWEEN',
1291
-                array(
1292
-                    EEM_Registration::instance()->convert_datetime_for_query(
1293
-                        'REG_date',
1294
-                        $current_year_and_month . '-01 00:00:00',
1295
-                        'Y-m-d H:i:s'
1296
-                    ),
1297
-                    EEM_Registration::instance()->convert_datetime_for_query(
1298
-                        'REG_date',
1299
-                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1300
-                        'Y-m-d H:i:s'
1301
-                    ),
1302
-                ),
1303
-            );
1304
-        } elseif ($month_range) {
1305
-            $pieces          = explode(' ', $month_range, 3);
1306
-            $month_requested = ! empty($pieces[0])
1307
-                ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
1308
-                : '';
1309
-            $year_requested  = ! empty($pieces[1])
1310
-                ? $pieces[1]
1311
-                : '';
1312
-            //if there is not a month or year then we can't go further
1313
-            if ($month_requested && $year_requested) {
1314
-                $days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1315
-                $where['REG_date'] = array(
1316
-                    'BETWEEN',
1317
-                    array(
1318
-                        EEM_Registration::instance()->convert_datetime_for_query(
1319
-                            'REG_date',
1320
-                            $year_requested . '-' . $month_requested . '-01 00:00:00',
1321
-                            'Y-m-d H:i:s'
1322
-                        ),
1323
-                        EEM_Registration::instance()->convert_datetime_for_query(
1324
-                            'REG_date',
1325
-                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1326
-                            'Y-m-d H:i:s'
1327
-                        ),
1328
-                    ),
1329
-                );
1330
-            }
1331
-        }
1332
-        return $where;
1333
-    }
1334
-
1335
-
1336
-    /**
1337
-     * Adds any provided search restraints to the where conditions for the registrations query
1338
-     *
1339
-     * @param array $request usually the same as $this->_req_data but not necessarily
1340
-     * @return array
1341
-     */
1342
-    protected function _add_search_to_where_conditions(array $request)
1343
-    {
1344
-        $where = array();
1345
-        if (! empty($request['s'])) {
1346
-            $search_string = '%' . sanitize_text_field($request['s']) . '%';
1347
-            $where['OR*search_conditions'] = array(
1348
-                'Event.EVT_name'                          => array('LIKE', $search_string),
1349
-                'Event.EVT_desc'                          => array('LIKE', $search_string),
1350
-                'Event.EVT_short_desc'                    => array('LIKE', $search_string),
1351
-                'Attendee.ATT_full_name'                  => array('LIKE', $search_string),
1352
-                'Attendee.ATT_fname'                      => array('LIKE', $search_string),
1353
-                'Attendee.ATT_lname'                      => array('LIKE', $search_string),
1354
-                'Attendee.ATT_short_bio'                  => array('LIKE', $search_string),
1355
-                'Attendee.ATT_email'                      => array('LIKE', $search_string),
1356
-                'Attendee.ATT_address'                    => array('LIKE', $search_string),
1357
-                'Attendee.ATT_address2'                   => array('LIKE', $search_string),
1358
-                'Attendee.ATT_city'                       => array('LIKE', $search_string),
1359
-                'REG_final_price'                         => array('LIKE', $search_string),
1360
-                'REG_code'                                => array('LIKE', $search_string),
1361
-                'REG_count'                               => array('LIKE', $search_string),
1362
-                'REG_group_size'                          => array('LIKE', $search_string),
1363
-                'Ticket.TKT_name'                         => array('LIKE', $search_string),
1364
-                'Ticket.TKT_description'                  => array('LIKE', $search_string),
1365
-                'Transaction.Payment.PAY_txn_id_chq_nmbr' => array('LIKE', $search_string),
1366
-            );
1367
-        }
1368
-        return $where;
1369
-    }
1370
-
1371
-
1372
-    /**
1373
-     * Sets up the where conditions for the registrations query.
1374
-     *
1375
-     * @param array $request
1376
-     * @return array
1377
-     * @throws EE_Error
1378
-     */
1379
-    protected function _get_where_conditions_for_registrations_query($request)
1380
-    {
1381
-        return apply_filters(
1382
-            'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
1383
-            array_merge(
1384
-                $this->_add_event_id_to_where_conditions($request),
1385
-                $this->_add_category_id_to_where_conditions($request),
1386
-                $this->_add_datetime_id_to_where_conditions($request),
1387
-                $this->_add_registration_status_to_where_conditions($request),
1388
-                $this->_add_date_to_where_conditions($request),
1389
-                $this->_add_search_to_where_conditions($request)
1390
-            ),
1391
-            $request
1392
-        );
1393
-    }
1394
-
1395
-
1396
-    /**
1397
-     * Sets up the orderby for the registrations query.
1398
-     *
1399
-     * @return array
1400
-     */
1401
-    protected function _get_orderby_for_registrations_query()
1402
-    {
1403
-        $orderby_field = ! empty($this->_req_data['orderby'])
1404
-            ? sanitize_text_field($this->_req_data['orderby'])
1405
-            : '';
1406
-        switch ($orderby_field) {
1407
-            case '_REG_ID':
1408
-                $orderby_field = 'REG_ID';
1409
-                break;
1410
-            case '_Reg_status':
1411
-                $orderby_field = 'STS_ID';
1412
-                break;
1413
-            case 'ATT_fname':
1414
-                $orderby_field = array('Attendee.ATT_fname', 'Attendee.ATT_lname');
1415
-                break;
1416
-            case 'ATT_lname':
1417
-                $orderby_field = array('Attendee.ATT_lname', 'Attendee.ATT_fname');
1418
-                break;
1419
-            case 'event_name':
1420
-                $orderby_field = 'Event.EVT_name';
1421
-                break;
1422
-            case 'DTT_EVT_start':
1423
-                $orderby_field = 'Event.Datetime.DTT_EVT_start';
1424
-                break;
1425
-            default: //'REG_date'
1426
-                $orderby_field = 'REG_date';
1427
-        }
1428
-
1429
-        //order
1430
-        $order = ! empty($this->_req_data['order'])
1431
-            ? sanitize_text_field($this->_req_data['order'])
1432
-            : 'DESC';
1433
-
1434
-        //mutate orderby_field
1435
-        $orderby_field = array_combine(
1436
-            (array) $orderby_field,
1437
-            array_fill(0, count($orderby_field), $order)
1438
-        );
1439
-        return array('order_by' => $orderby_field);
1440
-    }
1441
-
1442
-
1443
-    /**
1444
-     * Sets up the limit for the registrations query.
1445
-     *
1446
-     * @param $per_page
1447
-     * @return array
1448
-     */
1449
-    protected function _get_limit($per_page)
1450
-    {
1451
-        $current_page = ! empty($this->_req_data['paged'])
1452
-            ? absint($this->_req_data['paged'])
1453
-            : 1;
1454
-        $per_page     = ! empty($this->_req_data['perpage'])
1455
-            ? $this->_req_data['perpage']
1456
-            : $per_page;
1457
-
1458
-        //-1 means return all results so get out if that's set.
1459
-        if ((int)$per_page === -1) {
1460
-            return array();
1461
-        }
1462
-        $per_page = absint($per_page);
1463
-        $offset   = ($current_page - 1) * $per_page;
1464
-        return array('limit' => array($offset, $per_page));
1465
-    }
1466
-
1467
-
1468
-    public function get_registration_status_array()
1469
-    {
1470
-        return self::$_reg_status;
1471
-    }
1472
-
1473
-
1474
-
1475
-
1476
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1477
-    /**
1478
-     *        generates HTML for the View Registration Details Admin page
1479
-     *
1480
-     * @access protected
1481
-     * @return void
1482
-     * @throws DomainException
1483
-     * @throws EE_Error
1484
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1485
-     */
1486
-    protected function _registration_details()
1487
-    {
1488
-        $this->_template_args = array();
1489
-        $this->_set_registration_object();
1490
-        if (is_object($this->_registration)) {
1491
-            $transaction                                   = $this->_registration->transaction()
1492
-                ? $this->_registration->transaction()
1493
-                : EE_Transaction::new_instance();
1494
-            $this->_session                                = $transaction->session_data();
1495
-            $event_id                                      = $this->_registration->event_ID();
1496
-            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1497
-            $this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1498
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1499
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1500
-            $this->_template_args['grand_total']           = $transaction->total();
1501
-            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1502
-            // link back to overview
1503
-            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1504
-            $this->_template_args['registration']                = $this->_registration;
1505
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1506
-                array(
1507
-                    'action'   => 'default',
1508
-                    'event_id' => $event_id,
1509
-                ),
1510
-                REG_ADMIN_URL
1511
-            );
1512
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1513
-                array(
1514
-                    'action' => 'default',
1515
-                    'EVT_ID' => $event_id,
1516
-                    'page'   => 'espresso_transactions',
1517
-                ),
1518
-                admin_url('admin.php')
1519
-            );
1520
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1521
-                array(
1522
-                    'page'   => 'espresso_events',
1523
-                    'action' => 'edit',
1524
-                    'post'   => $event_id,
1525
-                ),
1526
-                admin_url('admin.php')
1527
-            );
1528
-            //next and previous links
1529
-            $next_reg                                      = $this->_registration->next(
1530
-                null,
1531
-                array(),
1532
-                'REG_ID'
1533
-            );
1534
-            $this->_template_args['next_registration']     = $next_reg
1535
-                ? $this->_next_link(
1536
-                    EE_Admin_Page::add_query_args_and_nonce(
1537
-                        array(
1538
-                            'action'  => 'view_registration',
1539
-                            '_REG_ID' => $next_reg['REG_ID'],
1540
-                        ),
1541
-                        REG_ADMIN_URL
1542
-                    ),
1543
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1544
-                )
1545
-                : '';
1546
-            $previous_reg                                  = $this->_registration->previous(
1547
-                null,
1548
-                array(),
1549
-                'REG_ID'
1550
-            );
1551
-            $this->_template_args['previous_registration'] = $previous_reg
1552
-                ? $this->_previous_link(
1553
-                    EE_Admin_Page::add_query_args_and_nonce(
1554
-                        array(
1555
-                            'action'  => 'view_registration',
1556
-                            '_REG_ID' => $previous_reg['REG_ID'],
1557
-                        ),
1558
-                        REG_ADMIN_URL
1559
-                    ),
1560
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1561
-                )
1562
-                : '';
1563
-            // grab header
1564
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1565
-            $this->_template_args['REG_ID']            = $this->_registration->ID();
1566
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1567
-                $template_path,
1568
-                $this->_template_args,
1569
-                true
1570
-            );
1571
-        } else {
1572
-            $this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1573
-        }
1574
-        // the details template wrapper
1575
-        $this->display_admin_page_with_sidebar();
1576
-    }
1577
-
1578
-
1579
-    protected function _registration_details_metaboxes()
1580
-    {
1581
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1582
-        $this->_set_registration_object();
1583
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1584
-        add_meta_box('edit-reg-status-mbox', esc_html__('Registration Status', 'event_espresso'),
1585
-            array($this, 'set_reg_status_buttons_metabox'), $this->wp_page_slug, 'normal', 'high');
1586
-        add_meta_box('edit-reg-details-mbox', esc_html__('Registration Details', 'event_espresso'),
1587
-            array($this, '_reg_details_meta_box'), $this->wp_page_slug, 'normal', 'high');
1588
-        if ($attendee instanceof EE_Attendee
1589
-            && EE_Registry::instance()->CAP->current_user_can(
1590
-                'ee_edit_registration',
1591
-                'edit-reg-questions-mbox'
1592
-            )
1593
-        ) {
1594
-            add_meta_box(
1595
-                'edit-reg-questions-mbox',
1596
-                esc_html__('Registration Form Answers', 'event_espresso'),
1597
-                array($this, '_reg_questions_meta_box'),
1598
-                $this->wp_page_slug,
1599
-                'normal',
1600
-                'high'
1601
-            );
1602
-        }
1603
-        add_meta_box(
1604
-            'edit-reg-registrant-mbox',
1605
-            esc_html__('Contact Details', 'event_espresso'),
1606
-            array($this, '_reg_registrant_side_meta_box'),
1607
-            $this->wp_page_slug,
1608
-            'side',
1609
-            'high'
1610
-        );
1611
-        if ($this->_registration->group_size() > 1) {
1612
-            add_meta_box(
1613
-                'edit-reg-attendees-mbox',
1614
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1615
-                array($this, '_reg_attendees_meta_box'),
1616
-                $this->wp_page_slug,
1617
-                'normal',
1618
-                'high'
1619
-            );
1620
-        }
1621
-    }
1622
-
1623
-
1624
-    /**
1625
-     * set_reg_status_buttons_metabox
1626
-     *
1627
-     * @access protected
1628
-     * @return string
1629
-     * @throws \EE_Error
1630
-     */
1631
-    public function set_reg_status_buttons_metabox()
1632
-    {
1633
-        $this->_set_registration_object();
1634
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1635
-        echo $change_reg_status_form->form_open(
1636
-            self::add_query_args_and_nonce(
1637
-                array(
1638
-                    'action' => 'change_reg_status',
1639
-                ),
1640
-                REG_ADMIN_URL
1641
-            )
1642
-        );
1643
-        echo $change_reg_status_form->get_html();
1644
-        echo $change_reg_status_form->form_close();
1645
-    }
1646
-
1647
-
1648
-
1649
-    /**
1650
-     * @return EE_Form_Section_Proper
1651
-     * @throws EE_Error
1652
-     */
1653
-    protected function _generate_reg_status_change_form()
1654
-    {
1655
-        return new EE_Form_Section_Proper(array(
1656
-            'name'            => 'reg_status_change_form',
1657
-            'html_id'         => 'reg-status-change-form',
1658
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1659
-            'subsections'     => array(
1660
-                'return'             => new EE_Hidden_Input(array(
1661
-                    'name'    => 'return',
1662
-                    'default' => 'view_registration',
1663
-                )),
1664
-                'REG_ID'             => new EE_Hidden_Input(array(
1665
-                    'name'    => 'REG_ID',
1666
-                    'default' => $this->_registration->ID(),
1667
-                )),
1668
-                'current_status'     => new EE_Form_Section_HTML(
1669
-                    EEH_HTML::tr(
1670
-                        EEH_HTML::th(
1671
-                            EEH_HTML::label(
1672
-                                EEH_HTML::strong(esc_html__('Current Registration Status', 'event_espresso')
1673
-                                )
1674
-                            )
1675
-                        )
1676
-                        . EEH_HTML::td(
1677
-                            EEH_HTML::strong(
1678
-                                $this->_registration->pretty_status(),
1679
-                                '',
1680
-                                'status-' . $this->_registration->status_ID(),
1681
-                                'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1682
-                            )
1683
-                        )
1684
-                    )
1685
-                ),
1686
-                'reg_status'         => new EE_Select_Input(
1687
-                    $this->_get_reg_statuses(),
1688
-                    array(
1689
-                        'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1690
-                        'default'         => $this->_registration->status_ID(),
1691
-                    )
1692
-                ),
1693
-                'send_notifications' => new EE_Yes_No_Input(
1694
-                    array(
1695
-                        'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1696
-                        'default'         => false,
1697
-                        'html_help_text'  => esc_html__(
1698
-                            'If set to "Yes", then the related messages will be sent to the registrant.',
1699
-                            'event_espresso'
1700
-                        ),
1701
-                    )
1702
-                ),
1703
-                'submit'             => new EE_Submit_Input(
1704
-                    array(
1705
-                        'html_class'      => 'button-primary',
1706
-                        'html_label_text' => '&nbsp;',
1707
-                        'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1708
-                    )
1709
-                ),
1710
-            ),
1711
-        ));
1712
-    }
1713
-
1714
-
1715
-    /**
1716
-     * Returns an array of all the buttons for the various statuses and switch status actions
1717
-     *
1718
-     * @return array
1719
-     * @throws EE_Error
1720
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1721
-     */
1722
-    protected function _get_reg_statuses()
1723
-    {
1724
-        $reg_status_array = EEM_Registration::instance()->reg_status_array();
1725
-        unset ($reg_status_array[EEM_Registration::status_id_incomplete]);
1726
-        // get current reg status
1727
-        $current_status = $this->_registration->status_ID();
1728
-        // is registration for free event? This will determine whether to display the pending payment option
1729
-        if (
1730
-            $current_status !== EEM_Registration::status_id_pending_payment
1731
-            && $this->_registration->transaction()->is_free()
1732
-        ) {
1733
-            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1734
-        }
1735
-        return EEM_Status::instance()->localized_status($reg_status_array, false, 'sentence');
1736
-    }
1737
-
1738
-
1739
-
1740
-    /**
1741
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1742
-     *
1743
-     * @param bool $status REG status given for changing registrations to.
1744
-     * @param bool $notify Whether to send messages notifications or not.
1745
-     * @return array  (array with reg_id(s) updated and whether update was successful.
1746
-     * @throws \EE_Error
1747
-     */
1748
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1749
-    {
1750
-        if (isset($this->_req_data['reg_status_change_form'])) {
1751
-            $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1752
-                ? (array)$this->_req_data['reg_status_change_form']['REG_ID'] : array();
1753
-        } else {
1754
-            $REG_IDs = isset($this->_req_data['_REG_ID']) ? (array)$this->_req_data['_REG_ID'] : array();
1755
-        }
1756
-        $success = $this->_set_registration_status($REG_IDs, $status);
1757
-        //notify?
1758
-        if ($success
1759
-            && $notify
1760
-            && EE_Registry::instance()->CAP->current_user_can(
1761
-                'ee_send_message',
1762
-                'espresso_registrations_resend_registration'
1763
-            )
1764
-        ) {
1765
-            $this->_process_resend_registration();
1766
-        }
1767
-        return $success;
1768
-    }
1769
-
1770
-
1771
-
1772
-    /**
1773
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1774
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1775
-     *
1776
-     * @param array $REG_IDs
1777
-     * @param bool  $status
1778
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1779
-     * @throws \RuntimeException
1780
-     * @throws \EE_Error
1781
-     *               the array of updated registrations).
1782
-     * @throws EE_Error
1783
-     * @throws RuntimeException
1784
-     */
1785
-    protected function _set_registration_status($REG_IDs = array(), $status = false)
1786
-    {
1787
-        $success = false;
1788
-        // typecast $REG_IDs
1789
-        $REG_IDs = (array)$REG_IDs;
1790
-        if ( ! empty($REG_IDs)) {
1791
-            $success = true;
1792
-            // set default status if none is passed
1793
-            $status = $status ? $status : EEM_Registration::status_id_pending_payment;
1794
-            // sanitize $REG_IDs
1795
-            $REG_IDs = array_filter($REG_IDs, 'absint');
1796
-            //loop through REG_ID's and change status
1797
-            foreach ($REG_IDs as $REG_ID) {
1798
-                $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1799
-                if ($registration instanceof EE_Registration) {
1800
-                    $registration->set_status($status);
1801
-                    $result = $registration->save();
1802
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1803
-                    $success = $result !== false ? $success : false;
1804
-                }
1805
-            }
1806
-        }
1807
-        //reset _req_data['_REG_ID'] for any potential future messages notifications
1808
-        $this->_req_data['_REG_ID'] = $REG_IDs;
1809
-        //return $success and processed registrations
1810
-        return array('REG_ID' => $REG_IDs, 'success' => $success);
1811
-    }
1812
-
1813
-
1814
-    /**
1815
-     * Common logic for setting up success message and redirecting to appropriate route
1816
-     *
1817
-     * @param  string $STS_ID status id for the registration changed to
1818
-     * @param   bool  $notify indicates whether the _set_registration_status_from_request does notifications or not.
1819
-     * @return void
1820
-     */
1821
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1822
-    {
1823
-        $result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1824
-            : array('success' => false);
1825
-        $success = isset($result['success']) && $result['success'];
1826
-        //setup success message
1827
-        if ($success) {
1828
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1829
-                $msg = sprintf(esc_html__('Registration status has been set to %s', 'event_espresso'),
1830
-                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1831
-            } else {
1832
-                $msg = sprintf(esc_html__('Registrations have been set to %s.', 'event_espresso'),
1833
-                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1834
-            }
1835
-            EE_Error::add_success($msg);
1836
-        } else {
1837
-            EE_Error::add_error(
1838
-                esc_html__(
1839
-                    'Something went wrong, and the status was not changed',
1840
-                    'event_espresso'
1841
-                ), __FILE__, __LINE__, __FUNCTION__
1842
-            );
1843
-        }
1844
-        if (isset($this->_req_data['return']) && $this->_req_data['return'] == 'view_registration') {
1845
-            $route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1846
-        } else {
1847
-            $route = array('action' => 'default');
1848
-        }
1849
-        //unset nonces
1850
-        foreach ($this->_req_data as $ref => $value) {
1851
-            if (strpos($ref, 'nonce') !== false) {
1852
-                unset($this->_req_data[$ref]);
1853
-                continue;
1854
-            }
1855
-            $value                 = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
1856
-            $this->_req_data[$ref] = $value;
1857
-        }
1858
-        //merge request vars so that the reloaded list table contains any existing filter query params
1859
-        $route = array_merge($this->_req_data, $route);
1860
-        $this->_redirect_after_action($success, '', '', $route, true);
1861
-    }
1862
-
1863
-
1864
-    /**
1865
-     * incoming reg status change from reg details page.
1866
-     *
1867
-     * @return void
1868
-     */
1869
-    protected function _change_reg_status()
1870
-    {
1871
-        $this->_req_data['return'] = 'view_registration';
1872
-        //set notify based on whether the send notifications toggle is set or not
1873
-        $notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1874
-        //$notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1875
-        $this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1876
-            ? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1877
-        switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1878
-            case EEM_Registration::status_id_approved :
1879
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence') :
1880
-                $this->approve_registration($notify);
1881
-                break;
1882
-            case EEM_Registration::status_id_pending_payment :
1883
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence') :
1884
-                $this->pending_registration($notify);
1885
-                break;
1886
-            case EEM_Registration::status_id_not_approved :
1887
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence') :
1888
-                $this->not_approve_registration($notify);
1889
-                break;
1890
-            case EEM_Registration::status_id_declined :
1891
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence') :
1892
-                $this->decline_registration($notify);
1893
-                break;
1894
-            case EEM_Registration::status_id_cancelled :
1895
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence') :
1896
-                $this->cancel_registration($notify);
1897
-                break;
1898
-            case EEM_Registration::status_id_wait_list :
1899
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence') :
1900
-                $this->wait_list_registration($notify);
1901
-                break;
1902
-            case EEM_Registration::status_id_incomplete :
1903
-            default :
1904
-                $result['success'] = false;
1905
-                unset($this->_req_data['return']);
1906
-                $this->_reg_status_change_return('', false);
1907
-                break;
1908
-        }
1909
-    }
1910
-
1911
-
1912
-    /**
1913
-     * Callback for bulk action routes.
1914
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1915
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
1916
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1917
-     * when an action is happening on just a single registration).
1918
-     * @param      $action
1919
-     * @param bool $notify
1920
-     */
1921
-    protected function bulk_action_on_registrations($action, $notify = false) {
1922
-        do_action(
1923
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1924
-            $this,
1925
-            $action,
1926
-            $notify
1927
-        );
1928
-        $method = $action . '_registration';
1929
-        if (method_exists($this, $method)) {
1930
-            $this->$method($notify);
1931
-        }
1932
-    }
1933
-
1934
-
1935
-    /**
1936
-     * approve_registration
1937
-     *
1938
-     * @access protected
1939
-     * @param bool $notify whether or not to notify the registrant about their approval.
1940
-     * @return void
1941
-     */
1942
-    protected function approve_registration($notify = false)
1943
-    {
1944
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1945
-    }
1946
-
1947
-
1948
-    /**
1949
-     *        decline_registration
1950
-     *
1951
-     * @access protected
1952
-     * @param bool $notify whether or not to notify the registrant about their status change.
1953
-     * @return void
1954
-     */
1955
-    protected function decline_registration($notify = false)
1956
-    {
1957
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1958
-    }
1959
-
1960
-
1961
-    /**
1962
-     *        cancel_registration
1963
-     *
1964
-     * @access protected
1965
-     * @param bool $notify whether or not to notify the registrant about their status change.
1966
-     * @return void
1967
-     */
1968
-    protected function cancel_registration($notify = false)
1969
-    {
1970
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1971
-    }
1972
-
1973
-
1974
-    /**
1975
-     *        not_approve_registration
1976
-     *
1977
-     * @access protected
1978
-     * @param bool $notify whether or not to notify the registrant about their status change.
1979
-     * @return void
1980
-     */
1981
-    protected function not_approve_registration($notify = false)
1982
-    {
1983
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1984
-    }
1985
-
1986
-
1987
-    /**
1988
-     *        decline_registration
1989
-     *
1990
-     * @access protected
1991
-     * @param bool $notify whether or not to notify the registrant about their status change.
1992
-     * @return void
1993
-     */
1994
-    protected function pending_registration($notify = false)
1995
-    {
1996
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1997
-    }
1998
-
1999
-
2000
-    /**
2001
-     * waitlist_registration
2002
-     *
2003
-     * @access protected
2004
-     * @param bool $notify whether or not to notify the registrant about their status change.
2005
-     * @return void
2006
-     */
2007
-    protected function wait_list_registration($notify = false)
2008
-    {
2009
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
2010
-    }
2011
-
2012
-
2013
-    /**
2014
-     *        generates HTML for the Registration main meta box
2015
-     *
2016
-     * @access public
2017
-     * @return void
2018
-     * @throws DomainException
2019
-     * @throws EE_Error
2020
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
2021
-     */
2022
-    public function _reg_details_meta_box()
2023
-    {
2024
-        EEH_Autoloader::register_line_item_display_autoloaders();
2025
-        EEH_Autoloader::register_line_item_filter_autoloaders();
2026
-        EE_Registry::instance()->load_helper('Line_Item');
2027
-        $transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2028
-            : EE_Transaction::new_instance();
2029
-        $this->_session = $transaction->session_data();
2030
-        $filters        = new EE_Line_Item_Filter_Collection();
2031
-        //$filters->add( new EE_Non_Zero_Line_Item_Filter() );
2032
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2033
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor($filters,
2034
-            $transaction->total_line_item());
2035
-        $filtered_line_item_tree                 = $line_item_filter_processor->process();
2036
-        $line_item_display                       = new EE_Line_Item_Display('reg_admin_table',
2037
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
2038
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2039
-            $filtered_line_item_tree,
2040
-            array('EE_Registration' => $this->_registration)
2041
-        );
2042
-        $attendee                                = $this->_registration->attendee();
2043
-        if (EE_Registry::instance()->CAP->current_user_can(
2044
-            'ee_read_transaction',
2045
-            'espresso_transactions_view_transaction'
2046
-        )) {
2047
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2048
-                EE_Admin_Page::add_query_args_and_nonce(
2049
-                    array(
2050
-                        'action' => 'view_transaction',
2051
-                        'TXN_ID' => $transaction->ID(),
2052
-                    ),
2053
-                    TXN_ADMIN_URL
2054
-                ),
2055
-                esc_html__(' View Transaction', 'event_espresso'),
2056
-                'button secondary-button right',
2057
-                'dashicons dashicons-cart'
2058
-            );
2059
-        } else {
2060
-            $this->_template_args['view_transaction_button'] = '';
2061
-        }
2062
-        if ($attendee instanceof EE_Attendee
2063
-            && EE_Registry::instance()->CAP->current_user_can(
2064
-                'ee_send_message',
2065
-                'espresso_registrations_resend_registration'
2066
-            )
2067
-        ) {
2068
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2069
-                EE_Admin_Page::add_query_args_and_nonce(
2070
-                    array(
2071
-                        'action'      => 'resend_registration',
2072
-                        '_REG_ID'     => $this->_registration->ID(),
2073
-                        'redirect_to' => 'view_registration',
2074
-                    ),
2075
-                    REG_ADMIN_URL
2076
-                ),
2077
-                esc_html__(' Resend Registration', 'event_espresso'),
2078
-                'button secondary-button right',
2079
-                'dashicons dashicons-email-alt'
2080
-            );
2081
-        } else {
2082
-            $this->_template_args['resend_registration_button'] = '';
2083
-        }
2084
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2085
-        $payment                               = $transaction->get_first_related('Payment');
2086
-        $payment                               = ! $payment instanceof EE_Payment
2087
-            ? EE_Payment::new_instance()
2088
-            : $payment;
2089
-        $payment_method                        = $payment->get_first_related('Payment_Method');
2090
-        $payment_method                        = ! $payment_method instanceof EE_Payment_Method
2091
-            ? EE_Payment_Method::new_instance()
2092
-            : $payment_method;
2093
-        $reg_details                           = array(
2094
-            'payment_method'       => $payment_method->name(),
2095
-            'response_msg'         => $payment->gateway_response(),
2096
-            'registration_id'      => $this->_registration->get('REG_code'),
2097
-            'registration_session' => $this->_registration->session_ID(),
2098
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2099
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2100
-        );
2101
-        if (isset($reg_details['registration_id'])) {
2102
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2103
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2104
-                'Registration ID',
2105
-                'event_espresso'
2106
-            );
2107
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2108
-        }
2109
-        if (isset($reg_details['payment_method'])) {
2110
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2111
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2112
-                'Most Recent Payment Method',
2113
-                'event_espresso'
2114
-            );
2115
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2116
-            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2117
-            $this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2118
-                'Payment method response',
2119
-                'event_espresso'
2120
-            );
2121
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2122
-        }
2123
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2124
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2125
-            'Registration Session',
2126
-            'event_espresso'
2127
-        );
2128
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2129
-        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2130
-        $this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2131
-            'Registration placed from IP',
2132
-            'event_espresso'
2133
-        );
2134
-        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2135
-        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2136
-        $this->_template_args['reg_details']['user_agent']['label']           = esc_html__('Registrant User Agent',
2137
-            'event_espresso');
2138
-        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2139
-        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2140
-            array(
2141
-                'action'   => 'default',
2142
-                'event_id' => $this->_registration->event_ID(),
2143
-            ),
2144
-            REG_ADMIN_URL
2145
-        );
2146
-        $this->_template_args['REG_ID']                                       = $this->_registration->ID();
2147
-        $this->_template_args['event_id']                                     = $this->_registration->event_ID();
2148
-        $template_path                                                        =
2149
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2150
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2151
-    }
2152
-
2153
-
2154
-    /**
2155
-     * generates HTML for the Registration Questions meta box.
2156
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2157
-     * otherwise uses new forms system
2158
-     *
2159
-     * @access public
2160
-     * @return void
2161
-     * @throws DomainException
2162
-     * @throws EE_Error
2163
-     */
2164
-    public function _reg_questions_meta_box()
2165
-    {
2166
-        //allow someone to override this method entirely
2167
-        if (apply_filters('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', true, $this,
2168
-            $this->_registration)) {
2169
-            $form                                              = $this->_get_reg_custom_questions_form(
2170
-                $this->_registration->ID()
2171
-            );
2172
-            $this->_template_args['att_questions']             = count($form->subforms()) > 0
2173
-                ? $form->get_html_and_js()
2174
-                : '';
2175
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2176
-            $this->_template_args['REG_ID']                    = $this->_registration->ID();
2177
-            $template_path                                     =
2178
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2179
-            echo EEH_Template::display_template($template_path, $this->_template_args, true);
2180
-        }
2181
-    }
2182
-
2183
-
2184
-    /**
2185
-     * form_before_question_group
2186
-     *
2187
-     * @deprecated    as of 4.8.32.rc.000
2188
-     * @access        public
2189
-     * @param        string $output
2190
-     * @return        string
2191
-     */
2192
-    public function form_before_question_group($output)
2193
-    {
2194
-        EE_Error::doing_it_wrong(
2195
-            __CLASS__ . '::' . __FUNCTION__,
2196
-            esc_html__(
2197
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2198
-                'event_espresso'
2199
-            ),
2200
-            '4.8.32.rc.000'
2201
-        );
2202
-        return '
1236
+		if (! empty($registration_status)) {
1237
+			$where['STS_ID'] = $registration_status;
1238
+		} else {
1239
+			//make sure we exclude incomplete registrations, but only if not trashed.
1240
+			if ($view === 'trash') {
1241
+				$where['REG_deleted'] = true;
1242
+			} elseif ($view === 'incomplete') {
1243
+				$where['STS_ID'] = EEM_Registration::status_id_incomplete;
1244
+			} else {
1245
+				$where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
1246
+			}
1247
+		}
1248
+		return $where;
1249
+	}
1250
+
1251
+
1252
+	/**
1253
+	 * Adds any provided date restraints to the where conditions for the registrations query.
1254
+	 *
1255
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1256
+	 * @return array
1257
+	 * @throws EE_Error
1258
+	 */
1259
+	protected function _add_date_to_where_conditions(array $request)
1260
+	{
1261
+		$where = array();
1262
+		$view = EEH_Array::is_set($request, 'status', '');
1263
+		$month_range             = ! empty($request['month_range'])
1264
+			? sanitize_text_field($request['month_range'])
1265
+			: '';
1266
+		$retrieve_for_today      = $view === 'today';
1267
+		$retrieve_for_this_month = $view === 'month';
1268
+
1269
+		if ($retrieve_for_today) {
1270
+			$now               = date('Y-m-d', current_time('timestamp'));
1271
+			$where['REG_date'] = array(
1272
+				'BETWEEN',
1273
+				array(
1274
+					EEM_Registration::instance()->convert_datetime_for_query(
1275
+						'REG_date',
1276
+						$now . ' 00:00:00',
1277
+						'Y-m-d H:i:s'
1278
+					),
1279
+					EEM_Registration::instance()->convert_datetime_for_query(
1280
+						'REG_date',
1281
+						$now . ' 23:59:59',
1282
+						'Y-m-d H:i:s'
1283
+					),
1284
+				),
1285
+			);
1286
+		} elseif ($retrieve_for_this_month) {
1287
+			$current_year_and_month = date('Y-m', current_time('timestamp'));
1288
+			$days_this_month        = date('t', current_time('timestamp'));
1289
+			$where['REG_date']      = array(
1290
+				'BETWEEN',
1291
+				array(
1292
+					EEM_Registration::instance()->convert_datetime_for_query(
1293
+						'REG_date',
1294
+						$current_year_and_month . '-01 00:00:00',
1295
+						'Y-m-d H:i:s'
1296
+					),
1297
+					EEM_Registration::instance()->convert_datetime_for_query(
1298
+						'REG_date',
1299
+						$current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1300
+						'Y-m-d H:i:s'
1301
+					),
1302
+				),
1303
+			);
1304
+		} elseif ($month_range) {
1305
+			$pieces          = explode(' ', $month_range, 3);
1306
+			$month_requested = ! empty($pieces[0])
1307
+				? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
1308
+				: '';
1309
+			$year_requested  = ! empty($pieces[1])
1310
+				? $pieces[1]
1311
+				: '';
1312
+			//if there is not a month or year then we can't go further
1313
+			if ($month_requested && $year_requested) {
1314
+				$days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1315
+				$where['REG_date'] = array(
1316
+					'BETWEEN',
1317
+					array(
1318
+						EEM_Registration::instance()->convert_datetime_for_query(
1319
+							'REG_date',
1320
+							$year_requested . '-' . $month_requested . '-01 00:00:00',
1321
+							'Y-m-d H:i:s'
1322
+						),
1323
+						EEM_Registration::instance()->convert_datetime_for_query(
1324
+							'REG_date',
1325
+							$year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1326
+							'Y-m-d H:i:s'
1327
+						),
1328
+					),
1329
+				);
1330
+			}
1331
+		}
1332
+		return $where;
1333
+	}
1334
+
1335
+
1336
+	/**
1337
+	 * Adds any provided search restraints to the where conditions for the registrations query
1338
+	 *
1339
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1340
+	 * @return array
1341
+	 */
1342
+	protected function _add_search_to_where_conditions(array $request)
1343
+	{
1344
+		$where = array();
1345
+		if (! empty($request['s'])) {
1346
+			$search_string = '%' . sanitize_text_field($request['s']) . '%';
1347
+			$where['OR*search_conditions'] = array(
1348
+				'Event.EVT_name'                          => array('LIKE', $search_string),
1349
+				'Event.EVT_desc'                          => array('LIKE', $search_string),
1350
+				'Event.EVT_short_desc'                    => array('LIKE', $search_string),
1351
+				'Attendee.ATT_full_name'                  => array('LIKE', $search_string),
1352
+				'Attendee.ATT_fname'                      => array('LIKE', $search_string),
1353
+				'Attendee.ATT_lname'                      => array('LIKE', $search_string),
1354
+				'Attendee.ATT_short_bio'                  => array('LIKE', $search_string),
1355
+				'Attendee.ATT_email'                      => array('LIKE', $search_string),
1356
+				'Attendee.ATT_address'                    => array('LIKE', $search_string),
1357
+				'Attendee.ATT_address2'                   => array('LIKE', $search_string),
1358
+				'Attendee.ATT_city'                       => array('LIKE', $search_string),
1359
+				'REG_final_price'                         => array('LIKE', $search_string),
1360
+				'REG_code'                                => array('LIKE', $search_string),
1361
+				'REG_count'                               => array('LIKE', $search_string),
1362
+				'REG_group_size'                          => array('LIKE', $search_string),
1363
+				'Ticket.TKT_name'                         => array('LIKE', $search_string),
1364
+				'Ticket.TKT_description'                  => array('LIKE', $search_string),
1365
+				'Transaction.Payment.PAY_txn_id_chq_nmbr' => array('LIKE', $search_string),
1366
+			);
1367
+		}
1368
+		return $where;
1369
+	}
1370
+
1371
+
1372
+	/**
1373
+	 * Sets up the where conditions for the registrations query.
1374
+	 *
1375
+	 * @param array $request
1376
+	 * @return array
1377
+	 * @throws EE_Error
1378
+	 */
1379
+	protected function _get_where_conditions_for_registrations_query($request)
1380
+	{
1381
+		return apply_filters(
1382
+			'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
1383
+			array_merge(
1384
+				$this->_add_event_id_to_where_conditions($request),
1385
+				$this->_add_category_id_to_where_conditions($request),
1386
+				$this->_add_datetime_id_to_where_conditions($request),
1387
+				$this->_add_registration_status_to_where_conditions($request),
1388
+				$this->_add_date_to_where_conditions($request),
1389
+				$this->_add_search_to_where_conditions($request)
1390
+			),
1391
+			$request
1392
+		);
1393
+	}
1394
+
1395
+
1396
+	/**
1397
+	 * Sets up the orderby for the registrations query.
1398
+	 *
1399
+	 * @return array
1400
+	 */
1401
+	protected function _get_orderby_for_registrations_query()
1402
+	{
1403
+		$orderby_field = ! empty($this->_req_data['orderby'])
1404
+			? sanitize_text_field($this->_req_data['orderby'])
1405
+			: '';
1406
+		switch ($orderby_field) {
1407
+			case '_REG_ID':
1408
+				$orderby_field = 'REG_ID';
1409
+				break;
1410
+			case '_Reg_status':
1411
+				$orderby_field = 'STS_ID';
1412
+				break;
1413
+			case 'ATT_fname':
1414
+				$orderby_field = array('Attendee.ATT_fname', 'Attendee.ATT_lname');
1415
+				break;
1416
+			case 'ATT_lname':
1417
+				$orderby_field = array('Attendee.ATT_lname', 'Attendee.ATT_fname');
1418
+				break;
1419
+			case 'event_name':
1420
+				$orderby_field = 'Event.EVT_name';
1421
+				break;
1422
+			case 'DTT_EVT_start':
1423
+				$orderby_field = 'Event.Datetime.DTT_EVT_start';
1424
+				break;
1425
+			default: //'REG_date'
1426
+				$orderby_field = 'REG_date';
1427
+		}
1428
+
1429
+		//order
1430
+		$order = ! empty($this->_req_data['order'])
1431
+			? sanitize_text_field($this->_req_data['order'])
1432
+			: 'DESC';
1433
+
1434
+		//mutate orderby_field
1435
+		$orderby_field = array_combine(
1436
+			(array) $orderby_field,
1437
+			array_fill(0, count($orderby_field), $order)
1438
+		);
1439
+		return array('order_by' => $orderby_field);
1440
+	}
1441
+
1442
+
1443
+	/**
1444
+	 * Sets up the limit for the registrations query.
1445
+	 *
1446
+	 * @param $per_page
1447
+	 * @return array
1448
+	 */
1449
+	protected function _get_limit($per_page)
1450
+	{
1451
+		$current_page = ! empty($this->_req_data['paged'])
1452
+			? absint($this->_req_data['paged'])
1453
+			: 1;
1454
+		$per_page     = ! empty($this->_req_data['perpage'])
1455
+			? $this->_req_data['perpage']
1456
+			: $per_page;
1457
+
1458
+		//-1 means return all results so get out if that's set.
1459
+		if ((int)$per_page === -1) {
1460
+			return array();
1461
+		}
1462
+		$per_page = absint($per_page);
1463
+		$offset   = ($current_page - 1) * $per_page;
1464
+		return array('limit' => array($offset, $per_page));
1465
+	}
1466
+
1467
+
1468
+	public function get_registration_status_array()
1469
+	{
1470
+		return self::$_reg_status;
1471
+	}
1472
+
1473
+
1474
+
1475
+
1476
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1477
+	/**
1478
+	 *        generates HTML for the View Registration Details Admin page
1479
+	 *
1480
+	 * @access protected
1481
+	 * @return void
1482
+	 * @throws DomainException
1483
+	 * @throws EE_Error
1484
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1485
+	 */
1486
+	protected function _registration_details()
1487
+	{
1488
+		$this->_template_args = array();
1489
+		$this->_set_registration_object();
1490
+		if (is_object($this->_registration)) {
1491
+			$transaction                                   = $this->_registration->transaction()
1492
+				? $this->_registration->transaction()
1493
+				: EE_Transaction::new_instance();
1494
+			$this->_session                                = $transaction->session_data();
1495
+			$event_id                                      = $this->_registration->event_ID();
1496
+			$this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1497
+			$this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1498
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1499
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1500
+			$this->_template_args['grand_total']           = $transaction->total();
1501
+			$this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1502
+			// link back to overview
1503
+			$this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1504
+			$this->_template_args['registration']                = $this->_registration;
1505
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1506
+				array(
1507
+					'action'   => 'default',
1508
+					'event_id' => $event_id,
1509
+				),
1510
+				REG_ADMIN_URL
1511
+			);
1512
+			$this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1513
+				array(
1514
+					'action' => 'default',
1515
+					'EVT_ID' => $event_id,
1516
+					'page'   => 'espresso_transactions',
1517
+				),
1518
+				admin_url('admin.php')
1519
+			);
1520
+			$this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1521
+				array(
1522
+					'page'   => 'espresso_events',
1523
+					'action' => 'edit',
1524
+					'post'   => $event_id,
1525
+				),
1526
+				admin_url('admin.php')
1527
+			);
1528
+			//next and previous links
1529
+			$next_reg                                      = $this->_registration->next(
1530
+				null,
1531
+				array(),
1532
+				'REG_ID'
1533
+			);
1534
+			$this->_template_args['next_registration']     = $next_reg
1535
+				? $this->_next_link(
1536
+					EE_Admin_Page::add_query_args_and_nonce(
1537
+						array(
1538
+							'action'  => 'view_registration',
1539
+							'_REG_ID' => $next_reg['REG_ID'],
1540
+						),
1541
+						REG_ADMIN_URL
1542
+					),
1543
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1544
+				)
1545
+				: '';
1546
+			$previous_reg                                  = $this->_registration->previous(
1547
+				null,
1548
+				array(),
1549
+				'REG_ID'
1550
+			);
1551
+			$this->_template_args['previous_registration'] = $previous_reg
1552
+				? $this->_previous_link(
1553
+					EE_Admin_Page::add_query_args_and_nonce(
1554
+						array(
1555
+							'action'  => 'view_registration',
1556
+							'_REG_ID' => $previous_reg['REG_ID'],
1557
+						),
1558
+						REG_ADMIN_URL
1559
+					),
1560
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1561
+				)
1562
+				: '';
1563
+			// grab header
1564
+			$template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1565
+			$this->_template_args['REG_ID']            = $this->_registration->ID();
1566
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1567
+				$template_path,
1568
+				$this->_template_args,
1569
+				true
1570
+			);
1571
+		} else {
1572
+			$this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1573
+		}
1574
+		// the details template wrapper
1575
+		$this->display_admin_page_with_sidebar();
1576
+	}
1577
+
1578
+
1579
+	protected function _registration_details_metaboxes()
1580
+	{
1581
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1582
+		$this->_set_registration_object();
1583
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1584
+		add_meta_box('edit-reg-status-mbox', esc_html__('Registration Status', 'event_espresso'),
1585
+			array($this, 'set_reg_status_buttons_metabox'), $this->wp_page_slug, 'normal', 'high');
1586
+		add_meta_box('edit-reg-details-mbox', esc_html__('Registration Details', 'event_espresso'),
1587
+			array($this, '_reg_details_meta_box'), $this->wp_page_slug, 'normal', 'high');
1588
+		if ($attendee instanceof EE_Attendee
1589
+			&& EE_Registry::instance()->CAP->current_user_can(
1590
+				'ee_edit_registration',
1591
+				'edit-reg-questions-mbox'
1592
+			)
1593
+		) {
1594
+			add_meta_box(
1595
+				'edit-reg-questions-mbox',
1596
+				esc_html__('Registration Form Answers', 'event_espresso'),
1597
+				array($this, '_reg_questions_meta_box'),
1598
+				$this->wp_page_slug,
1599
+				'normal',
1600
+				'high'
1601
+			);
1602
+		}
1603
+		add_meta_box(
1604
+			'edit-reg-registrant-mbox',
1605
+			esc_html__('Contact Details', 'event_espresso'),
1606
+			array($this, '_reg_registrant_side_meta_box'),
1607
+			$this->wp_page_slug,
1608
+			'side',
1609
+			'high'
1610
+		);
1611
+		if ($this->_registration->group_size() > 1) {
1612
+			add_meta_box(
1613
+				'edit-reg-attendees-mbox',
1614
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1615
+				array($this, '_reg_attendees_meta_box'),
1616
+				$this->wp_page_slug,
1617
+				'normal',
1618
+				'high'
1619
+			);
1620
+		}
1621
+	}
1622
+
1623
+
1624
+	/**
1625
+	 * set_reg_status_buttons_metabox
1626
+	 *
1627
+	 * @access protected
1628
+	 * @return string
1629
+	 * @throws \EE_Error
1630
+	 */
1631
+	public function set_reg_status_buttons_metabox()
1632
+	{
1633
+		$this->_set_registration_object();
1634
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1635
+		echo $change_reg_status_form->form_open(
1636
+			self::add_query_args_and_nonce(
1637
+				array(
1638
+					'action' => 'change_reg_status',
1639
+				),
1640
+				REG_ADMIN_URL
1641
+			)
1642
+		);
1643
+		echo $change_reg_status_form->get_html();
1644
+		echo $change_reg_status_form->form_close();
1645
+	}
1646
+
1647
+
1648
+
1649
+	/**
1650
+	 * @return EE_Form_Section_Proper
1651
+	 * @throws EE_Error
1652
+	 */
1653
+	protected function _generate_reg_status_change_form()
1654
+	{
1655
+		return new EE_Form_Section_Proper(array(
1656
+			'name'            => 'reg_status_change_form',
1657
+			'html_id'         => 'reg-status-change-form',
1658
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1659
+			'subsections'     => array(
1660
+				'return'             => new EE_Hidden_Input(array(
1661
+					'name'    => 'return',
1662
+					'default' => 'view_registration',
1663
+				)),
1664
+				'REG_ID'             => new EE_Hidden_Input(array(
1665
+					'name'    => 'REG_ID',
1666
+					'default' => $this->_registration->ID(),
1667
+				)),
1668
+				'current_status'     => new EE_Form_Section_HTML(
1669
+					EEH_HTML::tr(
1670
+						EEH_HTML::th(
1671
+							EEH_HTML::label(
1672
+								EEH_HTML::strong(esc_html__('Current Registration Status', 'event_espresso')
1673
+								)
1674
+							)
1675
+						)
1676
+						. EEH_HTML::td(
1677
+							EEH_HTML::strong(
1678
+								$this->_registration->pretty_status(),
1679
+								'',
1680
+								'status-' . $this->_registration->status_ID(),
1681
+								'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1682
+							)
1683
+						)
1684
+					)
1685
+				),
1686
+				'reg_status'         => new EE_Select_Input(
1687
+					$this->_get_reg_statuses(),
1688
+					array(
1689
+						'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1690
+						'default'         => $this->_registration->status_ID(),
1691
+					)
1692
+				),
1693
+				'send_notifications' => new EE_Yes_No_Input(
1694
+					array(
1695
+						'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1696
+						'default'         => false,
1697
+						'html_help_text'  => esc_html__(
1698
+							'If set to "Yes", then the related messages will be sent to the registrant.',
1699
+							'event_espresso'
1700
+						),
1701
+					)
1702
+				),
1703
+				'submit'             => new EE_Submit_Input(
1704
+					array(
1705
+						'html_class'      => 'button-primary',
1706
+						'html_label_text' => '&nbsp;',
1707
+						'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1708
+					)
1709
+				),
1710
+			),
1711
+		));
1712
+	}
1713
+
1714
+
1715
+	/**
1716
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1717
+	 *
1718
+	 * @return array
1719
+	 * @throws EE_Error
1720
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1721
+	 */
1722
+	protected function _get_reg_statuses()
1723
+	{
1724
+		$reg_status_array = EEM_Registration::instance()->reg_status_array();
1725
+		unset ($reg_status_array[EEM_Registration::status_id_incomplete]);
1726
+		// get current reg status
1727
+		$current_status = $this->_registration->status_ID();
1728
+		// is registration for free event? This will determine whether to display the pending payment option
1729
+		if (
1730
+			$current_status !== EEM_Registration::status_id_pending_payment
1731
+			&& $this->_registration->transaction()->is_free()
1732
+		) {
1733
+			unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1734
+		}
1735
+		return EEM_Status::instance()->localized_status($reg_status_array, false, 'sentence');
1736
+	}
1737
+
1738
+
1739
+
1740
+	/**
1741
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1742
+	 *
1743
+	 * @param bool $status REG status given for changing registrations to.
1744
+	 * @param bool $notify Whether to send messages notifications or not.
1745
+	 * @return array  (array with reg_id(s) updated and whether update was successful.
1746
+	 * @throws \EE_Error
1747
+	 */
1748
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1749
+	{
1750
+		if (isset($this->_req_data['reg_status_change_form'])) {
1751
+			$REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1752
+				? (array)$this->_req_data['reg_status_change_form']['REG_ID'] : array();
1753
+		} else {
1754
+			$REG_IDs = isset($this->_req_data['_REG_ID']) ? (array)$this->_req_data['_REG_ID'] : array();
1755
+		}
1756
+		$success = $this->_set_registration_status($REG_IDs, $status);
1757
+		//notify?
1758
+		if ($success
1759
+			&& $notify
1760
+			&& EE_Registry::instance()->CAP->current_user_can(
1761
+				'ee_send_message',
1762
+				'espresso_registrations_resend_registration'
1763
+			)
1764
+		) {
1765
+			$this->_process_resend_registration();
1766
+		}
1767
+		return $success;
1768
+	}
1769
+
1770
+
1771
+
1772
+	/**
1773
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1774
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1775
+	 *
1776
+	 * @param array $REG_IDs
1777
+	 * @param bool  $status
1778
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1779
+	 * @throws \RuntimeException
1780
+	 * @throws \EE_Error
1781
+	 *               the array of updated registrations).
1782
+	 * @throws EE_Error
1783
+	 * @throws RuntimeException
1784
+	 */
1785
+	protected function _set_registration_status($REG_IDs = array(), $status = false)
1786
+	{
1787
+		$success = false;
1788
+		// typecast $REG_IDs
1789
+		$REG_IDs = (array)$REG_IDs;
1790
+		if ( ! empty($REG_IDs)) {
1791
+			$success = true;
1792
+			// set default status if none is passed
1793
+			$status = $status ? $status : EEM_Registration::status_id_pending_payment;
1794
+			// sanitize $REG_IDs
1795
+			$REG_IDs = array_filter($REG_IDs, 'absint');
1796
+			//loop through REG_ID's and change status
1797
+			foreach ($REG_IDs as $REG_ID) {
1798
+				$registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1799
+				if ($registration instanceof EE_Registration) {
1800
+					$registration->set_status($status);
1801
+					$result = $registration->save();
1802
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1803
+					$success = $result !== false ? $success : false;
1804
+				}
1805
+			}
1806
+		}
1807
+		//reset _req_data['_REG_ID'] for any potential future messages notifications
1808
+		$this->_req_data['_REG_ID'] = $REG_IDs;
1809
+		//return $success and processed registrations
1810
+		return array('REG_ID' => $REG_IDs, 'success' => $success);
1811
+	}
1812
+
1813
+
1814
+	/**
1815
+	 * Common logic for setting up success message and redirecting to appropriate route
1816
+	 *
1817
+	 * @param  string $STS_ID status id for the registration changed to
1818
+	 * @param   bool  $notify indicates whether the _set_registration_status_from_request does notifications or not.
1819
+	 * @return void
1820
+	 */
1821
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1822
+	{
1823
+		$result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1824
+			: array('success' => false);
1825
+		$success = isset($result['success']) && $result['success'];
1826
+		//setup success message
1827
+		if ($success) {
1828
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1829
+				$msg = sprintf(esc_html__('Registration status has been set to %s', 'event_espresso'),
1830
+					EEH_Template::pretty_status($STS_ID, false, 'lower'));
1831
+			} else {
1832
+				$msg = sprintf(esc_html__('Registrations have been set to %s.', 'event_espresso'),
1833
+					EEH_Template::pretty_status($STS_ID, false, 'lower'));
1834
+			}
1835
+			EE_Error::add_success($msg);
1836
+		} else {
1837
+			EE_Error::add_error(
1838
+				esc_html__(
1839
+					'Something went wrong, and the status was not changed',
1840
+					'event_espresso'
1841
+				), __FILE__, __LINE__, __FUNCTION__
1842
+			);
1843
+		}
1844
+		if (isset($this->_req_data['return']) && $this->_req_data['return'] == 'view_registration') {
1845
+			$route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1846
+		} else {
1847
+			$route = array('action' => 'default');
1848
+		}
1849
+		//unset nonces
1850
+		foreach ($this->_req_data as $ref => $value) {
1851
+			if (strpos($ref, 'nonce') !== false) {
1852
+				unset($this->_req_data[$ref]);
1853
+				continue;
1854
+			}
1855
+			$value                 = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
1856
+			$this->_req_data[$ref] = $value;
1857
+		}
1858
+		//merge request vars so that the reloaded list table contains any existing filter query params
1859
+		$route = array_merge($this->_req_data, $route);
1860
+		$this->_redirect_after_action($success, '', '', $route, true);
1861
+	}
1862
+
1863
+
1864
+	/**
1865
+	 * incoming reg status change from reg details page.
1866
+	 *
1867
+	 * @return void
1868
+	 */
1869
+	protected function _change_reg_status()
1870
+	{
1871
+		$this->_req_data['return'] = 'view_registration';
1872
+		//set notify based on whether the send notifications toggle is set or not
1873
+		$notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1874
+		//$notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1875
+		$this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1876
+			? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1877
+		switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1878
+			case EEM_Registration::status_id_approved :
1879
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence') :
1880
+				$this->approve_registration($notify);
1881
+				break;
1882
+			case EEM_Registration::status_id_pending_payment :
1883
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence') :
1884
+				$this->pending_registration($notify);
1885
+				break;
1886
+			case EEM_Registration::status_id_not_approved :
1887
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence') :
1888
+				$this->not_approve_registration($notify);
1889
+				break;
1890
+			case EEM_Registration::status_id_declined :
1891
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence') :
1892
+				$this->decline_registration($notify);
1893
+				break;
1894
+			case EEM_Registration::status_id_cancelled :
1895
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence') :
1896
+				$this->cancel_registration($notify);
1897
+				break;
1898
+			case EEM_Registration::status_id_wait_list :
1899
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence') :
1900
+				$this->wait_list_registration($notify);
1901
+				break;
1902
+			case EEM_Registration::status_id_incomplete :
1903
+			default :
1904
+				$result['success'] = false;
1905
+				unset($this->_req_data['return']);
1906
+				$this->_reg_status_change_return('', false);
1907
+				break;
1908
+		}
1909
+	}
1910
+
1911
+
1912
+	/**
1913
+	 * Callback for bulk action routes.
1914
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1915
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
1916
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1917
+	 * when an action is happening on just a single registration).
1918
+	 * @param      $action
1919
+	 * @param bool $notify
1920
+	 */
1921
+	protected function bulk_action_on_registrations($action, $notify = false) {
1922
+		do_action(
1923
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1924
+			$this,
1925
+			$action,
1926
+			$notify
1927
+		);
1928
+		$method = $action . '_registration';
1929
+		if (method_exists($this, $method)) {
1930
+			$this->$method($notify);
1931
+		}
1932
+	}
1933
+
1934
+
1935
+	/**
1936
+	 * approve_registration
1937
+	 *
1938
+	 * @access protected
1939
+	 * @param bool $notify whether or not to notify the registrant about their approval.
1940
+	 * @return void
1941
+	 */
1942
+	protected function approve_registration($notify = false)
1943
+	{
1944
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1945
+	}
1946
+
1947
+
1948
+	/**
1949
+	 *        decline_registration
1950
+	 *
1951
+	 * @access protected
1952
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1953
+	 * @return void
1954
+	 */
1955
+	protected function decline_registration($notify = false)
1956
+	{
1957
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1958
+	}
1959
+
1960
+
1961
+	/**
1962
+	 *        cancel_registration
1963
+	 *
1964
+	 * @access protected
1965
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1966
+	 * @return void
1967
+	 */
1968
+	protected function cancel_registration($notify = false)
1969
+	{
1970
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1971
+	}
1972
+
1973
+
1974
+	/**
1975
+	 *        not_approve_registration
1976
+	 *
1977
+	 * @access protected
1978
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1979
+	 * @return void
1980
+	 */
1981
+	protected function not_approve_registration($notify = false)
1982
+	{
1983
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1984
+	}
1985
+
1986
+
1987
+	/**
1988
+	 *        decline_registration
1989
+	 *
1990
+	 * @access protected
1991
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1992
+	 * @return void
1993
+	 */
1994
+	protected function pending_registration($notify = false)
1995
+	{
1996
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1997
+	}
1998
+
1999
+
2000
+	/**
2001
+	 * waitlist_registration
2002
+	 *
2003
+	 * @access protected
2004
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2005
+	 * @return void
2006
+	 */
2007
+	protected function wait_list_registration($notify = false)
2008
+	{
2009
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
2010
+	}
2011
+
2012
+
2013
+	/**
2014
+	 *        generates HTML for the Registration main meta box
2015
+	 *
2016
+	 * @access public
2017
+	 * @return void
2018
+	 * @throws DomainException
2019
+	 * @throws EE_Error
2020
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
2021
+	 */
2022
+	public function _reg_details_meta_box()
2023
+	{
2024
+		EEH_Autoloader::register_line_item_display_autoloaders();
2025
+		EEH_Autoloader::register_line_item_filter_autoloaders();
2026
+		EE_Registry::instance()->load_helper('Line_Item');
2027
+		$transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2028
+			: EE_Transaction::new_instance();
2029
+		$this->_session = $transaction->session_data();
2030
+		$filters        = new EE_Line_Item_Filter_Collection();
2031
+		//$filters->add( new EE_Non_Zero_Line_Item_Filter() );
2032
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2033
+		$line_item_filter_processor              = new EE_Line_Item_Filter_Processor($filters,
2034
+			$transaction->total_line_item());
2035
+		$filtered_line_item_tree                 = $line_item_filter_processor->process();
2036
+		$line_item_display                       = new EE_Line_Item_Display('reg_admin_table',
2037
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
2038
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2039
+			$filtered_line_item_tree,
2040
+			array('EE_Registration' => $this->_registration)
2041
+		);
2042
+		$attendee                                = $this->_registration->attendee();
2043
+		if (EE_Registry::instance()->CAP->current_user_can(
2044
+			'ee_read_transaction',
2045
+			'espresso_transactions_view_transaction'
2046
+		)) {
2047
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2048
+				EE_Admin_Page::add_query_args_and_nonce(
2049
+					array(
2050
+						'action' => 'view_transaction',
2051
+						'TXN_ID' => $transaction->ID(),
2052
+					),
2053
+					TXN_ADMIN_URL
2054
+				),
2055
+				esc_html__(' View Transaction', 'event_espresso'),
2056
+				'button secondary-button right',
2057
+				'dashicons dashicons-cart'
2058
+			);
2059
+		} else {
2060
+			$this->_template_args['view_transaction_button'] = '';
2061
+		}
2062
+		if ($attendee instanceof EE_Attendee
2063
+			&& EE_Registry::instance()->CAP->current_user_can(
2064
+				'ee_send_message',
2065
+				'espresso_registrations_resend_registration'
2066
+			)
2067
+		) {
2068
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2069
+				EE_Admin_Page::add_query_args_and_nonce(
2070
+					array(
2071
+						'action'      => 'resend_registration',
2072
+						'_REG_ID'     => $this->_registration->ID(),
2073
+						'redirect_to' => 'view_registration',
2074
+					),
2075
+					REG_ADMIN_URL
2076
+				),
2077
+				esc_html__(' Resend Registration', 'event_espresso'),
2078
+				'button secondary-button right',
2079
+				'dashicons dashicons-email-alt'
2080
+			);
2081
+		} else {
2082
+			$this->_template_args['resend_registration_button'] = '';
2083
+		}
2084
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2085
+		$payment                               = $transaction->get_first_related('Payment');
2086
+		$payment                               = ! $payment instanceof EE_Payment
2087
+			? EE_Payment::new_instance()
2088
+			: $payment;
2089
+		$payment_method                        = $payment->get_first_related('Payment_Method');
2090
+		$payment_method                        = ! $payment_method instanceof EE_Payment_Method
2091
+			? EE_Payment_Method::new_instance()
2092
+			: $payment_method;
2093
+		$reg_details                           = array(
2094
+			'payment_method'       => $payment_method->name(),
2095
+			'response_msg'         => $payment->gateway_response(),
2096
+			'registration_id'      => $this->_registration->get('REG_code'),
2097
+			'registration_session' => $this->_registration->session_ID(),
2098
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2099
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2100
+		);
2101
+		if (isset($reg_details['registration_id'])) {
2102
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2103
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2104
+				'Registration ID',
2105
+				'event_espresso'
2106
+			);
2107
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2108
+		}
2109
+		if (isset($reg_details['payment_method'])) {
2110
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2111
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2112
+				'Most Recent Payment Method',
2113
+				'event_espresso'
2114
+			);
2115
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2116
+			$this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2117
+			$this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2118
+				'Payment method response',
2119
+				'event_espresso'
2120
+			);
2121
+			$this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2122
+		}
2123
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2124
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2125
+			'Registration Session',
2126
+			'event_espresso'
2127
+		);
2128
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2129
+		$this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2130
+		$this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2131
+			'Registration placed from IP',
2132
+			'event_espresso'
2133
+		);
2134
+		$this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2135
+		$this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2136
+		$this->_template_args['reg_details']['user_agent']['label']           = esc_html__('Registrant User Agent',
2137
+			'event_espresso');
2138
+		$this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2139
+		$this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2140
+			array(
2141
+				'action'   => 'default',
2142
+				'event_id' => $this->_registration->event_ID(),
2143
+			),
2144
+			REG_ADMIN_URL
2145
+		);
2146
+		$this->_template_args['REG_ID']                                       = $this->_registration->ID();
2147
+		$this->_template_args['event_id']                                     = $this->_registration->event_ID();
2148
+		$template_path                                                        =
2149
+			REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2150
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2151
+	}
2152
+
2153
+
2154
+	/**
2155
+	 * generates HTML for the Registration Questions meta box.
2156
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2157
+	 * otherwise uses new forms system
2158
+	 *
2159
+	 * @access public
2160
+	 * @return void
2161
+	 * @throws DomainException
2162
+	 * @throws EE_Error
2163
+	 */
2164
+	public function _reg_questions_meta_box()
2165
+	{
2166
+		//allow someone to override this method entirely
2167
+		if (apply_filters('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', true, $this,
2168
+			$this->_registration)) {
2169
+			$form                                              = $this->_get_reg_custom_questions_form(
2170
+				$this->_registration->ID()
2171
+			);
2172
+			$this->_template_args['att_questions']             = count($form->subforms()) > 0
2173
+				? $form->get_html_and_js()
2174
+				: '';
2175
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2176
+			$this->_template_args['REG_ID']                    = $this->_registration->ID();
2177
+			$template_path                                     =
2178
+				REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2179
+			echo EEH_Template::display_template($template_path, $this->_template_args, true);
2180
+		}
2181
+	}
2182
+
2183
+
2184
+	/**
2185
+	 * form_before_question_group
2186
+	 *
2187
+	 * @deprecated    as of 4.8.32.rc.000
2188
+	 * @access        public
2189
+	 * @param        string $output
2190
+	 * @return        string
2191
+	 */
2192
+	public function form_before_question_group($output)
2193
+	{
2194
+		EE_Error::doing_it_wrong(
2195
+			__CLASS__ . '::' . __FUNCTION__,
2196
+			esc_html__(
2197
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2198
+				'event_espresso'
2199
+			),
2200
+			'4.8.32.rc.000'
2201
+		);
2202
+		return '
2203 2203
 	<table class="form-table ee-width-100">
2204 2204
 		<tbody>
2205 2205
 			';
2206
-    }
2207
-
2208
-
2209
-    /**
2210
-     * form_after_question_group
2211
-     *
2212
-     * @deprecated    as of 4.8.32.rc.000
2213
-     * @access        public
2214
-     * @param        string $output
2215
-     * @return        string
2216
-     */
2217
-    public function form_after_question_group($output)
2218
-    {
2219
-        EE_Error::doing_it_wrong(
2220
-            __CLASS__ . '::' . __FUNCTION__,
2221
-            esc_html__(
2222
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2223
-                'event_espresso'
2224
-            ),
2225
-            '4.8.32.rc.000'
2226
-        );
2227
-        return '
2206
+	}
2207
+
2208
+
2209
+	/**
2210
+	 * form_after_question_group
2211
+	 *
2212
+	 * @deprecated    as of 4.8.32.rc.000
2213
+	 * @access        public
2214
+	 * @param        string $output
2215
+	 * @return        string
2216
+	 */
2217
+	public function form_after_question_group($output)
2218
+	{
2219
+		EE_Error::doing_it_wrong(
2220
+			__CLASS__ . '::' . __FUNCTION__,
2221
+			esc_html__(
2222
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2223
+				'event_espresso'
2224
+			),
2225
+			'4.8.32.rc.000'
2226
+		);
2227
+		return '
2228 2228
 			<tr class="hide-if-no-js">
2229 2229
 				<th> </th>
2230 2230
 				<td class="reg-admin-edit-attendee-question-td">
2231 2231
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" title="'
2232
-               . esc_attr__('click to edit question', 'event_espresso')
2233
-               . '">
2232
+			   . esc_attr__('click to edit question', 'event_espresso')
2233
+			   . '">
2234 2234
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2235
-               . esc_html__('edit the above question group', 'event_espresso')
2236
-               . '</span>
2235
+			   . esc_html__('edit the above question group', 'event_espresso')
2236
+			   . '</span>
2237 2237
 						<div class="dashicons dashicons-edit"></div>
2238 2238
 					</a>
2239 2239
 				</td>
@@ -2241,558 +2241,558 @@  discard block
 block discarded – undo
2241 2241
 		</tbody>
2242 2242
 	</table>
2243 2243
 ';
2244
-    }
2245
-
2246
-
2247
-    /**
2248
-     * form_form_field_label_wrap
2249
-     *
2250
-     * @deprecated    as of 4.8.32.rc.000
2251
-     * @access        public
2252
-     * @param        string $label
2253
-     * @return        string
2254
-     */
2255
-    public function form_form_field_label_wrap($label)
2256
-    {
2257
-        EE_Error::doing_it_wrong(
2258
-            __CLASS__ . '::' . __FUNCTION__,
2259
-            esc_html__(
2260
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2261
-                'event_espresso'
2262
-            ),
2263
-            '4.8.32.rc.000'
2264
-        );
2265
-        return '
2244
+	}
2245
+
2246
+
2247
+	/**
2248
+	 * form_form_field_label_wrap
2249
+	 *
2250
+	 * @deprecated    as of 4.8.32.rc.000
2251
+	 * @access        public
2252
+	 * @param        string $label
2253
+	 * @return        string
2254
+	 */
2255
+	public function form_form_field_label_wrap($label)
2256
+	{
2257
+		EE_Error::doing_it_wrong(
2258
+			__CLASS__ . '::' . __FUNCTION__,
2259
+			esc_html__(
2260
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2261
+				'event_espresso'
2262
+			),
2263
+			'4.8.32.rc.000'
2264
+		);
2265
+		return '
2266 2266
 			<tr>
2267 2267
 				<th>
2268 2268
 					' . $label . '
2269 2269
 				</th>';
2270
-    }
2271
-
2272
-
2273
-    /**
2274
-     * form_form_field_input__wrap
2275
-     *
2276
-     * @deprecated    as of 4.8.32.rc.000
2277
-     * @access        public
2278
-     * @param        string $input
2279
-     * @return        string
2280
-     */
2281
-    public function form_form_field_input__wrap($input)
2282
-    {
2283
-        EE_Error::doing_it_wrong(
2284
-            __CLASS__ . '::' . __FUNCTION__,
2285
-            esc_html__(
2286
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2287
-                'event_espresso'
2288
-            ),
2289
-            '4.8.32.rc.000'
2290
-        );
2291
-        return '
2270
+	}
2271
+
2272
+
2273
+	/**
2274
+	 * form_form_field_input__wrap
2275
+	 *
2276
+	 * @deprecated    as of 4.8.32.rc.000
2277
+	 * @access        public
2278
+	 * @param        string $input
2279
+	 * @return        string
2280
+	 */
2281
+	public function form_form_field_input__wrap($input)
2282
+	{
2283
+		EE_Error::doing_it_wrong(
2284
+			__CLASS__ . '::' . __FUNCTION__,
2285
+			esc_html__(
2286
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2287
+				'event_espresso'
2288
+			),
2289
+			'4.8.32.rc.000'
2290
+		);
2291
+		return '
2292 2292
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2293 2293
 					' . $input . '
2294 2294
 				</td>
2295 2295
 			</tr>';
2296
-    }
2297
-
2298
-
2299
-    /**
2300
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2301
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2302
-     * to display the page
2303
-     *
2304
-     * @access protected
2305
-     * @return void
2306
-     * @throws EE_Error
2307
-     */
2308
-    protected function _update_attendee_registration_form()
2309
-    {
2310
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2311
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
2312
-            $REG_ID  = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2313
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2314
-            if ($success) {
2315
-                $what  = esc_html__('Registration Form', 'event_espresso');
2316
-                $route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2317
-                    : array('action' => 'default');
2318
-                $this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2319
-            }
2320
-        }
2321
-    }
2322
-
2323
-
2324
-    /**
2325
-     * Gets the form for saving registrations custom questions (if done
2326
-     * previously retrieves the cached form object, which may have validation errors in it)
2327
-     *
2328
-     * @param int $REG_ID
2329
-     * @return EE_Registration_Custom_Questions_Form
2330
-     * @throws EE_Error
2331
-     */
2332
-    protected function _get_reg_custom_questions_form($REG_ID)
2333
-    {
2334
-        if ( ! $this->_reg_custom_questions_form) {
2335
-            require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2336
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2337
-                EEM_Registration::instance()->get_one_by_ID($REG_ID)
2338
-            );
2339
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2340
-        }
2341
-        return $this->_reg_custom_questions_form;
2342
-    }
2343
-
2344
-
2345
-    /**
2346
-     * Saves
2347
-     *
2348
-     * @access private
2349
-     * @param bool $REG_ID
2350
-     * @return bool
2351
-     * @throws EE_Error
2352
-     */
2353
-    private function _save_reg_custom_questions_form($REG_ID = false)
2354
-    {
2355
-        if ( ! $REG_ID) {
2356
-            EE_Error::add_error(
2357
-                esc_html__(
2358
-                    'An error occurred. No registration ID was received.', 'event_espresso'),
2359
-                __FILE__, __FUNCTION__, __LINE__
2360
-            );
2361
-        }
2362
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2363
-        $form->receive_form_submission($this->_req_data);
2364
-        $success = false;
2365
-        if ($form->is_valid()) {
2366
-            foreach ($form->subforms() as $question_group_id => $question_group_form) {
2367
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2368
-                    $where_conditions    = array(
2369
-                        'QST_ID' => $question_id,
2370
-                        'REG_ID' => $REG_ID,
2371
-                    );
2372
-                    $possibly_new_values = array(
2373
-                        'ANS_value' => $input->normalized_value(),
2374
-                    );
2375
-                    $answer              = EEM_Answer::instance()->get_one(array($where_conditions));
2376
-                    if ($answer instanceof EE_Answer) {
2377
-                        $success = $answer->save($possibly_new_values);
2378
-                    } else {
2379
-                        //insert it then
2380
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2381
-                        $answer      = EE_Answer::new_instance($cols_n_vals);
2382
-                        $success     = $answer->save();
2383
-                    }
2384
-                }
2385
-            }
2386
-        } else {
2387
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2388
-        }
2389
-        return $success;
2390
-    }
2391
-
2392
-
2393
-    /**
2394
-     *        generates HTML for the Registration main meta box
2395
-     *
2396
-     * @access public
2397
-     * @return void
2398
-     * @throws DomainException
2399
-     * @throws EE_Error
2400
-     */
2401
-    public function _reg_attendees_meta_box()
2402
-    {
2403
-        $REG = EEM_Registration::instance();
2404
-        //get all other registrations on this transaction, and cache
2405
-        //the attendees for them so we don't have to run another query using force_join
2406
-        $registrations                           = $REG->get_all(array(
2407
-            array(
2408
-                'TXN_ID' => $this->_registration->transaction_ID(),
2409
-                'REG_ID' => array('!=', $this->_registration->ID()),
2410
-            ),
2411
-            'force_join' => array('Attendee'),
2412
-        ));
2413
-        $this->_template_args['attendees']       = array();
2414
-        $this->_template_args['attendee_notice'] = '';
2415
-        if (empty($registrations)
2416
-            || (is_array($registrations)
2417
-                && ! EEH_Array::get_one_item_from_array($registrations))
2418
-        ) {
2419
-            EE_Error::add_error(
2420
-                esc_html__(
2421
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2422
-                    'event_espresso'
2423
-                ), __FILE__, __FUNCTION__, __LINE__
2424
-            );
2425
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2426
-        } else {
2427
-            $att_nmbr = 1;
2428
-            foreach ($registrations as $registration) {
2429
-                /* @var $registration EE_Registration */
2430
-                $attendee                                                    = $registration->attendee()
2431
-                    ? $registration->attendee()
2432
-                    : EEM_Attendee::instance()
2433
-                                  ->create_default_object();
2434
-                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2435
-                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2436
-                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2437
-                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2438
-                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2439
-                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2440
-                    ', ',
2441
-                    $attendee->full_address_as_array()
2442
-                );
2443
-                $this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2444
-                    array(
2445
-                        'action' => 'edit_attendee',
2446
-                        'post'   => $attendee->ID(),
2447
-                    ),
2448
-                    REG_ADMIN_URL
2449
-                );
2450
-                $this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2451
-                $att_nmbr++;
2452
-            }
2453
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2454
-        }
2455
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2456
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2457
-    }
2458
-
2459
-
2460
-    /**
2461
-     *        generates HTML for the Edit Registration side meta box
2462
-     *
2463
-     * @access public
2464
-     * @return void
2465
-     * @throws DomainException
2466
-     * @throws EE_Error
2467
-     */
2468
-    public function _reg_registrant_side_meta_box()
2469
-    {
2470
-        /*@var $attendee EE_Attendee */
2471
-        $att_check = $this->_registration->attendee();
2472
-        $attendee  = $att_check instanceof EE_Attendee ? $att_check : EEM_Attendee::instance()->create_default_object();
2473
-        //now let's determine if this is not the primary registration.  If it isn't then we set the
2474
-        //primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2475
-        //primary registration object (that way we know if we need to show create button or not)
2476
-        if ( ! $this->_registration->is_primary_registrant()) {
2477
-            $primary_registration = $this->_registration->get_primary_registration();
2478
-            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2479
-                : null;
2480
-            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2481
-                //in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2482
-                //custom attendee object so let's not worry about the primary reg.
2483
-                $primary_registration = null;
2484
-            }
2485
-        } else {
2486
-            $primary_registration = null;
2487
-        }
2488
-        $this->_template_args['ATT_ID']            = $attendee->ID();
2489
-        $this->_template_args['fname']             = $attendee->fname();
2490
-        $this->_template_args['lname']             = $attendee->lname();
2491
-        $this->_template_args['email']             = $attendee->email();
2492
-        $this->_template_args['phone']             = $attendee->phone();
2493
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2494
-        //edit link
2495
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2496
-            'action' => 'edit_attendee',
2497
-            'post'   => $attendee->ID(),
2498
-        ), REG_ADMIN_URL);
2499
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2500
-        //create link
2501
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2502
-            ? EE_Admin_Page::add_query_args_and_nonce(array(
2503
-                'action'  => 'duplicate_attendee',
2504
-                '_REG_ID' => $this->_registration->ID(),
2505
-            ), REG_ADMIN_URL) : '';
2506
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2507
-        $this->_template_args['att_check']    = $att_check;
2508
-        $template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2509
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2510
-    }
2511
-
2512
-
2513
-    /**
2514
-     * trash or restore registrations
2515
-     *
2516
-     * @param  boolean $trash whether to archive or restore
2517
-     * @return void
2518
-     * @throws EE_Error
2519
-     * @throws RuntimeException
2520
-     * @access protected
2521
-     */
2522
-    protected function _trash_or_restore_registrations($trash = true)
2523
-    {
2524
-        //if empty _REG_ID then get out because there's nothing to do
2525
-        if (empty($this->_req_data['_REG_ID'])) {
2526
-            EE_Error::add_error(
2527
-                sprintf(
2528
-                    esc_html__(
2529
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2530
-                        'event_espresso'
2531
-                    ),
2532
-                    $trash ? 'trash' : 'restore'
2533
-                ),
2534
-                __FILE__, __LINE__, __FUNCTION__
2535
-            );
2536
-            $this->_redirect_after_action(false, '', '', array(), true);
2537
-        }
2538
-        $success = 0;
2539
-        $overwrite_msgs = false;
2540
-        //Checkboxes
2541
-        if ( ! is_array($this->_req_data['_REG_ID'])) {
2542
-            $this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2543
-        }
2544
-        $reg_count = count($this->_req_data['_REG_ID']);
2545
-        // cycle thru checkboxes
2546
-        foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2547
-            /** @var EE_Registration $REG */
2548
-            $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2549
-            $payments = $REG->registration_payments();
2550
-            if (! empty($payments)) {
2551
-                $name = $REG->attendee() instanceof EE_Attendee
2552
-                    ? $REG->attendee()->full_name()
2553
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2554
-                $overwrite_msgs = true;
2555
-                EE_Error::add_error(
2556
-                    sprintf(
2557
-                        esc_html__(
2558
-                            'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2559
-                            'event_espresso'
2560
-                        ),
2561
-                        $name
2562
-                    ),
2563
-                    __FILE__, __FUNCTION__, __LINE__
2564
-                );
2565
-                //can't trash this registration because it has payments.
2566
-                continue;
2567
-            }
2568
-            $updated = $trash ? $REG->delete() : $REG->restore();
2569
-            if ($updated) {
2570
-                $success++;
2571
-            }
2572
-        }
2573
-        $this->_redirect_after_action(
2574
-            $success === $reg_count, // were ALL registrations affected?
2575
-            $success > 1
2576
-                ? esc_html__('Registrations', 'event_espresso')
2577
-                : esc_html__('Registration', 'event_espresso'),
2578
-            $trash
2579
-                ? esc_html__('moved to the trash', 'event_espresso')
2580
-                : esc_html__('restored', 'event_espresso'),
2581
-            array('action' => 'default'),
2582
-            $overwrite_msgs
2583
-        );
2584
-    }
2585
-
2586
-
2587
-    /**
2588
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2589
-     * registration but also.
2590
-     * 1. Removing relations to EE_Attendee
2591
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2592
-     * ALSO trashed.
2593
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2594
-     * 4. Removing relationships between all tickets and the related registrations
2595
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2596
-     * 6. Deleting permanently any related Checkins.
2597
-     *
2598
-     * @return void
2599
-     * @throws EE_Error
2600
-     */
2601
-    protected function _delete_registrations()
2602
-    {
2603
-        $REG_MDL = EEM_Registration::instance();
2604
-        $success = 1;
2605
-        //Checkboxes
2606
-        if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2607
-            // if array has more than one element than success message should be plural
2608
-            $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2609
-            // cycle thru checkboxes
2610
-            while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
2611
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2612
-                if ( ! $REG instanceof EE_Registration) {
2613
-                    continue;
2614
-                }
2615
-                $deleted = $this->_delete_registration($REG);
2616
-                if ( ! $deleted) {
2617
-                    $success = 0;
2618
-                }
2619
-            }
2620
-        } else {
2621
-            // grab single id and delete
2622
-            $REG_ID  = $this->_req_data['_REG_ID'];
2623
-            $REG     = $REG_MDL->get_one_by_ID($REG_ID);
2624
-            $deleted = $this->_delete_registration($REG);
2625
-            if ( ! $deleted) {
2626
-                $success = 0;
2627
-            }
2628
-        }
2629
-        $what        = $success > 1
2630
-            ? esc_html__('Registrations', 'event_espresso')
2631
-            : esc_html__('Registration', 'event_espresso');
2632
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2633
-        $this->_redirect_after_action(
2634
-            $success,
2635
-            $what,
2636
-            $action_desc,
2637
-            array('action' => 'default'),
2638
-            true
2639
-        );
2640
-    }
2641
-
2642
-
2643
-    /**
2644
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2645
-     * models get affected.
2646
-     *
2647
-     * @param  EE_Registration $REG registration to be deleted permenantly
2648
-     * @return bool true = successful deletion, false = fail.
2649
-     * @throws EE_Error
2650
-     */
2651
-    protected function _delete_registration(EE_Registration $REG)
2652
-    {
2653
-        //first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2654
-        //registrations on the transaction that are NOT trashed.
2655
-        $TXN         = $REG->get_first_related('Transaction');
2656
-        $REGS        = $TXN->get_many_related('Registration');
2657
-        $all_trashed = true;
2658
-        foreach ($REGS as $registration) {
2659
-            if ( ! $registration->get('REG_deleted')) {
2660
-                $all_trashed = false;
2661
-            }
2662
-        }
2663
-        if ( ! $all_trashed) {
2664
-            EE_Error::add_error(
2665
-                esc_html__(
2666
-                    'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2667
-                    'event_espresso'
2668
-                ),
2669
-                __FILE__, __FUNCTION__, __LINE__
2670
-            );
2671
-            return false;
2672
-        }
2673
-        //k made it here so that means we can delete all the related transactions and their answers (but let's do them
2674
-        //separately from THIS one).
2675
-        foreach ($REGS as $registration) {
2676
-            //delete related answers
2677
-            $registration->delete_related_permanently('Answer');
2678
-            //remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2679
-            $attendee = $registration->get_first_related('Attendee');
2680
-            if ($attendee instanceof EE_Attendee) {
2681
-                $registration->_remove_relation_to($attendee, 'Attendee');
2682
-            }
2683
-            //now remove relationships to tickets on this registration.
2684
-            $registration->_remove_relations('Ticket');
2685
-            //now delete permanently the checkins related to this registration.
2686
-            $registration->delete_related_permanently('Checkin');
2687
-            if ($registration->ID() === $REG->ID()) {
2688
-                continue;
2689
-            } //we don't want to delete permanently the existing registration just yet.
2690
-            //remove relation to transaction for these registrations if NOT the existing registrations
2691
-            $registration->_remove_relations('Transaction');
2692
-            //delete permanently any related messages.
2693
-            $registration->delete_related_permanently('Message');
2694
-            //now delete this registration permanently
2695
-            $registration->delete_permanently();
2696
-        }
2697
-        //now all related registrations on the transaction are handled.  So let's just handle this registration itself
2698
-        // (the transaction and line items should be all that's left).
2699
-        // delete the line items related to the transaction for this registration.
2700
-        $TXN->delete_related_permanently('Line_Item');
2701
-        //we need to remove all the relationships on the transaction
2702
-        $TXN->delete_related_permanently('Payment');
2703
-        $TXN->delete_related_permanently('Extra_Meta');
2704
-        $TXN->delete_related_permanently('Message');
2705
-        //now we can delete this REG permanently (and the transaction of course)
2706
-        $REG->delete_related_permanently('Transaction');
2707
-        return $REG->delete_permanently();
2708
-    }
2709
-
2710
-
2711
-    /**
2712
-     *    generates HTML for the Register New Attendee Admin page
2713
-     *
2714
-     * @access private
2715
-     * @throws DomainException
2716
-     * @throws EE_Error
2717
-     */
2718
-    public function new_registration()
2719
-    {
2720
-        if ( ! $this->_set_reg_event()) {
2721
-            throw new EE_Error(
2722
-                esc_html__(
2723
-                    'Unable to continue with registering because there is no Event ID in the request',
2724
-                    'event_espresso'
2725
-                )
2726
-            );
2727
-        }
2728
-        EE_Registry::instance()->REQ->set_espresso_page(true);
2729
-        // gotta start with a clean slate if we're not coming here via ajax
2730
-        if ( ! defined('DOING_AJAX')
2731
-             && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2732
-        ) {
2733
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2734
-        }
2735
-        $this->_template_args['event_name'] = '';
2736
-        // event name
2737
-        if ($this->_reg_event) {
2738
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2739
-            $edit_event_url                     = self::add_query_args_and_nonce(array(
2740
-                'action' => 'edit',
2741
-                'post'   => $this->_reg_event->ID(),
2742
-            ), EVENTS_ADMIN_URL);
2743
-            $edit_event_lnk                     = '<a href="'
2744
-                                                  . $edit_event_url
2745
-                                                  . '" title="'
2746
-                                                  . esc_attr__('Edit ', 'event_espresso')
2747
-                                                  . $this->_reg_event->name()
2748
-                                                  . '">'
2749
-                                                  . esc_html__('Edit Event', 'event_espresso')
2750
-                                                  . '</a>';
2751
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2752
-                                                   . $edit_event_lnk
2753
-                                                   . '</span>';
2754
-        }
2755
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2756
-        if (defined('DOING_AJAX')) {
2757
-            $this->_return_json();
2758
-        }
2759
-        // grab header
2760
-        $template_path                              =
2761
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2762
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2763
-            $this->_template_args, true);
2764
-        //$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2765
-        // the details template wrapper
2766
-        $this->display_admin_page_with_sidebar();
2767
-    }
2768
-
2769
-
2770
-    /**
2771
-     * This returns the content for a registration step
2772
-     *
2773
-     * @access protected
2774
-     * @return string html
2775
-     * @throws DomainException
2776
-     * @throws EE_Error
2777
-     */
2778
-    protected function _get_registration_step_content()
2779
-    {
2780
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2781
-            $warning_msg = sprintf(
2782
-                esc_html__(
2783
-                    '%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2784
-                    'event_espresso'
2785
-                ),
2786
-                '<br />',
2787
-                '<h3 class="important-notice">',
2788
-                '</h3>',
2789
-                '<div class="float-right">',
2790
-                '<span id="redirect_timer" class="important-notice">30</span>',
2791
-                '</div>',
2792
-                '<b>',
2793
-                '</b>'
2794
-            );
2795
-            return '
2296
+	}
2297
+
2298
+
2299
+	/**
2300
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2301
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2302
+	 * to display the page
2303
+	 *
2304
+	 * @access protected
2305
+	 * @return void
2306
+	 * @throws EE_Error
2307
+	 */
2308
+	protected function _update_attendee_registration_form()
2309
+	{
2310
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2311
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
2312
+			$REG_ID  = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2313
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2314
+			if ($success) {
2315
+				$what  = esc_html__('Registration Form', 'event_espresso');
2316
+				$route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2317
+					: array('action' => 'default');
2318
+				$this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2319
+			}
2320
+		}
2321
+	}
2322
+
2323
+
2324
+	/**
2325
+	 * Gets the form for saving registrations custom questions (if done
2326
+	 * previously retrieves the cached form object, which may have validation errors in it)
2327
+	 *
2328
+	 * @param int $REG_ID
2329
+	 * @return EE_Registration_Custom_Questions_Form
2330
+	 * @throws EE_Error
2331
+	 */
2332
+	protected function _get_reg_custom_questions_form($REG_ID)
2333
+	{
2334
+		if ( ! $this->_reg_custom_questions_form) {
2335
+			require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2336
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2337
+				EEM_Registration::instance()->get_one_by_ID($REG_ID)
2338
+			);
2339
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2340
+		}
2341
+		return $this->_reg_custom_questions_form;
2342
+	}
2343
+
2344
+
2345
+	/**
2346
+	 * Saves
2347
+	 *
2348
+	 * @access private
2349
+	 * @param bool $REG_ID
2350
+	 * @return bool
2351
+	 * @throws EE_Error
2352
+	 */
2353
+	private function _save_reg_custom_questions_form($REG_ID = false)
2354
+	{
2355
+		if ( ! $REG_ID) {
2356
+			EE_Error::add_error(
2357
+				esc_html__(
2358
+					'An error occurred. No registration ID was received.', 'event_espresso'),
2359
+				__FILE__, __FUNCTION__, __LINE__
2360
+			);
2361
+		}
2362
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2363
+		$form->receive_form_submission($this->_req_data);
2364
+		$success = false;
2365
+		if ($form->is_valid()) {
2366
+			foreach ($form->subforms() as $question_group_id => $question_group_form) {
2367
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2368
+					$where_conditions    = array(
2369
+						'QST_ID' => $question_id,
2370
+						'REG_ID' => $REG_ID,
2371
+					);
2372
+					$possibly_new_values = array(
2373
+						'ANS_value' => $input->normalized_value(),
2374
+					);
2375
+					$answer              = EEM_Answer::instance()->get_one(array($where_conditions));
2376
+					if ($answer instanceof EE_Answer) {
2377
+						$success = $answer->save($possibly_new_values);
2378
+					} else {
2379
+						//insert it then
2380
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2381
+						$answer      = EE_Answer::new_instance($cols_n_vals);
2382
+						$success     = $answer->save();
2383
+					}
2384
+				}
2385
+			}
2386
+		} else {
2387
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2388
+		}
2389
+		return $success;
2390
+	}
2391
+
2392
+
2393
+	/**
2394
+	 *        generates HTML for the Registration main meta box
2395
+	 *
2396
+	 * @access public
2397
+	 * @return void
2398
+	 * @throws DomainException
2399
+	 * @throws EE_Error
2400
+	 */
2401
+	public function _reg_attendees_meta_box()
2402
+	{
2403
+		$REG = EEM_Registration::instance();
2404
+		//get all other registrations on this transaction, and cache
2405
+		//the attendees for them so we don't have to run another query using force_join
2406
+		$registrations                           = $REG->get_all(array(
2407
+			array(
2408
+				'TXN_ID' => $this->_registration->transaction_ID(),
2409
+				'REG_ID' => array('!=', $this->_registration->ID()),
2410
+			),
2411
+			'force_join' => array('Attendee'),
2412
+		));
2413
+		$this->_template_args['attendees']       = array();
2414
+		$this->_template_args['attendee_notice'] = '';
2415
+		if (empty($registrations)
2416
+			|| (is_array($registrations)
2417
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2418
+		) {
2419
+			EE_Error::add_error(
2420
+				esc_html__(
2421
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2422
+					'event_espresso'
2423
+				), __FILE__, __FUNCTION__, __LINE__
2424
+			);
2425
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2426
+		} else {
2427
+			$att_nmbr = 1;
2428
+			foreach ($registrations as $registration) {
2429
+				/* @var $registration EE_Registration */
2430
+				$attendee                                                    = $registration->attendee()
2431
+					? $registration->attendee()
2432
+					: EEM_Attendee::instance()
2433
+								  ->create_default_object();
2434
+				$this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2435
+				$this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2436
+				$this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2437
+				$this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2438
+				$this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2439
+				$this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2440
+					', ',
2441
+					$attendee->full_address_as_array()
2442
+				);
2443
+				$this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2444
+					array(
2445
+						'action' => 'edit_attendee',
2446
+						'post'   => $attendee->ID(),
2447
+					),
2448
+					REG_ADMIN_URL
2449
+				);
2450
+				$this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2451
+				$att_nmbr++;
2452
+			}
2453
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2454
+		}
2455
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2456
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2457
+	}
2458
+
2459
+
2460
+	/**
2461
+	 *        generates HTML for the Edit Registration side meta box
2462
+	 *
2463
+	 * @access public
2464
+	 * @return void
2465
+	 * @throws DomainException
2466
+	 * @throws EE_Error
2467
+	 */
2468
+	public function _reg_registrant_side_meta_box()
2469
+	{
2470
+		/*@var $attendee EE_Attendee */
2471
+		$att_check = $this->_registration->attendee();
2472
+		$attendee  = $att_check instanceof EE_Attendee ? $att_check : EEM_Attendee::instance()->create_default_object();
2473
+		//now let's determine if this is not the primary registration.  If it isn't then we set the
2474
+		//primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2475
+		//primary registration object (that way we know if we need to show create button or not)
2476
+		if ( ! $this->_registration->is_primary_registrant()) {
2477
+			$primary_registration = $this->_registration->get_primary_registration();
2478
+			$primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2479
+				: null;
2480
+			if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2481
+				//in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2482
+				//custom attendee object so let's not worry about the primary reg.
2483
+				$primary_registration = null;
2484
+			}
2485
+		} else {
2486
+			$primary_registration = null;
2487
+		}
2488
+		$this->_template_args['ATT_ID']            = $attendee->ID();
2489
+		$this->_template_args['fname']             = $attendee->fname();
2490
+		$this->_template_args['lname']             = $attendee->lname();
2491
+		$this->_template_args['email']             = $attendee->email();
2492
+		$this->_template_args['phone']             = $attendee->phone();
2493
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2494
+		//edit link
2495
+		$this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2496
+			'action' => 'edit_attendee',
2497
+			'post'   => $attendee->ID(),
2498
+		), REG_ADMIN_URL);
2499
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2500
+		//create link
2501
+		$this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2502
+			? EE_Admin_Page::add_query_args_and_nonce(array(
2503
+				'action'  => 'duplicate_attendee',
2504
+				'_REG_ID' => $this->_registration->ID(),
2505
+			), REG_ADMIN_URL) : '';
2506
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2507
+		$this->_template_args['att_check']    = $att_check;
2508
+		$template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2509
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2510
+	}
2511
+
2512
+
2513
+	/**
2514
+	 * trash or restore registrations
2515
+	 *
2516
+	 * @param  boolean $trash whether to archive or restore
2517
+	 * @return void
2518
+	 * @throws EE_Error
2519
+	 * @throws RuntimeException
2520
+	 * @access protected
2521
+	 */
2522
+	protected function _trash_or_restore_registrations($trash = true)
2523
+	{
2524
+		//if empty _REG_ID then get out because there's nothing to do
2525
+		if (empty($this->_req_data['_REG_ID'])) {
2526
+			EE_Error::add_error(
2527
+				sprintf(
2528
+					esc_html__(
2529
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2530
+						'event_espresso'
2531
+					),
2532
+					$trash ? 'trash' : 'restore'
2533
+				),
2534
+				__FILE__, __LINE__, __FUNCTION__
2535
+			);
2536
+			$this->_redirect_after_action(false, '', '', array(), true);
2537
+		}
2538
+		$success = 0;
2539
+		$overwrite_msgs = false;
2540
+		//Checkboxes
2541
+		if ( ! is_array($this->_req_data['_REG_ID'])) {
2542
+			$this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2543
+		}
2544
+		$reg_count = count($this->_req_data['_REG_ID']);
2545
+		// cycle thru checkboxes
2546
+		foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2547
+			/** @var EE_Registration $REG */
2548
+			$REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2549
+			$payments = $REG->registration_payments();
2550
+			if (! empty($payments)) {
2551
+				$name = $REG->attendee() instanceof EE_Attendee
2552
+					? $REG->attendee()->full_name()
2553
+					: esc_html__('Unknown Attendee', 'event_espresso');
2554
+				$overwrite_msgs = true;
2555
+				EE_Error::add_error(
2556
+					sprintf(
2557
+						esc_html__(
2558
+							'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2559
+							'event_espresso'
2560
+						),
2561
+						$name
2562
+					),
2563
+					__FILE__, __FUNCTION__, __LINE__
2564
+				);
2565
+				//can't trash this registration because it has payments.
2566
+				continue;
2567
+			}
2568
+			$updated = $trash ? $REG->delete() : $REG->restore();
2569
+			if ($updated) {
2570
+				$success++;
2571
+			}
2572
+		}
2573
+		$this->_redirect_after_action(
2574
+			$success === $reg_count, // were ALL registrations affected?
2575
+			$success > 1
2576
+				? esc_html__('Registrations', 'event_espresso')
2577
+				: esc_html__('Registration', 'event_espresso'),
2578
+			$trash
2579
+				? esc_html__('moved to the trash', 'event_espresso')
2580
+				: esc_html__('restored', 'event_espresso'),
2581
+			array('action' => 'default'),
2582
+			$overwrite_msgs
2583
+		);
2584
+	}
2585
+
2586
+
2587
+	/**
2588
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2589
+	 * registration but also.
2590
+	 * 1. Removing relations to EE_Attendee
2591
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2592
+	 * ALSO trashed.
2593
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2594
+	 * 4. Removing relationships between all tickets and the related registrations
2595
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2596
+	 * 6. Deleting permanently any related Checkins.
2597
+	 *
2598
+	 * @return void
2599
+	 * @throws EE_Error
2600
+	 */
2601
+	protected function _delete_registrations()
2602
+	{
2603
+		$REG_MDL = EEM_Registration::instance();
2604
+		$success = 1;
2605
+		//Checkboxes
2606
+		if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2607
+			// if array has more than one element than success message should be plural
2608
+			$success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2609
+			// cycle thru checkboxes
2610
+			while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
2611
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2612
+				if ( ! $REG instanceof EE_Registration) {
2613
+					continue;
2614
+				}
2615
+				$deleted = $this->_delete_registration($REG);
2616
+				if ( ! $deleted) {
2617
+					$success = 0;
2618
+				}
2619
+			}
2620
+		} else {
2621
+			// grab single id and delete
2622
+			$REG_ID  = $this->_req_data['_REG_ID'];
2623
+			$REG     = $REG_MDL->get_one_by_ID($REG_ID);
2624
+			$deleted = $this->_delete_registration($REG);
2625
+			if ( ! $deleted) {
2626
+				$success = 0;
2627
+			}
2628
+		}
2629
+		$what        = $success > 1
2630
+			? esc_html__('Registrations', 'event_espresso')
2631
+			: esc_html__('Registration', 'event_espresso');
2632
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2633
+		$this->_redirect_after_action(
2634
+			$success,
2635
+			$what,
2636
+			$action_desc,
2637
+			array('action' => 'default'),
2638
+			true
2639
+		);
2640
+	}
2641
+
2642
+
2643
+	/**
2644
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2645
+	 * models get affected.
2646
+	 *
2647
+	 * @param  EE_Registration $REG registration to be deleted permenantly
2648
+	 * @return bool true = successful deletion, false = fail.
2649
+	 * @throws EE_Error
2650
+	 */
2651
+	protected function _delete_registration(EE_Registration $REG)
2652
+	{
2653
+		//first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2654
+		//registrations on the transaction that are NOT trashed.
2655
+		$TXN         = $REG->get_first_related('Transaction');
2656
+		$REGS        = $TXN->get_many_related('Registration');
2657
+		$all_trashed = true;
2658
+		foreach ($REGS as $registration) {
2659
+			if ( ! $registration->get('REG_deleted')) {
2660
+				$all_trashed = false;
2661
+			}
2662
+		}
2663
+		if ( ! $all_trashed) {
2664
+			EE_Error::add_error(
2665
+				esc_html__(
2666
+					'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2667
+					'event_espresso'
2668
+				),
2669
+				__FILE__, __FUNCTION__, __LINE__
2670
+			);
2671
+			return false;
2672
+		}
2673
+		//k made it here so that means we can delete all the related transactions and their answers (but let's do them
2674
+		//separately from THIS one).
2675
+		foreach ($REGS as $registration) {
2676
+			//delete related answers
2677
+			$registration->delete_related_permanently('Answer');
2678
+			//remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2679
+			$attendee = $registration->get_first_related('Attendee');
2680
+			if ($attendee instanceof EE_Attendee) {
2681
+				$registration->_remove_relation_to($attendee, 'Attendee');
2682
+			}
2683
+			//now remove relationships to tickets on this registration.
2684
+			$registration->_remove_relations('Ticket');
2685
+			//now delete permanently the checkins related to this registration.
2686
+			$registration->delete_related_permanently('Checkin');
2687
+			if ($registration->ID() === $REG->ID()) {
2688
+				continue;
2689
+			} //we don't want to delete permanently the existing registration just yet.
2690
+			//remove relation to transaction for these registrations if NOT the existing registrations
2691
+			$registration->_remove_relations('Transaction');
2692
+			//delete permanently any related messages.
2693
+			$registration->delete_related_permanently('Message');
2694
+			//now delete this registration permanently
2695
+			$registration->delete_permanently();
2696
+		}
2697
+		//now all related registrations on the transaction are handled.  So let's just handle this registration itself
2698
+		// (the transaction and line items should be all that's left).
2699
+		// delete the line items related to the transaction for this registration.
2700
+		$TXN->delete_related_permanently('Line_Item');
2701
+		//we need to remove all the relationships on the transaction
2702
+		$TXN->delete_related_permanently('Payment');
2703
+		$TXN->delete_related_permanently('Extra_Meta');
2704
+		$TXN->delete_related_permanently('Message');
2705
+		//now we can delete this REG permanently (and the transaction of course)
2706
+		$REG->delete_related_permanently('Transaction');
2707
+		return $REG->delete_permanently();
2708
+	}
2709
+
2710
+
2711
+	/**
2712
+	 *    generates HTML for the Register New Attendee Admin page
2713
+	 *
2714
+	 * @access private
2715
+	 * @throws DomainException
2716
+	 * @throws EE_Error
2717
+	 */
2718
+	public function new_registration()
2719
+	{
2720
+		if ( ! $this->_set_reg_event()) {
2721
+			throw new EE_Error(
2722
+				esc_html__(
2723
+					'Unable to continue with registering because there is no Event ID in the request',
2724
+					'event_espresso'
2725
+				)
2726
+			);
2727
+		}
2728
+		EE_Registry::instance()->REQ->set_espresso_page(true);
2729
+		// gotta start with a clean slate if we're not coming here via ajax
2730
+		if ( ! defined('DOING_AJAX')
2731
+			 && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2732
+		) {
2733
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2734
+		}
2735
+		$this->_template_args['event_name'] = '';
2736
+		// event name
2737
+		if ($this->_reg_event) {
2738
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2739
+			$edit_event_url                     = self::add_query_args_and_nonce(array(
2740
+				'action' => 'edit',
2741
+				'post'   => $this->_reg_event->ID(),
2742
+			), EVENTS_ADMIN_URL);
2743
+			$edit_event_lnk                     = '<a href="'
2744
+												  . $edit_event_url
2745
+												  . '" title="'
2746
+												  . esc_attr__('Edit ', 'event_espresso')
2747
+												  . $this->_reg_event->name()
2748
+												  . '">'
2749
+												  . esc_html__('Edit Event', 'event_espresso')
2750
+												  . '</a>';
2751
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2752
+												   . $edit_event_lnk
2753
+												   . '</span>';
2754
+		}
2755
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2756
+		if (defined('DOING_AJAX')) {
2757
+			$this->_return_json();
2758
+		}
2759
+		// grab header
2760
+		$template_path                              =
2761
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2762
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2763
+			$this->_template_args, true);
2764
+		//$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2765
+		// the details template wrapper
2766
+		$this->display_admin_page_with_sidebar();
2767
+	}
2768
+
2769
+
2770
+	/**
2771
+	 * This returns the content for a registration step
2772
+	 *
2773
+	 * @access protected
2774
+	 * @return string html
2775
+	 * @throws DomainException
2776
+	 * @throws EE_Error
2777
+	 */
2778
+	protected function _get_registration_step_content()
2779
+	{
2780
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2781
+			$warning_msg = sprintf(
2782
+				esc_html__(
2783
+					'%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2784
+					'event_espresso'
2785
+				),
2786
+				'<br />',
2787
+				'<h3 class="important-notice">',
2788
+				'</h3>',
2789
+				'<div class="float-right">',
2790
+				'<span id="redirect_timer" class="important-notice">30</span>',
2791
+				'</div>',
2792
+				'<b>',
2793
+				'</b>'
2794
+			);
2795
+			return '
2796 2796
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2797 2797
 	<script >
2798 2798
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2805,792 +2805,792 @@  discard block
 block discarded – undo
2805 2805
 	        }
2806 2806
 	    }, 800 );
2807 2807
 	</script >';
2808
-        }
2809
-        $template_args = array(
2810
-            'title'                    => '',
2811
-            'content'                  => '',
2812
-            'step_button_text'         => '',
2813
-            'show_notification_toggle' => false,
2814
-        );
2815
-        //to indicate we're processing a new registration
2816
-        $hidden_fields = array(
2817
-            'processing_registration' => array(
2818
-                'type'  => 'hidden',
2819
-                'value' => 0,
2820
-            ),
2821
-            'event_id'                => array(
2822
-                'type'  => 'hidden',
2823
-                'value' => $this->_reg_event->ID(),
2824
-            ),
2825
-        );
2826
-        //if the cart is empty then we know we're at step one so we'll display ticket selector
2827
-        $cart = EE_Registry::instance()->SSN->cart();
2828
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2829
-        switch ($step) {
2830
-            case 'ticket' :
2831
-                $hidden_fields['processing_registration']['value'] = 1;
2832
-                $template_args['title']                            = esc_html__(
2833
-                    'Step One: Select the Ticket for this registration',
2834
-                    'event_espresso'
2835
-                );
2836
-                $template_args['content']                          =
2837
-                    EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2838
-                $template_args['step_button_text']                 = esc_html__(
2839
-                    'Add Tickets and Continue to Registrant Details',
2840
-                    'event_espresso'
2841
-                );
2842
-                $template_args['show_notification_toggle']         = false;
2843
-                break;
2844
-            case 'questions' :
2845
-                $hidden_fields['processing_registration']['value'] = 2;
2846
-                $template_args['title']                            = esc_html__(
2847
-                    'Step Two: Add Registrant Details for this Registration',
2848
-                    'event_espresso'
2849
-                );
2850
-                //in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2851
-                // properly by the first process_reg_step run.
2852
-                $template_args['content']                  =
2853
-                    EED_Single_Page_Checkout::registration_checkout_for_admin();
2854
-                $template_args['step_button_text']         = esc_html__(
2855
-                    'Save Registration and Continue to Details',
2856
-                    'event_espresso'
2857
-                );
2858
-                $template_args['show_notification_toggle'] = true;
2859
-                break;
2860
-        }
2861
-        //we come back to the process_registration_step route.
2862
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2863
-        return EEH_Template::display_template(
2864
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2865
-            $template_args,
2866
-            true
2867
-        );
2868
-    }
2869
-
2870
-
2871
-    /**
2872
-     *        set_reg_event
2873
-     *
2874
-     * @access private
2875
-     * @return bool
2876
-     * @throws EE_Error
2877
-     */
2878
-    private function _set_reg_event()
2879
-    {
2880
-        if (is_object($this->_reg_event)) {
2881
-            return true;
2882
-        }
2883
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2884
-        if ( ! $EVT_ID) {
2885
-            return false;
2886
-        }
2887
-        $this->_reg_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2888
-        return true;
2889
-    }
2890
-
2891
-
2892
-    /**
2893
-     * process_reg_step
2894
-     *
2895
-     * @access        public
2896
-     * @return string
2897
-     * @throws DomainException
2898
-     * @throws EE_Error
2899
-     * @throws RuntimeException
2900
-     */
2901
-    public function process_reg_step()
2902
-    {
2903
-        EE_System::do_not_cache();
2904
-        $this->_set_reg_event();
2905
-        EE_Registry::instance()->REQ->set_espresso_page(true);
2906
-        EE_Registry::instance()->REQ->set('uts', time());
2907
-        //what step are we on?
2908
-        $cart = EE_Registry::instance()->SSN->cart();
2909
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2910
-        //if doing ajax then we need to verify the nonce
2911
-        if (defined('DOING_AJAX')) {
2912
-            $nonce = isset($this->_req_data[$this->_req_nonce])
2913
-                ? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
2914
-            $this->_verify_nonce($nonce, $this->_req_nonce);
2915
-        }
2916
-        switch ($step) {
2917
-            case 'ticket' :
2918
-                //process ticket selection
2919
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
2920
-                if ($success) {
2921
-                    EE_Error::add_success(
2922
-                        esc_html__(
2923
-                            'Tickets Selected. Now complete the registration.',
2924
-                            'event_espresso'
2925
-                        )
2926
-                    );
2927
-                } else {
2928
-                    $query_args['step_error'] = $this->_req_data['step_error'] = true;
2929
-                }
2930
-                if (defined('DOING_AJAX')) {
2931
-                    $this->new_registration(); //display next step
2932
-                } else {
2933
-                    $query_args = array(
2934
-                        'action'                  => 'new_registration',
2935
-                        'processing_registration' => 1,
2936
-                        'event_id'                => $this->_reg_event->ID(),
2937
-                        'uts'                     => time(),
2938
-                    );
2939
-                    $this->_redirect_after_action(
2940
-                        false,
2941
-                        '',
2942
-                        '',
2943
-                        $query_args,
2944
-                        true
2945
-                    );
2946
-                }
2947
-                break;
2948
-            case 'questions' :
2949
-                if (! isset(
2950
-                    $this->_req_data['txn_reg_status_change'],
2951
-                    $this->_req_data['txn_reg_status_change']['send_notifications'])
2952
-                ) {
2953
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
2954
-                }
2955
-                //process registration
2956
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
2957
-                if ($cart instanceof EE_Cart) {
2958
-                    $grand_total = $cart->get_cart_grand_total();
2959
-                    if ($grand_total instanceof EE_Line_Item) {
2960
-                        $grand_total->save_this_and_descendants_to_txn();
2961
-                    }
2962
-                }
2963
-                if ( ! $transaction instanceof EE_Transaction) {
2964
-                    $query_args = array(
2965
-                        'action'                  => 'new_registration',
2966
-                        'processing_registration' => 2,
2967
-                        'event_id'                => $this->_reg_event->ID(),
2968
-                        'uts'                     => time(),
2969
-                    );
2970
-                    if (defined('DOING_AJAX')) {
2971
-                        //display registration form again because there are errors (maybe validation?)
2972
-                        $this->new_registration();
2973
-                        return;
2974
-                    } else {
2975
-                        $this->_redirect_after_action(
2976
-                            false,
2977
-                            '',
2978
-                            '',
2979
-                            $query_args,
2980
-                            true
2981
-                        );
2982
-                        return;
2983
-                    }
2984
-                }
2985
-                // maybe update status, and make sure to save transaction if not done already
2986
-                if ( ! $transaction->update_status_based_on_total_paid()) {
2987
-                    $transaction->save();
2988
-                }
2989
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2990
-                $this->_req_data = array();
2991
-                $query_args      = array(
2992
-                    'action'        => 'redirect_to_txn',
2993
-                    'TXN_ID'        => $transaction->ID(),
2994
-                    'EVT_ID'        => $this->_reg_event->ID(),
2995
-                    'event_name'    => urlencode($this->_reg_event->name()),
2996
-                    'redirect_from' => 'new_registration',
2997
-                );
2998
-                $this->_redirect_after_action(false, '', '', $query_args, true);
2999
-                break;
3000
-        }
3001
-        //what are you looking here for?  Should be nothing to do at this point.
3002
-    }
3003
-
3004
-
3005
-    /**
3006
-     * redirect_to_txn
3007
-     *
3008
-     * @access public
3009
-     * @return void
3010
-     * @throws EE_Error
3011
-     */
3012
-    public function redirect_to_txn()
3013
-    {
3014
-        EE_System::do_not_cache();
3015
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3016
-        $query_args = array(
3017
-            'action' => 'view_transaction',
3018
-            'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3019
-            'page'   => 'espresso_transactions',
3020
-        );
3021
-        if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3022
-            $query_args['EVT_ID']        = $this->_req_data['EVT_ID'];
3023
-            $query_args['event_name']    = urlencode($this->_req_data['event_name']);
3024
-            $query_args['redirect_from'] = $this->_req_data['redirect_from'];
3025
-        }
3026
-        EE_Error::add_success(
3027
-            esc_html__(
3028
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3029
-                'event_espresso'
3030
-            )
3031
-        );
3032
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3033
-    }
3034
-
3035
-
3036
-    /**
3037
-     *        generates HTML for the Attendee Contact List
3038
-     *
3039
-     * @access protected
3040
-     * @return void
3041
-     */
3042
-    protected function _attendee_contact_list_table()
3043
-    {
3044
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3045
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3046
-        $this->display_admin_list_table_page_with_no_sidebar();
3047
-    }
3048
-
3049
-
3050
-    /**
3051
-     *        get_attendees
3052
-     *
3053
-     * @param      $per_page
3054
-     * @param bool $count whether to return count or data.
3055
-     * @param bool $trash
3056
-     * @return array
3057
-     * @throws EE_Error
3058
-     * @access public
3059
-     */
3060
-    public function get_attendees($per_page, $count = false, $trash = false)
3061
-    {
3062
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3063
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3064
-        $ATT_MDL                    = EEM_Attendee::instance();
3065
-        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3066
-        switch ($this->_req_data['orderby']) {
3067
-            case 'ATT_ID':
3068
-                $orderby = 'ATT_ID';
3069
-                break;
3070
-            case 'ATT_fname':
3071
-                $orderby = 'ATT_fname';
3072
-                break;
3073
-            case 'ATT_email':
3074
-                $orderby = 'ATT_email';
3075
-                break;
3076
-            case 'ATT_city':
3077
-                $orderby = 'ATT_city';
3078
-                break;
3079
-            case 'STA_ID':
3080
-                $orderby = 'STA_ID';
3081
-                break;
3082
-            case 'CNT_ID':
3083
-                $orderby = 'CNT_ID';
3084
-                break;
3085
-            default:
3086
-                $orderby = 'ATT_lname';
3087
-        }
3088
-        $sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3089
-            ? $this->_req_data['order']
3090
-            : 'ASC';
3091
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3092
-            ? $this->_req_data['paged']
3093
-            : 1;
3094
-        $per_page     = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3095
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3096
-            ? $this->_req_data['perpage']
3097
-            : $per_page;
3098
-        $_where       = array();
3099
-        if ( ! empty($this->_req_data['s'])) {
3100
-            $sstr         = '%' . $this->_req_data['s'] . '%';
3101
-            $_where['OR'] = array(
3102
-                'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3103
-                'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3104
-                'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3105
-                'ATT_fname'                         => array('LIKE', $sstr),
3106
-                'ATT_lname'                         => array('LIKE', $sstr),
3107
-                'ATT_short_bio'                     => array('LIKE', $sstr),
3108
-                'ATT_email'                         => array('LIKE', $sstr),
3109
-                'ATT_address'                       => array('LIKE', $sstr),
3110
-                'ATT_address2'                      => array('LIKE', $sstr),
3111
-                'ATT_city'                          => array('LIKE', $sstr),
3112
-                'Country.CNT_name'                  => array('LIKE', $sstr),
3113
-                'State.STA_name'                    => array('LIKE', $sstr),
3114
-                'ATT_phone'                         => array('LIKE', $sstr),
3115
-                'Registration.REG_final_price'      => array('LIKE', $sstr),
3116
-                'Registration.REG_code'             => array('LIKE', $sstr),
3117
-                'Registration.REG_count'            => array('LIKE', $sstr),
3118
-                'Registration.REG_group_size'       => array('LIKE', $sstr),
3119
-            );
3120
-        }
3121
-        $offset = ($current_page - 1) * $per_page;
3122
-        $limit  = $count ? null : array($offset, $per_page);
3123
-        if ($trash) {
3124
-            $_where['status'] = array('!=', 'publish');
3125
-            $all_attendees    = $count
3126
-                ? $ATT_MDL->count(array(
3127
-                    $_where,
3128
-                    'order_by' => array($orderby => $sort),
3129
-                    'limit'    => $limit,
3130
-                ), 'ATT_ID', true)
3131
-                : $ATT_MDL->get_all(array(
3132
-                    $_where,
3133
-                    'order_by' => array($orderby => $sort),
3134
-                    'limit'    => $limit,
3135
-                ));
3136
-        } else {
3137
-            $_where['status'] = array('IN', array('publish'));
3138
-            $all_attendees    = $count
3139
-                ? $ATT_MDL->count(array(
3140
-                    $_where,
3141
-                    'order_by' => array($orderby => $sort),
3142
-                    'limit'    => $limit,
3143
-                ), 'ATT_ID', true)
3144
-                : $ATT_MDL->get_all(array(
3145
-                    $_where,
3146
-                    'order_by' => array($orderby => $sort),
3147
-                    'limit'    => $limit,
3148
-                ));
3149
-        }
3150
-        return $all_attendees;
3151
-    }
3152
-
3153
-
3154
-    /**
3155
-     * This is just taking care of resending the registration confirmation
3156
-     *
3157
-     * @access protected
3158
-     * @return void
3159
-     */
3160
-    protected function _resend_registration()
3161
-    {
3162
-        $this->_process_resend_registration();
3163
-        $query_args = isset($this->_req_data['redirect_to'])
3164
-            ? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3165
-            : array('action' => 'default');
3166
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3167
-    }
3168
-
3169
-    /**
3170
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3171
-     * to use when selecting registrations
3172
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3173
-     *                                                     the query parameters from the request
3174
-     * @return void ends the request with a redirect or download
3175
-     */
3176
-    public function _registrations_report_base( $method_name_for_getting_query_params )
3177
-    {
3178
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3179
-            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3180
-                array(
3181
-                    'page'        => 'espresso_batch',
3182
-                    'batch'       => 'file',
3183
-                    'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3184
-                    'filters'     => urlencode(
3185
-                        serialize(
3186
-                            call_user_func(
3187
-                                array( $this, $method_name_for_getting_query_params ),
3188
-                                EEH_Array::is_set(
3189
-                                    $this->_req_data,
3190
-                                    'filters',
3191
-                                    array()
3192
-                                )
3193
-                            )
3194
-                        )
3195
-                ),
3196
-                'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3197
-                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3198
-                'return_url'  => urlencode($this->_req_data['return_url']),
3199
-            )));
3200
-        } else {
3201
-            $new_request_args = array(
3202
-                'export' => 'report',
3203
-                'action' => 'registrations_report_for_event',
3204
-                'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3205
-            );
3206
-            $this->_req_data = array_merge($this->_req_data, $new_request_args);
3207
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3208
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3209
-                $EE_Export = EE_Export::instance($this->_req_data);
3210
-                $EE_Export->export();
3211
-            }
3212
-        }
3213
-    }
3214
-
3215
-
3216
-
3217
-    /**
3218
-     * Creates a registration report using only query parameters in the request
3219
-     * @return void
3220
-     */
3221
-    public function _registrations_report()
3222
-    {
3223
-        $this->_registrations_report_base('_get_registration_query_parameters');
3224
-    }
3225
-
3226
-
3227
-    public function _contact_list_export()
3228
-    {
3229
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3230
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3231
-            $EE_Export = EE_Export::instance($this->_req_data);
3232
-            $EE_Export->export_attendees();
3233
-        }
3234
-    }
3235
-
3236
-
3237
-    public function _contact_list_report()
3238
-    {
3239
-        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3240
-            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
3241
-                'page'        => 'espresso_batch',
3242
-                'batch'       => 'file',
3243
-                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3244
-                'return_url'  => urlencode($this->_req_data['return_url']),
3245
-            )));
3246
-        } else {
3247
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3248
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3249
-                $EE_Export = EE_Export::instance($this->_req_data);
3250
-                $EE_Export->report_attendees();
3251
-            }
3252
-        }
3253
-    }
3254
-
3255
-
3256
-
3257
-
3258
-
3259
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3260
-    /**
3261
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3262
-     *
3263
-     * @return void
3264
-     * @throws EE_Error
3265
-     */
3266
-    protected function _duplicate_attendee()
3267
-    {
3268
-        $action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3269
-        //verify we have necessary info
3270
-        if (empty($this->_req_data['_REG_ID'])) {
3271
-            EE_Error::add_error(
3272
-                esc_html__(
3273
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3274
-                    'event_espresso'
3275
-                ), __FILE__, __LINE__, __FUNCTION__
3276
-            );
3277
-            $query_args = array('action' => $action);
3278
-            $this->_redirect_after_action('', '', '', $query_args, true);
3279
-        }
3280
-        //okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3281
-        $registration = EEM_Registration::instance()->get_one_by_ID($this->_req_data['_REG_ID']);
3282
-        $attendee     = $registration->attendee();
3283
-        //remove relation of existing attendee on registration
3284
-        $registration->_remove_relation_to($attendee, 'Attendee');
3285
-        //new attendee
3286
-        $new_attendee = clone $attendee;
3287
-        $new_attendee->set('ATT_ID', 0);
3288
-        $new_attendee->save();
3289
-        //add new attendee to reg
3290
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3291
-        EE_Error::add_success(
3292
-            esc_html__(
3293
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3294
-                'event_espresso'
3295
-            )
3296
-        );
3297
-        //redirect to edit page for attendee
3298
-        $query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3299
-        $this->_redirect_after_action('', '', '', $query_args, true);
3300
-    }
3301
-
3302
-
3303
-    //related to cpt routes
3304
-    protected function _insert_update_cpt_item($post_id, $post)
3305
-    {
3306
-        $success  = true;
3307
-        $attendee = EEM_Attendee::instance()->get_one_by_ID($post_id);
3308
-        //for attendee updates
3309
-        if ($post->post_type = 'espresso_attendees' && ! empty($attendee)) {
3310
-            //note we should only be UPDATING attendees at this point.
3311
-            $updated_fields = array(
3312
-                'ATT_fname'     => $this->_req_data['ATT_fname'],
3313
-                'ATT_lname'     => $this->_req_data['ATT_lname'],
3314
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3315
-                'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3316
-                'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3317
-                'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3318
-                'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3319
-                'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3320
-                'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3321
-                'ATT_email'     => isset($this->_req_data['ATT_email']) ? $this->_req_data['ATT_email'] : '',
3322
-                'ATT_phone'     => isset($this->_req_data['ATT_phone']) ? $this->_req_data['ATT_phone'] : '',
3323
-            );
3324
-            foreach ($updated_fields as $field => $value) {
3325
-                $attendee->set($field, $value);
3326
-            }
3327
-            $success                   = $attendee->save();
3328
-            $attendee_update_callbacks = apply_filters(
3329
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3330
-                array()
3331
-            );
3332
-            foreach ($attendee_update_callbacks as $a_callback) {
3333
-                if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3334
-                    throw new EE_Error(
3335
-                        sprintf(
3336
-                            esc_html__(
3337
-                                'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3338
-                                'event_espresso'
3339
-                            ),
3340
-                            $a_callback
3341
-                        )
3342
-                    );
3343
-                }
3344
-            }
3345
-        }
3346
-        if ($success === false) {
3347
-            EE_Error::add_error(
3348
-                esc_html__(
3349
-                    'Something went wrong with updating the meta table data for the registration.',
3350
-                    'event_espresso'
3351
-                ),
3352
-                __FILE__, __FUNCTION__, __LINE__
3353
-            );
3354
-        }
3355
-    }
3356
-
3357
-
3358
-    public function trash_cpt_item($post_id)
3359
-    {
3360
-    }
3361
-
3362
-
3363
-    public function delete_cpt_item($post_id)
3364
-    {
3365
-    }
3366
-
3367
-
3368
-    public function restore_cpt_item($post_id)
3369
-    {
3370
-    }
3371
-
3372
-
3373
-    protected function _restore_cpt_item($post_id, $revision_id)
3374
-    {
3375
-    }
3376
-
3377
-
3378
-    public function attendee_editor_metaboxes()
3379
-    {
3380
-        $this->verify_cpt_object();
3381
-        remove_meta_box(
3382
-            'postexcerpt',
3383
-            esc_html__('Excerpt', 'event_espresso'),
3384
-            'post_excerpt_meta_box',
3385
-            $this->_cpt_routes[$this->_req_action],
3386
-            'normal',
3387
-            'core'
3388
-        );
3389
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
3390
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3391
-            add_meta_box(
3392
-                'postexcerpt',
3393
-                esc_html__('Short Biography', 'event_espresso'),
3394
-                'post_excerpt_meta_box',
3395
-                $this->_cpt_routes[$this->_req_action],
3396
-                'normal'
3397
-            );
3398
-        }
3399
-        if (post_type_supports('espresso_attendees', 'comments')) {
3400
-            add_meta_box(
3401
-                'commentsdiv',
3402
-                esc_html__('Notes on the Contact', 'event_espresso'),
3403
-                'post_comment_meta_box',
3404
-                $this->_cpt_routes[$this->_req_action],
3405
-                'normal',
3406
-                'core'
3407
-            );
3408
-        }
3409
-        add_meta_box(
3410
-            'attendee_contact_info',
3411
-            esc_html__('Contact Info', 'event_espresso'),
3412
-            array($this, 'attendee_contact_info'),
3413
-            $this->_cpt_routes[$this->_req_action],
3414
-            'side',
3415
-            'core'
3416
-        );
3417
-        add_meta_box(
3418
-            'attendee_details_address',
3419
-            esc_html__('Address Details', 'event_espresso'),
3420
-            array($this, 'attendee_address_details'),
3421
-            $this->_cpt_routes[$this->_req_action],
3422
-            'normal',
3423
-            'core'
3424
-        );
3425
-        add_meta_box(
3426
-            'attendee_registrations',
3427
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3428
-            array($this, 'attendee_registrations_meta_box'),
3429
-            $this->_cpt_routes[$this->_req_action],
3430
-            'normal',
3431
-            'high'
3432
-        );
3433
-    }
3434
-
3435
-
3436
-    /**
3437
-     * Metabox for attendee contact info
3438
-     *
3439
-     * @param  WP_Post $post wp post object
3440
-     * @return string attendee contact info ( and form )
3441
-     * @throws DomainException
3442
-     */
3443
-    public function attendee_contact_info($post)
3444
-    {
3445
-        //get attendee object ( should already have it )
3446
-        $this->_template_args['attendee'] = $this->_cpt_model_obj;
3447
-        $template                         = REG_TEMPLATE_PATH . 'attendee_contact_info_metabox_content.template.php';
3448
-        EEH_Template::display_template($template, $this->_template_args);
3449
-    }
3450
-
3451
-
3452
-    /**
3453
-     * Metabox for attendee details
3454
-     *
3455
-     * @param  WP_Post $post wp post object
3456
-     * @return string attendee address details (and form)
3457
-     * @throws DomainException
3458
-     */
3459
-    public function attendee_address_details($post)
3460
-    {
3461
-        //get attendee object (should already have it)
3462
-        $this->_template_args['attendee']     = $this->_cpt_model_obj;
3463
-        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3464
-            new EE_Question_Form_Input(
3465
-                EE_Question::new_instance(
3466
-                    array(
3467
-                        'QST_ID'           => 0,
3468
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3469
-                        'QST_system'       => 'admin-state',
3470
-                    )
3471
-                ),
3472
-                EE_Answer::new_instance(
3473
-                    array(
3474
-                        'ANS_ID'    => 0,
3475
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3476
-                    )
3477
-                ),
3478
-                array(
3479
-                    'input_id'       => 'STA_ID',
3480
-                    'input_name'     => 'STA_ID',
3481
-                    'input_prefix'   => '',
3482
-                    'append_qstn_id' => false,
3483
-                )
3484
-            )
3485
-        );
3486
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3487
-            new EE_Question_Form_Input(
3488
-                EE_Question::new_instance(
3489
-                    array(
3490
-                        'QST_ID'           => 0,
3491
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3492
-                        'QST_system'       => 'admin-country',
3493
-                    )
3494
-                ),
3495
-                EE_Answer::new_instance(
3496
-                    array(
3497
-                        'ANS_ID'    => 0,
3498
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3499
-                    )
3500
-                ),
3501
-                array(
3502
-                    'input_id'       => 'CNT_ISO',
3503
-                    'input_name'     => 'CNT_ISO',
3504
-                    'input_prefix'   => '',
3505
-                    'append_qstn_id' => false,
3506
-                )
3507
-            )
3508
-        );
3509
-        $template                             =
3510
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3511
-        EEH_Template::display_template($template, $this->_template_args);
3512
-    }
3513
-
3514
-
3515
-    /**
3516
-     *        _attendee_details
3517
-     *
3518
-     * @access protected
3519
-     * @param $post
3520
-     * @return void
3521
-     * @throws DomainException
3522
-     * @throws EE_Error
3523
-     */
3524
-    public function attendee_registrations_meta_box($post)
3525
-    {
3526
-        $this->_template_args['attendee']      = $this->_cpt_model_obj;
3527
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3528
-        $template                              =
3529
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3530
-        EEH_Template::display_template($template, $this->_template_args);
3531
-    }
3532
-
3533
-
3534
-    /**
3535
-     * add in the form fields for the attendee edit
3536
-     *
3537
-     * @param  WP_Post $post wp post object
3538
-     * @return string html for new form.
3539
-     * @throws DomainException
3540
-     */
3541
-    public function after_title_form_fields($post)
3542
-    {
3543
-        if ($post->post_type == 'espresso_attendees') {
3544
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3545
-            $template_args['attendee'] = $this->_cpt_model_obj;
3546
-            EEH_Template::display_template($template, $template_args);
3547
-        }
3548
-    }
3549
-
3550
-
3551
-    /**
3552
-     *        _trash_or_restore_attendee
3553
-     *
3554
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3555
-     * @return void
3556
-     * @throws EE_Error
3557
-     * @access protected
3558
-     */
3559
-    protected function _trash_or_restore_attendees($trash = true)
3560
-    {
3561
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3562
-        $ATT_MDL = EEM_Attendee::instance();
3563
-        $success = 1;
3564
-        //Checkboxes
3565
-        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3566
-            // if array has more than one element than success message should be plural
3567
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3568
-            // cycle thru checkboxes
3569
-            while (list($ATT_ID, $value) = each($this->_req_data['checkbox'])) {
3570
-                $updated = $trash ? $ATT_MDL->update_by_ID(array('status' => 'trash'), $ATT_ID)
3571
-                    : $ATT_MDL->update_by_ID(array('status' => 'publish'), $ATT_ID);
3572
-                if ( ! $updated) {
3573
-                    $success = 0;
3574
-                }
3575
-            }
3576
-        } else {
3577
-            // grab single id and delete
3578
-            $ATT_ID = absint($this->_req_data['ATT_ID']);
3579
-            //get attendee
3580
-            $att     = $ATT_MDL->get_one_by_ID($ATT_ID);
3581
-            $updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3582
-            $updated = $att->save();
3583
-            if ( ! $updated) {
3584
-                $success = 0;
3585
-            }
3586
-        }
3587
-        $what        = $success > 1
3588
-            ? esc_html__('Contacts', 'event_espresso')
3589
-            : esc_html__('Contact', 'event_espresso');
3590
-        $action_desc = $trash
3591
-            ? esc_html__('moved to the trash', 'event_espresso')
3592
-            : esc_html__('restored', 'event_espresso');
3593
-        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3594
-    }
2808
+		}
2809
+		$template_args = array(
2810
+			'title'                    => '',
2811
+			'content'                  => '',
2812
+			'step_button_text'         => '',
2813
+			'show_notification_toggle' => false,
2814
+		);
2815
+		//to indicate we're processing a new registration
2816
+		$hidden_fields = array(
2817
+			'processing_registration' => array(
2818
+				'type'  => 'hidden',
2819
+				'value' => 0,
2820
+			),
2821
+			'event_id'                => array(
2822
+				'type'  => 'hidden',
2823
+				'value' => $this->_reg_event->ID(),
2824
+			),
2825
+		);
2826
+		//if the cart is empty then we know we're at step one so we'll display ticket selector
2827
+		$cart = EE_Registry::instance()->SSN->cart();
2828
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2829
+		switch ($step) {
2830
+			case 'ticket' :
2831
+				$hidden_fields['processing_registration']['value'] = 1;
2832
+				$template_args['title']                            = esc_html__(
2833
+					'Step One: Select the Ticket for this registration',
2834
+					'event_espresso'
2835
+				);
2836
+				$template_args['content']                          =
2837
+					EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2838
+				$template_args['step_button_text']                 = esc_html__(
2839
+					'Add Tickets and Continue to Registrant Details',
2840
+					'event_espresso'
2841
+				);
2842
+				$template_args['show_notification_toggle']         = false;
2843
+				break;
2844
+			case 'questions' :
2845
+				$hidden_fields['processing_registration']['value'] = 2;
2846
+				$template_args['title']                            = esc_html__(
2847
+					'Step Two: Add Registrant Details for this Registration',
2848
+					'event_espresso'
2849
+				);
2850
+				//in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2851
+				// properly by the first process_reg_step run.
2852
+				$template_args['content']                  =
2853
+					EED_Single_Page_Checkout::registration_checkout_for_admin();
2854
+				$template_args['step_button_text']         = esc_html__(
2855
+					'Save Registration and Continue to Details',
2856
+					'event_espresso'
2857
+				);
2858
+				$template_args['show_notification_toggle'] = true;
2859
+				break;
2860
+		}
2861
+		//we come back to the process_registration_step route.
2862
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2863
+		return EEH_Template::display_template(
2864
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2865
+			$template_args,
2866
+			true
2867
+		);
2868
+	}
2869
+
2870
+
2871
+	/**
2872
+	 *        set_reg_event
2873
+	 *
2874
+	 * @access private
2875
+	 * @return bool
2876
+	 * @throws EE_Error
2877
+	 */
2878
+	private function _set_reg_event()
2879
+	{
2880
+		if (is_object($this->_reg_event)) {
2881
+			return true;
2882
+		}
2883
+		$EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2884
+		if ( ! $EVT_ID) {
2885
+			return false;
2886
+		}
2887
+		$this->_reg_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2888
+		return true;
2889
+	}
2890
+
2891
+
2892
+	/**
2893
+	 * process_reg_step
2894
+	 *
2895
+	 * @access        public
2896
+	 * @return string
2897
+	 * @throws DomainException
2898
+	 * @throws EE_Error
2899
+	 * @throws RuntimeException
2900
+	 */
2901
+	public function process_reg_step()
2902
+	{
2903
+		EE_System::do_not_cache();
2904
+		$this->_set_reg_event();
2905
+		EE_Registry::instance()->REQ->set_espresso_page(true);
2906
+		EE_Registry::instance()->REQ->set('uts', time());
2907
+		//what step are we on?
2908
+		$cart = EE_Registry::instance()->SSN->cart();
2909
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2910
+		//if doing ajax then we need to verify the nonce
2911
+		if (defined('DOING_AJAX')) {
2912
+			$nonce = isset($this->_req_data[$this->_req_nonce])
2913
+				? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
2914
+			$this->_verify_nonce($nonce, $this->_req_nonce);
2915
+		}
2916
+		switch ($step) {
2917
+			case 'ticket' :
2918
+				//process ticket selection
2919
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
2920
+				if ($success) {
2921
+					EE_Error::add_success(
2922
+						esc_html__(
2923
+							'Tickets Selected. Now complete the registration.',
2924
+							'event_espresso'
2925
+						)
2926
+					);
2927
+				} else {
2928
+					$query_args['step_error'] = $this->_req_data['step_error'] = true;
2929
+				}
2930
+				if (defined('DOING_AJAX')) {
2931
+					$this->new_registration(); //display next step
2932
+				} else {
2933
+					$query_args = array(
2934
+						'action'                  => 'new_registration',
2935
+						'processing_registration' => 1,
2936
+						'event_id'                => $this->_reg_event->ID(),
2937
+						'uts'                     => time(),
2938
+					);
2939
+					$this->_redirect_after_action(
2940
+						false,
2941
+						'',
2942
+						'',
2943
+						$query_args,
2944
+						true
2945
+					);
2946
+				}
2947
+				break;
2948
+			case 'questions' :
2949
+				if (! isset(
2950
+					$this->_req_data['txn_reg_status_change'],
2951
+					$this->_req_data['txn_reg_status_change']['send_notifications'])
2952
+				) {
2953
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
2954
+				}
2955
+				//process registration
2956
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
2957
+				if ($cart instanceof EE_Cart) {
2958
+					$grand_total = $cart->get_cart_grand_total();
2959
+					if ($grand_total instanceof EE_Line_Item) {
2960
+						$grand_total->save_this_and_descendants_to_txn();
2961
+					}
2962
+				}
2963
+				if ( ! $transaction instanceof EE_Transaction) {
2964
+					$query_args = array(
2965
+						'action'                  => 'new_registration',
2966
+						'processing_registration' => 2,
2967
+						'event_id'                => $this->_reg_event->ID(),
2968
+						'uts'                     => time(),
2969
+					);
2970
+					if (defined('DOING_AJAX')) {
2971
+						//display registration form again because there are errors (maybe validation?)
2972
+						$this->new_registration();
2973
+						return;
2974
+					} else {
2975
+						$this->_redirect_after_action(
2976
+							false,
2977
+							'',
2978
+							'',
2979
+							$query_args,
2980
+							true
2981
+						);
2982
+						return;
2983
+					}
2984
+				}
2985
+				// maybe update status, and make sure to save transaction if not done already
2986
+				if ( ! $transaction->update_status_based_on_total_paid()) {
2987
+					$transaction->save();
2988
+				}
2989
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2990
+				$this->_req_data = array();
2991
+				$query_args      = array(
2992
+					'action'        => 'redirect_to_txn',
2993
+					'TXN_ID'        => $transaction->ID(),
2994
+					'EVT_ID'        => $this->_reg_event->ID(),
2995
+					'event_name'    => urlencode($this->_reg_event->name()),
2996
+					'redirect_from' => 'new_registration',
2997
+				);
2998
+				$this->_redirect_after_action(false, '', '', $query_args, true);
2999
+				break;
3000
+		}
3001
+		//what are you looking here for?  Should be nothing to do at this point.
3002
+	}
3003
+
3004
+
3005
+	/**
3006
+	 * redirect_to_txn
3007
+	 *
3008
+	 * @access public
3009
+	 * @return void
3010
+	 * @throws EE_Error
3011
+	 */
3012
+	public function redirect_to_txn()
3013
+	{
3014
+		EE_System::do_not_cache();
3015
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3016
+		$query_args = array(
3017
+			'action' => 'view_transaction',
3018
+			'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3019
+			'page'   => 'espresso_transactions',
3020
+		);
3021
+		if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3022
+			$query_args['EVT_ID']        = $this->_req_data['EVT_ID'];
3023
+			$query_args['event_name']    = urlencode($this->_req_data['event_name']);
3024
+			$query_args['redirect_from'] = $this->_req_data['redirect_from'];
3025
+		}
3026
+		EE_Error::add_success(
3027
+			esc_html__(
3028
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3029
+				'event_espresso'
3030
+			)
3031
+		);
3032
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3033
+	}
3034
+
3035
+
3036
+	/**
3037
+	 *        generates HTML for the Attendee Contact List
3038
+	 *
3039
+	 * @access protected
3040
+	 * @return void
3041
+	 */
3042
+	protected function _attendee_contact_list_table()
3043
+	{
3044
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3045
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3046
+		$this->display_admin_list_table_page_with_no_sidebar();
3047
+	}
3048
+
3049
+
3050
+	/**
3051
+	 *        get_attendees
3052
+	 *
3053
+	 * @param      $per_page
3054
+	 * @param bool $count whether to return count or data.
3055
+	 * @param bool $trash
3056
+	 * @return array
3057
+	 * @throws EE_Error
3058
+	 * @access public
3059
+	 */
3060
+	public function get_attendees($per_page, $count = false, $trash = false)
3061
+	{
3062
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3063
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3064
+		$ATT_MDL                    = EEM_Attendee::instance();
3065
+		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3066
+		switch ($this->_req_data['orderby']) {
3067
+			case 'ATT_ID':
3068
+				$orderby = 'ATT_ID';
3069
+				break;
3070
+			case 'ATT_fname':
3071
+				$orderby = 'ATT_fname';
3072
+				break;
3073
+			case 'ATT_email':
3074
+				$orderby = 'ATT_email';
3075
+				break;
3076
+			case 'ATT_city':
3077
+				$orderby = 'ATT_city';
3078
+				break;
3079
+			case 'STA_ID':
3080
+				$orderby = 'STA_ID';
3081
+				break;
3082
+			case 'CNT_ID':
3083
+				$orderby = 'CNT_ID';
3084
+				break;
3085
+			default:
3086
+				$orderby = 'ATT_lname';
3087
+		}
3088
+		$sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3089
+			? $this->_req_data['order']
3090
+			: 'ASC';
3091
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3092
+			? $this->_req_data['paged']
3093
+			: 1;
3094
+		$per_page     = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3095
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3096
+			? $this->_req_data['perpage']
3097
+			: $per_page;
3098
+		$_where       = array();
3099
+		if ( ! empty($this->_req_data['s'])) {
3100
+			$sstr         = '%' . $this->_req_data['s'] . '%';
3101
+			$_where['OR'] = array(
3102
+				'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3103
+				'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3104
+				'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3105
+				'ATT_fname'                         => array('LIKE', $sstr),
3106
+				'ATT_lname'                         => array('LIKE', $sstr),
3107
+				'ATT_short_bio'                     => array('LIKE', $sstr),
3108
+				'ATT_email'                         => array('LIKE', $sstr),
3109
+				'ATT_address'                       => array('LIKE', $sstr),
3110
+				'ATT_address2'                      => array('LIKE', $sstr),
3111
+				'ATT_city'                          => array('LIKE', $sstr),
3112
+				'Country.CNT_name'                  => array('LIKE', $sstr),
3113
+				'State.STA_name'                    => array('LIKE', $sstr),
3114
+				'ATT_phone'                         => array('LIKE', $sstr),
3115
+				'Registration.REG_final_price'      => array('LIKE', $sstr),
3116
+				'Registration.REG_code'             => array('LIKE', $sstr),
3117
+				'Registration.REG_count'            => array('LIKE', $sstr),
3118
+				'Registration.REG_group_size'       => array('LIKE', $sstr),
3119
+			);
3120
+		}
3121
+		$offset = ($current_page - 1) * $per_page;
3122
+		$limit  = $count ? null : array($offset, $per_page);
3123
+		if ($trash) {
3124
+			$_where['status'] = array('!=', 'publish');
3125
+			$all_attendees    = $count
3126
+				? $ATT_MDL->count(array(
3127
+					$_where,
3128
+					'order_by' => array($orderby => $sort),
3129
+					'limit'    => $limit,
3130
+				), 'ATT_ID', true)
3131
+				: $ATT_MDL->get_all(array(
3132
+					$_where,
3133
+					'order_by' => array($orderby => $sort),
3134
+					'limit'    => $limit,
3135
+				));
3136
+		} else {
3137
+			$_where['status'] = array('IN', array('publish'));
3138
+			$all_attendees    = $count
3139
+				? $ATT_MDL->count(array(
3140
+					$_where,
3141
+					'order_by' => array($orderby => $sort),
3142
+					'limit'    => $limit,
3143
+				), 'ATT_ID', true)
3144
+				: $ATT_MDL->get_all(array(
3145
+					$_where,
3146
+					'order_by' => array($orderby => $sort),
3147
+					'limit'    => $limit,
3148
+				));
3149
+		}
3150
+		return $all_attendees;
3151
+	}
3152
+
3153
+
3154
+	/**
3155
+	 * This is just taking care of resending the registration confirmation
3156
+	 *
3157
+	 * @access protected
3158
+	 * @return void
3159
+	 */
3160
+	protected function _resend_registration()
3161
+	{
3162
+		$this->_process_resend_registration();
3163
+		$query_args = isset($this->_req_data['redirect_to'])
3164
+			? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3165
+			: array('action' => 'default');
3166
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3167
+	}
3168
+
3169
+	/**
3170
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3171
+	 * to use when selecting registrations
3172
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3173
+	 *                                                     the query parameters from the request
3174
+	 * @return void ends the request with a redirect or download
3175
+	 */
3176
+	public function _registrations_report_base( $method_name_for_getting_query_params )
3177
+	{
3178
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3179
+			wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3180
+				array(
3181
+					'page'        => 'espresso_batch',
3182
+					'batch'       => 'file',
3183
+					'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3184
+					'filters'     => urlencode(
3185
+						serialize(
3186
+							call_user_func(
3187
+								array( $this, $method_name_for_getting_query_params ),
3188
+								EEH_Array::is_set(
3189
+									$this->_req_data,
3190
+									'filters',
3191
+									array()
3192
+								)
3193
+							)
3194
+						)
3195
+				),
3196
+				'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3197
+				'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3198
+				'return_url'  => urlencode($this->_req_data['return_url']),
3199
+			)));
3200
+		} else {
3201
+			$new_request_args = array(
3202
+				'export' => 'report',
3203
+				'action' => 'registrations_report_for_event',
3204
+				'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3205
+			);
3206
+			$this->_req_data = array_merge($this->_req_data, $new_request_args);
3207
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3208
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3209
+				$EE_Export = EE_Export::instance($this->_req_data);
3210
+				$EE_Export->export();
3211
+			}
3212
+		}
3213
+	}
3214
+
3215
+
3216
+
3217
+	/**
3218
+	 * Creates a registration report using only query parameters in the request
3219
+	 * @return void
3220
+	 */
3221
+	public function _registrations_report()
3222
+	{
3223
+		$this->_registrations_report_base('_get_registration_query_parameters');
3224
+	}
3225
+
3226
+
3227
+	public function _contact_list_export()
3228
+	{
3229
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3230
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3231
+			$EE_Export = EE_Export::instance($this->_req_data);
3232
+			$EE_Export->export_attendees();
3233
+		}
3234
+	}
3235
+
3236
+
3237
+	public function _contact_list_report()
3238
+	{
3239
+		if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3240
+			wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
3241
+				'page'        => 'espresso_batch',
3242
+				'batch'       => 'file',
3243
+				'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3244
+				'return_url'  => urlencode($this->_req_data['return_url']),
3245
+			)));
3246
+		} else {
3247
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3248
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3249
+				$EE_Export = EE_Export::instance($this->_req_data);
3250
+				$EE_Export->report_attendees();
3251
+			}
3252
+		}
3253
+	}
3254
+
3255
+
3256
+
3257
+
3258
+
3259
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3260
+	/**
3261
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3262
+	 *
3263
+	 * @return void
3264
+	 * @throws EE_Error
3265
+	 */
3266
+	protected function _duplicate_attendee()
3267
+	{
3268
+		$action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3269
+		//verify we have necessary info
3270
+		if (empty($this->_req_data['_REG_ID'])) {
3271
+			EE_Error::add_error(
3272
+				esc_html__(
3273
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3274
+					'event_espresso'
3275
+				), __FILE__, __LINE__, __FUNCTION__
3276
+			);
3277
+			$query_args = array('action' => $action);
3278
+			$this->_redirect_after_action('', '', '', $query_args, true);
3279
+		}
3280
+		//okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3281
+		$registration = EEM_Registration::instance()->get_one_by_ID($this->_req_data['_REG_ID']);
3282
+		$attendee     = $registration->attendee();
3283
+		//remove relation of existing attendee on registration
3284
+		$registration->_remove_relation_to($attendee, 'Attendee');
3285
+		//new attendee
3286
+		$new_attendee = clone $attendee;
3287
+		$new_attendee->set('ATT_ID', 0);
3288
+		$new_attendee->save();
3289
+		//add new attendee to reg
3290
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3291
+		EE_Error::add_success(
3292
+			esc_html__(
3293
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3294
+				'event_espresso'
3295
+			)
3296
+		);
3297
+		//redirect to edit page for attendee
3298
+		$query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3299
+		$this->_redirect_after_action('', '', '', $query_args, true);
3300
+	}
3301
+
3302
+
3303
+	//related to cpt routes
3304
+	protected function _insert_update_cpt_item($post_id, $post)
3305
+	{
3306
+		$success  = true;
3307
+		$attendee = EEM_Attendee::instance()->get_one_by_ID($post_id);
3308
+		//for attendee updates
3309
+		if ($post->post_type = 'espresso_attendees' && ! empty($attendee)) {
3310
+			//note we should only be UPDATING attendees at this point.
3311
+			$updated_fields = array(
3312
+				'ATT_fname'     => $this->_req_data['ATT_fname'],
3313
+				'ATT_lname'     => $this->_req_data['ATT_lname'],
3314
+				'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3315
+				'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3316
+				'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3317
+				'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3318
+				'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3319
+				'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3320
+				'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3321
+				'ATT_email'     => isset($this->_req_data['ATT_email']) ? $this->_req_data['ATT_email'] : '',
3322
+				'ATT_phone'     => isset($this->_req_data['ATT_phone']) ? $this->_req_data['ATT_phone'] : '',
3323
+			);
3324
+			foreach ($updated_fields as $field => $value) {
3325
+				$attendee->set($field, $value);
3326
+			}
3327
+			$success                   = $attendee->save();
3328
+			$attendee_update_callbacks = apply_filters(
3329
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3330
+				array()
3331
+			);
3332
+			foreach ($attendee_update_callbacks as $a_callback) {
3333
+				if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3334
+					throw new EE_Error(
3335
+						sprintf(
3336
+							esc_html__(
3337
+								'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3338
+								'event_espresso'
3339
+							),
3340
+							$a_callback
3341
+						)
3342
+					);
3343
+				}
3344
+			}
3345
+		}
3346
+		if ($success === false) {
3347
+			EE_Error::add_error(
3348
+				esc_html__(
3349
+					'Something went wrong with updating the meta table data for the registration.',
3350
+					'event_espresso'
3351
+				),
3352
+				__FILE__, __FUNCTION__, __LINE__
3353
+			);
3354
+		}
3355
+	}
3356
+
3357
+
3358
+	public function trash_cpt_item($post_id)
3359
+	{
3360
+	}
3361
+
3362
+
3363
+	public function delete_cpt_item($post_id)
3364
+	{
3365
+	}
3366
+
3367
+
3368
+	public function restore_cpt_item($post_id)
3369
+	{
3370
+	}
3371
+
3372
+
3373
+	protected function _restore_cpt_item($post_id, $revision_id)
3374
+	{
3375
+	}
3376
+
3377
+
3378
+	public function attendee_editor_metaboxes()
3379
+	{
3380
+		$this->verify_cpt_object();
3381
+		remove_meta_box(
3382
+			'postexcerpt',
3383
+			esc_html__('Excerpt', 'event_espresso'),
3384
+			'post_excerpt_meta_box',
3385
+			$this->_cpt_routes[$this->_req_action],
3386
+			'normal',
3387
+			'core'
3388
+		);
3389
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
3390
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3391
+			add_meta_box(
3392
+				'postexcerpt',
3393
+				esc_html__('Short Biography', 'event_espresso'),
3394
+				'post_excerpt_meta_box',
3395
+				$this->_cpt_routes[$this->_req_action],
3396
+				'normal'
3397
+			);
3398
+		}
3399
+		if (post_type_supports('espresso_attendees', 'comments')) {
3400
+			add_meta_box(
3401
+				'commentsdiv',
3402
+				esc_html__('Notes on the Contact', 'event_espresso'),
3403
+				'post_comment_meta_box',
3404
+				$this->_cpt_routes[$this->_req_action],
3405
+				'normal',
3406
+				'core'
3407
+			);
3408
+		}
3409
+		add_meta_box(
3410
+			'attendee_contact_info',
3411
+			esc_html__('Contact Info', 'event_espresso'),
3412
+			array($this, 'attendee_contact_info'),
3413
+			$this->_cpt_routes[$this->_req_action],
3414
+			'side',
3415
+			'core'
3416
+		);
3417
+		add_meta_box(
3418
+			'attendee_details_address',
3419
+			esc_html__('Address Details', 'event_espresso'),
3420
+			array($this, 'attendee_address_details'),
3421
+			$this->_cpt_routes[$this->_req_action],
3422
+			'normal',
3423
+			'core'
3424
+		);
3425
+		add_meta_box(
3426
+			'attendee_registrations',
3427
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3428
+			array($this, 'attendee_registrations_meta_box'),
3429
+			$this->_cpt_routes[$this->_req_action],
3430
+			'normal',
3431
+			'high'
3432
+		);
3433
+	}
3434
+
3435
+
3436
+	/**
3437
+	 * Metabox for attendee contact info
3438
+	 *
3439
+	 * @param  WP_Post $post wp post object
3440
+	 * @return string attendee contact info ( and form )
3441
+	 * @throws DomainException
3442
+	 */
3443
+	public function attendee_contact_info($post)
3444
+	{
3445
+		//get attendee object ( should already have it )
3446
+		$this->_template_args['attendee'] = $this->_cpt_model_obj;
3447
+		$template                         = REG_TEMPLATE_PATH . 'attendee_contact_info_metabox_content.template.php';
3448
+		EEH_Template::display_template($template, $this->_template_args);
3449
+	}
3450
+
3451
+
3452
+	/**
3453
+	 * Metabox for attendee details
3454
+	 *
3455
+	 * @param  WP_Post $post wp post object
3456
+	 * @return string attendee address details (and form)
3457
+	 * @throws DomainException
3458
+	 */
3459
+	public function attendee_address_details($post)
3460
+	{
3461
+		//get attendee object (should already have it)
3462
+		$this->_template_args['attendee']     = $this->_cpt_model_obj;
3463
+		$this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3464
+			new EE_Question_Form_Input(
3465
+				EE_Question::new_instance(
3466
+					array(
3467
+						'QST_ID'           => 0,
3468
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3469
+						'QST_system'       => 'admin-state',
3470
+					)
3471
+				),
3472
+				EE_Answer::new_instance(
3473
+					array(
3474
+						'ANS_ID'    => 0,
3475
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3476
+					)
3477
+				),
3478
+				array(
3479
+					'input_id'       => 'STA_ID',
3480
+					'input_name'     => 'STA_ID',
3481
+					'input_prefix'   => '',
3482
+					'append_qstn_id' => false,
3483
+				)
3484
+			)
3485
+		);
3486
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3487
+			new EE_Question_Form_Input(
3488
+				EE_Question::new_instance(
3489
+					array(
3490
+						'QST_ID'           => 0,
3491
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3492
+						'QST_system'       => 'admin-country',
3493
+					)
3494
+				),
3495
+				EE_Answer::new_instance(
3496
+					array(
3497
+						'ANS_ID'    => 0,
3498
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3499
+					)
3500
+				),
3501
+				array(
3502
+					'input_id'       => 'CNT_ISO',
3503
+					'input_name'     => 'CNT_ISO',
3504
+					'input_prefix'   => '',
3505
+					'append_qstn_id' => false,
3506
+				)
3507
+			)
3508
+		);
3509
+		$template                             =
3510
+			REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3511
+		EEH_Template::display_template($template, $this->_template_args);
3512
+	}
3513
+
3514
+
3515
+	/**
3516
+	 *        _attendee_details
3517
+	 *
3518
+	 * @access protected
3519
+	 * @param $post
3520
+	 * @return void
3521
+	 * @throws DomainException
3522
+	 * @throws EE_Error
3523
+	 */
3524
+	public function attendee_registrations_meta_box($post)
3525
+	{
3526
+		$this->_template_args['attendee']      = $this->_cpt_model_obj;
3527
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3528
+		$template                              =
3529
+			REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3530
+		EEH_Template::display_template($template, $this->_template_args);
3531
+	}
3532
+
3533
+
3534
+	/**
3535
+	 * add in the form fields for the attendee edit
3536
+	 *
3537
+	 * @param  WP_Post $post wp post object
3538
+	 * @return string html for new form.
3539
+	 * @throws DomainException
3540
+	 */
3541
+	public function after_title_form_fields($post)
3542
+	{
3543
+		if ($post->post_type == 'espresso_attendees') {
3544
+			$template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3545
+			$template_args['attendee'] = $this->_cpt_model_obj;
3546
+			EEH_Template::display_template($template, $template_args);
3547
+		}
3548
+	}
3549
+
3550
+
3551
+	/**
3552
+	 *        _trash_or_restore_attendee
3553
+	 *
3554
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3555
+	 * @return void
3556
+	 * @throws EE_Error
3557
+	 * @access protected
3558
+	 */
3559
+	protected function _trash_or_restore_attendees($trash = true)
3560
+	{
3561
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3562
+		$ATT_MDL = EEM_Attendee::instance();
3563
+		$success = 1;
3564
+		//Checkboxes
3565
+		if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3566
+			// if array has more than one element than success message should be plural
3567
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3568
+			// cycle thru checkboxes
3569
+			while (list($ATT_ID, $value) = each($this->_req_data['checkbox'])) {
3570
+				$updated = $trash ? $ATT_MDL->update_by_ID(array('status' => 'trash'), $ATT_ID)
3571
+					: $ATT_MDL->update_by_ID(array('status' => 'publish'), $ATT_ID);
3572
+				if ( ! $updated) {
3573
+					$success = 0;
3574
+				}
3575
+			}
3576
+		} else {
3577
+			// grab single id and delete
3578
+			$ATT_ID = absint($this->_req_data['ATT_ID']);
3579
+			//get attendee
3580
+			$att     = $ATT_MDL->get_one_by_ID($ATT_ID);
3581
+			$updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3582
+			$updated = $att->save();
3583
+			if ( ! $updated) {
3584
+				$success = 0;
3585
+			}
3586
+		}
3587
+		$what        = $success > 1
3588
+			? esc_html__('Contacts', 'event_espresso')
3589
+			: esc_html__('Contact', 'event_espresso');
3590
+		$action_desc = $trash
3591
+			? esc_html__('moved to the trash', 'event_espresso')
3592
+			: esc_html__('restored', 'event_espresso');
3593
+		$this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3594
+	}
3595 3595
 
3596 3596
 }
Please login to merge, or discard this patch.
admin_pages/registrations/EE_Registrations_List_Table.class.php 1 patch
Indentation   +846 added lines, -846 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -26,875 +26,875 @@  discard block
 block discarded – undo
26 26
 
27 27
 
28 28
 
29
-    private $_status;
30
-
31
-
32
-
33
-    /**
34
-     * An array of transaction details for the related transaction to the registration being processed.
35
-     * This is set via the _set_related_details method.
36
-     *
37
-     * @var array
38
-     */
39
-    protected $_transaction_details = array();
40
-
41
-
42
-
43
-    /**
44
-     * An array of event details for the related event to the registration being processed.
45
-     * This is set via the _set_related_details method.
46
-     *
47
-     * @var array
48
-     */
49
-    protected $_event_details = array();
50
-
51
-
52
-
53
-    /**
54
-     * @param \Registrations_Admin_Page $admin_page
55
-     */
56
-    public function __construct(Registrations_Admin_Page $admin_page)
57
-    {
58
-        if ( ! empty($_GET['event_id'])) {
59
-            $extra_query_args = array();
60
-            foreach ($admin_page->get_views() as $key => $view_details) {
61
-                $extra_query_args[$view_details['slug']] = array('event_id' => $_GET['event_id']);
62
-            }
63
-            $this->_views = $admin_page->get_list_table_view_RLs($extra_query_args);
64
-        }
65
-        parent::__construct($admin_page);
66
-        $this->_status = $this->_admin_page->get_registration_status_array();
67
-    }
68
-
69
-
70
-
71
-    /**
72
-     *    _setup_data
73
-     *
74
-     * @access protected
75
-     * @return void
76
-     */
77
-    protected function _setup_data()
78
-    {
79
-        $this->_data = $this->_admin_page->get_registrations($this->_per_page);
80
-        $this->_all_data_count = $this->_admin_page->get_registrations($this->_per_page, true, false, false);
81
-    }
82
-
83
-
84
-
85
-    /**
86
-     *    _set_properties
87
-     *
88
-     * @access protected
89
-     * @return void
90
-     */
91
-    protected function _set_properties()
92
-    {
93
-        $this->_wp_list_args = array(
94
-            'singular' => __('registration', 'event_espresso'),
95
-            'plural'   => __('registrations', 'event_espresso'),
96
-            'ajax'     => true,
97
-            'screen'   => $this->_admin_page->get_current_screen()->id,
98
-        );
99
-        $ID_column_name = __('ID', 'event_espresso');
100
-        $ID_column_name .= ' : <span class="show-on-mobile-view-only" style="float:none">';
101
-        $ID_column_name .= __('Registrant Name', 'event_espresso');
102
-        $ID_column_name .= '</span> ';
103
-        if (isset($_GET['event_id'])) {
104
-            $this->_columns = array(
105
-                'cb'               => '<input type="checkbox" />', //Render a checkbox instead of text
106
-                '_REG_ID'          => $ID_column_name,
107
-                'ATT_fname'        => __('Name', 'event_espresso'),
108
-                'ATT_email'        => __('Email', 'event_espresso'),
109
-                '_REG_date'        => __('Reg Date', 'event_espresso'),
110
-                'PRC_amount'       => __('TKT Price', 'event_espresso'),
111
-                '_REG_final_price' => __('Final Price', 'event_espresso'),
112
-                'TXN_total'        => __('Total Txn', 'event_espresso'),
113
-                'TXN_paid'         => __('Paid', 'event_espresso'),
114
-                'actions'          => __('Actions', 'event_espresso'),
115
-            );
116
-            $this->_bottom_buttons = array(
117
-                'report' => array(
118
-                    'route'         => 'registrations_report',
119
-                    'extra_request' => array(
120
-                        'EVT_ID'     => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null,
121
-                        'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
122
-                    ),
123
-                ),
124
-            );
125
-        } else {
126
-            $this->_columns = array(
127
-                'cb'               => '<input type="checkbox" />', //Render a checkbox instead of text
128
-                '_REG_ID'          => $ID_column_name,
129
-                'ATT_fname'        => __('Name', 'event_espresso'),
130
-                '_REG_date'        => __('TXN Date', 'event_espresso'),
131
-                'event_name'       => __('Event', 'event_espresso'),
132
-                'DTT_EVT_start'    => __('Event Date', 'event_espresso'),
133
-                '_REG_final_price' => __('Price', 'event_espresso'),
134
-                '_REG_paid'        => __('Paid', 'event_espresso'),
135
-                'actions'          => __('Actions', 'event_espresso'),
136
-            );
137
-            $this->_bottom_buttons = array(
138
-                'report_all' => array(
139
-                    'route'         => 'registrations_report',
140
-                    'extra_request' => array(
141
-                        'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
142
-                    ),
143
-                ),
144
-            );
145
-        }
146
-        $this->_bottom_buttons['report_filtered'] = array(
147
-            'route'         => 'registrations_report',
148
-            'extra_request' => array(
149
-                'use_filters' => true,
150
-                'filters'     => array_diff_key($this->_req_data, array_flip(array(
151
-                            'page',
152
-                            'action',
153
-                            'default_nonce',
154
-                        ))),
155
-                'return_url'  => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
156
-            ),
157
-        );
158
-        $this->_primary_column = '_REG_ID';
159
-        $this->_sortable_columns = array(
160
-            '_REG_date'     => array('_REG_date' => true),   //true means its already sorted
161
-            /**
162
-             * Allows users to change the default sort if they wish.
163
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
164
-             */
165
-            'ATT_fname'     => array(
166
-                    'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
167
-                    true,
168
-                    $this
169
-                )
170
-                ? array('ATT_lname' => false)
171
-                : array('ATT_fname' => false),
172
-            'event_name'    => array('event_name' => false),
173
-            'DTT_EVT_start' => array('DTT_EVT_start' => false),
174
-            '_REG_ID'       => array('_REG_ID' => false),
175
-        );
176
-        $this->_hidden_columns = array();
177
-    }
178
-
179
-
180
-
181
-    /**
182
-     * This simply sets up the row class for the table rows.
183
-     * Allows for easier overriding of child methods for setting up sorting.
184
-     *
185
-     * @param  EE_Registration $item the current item
186
-     * @return string
187
-     */
188
-    protected function _get_row_class($item)
189
-    {
190
-        $class = parent::_get_row_class($item);
191
-        //add status class
192
-        $class .= ' ee-status-strip reg-status-' . $item->status_ID();
193
-        if ($this->_has_checkbox_column) {
194
-            $class .= ' has-checkbox-column';
195
-        }
196
-        return $class;
197
-    }
198
-
199
-
200
-
201
-    /**
202
-     * Set the $_transaction_details property if not set yet.
203
-     *
204
-     * @param EE_Registration $registration
205
-     * @throws \EE_Error
206
-     */
207
-    protected function _set_related_details(EE_Registration $registration)
208
-    {
209
-        $transaction = $registration->get_first_related('Transaction');
210
-        $status = $transaction instanceof EE_Transaction ? $transaction->status_ID()
211
-            : EEM_Transaction::failed_status_code;
212
-        $this->_transaction_details = array(
213
-            'transaction' => $transaction,
214
-            'status'      => $status,
215
-            'id'          => $transaction instanceof EE_Transaction ? $transaction->ID() : 0,
216
-            'title_attr'  => sprintf(__('View Transaction Details (%s)', 'event_espresso'),
217
-                EEH_Template::pretty_status($status, false, 'sentence')),
218
-        );
219
-        try {
220
-            $event = $registration->event();
221
-        } catch (\EventEspresso\core\exceptions\EntityNotFoundException $e) {
222
-            $event = null;
223
-        }
224
-        $status = $event instanceof EE_Event ? $event->get_active_status() : EE_Datetime::inactive;
225
-        $this->_event_details = array(
226
-            'event'      => $event,
227
-            'status'     => $status,
228
-            'id'         => $event instanceof EE_Event ? $event->ID() : 0,
229
-            'title_attr' => sprintf(__('Edit Event (%s)', 'event_espresso'),
230
-                EEH_Template::pretty_status($status, false, 'sentence')),
231
-        );
232
-    }
233
-
234
-
235
-
236
-    /**
237
-     *    _get_table_filters
238
-     *
239
-     * @access protected
240
-     * @return array
241
-     */
242
-    protected function _get_table_filters()
243
-    {
244
-        $filters = array();
245
-        //todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as methods.
246
-        $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
247
-        $cur_category = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
248
-        $reg_status = isset($this->_req_data['_reg_status']) ? $this->_req_data['_reg_status'] : '';
249
-        $filters[] = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category);
250
-        $filters[] = EEH_Form_Fields::generate_event_category_dropdown($cur_category);
251
-        $status = array();
252
-        $status[] = array('id' => 0, 'text' => __('Select Status', 'event_espresso'));
253
-        foreach ($this->_status as $key => $value) {
254
-            $status[] = array('id' => $key, 'text' => $value);
255
-        }
256
-        if ($this->_view !== 'incomplete') {
257
-            $filters[] = EEH_Form_Fields::select_input('_reg_status', $status,
258
-                isset($this->_req_data['_reg_status']) ? strtoupper(sanitize_key($this->_req_data['_reg_status']))
259
-                    : '');
260
-        }
261
-        if (isset($this->_req_data['event_id'])) {
262
-            $filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id');
263
-        }
264
-        return $filters;
265
-    }
266
-
267
-
268
-
269
-    /**
270
-     *    _add_view_counts
271
-     *
272
-     * @access protected
273
-     * @return void
274
-     * @throws \EE_Error
275
-     */
276
-    protected function _add_view_counts()
277
-    {
278
-        $this->_views['all']['count'] = $this->_total_registrations();
279
-        $this->_views['month']['count'] = $this->_total_registrations_this_month();
280
-        $this->_views['today']['count'] = $this->_total_registrations_today();
281
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_registrations',
282
-            'espresso_registrations_trash_registrations')
283
-        ) {
284
-            $this->_views['incomplete']['count'] = $this->_total_registrations('incomplete');
285
-            $this->_views['trash']['count'] = $this->_total_registrations('trash');
286
-        }
287
-    }
288
-
289
-
290
-
291
-    /**
292
-     * _total_registrations
293
-     *
294
-     * @access protected
295
-     * @param string $view
296
-     * @return int
297
-     * @throws \EE_Error
298
-     */
299
-    protected function _total_registrations($view = '')
300
-    {
301
-        $_where = array();
302
-        $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
303
-        if ($EVT_ID) {
304
-            $_where['EVT_ID'] = $EVT_ID;
305
-        }
306
-        switch ($view) {
307
-            case 'trash' :
308
-                return EEM_Registration::instance()->count_deleted(array($_where));
309
-                break;
310
-            case 'incomplete' :
311
-                $_where['STS_ID'] = EEM_Registration::status_id_incomplete;
312
-                break;
313
-            default :
314
-                $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
315
-        }
316
-        return EEM_Registration::instance()->count(array($_where));
317
-    }
318
-
319
-
320
-
321
-    /**
322
-     * _total_registrations_this_month
323
-     *
324
-     * @access protected
325
-     * @return int
326
-     * @throws \EE_Error
327
-     */
328
-    protected function _total_registrations_this_month()
329
-    {
330
-        $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
331
-        $_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array();
332
-        $this_year_r = date('Y', current_time('timestamp'));
333
-        $time_start = ' 00:00:00';
334
-        $time_end = ' 23:59:59';
335
-        $this_month_r = date('m', current_time('timestamp'));
336
-        $days_this_month = date('t', current_time('timestamp'));
337
-        //setup date query.
338
-        $beginning_string = EEM_Registration::instance()
339
-                                            ->convert_datetime_for_query('REG_date',
340
-                                                $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
341
-                                                'Y-m-d H:i:s');
342
-        $end_string = EEM_Registration::instance()
343
-                                      ->convert_datetime_for_query('REG_date',
344
-                                          $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
345
-                                          'Y-m-d H:i:s');
346
-        $_where['REG_date'] = array(
347
-            'BETWEEN',
348
-            array(
349
-                $beginning_string,
350
-                $end_string,
351
-            ),
352
-        );
353
-        $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
354
-        return EEM_Registration::instance()->count(array($_where));
355
-    }
356
-
357
-
358
-
359
-    /**
360
-     * _total_registrations_today
361
-     *
362
-     * @access protected
363
-     * @return int
364
-     * @throws \EE_Error
365
-     */
366
-    protected function _total_registrations_today()
367
-    {
368
-        $EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
369
-        $_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array();
370
-        $current_date = date('Y-m-d', current_time('timestamp'));
371
-        $time_start = ' 00:00:00';
372
-        $time_end = ' 23:59:59';
373
-        $_where['REG_date'] = array(
374
-            'BETWEEN',
375
-            array(
376
-                EEM_Registration::instance()
377
-                                ->convert_datetime_for_query('REG_date', $current_date . $time_start, 'Y-m-d H:i:s'),
378
-                EEM_Registration::instance()
379
-                                ->convert_datetime_for_query('REG_date', $current_date . $time_end, 'Y-m-d H:i:s'),
380
-            ),
381
-        );
382
-        $_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
383
-        return EEM_Registration::instance()->count(array($_where));
384
-    }
385
-
386
-
387
-
388
-    /**
389
-     * column_cb
390
-     *
391
-     * @access public
392
-     * @param \EE_Registration $item
393
-     * @return string
394
-     * @throws \EE_Error
395
-     */
396
-    public function column_cb($item)
397
-    {
398
-        /** checkbox/lock **/
399
-        $transaction = $item->get_first_related('Transaction');
400
-        $payment_count = $transaction instanceof EE_Transaction ? $transaction->count_related('Payment') : 0;
401
-        return $payment_count > 0
402
-            ||  ! EE_Registry::instance()->CAP->current_user_can(
403
-                'ee_edit_registration',
404
-                'registration_list_table_checkbox_input',
405
-                $item->ID()
406
-            )
407
-            ? sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID())
408
-                                    . '<span class="ee-lock-icon"></span>'
409
-            : sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID());
410
-    }
411
-
412
-
413
-
414
-    /**
415
-     * column__REG_ID
416
-     *
417
-     * @access public
418
-     * @param \EE_Registration $item
419
-     * @return string
420
-     * @throws \EE_Error
421
-     */
422
-    public function column__REG_ID(EE_Registration $item)
423
-    {
424
-        $attendee = $item->attendee();
425
-        $content = $item->ID();
426
-        $content .= '<div class="show-on-mobile-view-only">';
427
-        $content .= '<br>';
428
-        $content .= $attendee instanceof EE_Attendee ? $attendee->full_name() : '';
429
-        $content .= '&nbsp;' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
430
-        $content .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
431
-        $content .= '</div>';
432
-        return $content;
433
-    }
434
-
435
-
436
-
437
-    /**
438
-     * column__REG_date
439
-     *
440
-     * @access public
441
-     * @param \EE_Registration $item
442
-     * @return string
443
-     * @throws \EE_Error
444
-     */
445
-    public function column__REG_date(EE_Registration $item)
446
-    {
447
-        $this->_set_related_details($item);
448
-        //Build row actions
449
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
450
-            'action' => 'view_transaction',
451
-            'TXN_ID' => $this->_transaction_details['id'],
452
-        ), TXN_ADMIN_URL);
453
-        $view_link = EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
454
-            'espresso_transactions_view_transaction') ? '<a class="ee-status-color-'
455
-                                                        . $this->_transaction_details['status']
456
-                                                        . '" href="'
457
-                                                        . $view_lnk_url
458
-                                                        . '" title="'
459
-                                                        . esc_attr($this->_transaction_details['title_attr'])
460
-                                                        . '">'
461
-                                                        . $item->get_i18n_datetime('REG_date')
462
-                                                        . '</a>' : $item->get_i18n_datetime('REG_date');
463
-        $view_link .= '<br><span class="ee-status-text-small">'
464
-                      . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
465
-                      . '</span>';
466
-        return $view_link;
467
-    }
468
-
469
-
470
-
471
-    /**
472
-     * column_event_name
473
-     *
474
-     * @access public
475
-     * @param \EE_Registration $item
476
-     * @return string
477
-     * @throws \EE_Error
478
-     */
479
-    public function column_event_name(EE_Registration $item)
480
-    {
481
-        $this->_set_related_details($item);
482
-        // page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62
483
-        $EVT_ID = $item->event_ID();
484
-        $event_name = $item->event_name();
485
-        $event_name = $event_name ? $event_name : __("No Associated Event", 'event_espresso');
486
-        $event_name = wp_trim_words($event_name, 30, '...');
487
-        if ($EVT_ID) {
488
-            $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'edit', 'post' => $EVT_ID),
489
-                EVENTS_ADMIN_URL);
490
-            $edit_event = EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
491
-                ? '<a class="ee-status-color-'
492
-                  . $this->_event_details['status']
493
-                  . '" href="'
494
-                  . $edit_event_url
495
-                  . '" title="'
496
-                  . esc_attr($this->_event_details['title_attr'])
497
-                  . '">'
498
-                  . $event_name
499
-                  . '</a>' : $event_name;
500
-            $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(array('event_id' => $EVT_ID), REG_ADMIN_URL);
501
-            $actions['event_filter'] = '<a href="' . $edit_event_url . '" title="';
502
-            $actions['event_filter'] .= sprintf(esc_attr__('Filter this list to only show registrations for %s',
503
-                'event_espresso'), $event_name);
504
-            $actions['event_filter'] .= '">' . __('View Registrations', 'event_espresso') . '</a>';
505
-        } else {
506
-            $edit_event = $event_name;
507
-            $actions['event_filter'] = '';
508
-        }
509
-        return sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions));
510
-    }
511
-
512
-
513
-
514
-    /**
515
-     * column_DTT_EVT_start
516
-     *
517
-     * @access public
518
-     * @param \EE_Registration $item
519
-     * @return string
520
-     * @throws \EE_Error
521
-     */
522
-    public function column_DTT_EVT_start(EE_Registration $item)
523
-    {
524
-        $datetime_strings = array();
525
-        $ticket = $item->ticket(true);
526
-        if ($ticket instanceof EE_Ticket) {
527
-            $remove_defaults = array('default_where_conditions' => 'none');
528
-            $datetimes = $ticket->datetimes($remove_defaults);
529
-            foreach ($datetimes as $datetime) {
530
-                $datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start');
531
-            }
532
-            return implode("<br />", $datetime_strings);
533
-        } else {
534
-            return __('There is no ticket on this registration', 'event_espresso');
535
-        }
536
-    }
537
-
538
-
539
-
540
-    /**
541
-     * column_ATT_fname
542
-     *
543
-     * @access public
544
-     * @param \EE_Registration $item
545
-     * @return string
546
-     * @throws \EE_Error
547
-     */
548
-    public function column_ATT_fname(EE_Registration $item)
549
-    {
550
-        $attendee = $item->attendee();
551
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
552
-            'action'  => 'view_registration',
553
-            '_REG_ID' => $item->ID(),
554
-        ), REG_ADMIN_URL);
555
-        $attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : '';
556
-        $link = EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
557
-            'espresso_registrations_view_registration', $item->ID()) ? '<a href="'
558
-                                                                       . $edit_lnk_url
559
-                                                                       . '" title="'
560
-                                                                       . esc_attr__('View Registration Details',
561
-                'event_espresso')
562
-                                                                       . '">'
563
-                                                                       . $attendee_name
564
-                                                                       . '</a>' : $attendee_name;
565
-        $link .= $item->count() === 1
566
-            ? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>' : '';
567
-        $t = $item->get_first_related('Transaction');
568
-        $payment_count = $t instanceof EE_Transaction ? $t->count_related('Payment') : 0;
569
-        //append group count to name
570
-        $link .= '&nbsp;' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
571
-        //append reg_code
572
-        $link .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
573
-        //reg status text for accessibility
574
-        $link .= '<br><span class="ee-status-text-small">' . EEH_Template::pretty_status($item->status_ID(), false,
575
-                'sentence') . '</span>';
576
-        //trash/restore/delete actions
577
-        $actions = array();
578
-        if ($this->_view !== 'trash'
579
-            && $payment_count === 0
580
-            && EE_Registry::instance()->CAP->current_user_can('ee_delete_registration',
581
-                'espresso_registrations_trash_registrations', $item->ID())
582
-        ) {
583
-            $trash_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
584
-                'action'  => 'trash_registrations',
585
-                '_REG_ID' => $item->ID(),
586
-            ), REG_ADMIN_URL);
587
-            $actions['trash'] = '<a href="' . $trash_lnk_url . '" title="' . esc_attr__('Trash Registration',
588
-                    'event_espresso') . '">' . __('Trash', 'event_espresso') . '</a>';
589
-        } elseif ($this->_view === 'trash') {
590
-            // restore registration link
591
-            if (EE_Registry::instance()->CAP->current_user_can('ee_delete_registration',
592
-                'espresso_registrations_restore_registrations', $item->ID())
593
-            ) {
594
-                $restore_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
595
-                    'action'  => 'restore_registrations',
596
-                    '_REG_ID' => $item->ID(),
597
-                ), REG_ADMIN_URL);
598
-                $actions['restore'] = '<a href="' . $restore_lnk_url . '" title="' . esc_attr__('Restore Registration',
599
-                        'event_espresso') . '">' . __('Restore', 'event_espresso') . '</a>';
600
-            }
601
-            if (EE_Registry::instance()->CAP->current_user_can('ee_delete_registration',
602
-                'espresso_registrations_ee_delete_registrations', $item->ID())
603
-            ) {
604
-                $delete_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
605
-                    'action'  => 'delete_registrations',
606
-                    '_REG_ID' => $item->ID(),
607
-                ), REG_ADMIN_URL);
608
-                $actions['delete'] = '<a href="'
609
-                                     . $delete_lnk_url
610
-                                     . '" title="'
611
-                                     . esc_attr__('Delete Registration Permanently', 'event_espresso')
612
-                                     . '">'
613
-                                     . __('Delete', 'event_espresso')
614
-                                     . '</a>';
615
-            }
616
-        }
617
-        return sprintf('%1$s %2$s', $link, $this->row_actions($actions));
618
-    }
619
-
620
-
621
-
622
-    /**
623
-     * column_ATT_email
624
-     *
625
-     * @access public
626
-     * @param \EE_Registration $item
627
-     * @return string
628
-     * @throws \EE_Error
629
-     */
630
-    public function column_ATT_email(EE_Registration $item)
631
-    {
632
-        $attendee = $item->get_first_related('Attendee');
633
-        return ! $attendee instanceof EE_Attendee ? __('No attached contact record.', 'event_espresso')
634
-            : $attendee->email();
635
-    }
636
-
637
-
638
-
639
-    /**
640
-     * column__REG_count
641
-     *
642
-     * @access public
643
-     * @param \EE_Registration $item
644
-     * @return string
645
-     */
646
-    public function column__REG_count(EE_Registration $item)
647
-    {
648
-        return sprintf(__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size());
649
-    }
650
-
651
-
652
-
653
-    /**
654
-     * column_PRC_amount
655
-     *
656
-     * @access public
657
-     * @param \EE_Registration $item
658
-     * @return string
659
-     */
660
-    public function column_PRC_amount(EE_Registration $item)
661
-    {
662
-        $ticket = $item->ticket();
663
-        $content = isset($_GET['event_id']) && $ticket instanceof EE_Ticket ? '<span class="TKT_name">'
664
-                                                                              . $ticket->name()
665
-                                                                              . '</span><br />' : '';
666
-        if ($item->final_price() > 0) {
667
-            $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
668
-        } else {
669
-            // free event
670
-            $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
671
-                        . __('free', 'event_espresso')
672
-                        . '</span>';
673
-        }
674
-        return $content;
675
-    }
676
-
677
-
678
-
679
-    /**
680
-     * column__REG_final_price
681
-     *
682
-     * @access public
683
-     * @param \EE_Registration $item
684
-     * @return string
685
-     */
686
-    public function column__REG_final_price(EE_Registration $item)
687
-    {
688
-        $ticket = $item->ticket();
689
-        $content = isset($_GET['event_id']) || ! $ticket instanceof EE_Ticket
690
-            ? ''
691
-            : '<span class="TKT_name">'
692
-              . $ticket->name()
693
-              . '</span><br />';
694
-        $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
695
-        return $content;
696
-    }
697
-
698
-
699
-
700
-    /**
701
-     * column__REG_paid
702
-     *
703
-     * @access public
704
-     * @param \EE_Registration $item
705
-     * @return string
706
-     */
707
-    public function column__REG_paid(EE_Registration $item)
708
-    {
709
-        $payment_method = $item->payment_method();
710
-        $payment_method_name = $payment_method instanceof EE_Payment_Method ? $payment_method->admin_name()
711
-            : __('Unknown', 'event_espresso');
712
-        $content = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>';
713
-        if ($item->paid() > 0) {
714
-            $content .= '<br><span class="ee-status-text-small">' . sprintf(__('...via %s', 'event_espresso'),
715
-                    $payment_method_name) . '</span>';
716
-        }
717
-        return $content;
718
-    }
719
-
720
-
721
-
722
-    /**
723
-     * column_TXN_total
724
-     *
725
-     * @access public
726
-     * @param \EE_Registration $item
727
-     * @return string
728
-     * @throws \EE_Error
729
-     */
730
-    public function column_TXN_total(EE_Registration $item)
731
-    {
732
-        if ($item->transaction()) {
733
-            $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
734
-                'action' => 'view_transaction',
735
-                'TXN_ID' => $item->transaction_ID(),
736
-            ), TXN_ADMIN_URL);
737
-            return EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
738
-                'espresso_transactions_view_transaction', $item->transaction_ID())
739
-                ? '<span class="reg-pad-rght"><a class="status-'
740
-                  . $item->transaction()->status_ID()
741
-                  . '" href="'
742
-                  . $view_txn_lnk_url
743
-                  . '"  title="'
744
-                  . esc_attr__('View Transaction', 'event_espresso')
745
-                  . '">'
746
-                  . $item->transaction()->pretty_total()
747
-                  . '</a></span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
748
-        } else {
749
-            return __("None", "event_espresso");
750
-        }
751
-    }
752
-
753
-
754
-
755
-    /**
756
-     * column_TXN_paid
757
-     *
758
-     * @access public
759
-     * @param \EE_Registration $item
760
-     * @return string
761
-     * @throws \EE_Error
762
-     */
763
-    public function column_TXN_paid(EE_Registration $item)
764
-    {
765
-        if ($item->count() === 1) {
766
-            $transaction = $item->transaction() ? $item->transaction() : EE_Transaction::new_instance();
767
-            if ($transaction->paid() >= $transaction->total()) {
768
-                return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
769
-            } else {
770
-                $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
771
-                    'action' => 'view_transaction',
772
-                    'TXN_ID' => $item->transaction_ID(),
773
-                ), TXN_ADMIN_URL);
774
-                return EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
775
-                    'espresso_transactions_view_transaction', $item->transaction_ID())
776
-                    ? '<span class="reg-pad-rght"><a class="status-'
777
-                      . $transaction->status_ID()
778
-                      . '" href="'
779
-                      . $view_txn_lnk_url
780
-                      . '"  title="'
781
-                      . esc_attr__('View Transaction', 'event_espresso')
782
-                      . '">'
783
-                      . $item->transaction()->pretty_paid()
784
-                      . '</a><span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
785
-            }
786
-        }
787
-        return '&nbsp;';
788
-    }
789
-
790
-
791
-
792
-    /**
793
-     * column_actions
794
-     *
795
-     * @access public
796
-     * @param \EE_Registration $item
797
-     * @return string
798
-     * @throws \EE_Error
799
-     */
800
-    public function column_actions(EE_Registration $item)
801
-    {
802
-        $actions = array();
803
-        $attendee = $item->attendee();
804
-        $this->_set_related_details($item);
805
-        //Build row actions
806
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
807
-            'action'  => 'view_registration',
808
-            '_REG_ID' => $item->ID(),
809
-        ), REG_ADMIN_URL);
810
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
811
-            'action' => 'edit_attendee',
812
-            'post'   => $item->attendee_ID(),
813
-        ), REG_ADMIN_URL);
814
-        // page=attendees&event_admin_reports=resend_email&registration_id=43653465634&event_id=2&form_action=resend_email
815
-        //$resend_reg_lnk_url_params = array( 'action'=>'resend_registration', '_REG_ID'=>$item->REG_ID );
816
-        $resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
817
-            'action'  => 'resend_registration',
818
-            '_REG_ID' => $item->ID(),
819
-        ), REG_ADMIN_URL, true);
820
-        //Build row actions
821
-        $actions['view_lnk'] = EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
822
-            'espresso_registrations_view_registration', $item->ID()) ? '
29
+	private $_status;
30
+
31
+
32
+
33
+	/**
34
+	 * An array of transaction details for the related transaction to the registration being processed.
35
+	 * This is set via the _set_related_details method.
36
+	 *
37
+	 * @var array
38
+	 */
39
+	protected $_transaction_details = array();
40
+
41
+
42
+
43
+	/**
44
+	 * An array of event details for the related event to the registration being processed.
45
+	 * This is set via the _set_related_details method.
46
+	 *
47
+	 * @var array
48
+	 */
49
+	protected $_event_details = array();
50
+
51
+
52
+
53
+	/**
54
+	 * @param \Registrations_Admin_Page $admin_page
55
+	 */
56
+	public function __construct(Registrations_Admin_Page $admin_page)
57
+	{
58
+		if ( ! empty($_GET['event_id'])) {
59
+			$extra_query_args = array();
60
+			foreach ($admin_page->get_views() as $key => $view_details) {
61
+				$extra_query_args[$view_details['slug']] = array('event_id' => $_GET['event_id']);
62
+			}
63
+			$this->_views = $admin_page->get_list_table_view_RLs($extra_query_args);
64
+		}
65
+		parent::__construct($admin_page);
66
+		$this->_status = $this->_admin_page->get_registration_status_array();
67
+	}
68
+
69
+
70
+
71
+	/**
72
+	 *    _setup_data
73
+	 *
74
+	 * @access protected
75
+	 * @return void
76
+	 */
77
+	protected function _setup_data()
78
+	{
79
+		$this->_data = $this->_admin_page->get_registrations($this->_per_page);
80
+		$this->_all_data_count = $this->_admin_page->get_registrations($this->_per_page, true, false, false);
81
+	}
82
+
83
+
84
+
85
+	/**
86
+	 *    _set_properties
87
+	 *
88
+	 * @access protected
89
+	 * @return void
90
+	 */
91
+	protected function _set_properties()
92
+	{
93
+		$this->_wp_list_args = array(
94
+			'singular' => __('registration', 'event_espresso'),
95
+			'plural'   => __('registrations', 'event_espresso'),
96
+			'ajax'     => true,
97
+			'screen'   => $this->_admin_page->get_current_screen()->id,
98
+		);
99
+		$ID_column_name = __('ID', 'event_espresso');
100
+		$ID_column_name .= ' : <span class="show-on-mobile-view-only" style="float:none">';
101
+		$ID_column_name .= __('Registrant Name', 'event_espresso');
102
+		$ID_column_name .= '</span> ';
103
+		if (isset($_GET['event_id'])) {
104
+			$this->_columns = array(
105
+				'cb'               => '<input type="checkbox" />', //Render a checkbox instead of text
106
+				'_REG_ID'          => $ID_column_name,
107
+				'ATT_fname'        => __('Name', 'event_espresso'),
108
+				'ATT_email'        => __('Email', 'event_espresso'),
109
+				'_REG_date'        => __('Reg Date', 'event_espresso'),
110
+				'PRC_amount'       => __('TKT Price', 'event_espresso'),
111
+				'_REG_final_price' => __('Final Price', 'event_espresso'),
112
+				'TXN_total'        => __('Total Txn', 'event_espresso'),
113
+				'TXN_paid'         => __('Paid', 'event_espresso'),
114
+				'actions'          => __('Actions', 'event_espresso'),
115
+			);
116
+			$this->_bottom_buttons = array(
117
+				'report' => array(
118
+					'route'         => 'registrations_report',
119
+					'extra_request' => array(
120
+						'EVT_ID'     => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null,
121
+						'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
122
+					),
123
+				),
124
+			);
125
+		} else {
126
+			$this->_columns = array(
127
+				'cb'               => '<input type="checkbox" />', //Render a checkbox instead of text
128
+				'_REG_ID'          => $ID_column_name,
129
+				'ATT_fname'        => __('Name', 'event_espresso'),
130
+				'_REG_date'        => __('TXN Date', 'event_espresso'),
131
+				'event_name'       => __('Event', 'event_espresso'),
132
+				'DTT_EVT_start'    => __('Event Date', 'event_espresso'),
133
+				'_REG_final_price' => __('Price', 'event_espresso'),
134
+				'_REG_paid'        => __('Paid', 'event_espresso'),
135
+				'actions'          => __('Actions', 'event_espresso'),
136
+			);
137
+			$this->_bottom_buttons = array(
138
+				'report_all' => array(
139
+					'route'         => 'registrations_report',
140
+					'extra_request' => array(
141
+						'return_url' => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
142
+					),
143
+				),
144
+			);
145
+		}
146
+		$this->_bottom_buttons['report_filtered'] = array(
147
+			'route'         => 'registrations_report',
148
+			'extra_request' => array(
149
+				'use_filters' => true,
150
+				'filters'     => array_diff_key($this->_req_data, array_flip(array(
151
+							'page',
152
+							'action',
153
+							'default_nonce',
154
+						))),
155
+				'return_url'  => urlencode("//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"),
156
+			),
157
+		);
158
+		$this->_primary_column = '_REG_ID';
159
+		$this->_sortable_columns = array(
160
+			'_REG_date'     => array('_REG_date' => true),   //true means its already sorted
161
+			/**
162
+			 * Allows users to change the default sort if they wish.
163
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
164
+			 */
165
+			'ATT_fname'     => array(
166
+					'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
167
+					true,
168
+					$this
169
+				)
170
+				? array('ATT_lname' => false)
171
+				: array('ATT_fname' => false),
172
+			'event_name'    => array('event_name' => false),
173
+			'DTT_EVT_start' => array('DTT_EVT_start' => false),
174
+			'_REG_ID'       => array('_REG_ID' => false),
175
+		);
176
+		$this->_hidden_columns = array();
177
+	}
178
+
179
+
180
+
181
+	/**
182
+	 * This simply sets up the row class for the table rows.
183
+	 * Allows for easier overriding of child methods for setting up sorting.
184
+	 *
185
+	 * @param  EE_Registration $item the current item
186
+	 * @return string
187
+	 */
188
+	protected function _get_row_class($item)
189
+	{
190
+		$class = parent::_get_row_class($item);
191
+		//add status class
192
+		$class .= ' ee-status-strip reg-status-' . $item->status_ID();
193
+		if ($this->_has_checkbox_column) {
194
+			$class .= ' has-checkbox-column';
195
+		}
196
+		return $class;
197
+	}
198
+
199
+
200
+
201
+	/**
202
+	 * Set the $_transaction_details property if not set yet.
203
+	 *
204
+	 * @param EE_Registration $registration
205
+	 * @throws \EE_Error
206
+	 */
207
+	protected function _set_related_details(EE_Registration $registration)
208
+	{
209
+		$transaction = $registration->get_first_related('Transaction');
210
+		$status = $transaction instanceof EE_Transaction ? $transaction->status_ID()
211
+			: EEM_Transaction::failed_status_code;
212
+		$this->_transaction_details = array(
213
+			'transaction' => $transaction,
214
+			'status'      => $status,
215
+			'id'          => $transaction instanceof EE_Transaction ? $transaction->ID() : 0,
216
+			'title_attr'  => sprintf(__('View Transaction Details (%s)', 'event_espresso'),
217
+				EEH_Template::pretty_status($status, false, 'sentence')),
218
+		);
219
+		try {
220
+			$event = $registration->event();
221
+		} catch (\EventEspresso\core\exceptions\EntityNotFoundException $e) {
222
+			$event = null;
223
+		}
224
+		$status = $event instanceof EE_Event ? $event->get_active_status() : EE_Datetime::inactive;
225
+		$this->_event_details = array(
226
+			'event'      => $event,
227
+			'status'     => $status,
228
+			'id'         => $event instanceof EE_Event ? $event->ID() : 0,
229
+			'title_attr' => sprintf(__('Edit Event (%s)', 'event_espresso'),
230
+				EEH_Template::pretty_status($status, false, 'sentence')),
231
+		);
232
+	}
233
+
234
+
235
+
236
+	/**
237
+	 *    _get_table_filters
238
+	 *
239
+	 * @access protected
240
+	 * @return array
241
+	 */
242
+	protected function _get_table_filters()
243
+	{
244
+		$filters = array();
245
+		//todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as methods.
246
+		$cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
247
+		$cur_category = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
248
+		$reg_status = isset($this->_req_data['_reg_status']) ? $this->_req_data['_reg_status'] : '';
249
+		$filters[] = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category);
250
+		$filters[] = EEH_Form_Fields::generate_event_category_dropdown($cur_category);
251
+		$status = array();
252
+		$status[] = array('id' => 0, 'text' => __('Select Status', 'event_espresso'));
253
+		foreach ($this->_status as $key => $value) {
254
+			$status[] = array('id' => $key, 'text' => $value);
255
+		}
256
+		if ($this->_view !== 'incomplete') {
257
+			$filters[] = EEH_Form_Fields::select_input('_reg_status', $status,
258
+				isset($this->_req_data['_reg_status']) ? strtoupper(sanitize_key($this->_req_data['_reg_status']))
259
+					: '');
260
+		}
261
+		if (isset($this->_req_data['event_id'])) {
262
+			$filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id');
263
+		}
264
+		return $filters;
265
+	}
266
+
267
+
268
+
269
+	/**
270
+	 *    _add_view_counts
271
+	 *
272
+	 * @access protected
273
+	 * @return void
274
+	 * @throws \EE_Error
275
+	 */
276
+	protected function _add_view_counts()
277
+	{
278
+		$this->_views['all']['count'] = $this->_total_registrations();
279
+		$this->_views['month']['count'] = $this->_total_registrations_this_month();
280
+		$this->_views['today']['count'] = $this->_total_registrations_today();
281
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_registrations',
282
+			'espresso_registrations_trash_registrations')
283
+		) {
284
+			$this->_views['incomplete']['count'] = $this->_total_registrations('incomplete');
285
+			$this->_views['trash']['count'] = $this->_total_registrations('trash');
286
+		}
287
+	}
288
+
289
+
290
+
291
+	/**
292
+	 * _total_registrations
293
+	 *
294
+	 * @access protected
295
+	 * @param string $view
296
+	 * @return int
297
+	 * @throws \EE_Error
298
+	 */
299
+	protected function _total_registrations($view = '')
300
+	{
301
+		$_where = array();
302
+		$EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
303
+		if ($EVT_ID) {
304
+			$_where['EVT_ID'] = $EVT_ID;
305
+		}
306
+		switch ($view) {
307
+			case 'trash' :
308
+				return EEM_Registration::instance()->count_deleted(array($_where));
309
+				break;
310
+			case 'incomplete' :
311
+				$_where['STS_ID'] = EEM_Registration::status_id_incomplete;
312
+				break;
313
+			default :
314
+				$_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
315
+		}
316
+		return EEM_Registration::instance()->count(array($_where));
317
+	}
318
+
319
+
320
+
321
+	/**
322
+	 * _total_registrations_this_month
323
+	 *
324
+	 * @access protected
325
+	 * @return int
326
+	 * @throws \EE_Error
327
+	 */
328
+	protected function _total_registrations_this_month()
329
+	{
330
+		$EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
331
+		$_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array();
332
+		$this_year_r = date('Y', current_time('timestamp'));
333
+		$time_start = ' 00:00:00';
334
+		$time_end = ' 23:59:59';
335
+		$this_month_r = date('m', current_time('timestamp'));
336
+		$days_this_month = date('t', current_time('timestamp'));
337
+		//setup date query.
338
+		$beginning_string = EEM_Registration::instance()
339
+											->convert_datetime_for_query('REG_date',
340
+												$this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
341
+												'Y-m-d H:i:s');
342
+		$end_string = EEM_Registration::instance()
343
+									  ->convert_datetime_for_query('REG_date',
344
+										  $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
345
+										  'Y-m-d H:i:s');
346
+		$_where['REG_date'] = array(
347
+			'BETWEEN',
348
+			array(
349
+				$beginning_string,
350
+				$end_string,
351
+			),
352
+		);
353
+		$_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
354
+		return EEM_Registration::instance()->count(array($_where));
355
+	}
356
+
357
+
358
+
359
+	/**
360
+	 * _total_registrations_today
361
+	 *
362
+	 * @access protected
363
+	 * @return int
364
+	 * @throws \EE_Error
365
+	 */
366
+	protected function _total_registrations_today()
367
+	{
368
+		$EVT_ID = isset($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : false;
369
+		$_where = $EVT_ID ? array('EVT_ID' => $EVT_ID) : array();
370
+		$current_date = date('Y-m-d', current_time('timestamp'));
371
+		$time_start = ' 00:00:00';
372
+		$time_end = ' 23:59:59';
373
+		$_where['REG_date'] = array(
374
+			'BETWEEN',
375
+			array(
376
+				EEM_Registration::instance()
377
+								->convert_datetime_for_query('REG_date', $current_date . $time_start, 'Y-m-d H:i:s'),
378
+				EEM_Registration::instance()
379
+								->convert_datetime_for_query('REG_date', $current_date . $time_end, 'Y-m-d H:i:s'),
380
+			),
381
+		);
382
+		$_where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
383
+		return EEM_Registration::instance()->count(array($_where));
384
+	}
385
+
386
+
387
+
388
+	/**
389
+	 * column_cb
390
+	 *
391
+	 * @access public
392
+	 * @param \EE_Registration $item
393
+	 * @return string
394
+	 * @throws \EE_Error
395
+	 */
396
+	public function column_cb($item)
397
+	{
398
+		/** checkbox/lock **/
399
+		$transaction = $item->get_first_related('Transaction');
400
+		$payment_count = $transaction instanceof EE_Transaction ? $transaction->count_related('Payment') : 0;
401
+		return $payment_count > 0
402
+			||  ! EE_Registry::instance()->CAP->current_user_can(
403
+				'ee_edit_registration',
404
+				'registration_list_table_checkbox_input',
405
+				$item->ID()
406
+			)
407
+			? sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID())
408
+									. '<span class="ee-lock-icon"></span>'
409
+			: sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID());
410
+	}
411
+
412
+
413
+
414
+	/**
415
+	 * column__REG_ID
416
+	 *
417
+	 * @access public
418
+	 * @param \EE_Registration $item
419
+	 * @return string
420
+	 * @throws \EE_Error
421
+	 */
422
+	public function column__REG_ID(EE_Registration $item)
423
+	{
424
+		$attendee = $item->attendee();
425
+		$content = $item->ID();
426
+		$content .= '<div class="show-on-mobile-view-only">';
427
+		$content .= '<br>';
428
+		$content .= $attendee instanceof EE_Attendee ? $attendee->full_name() : '';
429
+		$content .= '&nbsp;' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
430
+		$content .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
431
+		$content .= '</div>';
432
+		return $content;
433
+	}
434
+
435
+
436
+
437
+	/**
438
+	 * column__REG_date
439
+	 *
440
+	 * @access public
441
+	 * @param \EE_Registration $item
442
+	 * @return string
443
+	 * @throws \EE_Error
444
+	 */
445
+	public function column__REG_date(EE_Registration $item)
446
+	{
447
+		$this->_set_related_details($item);
448
+		//Build row actions
449
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
450
+			'action' => 'view_transaction',
451
+			'TXN_ID' => $this->_transaction_details['id'],
452
+		), TXN_ADMIN_URL);
453
+		$view_link = EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
454
+			'espresso_transactions_view_transaction') ? '<a class="ee-status-color-'
455
+														. $this->_transaction_details['status']
456
+														. '" href="'
457
+														. $view_lnk_url
458
+														. '" title="'
459
+														. esc_attr($this->_transaction_details['title_attr'])
460
+														. '">'
461
+														. $item->get_i18n_datetime('REG_date')
462
+														. '</a>' : $item->get_i18n_datetime('REG_date');
463
+		$view_link .= '<br><span class="ee-status-text-small">'
464
+					  . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
465
+					  . '</span>';
466
+		return $view_link;
467
+	}
468
+
469
+
470
+
471
+	/**
472
+	 * column_event_name
473
+	 *
474
+	 * @access public
475
+	 * @param \EE_Registration $item
476
+	 * @return string
477
+	 * @throws \EE_Error
478
+	 */
479
+	public function column_event_name(EE_Registration $item)
480
+	{
481
+		$this->_set_related_details($item);
482
+		// page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62
483
+		$EVT_ID = $item->event_ID();
484
+		$event_name = $item->event_name();
485
+		$event_name = $event_name ? $event_name : __("No Associated Event", 'event_espresso');
486
+		$event_name = wp_trim_words($event_name, 30, '...');
487
+		if ($EVT_ID) {
488
+			$edit_event_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'edit', 'post' => $EVT_ID),
489
+				EVENTS_ADMIN_URL);
490
+			$edit_event = EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
491
+				? '<a class="ee-status-color-'
492
+				  . $this->_event_details['status']
493
+				  . '" href="'
494
+				  . $edit_event_url
495
+				  . '" title="'
496
+				  . esc_attr($this->_event_details['title_attr'])
497
+				  . '">'
498
+				  . $event_name
499
+				  . '</a>' : $event_name;
500
+			$edit_event_url = EE_Admin_Page::add_query_args_and_nonce(array('event_id' => $EVT_ID), REG_ADMIN_URL);
501
+			$actions['event_filter'] = '<a href="' . $edit_event_url . '" title="';
502
+			$actions['event_filter'] .= sprintf(esc_attr__('Filter this list to only show registrations for %s',
503
+				'event_espresso'), $event_name);
504
+			$actions['event_filter'] .= '">' . __('View Registrations', 'event_espresso') . '</a>';
505
+		} else {
506
+			$edit_event = $event_name;
507
+			$actions['event_filter'] = '';
508
+		}
509
+		return sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions));
510
+	}
511
+
512
+
513
+
514
+	/**
515
+	 * column_DTT_EVT_start
516
+	 *
517
+	 * @access public
518
+	 * @param \EE_Registration $item
519
+	 * @return string
520
+	 * @throws \EE_Error
521
+	 */
522
+	public function column_DTT_EVT_start(EE_Registration $item)
523
+	{
524
+		$datetime_strings = array();
525
+		$ticket = $item->ticket(true);
526
+		if ($ticket instanceof EE_Ticket) {
527
+			$remove_defaults = array('default_where_conditions' => 'none');
528
+			$datetimes = $ticket->datetimes($remove_defaults);
529
+			foreach ($datetimes as $datetime) {
530
+				$datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start');
531
+			}
532
+			return implode("<br />", $datetime_strings);
533
+		} else {
534
+			return __('There is no ticket on this registration', 'event_espresso');
535
+		}
536
+	}
537
+
538
+
539
+
540
+	/**
541
+	 * column_ATT_fname
542
+	 *
543
+	 * @access public
544
+	 * @param \EE_Registration $item
545
+	 * @return string
546
+	 * @throws \EE_Error
547
+	 */
548
+	public function column_ATT_fname(EE_Registration $item)
549
+	{
550
+		$attendee = $item->attendee();
551
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
552
+			'action'  => 'view_registration',
553
+			'_REG_ID' => $item->ID(),
554
+		), REG_ADMIN_URL);
555
+		$attendee_name = $attendee instanceof EE_Attendee ? $attendee->full_name() : '';
556
+		$link = EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
557
+			'espresso_registrations_view_registration', $item->ID()) ? '<a href="'
558
+																	   . $edit_lnk_url
559
+																	   . '" title="'
560
+																	   . esc_attr__('View Registration Details',
561
+				'event_espresso')
562
+																	   . '">'
563
+																	   . $attendee_name
564
+																	   . '</a>' : $attendee_name;
565
+		$link .= $item->count() === 1
566
+			? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>' : '';
567
+		$t = $item->get_first_related('Transaction');
568
+		$payment_count = $t instanceof EE_Transaction ? $t->count_related('Payment') : 0;
569
+		//append group count to name
570
+		$link .= '&nbsp;' . sprintf(__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
571
+		//append reg_code
572
+		$link .= '<br>' . sprintf(__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
573
+		//reg status text for accessibility
574
+		$link .= '<br><span class="ee-status-text-small">' . EEH_Template::pretty_status($item->status_ID(), false,
575
+				'sentence') . '</span>';
576
+		//trash/restore/delete actions
577
+		$actions = array();
578
+		if ($this->_view !== 'trash'
579
+			&& $payment_count === 0
580
+			&& EE_Registry::instance()->CAP->current_user_can('ee_delete_registration',
581
+				'espresso_registrations_trash_registrations', $item->ID())
582
+		) {
583
+			$trash_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
584
+				'action'  => 'trash_registrations',
585
+				'_REG_ID' => $item->ID(),
586
+			), REG_ADMIN_URL);
587
+			$actions['trash'] = '<a href="' . $trash_lnk_url . '" title="' . esc_attr__('Trash Registration',
588
+					'event_espresso') . '">' . __('Trash', 'event_espresso') . '</a>';
589
+		} elseif ($this->_view === 'trash') {
590
+			// restore registration link
591
+			if (EE_Registry::instance()->CAP->current_user_can('ee_delete_registration',
592
+				'espresso_registrations_restore_registrations', $item->ID())
593
+			) {
594
+				$restore_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
595
+					'action'  => 'restore_registrations',
596
+					'_REG_ID' => $item->ID(),
597
+				), REG_ADMIN_URL);
598
+				$actions['restore'] = '<a href="' . $restore_lnk_url . '" title="' . esc_attr__('Restore Registration',
599
+						'event_espresso') . '">' . __('Restore', 'event_espresso') . '</a>';
600
+			}
601
+			if (EE_Registry::instance()->CAP->current_user_can('ee_delete_registration',
602
+				'espresso_registrations_ee_delete_registrations', $item->ID())
603
+			) {
604
+				$delete_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
605
+					'action'  => 'delete_registrations',
606
+					'_REG_ID' => $item->ID(),
607
+				), REG_ADMIN_URL);
608
+				$actions['delete'] = '<a href="'
609
+									 . $delete_lnk_url
610
+									 . '" title="'
611
+									 . esc_attr__('Delete Registration Permanently', 'event_espresso')
612
+									 . '">'
613
+									 . __('Delete', 'event_espresso')
614
+									 . '</a>';
615
+			}
616
+		}
617
+		return sprintf('%1$s %2$s', $link, $this->row_actions($actions));
618
+	}
619
+
620
+
621
+
622
+	/**
623
+	 * column_ATT_email
624
+	 *
625
+	 * @access public
626
+	 * @param \EE_Registration $item
627
+	 * @return string
628
+	 * @throws \EE_Error
629
+	 */
630
+	public function column_ATT_email(EE_Registration $item)
631
+	{
632
+		$attendee = $item->get_first_related('Attendee');
633
+		return ! $attendee instanceof EE_Attendee ? __('No attached contact record.', 'event_espresso')
634
+			: $attendee->email();
635
+	}
636
+
637
+
638
+
639
+	/**
640
+	 * column__REG_count
641
+	 *
642
+	 * @access public
643
+	 * @param \EE_Registration $item
644
+	 * @return string
645
+	 */
646
+	public function column__REG_count(EE_Registration $item)
647
+	{
648
+		return sprintf(__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size());
649
+	}
650
+
651
+
652
+
653
+	/**
654
+	 * column_PRC_amount
655
+	 *
656
+	 * @access public
657
+	 * @param \EE_Registration $item
658
+	 * @return string
659
+	 */
660
+	public function column_PRC_amount(EE_Registration $item)
661
+	{
662
+		$ticket = $item->ticket();
663
+		$content = isset($_GET['event_id']) && $ticket instanceof EE_Ticket ? '<span class="TKT_name">'
664
+																			  . $ticket->name()
665
+																			  . '</span><br />' : '';
666
+		if ($item->final_price() > 0) {
667
+			$content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
668
+		} else {
669
+			// free event
670
+			$content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
671
+						. __('free', 'event_espresso')
672
+						. '</span>';
673
+		}
674
+		return $content;
675
+	}
676
+
677
+
678
+
679
+	/**
680
+	 * column__REG_final_price
681
+	 *
682
+	 * @access public
683
+	 * @param \EE_Registration $item
684
+	 * @return string
685
+	 */
686
+	public function column__REG_final_price(EE_Registration $item)
687
+	{
688
+		$ticket = $item->ticket();
689
+		$content = isset($_GET['event_id']) || ! $ticket instanceof EE_Ticket
690
+			? ''
691
+			: '<span class="TKT_name">'
692
+			  . $ticket->name()
693
+			  . '</span><br />';
694
+		$content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
695
+		return $content;
696
+	}
697
+
698
+
699
+
700
+	/**
701
+	 * column__REG_paid
702
+	 *
703
+	 * @access public
704
+	 * @param \EE_Registration $item
705
+	 * @return string
706
+	 */
707
+	public function column__REG_paid(EE_Registration $item)
708
+	{
709
+		$payment_method = $item->payment_method();
710
+		$payment_method_name = $payment_method instanceof EE_Payment_Method ? $payment_method->admin_name()
711
+			: __('Unknown', 'event_espresso');
712
+		$content = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>';
713
+		if ($item->paid() > 0) {
714
+			$content .= '<br><span class="ee-status-text-small">' . sprintf(__('...via %s', 'event_espresso'),
715
+					$payment_method_name) . '</span>';
716
+		}
717
+		return $content;
718
+	}
719
+
720
+
721
+
722
+	/**
723
+	 * column_TXN_total
724
+	 *
725
+	 * @access public
726
+	 * @param \EE_Registration $item
727
+	 * @return string
728
+	 * @throws \EE_Error
729
+	 */
730
+	public function column_TXN_total(EE_Registration $item)
731
+	{
732
+		if ($item->transaction()) {
733
+			$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
734
+				'action' => 'view_transaction',
735
+				'TXN_ID' => $item->transaction_ID(),
736
+			), TXN_ADMIN_URL);
737
+			return EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
738
+				'espresso_transactions_view_transaction', $item->transaction_ID())
739
+				? '<span class="reg-pad-rght"><a class="status-'
740
+				  . $item->transaction()->status_ID()
741
+				  . '" href="'
742
+				  . $view_txn_lnk_url
743
+				  . '"  title="'
744
+				  . esc_attr__('View Transaction', 'event_espresso')
745
+				  . '">'
746
+				  . $item->transaction()->pretty_total()
747
+				  . '</a></span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
748
+		} else {
749
+			return __("None", "event_espresso");
750
+		}
751
+	}
752
+
753
+
754
+
755
+	/**
756
+	 * column_TXN_paid
757
+	 *
758
+	 * @access public
759
+	 * @param \EE_Registration $item
760
+	 * @return string
761
+	 * @throws \EE_Error
762
+	 */
763
+	public function column_TXN_paid(EE_Registration $item)
764
+	{
765
+		if ($item->count() === 1) {
766
+			$transaction = $item->transaction() ? $item->transaction() : EE_Transaction::new_instance();
767
+			if ($transaction->paid() >= $transaction->total()) {
768
+				return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
769
+			} else {
770
+				$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
771
+					'action' => 'view_transaction',
772
+					'TXN_ID' => $item->transaction_ID(),
773
+				), TXN_ADMIN_URL);
774
+				return EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
775
+					'espresso_transactions_view_transaction', $item->transaction_ID())
776
+					? '<span class="reg-pad-rght"><a class="status-'
777
+					  . $transaction->status_ID()
778
+					  . '" href="'
779
+					  . $view_txn_lnk_url
780
+					  . '"  title="'
781
+					  . esc_attr__('View Transaction', 'event_espresso')
782
+					  . '">'
783
+					  . $item->transaction()->pretty_paid()
784
+					  . '</a><span>' : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
785
+			}
786
+		}
787
+		return '&nbsp;';
788
+	}
789
+
790
+
791
+
792
+	/**
793
+	 * column_actions
794
+	 *
795
+	 * @access public
796
+	 * @param \EE_Registration $item
797
+	 * @return string
798
+	 * @throws \EE_Error
799
+	 */
800
+	public function column_actions(EE_Registration $item)
801
+	{
802
+		$actions = array();
803
+		$attendee = $item->attendee();
804
+		$this->_set_related_details($item);
805
+		//Build row actions
806
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
807
+			'action'  => 'view_registration',
808
+			'_REG_ID' => $item->ID(),
809
+		), REG_ADMIN_URL);
810
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
811
+			'action' => 'edit_attendee',
812
+			'post'   => $item->attendee_ID(),
813
+		), REG_ADMIN_URL);
814
+		// page=attendees&event_admin_reports=resend_email&registration_id=43653465634&event_id=2&form_action=resend_email
815
+		//$resend_reg_lnk_url_params = array( 'action'=>'resend_registration', '_REG_ID'=>$item->REG_ID );
816
+		$resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
817
+			'action'  => 'resend_registration',
818
+			'_REG_ID' => $item->ID(),
819
+		), REG_ADMIN_URL, true);
820
+		//Build row actions
821
+		$actions['view_lnk'] = EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
822
+			'espresso_registrations_view_registration', $item->ID()) ? '
823 823
 			<li>
824 824
 			<a href="' . $view_lnk_url . '" title="' . esc_attr__('View Registration Details', 'event_espresso') . '" class="tiny-text">
825 825
 				<div class="dashicons dashicons-clipboard"></div>
826 826
 			</a>
827 827
 			</li>' : '';
828
-        $actions['edit_lnk'] = EE_Registry::instance()->CAP->current_user_can('ee_edit_contacts',
829
-            'espresso_registrations_edit_attendee')
830
-                               && $attendee instanceof EE_Attendee ? '
828
+		$actions['edit_lnk'] = EE_Registry::instance()->CAP->current_user_can('ee_edit_contacts',
829
+			'espresso_registrations_edit_attendee')
830
+							   && $attendee instanceof EE_Attendee ? '
831 831
 			<li>
832 832
 			<a href="' . $edit_lnk_url . '" title="' . esc_attr__('Edit Contact Details', 'event_espresso') . '" class="tiny-text">
833 833
 				<div class="ee-icon ee-icon-user-edit ee-icon-size-16"></div>
834 834
 			</a>
835 835
 			</li>' : '';
836
-        $actions['resend_reg_lnk'] = $attendee instanceof EE_Attendee
837
-                                     && EE_Registry::instance()->CAP->current_user_can('ee_send_message',
838
-            'espresso_registrations_resend_registration', $item->ID()) ? '
836
+		$actions['resend_reg_lnk'] = $attendee instanceof EE_Attendee
837
+									 && EE_Registry::instance()->CAP->current_user_can('ee_send_message',
838
+			'espresso_registrations_resend_registration', $item->ID()) ? '
839 839
 			<li>
840 840
 			<a href="'
841
-                                                                         . $resend_reg_lnk_url
842
-                                                                         . '" title="'
843
-                                                                         . esc_attr__('Resend Registration Details',
844
-                'event_espresso')
845
-                                                                         . '" class="tiny-text">
841
+																		 . $resend_reg_lnk_url
842
+																		 . '" title="'
843
+																		 . esc_attr__('Resend Registration Details',
844
+				'event_espresso')
845
+																		 . '" class="tiny-text">
846 846
 				<div class="dashicons dashicons-email-alt"></div>
847 847
 			</a>
848 848
 			</li>' : '';
849
-        // page=transactions&action=view_transaction&txn=256&_wpnonce=6414da4dbb
850
-        $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
851
-            'action' => 'view_transaction',
852
-            'TXN_ID' => $this->_transaction_details['id'],
853
-        ), TXN_ADMIN_URL);
854
-        $actions['view_txn_lnk'] = EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
855
-            'espresso_transactions_view_transaction', $this->_transaction_details['id']) ? '
849
+		// page=transactions&action=view_transaction&txn=256&_wpnonce=6414da4dbb
850
+		$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
851
+			'action' => 'view_transaction',
852
+			'TXN_ID' => $this->_transaction_details['id'],
853
+		), TXN_ADMIN_URL);
854
+		$actions['view_txn_lnk'] = EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
855
+			'espresso_transactions_view_transaction', $this->_transaction_details['id']) ? '
856 856
 			<li>
857 857
 			<a class="ee-status-color-'
858
-                                                                                           . $this->_transaction_details['status']
859
-                                                                                           . ' tiny-text" href="'
860
-                                                                                           . $view_txn_lnk_url
861
-                                                                                           . '"  title="'
862
-                                                                                           . $this->_transaction_details['title_attr']
863
-                                                                                           . '">
858
+																						   . $this->_transaction_details['status']
859
+																						   . ' tiny-text" href="'
860
+																						   . $view_txn_lnk_url
861
+																						   . '"  title="'
862
+																						   . $this->_transaction_details['title_attr']
863
+																						   . '">
864 864
 				<div class="dashicons dashicons-cart"></div>
865 865
 			</a>
866 866
 			</li>' : '';
867
-        //invoice link
868
-        $actions['dl_invoice_lnk'] = '';
869
-        $dl_invoice_lnk_url = $item->invoice_url();
870
-        //only show invoice link if message type is active.
871
-        if ($attendee instanceof EE_Attendee
872
-            && $item->is_primary_registrant()
873
-            && EEH_MSG_Template::is_mt_active('invoice')
874
-        ) {
875
-            $actions['dl_invoice_lnk'] = '
867
+		//invoice link
868
+		$actions['dl_invoice_lnk'] = '';
869
+		$dl_invoice_lnk_url = $item->invoice_url();
870
+		//only show invoice link if message type is active.
871
+		if ($attendee instanceof EE_Attendee
872
+			&& $item->is_primary_registrant()
873
+			&& EEH_MSG_Template::is_mt_active('invoice')
874
+		) {
875
+			$actions['dl_invoice_lnk'] = '
876 876
 		<li>
877 877
 			<a title="'
878
-                                         . esc_attr__('View Transaction Invoice', 'event_espresso')
879
-                                         . '" target="_blank" href="'
880
-                                         . $dl_invoice_lnk_url
881
-                                         . '" class="tiny-text">
878
+										 . esc_attr__('View Transaction Invoice', 'event_espresso')
879
+										 . '" target="_blank" href="'
880
+										 . $dl_invoice_lnk_url
881
+										 . '" class="tiny-text">
882 882
 				<span class="dashicons dashicons-media-spreadsheet ee-icon-size-18"></span>
883 883
 			</a>
884 884
 		</li>';
885
-        }
886
-        $actions['filtered_messages_link'] = '';
887
-        //message list table link (filtered by REG_ID
888
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
889
-            $actions['filtered_messages_link'] = '<li>'
890
-                                                 . EEH_MSG_Template::get_message_action_link('see_notifications_for',
891
-                    null, array(
892
-                        '_REG_ID' => $item->ID(),
893
-                    ))
894
-                                                 . '</li>';
895
-        }
896
-        $actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this);
897
-        return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul');
898
-    }
885
+		}
886
+		$actions['filtered_messages_link'] = '';
887
+		//message list table link (filtered by REG_ID
888
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
889
+			$actions['filtered_messages_link'] = '<li>'
890
+												 . EEH_MSG_Template::get_message_action_link('see_notifications_for',
891
+					null, array(
892
+						'_REG_ID' => $item->ID(),
893
+					))
894
+												 . '</li>';
895
+		}
896
+		$actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this);
897
+		return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul');
898
+	}
899 899
 
900 900
 }
Please login to merge, or discard this patch.
core/services/loaders/CachingLoader.php 2 patches
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -22,117 +22,117 @@
 block discarded – undo
22 22
 class CachingLoader extends LoaderDecorator
23 23
 {
24 24
 
25
-    /**
26
-     * @var CollectionInterface $cache
27
-     */
28
-    protected $cache;
29
-
30
-    /**
31
-     * @var string $identifier
32
-     */
33
-    protected $identifier;
34
-
35
-
36
-
37
-    /**
38
-     * CachingLoader constructor.
39
-     *
40
-     * @param LoaderDecoratorInterface $loader
41
-     * @param CollectionInterface      $cache
42
-     * @param string                   $identifier
43
-     * @throws InvalidDataTypeException
44
-     */
45
-    public function __construct(LoaderDecoratorInterface $loader, CollectionInterface $cache, $identifier = '')
46
-    {
47
-        parent::__construct($loader);
48
-        $this->cache = $cache;
49
-        $this->setIdentifier($identifier);
50
-        if ($this->identifier !== '') {
51
-            // to only clear this cache, and assuming an identifier has been set, simply do the following:
52
-            // do_action('AHEE__EventEspresso\core\services\loaders\CachingLoader__resetCache__IDENTIFIER');
53
-            // where "IDENTIFIER" = the string that was set during construction
54
-            add_action(
55
-                "AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache__{$identifier}",
56
-                array($this, 'reset')
57
-            );
58
-        }
59
-        // to clear ALL caches, simply do the following:
60
-        // do_action('AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache');
61
-        add_action(
62
-            'AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache',
63
-            array($this, 'reset')
64
-        );
65
-    }
66
-
67
-
68
-
69
-    /**
70
-     * @return string
71
-     */
72
-    public function identifier()
73
-    {
74
-        return $this->identifier;
75
-    }
76
-
77
-
78
-
79
-    /**
80
-     * @param string $identifier
81
-     * @throws InvalidDataTypeException
82
-     */
83
-    private function setIdentifier($identifier)
84
-    {
85
-        if ( ! is_string($identifier)) {
86
-            throw new InvalidDataTypeException('$identifier', $identifier, 'string');
87
-        }
88
-        $this->identifier = $identifier;
89
-    }
90
-
91
-
92
-
93
-    /**
94
-     * @param string $fqcn
95
-     * @param array  $arguments
96
-     * @param bool   $shared
97
-     * @return mixed
98
-     * @throws InvalidEntityException
99
-     * @throws ServiceNotFoundException
100
-     */
101
-    public function load($fqcn, $arguments = array(), $shared = true)
102
-    {
103
-        $fqcn = ltrim($fqcn, '\\');
104
-        // caching can be turned off via the following code:
105
-        // add_filter('FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache', '__return_true');
106
-        if(
107
-            apply_filters(
108
-                'FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache',
109
-                false,
110
-                $this
111
-            )
112
-        ){
113
-            // even though $shared might be true, caching should be bypassed for whatever reason,
114
-            // so we don't want the core loader to cache anything, therefore caching is turned off
115
-            return $this->loader->load($fqcn, $arguments, false);
116
-        }
117
-        $identifier = md5($fqcn . serialize($arguments));
118
-        if($this->cache->has($identifier)){
119
-            return $this->cache->get($identifier);
120
-        }
121
-        $object = $this->loader->load($fqcn, $arguments, $shared);
122
-        $this->cache->add($object, $identifier);
123
-        return $object;
124
-    }
125
-
126
-
127
-
128
-    /**
129
-     * empties cache and calls reset() on loader if method exists
130
-     */
131
-    public function reset()
132
-    {
133
-        $this->cache->detachAll();
134
-        $this->loader->reset();
135
-    }
25
+	/**
26
+	 * @var CollectionInterface $cache
27
+	 */
28
+	protected $cache;
29
+
30
+	/**
31
+	 * @var string $identifier
32
+	 */
33
+	protected $identifier;
34
+
35
+
36
+
37
+	/**
38
+	 * CachingLoader constructor.
39
+	 *
40
+	 * @param LoaderDecoratorInterface $loader
41
+	 * @param CollectionInterface      $cache
42
+	 * @param string                   $identifier
43
+	 * @throws InvalidDataTypeException
44
+	 */
45
+	public function __construct(LoaderDecoratorInterface $loader, CollectionInterface $cache, $identifier = '')
46
+	{
47
+		parent::__construct($loader);
48
+		$this->cache = $cache;
49
+		$this->setIdentifier($identifier);
50
+		if ($this->identifier !== '') {
51
+			// to only clear this cache, and assuming an identifier has been set, simply do the following:
52
+			// do_action('AHEE__EventEspresso\core\services\loaders\CachingLoader__resetCache__IDENTIFIER');
53
+			// where "IDENTIFIER" = the string that was set during construction
54
+			add_action(
55
+				"AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache__{$identifier}",
56
+				array($this, 'reset')
57
+			);
58
+		}
59
+		// to clear ALL caches, simply do the following:
60
+		// do_action('AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache');
61
+		add_action(
62
+			'AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache',
63
+			array($this, 'reset')
64
+		);
65
+	}
66
+
67
+
68
+
69
+	/**
70
+	 * @return string
71
+	 */
72
+	public function identifier()
73
+	{
74
+		return $this->identifier;
75
+	}
76
+
77
+
78
+
79
+	/**
80
+	 * @param string $identifier
81
+	 * @throws InvalidDataTypeException
82
+	 */
83
+	private function setIdentifier($identifier)
84
+	{
85
+		if ( ! is_string($identifier)) {
86
+			throw new InvalidDataTypeException('$identifier', $identifier, 'string');
87
+		}
88
+		$this->identifier = $identifier;
89
+	}
90
+
91
+
92
+
93
+	/**
94
+	 * @param string $fqcn
95
+	 * @param array  $arguments
96
+	 * @param bool   $shared
97
+	 * @return mixed
98
+	 * @throws InvalidEntityException
99
+	 * @throws ServiceNotFoundException
100
+	 */
101
+	public function load($fqcn, $arguments = array(), $shared = true)
102
+	{
103
+		$fqcn = ltrim($fqcn, '\\');
104
+		// caching can be turned off via the following code:
105
+		// add_filter('FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache', '__return_true');
106
+		if(
107
+			apply_filters(
108
+				'FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache',
109
+				false,
110
+				$this
111
+			)
112
+		){
113
+			// even though $shared might be true, caching should be bypassed for whatever reason,
114
+			// so we don't want the core loader to cache anything, therefore caching is turned off
115
+			return $this->loader->load($fqcn, $arguments, false);
116
+		}
117
+		$identifier = md5($fqcn . serialize($arguments));
118
+		if($this->cache->has($identifier)){
119
+			return $this->cache->get($identifier);
120
+		}
121
+		$object = $this->loader->load($fqcn, $arguments, $shared);
122
+		$this->cache->add($object, $identifier);
123
+		return $object;
124
+	}
125
+
126
+
127
+
128
+	/**
129
+	 * empties cache and calls reset() on loader if method exists
130
+	 */
131
+	public function reset()
132
+	{
133
+		$this->cache->detachAll();
134
+		$this->loader->reset();
135
+	}
136 136
 
137 137
 
138 138
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -103,19 +103,19 @@
 block discarded – undo
103 103
         $fqcn = ltrim($fqcn, '\\');
104 104
         // caching can be turned off via the following code:
105 105
         // add_filter('FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache', '__return_true');
106
-        if(
106
+        if (
107 107
             apply_filters(
108 108
                 'FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache',
109 109
                 false,
110 110
                 $this
111 111
             )
112
-        ){
112
+        ) {
113 113
             // even though $shared might be true, caching should be bypassed for whatever reason,
114 114
             // so we don't want the core loader to cache anything, therefore caching is turned off
115 115
             return $this->loader->load($fqcn, $arguments, false);
116 116
         }
117
-        $identifier = md5($fqcn . serialize($arguments));
118
-        if($this->cache->has($identifier)){
117
+        $identifier = md5($fqcn.serialize($arguments));
118
+        if ($this->cache->has($identifier)) {
119 119
             return $this->cache->get($identifier);
120 120
         }
121 121
         $object = $this->loader->load($fqcn, $arguments, $shared);
Please login to merge, or discard this patch.
core/db_models/EEM_Change_Log.model.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
                 ),
107 107
             ),
108 108
         );
109
-        $this->_model_relations    = array();
109
+        $this->_model_relations = array();
110 110
         foreach ($models_this_can_attach_to as $model) {
111 111
             if ($model == 'WP_User') {
112 112
                 $this->_model_relations[$model] = new EE_Belongs_To_Relation();
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
      */
164 164
     public function gateway_log($message, $related_obj_id, $related_obj_type)
165 165
     {
166
-        if (! EE_Registry::instance()->is_model_name($related_obj_type)) {
166
+        if ( ! EE_Registry::instance()->is_model_name($related_obj_type)) {
167 167
             throw new EE_Error(
168 168
                 sprintf(
169 169
                     esc_html__(
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
         global $wpdb;
213 213
         return $wpdb->query(
214 214
             $wpdb->prepare(
215
-                'DELETE FROM ' . $this->table() . ' WHERE LOG_type = %s AND LOG_time < %s',
215
+                'DELETE FROM '.$this->table().' WHERE LOG_type = %s AND LOG_time < %s',
216 216
                 EEM_Change_Log::type_gateway,
217 217
                 $datetime->format(EE_Datetime_Field::mysql_timestamp_format)
218 218
             )
Please login to merge, or discard this patch.
Indentation   +228 added lines, -228 removed lines patch added patch discarded remove patch
@@ -13,246 +13,246 @@
 block discarded – undo
13 13
 class EEM_Change_Log extends EEM_Base
14 14
 {
15 15
 
16
-    /**
17
-     * the related object was created log type
18
-     */
19
-    const type_create = 'create';
20
-    /**
21
-     * the related object was updated (changed, or soft-deleted)
22
-     */
23
-    const type_update = 'update';
24
-    /**
25
-     * the related object was deleted permanently
26
-     */
27
-    const type_delete = 'delete';
28
-    /**
29
-     * the related item had something worth noting happen on it, but
30
-     * only for the purposes of debugging problems
31
-     */
32
-    const type_debug = 'debug';
33
-    /**
34
-     * the related item had an error occur on it
35
-     */
36
-    const type_error = 'error';
37
-    /**
38
-     * the related item is regarding some gateway interaction, like an IPN
39
-     * or request to process a payment
40
-     */
41
-    const type_gateway = 'gateway';
16
+	/**
17
+	 * the related object was created log type
18
+	 */
19
+	const type_create = 'create';
20
+	/**
21
+	 * the related object was updated (changed, or soft-deleted)
22
+	 */
23
+	const type_update = 'update';
24
+	/**
25
+	 * the related object was deleted permanently
26
+	 */
27
+	const type_delete = 'delete';
28
+	/**
29
+	 * the related item had something worth noting happen on it, but
30
+	 * only for the purposes of debugging problems
31
+	 */
32
+	const type_debug = 'debug';
33
+	/**
34
+	 * the related item had an error occur on it
35
+	 */
36
+	const type_error = 'error';
37
+	/**
38
+	 * the related item is regarding some gateway interaction, like an IPN
39
+	 * or request to process a payment
40
+	 */
41
+	const type_gateway = 'gateway';
42 42
 
43
-    /**
44
-     * private instance of the EEM_Change_Log object
45
-     *
46
-     * @access private
47
-     * @var EEM_Change_Log $_instance
48
-     */
49
-    protected static $_instance = null;
43
+	/**
44
+	 * private instance of the EEM_Change_Log object
45
+	 *
46
+	 * @access private
47
+	 * @var EEM_Change_Log $_instance
48
+	 */
49
+	protected static $_instance = null;
50 50
 
51 51
 
52
-    /**
53
-     * constructor
54
-     *
55
-     * @access protected
56
-     * @param null $timezone
57
-     * @throws EE_Error
58
-     */
59
-    protected function __construct($timezone = null)
60
-    {
61
-        global $current_user;
62
-        $this->singular_item       = esc_html__('Log', 'event_espresso');
63
-        $this->plural_item         = esc_html__('Logs', 'event_espresso');
64
-        $this->_tables             = array(
65
-            'Log' => new EE_Primary_Table('esp_log', 'LOG_ID'),
66
-        );
67
-        $models_this_can_attach_to = array_keys(EE_Registry::instance()->non_abstract_db_models);
68
-        $this->_fields             = array(
69
-            'Log' => array(
70
-                'LOG_ID'      => new EE_Primary_Key_Int_Field('LOG_ID', esc_html__('Log ID', 'event_espresso')),
71
-                'LOG_time'    => new EE_Datetime_Field(
72
-                    'LOG_time',
73
-                    esc_html__("Log Time", 'event_espresso'),
74
-                    false,
75
-                    EE_Datetime_Field::now
76
-                ),
77
-                'OBJ_ID'      => new EE_Foreign_Key_String_Field(
78
-                    'OBJ_ID',
79
-                    esc_html__("Object ID (int or string)", 'event_espresso'),
80
-                    true,
81
-                    null,
82
-                    $models_this_can_attach_to
83
-                ),
84
-                'OBJ_type'    => new EE_Any_Foreign_Model_Name_Field(
85
-                    'OBJ_type',
86
-                    esc_html__("Object Type", 'event_espresso'),
87
-                    true,
88
-                    null,
89
-                    $models_this_can_attach_to
90
-                ),
91
-                'LOG_type'    => new EE_Plain_Text_Field(
92
-                    'LOG_type',
93
-                    esc_html__("Type of log entry", "event_espresso"),
94
-                    false,
95
-                    self::type_debug
96
-                ),
97
-                'LOG_message' => new EE_Maybe_Serialized_Text_Field(
98
-                    'LOG_message',
99
-                    esc_html__("Log Message (body)", 'event_espresso'),
100
-                    true
101
-                ),
102
-                'LOG_wp_user' => new EE_WP_User_Field(
103
-                    'LOG_wp_user',
104
-                    esc_html__("User who was logged in while this occurred", 'event_espresso'),
105
-                    true
106
-                ),
107
-            ),
108
-        );
109
-        $this->_model_relations    = array();
110
-        foreach ($models_this_can_attach_to as $model) {
111
-            if ($model == 'WP_User') {
112
-                $this->_model_relations[$model] = new EE_Belongs_To_Relation();
113
-            } elseif ($model != 'Change_Log') {
114
-                $this->_model_relations[$model] = new EE_Belongs_To_Any_Relation();
115
-            }
116
-        }
117
-        //use completely custom caps for this
118
-        $this->_cap_restriction_generators = false;
119
-        //caps-wise this is all-or-nothing: if you have the default role you can access anything, otherwise nothing
120
-        foreach ($this->_cap_contexts_to_cap_action_map as $cap_context => $action) {
121
-            $this->_cap_restrictions[$cap_context][EE_Restriction_Generator_Base::get_default_restrictions_cap()]
122
-                = new EE_Return_None_Where_Conditions();
123
-        }
124
-        parent::__construct($timezone);
125
-    }
52
+	/**
53
+	 * constructor
54
+	 *
55
+	 * @access protected
56
+	 * @param null $timezone
57
+	 * @throws EE_Error
58
+	 */
59
+	protected function __construct($timezone = null)
60
+	{
61
+		global $current_user;
62
+		$this->singular_item       = esc_html__('Log', 'event_espresso');
63
+		$this->plural_item         = esc_html__('Logs', 'event_espresso');
64
+		$this->_tables             = array(
65
+			'Log' => new EE_Primary_Table('esp_log', 'LOG_ID'),
66
+		);
67
+		$models_this_can_attach_to = array_keys(EE_Registry::instance()->non_abstract_db_models);
68
+		$this->_fields             = array(
69
+			'Log' => array(
70
+				'LOG_ID'      => new EE_Primary_Key_Int_Field('LOG_ID', esc_html__('Log ID', 'event_espresso')),
71
+				'LOG_time'    => new EE_Datetime_Field(
72
+					'LOG_time',
73
+					esc_html__("Log Time", 'event_espresso'),
74
+					false,
75
+					EE_Datetime_Field::now
76
+				),
77
+				'OBJ_ID'      => new EE_Foreign_Key_String_Field(
78
+					'OBJ_ID',
79
+					esc_html__("Object ID (int or string)", 'event_espresso'),
80
+					true,
81
+					null,
82
+					$models_this_can_attach_to
83
+				),
84
+				'OBJ_type'    => new EE_Any_Foreign_Model_Name_Field(
85
+					'OBJ_type',
86
+					esc_html__("Object Type", 'event_espresso'),
87
+					true,
88
+					null,
89
+					$models_this_can_attach_to
90
+				),
91
+				'LOG_type'    => new EE_Plain_Text_Field(
92
+					'LOG_type',
93
+					esc_html__("Type of log entry", "event_espresso"),
94
+					false,
95
+					self::type_debug
96
+				),
97
+				'LOG_message' => new EE_Maybe_Serialized_Text_Field(
98
+					'LOG_message',
99
+					esc_html__("Log Message (body)", 'event_espresso'),
100
+					true
101
+				),
102
+				'LOG_wp_user' => new EE_WP_User_Field(
103
+					'LOG_wp_user',
104
+					esc_html__("User who was logged in while this occurred", 'event_espresso'),
105
+					true
106
+				),
107
+			),
108
+		);
109
+		$this->_model_relations    = array();
110
+		foreach ($models_this_can_attach_to as $model) {
111
+			if ($model == 'WP_User') {
112
+				$this->_model_relations[$model] = new EE_Belongs_To_Relation();
113
+			} elseif ($model != 'Change_Log') {
114
+				$this->_model_relations[$model] = new EE_Belongs_To_Any_Relation();
115
+			}
116
+		}
117
+		//use completely custom caps for this
118
+		$this->_cap_restriction_generators = false;
119
+		//caps-wise this is all-or-nothing: if you have the default role you can access anything, otherwise nothing
120
+		foreach ($this->_cap_contexts_to_cap_action_map as $cap_context => $action) {
121
+			$this->_cap_restrictions[$cap_context][EE_Restriction_Generator_Base::get_default_restrictions_cap()]
122
+				= new EE_Return_None_Where_Conditions();
123
+		}
124
+		parent::__construct($timezone);
125
+	}
126 126
 
127
-    /**
128
-     * @param string        $log_type !see the acceptable values of LOG_type in EEM__Change_Log::__construct
129
-     * @param mixed         $message  array|string of the message you want to record
130
-     * @param EE_Base_Class $related_model_obj
131
-     * @return EE_Change_Log
132
-     * @throws EE_Error
133
-     */
134
-    public function log($log_type, $message, $related_model_obj)
135
-    {
136
-        if ($related_model_obj instanceof EE_Base_Class) {
137
-            $obj_id   = $related_model_obj->ID();
138
-            $obj_type = $related_model_obj->get_model()->get_this_model_name();
139
-        } else {
140
-            $obj_id   = null;
141
-            $obj_type = null;
142
-        }
143
-        /** @var EE_Change_Log $log */
144
-        $log = EE_Change_Log::new_instance(array(
145
-            'LOG_type'    => $log_type,
146
-            'LOG_message' => $message,
147
-            'OBJ_ID'      => $obj_id,
148
-            'OBJ_type'    => $obj_type,
149
-        ));
150
-        $log->save();
151
-        return $log;
152
-    }
127
+	/**
128
+	 * @param string        $log_type !see the acceptable values of LOG_type in EEM__Change_Log::__construct
129
+	 * @param mixed         $message  array|string of the message you want to record
130
+	 * @param EE_Base_Class $related_model_obj
131
+	 * @return EE_Change_Log
132
+	 * @throws EE_Error
133
+	 */
134
+	public function log($log_type, $message, $related_model_obj)
135
+	{
136
+		if ($related_model_obj instanceof EE_Base_Class) {
137
+			$obj_id   = $related_model_obj->ID();
138
+			$obj_type = $related_model_obj->get_model()->get_this_model_name();
139
+		} else {
140
+			$obj_id   = null;
141
+			$obj_type = null;
142
+		}
143
+		/** @var EE_Change_Log $log */
144
+		$log = EE_Change_Log::new_instance(array(
145
+			'LOG_type'    => $log_type,
146
+			'LOG_message' => $message,
147
+			'OBJ_ID'      => $obj_id,
148
+			'OBJ_type'    => $obj_type,
149
+		));
150
+		$log->save();
151
+		return $log;
152
+	}
153 153
 
154 154
 
155
-    /**
156
-     * Adds a gateway log for the specified object, given its ID and type
157
-     *
158
-     * @param string $message
159
-     * @param mixed  $related_obj_id
160
-     * @param string $related_obj_type
161
-     * @throws EE_Error
162
-     * @return EE_Change_Log
163
-     */
164
-    public function gateway_log($message, $related_obj_id, $related_obj_type)
165
-    {
166
-        if (! EE_Registry::instance()->is_model_name($related_obj_type)) {
167
-            throw new EE_Error(
168
-                sprintf(
169
-                    esc_html__(
170
-                        "'%s' is not a model name. A model name must be provided when making a gateway log. Eg, 'Payment', 'Payment_Method', etc",
171
-                        "event_espresso"
172
-                    ),
173
-                    $related_obj_type
174
-                )
175
-            );
176
-        }
177
-        /** @var EE_Change_Log $log */
178
-        $log = EE_Change_Log::new_instance(array(
179
-            'LOG_type'    => EEM_Change_Log::type_gateway,
180
-            'LOG_message' => $message,
181
-            'OBJ_ID'      => $related_obj_id,
182
-            'OBJ_type'    => $related_obj_type,
183
-        ));
184
-        $log->save();
185
-        return $log;
186
-    }
155
+	/**
156
+	 * Adds a gateway log for the specified object, given its ID and type
157
+	 *
158
+	 * @param string $message
159
+	 * @param mixed  $related_obj_id
160
+	 * @param string $related_obj_type
161
+	 * @throws EE_Error
162
+	 * @return EE_Change_Log
163
+	 */
164
+	public function gateway_log($message, $related_obj_id, $related_obj_type)
165
+	{
166
+		if (! EE_Registry::instance()->is_model_name($related_obj_type)) {
167
+			throw new EE_Error(
168
+				sprintf(
169
+					esc_html__(
170
+						"'%s' is not a model name. A model name must be provided when making a gateway log. Eg, 'Payment', 'Payment_Method', etc",
171
+						"event_espresso"
172
+					),
173
+					$related_obj_type
174
+				)
175
+			);
176
+		}
177
+		/** @var EE_Change_Log $log */
178
+		$log = EE_Change_Log::new_instance(array(
179
+			'LOG_type'    => EEM_Change_Log::type_gateway,
180
+			'LOG_message' => $message,
181
+			'OBJ_ID'      => $related_obj_id,
182
+			'OBJ_type'    => $related_obj_type,
183
+		));
184
+		$log->save();
185
+		return $log;
186
+	}
187 187
 
188 188
 
189
-    /**
190
-     * Just gets the bare-bones wpdb results as an array in cases where efficiency is essential
191
-     *
192
-     * @param array $query_params @see EEM_Base::get_all
193
-     * @return array of arrays
194
-     * @throws EE_Error
195
-     */
196
-    public function get_all_efficiently($query_params)
197
-    {
198
-        return $this->_get_all_wpdb_results($query_params);
199
-    }
189
+	/**
190
+	 * Just gets the bare-bones wpdb results as an array in cases where efficiency is essential
191
+	 *
192
+	 * @param array $query_params @see EEM_Base::get_all
193
+	 * @return array of arrays
194
+	 * @throws EE_Error
195
+	 */
196
+	public function get_all_efficiently($query_params)
197
+	{
198
+		return $this->_get_all_wpdb_results($query_params);
199
+	}
200 200
 
201 201
 
202
-    /**
203
-     * Executes a database query to delete gateway logs. Does not affect model objects, so if you attempt to use
204
-     * models after this, they may be out-of-sync with the database
205
-     *
206
-     * @param DateTime $datetime
207
-     * @return false|int
208
-     * @throws EE_Error
209
-     */
210
-    public function delete_gateway_logs_older_than(DateTime $datetime)
211
-    {
212
-        global $wpdb;
213
-        return $wpdb->query(
214
-            $wpdb->prepare(
215
-                'DELETE FROM ' . $this->table() . ' WHERE LOG_type = %s AND LOG_time < %s',
216
-                EEM_Change_Log::type_gateway,
217
-                $datetime->format(EE_Datetime_Field::mysql_timestamp_format)
218
-            )
219
-        );
220
-    }
202
+	/**
203
+	 * Executes a database query to delete gateway logs. Does not affect model objects, so if you attempt to use
204
+	 * models after this, they may be out-of-sync with the database
205
+	 *
206
+	 * @param DateTime $datetime
207
+	 * @return false|int
208
+	 * @throws EE_Error
209
+	 */
210
+	public function delete_gateway_logs_older_than(DateTime $datetime)
211
+	{
212
+		global $wpdb;
213
+		return $wpdb->query(
214
+			$wpdb->prepare(
215
+				'DELETE FROM ' . $this->table() . ' WHERE LOG_type = %s AND LOG_time < %s',
216
+				EEM_Change_Log::type_gateway,
217
+				$datetime->format(EE_Datetime_Field::mysql_timestamp_format)
218
+			)
219
+		);
220
+	}
221 221
 
222 222
 
223
-    /**
224
-     * Returns the map of type to pretty label for identifiers used for `LOG_type`.  Client code can register their own
225
-     * map vai the given filter.
226
-     *
227
-     * @return array
228
-     */
229
-    public static function get_pretty_label_map_for_registered_types()
230
-    {
231
-        return apply_filters(
232
-            'FHEE__EEM_Change_Log__get_pretty_label_map_for_registered_types',
233
-            array(
234
-                self::type_create=>  esc_html__("Create", "event_espresso"),
235
-                self::type_update=>  esc_html__("Update", "event_espresso"),
236
-                self::type_delete => esc_html__("Delete", "event_espresso"),
237
-                self::type_debug=>  esc_html__("Debug", "event_espresso"),
238
-                self::type_error=>  esc_html__("Error", "event_espresso"),
239
-                self::type_gateway=> esc_html__("Gateway Interaction (IPN or Direct Payment)", 'event_espresso')
240
-            )
241
-        );
242
-    }
223
+	/**
224
+	 * Returns the map of type to pretty label for identifiers used for `LOG_type`.  Client code can register their own
225
+	 * map vai the given filter.
226
+	 *
227
+	 * @return array
228
+	 */
229
+	public static function get_pretty_label_map_for_registered_types()
230
+	{
231
+		return apply_filters(
232
+			'FHEE__EEM_Change_Log__get_pretty_label_map_for_registered_types',
233
+			array(
234
+				self::type_create=>  esc_html__("Create", "event_espresso"),
235
+				self::type_update=>  esc_html__("Update", "event_espresso"),
236
+				self::type_delete => esc_html__("Delete", "event_espresso"),
237
+				self::type_debug=>  esc_html__("Debug", "event_espresso"),
238
+				self::type_error=>  esc_html__("Error", "event_espresso"),
239
+				self::type_gateway=> esc_html__("Gateway Interaction (IPN or Direct Payment)", 'event_espresso')
240
+			)
241
+		);
242
+	}
243 243
 
244 244
 
245
-    /**
246
-     * Return the pretty (localized) label for the given log type identifier.
247
-     * @param string $type_identifier
248
-     * @return string
249
-     */
250
-    public static function get_pretty_label_for_type($type_identifier)
251
-    {
252
-        $type_identifier_map = self::get_pretty_label_map_for_registered_types();
253
-        //we fallback to the incoming type identifier if there is no localized label for it.
254
-        return isset($type_identifier_map[$type_identifier])
255
-            ? $type_identifier_map[$type_identifier]
256
-            : $type_identifier;
257
-    }
245
+	/**
246
+	 * Return the pretty (localized) label for the given log type identifier.
247
+	 * @param string $type_identifier
248
+	 * @return string
249
+	 */
250
+	public static function get_pretty_label_for_type($type_identifier)
251
+	{
252
+		$type_identifier_map = self::get_pretty_label_map_for_registered_types();
253
+		//we fallback to the incoming type identifier if there is no localized label for it.
254
+		return isset($type_identifier_map[$type_identifier])
255
+			? $type_identifier_map[$type_identifier]
256
+			: $type_identifier;
257
+	}
258 258
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Change_Log.class.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -193,7 +193,7 @@
 block discarded – undo
193 193
     {
194 194
         $model_name_of_related_obj = $this->OBJ_type();
195 195
         $is_model_name             = EE_Registry::instance()->is_model_name($model_name_of_related_obj);
196
-        if (! $is_model_name) {
196
+        if ( ! $is_model_name) {
197 197
             return null;
198 198
         } else {
199 199
             return $this->get_first_related($model_name_of_related_obj);
Please login to merge, or discard this patch.
Indentation   +185 added lines, -185 removed lines patch added patch discarded remove patch
@@ -15,189 +15,189 @@
 block discarded – undo
15 15
 
16 16
 
17 17
 
18
-    /**
19
-     * Gets message
20
-     *
21
-     * @return mixed
22
-     * @throws EE_Error
23
-     */
24
-    public function message()
25
-    {
26
-        return $this->get('LOG_message');
27
-    }
28
-
29
-    /**
30
-     * Sets message
31
-     *
32
-     * @param mixed $message
33
-     * @throws EE_Error
34
-     */
35
-    public function set_message($message)
36
-    {
37
-        $this->set('LOG_message', $message);
38
-    }
39
-
40
-    /**
41
-     * Gets time
42
-     *
43
-     * @return string
44
-     * @throws EE_Error
45
-     */
46
-    public function time()
47
-    {
48
-        return $this->get('LOG_time');
49
-    }
50
-
51
-    /**
52
-     * Sets time
53
-     *
54
-     * @param string $time
55
-     * @throws EE_Error
56
-     */
57
-    public function set_time($time)
58
-    {
59
-        $this->set('LOG_time', $time);
60
-    }
61
-
62
-    /**
63
-     * Gets log_type
64
-     *
65
-     * @return string
66
-     * @throws EE_Error
67
-     */
68
-    public function log_type()
69
-    {
70
-        return $this->get('LOG_type');
71
-    }
72
-
73
-
74
-    /**
75
-     * Return the localized log type label.
76
-     * @return string
77
-     * @throws EE_Error
78
-     */
79
-    public function log_type_label()
80
-    {
81
-        return EEM_Change_Log::get_pretty_label_for_type($this->log_type());
82
-    }
83
-
84
-    /**
85
-     * Sets log_type
86
-     *
87
-     * @param string $log_type
88
-     * @throws EE_Error
89
-     */
90
-    public function set_log_type($log_type)
91
-    {
92
-        $this->set('LOG_type', $log_type);
93
-    }
94
-
95
-    /**
96
-     * Gets type of the model object related to this log
97
-     *
98
-     * @return string
99
-     * @throws EE_Error
100
-     */
101
-    public function OBJ_type()
102
-    {
103
-        return $this->get('OBJ_type');
104
-    }
105
-
106
-    /**
107
-     * Sets type
108
-     *
109
-     * @param string $type
110
-     * @throws EE_Error
111
-     */
112
-    public function set_OBJ_type($type)
113
-    {
114
-        $this->set('OBJ_type', $type);
115
-    }
116
-
117
-    /**
118
-     * Gets OBJ_ID (the ID of the item related to this log)
119
-     *
120
-     * @return mixed
121
-     * @throws EE_Error
122
-     */
123
-    public function OBJ_ID()
124
-    {
125
-        return $this->get('OBJ_ID');
126
-    }
127
-
128
-    /**
129
-     * Sets OBJ_ID
130
-     *
131
-     * @param mixed $OBJ_ID
132
-     * @throws EE_Error
133
-     */
134
-    public function set_OBJ_ID($OBJ_ID)
135
-    {
136
-        $this->set('OBJ_ID', $OBJ_ID);
137
-    }
138
-
139
-    /**
140
-     * Gets wp_user
141
-     *
142
-     * @return int
143
-     * @throws EE_Error
144
-     */
145
-    public function wp_user()
146
-    {
147
-        return $this->get('LOG_wp_user');
148
-    }
149
-
150
-    /**
151
-     * Sets wp_user
152
-     *
153
-     * @param int $wp_user_id
154
-     * @throws EE_Error
155
-     */
156
-    public function set_wp_user($wp_user_id)
157
-    {
158
-        $this->set('LOG_wp_user', $wp_user_id);
159
-    }
160
-
161
-    /**
162
-     * Gets the model object attached to this log
163
-     *
164
-     * @return EE_Base_Class
165
-     * @throws EE_Error
166
-     */
167
-    public function object()
168
-    {
169
-        $model_name_of_related_obj = $this->OBJ_type();
170
-        $is_model_name             = EE_Registry::instance()->is_model_name($model_name_of_related_obj);
171
-        if (! $is_model_name) {
172
-            return null;
173
-        } else {
174
-            return $this->get_first_related($model_name_of_related_obj);
175
-        }
176
-    }
177
-
178
-    /**
179
-     * Shorthand for setting the OBJ_ID and OBJ_type. Slightly handier than using
180
-     * _add_relation_to because you don't have to specify what type of model you're
181
-     * associating it with
182
-     *
183
-     * @param EE_Base_Class $object
184
-     * @param boolean       $save
185
-     * @return bool if $save=true, NULL is $save=false
186
-     * @throws EE_Error
187
-     */
188
-    public function set_object($object, $save = true)
189
-    {
190
-        if ($object instanceof EE_Base_Class) {
191
-            $this->set_OBJ_type($object->get_model()->get_this_model_name());
192
-            $this->set_OBJ_ID($object->ID());
193
-        } else {
194
-            $this->set_OBJ_type(null);
195
-            $this->set_OBJ_ID(null);
196
-        }
197
-        if ($save) {
198
-            return $this->save();
199
-        } else {
200
-            return null;
201
-        }
202
-    }
18
+	/**
19
+	 * Gets message
20
+	 *
21
+	 * @return mixed
22
+	 * @throws EE_Error
23
+	 */
24
+	public function message()
25
+	{
26
+		return $this->get('LOG_message');
27
+	}
28
+
29
+	/**
30
+	 * Sets message
31
+	 *
32
+	 * @param mixed $message
33
+	 * @throws EE_Error
34
+	 */
35
+	public function set_message($message)
36
+	{
37
+		$this->set('LOG_message', $message);
38
+	}
39
+
40
+	/**
41
+	 * Gets time
42
+	 *
43
+	 * @return string
44
+	 * @throws EE_Error
45
+	 */
46
+	public function time()
47
+	{
48
+		return $this->get('LOG_time');
49
+	}
50
+
51
+	/**
52
+	 * Sets time
53
+	 *
54
+	 * @param string $time
55
+	 * @throws EE_Error
56
+	 */
57
+	public function set_time($time)
58
+	{
59
+		$this->set('LOG_time', $time);
60
+	}
61
+
62
+	/**
63
+	 * Gets log_type
64
+	 *
65
+	 * @return string
66
+	 * @throws EE_Error
67
+	 */
68
+	public function log_type()
69
+	{
70
+		return $this->get('LOG_type');
71
+	}
72
+
73
+
74
+	/**
75
+	 * Return the localized log type label.
76
+	 * @return string
77
+	 * @throws EE_Error
78
+	 */
79
+	public function log_type_label()
80
+	{
81
+		return EEM_Change_Log::get_pretty_label_for_type($this->log_type());
82
+	}
83
+
84
+	/**
85
+	 * Sets log_type
86
+	 *
87
+	 * @param string $log_type
88
+	 * @throws EE_Error
89
+	 */
90
+	public function set_log_type($log_type)
91
+	{
92
+		$this->set('LOG_type', $log_type);
93
+	}
94
+
95
+	/**
96
+	 * Gets type of the model object related to this log
97
+	 *
98
+	 * @return string
99
+	 * @throws EE_Error
100
+	 */
101
+	public function OBJ_type()
102
+	{
103
+		return $this->get('OBJ_type');
104
+	}
105
+
106
+	/**
107
+	 * Sets type
108
+	 *
109
+	 * @param string $type
110
+	 * @throws EE_Error
111
+	 */
112
+	public function set_OBJ_type($type)
113
+	{
114
+		$this->set('OBJ_type', $type);
115
+	}
116
+
117
+	/**
118
+	 * Gets OBJ_ID (the ID of the item related to this log)
119
+	 *
120
+	 * @return mixed
121
+	 * @throws EE_Error
122
+	 */
123
+	public function OBJ_ID()
124
+	{
125
+		return $this->get('OBJ_ID');
126
+	}
127
+
128
+	/**
129
+	 * Sets OBJ_ID
130
+	 *
131
+	 * @param mixed $OBJ_ID
132
+	 * @throws EE_Error
133
+	 */
134
+	public function set_OBJ_ID($OBJ_ID)
135
+	{
136
+		$this->set('OBJ_ID', $OBJ_ID);
137
+	}
138
+
139
+	/**
140
+	 * Gets wp_user
141
+	 *
142
+	 * @return int
143
+	 * @throws EE_Error
144
+	 */
145
+	public function wp_user()
146
+	{
147
+		return $this->get('LOG_wp_user');
148
+	}
149
+
150
+	/**
151
+	 * Sets wp_user
152
+	 *
153
+	 * @param int $wp_user_id
154
+	 * @throws EE_Error
155
+	 */
156
+	public function set_wp_user($wp_user_id)
157
+	{
158
+		$this->set('LOG_wp_user', $wp_user_id);
159
+	}
160
+
161
+	/**
162
+	 * Gets the model object attached to this log
163
+	 *
164
+	 * @return EE_Base_Class
165
+	 * @throws EE_Error
166
+	 */
167
+	public function object()
168
+	{
169
+		$model_name_of_related_obj = $this->OBJ_type();
170
+		$is_model_name             = EE_Registry::instance()->is_model_name($model_name_of_related_obj);
171
+		if (! $is_model_name) {
172
+			return null;
173
+		} else {
174
+			return $this->get_first_related($model_name_of_related_obj);
175
+		}
176
+	}
177
+
178
+	/**
179
+	 * Shorthand for setting the OBJ_ID and OBJ_type. Slightly handier than using
180
+	 * _add_relation_to because you don't have to specify what type of model you're
181
+	 * associating it with
182
+	 *
183
+	 * @param EE_Base_Class $object
184
+	 * @param boolean       $save
185
+	 * @return bool if $save=true, NULL is $save=false
186
+	 * @throws EE_Error
187
+	 */
188
+	public function set_object($object, $save = true)
189
+	{
190
+		if ($object instanceof EE_Base_Class) {
191
+			$this->set_OBJ_type($object->get_model()->get_this_model_name());
192
+			$this->set_OBJ_ID($object->ID());
193
+		} else {
194
+			$this->set_OBJ_type(null);
195
+			$this->set_OBJ_ID(null);
196
+		}
197
+		if ($save) {
198
+			return $this->save();
199
+		} else {
200
+			return null;
201
+		}
202
+	}
203 203
 }
Please login to merge, or discard this patch.