@@ -21,79 +21,79 @@ |
||
| 21 | 21 | */ |
| 22 | 22 | class ConfirmEventDeletionForm extends \EE_Form_Section_Proper |
| 23 | 23 | { |
| 24 | - /** |
|
| 25 | - * @var EE_Event[] |
|
| 26 | - */ |
|
| 27 | - protected $events; |
|
| 28 | - public function __construct($event_ids, $options_array = array()) |
|
| 29 | - { |
|
| 30 | - if (! isset($options_array['subsections'])) { |
|
| 31 | - $options_array['subsections'] = []; |
|
| 32 | - } |
|
| 33 | - if (! isset($options_array['subsections']['events'])) { |
|
| 34 | - $events_subsection = new \EE_Form_Section_Proper(); |
|
| 35 | - $options_array['subsections']['events'] = $events_subsection; |
|
| 36 | - } |
|
| 37 | - $events = EEM_Event::instance()->get_all_deleted_and_undeleted( |
|
| 38 | - [ |
|
| 39 | - [ |
|
| 40 | - 'EVT_ID' => ['IN',$event_ids] |
|
| 41 | - ] |
|
| 42 | - ] |
|
| 43 | - ); |
|
| 44 | - if (! is_array($events)) { |
|
| 45 | - throw new UnexpectedEntityException($event_ids, 'array'); |
|
| 46 | - } |
|
| 47 | - $this->events = $events; |
|
| 48 | - $events_inputs = [ |
|
| 49 | - 'intro' => new EE_Form_Section_HTML( |
|
| 50 | - EEH_HTML::h2(esc_html__('In order to prevent accidentally deleting the wrong events, please enter the unique URL slug of each event.', 'event_espresso')) |
|
| 51 | - ) |
|
| 52 | - ]; |
|
| 53 | - foreach ($events as $event) { |
|
| 54 | - $events_inputs[ $event->ID() ] = new \EE_Text_Input( |
|
| 55 | - [ |
|
| 56 | - 'html_label_text' => esc_html( |
|
| 57 | - sprintf( |
|
| 58 | - __('Please enter the URL slug of "%1$s" (hint: it’s "%2$s")', 'event_espresso'), |
|
| 59 | - $event->name(), |
|
| 60 | - $event->slug() |
|
| 61 | - ) |
|
| 62 | - ), |
|
| 63 | - 'required' => false |
|
| 64 | - ] |
|
| 65 | - ); |
|
| 66 | - } |
|
| 67 | - $events_subsection->add_subsections($events_inputs); |
|
| 68 | - $options_array['subsections']['backup'] = new EE_Checkbox_Multi_Input( |
|
| 69 | - [ |
|
| 70 | - 'yes' => esc_html__('I have backed up my database.', 'event_espresso') |
|
| 71 | - ], |
|
| 72 | - [ |
|
| 73 | - 'html_label_text' => esc_html__('Deleting this data cannot be undone. Please confirm you have a usable database backup.', 'event_espresso'), |
|
| 74 | - 'required' => true |
|
| 75 | - ] |
|
| 76 | - ); |
|
| 77 | - parent::__construct($options_array); |
|
| 78 | - } |
|
| 24 | + /** |
|
| 25 | + * @var EE_Event[] |
|
| 26 | + */ |
|
| 27 | + protected $events; |
|
| 28 | + public function __construct($event_ids, $options_array = array()) |
|
| 29 | + { |
|
| 30 | + if (! isset($options_array['subsections'])) { |
|
| 31 | + $options_array['subsections'] = []; |
|
| 32 | + } |
|
| 33 | + if (! isset($options_array['subsections']['events'])) { |
|
| 34 | + $events_subsection = new \EE_Form_Section_Proper(); |
|
| 35 | + $options_array['subsections']['events'] = $events_subsection; |
|
| 36 | + } |
|
| 37 | + $events = EEM_Event::instance()->get_all_deleted_and_undeleted( |
|
| 38 | + [ |
|
| 39 | + [ |
|
| 40 | + 'EVT_ID' => ['IN',$event_ids] |
|
| 41 | + ] |
|
| 42 | + ] |
|
| 43 | + ); |
|
| 44 | + if (! is_array($events)) { |
|
| 45 | + throw new UnexpectedEntityException($event_ids, 'array'); |
|
| 46 | + } |
|
| 47 | + $this->events = $events; |
|
| 48 | + $events_inputs = [ |
|
| 49 | + 'intro' => new EE_Form_Section_HTML( |
|
| 50 | + EEH_HTML::h2(esc_html__('In order to prevent accidentally deleting the wrong events, please enter the unique URL slug of each event.', 'event_espresso')) |
|
| 51 | + ) |
|
| 52 | + ]; |
|
| 53 | + foreach ($events as $event) { |
|
| 54 | + $events_inputs[ $event->ID() ] = new \EE_Text_Input( |
|
| 55 | + [ |
|
| 56 | + 'html_label_text' => esc_html( |
|
| 57 | + sprintf( |
|
| 58 | + __('Please enter the URL slug of "%1$s" (hint: it’s "%2$s")', 'event_espresso'), |
|
| 59 | + $event->name(), |
|
| 60 | + $event->slug() |
|
| 61 | + ) |
|
| 62 | + ), |
|
| 63 | + 'required' => false |
|
| 64 | + ] |
|
| 65 | + ); |
|
| 66 | + } |
|
| 67 | + $events_subsection->add_subsections($events_inputs); |
|
| 68 | + $options_array['subsections']['backup'] = new EE_Checkbox_Multi_Input( |
|
| 69 | + [ |
|
| 70 | + 'yes' => esc_html__('I have backed up my database.', 'event_espresso') |
|
| 71 | + ], |
|
| 72 | + [ |
|
| 73 | + 'html_label_text' => esc_html__('Deleting this data cannot be undone. Please confirm you have a usable database backup.', 'event_espresso'), |
|
| 74 | + 'required' => true |
|
| 75 | + ] |
|
| 76 | + ); |
|
| 77 | + parent::__construct($options_array); |
|
| 78 | + } |
|
| 79 | 79 | |
| 80 | - public function _validate() |
|
| 81 | - { |
|
| 82 | - parent::_validate(); |
|
| 83 | - $events_subsection = $this->get_proper_subsection('events'); |
|
| 84 | - foreach ($this->events as $event) { |
|
| 85 | - $event_input = $events_subsection->get_input($event->ID()); |
|
| 86 | - if ((string) $event_input->normalized_value() !== $event->slug()) { |
|
| 87 | - $event_input->add_validation_error( |
|
| 88 | - sprintf( |
|
| 89 | - esc_html__('You entered the incorrect URL slug for the event "%1$s". Please enter it again (use "%2$s") to confirm you are deleting the correct event.', 'event_espresso'), |
|
| 90 | - $event->name(), |
|
| 91 | - $event->slug() |
|
| 92 | - ) |
|
| 93 | - ); |
|
| 94 | - } |
|
| 95 | - } |
|
| 96 | - } |
|
| 80 | + public function _validate() |
|
| 81 | + { |
|
| 82 | + parent::_validate(); |
|
| 83 | + $events_subsection = $this->get_proper_subsection('events'); |
|
| 84 | + foreach ($this->events as $event) { |
|
| 85 | + $event_input = $events_subsection->get_input($event->ID()); |
|
| 86 | + if ((string) $event_input->normalized_value() !== $event->slug()) { |
|
| 87 | + $event_input->add_validation_error( |
|
| 88 | + sprintf( |
|
| 89 | + esc_html__('You entered the incorrect URL slug for the event "%1$s". Please enter it again (use "%2$s") to confirm you are deleting the correct event.', 'event_espresso'), |
|
| 90 | + $event->name(), |
|
| 91 | + $event->slug() |
|
| 92 | + ) |
|
| 93 | + ); |
|
| 94 | + } |
|
| 95 | + } |
|
| 96 | + } |
|
| 97 | 97 | } |
| 98 | 98 | // End of file ConfirmEventDeletionForm.php |
| 99 | 99 | // Location: EventEspresso\admin_pages\events\form_sections/ConfirmEventDeletionForm.php |
@@ -27,21 +27,21 @@ discard block |
||
| 27 | 27 | protected $events; |
| 28 | 28 | public function __construct($event_ids, $options_array = array()) |
| 29 | 29 | { |
| 30 | - if (! isset($options_array['subsections'])) { |
|
| 30 | + if ( ! isset($options_array['subsections'])) { |
|
| 31 | 31 | $options_array['subsections'] = []; |
| 32 | 32 | } |
| 33 | - if (! isset($options_array['subsections']['events'])) { |
|
| 33 | + if ( ! isset($options_array['subsections']['events'])) { |
|
| 34 | 34 | $events_subsection = new \EE_Form_Section_Proper(); |
| 35 | 35 | $options_array['subsections']['events'] = $events_subsection; |
| 36 | 36 | } |
| 37 | 37 | $events = EEM_Event::instance()->get_all_deleted_and_undeleted( |
| 38 | 38 | [ |
| 39 | 39 | [ |
| 40 | - 'EVT_ID' => ['IN',$event_ids] |
|
| 40 | + 'EVT_ID' => ['IN', $event_ids] |
|
| 41 | 41 | ] |
| 42 | 42 | ] |
| 43 | 43 | ); |
| 44 | - if (! is_array($events)) { |
|
| 44 | + if ( ! is_array($events)) { |
|
| 45 | 45 | throw new UnexpectedEntityException($event_ids, 'array'); |
| 46 | 46 | } |
| 47 | 47 | $this->events = $events; |
@@ -51,7 +51,7 @@ discard block |
||
| 51 | 51 | ) |
| 52 | 52 | ]; |
| 53 | 53 | foreach ($events as $event) { |
| 54 | - $events_inputs[ $event->ID() ] = new \EE_Text_Input( |
|
| 54 | + $events_inputs[$event->ID()] = new \EE_Text_Input( |
|
| 55 | 55 | [ |
| 56 | 56 | 'html_label_text' => esc_html( |
| 57 | 57 | sprintf( |
@@ -14,1528 +14,1528 @@ |
||
| 14 | 14 | class EE_Form_Section_Proper extends EE_Form_Section_Validatable |
| 15 | 15 | { |
| 16 | 16 | |
| 17 | - const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data'; |
|
| 18 | - |
|
| 19 | - /** |
|
| 20 | - * Subsections |
|
| 21 | - * |
|
| 22 | - * @var EE_Form_Section_Validatable[] |
|
| 23 | - */ |
|
| 24 | - protected $_subsections = array(); |
|
| 25 | - |
|
| 26 | - /** |
|
| 27 | - * Strategy for laying out the form |
|
| 28 | - * |
|
| 29 | - * @var EE_Form_Section_Layout_Base |
|
| 30 | - */ |
|
| 31 | - protected $_layout_strategy; |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * Whether or not this form has received and validated a form submission yet |
|
| 35 | - * |
|
| 36 | - * @var boolean |
|
| 37 | - */ |
|
| 38 | - protected $_received_submission = false; |
|
| 39 | - |
|
| 40 | - /** |
|
| 41 | - * message displayed to users upon successful form submission |
|
| 42 | - * |
|
| 43 | - * @var string |
|
| 44 | - */ |
|
| 45 | - protected $_form_submission_success_message = ''; |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * message displayed to users upon unsuccessful form submission |
|
| 49 | - * |
|
| 50 | - * @var string |
|
| 51 | - */ |
|
| 52 | - protected $_form_submission_error_message = ''; |
|
| 53 | - |
|
| 54 | - /** |
|
| 55 | - * @var array like $_REQUEST |
|
| 56 | - */ |
|
| 57 | - protected $cached_request_data; |
|
| 58 | - |
|
| 59 | - /** |
|
| 60 | - * Stores whether this form (and its sub-sections) were found to be valid or not. |
|
| 61 | - * Starts off as null, but once the form is validated, it set to either true or false |
|
| 62 | - * @var boolean|null |
|
| 63 | - */ |
|
| 64 | - protected $is_valid; |
|
| 65 | - |
|
| 66 | - /** |
|
| 67 | - * Stores all the data that will localized for form validation |
|
| 68 | - * |
|
| 69 | - * @var array |
|
| 70 | - */ |
|
| 71 | - static protected $_js_localization = array(); |
|
| 72 | - |
|
| 73 | - /** |
|
| 74 | - * whether or not the form's localized validation JS vars have been set |
|
| 75 | - * |
|
| 76 | - * @type boolean |
|
| 77 | - */ |
|
| 78 | - static protected $_scripts_localized = false; |
|
| 79 | - |
|
| 80 | - |
|
| 81 | - /** |
|
| 82 | - * when constructing a proper form section, calls _construct_finalize on children |
|
| 83 | - * so that they know who their parent is, and what name they've been given. |
|
| 84 | - * |
|
| 85 | - * @param array[] $options_array { |
|
| 86 | - * @type $subsections EE_Form_Section_Validatable[] where keys are the section's name |
|
| 87 | - * @type $include string[] numerically-indexed where values are section names to be included, |
|
| 88 | - * and in that order. This is handy if you want |
|
| 89 | - * the subsections to be ordered differently than the default, and if you override |
|
| 90 | - * which fields are shown |
|
| 91 | - * @type $exclude string[] values are subsections to be excluded. This is handy if you want |
|
| 92 | - * to remove certain default subsections (note: if you specify BOTH 'include' AND |
|
| 93 | - * 'exclude', the inclusions will be applied first, and the exclusions will exclude |
|
| 94 | - * items from that list of inclusions) |
|
| 95 | - * @type $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form |
|
| 96 | - * } @see EE_Form_Section_Validatable::__construct() |
|
| 97 | - * @throws EE_Error |
|
| 98 | - */ |
|
| 99 | - public function __construct($options_array = array()) |
|
| 100 | - { |
|
| 101 | - $options_array = (array) apply_filters( |
|
| 102 | - 'FHEE__EE_Form_Section_Proper___construct__options_array', |
|
| 103 | - $options_array, |
|
| 104 | - $this |
|
| 105 | - ); |
|
| 106 | - // call parent first, as it may be setting the name |
|
| 107 | - parent::__construct($options_array); |
|
| 108 | - // if they've included subsections in the constructor, add them now |
|
| 109 | - if (isset($options_array['include'])) { |
|
| 110 | - // we are going to make sure we ONLY have those subsections to include |
|
| 111 | - // AND we are going to make sure they're in that specified order |
|
| 112 | - $reordered_subsections = array(); |
|
| 113 | - foreach ($options_array['include'] as $input_name) { |
|
| 114 | - if (isset($this->_subsections[ $input_name ])) { |
|
| 115 | - $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ]; |
|
| 116 | - } |
|
| 117 | - } |
|
| 118 | - $this->_subsections = $reordered_subsections; |
|
| 119 | - } |
|
| 120 | - if (isset($options_array['exclude'])) { |
|
| 121 | - $exclude = $options_array['exclude']; |
|
| 122 | - $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude)); |
|
| 123 | - } |
|
| 124 | - if (isset($options_array['layout_strategy'])) { |
|
| 125 | - $this->_layout_strategy = $options_array['layout_strategy']; |
|
| 126 | - } |
|
| 127 | - if (! $this->_layout_strategy) { |
|
| 128 | - $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout(); |
|
| 129 | - } |
|
| 130 | - $this->_layout_strategy->_construct_finalize($this); |
|
| 131 | - // ok so we are definitely going to want the forms JS, |
|
| 132 | - // so enqueue it or remember to enqueue it during wp_enqueue_scripts |
|
| 133 | - if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) { |
|
| 134 | - // ok so they've constructed this object after when they should have. |
|
| 135 | - // just enqueue the generic form scripts and initialize the form immediately in the JS |
|
| 136 | - EE_Form_Section_Proper::wp_enqueue_scripts(true); |
|
| 137 | - } else { |
|
| 138 | - add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 139 | - add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 140 | - } |
|
| 141 | - add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1); |
|
| 142 | - /** |
|
| 143 | - * Gives other plugins a chance to hook in before construct finalize is called. |
|
| 144 | - * The form probably doesn't yet have a parent form section. |
|
| 145 | - * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form, |
|
| 146 | - * assuming you don't care what the form section's name, HTML ID, or HTML name etc are. |
|
| 147 | - * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end |
|
| 148 | - * |
|
| 149 | - * @since 4.9.32 |
|
| 150 | - * @param EE_Form_Section_Proper $this before __construct is done, but all of its logic, |
|
| 151 | - * except maybe calling _construct_finalize has been done |
|
| 152 | - * @param array $options_array options passed into the constructor |
|
| 153 | - */ |
|
| 154 | - do_action( |
|
| 155 | - 'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called', |
|
| 156 | - $this, |
|
| 157 | - $options_array |
|
| 158 | - ); |
|
| 159 | - if (isset($options_array['name'])) { |
|
| 160 | - $this->_construct_finalize(null, $options_array['name']); |
|
| 161 | - } |
|
| 162 | - } |
|
| 163 | - |
|
| 164 | - |
|
| 165 | - /** |
|
| 166 | - * Finishes construction given the parent form section and this form section's name |
|
| 167 | - * |
|
| 168 | - * @param EE_Form_Section_Proper $parent_form_section |
|
| 169 | - * @param string $name |
|
| 170 | - * @throws EE_Error |
|
| 171 | - */ |
|
| 172 | - public function _construct_finalize($parent_form_section, $name) |
|
| 173 | - { |
|
| 174 | - parent::_construct_finalize($parent_form_section, $name); |
|
| 175 | - $this->_set_default_name_if_empty(); |
|
| 176 | - $this->_set_default_html_id_if_empty(); |
|
| 177 | - foreach ($this->_subsections as $subsection_name => $subsection) { |
|
| 178 | - if ($subsection instanceof EE_Form_Section_Base) { |
|
| 179 | - $subsection->_construct_finalize($this, $subsection_name); |
|
| 180 | - } else { |
|
| 181 | - throw new EE_Error( |
|
| 182 | - sprintf( |
|
| 183 | - esc_html__( |
|
| 184 | - 'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"', |
|
| 185 | - 'event_espresso' |
|
| 186 | - ), |
|
| 187 | - $subsection_name, |
|
| 188 | - get_class($this), |
|
| 189 | - $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 190 | - ) |
|
| 191 | - ); |
|
| 192 | - } |
|
| 193 | - } |
|
| 194 | - /** |
|
| 195 | - * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed. |
|
| 196 | - * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID |
|
| 197 | - * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done. |
|
| 198 | - * This might only happen just before displaying the form, or just before it receives form submission data. |
|
| 199 | - * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've |
|
| 200 | - * ensured it has a name, HTML IDs, etc |
|
| 201 | - * |
|
| 202 | - * @param EE_Form_Section_Proper $this |
|
| 203 | - * @param EE_Form_Section_Proper|null $parent_form_section |
|
| 204 | - * @param string $name |
|
| 205 | - */ |
|
| 206 | - do_action( |
|
| 207 | - 'AHEE__EE_Form_Section_Proper___construct_finalize__end', |
|
| 208 | - $this, |
|
| 209 | - $parent_form_section, |
|
| 210 | - $name |
|
| 211 | - ); |
|
| 212 | - } |
|
| 213 | - |
|
| 214 | - |
|
| 215 | - /** |
|
| 216 | - * Gets the layout strategy for this form section |
|
| 217 | - * |
|
| 218 | - * @return EE_Form_Section_Layout_Base |
|
| 219 | - */ |
|
| 220 | - public function get_layout_strategy() |
|
| 221 | - { |
|
| 222 | - return $this->_layout_strategy; |
|
| 223 | - } |
|
| 224 | - |
|
| 225 | - |
|
| 226 | - /** |
|
| 227 | - * Gets the HTML for a single input for this form section according |
|
| 228 | - * to the layout strategy |
|
| 229 | - * |
|
| 230 | - * @param EE_Form_Input_Base $input |
|
| 231 | - * @return string |
|
| 232 | - */ |
|
| 233 | - public function get_html_for_input($input) |
|
| 234 | - { |
|
| 235 | - return $this->_layout_strategy->layout_input($input); |
|
| 236 | - } |
|
| 237 | - |
|
| 238 | - |
|
| 239 | - /** |
|
| 240 | - * was_submitted - checks if form inputs are present in request data |
|
| 241 | - * Basically an alias for form_data_present_in() (which is used by both |
|
| 242 | - * proper form sections and form inputs) |
|
| 243 | - * |
|
| 244 | - * @param null $form_data |
|
| 245 | - * @return boolean |
|
| 246 | - * @throws EE_Error |
|
| 247 | - */ |
|
| 248 | - public function was_submitted($form_data = null) |
|
| 249 | - { |
|
| 250 | - return $this->form_data_present_in($form_data); |
|
| 251 | - } |
|
| 252 | - |
|
| 253 | - /** |
|
| 254 | - * Gets the cached request data; but if there is none, or $req_data was set with |
|
| 255 | - * something different, refresh the cache, and then return it |
|
| 256 | - * @param null $req_data |
|
| 257 | - * @return array |
|
| 258 | - */ |
|
| 259 | - protected function getCachedRequest($req_data = null) |
|
| 260 | - { |
|
| 261 | - if ($this->cached_request_data === null |
|
| 262 | - || ( |
|
| 263 | - $req_data !== null && |
|
| 264 | - $req_data !== $this->cached_request_data |
|
| 265 | - ) |
|
| 266 | - ) { |
|
| 267 | - $req_data = apply_filters( |
|
| 268 | - 'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data', |
|
| 269 | - $req_data, |
|
| 270 | - $this |
|
| 271 | - ); |
|
| 272 | - if ($req_data === null) { |
|
| 273 | - $req_data = array_merge($_GET, $_POST); |
|
| 274 | - } |
|
| 275 | - $req_data = apply_filters( |
|
| 276 | - 'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data', |
|
| 277 | - $req_data, |
|
| 278 | - $this |
|
| 279 | - ); |
|
| 280 | - $this->cached_request_data = (array) $req_data; |
|
| 281 | - } |
|
| 282 | - return $this->cached_request_data; |
|
| 283 | - } |
|
| 284 | - |
|
| 285 | - |
|
| 286 | - /** |
|
| 287 | - * After the form section is initially created, call this to sanitize the data in the submission |
|
| 288 | - * which relates to this form section, validate it, and set it as properties on the form. |
|
| 289 | - * |
|
| 290 | - * @param array|null $req_data should usually be $_POST (the default). |
|
| 291 | - * However, you CAN supply a different array. |
|
| 292 | - * Consider using set_defaults() instead however. |
|
| 293 | - * (If you rendered the form in the page using echo $form_x->get_html() |
|
| 294 | - * the inputs will have the correct name in the request data for this function |
|
| 295 | - * to find them and populate the form with them. |
|
| 296 | - * If you have a flat form (with only input subsections), |
|
| 297 | - * you can supply a flat array where keys |
|
| 298 | - * are the form input names and values are their values) |
|
| 299 | - * @param boolean $validate whether or not to perform validation on this data. Default is, |
|
| 300 | - * of course, to validate that data, and set errors on the invalid values. |
|
| 301 | - * But if the data has already been validated |
|
| 302 | - * (eg you validated the data then stored it in the DB) |
|
| 303 | - * you may want to skip this step. |
|
| 304 | - * @throws InvalidArgumentException |
|
| 305 | - * @throws InvalidInterfaceException |
|
| 306 | - * @throws InvalidDataTypeException |
|
| 307 | - * @throws EE_Error |
|
| 308 | - */ |
|
| 309 | - public function receive_form_submission($req_data = null, $validate = true) |
|
| 310 | - { |
|
| 311 | - $req_data = $this->getCachedRequest($req_data); |
|
| 312 | - $this->_normalize($req_data); |
|
| 313 | - if ($validate) { |
|
| 314 | - $this->_validate(); |
|
| 315 | - // if it's invalid, we're going to want to re-display so remember what they submitted |
|
| 316 | - if (! $this->is_valid()) { |
|
| 317 | - $this->store_submitted_form_data_in_session(); |
|
| 318 | - } |
|
| 319 | - } |
|
| 320 | - if ($this->submission_error_message() === '' && ! $this->is_valid()) { |
|
| 321 | - $this->set_submission_error_message(); |
|
| 322 | - } |
|
| 323 | - do_action( |
|
| 324 | - 'AHEE__EE_Form_Section_Proper__receive_form_submission__end', |
|
| 325 | - $req_data, |
|
| 326 | - $this, |
|
| 327 | - $validate |
|
| 328 | - ); |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - |
|
| 332 | - /** |
|
| 333 | - * caches the originally submitted input values in the session |
|
| 334 | - * so that they can be used to repopulate the form if it failed validation |
|
| 335 | - * |
|
| 336 | - * @return boolean whether or not the data was successfully stored in the session |
|
| 337 | - * @throws InvalidArgumentException |
|
| 338 | - * @throws InvalidInterfaceException |
|
| 339 | - * @throws InvalidDataTypeException |
|
| 340 | - * @throws EE_Error |
|
| 341 | - */ |
|
| 342 | - protected function store_submitted_form_data_in_session() |
|
| 343 | - { |
|
| 344 | - return EE_Registry::instance()->SSN->set_session_data( |
|
| 345 | - array( |
|
| 346 | - EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true), |
|
| 347 | - ) |
|
| 348 | - ); |
|
| 349 | - } |
|
| 350 | - |
|
| 351 | - |
|
| 352 | - /** |
|
| 353 | - * retrieves the originally submitted input values in the session |
|
| 354 | - * so that they can be used to repopulate the form if it failed validation |
|
| 355 | - * |
|
| 356 | - * @return array |
|
| 357 | - * @throws InvalidArgumentException |
|
| 358 | - * @throws InvalidInterfaceException |
|
| 359 | - * @throws InvalidDataTypeException |
|
| 360 | - */ |
|
| 361 | - protected function get_submitted_form_data_from_session() |
|
| 362 | - { |
|
| 363 | - $session = EE_Registry::instance()->SSN; |
|
| 364 | - if ($session instanceof EE_Session) { |
|
| 365 | - return $session->get_session_data( |
|
| 366 | - EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY |
|
| 367 | - ); |
|
| 368 | - } |
|
| 369 | - return array(); |
|
| 370 | - } |
|
| 371 | - |
|
| 372 | - |
|
| 373 | - /** |
|
| 374 | - * flushed the originally submitted input values from the session |
|
| 375 | - * |
|
| 376 | - * @return boolean whether or not the data was successfully removed from the session |
|
| 377 | - * @throws InvalidArgumentException |
|
| 378 | - * @throws InvalidInterfaceException |
|
| 379 | - * @throws InvalidDataTypeException |
|
| 380 | - */ |
|
| 381 | - public static function flush_submitted_form_data_from_session() |
|
| 382 | - { |
|
| 383 | - return EE_Registry::instance()->SSN->reset_data( |
|
| 384 | - array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY) |
|
| 385 | - ); |
|
| 386 | - } |
|
| 387 | - |
|
| 388 | - |
|
| 389 | - /** |
|
| 390 | - * Populates this form and its subsections with data from the session. |
|
| 391 | - * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows |
|
| 392 | - * validation errors when displaying too) |
|
| 393 | - * Returns true if the form was populated from the session, false otherwise |
|
| 394 | - * |
|
| 395 | - * @return boolean |
|
| 396 | - * @throws InvalidArgumentException |
|
| 397 | - * @throws InvalidInterfaceException |
|
| 398 | - * @throws InvalidDataTypeException |
|
| 399 | - * @throws EE_Error |
|
| 400 | - */ |
|
| 401 | - public function populate_from_session() |
|
| 402 | - { |
|
| 403 | - $form_data_in_session = $this->get_submitted_form_data_from_session(); |
|
| 404 | - if (empty($form_data_in_session)) { |
|
| 405 | - return false; |
|
| 406 | - } |
|
| 407 | - $this->receive_form_submission($form_data_in_session); |
|
| 408 | - add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session')); |
|
| 409 | - if ($this->form_data_present_in($form_data_in_session)) { |
|
| 410 | - return true; |
|
| 411 | - } |
|
| 412 | - return false; |
|
| 413 | - } |
|
| 414 | - |
|
| 415 | - |
|
| 416 | - /** |
|
| 417 | - * Populates the default data for the form, given an array where keys are |
|
| 418 | - * the input names, and values are their values (preferably normalized to be their |
|
| 419 | - * proper PHP types, not all strings... although that should be ok too). |
|
| 420 | - * Proper subsections are sub-arrays, the key being the subsection's name, and |
|
| 421 | - * the value being an array formatted in teh same way |
|
| 422 | - * |
|
| 423 | - * @param array $default_data |
|
| 424 | - * @throws EE_Error |
|
| 425 | - */ |
|
| 426 | - public function populate_defaults($default_data) |
|
| 427 | - { |
|
| 428 | - foreach ($this->subsections(false) as $subsection_name => $subsection) { |
|
| 429 | - if (isset($default_data[ $subsection_name ])) { |
|
| 430 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 431 | - $subsection->set_default($default_data[ $subsection_name ]); |
|
| 432 | - } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 433 | - $subsection->populate_defaults($default_data[ $subsection_name ]); |
|
| 434 | - } |
|
| 435 | - } |
|
| 436 | - } |
|
| 437 | - } |
|
| 438 | - |
|
| 439 | - |
|
| 440 | - /** |
|
| 441 | - * returns true if subsection exists |
|
| 442 | - * |
|
| 443 | - * @param string $name |
|
| 444 | - * @return boolean |
|
| 445 | - */ |
|
| 446 | - public function subsection_exists($name) |
|
| 447 | - { |
|
| 448 | - return isset($this->_subsections[ $name ]) ? true : false; |
|
| 449 | - } |
|
| 450 | - |
|
| 451 | - |
|
| 452 | - /** |
|
| 453 | - * Gets the subsection specified by its name |
|
| 454 | - * |
|
| 455 | - * @param string $name |
|
| 456 | - * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE |
|
| 457 | - * so that the inputs will be properly configured. |
|
| 458 | - * However, some client code may be ok |
|
| 459 | - * with construction finalize being called later |
|
| 460 | - * (realizing that the subsections' html names |
|
| 461 | - * might not be set yet, etc.) |
|
| 462 | - * @return EE_Form_Section_Base |
|
| 463 | - * @throws EE_Error |
|
| 464 | - */ |
|
| 465 | - public function get_subsection($name, $require_construction_to_be_finalized = true) |
|
| 466 | - { |
|
| 467 | - if ($require_construction_to_be_finalized) { |
|
| 468 | - $this->ensure_construct_finalized_called(); |
|
| 469 | - } |
|
| 470 | - return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null; |
|
| 471 | - } |
|
| 472 | - |
|
| 473 | - |
|
| 474 | - /** |
|
| 475 | - * Gets all the validatable subsections of this form section |
|
| 476 | - * |
|
| 477 | - * @return EE_Form_Section_Validatable[] |
|
| 478 | - * @throws EE_Error |
|
| 479 | - */ |
|
| 480 | - public function get_validatable_subsections() |
|
| 481 | - { |
|
| 482 | - $validatable_subsections = array(); |
|
| 483 | - foreach ($this->subsections() as $name => $obj) { |
|
| 484 | - if ($obj instanceof EE_Form_Section_Validatable) { |
|
| 485 | - $validatable_subsections[ $name ] = $obj; |
|
| 486 | - } |
|
| 487 | - } |
|
| 488 | - return $validatable_subsections; |
|
| 489 | - } |
|
| 490 | - |
|
| 491 | - |
|
| 492 | - /** |
|
| 493 | - * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child, |
|
| 494 | - * throw an EE_Error. |
|
| 495 | - * |
|
| 496 | - * @param string $name |
|
| 497 | - * @param boolean $require_construction_to_be_finalized most client code should |
|
| 498 | - * leave this as TRUE so that the inputs will be properly |
|
| 499 | - * configured. However, some client code may be ok with |
|
| 500 | - * construction finalize being called later |
|
| 501 | - * (realizing that the subsections' html names might not be |
|
| 502 | - * set yet, etc.) |
|
| 503 | - * @return EE_Form_Input_Base |
|
| 504 | - * @throws EE_Error |
|
| 505 | - */ |
|
| 506 | - public function get_input($name, $require_construction_to_be_finalized = true) |
|
| 507 | - { |
|
| 508 | - $subsection = $this->get_subsection( |
|
| 509 | - $name, |
|
| 510 | - $require_construction_to_be_finalized |
|
| 511 | - ); |
|
| 512 | - if (! $subsection instanceof EE_Form_Input_Base) { |
|
| 513 | - throw new EE_Error( |
|
| 514 | - sprintf( |
|
| 515 | - esc_html__( |
|
| 516 | - "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'", |
|
| 517 | - 'event_espresso' |
|
| 518 | - ), |
|
| 519 | - $name, |
|
| 520 | - get_class($this), |
|
| 521 | - $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 522 | - ) |
|
| 523 | - ); |
|
| 524 | - } |
|
| 525 | - return $subsection; |
|
| 526 | - } |
|
| 527 | - |
|
| 528 | - |
|
| 529 | - /** |
|
| 530 | - * Like get_input(), gets the proper subsection of the form given the name, |
|
| 531 | - * otherwise throws an EE_Error |
|
| 532 | - * |
|
| 533 | - * @param string $name |
|
| 534 | - * @param boolean $require_construction_to_be_finalized most client code should |
|
| 535 | - * leave this as TRUE so that the inputs will be properly |
|
| 536 | - * configured. However, some client code may be ok with |
|
| 537 | - * construction finalize being called later |
|
| 538 | - * (realizing that the subsections' html names might not be |
|
| 539 | - * set yet, etc.) |
|
| 540 | - * @return EE_Form_Section_Proper |
|
| 541 | - * @throws EE_Error |
|
| 542 | - */ |
|
| 543 | - public function get_proper_subsection($name, $require_construction_to_be_finalized = true) |
|
| 544 | - { |
|
| 545 | - $subsection = $this->get_subsection( |
|
| 546 | - $name, |
|
| 547 | - $require_construction_to_be_finalized |
|
| 548 | - ); |
|
| 549 | - if (! $subsection instanceof EE_Form_Section_Proper) { |
|
| 550 | - throw new EE_Error( |
|
| 551 | - sprintf( |
|
| 552 | - esc_html__( |
|
| 553 | - "Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'", |
|
| 554 | - 'event_espresso' |
|
| 555 | - ), |
|
| 556 | - $name, |
|
| 557 | - get_class($this) |
|
| 558 | - ) |
|
| 559 | - ); |
|
| 560 | - } |
|
| 561 | - return $subsection; |
|
| 562 | - } |
|
| 563 | - |
|
| 564 | - |
|
| 565 | - /** |
|
| 566 | - * Gets the value of the specified input. Should be called after receive_form_submission() |
|
| 567 | - * or populate_defaults() on the form, where the normalized value on the input is set. |
|
| 568 | - * |
|
| 569 | - * @param string $name |
|
| 570 | - * @return mixed depending on the input's type and its normalization strategy |
|
| 571 | - * @throws EE_Error |
|
| 572 | - */ |
|
| 573 | - public function get_input_value($name) |
|
| 574 | - { |
|
| 575 | - $input = $this->get_input($name); |
|
| 576 | - return $input->normalized_value(); |
|
| 577 | - } |
|
| 578 | - |
|
| 579 | - |
|
| 580 | - /** |
|
| 581 | - * Checks if this form section itself is valid, and then checks its subsections |
|
| 582 | - * |
|
| 583 | - * @throws EE_Error |
|
| 584 | - * @return boolean |
|
| 585 | - */ |
|
| 586 | - public function is_valid() |
|
| 587 | - { |
|
| 588 | - if ($this->is_valid === null) { |
|
| 589 | - if (! $this->has_received_submission()) { |
|
| 590 | - throw new EE_Error( |
|
| 591 | - sprintf( |
|
| 592 | - esc_html__( |
|
| 593 | - 'You cannot check if a form is valid before receiving the form submission using receive_form_submission', |
|
| 594 | - 'event_espresso' |
|
| 595 | - ) |
|
| 596 | - ) |
|
| 597 | - ); |
|
| 598 | - } |
|
| 599 | - if (! parent::is_valid()) { |
|
| 600 | - $this->is_valid = false; |
|
| 601 | - } else { |
|
| 602 | - // ok so no general errors to this entire form section. |
|
| 603 | - // so let's check the subsections, but only set errors if that hasn't been done yet |
|
| 604 | - $this->is_valid = true; |
|
| 605 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 606 | - if (! $subsection->is_valid()) { |
|
| 607 | - $this->is_valid = false; |
|
| 608 | - } |
|
| 609 | - } |
|
| 610 | - } |
|
| 611 | - } |
|
| 612 | - return $this->is_valid; |
|
| 613 | - } |
|
| 614 | - |
|
| 615 | - |
|
| 616 | - /** |
|
| 617 | - * gets the default name of this form section if none is specified |
|
| 618 | - * |
|
| 619 | - * @return void |
|
| 620 | - */ |
|
| 621 | - protected function _set_default_name_if_empty() |
|
| 622 | - { |
|
| 623 | - if (! $this->_name) { |
|
| 624 | - $classname = get_class($this); |
|
| 625 | - $default_name = str_replace('EE_', '', $classname); |
|
| 626 | - $this->_name = $default_name; |
|
| 627 | - } |
|
| 628 | - } |
|
| 629 | - |
|
| 630 | - |
|
| 631 | - /** |
|
| 632 | - * Returns the HTML for the form, except for the form opening and closing tags |
|
| 633 | - * (as the form section doesn't know where you necessarily want to send the information to), |
|
| 634 | - * and except for a submit button. Enqueues JS and CSS; if called early enough we will |
|
| 635 | - * try to enqueue them in the header, otherwise they'll be enqueued in the footer. |
|
| 636 | - * Not doing_it_wrong because theoretically this CAN be used properly, |
|
| 637 | - * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue |
|
| 638 | - * any CSS. |
|
| 639 | - * |
|
| 640 | - * @throws InvalidArgumentException |
|
| 641 | - * @throws InvalidInterfaceException |
|
| 642 | - * @throws InvalidDataTypeException |
|
| 643 | - * @throws EE_Error |
|
| 644 | - */ |
|
| 645 | - public function get_html_and_js() |
|
| 646 | - { |
|
| 647 | - $this->enqueue_js(); |
|
| 648 | - return $this->get_html(); |
|
| 649 | - } |
|
| 650 | - |
|
| 651 | - |
|
| 652 | - /** |
|
| 653 | - * returns HTML for displaying this form section. recursively calls display_section() on all subsections |
|
| 654 | - * |
|
| 655 | - * @param bool $display_previously_submitted_data |
|
| 656 | - * @return string |
|
| 657 | - * @throws InvalidArgumentException |
|
| 658 | - * @throws InvalidInterfaceException |
|
| 659 | - * @throws InvalidDataTypeException |
|
| 660 | - * @throws EE_Error |
|
| 661 | - * @throws EE_Error |
|
| 662 | - * @throws EE_Error |
|
| 663 | - */ |
|
| 664 | - public function get_html($display_previously_submitted_data = true) |
|
| 665 | - { |
|
| 666 | - $this->ensure_construct_finalized_called(); |
|
| 667 | - if ($display_previously_submitted_data) { |
|
| 668 | - $this->populate_from_session(); |
|
| 669 | - } |
|
| 670 | - return $this->_form_html_filter |
|
| 671 | - ? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this) |
|
| 672 | - : $this->_layout_strategy->layout_form(); |
|
| 673 | - } |
|
| 674 | - |
|
| 675 | - |
|
| 676 | - /** |
|
| 677 | - * enqueues JS and CSS for the form. |
|
| 678 | - * It is preferred to call this before wp_enqueue_scripts so the |
|
| 679 | - * scripts and styles can be put in the header, but if called later |
|
| 680 | - * they will be put in the footer (which is OK for JS, but in HTML4 CSS should |
|
| 681 | - * only be in the header; but in HTML5 its ok in the body. |
|
| 682 | - * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag. |
|
| 683 | - * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.) |
|
| 684 | - * |
|
| 685 | - * @return void |
|
| 686 | - * @throws EE_Error |
|
| 687 | - */ |
|
| 688 | - public function enqueue_js() |
|
| 689 | - { |
|
| 690 | - $this->_enqueue_and_localize_form_js(); |
|
| 691 | - foreach ($this->subsections() as $subsection) { |
|
| 692 | - $subsection->enqueue_js(); |
|
| 693 | - } |
|
| 694 | - } |
|
| 695 | - |
|
| 696 | - |
|
| 697 | - /** |
|
| 698 | - * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts(). |
|
| 699 | - * This must be done BEFORE wp_enqueue_scripts() gets called, which is on |
|
| 700 | - * the wp_enqueue_scripts hook. |
|
| 701 | - * However, registering the form js and localizing it can happen when we |
|
| 702 | - * actually output the form (which is preferred, seeing how teh form's fields |
|
| 703 | - * could change until it's actually outputted) |
|
| 704 | - * |
|
| 705 | - * @param boolean $init_form_validation_automatically whether or not we want the form validation |
|
| 706 | - * to be triggered automatically or not |
|
| 707 | - * @return void |
|
| 708 | - */ |
|
| 709 | - public static function wp_enqueue_scripts($init_form_validation_automatically = true) |
|
| 710 | - { |
|
| 711 | - wp_register_script( |
|
| 712 | - 'ee_form_section_validation', |
|
| 713 | - EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js', |
|
| 714 | - array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'), |
|
| 715 | - EVENT_ESPRESSO_VERSION, |
|
| 716 | - true |
|
| 717 | - ); |
|
| 718 | - wp_localize_script( |
|
| 719 | - 'ee_form_section_validation', |
|
| 720 | - 'ee_form_section_validation_init', |
|
| 721 | - array('init' => $init_form_validation_automatically ? '1' : '0') |
|
| 722 | - ); |
|
| 723 | - } |
|
| 724 | - |
|
| 725 | - |
|
| 726 | - /** |
|
| 727 | - * gets the variables used by form_section_validation.js. |
|
| 728 | - * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script, |
|
| 729 | - * but before the wordpress hook wp_loaded |
|
| 730 | - * |
|
| 731 | - * @throws EE_Error |
|
| 732 | - */ |
|
| 733 | - public function _enqueue_and_localize_form_js() |
|
| 734 | - { |
|
| 735 | - $this->ensure_construct_finalized_called(); |
|
| 736 | - // actually, we don't want to localize just yet. There may be other forms on the page. |
|
| 737 | - // so we need to add our form section data to a static variable accessible by all form sections |
|
| 738 | - // and localize it just before the footer |
|
| 739 | - $this->localize_validation_rules(); |
|
| 740 | - add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2); |
|
| 741 | - add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms')); |
|
| 742 | - } |
|
| 743 | - |
|
| 744 | - |
|
| 745 | - /** |
|
| 746 | - * add our form section data to a static variable accessible by all form sections |
|
| 747 | - * |
|
| 748 | - * @param bool $return_for_subsection |
|
| 749 | - * @return void |
|
| 750 | - * @throws EE_Error |
|
| 751 | - */ |
|
| 752 | - public function localize_validation_rules($return_for_subsection = false) |
|
| 753 | - { |
|
| 754 | - // we only want to localize vars ONCE for the entire form, |
|
| 755 | - // so if the form section doesn't have a parent, then it must be the top dog |
|
| 756 | - if ($return_for_subsection || ! $this->parent_section()) { |
|
| 757 | - EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array( |
|
| 758 | - 'form_section_id' => $this->html_id(true), |
|
| 759 | - 'validation_rules' => $this->get_jquery_validation_rules(), |
|
| 760 | - 'other_data' => $this->get_other_js_data(), |
|
| 761 | - 'errors' => $this->subsection_validation_errors_by_html_name(), |
|
| 762 | - ); |
|
| 763 | - EE_Form_Section_Proper::$_scripts_localized = true; |
|
| 764 | - } |
|
| 765 | - } |
|
| 766 | - |
|
| 767 | - |
|
| 768 | - /** |
|
| 769 | - * Gets an array of extra data that will be useful for client-side javascript. |
|
| 770 | - * This is primarily data added by inputs and forms in addition to any |
|
| 771 | - * scripts they might enqueue |
|
| 772 | - * |
|
| 773 | - * @param array $form_other_js_data |
|
| 774 | - * @return array |
|
| 775 | - * @throws EE_Error |
|
| 776 | - */ |
|
| 777 | - public function get_other_js_data($form_other_js_data = array()) |
|
| 778 | - { |
|
| 779 | - foreach ($this->subsections() as $subsection) { |
|
| 780 | - $form_other_js_data = $subsection->get_other_js_data($form_other_js_data); |
|
| 781 | - } |
|
| 782 | - return $form_other_js_data; |
|
| 783 | - } |
|
| 784 | - |
|
| 785 | - |
|
| 786 | - /** |
|
| 787 | - * Gets a flat array of inputs for this form section and its subsections. |
|
| 788 | - * Keys are their form names, and values are the inputs themselves |
|
| 789 | - * |
|
| 790 | - * @return EE_Form_Input_Base |
|
| 791 | - * @throws EE_Error |
|
| 792 | - */ |
|
| 793 | - public function inputs_in_subsections() |
|
| 794 | - { |
|
| 795 | - $inputs = array(); |
|
| 796 | - foreach ($this->subsections() as $subsection) { |
|
| 797 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 798 | - $inputs[ $subsection->html_name() ] = $subsection; |
|
| 799 | - } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 800 | - $inputs += $subsection->inputs_in_subsections(); |
|
| 801 | - } |
|
| 802 | - } |
|
| 803 | - return $inputs; |
|
| 804 | - } |
|
| 805 | - |
|
| 806 | - |
|
| 807 | - /** |
|
| 808 | - * Gets a flat array of all the validation errors. |
|
| 809 | - * Keys are html names (because those should be unique) |
|
| 810 | - * and values are a string of all their validation errors |
|
| 811 | - * |
|
| 812 | - * @return string[] |
|
| 813 | - * @throws EE_Error |
|
| 814 | - */ |
|
| 815 | - public function subsection_validation_errors_by_html_name() |
|
| 816 | - { |
|
| 817 | - $inputs = $this->inputs(); |
|
| 818 | - $errors = array(); |
|
| 819 | - foreach ($inputs as $form_input) { |
|
| 820 | - if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) { |
|
| 821 | - $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string(); |
|
| 822 | - } |
|
| 823 | - } |
|
| 824 | - return $errors; |
|
| 825 | - } |
|
| 826 | - |
|
| 827 | - |
|
| 828 | - /** |
|
| 829 | - * passes all the form data required by the JS to the JS, and enqueues the few required JS files. |
|
| 830 | - * Should be setup by each form during the _enqueues_and_localize_form_js |
|
| 831 | - * |
|
| 832 | - * @throws InvalidArgumentException |
|
| 833 | - * @throws InvalidInterfaceException |
|
| 834 | - * @throws InvalidDataTypeException |
|
| 835 | - */ |
|
| 836 | - public static function localize_script_for_all_forms() |
|
| 837 | - { |
|
| 838 | - // allow inputs and stuff to hook in their JS and stuff here |
|
| 839 | - do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin'); |
|
| 840 | - EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages(); |
|
| 841 | - $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level) |
|
| 842 | - ? EE_Registry::instance()->CFG->registration->email_validation_level |
|
| 843 | - : 'wp_default'; |
|
| 844 | - EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level; |
|
| 845 | - wp_enqueue_script('ee_form_section_validation'); |
|
| 846 | - wp_localize_script( |
|
| 847 | - 'ee_form_section_validation', |
|
| 848 | - 'ee_form_section_vars', |
|
| 849 | - EE_Form_Section_Proper::$_js_localization |
|
| 850 | - ); |
|
| 851 | - } |
|
| 852 | - |
|
| 853 | - |
|
| 854 | - /** |
|
| 855 | - * ensure_scripts_localized |
|
| 856 | - * |
|
| 857 | - * @throws EE_Error |
|
| 858 | - */ |
|
| 859 | - public function ensure_scripts_localized() |
|
| 860 | - { |
|
| 861 | - if (! EE_Form_Section_Proper::$_scripts_localized) { |
|
| 862 | - $this->_enqueue_and_localize_form_js(); |
|
| 863 | - } |
|
| 864 | - } |
|
| 865 | - |
|
| 866 | - |
|
| 867 | - /** |
|
| 868 | - * Gets the hard-coded validation error messages to be used in the JS. The convention |
|
| 869 | - * is that the key here should be the same as the custom validation rule put in the JS file |
|
| 870 | - * |
|
| 871 | - * @return array keys are custom validation rules, and values are internationalized strings |
|
| 872 | - */ |
|
| 873 | - private static function _get_localized_error_messages() |
|
| 874 | - { |
|
| 875 | - return array( |
|
| 876 | - 'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'), |
|
| 877 | - 'regex' => esc_html__('Please check your input', 'event_espresso'), |
|
| 878 | - ); |
|
| 879 | - } |
|
| 880 | - |
|
| 881 | - |
|
| 882 | - /** |
|
| 883 | - * @return array |
|
| 884 | - */ |
|
| 885 | - public static function js_localization() |
|
| 886 | - { |
|
| 887 | - return self::$_js_localization; |
|
| 888 | - } |
|
| 889 | - |
|
| 890 | - |
|
| 891 | - /** |
|
| 892 | - * @return void |
|
| 893 | - */ |
|
| 894 | - public static function reset_js_localization() |
|
| 895 | - { |
|
| 896 | - self::$_js_localization = array(); |
|
| 897 | - } |
|
| 898 | - |
|
| 899 | - |
|
| 900 | - /** |
|
| 901 | - * Gets the JS to put inside the jquery validation rules for subsection of this form section. |
|
| 902 | - * See parent function for more... |
|
| 903 | - * |
|
| 904 | - * @return array |
|
| 905 | - * @throws EE_Error |
|
| 906 | - */ |
|
| 907 | - public function get_jquery_validation_rules() |
|
| 908 | - { |
|
| 909 | - $jquery_validation_rules = array(); |
|
| 910 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 911 | - $jquery_validation_rules = array_merge( |
|
| 912 | - $jquery_validation_rules, |
|
| 913 | - $subsection->get_jquery_validation_rules() |
|
| 914 | - ); |
|
| 915 | - } |
|
| 916 | - return $jquery_validation_rules; |
|
| 917 | - } |
|
| 918 | - |
|
| 919 | - |
|
| 920 | - /** |
|
| 921 | - * Sanitizes all the data and sets the sanitized value of each field |
|
| 922 | - * |
|
| 923 | - * @param array $req_data like $_POST |
|
| 924 | - * @return void |
|
| 925 | - * @throws EE_Error |
|
| 926 | - */ |
|
| 927 | - protected function _normalize($req_data) |
|
| 928 | - { |
|
| 929 | - $this->_received_submission = true; |
|
| 930 | - $this->_validation_errors = array(); |
|
| 931 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 932 | - try { |
|
| 933 | - $subsection->_normalize($req_data); |
|
| 934 | - } catch (EE_Validation_Error $e) { |
|
| 935 | - $subsection->add_validation_error($e); |
|
| 936 | - } |
|
| 937 | - } |
|
| 938 | - } |
|
| 939 | - |
|
| 940 | - |
|
| 941 | - /** |
|
| 942 | - * Performs validation on this form section and its subsections. |
|
| 943 | - * For each subsection, |
|
| 944 | - * calls _validate_{subsection_name} on THIS form (if the function exists) |
|
| 945 | - * and passes it the subsection, then calls _validate on that subsection. |
|
| 946 | - * If you need to perform validation on the form as a whole (considering multiple) |
|
| 947 | - * you would be best to override this _validate method, |
|
| 948 | - * calling parent::_validate() first. |
|
| 949 | - * |
|
| 950 | - * @throws EE_Error |
|
| 951 | - */ |
|
| 952 | - protected function _validate() |
|
| 953 | - { |
|
| 954 | - // reset the cache of whether this form is valid or not- we're re-validating it now |
|
| 955 | - $this->is_valid = null; |
|
| 956 | - foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) { |
|
| 957 | - if (method_exists($this, '_validate_' . $subsection_name)) { |
|
| 958 | - call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection)); |
|
| 959 | - } |
|
| 960 | - $subsection->_validate(); |
|
| 961 | - } |
|
| 962 | - } |
|
| 963 | - |
|
| 964 | - |
|
| 965 | - /** |
|
| 966 | - * Gets all the validated inputs for the form section |
|
| 967 | - * |
|
| 968 | - * @return array |
|
| 969 | - * @throws EE_Error |
|
| 970 | - */ |
|
| 971 | - public function valid_data() |
|
| 972 | - { |
|
| 973 | - $inputs = array(); |
|
| 974 | - foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 975 | - if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 976 | - $inputs[ $subsection_name ] = $subsection->valid_data(); |
|
| 977 | - } elseif ($subsection instanceof EE_Form_Input_Base) { |
|
| 978 | - $inputs[ $subsection_name ] = $subsection->normalized_value(); |
|
| 979 | - } |
|
| 980 | - } |
|
| 981 | - return $inputs; |
|
| 982 | - } |
|
| 983 | - |
|
| 984 | - |
|
| 985 | - /** |
|
| 986 | - * Gets all the inputs on this form section |
|
| 987 | - * |
|
| 988 | - * @return EE_Form_Input_Base[] |
|
| 989 | - * @throws EE_Error |
|
| 990 | - */ |
|
| 991 | - public function inputs() |
|
| 992 | - { |
|
| 993 | - $inputs = array(); |
|
| 994 | - foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 995 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 996 | - $inputs[ $subsection_name ] = $subsection; |
|
| 997 | - } |
|
| 998 | - } |
|
| 999 | - return $inputs; |
|
| 1000 | - } |
|
| 1001 | - |
|
| 1002 | - |
|
| 1003 | - /** |
|
| 1004 | - * Gets all the subsections which are a proper form |
|
| 1005 | - * |
|
| 1006 | - * @return EE_Form_Section_Proper[] |
|
| 1007 | - * @throws EE_Error |
|
| 1008 | - */ |
|
| 1009 | - public function subforms() |
|
| 1010 | - { |
|
| 1011 | - $form_sections = array(); |
|
| 1012 | - foreach ($this->subsections() as $name => $obj) { |
|
| 1013 | - if ($obj instanceof EE_Form_Section_Proper) { |
|
| 1014 | - $form_sections[ $name ] = $obj; |
|
| 1015 | - } |
|
| 1016 | - } |
|
| 1017 | - return $form_sections; |
|
| 1018 | - } |
|
| 1019 | - |
|
| 1020 | - |
|
| 1021 | - /** |
|
| 1022 | - * Gets all the subsections (inputs, proper subsections, or html-only sections). |
|
| 1023 | - * Consider using inputs() or subforms() |
|
| 1024 | - * if you only want form inputs or proper form sections. |
|
| 1025 | - * |
|
| 1026 | - * @param boolean $require_construction_to_be_finalized most client code should |
|
| 1027 | - * leave this as TRUE so that the inputs will be properly |
|
| 1028 | - * configured. However, some client code may be ok with |
|
| 1029 | - * construction finalize being called later |
|
| 1030 | - * (realizing that the subsections' html names might not be |
|
| 1031 | - * set yet, etc.) |
|
| 1032 | - * @return EE_Form_Section_Proper[] |
|
| 1033 | - * @throws EE_Error |
|
| 1034 | - */ |
|
| 1035 | - public function subsections($require_construction_to_be_finalized = true) |
|
| 1036 | - { |
|
| 1037 | - if ($require_construction_to_be_finalized) { |
|
| 1038 | - $this->ensure_construct_finalized_called(); |
|
| 1039 | - } |
|
| 1040 | - return $this->_subsections; |
|
| 1041 | - } |
|
| 1042 | - |
|
| 1043 | - |
|
| 1044 | - /** |
|
| 1045 | - * Returns whether this form has any subforms or inputs |
|
| 1046 | - * @return bool |
|
| 1047 | - */ |
|
| 1048 | - public function hasSubsections() |
|
| 1049 | - { |
|
| 1050 | - return ! empty($this->_subsections); |
|
| 1051 | - } |
|
| 1052 | - |
|
| 1053 | - |
|
| 1054 | - /** |
|
| 1055 | - * Returns a simple array where keys are input names, and values are their normalized |
|
| 1056 | - * values. (Similar to calling get_input_value on inputs) |
|
| 1057 | - * |
|
| 1058 | - * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1059 | - * or just this forms' direct children inputs |
|
| 1060 | - * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1061 | - * or allow multidimensional array |
|
| 1062 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1063 | - * with array keys being input names |
|
| 1064 | - * (regardless of whether they are from a subsection or not), |
|
| 1065 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1066 | - * where keys are always subsection names and values are either |
|
| 1067 | - * the input's normalized value, or an array like the top-level array |
|
| 1068 | - * @throws EE_Error |
|
| 1069 | - */ |
|
| 1070 | - public function input_values($include_subform_inputs = false, $flatten = false) |
|
| 1071 | - { |
|
| 1072 | - return $this->_input_values(false, $include_subform_inputs, $flatten); |
|
| 1073 | - } |
|
| 1074 | - |
|
| 1075 | - |
|
| 1076 | - /** |
|
| 1077 | - * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value' |
|
| 1078 | - * of each input. On some inputs (especially radio boxes or checkboxes), the value stored |
|
| 1079 | - * is not necessarily the value we want to display to users. This creates an array |
|
| 1080 | - * where keys are the input names, and values are their display values |
|
| 1081 | - * |
|
| 1082 | - * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1083 | - * or just this forms' direct children inputs |
|
| 1084 | - * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1085 | - * or allow multidimensional array |
|
| 1086 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1087 | - * with array keys being input names |
|
| 1088 | - * (regardless of whether they are from a subsection or not), |
|
| 1089 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1090 | - * where keys are always subsection names and values are either |
|
| 1091 | - * the input's normalized value, or an array like the top-level array |
|
| 1092 | - * @throws EE_Error |
|
| 1093 | - */ |
|
| 1094 | - public function input_pretty_values($include_subform_inputs = false, $flatten = false) |
|
| 1095 | - { |
|
| 1096 | - return $this->_input_values(true, $include_subform_inputs, $flatten); |
|
| 1097 | - } |
|
| 1098 | - |
|
| 1099 | - |
|
| 1100 | - /** |
|
| 1101 | - * Gets the input values from the form |
|
| 1102 | - * |
|
| 1103 | - * @param boolean $pretty Whether to retrieve the pretty value, |
|
| 1104 | - * or just the normalized value |
|
| 1105 | - * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1106 | - * or just this forms' direct children inputs |
|
| 1107 | - * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1108 | - * or allow multidimensional array |
|
| 1109 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being |
|
| 1110 | - * input names (regardless of whether they are from a subsection or not), |
|
| 1111 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1112 | - * where keys are always subsection names and values are either |
|
| 1113 | - * the input's normalized value, or an array like the top-level array |
|
| 1114 | - * @throws EE_Error |
|
| 1115 | - */ |
|
| 1116 | - public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false) |
|
| 1117 | - { |
|
| 1118 | - $input_values = array(); |
|
| 1119 | - foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 1120 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1121 | - $input_values[ $subsection_name ] = $pretty |
|
| 1122 | - ? $subsection->pretty_value() |
|
| 1123 | - : $subsection->normalized_value(); |
|
| 1124 | - } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) { |
|
| 1125 | - $subform_input_values = $subsection->_input_values( |
|
| 1126 | - $pretty, |
|
| 1127 | - $include_subform_inputs, |
|
| 1128 | - $flatten |
|
| 1129 | - ); |
|
| 1130 | - if ($flatten) { |
|
| 1131 | - $input_values = array_merge($input_values, $subform_input_values); |
|
| 1132 | - } else { |
|
| 1133 | - $input_values[ $subsection_name ] = $subform_input_values; |
|
| 1134 | - } |
|
| 1135 | - } |
|
| 1136 | - } |
|
| 1137 | - return $input_values; |
|
| 1138 | - } |
|
| 1139 | - |
|
| 1140 | - |
|
| 1141 | - /** |
|
| 1142 | - * Gets the originally submitted input values from the form |
|
| 1143 | - * |
|
| 1144 | - * @param boolean $include_subforms Whether to include inputs from subforms, |
|
| 1145 | - * or just this forms' direct children inputs |
|
| 1146 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1147 | - * with array keys being input names |
|
| 1148 | - * (regardless of whether they are from a subsection or not), |
|
| 1149 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1150 | - * where keys are always subsection names and values are either |
|
| 1151 | - * the input's normalized value, or an array like the top-level array |
|
| 1152 | - * @throws EE_Error |
|
| 1153 | - */ |
|
| 1154 | - public function submitted_values($include_subforms = false) |
|
| 1155 | - { |
|
| 1156 | - $submitted_values = array(); |
|
| 1157 | - foreach ($this->subsections() as $subsection) { |
|
| 1158 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1159 | - // is this input part of an array of inputs? |
|
| 1160 | - if (strpos($subsection->html_name(), '[') !== false) { |
|
| 1161 | - $full_input_name = EEH_Array::convert_array_values_to_keys( |
|
| 1162 | - explode( |
|
| 1163 | - '[', |
|
| 1164 | - str_replace(']', '', $subsection->html_name()) |
|
| 1165 | - ), |
|
| 1166 | - $subsection->raw_value() |
|
| 1167 | - ); |
|
| 1168 | - $submitted_values = array_replace_recursive($submitted_values, $full_input_name); |
|
| 1169 | - } else { |
|
| 1170 | - $submitted_values[ $subsection->html_name() ] = $subsection->raw_value(); |
|
| 1171 | - } |
|
| 1172 | - } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) { |
|
| 1173 | - $subform_input_values = $subsection->submitted_values($include_subforms); |
|
| 1174 | - $submitted_values = array_replace_recursive($submitted_values, $subform_input_values); |
|
| 1175 | - } |
|
| 1176 | - } |
|
| 1177 | - return $submitted_values; |
|
| 1178 | - } |
|
| 1179 | - |
|
| 1180 | - |
|
| 1181 | - /** |
|
| 1182 | - * Indicates whether or not this form has received a submission yet |
|
| 1183 | - * (ie, had receive_form_submission called on it yet) |
|
| 1184 | - * |
|
| 1185 | - * @return boolean |
|
| 1186 | - * @throws EE_Error |
|
| 1187 | - */ |
|
| 1188 | - public function has_received_submission() |
|
| 1189 | - { |
|
| 1190 | - $this->ensure_construct_finalized_called(); |
|
| 1191 | - return $this->_received_submission; |
|
| 1192 | - } |
|
| 1193 | - |
|
| 1194 | - |
|
| 1195 | - /** |
|
| 1196 | - * Equivalent to passing 'exclude' in the constructor's options array. |
|
| 1197 | - * Removes the listed inputs from the form |
|
| 1198 | - * |
|
| 1199 | - * @param array $inputs_to_exclude values are the input names |
|
| 1200 | - * @return void |
|
| 1201 | - */ |
|
| 1202 | - public function exclude(array $inputs_to_exclude = array()) |
|
| 1203 | - { |
|
| 1204 | - foreach ($inputs_to_exclude as $input_to_exclude_name) { |
|
| 1205 | - unset($this->_subsections[ $input_to_exclude_name ]); |
|
| 1206 | - } |
|
| 1207 | - } |
|
| 1208 | - |
|
| 1209 | - |
|
| 1210 | - /** |
|
| 1211 | - * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy. |
|
| 1212 | - * @param array $inputs_to_hide |
|
| 1213 | - * @throws EE_Error |
|
| 1214 | - */ |
|
| 1215 | - public function hide(array $inputs_to_hide = array()) |
|
| 1216 | - { |
|
| 1217 | - foreach ($inputs_to_hide as $input_to_hide) { |
|
| 1218 | - $input = $this->get_input($input_to_hide); |
|
| 1219 | - $input->set_display_strategy(new EE_Hidden_Display_Strategy()); |
|
| 1220 | - } |
|
| 1221 | - } |
|
| 1222 | - |
|
| 1223 | - |
|
| 1224 | - /** |
|
| 1225 | - * add_subsections |
|
| 1226 | - * Adds the listed subsections to the form section. |
|
| 1227 | - * If $subsection_name_to_target is provided, |
|
| 1228 | - * then new subsections are added before or after that subsection, |
|
| 1229 | - * otherwise to the start or end of the entire subsections array. |
|
| 1230 | - * |
|
| 1231 | - * @param EE_Form_Section_Base[] $new_subsections array of new form subsections |
|
| 1232 | - * where keys are their names |
|
| 1233 | - * @param string $subsection_name_to_target an existing for section that $new_subsections |
|
| 1234 | - * should be added before or after |
|
| 1235 | - * IF $subsection_name_to_target is null, |
|
| 1236 | - * then $new_subsections will be added to |
|
| 1237 | - * the beginning or end of the entire subsections array |
|
| 1238 | - * @param boolean $add_before whether to add $new_subsections, before or after |
|
| 1239 | - * $subsection_name_to_target, |
|
| 1240 | - * or if $subsection_name_to_target is null, |
|
| 1241 | - * before or after entire subsections array |
|
| 1242 | - * @return void |
|
| 1243 | - * @throws EE_Error |
|
| 1244 | - */ |
|
| 1245 | - public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true) |
|
| 1246 | - { |
|
| 1247 | - foreach ($new_subsections as $subsection_name => $subsection) { |
|
| 1248 | - if (! $subsection instanceof EE_Form_Section_Base) { |
|
| 1249 | - EE_Error::add_error( |
|
| 1250 | - sprintf( |
|
| 1251 | - esc_html__( |
|
| 1252 | - "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.", |
|
| 1253 | - 'event_espresso' |
|
| 1254 | - ), |
|
| 1255 | - get_class($subsection), |
|
| 1256 | - $subsection_name, |
|
| 1257 | - $this->name() |
|
| 1258 | - ) |
|
| 1259 | - ); |
|
| 1260 | - unset($new_subsections[ $subsection_name ]); |
|
| 1261 | - } |
|
| 1262 | - } |
|
| 1263 | - $this->_subsections = EEH_Array::insert_into_array( |
|
| 1264 | - $this->_subsections, |
|
| 1265 | - $new_subsections, |
|
| 1266 | - $subsection_name_to_target, |
|
| 1267 | - $add_before |
|
| 1268 | - ); |
|
| 1269 | - if ($this->_construction_finalized) { |
|
| 1270 | - foreach ($this->_subsections as $name => $subsection) { |
|
| 1271 | - $subsection->_construct_finalize($this, $name); |
|
| 1272 | - } |
|
| 1273 | - } |
|
| 1274 | - } |
|
| 1275 | - |
|
| 1276 | - |
|
| 1277 | - /** |
|
| 1278 | - * @param string $subsection_name |
|
| 1279 | - * @param bool $recursive |
|
| 1280 | - * @return bool |
|
| 1281 | - */ |
|
| 1282 | - public function has_subsection($subsection_name, $recursive = false) |
|
| 1283 | - { |
|
| 1284 | - foreach ($this->_subsections as $name => $subsection) { |
|
| 1285 | - if ($name === $subsection_name |
|
| 1286 | - || ( |
|
| 1287 | - $recursive |
|
| 1288 | - && $subsection instanceof EE_Form_Section_Proper |
|
| 1289 | - && $subsection->has_subsection($subsection_name, $recursive) |
|
| 1290 | - ) |
|
| 1291 | - ) { |
|
| 1292 | - return true; |
|
| 1293 | - } |
|
| 1294 | - } |
|
| 1295 | - return false; |
|
| 1296 | - } |
|
| 1297 | - |
|
| 1298 | - |
|
| 1299 | - |
|
| 1300 | - /** |
|
| 1301 | - * Just gets all validatable subsections to clean their sensitive data |
|
| 1302 | - * |
|
| 1303 | - * @throws EE_Error |
|
| 1304 | - */ |
|
| 1305 | - public function clean_sensitive_data() |
|
| 1306 | - { |
|
| 1307 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1308 | - $subsection->clean_sensitive_data(); |
|
| 1309 | - } |
|
| 1310 | - } |
|
| 1311 | - |
|
| 1312 | - |
|
| 1313 | - /** |
|
| 1314 | - * Sets the submission error message (aka validation error message for this form section and all sub-sections) |
|
| 1315 | - * @param string $form_submission_error_message |
|
| 1316 | - * @param EE_Form_Section_Validatable $form_section unused |
|
| 1317 | - * @throws EE_Error |
|
| 1318 | - */ |
|
| 1319 | - public function set_submission_error_message( |
|
| 1320 | - $form_submission_error_message = '' |
|
| 1321 | - ) { |
|
| 1322 | - $this->_form_submission_error_message = ! empty($form_submission_error_message) |
|
| 1323 | - ? $form_submission_error_message |
|
| 1324 | - : $this->getAllValidationErrorsString(); |
|
| 1325 | - } |
|
| 1326 | - |
|
| 1327 | - |
|
| 1328 | - /** |
|
| 1329 | - * Returns the cached error message. A default value is set for this during _validate(), |
|
| 1330 | - * (called during receive_form_submission) but it can be explicitly set using |
|
| 1331 | - * set_submission_error_message |
|
| 1332 | - * |
|
| 1333 | - * @return string |
|
| 1334 | - */ |
|
| 1335 | - public function submission_error_message() |
|
| 1336 | - { |
|
| 1337 | - return $this->_form_submission_error_message; |
|
| 1338 | - } |
|
| 1339 | - |
|
| 1340 | - |
|
| 1341 | - /** |
|
| 1342 | - * Sets a message to display if the data submitted to the form was valid. |
|
| 1343 | - * @param string $form_submission_success_message |
|
| 1344 | - */ |
|
| 1345 | - public function set_submission_success_message($form_submission_success_message = '') |
|
| 1346 | - { |
|
| 1347 | - $this->_form_submission_success_message = ! empty($form_submission_success_message) |
|
| 1348 | - ? $form_submission_success_message |
|
| 1349 | - : esc_html__('Form submitted successfully', 'event_espresso'); |
|
| 1350 | - } |
|
| 1351 | - |
|
| 1352 | - |
|
| 1353 | - /** |
|
| 1354 | - * Gets a message appropriate for display when the form is correctly submitted |
|
| 1355 | - * @return string |
|
| 1356 | - */ |
|
| 1357 | - public function submission_success_message() |
|
| 1358 | - { |
|
| 1359 | - return $this->_form_submission_success_message; |
|
| 1360 | - } |
|
| 1361 | - |
|
| 1362 | - |
|
| 1363 | - /** |
|
| 1364 | - * Returns the prefix that should be used on child of this form section for |
|
| 1365 | - * their html names. If this form section itself has a parent, prepends ITS |
|
| 1366 | - * prefix onto this form section's prefix. Used primarily by |
|
| 1367 | - * EE_Form_Input_Base::_set_default_html_name_if_empty |
|
| 1368 | - * |
|
| 1369 | - * @return string |
|
| 1370 | - * @throws EE_Error |
|
| 1371 | - */ |
|
| 1372 | - public function html_name_prefix() |
|
| 1373 | - { |
|
| 1374 | - if ($this->parent_section() instanceof EE_Form_Section_Proper) { |
|
| 1375 | - return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']'; |
|
| 1376 | - } |
|
| 1377 | - return $this->name(); |
|
| 1378 | - } |
|
| 1379 | - |
|
| 1380 | - |
|
| 1381 | - /** |
|
| 1382 | - * Gets the name, but first checks _construct_finalize has been called. If not, |
|
| 1383 | - * calls it (assumes there is no parent and that we want the name to be whatever |
|
| 1384 | - * was set, which is probably nothing, or the classname) |
|
| 1385 | - * |
|
| 1386 | - * @return string |
|
| 1387 | - * @throws EE_Error |
|
| 1388 | - */ |
|
| 1389 | - public function name() |
|
| 1390 | - { |
|
| 1391 | - $this->ensure_construct_finalized_called(); |
|
| 1392 | - return parent::name(); |
|
| 1393 | - } |
|
| 1394 | - |
|
| 1395 | - |
|
| 1396 | - /** |
|
| 1397 | - * @return EE_Form_Section_Proper |
|
| 1398 | - * @throws EE_Error |
|
| 1399 | - */ |
|
| 1400 | - public function parent_section() |
|
| 1401 | - { |
|
| 1402 | - $this->ensure_construct_finalized_called(); |
|
| 1403 | - return parent::parent_section(); |
|
| 1404 | - } |
|
| 1405 | - |
|
| 1406 | - |
|
| 1407 | - /** |
|
| 1408 | - * make sure construction finalized was called, otherwise children might not be ready |
|
| 1409 | - * |
|
| 1410 | - * @return void |
|
| 1411 | - * @throws EE_Error |
|
| 1412 | - */ |
|
| 1413 | - public function ensure_construct_finalized_called() |
|
| 1414 | - { |
|
| 1415 | - if (! $this->_construction_finalized) { |
|
| 1416 | - $this->_construct_finalize($this->_parent_section, $this->_name); |
|
| 1417 | - } |
|
| 1418 | - } |
|
| 1419 | - |
|
| 1420 | - |
|
| 1421 | - /** |
|
| 1422 | - * Checks if any of this form section's inputs, or any of its children's inputs, |
|
| 1423 | - * are in teh form data. If any are found, returns true. Else false |
|
| 1424 | - * |
|
| 1425 | - * @param array $req_data |
|
| 1426 | - * @return boolean |
|
| 1427 | - * @throws EE_Error |
|
| 1428 | - */ |
|
| 1429 | - public function form_data_present_in($req_data = null) |
|
| 1430 | - { |
|
| 1431 | - $req_data = $this->getCachedRequest($req_data); |
|
| 1432 | - foreach ($this->subsections() as $subsection) { |
|
| 1433 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1434 | - if ($subsection->form_data_present_in($req_data)) { |
|
| 1435 | - return true; |
|
| 1436 | - } |
|
| 1437 | - } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1438 | - if ($subsection->form_data_present_in($req_data)) { |
|
| 1439 | - return true; |
|
| 1440 | - } |
|
| 1441 | - } |
|
| 1442 | - } |
|
| 1443 | - return false; |
|
| 1444 | - } |
|
| 1445 | - |
|
| 1446 | - |
|
| 1447 | - /** |
|
| 1448 | - * Gets validation errors for this form section and subsections |
|
| 1449 | - * Similar to EE_Form_Section_Validatable::get_validation_errors() except this |
|
| 1450 | - * gets the validation errors for ALL subsection |
|
| 1451 | - * |
|
| 1452 | - * @return EE_Validation_Error[] |
|
| 1453 | - * @throws EE_Error |
|
| 1454 | - */ |
|
| 1455 | - public function get_validation_errors_accumulated() |
|
| 1456 | - { |
|
| 1457 | - $validation_errors = $this->get_validation_errors(); |
|
| 1458 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1459 | - if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1460 | - $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated(); |
|
| 1461 | - } else { |
|
| 1462 | - $validation_errors_on_this_subsection = $subsection->get_validation_errors(); |
|
| 1463 | - } |
|
| 1464 | - if ($validation_errors_on_this_subsection) { |
|
| 1465 | - $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection); |
|
| 1466 | - } |
|
| 1467 | - } |
|
| 1468 | - return $validation_errors; |
|
| 1469 | - } |
|
| 1470 | - |
|
| 1471 | - /** |
|
| 1472 | - * Fetch validation errors from children and grandchildren and puts them in a single string. |
|
| 1473 | - * This traverses the form section tree to generate this, but you probably want to instead use |
|
| 1474 | - * get_form_submission_error_message() which is usually this message cached (or a custom validation error message) |
|
| 1475 | - * |
|
| 1476 | - * @return string |
|
| 1477 | - * @since 4.9.59.p |
|
| 1478 | - */ |
|
| 1479 | - protected function getAllValidationErrorsString() |
|
| 1480 | - { |
|
| 1481 | - $submission_error_messages = array(); |
|
| 1482 | - // bad, bad, bad registrant |
|
| 1483 | - foreach ($this->get_validation_errors_accumulated() as $validation_error) { |
|
| 1484 | - if ($validation_error instanceof EE_Validation_Error) { |
|
| 1485 | - $form_section = $validation_error->get_form_section(); |
|
| 1486 | - if ($form_section instanceof EE_Form_Input_Base) { |
|
| 1487 | - $label = $validation_error->get_form_section()->html_label_text(); |
|
| 1488 | - } elseif ($form_section instanceof EE_Form_Section_Validatable) { |
|
| 1489 | - $label = $validation_error->get_form_section()->name(); |
|
| 1490 | - } else { |
|
| 1491 | - $label = esc_html__('Unknown', 'event_espresso'); |
|
| 1492 | - } |
|
| 1493 | - $submission_error_messages[] = sprintf( |
|
| 1494 | - __('%s : %s', 'event_espresso'), |
|
| 1495 | - $label, |
|
| 1496 | - $validation_error->getMessage() |
|
| 1497 | - ); |
|
| 1498 | - } |
|
| 1499 | - } |
|
| 1500 | - return implode('<br>', $submission_error_messages); |
|
| 1501 | - } |
|
| 1502 | - |
|
| 1503 | - |
|
| 1504 | - /** |
|
| 1505 | - * This isn't just the name of an input, it's a path pointing to an input. The |
|
| 1506 | - * path is similar to a folder path: slash (/) means to descend into a subsection, |
|
| 1507 | - * dot-dot-slash (../) means to ascend into the parent section. |
|
| 1508 | - * After a series of slashes and dot-dot-slashes, there should be the name of an input, |
|
| 1509 | - * which will be returned. |
|
| 1510 | - * Eg, if you want the related input to be conditional on a sibling input name 'foobar' |
|
| 1511 | - * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name |
|
| 1512 | - * 'baz', use '../baz'. If you want it to be conditional on a cousin input, |
|
| 1513 | - * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'. |
|
| 1514 | - * Etc |
|
| 1515 | - * |
|
| 1516 | - * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false |
|
| 1517 | - * @return EE_Form_Section_Base |
|
| 1518 | - * @throws EE_Error |
|
| 1519 | - */ |
|
| 1520 | - public function find_section_from_path($form_section_path) |
|
| 1521 | - { |
|
| 1522 | - // check if we can find the input from purely going straight up the tree |
|
| 1523 | - $input = parent::find_section_from_path($form_section_path); |
|
| 1524 | - if ($input instanceof EE_Form_Section_Base) { |
|
| 1525 | - return $input; |
|
| 1526 | - } |
|
| 1527 | - $next_slash_pos = strpos($form_section_path, '/'); |
|
| 1528 | - if ($next_slash_pos !== false) { |
|
| 1529 | - $child_section_name = substr($form_section_path, 0, $next_slash_pos); |
|
| 1530 | - $subpath = substr($form_section_path, $next_slash_pos + 1); |
|
| 1531 | - } else { |
|
| 1532 | - $child_section_name = $form_section_path; |
|
| 1533 | - $subpath = ''; |
|
| 1534 | - } |
|
| 1535 | - $child_section = $this->get_subsection($child_section_name); |
|
| 1536 | - if ($child_section instanceof EE_Form_Section_Base) { |
|
| 1537 | - return $child_section->find_section_from_path($subpath); |
|
| 1538 | - } |
|
| 1539 | - return null; |
|
| 1540 | - } |
|
| 17 | + const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data'; |
|
| 18 | + |
|
| 19 | + /** |
|
| 20 | + * Subsections |
|
| 21 | + * |
|
| 22 | + * @var EE_Form_Section_Validatable[] |
|
| 23 | + */ |
|
| 24 | + protected $_subsections = array(); |
|
| 25 | + |
|
| 26 | + /** |
|
| 27 | + * Strategy for laying out the form |
|
| 28 | + * |
|
| 29 | + * @var EE_Form_Section_Layout_Base |
|
| 30 | + */ |
|
| 31 | + protected $_layout_strategy; |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * Whether or not this form has received and validated a form submission yet |
|
| 35 | + * |
|
| 36 | + * @var boolean |
|
| 37 | + */ |
|
| 38 | + protected $_received_submission = false; |
|
| 39 | + |
|
| 40 | + /** |
|
| 41 | + * message displayed to users upon successful form submission |
|
| 42 | + * |
|
| 43 | + * @var string |
|
| 44 | + */ |
|
| 45 | + protected $_form_submission_success_message = ''; |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * message displayed to users upon unsuccessful form submission |
|
| 49 | + * |
|
| 50 | + * @var string |
|
| 51 | + */ |
|
| 52 | + protected $_form_submission_error_message = ''; |
|
| 53 | + |
|
| 54 | + /** |
|
| 55 | + * @var array like $_REQUEST |
|
| 56 | + */ |
|
| 57 | + protected $cached_request_data; |
|
| 58 | + |
|
| 59 | + /** |
|
| 60 | + * Stores whether this form (and its sub-sections) were found to be valid or not. |
|
| 61 | + * Starts off as null, but once the form is validated, it set to either true or false |
|
| 62 | + * @var boolean|null |
|
| 63 | + */ |
|
| 64 | + protected $is_valid; |
|
| 65 | + |
|
| 66 | + /** |
|
| 67 | + * Stores all the data that will localized for form validation |
|
| 68 | + * |
|
| 69 | + * @var array |
|
| 70 | + */ |
|
| 71 | + static protected $_js_localization = array(); |
|
| 72 | + |
|
| 73 | + /** |
|
| 74 | + * whether or not the form's localized validation JS vars have been set |
|
| 75 | + * |
|
| 76 | + * @type boolean |
|
| 77 | + */ |
|
| 78 | + static protected $_scripts_localized = false; |
|
| 79 | + |
|
| 80 | + |
|
| 81 | + /** |
|
| 82 | + * when constructing a proper form section, calls _construct_finalize on children |
|
| 83 | + * so that they know who their parent is, and what name they've been given. |
|
| 84 | + * |
|
| 85 | + * @param array[] $options_array { |
|
| 86 | + * @type $subsections EE_Form_Section_Validatable[] where keys are the section's name |
|
| 87 | + * @type $include string[] numerically-indexed where values are section names to be included, |
|
| 88 | + * and in that order. This is handy if you want |
|
| 89 | + * the subsections to be ordered differently than the default, and if you override |
|
| 90 | + * which fields are shown |
|
| 91 | + * @type $exclude string[] values are subsections to be excluded. This is handy if you want |
|
| 92 | + * to remove certain default subsections (note: if you specify BOTH 'include' AND |
|
| 93 | + * 'exclude', the inclusions will be applied first, and the exclusions will exclude |
|
| 94 | + * items from that list of inclusions) |
|
| 95 | + * @type $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form |
|
| 96 | + * } @see EE_Form_Section_Validatable::__construct() |
|
| 97 | + * @throws EE_Error |
|
| 98 | + */ |
|
| 99 | + public function __construct($options_array = array()) |
|
| 100 | + { |
|
| 101 | + $options_array = (array) apply_filters( |
|
| 102 | + 'FHEE__EE_Form_Section_Proper___construct__options_array', |
|
| 103 | + $options_array, |
|
| 104 | + $this |
|
| 105 | + ); |
|
| 106 | + // call parent first, as it may be setting the name |
|
| 107 | + parent::__construct($options_array); |
|
| 108 | + // if they've included subsections in the constructor, add them now |
|
| 109 | + if (isset($options_array['include'])) { |
|
| 110 | + // we are going to make sure we ONLY have those subsections to include |
|
| 111 | + // AND we are going to make sure they're in that specified order |
|
| 112 | + $reordered_subsections = array(); |
|
| 113 | + foreach ($options_array['include'] as $input_name) { |
|
| 114 | + if (isset($this->_subsections[ $input_name ])) { |
|
| 115 | + $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ]; |
|
| 116 | + } |
|
| 117 | + } |
|
| 118 | + $this->_subsections = $reordered_subsections; |
|
| 119 | + } |
|
| 120 | + if (isset($options_array['exclude'])) { |
|
| 121 | + $exclude = $options_array['exclude']; |
|
| 122 | + $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude)); |
|
| 123 | + } |
|
| 124 | + if (isset($options_array['layout_strategy'])) { |
|
| 125 | + $this->_layout_strategy = $options_array['layout_strategy']; |
|
| 126 | + } |
|
| 127 | + if (! $this->_layout_strategy) { |
|
| 128 | + $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout(); |
|
| 129 | + } |
|
| 130 | + $this->_layout_strategy->_construct_finalize($this); |
|
| 131 | + // ok so we are definitely going to want the forms JS, |
|
| 132 | + // so enqueue it or remember to enqueue it during wp_enqueue_scripts |
|
| 133 | + if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) { |
|
| 134 | + // ok so they've constructed this object after when they should have. |
|
| 135 | + // just enqueue the generic form scripts and initialize the form immediately in the JS |
|
| 136 | + EE_Form_Section_Proper::wp_enqueue_scripts(true); |
|
| 137 | + } else { |
|
| 138 | + add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 139 | + add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 140 | + } |
|
| 141 | + add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1); |
|
| 142 | + /** |
|
| 143 | + * Gives other plugins a chance to hook in before construct finalize is called. |
|
| 144 | + * The form probably doesn't yet have a parent form section. |
|
| 145 | + * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form, |
|
| 146 | + * assuming you don't care what the form section's name, HTML ID, or HTML name etc are. |
|
| 147 | + * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end |
|
| 148 | + * |
|
| 149 | + * @since 4.9.32 |
|
| 150 | + * @param EE_Form_Section_Proper $this before __construct is done, but all of its logic, |
|
| 151 | + * except maybe calling _construct_finalize has been done |
|
| 152 | + * @param array $options_array options passed into the constructor |
|
| 153 | + */ |
|
| 154 | + do_action( |
|
| 155 | + 'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called', |
|
| 156 | + $this, |
|
| 157 | + $options_array |
|
| 158 | + ); |
|
| 159 | + if (isset($options_array['name'])) { |
|
| 160 | + $this->_construct_finalize(null, $options_array['name']); |
|
| 161 | + } |
|
| 162 | + } |
|
| 163 | + |
|
| 164 | + |
|
| 165 | + /** |
|
| 166 | + * Finishes construction given the parent form section and this form section's name |
|
| 167 | + * |
|
| 168 | + * @param EE_Form_Section_Proper $parent_form_section |
|
| 169 | + * @param string $name |
|
| 170 | + * @throws EE_Error |
|
| 171 | + */ |
|
| 172 | + public function _construct_finalize($parent_form_section, $name) |
|
| 173 | + { |
|
| 174 | + parent::_construct_finalize($parent_form_section, $name); |
|
| 175 | + $this->_set_default_name_if_empty(); |
|
| 176 | + $this->_set_default_html_id_if_empty(); |
|
| 177 | + foreach ($this->_subsections as $subsection_name => $subsection) { |
|
| 178 | + if ($subsection instanceof EE_Form_Section_Base) { |
|
| 179 | + $subsection->_construct_finalize($this, $subsection_name); |
|
| 180 | + } else { |
|
| 181 | + throw new EE_Error( |
|
| 182 | + sprintf( |
|
| 183 | + esc_html__( |
|
| 184 | + 'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"', |
|
| 185 | + 'event_espresso' |
|
| 186 | + ), |
|
| 187 | + $subsection_name, |
|
| 188 | + get_class($this), |
|
| 189 | + $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 190 | + ) |
|
| 191 | + ); |
|
| 192 | + } |
|
| 193 | + } |
|
| 194 | + /** |
|
| 195 | + * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed. |
|
| 196 | + * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID |
|
| 197 | + * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done. |
|
| 198 | + * This might only happen just before displaying the form, or just before it receives form submission data. |
|
| 199 | + * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've |
|
| 200 | + * ensured it has a name, HTML IDs, etc |
|
| 201 | + * |
|
| 202 | + * @param EE_Form_Section_Proper $this |
|
| 203 | + * @param EE_Form_Section_Proper|null $parent_form_section |
|
| 204 | + * @param string $name |
|
| 205 | + */ |
|
| 206 | + do_action( |
|
| 207 | + 'AHEE__EE_Form_Section_Proper___construct_finalize__end', |
|
| 208 | + $this, |
|
| 209 | + $parent_form_section, |
|
| 210 | + $name |
|
| 211 | + ); |
|
| 212 | + } |
|
| 213 | + |
|
| 214 | + |
|
| 215 | + /** |
|
| 216 | + * Gets the layout strategy for this form section |
|
| 217 | + * |
|
| 218 | + * @return EE_Form_Section_Layout_Base |
|
| 219 | + */ |
|
| 220 | + public function get_layout_strategy() |
|
| 221 | + { |
|
| 222 | + return $this->_layout_strategy; |
|
| 223 | + } |
|
| 224 | + |
|
| 225 | + |
|
| 226 | + /** |
|
| 227 | + * Gets the HTML for a single input for this form section according |
|
| 228 | + * to the layout strategy |
|
| 229 | + * |
|
| 230 | + * @param EE_Form_Input_Base $input |
|
| 231 | + * @return string |
|
| 232 | + */ |
|
| 233 | + public function get_html_for_input($input) |
|
| 234 | + { |
|
| 235 | + return $this->_layout_strategy->layout_input($input); |
|
| 236 | + } |
|
| 237 | + |
|
| 238 | + |
|
| 239 | + /** |
|
| 240 | + * was_submitted - checks if form inputs are present in request data |
|
| 241 | + * Basically an alias for form_data_present_in() (which is used by both |
|
| 242 | + * proper form sections and form inputs) |
|
| 243 | + * |
|
| 244 | + * @param null $form_data |
|
| 245 | + * @return boolean |
|
| 246 | + * @throws EE_Error |
|
| 247 | + */ |
|
| 248 | + public function was_submitted($form_data = null) |
|
| 249 | + { |
|
| 250 | + return $this->form_data_present_in($form_data); |
|
| 251 | + } |
|
| 252 | + |
|
| 253 | + /** |
|
| 254 | + * Gets the cached request data; but if there is none, or $req_data was set with |
|
| 255 | + * something different, refresh the cache, and then return it |
|
| 256 | + * @param null $req_data |
|
| 257 | + * @return array |
|
| 258 | + */ |
|
| 259 | + protected function getCachedRequest($req_data = null) |
|
| 260 | + { |
|
| 261 | + if ($this->cached_request_data === null |
|
| 262 | + || ( |
|
| 263 | + $req_data !== null && |
|
| 264 | + $req_data !== $this->cached_request_data |
|
| 265 | + ) |
|
| 266 | + ) { |
|
| 267 | + $req_data = apply_filters( |
|
| 268 | + 'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data', |
|
| 269 | + $req_data, |
|
| 270 | + $this |
|
| 271 | + ); |
|
| 272 | + if ($req_data === null) { |
|
| 273 | + $req_data = array_merge($_GET, $_POST); |
|
| 274 | + } |
|
| 275 | + $req_data = apply_filters( |
|
| 276 | + 'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data', |
|
| 277 | + $req_data, |
|
| 278 | + $this |
|
| 279 | + ); |
|
| 280 | + $this->cached_request_data = (array) $req_data; |
|
| 281 | + } |
|
| 282 | + return $this->cached_request_data; |
|
| 283 | + } |
|
| 284 | + |
|
| 285 | + |
|
| 286 | + /** |
|
| 287 | + * After the form section is initially created, call this to sanitize the data in the submission |
|
| 288 | + * which relates to this form section, validate it, and set it as properties on the form. |
|
| 289 | + * |
|
| 290 | + * @param array|null $req_data should usually be $_POST (the default). |
|
| 291 | + * However, you CAN supply a different array. |
|
| 292 | + * Consider using set_defaults() instead however. |
|
| 293 | + * (If you rendered the form in the page using echo $form_x->get_html() |
|
| 294 | + * the inputs will have the correct name in the request data for this function |
|
| 295 | + * to find them and populate the form with them. |
|
| 296 | + * If you have a flat form (with only input subsections), |
|
| 297 | + * you can supply a flat array where keys |
|
| 298 | + * are the form input names and values are their values) |
|
| 299 | + * @param boolean $validate whether or not to perform validation on this data. Default is, |
|
| 300 | + * of course, to validate that data, and set errors on the invalid values. |
|
| 301 | + * But if the data has already been validated |
|
| 302 | + * (eg you validated the data then stored it in the DB) |
|
| 303 | + * you may want to skip this step. |
|
| 304 | + * @throws InvalidArgumentException |
|
| 305 | + * @throws InvalidInterfaceException |
|
| 306 | + * @throws InvalidDataTypeException |
|
| 307 | + * @throws EE_Error |
|
| 308 | + */ |
|
| 309 | + public function receive_form_submission($req_data = null, $validate = true) |
|
| 310 | + { |
|
| 311 | + $req_data = $this->getCachedRequest($req_data); |
|
| 312 | + $this->_normalize($req_data); |
|
| 313 | + if ($validate) { |
|
| 314 | + $this->_validate(); |
|
| 315 | + // if it's invalid, we're going to want to re-display so remember what they submitted |
|
| 316 | + if (! $this->is_valid()) { |
|
| 317 | + $this->store_submitted_form_data_in_session(); |
|
| 318 | + } |
|
| 319 | + } |
|
| 320 | + if ($this->submission_error_message() === '' && ! $this->is_valid()) { |
|
| 321 | + $this->set_submission_error_message(); |
|
| 322 | + } |
|
| 323 | + do_action( |
|
| 324 | + 'AHEE__EE_Form_Section_Proper__receive_form_submission__end', |
|
| 325 | + $req_data, |
|
| 326 | + $this, |
|
| 327 | + $validate |
|
| 328 | + ); |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + |
|
| 332 | + /** |
|
| 333 | + * caches the originally submitted input values in the session |
|
| 334 | + * so that they can be used to repopulate the form if it failed validation |
|
| 335 | + * |
|
| 336 | + * @return boolean whether or not the data was successfully stored in the session |
|
| 337 | + * @throws InvalidArgumentException |
|
| 338 | + * @throws InvalidInterfaceException |
|
| 339 | + * @throws InvalidDataTypeException |
|
| 340 | + * @throws EE_Error |
|
| 341 | + */ |
|
| 342 | + protected function store_submitted_form_data_in_session() |
|
| 343 | + { |
|
| 344 | + return EE_Registry::instance()->SSN->set_session_data( |
|
| 345 | + array( |
|
| 346 | + EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true), |
|
| 347 | + ) |
|
| 348 | + ); |
|
| 349 | + } |
|
| 350 | + |
|
| 351 | + |
|
| 352 | + /** |
|
| 353 | + * retrieves the originally submitted input values in the session |
|
| 354 | + * so that they can be used to repopulate the form if it failed validation |
|
| 355 | + * |
|
| 356 | + * @return array |
|
| 357 | + * @throws InvalidArgumentException |
|
| 358 | + * @throws InvalidInterfaceException |
|
| 359 | + * @throws InvalidDataTypeException |
|
| 360 | + */ |
|
| 361 | + protected function get_submitted_form_data_from_session() |
|
| 362 | + { |
|
| 363 | + $session = EE_Registry::instance()->SSN; |
|
| 364 | + if ($session instanceof EE_Session) { |
|
| 365 | + return $session->get_session_data( |
|
| 366 | + EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY |
|
| 367 | + ); |
|
| 368 | + } |
|
| 369 | + return array(); |
|
| 370 | + } |
|
| 371 | + |
|
| 372 | + |
|
| 373 | + /** |
|
| 374 | + * flushed the originally submitted input values from the session |
|
| 375 | + * |
|
| 376 | + * @return boolean whether or not the data was successfully removed from the session |
|
| 377 | + * @throws InvalidArgumentException |
|
| 378 | + * @throws InvalidInterfaceException |
|
| 379 | + * @throws InvalidDataTypeException |
|
| 380 | + */ |
|
| 381 | + public static function flush_submitted_form_data_from_session() |
|
| 382 | + { |
|
| 383 | + return EE_Registry::instance()->SSN->reset_data( |
|
| 384 | + array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY) |
|
| 385 | + ); |
|
| 386 | + } |
|
| 387 | + |
|
| 388 | + |
|
| 389 | + /** |
|
| 390 | + * Populates this form and its subsections with data from the session. |
|
| 391 | + * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows |
|
| 392 | + * validation errors when displaying too) |
|
| 393 | + * Returns true if the form was populated from the session, false otherwise |
|
| 394 | + * |
|
| 395 | + * @return boolean |
|
| 396 | + * @throws InvalidArgumentException |
|
| 397 | + * @throws InvalidInterfaceException |
|
| 398 | + * @throws InvalidDataTypeException |
|
| 399 | + * @throws EE_Error |
|
| 400 | + */ |
|
| 401 | + public function populate_from_session() |
|
| 402 | + { |
|
| 403 | + $form_data_in_session = $this->get_submitted_form_data_from_session(); |
|
| 404 | + if (empty($form_data_in_session)) { |
|
| 405 | + return false; |
|
| 406 | + } |
|
| 407 | + $this->receive_form_submission($form_data_in_session); |
|
| 408 | + add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session')); |
|
| 409 | + if ($this->form_data_present_in($form_data_in_session)) { |
|
| 410 | + return true; |
|
| 411 | + } |
|
| 412 | + return false; |
|
| 413 | + } |
|
| 414 | + |
|
| 415 | + |
|
| 416 | + /** |
|
| 417 | + * Populates the default data for the form, given an array where keys are |
|
| 418 | + * the input names, and values are their values (preferably normalized to be their |
|
| 419 | + * proper PHP types, not all strings... although that should be ok too). |
|
| 420 | + * Proper subsections are sub-arrays, the key being the subsection's name, and |
|
| 421 | + * the value being an array formatted in teh same way |
|
| 422 | + * |
|
| 423 | + * @param array $default_data |
|
| 424 | + * @throws EE_Error |
|
| 425 | + */ |
|
| 426 | + public function populate_defaults($default_data) |
|
| 427 | + { |
|
| 428 | + foreach ($this->subsections(false) as $subsection_name => $subsection) { |
|
| 429 | + if (isset($default_data[ $subsection_name ])) { |
|
| 430 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 431 | + $subsection->set_default($default_data[ $subsection_name ]); |
|
| 432 | + } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 433 | + $subsection->populate_defaults($default_data[ $subsection_name ]); |
|
| 434 | + } |
|
| 435 | + } |
|
| 436 | + } |
|
| 437 | + } |
|
| 438 | + |
|
| 439 | + |
|
| 440 | + /** |
|
| 441 | + * returns true if subsection exists |
|
| 442 | + * |
|
| 443 | + * @param string $name |
|
| 444 | + * @return boolean |
|
| 445 | + */ |
|
| 446 | + public function subsection_exists($name) |
|
| 447 | + { |
|
| 448 | + return isset($this->_subsections[ $name ]) ? true : false; |
|
| 449 | + } |
|
| 450 | + |
|
| 451 | + |
|
| 452 | + /** |
|
| 453 | + * Gets the subsection specified by its name |
|
| 454 | + * |
|
| 455 | + * @param string $name |
|
| 456 | + * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE |
|
| 457 | + * so that the inputs will be properly configured. |
|
| 458 | + * However, some client code may be ok |
|
| 459 | + * with construction finalize being called later |
|
| 460 | + * (realizing that the subsections' html names |
|
| 461 | + * might not be set yet, etc.) |
|
| 462 | + * @return EE_Form_Section_Base |
|
| 463 | + * @throws EE_Error |
|
| 464 | + */ |
|
| 465 | + public function get_subsection($name, $require_construction_to_be_finalized = true) |
|
| 466 | + { |
|
| 467 | + if ($require_construction_to_be_finalized) { |
|
| 468 | + $this->ensure_construct_finalized_called(); |
|
| 469 | + } |
|
| 470 | + return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null; |
|
| 471 | + } |
|
| 472 | + |
|
| 473 | + |
|
| 474 | + /** |
|
| 475 | + * Gets all the validatable subsections of this form section |
|
| 476 | + * |
|
| 477 | + * @return EE_Form_Section_Validatable[] |
|
| 478 | + * @throws EE_Error |
|
| 479 | + */ |
|
| 480 | + public function get_validatable_subsections() |
|
| 481 | + { |
|
| 482 | + $validatable_subsections = array(); |
|
| 483 | + foreach ($this->subsections() as $name => $obj) { |
|
| 484 | + if ($obj instanceof EE_Form_Section_Validatable) { |
|
| 485 | + $validatable_subsections[ $name ] = $obj; |
|
| 486 | + } |
|
| 487 | + } |
|
| 488 | + return $validatable_subsections; |
|
| 489 | + } |
|
| 490 | + |
|
| 491 | + |
|
| 492 | + /** |
|
| 493 | + * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child, |
|
| 494 | + * throw an EE_Error. |
|
| 495 | + * |
|
| 496 | + * @param string $name |
|
| 497 | + * @param boolean $require_construction_to_be_finalized most client code should |
|
| 498 | + * leave this as TRUE so that the inputs will be properly |
|
| 499 | + * configured. However, some client code may be ok with |
|
| 500 | + * construction finalize being called later |
|
| 501 | + * (realizing that the subsections' html names might not be |
|
| 502 | + * set yet, etc.) |
|
| 503 | + * @return EE_Form_Input_Base |
|
| 504 | + * @throws EE_Error |
|
| 505 | + */ |
|
| 506 | + public function get_input($name, $require_construction_to_be_finalized = true) |
|
| 507 | + { |
|
| 508 | + $subsection = $this->get_subsection( |
|
| 509 | + $name, |
|
| 510 | + $require_construction_to_be_finalized |
|
| 511 | + ); |
|
| 512 | + if (! $subsection instanceof EE_Form_Input_Base) { |
|
| 513 | + throw new EE_Error( |
|
| 514 | + sprintf( |
|
| 515 | + esc_html__( |
|
| 516 | + "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'", |
|
| 517 | + 'event_espresso' |
|
| 518 | + ), |
|
| 519 | + $name, |
|
| 520 | + get_class($this), |
|
| 521 | + $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 522 | + ) |
|
| 523 | + ); |
|
| 524 | + } |
|
| 525 | + return $subsection; |
|
| 526 | + } |
|
| 527 | + |
|
| 528 | + |
|
| 529 | + /** |
|
| 530 | + * Like get_input(), gets the proper subsection of the form given the name, |
|
| 531 | + * otherwise throws an EE_Error |
|
| 532 | + * |
|
| 533 | + * @param string $name |
|
| 534 | + * @param boolean $require_construction_to_be_finalized most client code should |
|
| 535 | + * leave this as TRUE so that the inputs will be properly |
|
| 536 | + * configured. However, some client code may be ok with |
|
| 537 | + * construction finalize being called later |
|
| 538 | + * (realizing that the subsections' html names might not be |
|
| 539 | + * set yet, etc.) |
|
| 540 | + * @return EE_Form_Section_Proper |
|
| 541 | + * @throws EE_Error |
|
| 542 | + */ |
|
| 543 | + public function get_proper_subsection($name, $require_construction_to_be_finalized = true) |
|
| 544 | + { |
|
| 545 | + $subsection = $this->get_subsection( |
|
| 546 | + $name, |
|
| 547 | + $require_construction_to_be_finalized |
|
| 548 | + ); |
|
| 549 | + if (! $subsection instanceof EE_Form_Section_Proper) { |
|
| 550 | + throw new EE_Error( |
|
| 551 | + sprintf( |
|
| 552 | + esc_html__( |
|
| 553 | + "Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'", |
|
| 554 | + 'event_espresso' |
|
| 555 | + ), |
|
| 556 | + $name, |
|
| 557 | + get_class($this) |
|
| 558 | + ) |
|
| 559 | + ); |
|
| 560 | + } |
|
| 561 | + return $subsection; |
|
| 562 | + } |
|
| 563 | + |
|
| 564 | + |
|
| 565 | + /** |
|
| 566 | + * Gets the value of the specified input. Should be called after receive_form_submission() |
|
| 567 | + * or populate_defaults() on the form, where the normalized value on the input is set. |
|
| 568 | + * |
|
| 569 | + * @param string $name |
|
| 570 | + * @return mixed depending on the input's type and its normalization strategy |
|
| 571 | + * @throws EE_Error |
|
| 572 | + */ |
|
| 573 | + public function get_input_value($name) |
|
| 574 | + { |
|
| 575 | + $input = $this->get_input($name); |
|
| 576 | + return $input->normalized_value(); |
|
| 577 | + } |
|
| 578 | + |
|
| 579 | + |
|
| 580 | + /** |
|
| 581 | + * Checks if this form section itself is valid, and then checks its subsections |
|
| 582 | + * |
|
| 583 | + * @throws EE_Error |
|
| 584 | + * @return boolean |
|
| 585 | + */ |
|
| 586 | + public function is_valid() |
|
| 587 | + { |
|
| 588 | + if ($this->is_valid === null) { |
|
| 589 | + if (! $this->has_received_submission()) { |
|
| 590 | + throw new EE_Error( |
|
| 591 | + sprintf( |
|
| 592 | + esc_html__( |
|
| 593 | + 'You cannot check if a form is valid before receiving the form submission using receive_form_submission', |
|
| 594 | + 'event_espresso' |
|
| 595 | + ) |
|
| 596 | + ) |
|
| 597 | + ); |
|
| 598 | + } |
|
| 599 | + if (! parent::is_valid()) { |
|
| 600 | + $this->is_valid = false; |
|
| 601 | + } else { |
|
| 602 | + // ok so no general errors to this entire form section. |
|
| 603 | + // so let's check the subsections, but only set errors if that hasn't been done yet |
|
| 604 | + $this->is_valid = true; |
|
| 605 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 606 | + if (! $subsection->is_valid()) { |
|
| 607 | + $this->is_valid = false; |
|
| 608 | + } |
|
| 609 | + } |
|
| 610 | + } |
|
| 611 | + } |
|
| 612 | + return $this->is_valid; |
|
| 613 | + } |
|
| 614 | + |
|
| 615 | + |
|
| 616 | + /** |
|
| 617 | + * gets the default name of this form section if none is specified |
|
| 618 | + * |
|
| 619 | + * @return void |
|
| 620 | + */ |
|
| 621 | + protected function _set_default_name_if_empty() |
|
| 622 | + { |
|
| 623 | + if (! $this->_name) { |
|
| 624 | + $classname = get_class($this); |
|
| 625 | + $default_name = str_replace('EE_', '', $classname); |
|
| 626 | + $this->_name = $default_name; |
|
| 627 | + } |
|
| 628 | + } |
|
| 629 | + |
|
| 630 | + |
|
| 631 | + /** |
|
| 632 | + * Returns the HTML for the form, except for the form opening and closing tags |
|
| 633 | + * (as the form section doesn't know where you necessarily want to send the information to), |
|
| 634 | + * and except for a submit button. Enqueues JS and CSS; if called early enough we will |
|
| 635 | + * try to enqueue them in the header, otherwise they'll be enqueued in the footer. |
|
| 636 | + * Not doing_it_wrong because theoretically this CAN be used properly, |
|
| 637 | + * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue |
|
| 638 | + * any CSS. |
|
| 639 | + * |
|
| 640 | + * @throws InvalidArgumentException |
|
| 641 | + * @throws InvalidInterfaceException |
|
| 642 | + * @throws InvalidDataTypeException |
|
| 643 | + * @throws EE_Error |
|
| 644 | + */ |
|
| 645 | + public function get_html_and_js() |
|
| 646 | + { |
|
| 647 | + $this->enqueue_js(); |
|
| 648 | + return $this->get_html(); |
|
| 649 | + } |
|
| 650 | + |
|
| 651 | + |
|
| 652 | + /** |
|
| 653 | + * returns HTML for displaying this form section. recursively calls display_section() on all subsections |
|
| 654 | + * |
|
| 655 | + * @param bool $display_previously_submitted_data |
|
| 656 | + * @return string |
|
| 657 | + * @throws InvalidArgumentException |
|
| 658 | + * @throws InvalidInterfaceException |
|
| 659 | + * @throws InvalidDataTypeException |
|
| 660 | + * @throws EE_Error |
|
| 661 | + * @throws EE_Error |
|
| 662 | + * @throws EE_Error |
|
| 663 | + */ |
|
| 664 | + public function get_html($display_previously_submitted_data = true) |
|
| 665 | + { |
|
| 666 | + $this->ensure_construct_finalized_called(); |
|
| 667 | + if ($display_previously_submitted_data) { |
|
| 668 | + $this->populate_from_session(); |
|
| 669 | + } |
|
| 670 | + return $this->_form_html_filter |
|
| 671 | + ? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this) |
|
| 672 | + : $this->_layout_strategy->layout_form(); |
|
| 673 | + } |
|
| 674 | + |
|
| 675 | + |
|
| 676 | + /** |
|
| 677 | + * enqueues JS and CSS for the form. |
|
| 678 | + * It is preferred to call this before wp_enqueue_scripts so the |
|
| 679 | + * scripts and styles can be put in the header, but if called later |
|
| 680 | + * they will be put in the footer (which is OK for JS, but in HTML4 CSS should |
|
| 681 | + * only be in the header; but in HTML5 its ok in the body. |
|
| 682 | + * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag. |
|
| 683 | + * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.) |
|
| 684 | + * |
|
| 685 | + * @return void |
|
| 686 | + * @throws EE_Error |
|
| 687 | + */ |
|
| 688 | + public function enqueue_js() |
|
| 689 | + { |
|
| 690 | + $this->_enqueue_and_localize_form_js(); |
|
| 691 | + foreach ($this->subsections() as $subsection) { |
|
| 692 | + $subsection->enqueue_js(); |
|
| 693 | + } |
|
| 694 | + } |
|
| 695 | + |
|
| 696 | + |
|
| 697 | + /** |
|
| 698 | + * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts(). |
|
| 699 | + * This must be done BEFORE wp_enqueue_scripts() gets called, which is on |
|
| 700 | + * the wp_enqueue_scripts hook. |
|
| 701 | + * However, registering the form js and localizing it can happen when we |
|
| 702 | + * actually output the form (which is preferred, seeing how teh form's fields |
|
| 703 | + * could change until it's actually outputted) |
|
| 704 | + * |
|
| 705 | + * @param boolean $init_form_validation_automatically whether or not we want the form validation |
|
| 706 | + * to be triggered automatically or not |
|
| 707 | + * @return void |
|
| 708 | + */ |
|
| 709 | + public static function wp_enqueue_scripts($init_form_validation_automatically = true) |
|
| 710 | + { |
|
| 711 | + wp_register_script( |
|
| 712 | + 'ee_form_section_validation', |
|
| 713 | + EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js', |
|
| 714 | + array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'), |
|
| 715 | + EVENT_ESPRESSO_VERSION, |
|
| 716 | + true |
|
| 717 | + ); |
|
| 718 | + wp_localize_script( |
|
| 719 | + 'ee_form_section_validation', |
|
| 720 | + 'ee_form_section_validation_init', |
|
| 721 | + array('init' => $init_form_validation_automatically ? '1' : '0') |
|
| 722 | + ); |
|
| 723 | + } |
|
| 724 | + |
|
| 725 | + |
|
| 726 | + /** |
|
| 727 | + * gets the variables used by form_section_validation.js. |
|
| 728 | + * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script, |
|
| 729 | + * but before the wordpress hook wp_loaded |
|
| 730 | + * |
|
| 731 | + * @throws EE_Error |
|
| 732 | + */ |
|
| 733 | + public function _enqueue_and_localize_form_js() |
|
| 734 | + { |
|
| 735 | + $this->ensure_construct_finalized_called(); |
|
| 736 | + // actually, we don't want to localize just yet. There may be other forms on the page. |
|
| 737 | + // so we need to add our form section data to a static variable accessible by all form sections |
|
| 738 | + // and localize it just before the footer |
|
| 739 | + $this->localize_validation_rules(); |
|
| 740 | + add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2); |
|
| 741 | + add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms')); |
|
| 742 | + } |
|
| 743 | + |
|
| 744 | + |
|
| 745 | + /** |
|
| 746 | + * add our form section data to a static variable accessible by all form sections |
|
| 747 | + * |
|
| 748 | + * @param bool $return_for_subsection |
|
| 749 | + * @return void |
|
| 750 | + * @throws EE_Error |
|
| 751 | + */ |
|
| 752 | + public function localize_validation_rules($return_for_subsection = false) |
|
| 753 | + { |
|
| 754 | + // we only want to localize vars ONCE for the entire form, |
|
| 755 | + // so if the form section doesn't have a parent, then it must be the top dog |
|
| 756 | + if ($return_for_subsection || ! $this->parent_section()) { |
|
| 757 | + EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array( |
|
| 758 | + 'form_section_id' => $this->html_id(true), |
|
| 759 | + 'validation_rules' => $this->get_jquery_validation_rules(), |
|
| 760 | + 'other_data' => $this->get_other_js_data(), |
|
| 761 | + 'errors' => $this->subsection_validation_errors_by_html_name(), |
|
| 762 | + ); |
|
| 763 | + EE_Form_Section_Proper::$_scripts_localized = true; |
|
| 764 | + } |
|
| 765 | + } |
|
| 766 | + |
|
| 767 | + |
|
| 768 | + /** |
|
| 769 | + * Gets an array of extra data that will be useful for client-side javascript. |
|
| 770 | + * This is primarily data added by inputs and forms in addition to any |
|
| 771 | + * scripts they might enqueue |
|
| 772 | + * |
|
| 773 | + * @param array $form_other_js_data |
|
| 774 | + * @return array |
|
| 775 | + * @throws EE_Error |
|
| 776 | + */ |
|
| 777 | + public function get_other_js_data($form_other_js_data = array()) |
|
| 778 | + { |
|
| 779 | + foreach ($this->subsections() as $subsection) { |
|
| 780 | + $form_other_js_data = $subsection->get_other_js_data($form_other_js_data); |
|
| 781 | + } |
|
| 782 | + return $form_other_js_data; |
|
| 783 | + } |
|
| 784 | + |
|
| 785 | + |
|
| 786 | + /** |
|
| 787 | + * Gets a flat array of inputs for this form section and its subsections. |
|
| 788 | + * Keys are their form names, and values are the inputs themselves |
|
| 789 | + * |
|
| 790 | + * @return EE_Form_Input_Base |
|
| 791 | + * @throws EE_Error |
|
| 792 | + */ |
|
| 793 | + public function inputs_in_subsections() |
|
| 794 | + { |
|
| 795 | + $inputs = array(); |
|
| 796 | + foreach ($this->subsections() as $subsection) { |
|
| 797 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 798 | + $inputs[ $subsection->html_name() ] = $subsection; |
|
| 799 | + } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 800 | + $inputs += $subsection->inputs_in_subsections(); |
|
| 801 | + } |
|
| 802 | + } |
|
| 803 | + return $inputs; |
|
| 804 | + } |
|
| 805 | + |
|
| 806 | + |
|
| 807 | + /** |
|
| 808 | + * Gets a flat array of all the validation errors. |
|
| 809 | + * Keys are html names (because those should be unique) |
|
| 810 | + * and values are a string of all their validation errors |
|
| 811 | + * |
|
| 812 | + * @return string[] |
|
| 813 | + * @throws EE_Error |
|
| 814 | + */ |
|
| 815 | + public function subsection_validation_errors_by_html_name() |
|
| 816 | + { |
|
| 817 | + $inputs = $this->inputs(); |
|
| 818 | + $errors = array(); |
|
| 819 | + foreach ($inputs as $form_input) { |
|
| 820 | + if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) { |
|
| 821 | + $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string(); |
|
| 822 | + } |
|
| 823 | + } |
|
| 824 | + return $errors; |
|
| 825 | + } |
|
| 826 | + |
|
| 827 | + |
|
| 828 | + /** |
|
| 829 | + * passes all the form data required by the JS to the JS, and enqueues the few required JS files. |
|
| 830 | + * Should be setup by each form during the _enqueues_and_localize_form_js |
|
| 831 | + * |
|
| 832 | + * @throws InvalidArgumentException |
|
| 833 | + * @throws InvalidInterfaceException |
|
| 834 | + * @throws InvalidDataTypeException |
|
| 835 | + */ |
|
| 836 | + public static function localize_script_for_all_forms() |
|
| 837 | + { |
|
| 838 | + // allow inputs and stuff to hook in their JS and stuff here |
|
| 839 | + do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin'); |
|
| 840 | + EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages(); |
|
| 841 | + $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level) |
|
| 842 | + ? EE_Registry::instance()->CFG->registration->email_validation_level |
|
| 843 | + : 'wp_default'; |
|
| 844 | + EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level; |
|
| 845 | + wp_enqueue_script('ee_form_section_validation'); |
|
| 846 | + wp_localize_script( |
|
| 847 | + 'ee_form_section_validation', |
|
| 848 | + 'ee_form_section_vars', |
|
| 849 | + EE_Form_Section_Proper::$_js_localization |
|
| 850 | + ); |
|
| 851 | + } |
|
| 852 | + |
|
| 853 | + |
|
| 854 | + /** |
|
| 855 | + * ensure_scripts_localized |
|
| 856 | + * |
|
| 857 | + * @throws EE_Error |
|
| 858 | + */ |
|
| 859 | + public function ensure_scripts_localized() |
|
| 860 | + { |
|
| 861 | + if (! EE_Form_Section_Proper::$_scripts_localized) { |
|
| 862 | + $this->_enqueue_and_localize_form_js(); |
|
| 863 | + } |
|
| 864 | + } |
|
| 865 | + |
|
| 866 | + |
|
| 867 | + /** |
|
| 868 | + * Gets the hard-coded validation error messages to be used in the JS. The convention |
|
| 869 | + * is that the key here should be the same as the custom validation rule put in the JS file |
|
| 870 | + * |
|
| 871 | + * @return array keys are custom validation rules, and values are internationalized strings |
|
| 872 | + */ |
|
| 873 | + private static function _get_localized_error_messages() |
|
| 874 | + { |
|
| 875 | + return array( |
|
| 876 | + 'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'), |
|
| 877 | + 'regex' => esc_html__('Please check your input', 'event_espresso'), |
|
| 878 | + ); |
|
| 879 | + } |
|
| 880 | + |
|
| 881 | + |
|
| 882 | + /** |
|
| 883 | + * @return array |
|
| 884 | + */ |
|
| 885 | + public static function js_localization() |
|
| 886 | + { |
|
| 887 | + return self::$_js_localization; |
|
| 888 | + } |
|
| 889 | + |
|
| 890 | + |
|
| 891 | + /** |
|
| 892 | + * @return void |
|
| 893 | + */ |
|
| 894 | + public static function reset_js_localization() |
|
| 895 | + { |
|
| 896 | + self::$_js_localization = array(); |
|
| 897 | + } |
|
| 898 | + |
|
| 899 | + |
|
| 900 | + /** |
|
| 901 | + * Gets the JS to put inside the jquery validation rules for subsection of this form section. |
|
| 902 | + * See parent function for more... |
|
| 903 | + * |
|
| 904 | + * @return array |
|
| 905 | + * @throws EE_Error |
|
| 906 | + */ |
|
| 907 | + public function get_jquery_validation_rules() |
|
| 908 | + { |
|
| 909 | + $jquery_validation_rules = array(); |
|
| 910 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 911 | + $jquery_validation_rules = array_merge( |
|
| 912 | + $jquery_validation_rules, |
|
| 913 | + $subsection->get_jquery_validation_rules() |
|
| 914 | + ); |
|
| 915 | + } |
|
| 916 | + return $jquery_validation_rules; |
|
| 917 | + } |
|
| 918 | + |
|
| 919 | + |
|
| 920 | + /** |
|
| 921 | + * Sanitizes all the data and sets the sanitized value of each field |
|
| 922 | + * |
|
| 923 | + * @param array $req_data like $_POST |
|
| 924 | + * @return void |
|
| 925 | + * @throws EE_Error |
|
| 926 | + */ |
|
| 927 | + protected function _normalize($req_data) |
|
| 928 | + { |
|
| 929 | + $this->_received_submission = true; |
|
| 930 | + $this->_validation_errors = array(); |
|
| 931 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 932 | + try { |
|
| 933 | + $subsection->_normalize($req_data); |
|
| 934 | + } catch (EE_Validation_Error $e) { |
|
| 935 | + $subsection->add_validation_error($e); |
|
| 936 | + } |
|
| 937 | + } |
|
| 938 | + } |
|
| 939 | + |
|
| 940 | + |
|
| 941 | + /** |
|
| 942 | + * Performs validation on this form section and its subsections. |
|
| 943 | + * For each subsection, |
|
| 944 | + * calls _validate_{subsection_name} on THIS form (if the function exists) |
|
| 945 | + * and passes it the subsection, then calls _validate on that subsection. |
|
| 946 | + * If you need to perform validation on the form as a whole (considering multiple) |
|
| 947 | + * you would be best to override this _validate method, |
|
| 948 | + * calling parent::_validate() first. |
|
| 949 | + * |
|
| 950 | + * @throws EE_Error |
|
| 951 | + */ |
|
| 952 | + protected function _validate() |
|
| 953 | + { |
|
| 954 | + // reset the cache of whether this form is valid or not- we're re-validating it now |
|
| 955 | + $this->is_valid = null; |
|
| 956 | + foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) { |
|
| 957 | + if (method_exists($this, '_validate_' . $subsection_name)) { |
|
| 958 | + call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection)); |
|
| 959 | + } |
|
| 960 | + $subsection->_validate(); |
|
| 961 | + } |
|
| 962 | + } |
|
| 963 | + |
|
| 964 | + |
|
| 965 | + /** |
|
| 966 | + * Gets all the validated inputs for the form section |
|
| 967 | + * |
|
| 968 | + * @return array |
|
| 969 | + * @throws EE_Error |
|
| 970 | + */ |
|
| 971 | + public function valid_data() |
|
| 972 | + { |
|
| 973 | + $inputs = array(); |
|
| 974 | + foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 975 | + if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 976 | + $inputs[ $subsection_name ] = $subsection->valid_data(); |
|
| 977 | + } elseif ($subsection instanceof EE_Form_Input_Base) { |
|
| 978 | + $inputs[ $subsection_name ] = $subsection->normalized_value(); |
|
| 979 | + } |
|
| 980 | + } |
|
| 981 | + return $inputs; |
|
| 982 | + } |
|
| 983 | + |
|
| 984 | + |
|
| 985 | + /** |
|
| 986 | + * Gets all the inputs on this form section |
|
| 987 | + * |
|
| 988 | + * @return EE_Form_Input_Base[] |
|
| 989 | + * @throws EE_Error |
|
| 990 | + */ |
|
| 991 | + public function inputs() |
|
| 992 | + { |
|
| 993 | + $inputs = array(); |
|
| 994 | + foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 995 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 996 | + $inputs[ $subsection_name ] = $subsection; |
|
| 997 | + } |
|
| 998 | + } |
|
| 999 | + return $inputs; |
|
| 1000 | + } |
|
| 1001 | + |
|
| 1002 | + |
|
| 1003 | + /** |
|
| 1004 | + * Gets all the subsections which are a proper form |
|
| 1005 | + * |
|
| 1006 | + * @return EE_Form_Section_Proper[] |
|
| 1007 | + * @throws EE_Error |
|
| 1008 | + */ |
|
| 1009 | + public function subforms() |
|
| 1010 | + { |
|
| 1011 | + $form_sections = array(); |
|
| 1012 | + foreach ($this->subsections() as $name => $obj) { |
|
| 1013 | + if ($obj instanceof EE_Form_Section_Proper) { |
|
| 1014 | + $form_sections[ $name ] = $obj; |
|
| 1015 | + } |
|
| 1016 | + } |
|
| 1017 | + return $form_sections; |
|
| 1018 | + } |
|
| 1019 | + |
|
| 1020 | + |
|
| 1021 | + /** |
|
| 1022 | + * Gets all the subsections (inputs, proper subsections, or html-only sections). |
|
| 1023 | + * Consider using inputs() or subforms() |
|
| 1024 | + * if you only want form inputs or proper form sections. |
|
| 1025 | + * |
|
| 1026 | + * @param boolean $require_construction_to_be_finalized most client code should |
|
| 1027 | + * leave this as TRUE so that the inputs will be properly |
|
| 1028 | + * configured. However, some client code may be ok with |
|
| 1029 | + * construction finalize being called later |
|
| 1030 | + * (realizing that the subsections' html names might not be |
|
| 1031 | + * set yet, etc.) |
|
| 1032 | + * @return EE_Form_Section_Proper[] |
|
| 1033 | + * @throws EE_Error |
|
| 1034 | + */ |
|
| 1035 | + public function subsections($require_construction_to_be_finalized = true) |
|
| 1036 | + { |
|
| 1037 | + if ($require_construction_to_be_finalized) { |
|
| 1038 | + $this->ensure_construct_finalized_called(); |
|
| 1039 | + } |
|
| 1040 | + return $this->_subsections; |
|
| 1041 | + } |
|
| 1042 | + |
|
| 1043 | + |
|
| 1044 | + /** |
|
| 1045 | + * Returns whether this form has any subforms or inputs |
|
| 1046 | + * @return bool |
|
| 1047 | + */ |
|
| 1048 | + public function hasSubsections() |
|
| 1049 | + { |
|
| 1050 | + return ! empty($this->_subsections); |
|
| 1051 | + } |
|
| 1052 | + |
|
| 1053 | + |
|
| 1054 | + /** |
|
| 1055 | + * Returns a simple array where keys are input names, and values are their normalized |
|
| 1056 | + * values. (Similar to calling get_input_value on inputs) |
|
| 1057 | + * |
|
| 1058 | + * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1059 | + * or just this forms' direct children inputs |
|
| 1060 | + * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1061 | + * or allow multidimensional array |
|
| 1062 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1063 | + * with array keys being input names |
|
| 1064 | + * (regardless of whether they are from a subsection or not), |
|
| 1065 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1066 | + * where keys are always subsection names and values are either |
|
| 1067 | + * the input's normalized value, or an array like the top-level array |
|
| 1068 | + * @throws EE_Error |
|
| 1069 | + */ |
|
| 1070 | + public function input_values($include_subform_inputs = false, $flatten = false) |
|
| 1071 | + { |
|
| 1072 | + return $this->_input_values(false, $include_subform_inputs, $flatten); |
|
| 1073 | + } |
|
| 1074 | + |
|
| 1075 | + |
|
| 1076 | + /** |
|
| 1077 | + * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value' |
|
| 1078 | + * of each input. On some inputs (especially radio boxes or checkboxes), the value stored |
|
| 1079 | + * is not necessarily the value we want to display to users. This creates an array |
|
| 1080 | + * where keys are the input names, and values are their display values |
|
| 1081 | + * |
|
| 1082 | + * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1083 | + * or just this forms' direct children inputs |
|
| 1084 | + * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1085 | + * or allow multidimensional array |
|
| 1086 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1087 | + * with array keys being input names |
|
| 1088 | + * (regardless of whether they are from a subsection or not), |
|
| 1089 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1090 | + * where keys are always subsection names and values are either |
|
| 1091 | + * the input's normalized value, or an array like the top-level array |
|
| 1092 | + * @throws EE_Error |
|
| 1093 | + */ |
|
| 1094 | + public function input_pretty_values($include_subform_inputs = false, $flatten = false) |
|
| 1095 | + { |
|
| 1096 | + return $this->_input_values(true, $include_subform_inputs, $flatten); |
|
| 1097 | + } |
|
| 1098 | + |
|
| 1099 | + |
|
| 1100 | + /** |
|
| 1101 | + * Gets the input values from the form |
|
| 1102 | + * |
|
| 1103 | + * @param boolean $pretty Whether to retrieve the pretty value, |
|
| 1104 | + * or just the normalized value |
|
| 1105 | + * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1106 | + * or just this forms' direct children inputs |
|
| 1107 | + * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1108 | + * or allow multidimensional array |
|
| 1109 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being |
|
| 1110 | + * input names (regardless of whether they are from a subsection or not), |
|
| 1111 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1112 | + * where keys are always subsection names and values are either |
|
| 1113 | + * the input's normalized value, or an array like the top-level array |
|
| 1114 | + * @throws EE_Error |
|
| 1115 | + */ |
|
| 1116 | + public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false) |
|
| 1117 | + { |
|
| 1118 | + $input_values = array(); |
|
| 1119 | + foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 1120 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1121 | + $input_values[ $subsection_name ] = $pretty |
|
| 1122 | + ? $subsection->pretty_value() |
|
| 1123 | + : $subsection->normalized_value(); |
|
| 1124 | + } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) { |
|
| 1125 | + $subform_input_values = $subsection->_input_values( |
|
| 1126 | + $pretty, |
|
| 1127 | + $include_subform_inputs, |
|
| 1128 | + $flatten |
|
| 1129 | + ); |
|
| 1130 | + if ($flatten) { |
|
| 1131 | + $input_values = array_merge($input_values, $subform_input_values); |
|
| 1132 | + } else { |
|
| 1133 | + $input_values[ $subsection_name ] = $subform_input_values; |
|
| 1134 | + } |
|
| 1135 | + } |
|
| 1136 | + } |
|
| 1137 | + return $input_values; |
|
| 1138 | + } |
|
| 1139 | + |
|
| 1140 | + |
|
| 1141 | + /** |
|
| 1142 | + * Gets the originally submitted input values from the form |
|
| 1143 | + * |
|
| 1144 | + * @param boolean $include_subforms Whether to include inputs from subforms, |
|
| 1145 | + * or just this forms' direct children inputs |
|
| 1146 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1147 | + * with array keys being input names |
|
| 1148 | + * (regardless of whether they are from a subsection or not), |
|
| 1149 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1150 | + * where keys are always subsection names and values are either |
|
| 1151 | + * the input's normalized value, or an array like the top-level array |
|
| 1152 | + * @throws EE_Error |
|
| 1153 | + */ |
|
| 1154 | + public function submitted_values($include_subforms = false) |
|
| 1155 | + { |
|
| 1156 | + $submitted_values = array(); |
|
| 1157 | + foreach ($this->subsections() as $subsection) { |
|
| 1158 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1159 | + // is this input part of an array of inputs? |
|
| 1160 | + if (strpos($subsection->html_name(), '[') !== false) { |
|
| 1161 | + $full_input_name = EEH_Array::convert_array_values_to_keys( |
|
| 1162 | + explode( |
|
| 1163 | + '[', |
|
| 1164 | + str_replace(']', '', $subsection->html_name()) |
|
| 1165 | + ), |
|
| 1166 | + $subsection->raw_value() |
|
| 1167 | + ); |
|
| 1168 | + $submitted_values = array_replace_recursive($submitted_values, $full_input_name); |
|
| 1169 | + } else { |
|
| 1170 | + $submitted_values[ $subsection->html_name() ] = $subsection->raw_value(); |
|
| 1171 | + } |
|
| 1172 | + } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) { |
|
| 1173 | + $subform_input_values = $subsection->submitted_values($include_subforms); |
|
| 1174 | + $submitted_values = array_replace_recursive($submitted_values, $subform_input_values); |
|
| 1175 | + } |
|
| 1176 | + } |
|
| 1177 | + return $submitted_values; |
|
| 1178 | + } |
|
| 1179 | + |
|
| 1180 | + |
|
| 1181 | + /** |
|
| 1182 | + * Indicates whether or not this form has received a submission yet |
|
| 1183 | + * (ie, had receive_form_submission called on it yet) |
|
| 1184 | + * |
|
| 1185 | + * @return boolean |
|
| 1186 | + * @throws EE_Error |
|
| 1187 | + */ |
|
| 1188 | + public function has_received_submission() |
|
| 1189 | + { |
|
| 1190 | + $this->ensure_construct_finalized_called(); |
|
| 1191 | + return $this->_received_submission; |
|
| 1192 | + } |
|
| 1193 | + |
|
| 1194 | + |
|
| 1195 | + /** |
|
| 1196 | + * Equivalent to passing 'exclude' in the constructor's options array. |
|
| 1197 | + * Removes the listed inputs from the form |
|
| 1198 | + * |
|
| 1199 | + * @param array $inputs_to_exclude values are the input names |
|
| 1200 | + * @return void |
|
| 1201 | + */ |
|
| 1202 | + public function exclude(array $inputs_to_exclude = array()) |
|
| 1203 | + { |
|
| 1204 | + foreach ($inputs_to_exclude as $input_to_exclude_name) { |
|
| 1205 | + unset($this->_subsections[ $input_to_exclude_name ]); |
|
| 1206 | + } |
|
| 1207 | + } |
|
| 1208 | + |
|
| 1209 | + |
|
| 1210 | + /** |
|
| 1211 | + * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy. |
|
| 1212 | + * @param array $inputs_to_hide |
|
| 1213 | + * @throws EE_Error |
|
| 1214 | + */ |
|
| 1215 | + public function hide(array $inputs_to_hide = array()) |
|
| 1216 | + { |
|
| 1217 | + foreach ($inputs_to_hide as $input_to_hide) { |
|
| 1218 | + $input = $this->get_input($input_to_hide); |
|
| 1219 | + $input->set_display_strategy(new EE_Hidden_Display_Strategy()); |
|
| 1220 | + } |
|
| 1221 | + } |
|
| 1222 | + |
|
| 1223 | + |
|
| 1224 | + /** |
|
| 1225 | + * add_subsections |
|
| 1226 | + * Adds the listed subsections to the form section. |
|
| 1227 | + * If $subsection_name_to_target is provided, |
|
| 1228 | + * then new subsections are added before or after that subsection, |
|
| 1229 | + * otherwise to the start or end of the entire subsections array. |
|
| 1230 | + * |
|
| 1231 | + * @param EE_Form_Section_Base[] $new_subsections array of new form subsections |
|
| 1232 | + * where keys are their names |
|
| 1233 | + * @param string $subsection_name_to_target an existing for section that $new_subsections |
|
| 1234 | + * should be added before or after |
|
| 1235 | + * IF $subsection_name_to_target is null, |
|
| 1236 | + * then $new_subsections will be added to |
|
| 1237 | + * the beginning or end of the entire subsections array |
|
| 1238 | + * @param boolean $add_before whether to add $new_subsections, before or after |
|
| 1239 | + * $subsection_name_to_target, |
|
| 1240 | + * or if $subsection_name_to_target is null, |
|
| 1241 | + * before or after entire subsections array |
|
| 1242 | + * @return void |
|
| 1243 | + * @throws EE_Error |
|
| 1244 | + */ |
|
| 1245 | + public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true) |
|
| 1246 | + { |
|
| 1247 | + foreach ($new_subsections as $subsection_name => $subsection) { |
|
| 1248 | + if (! $subsection instanceof EE_Form_Section_Base) { |
|
| 1249 | + EE_Error::add_error( |
|
| 1250 | + sprintf( |
|
| 1251 | + esc_html__( |
|
| 1252 | + "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.", |
|
| 1253 | + 'event_espresso' |
|
| 1254 | + ), |
|
| 1255 | + get_class($subsection), |
|
| 1256 | + $subsection_name, |
|
| 1257 | + $this->name() |
|
| 1258 | + ) |
|
| 1259 | + ); |
|
| 1260 | + unset($new_subsections[ $subsection_name ]); |
|
| 1261 | + } |
|
| 1262 | + } |
|
| 1263 | + $this->_subsections = EEH_Array::insert_into_array( |
|
| 1264 | + $this->_subsections, |
|
| 1265 | + $new_subsections, |
|
| 1266 | + $subsection_name_to_target, |
|
| 1267 | + $add_before |
|
| 1268 | + ); |
|
| 1269 | + if ($this->_construction_finalized) { |
|
| 1270 | + foreach ($this->_subsections as $name => $subsection) { |
|
| 1271 | + $subsection->_construct_finalize($this, $name); |
|
| 1272 | + } |
|
| 1273 | + } |
|
| 1274 | + } |
|
| 1275 | + |
|
| 1276 | + |
|
| 1277 | + /** |
|
| 1278 | + * @param string $subsection_name |
|
| 1279 | + * @param bool $recursive |
|
| 1280 | + * @return bool |
|
| 1281 | + */ |
|
| 1282 | + public function has_subsection($subsection_name, $recursive = false) |
|
| 1283 | + { |
|
| 1284 | + foreach ($this->_subsections as $name => $subsection) { |
|
| 1285 | + if ($name === $subsection_name |
|
| 1286 | + || ( |
|
| 1287 | + $recursive |
|
| 1288 | + && $subsection instanceof EE_Form_Section_Proper |
|
| 1289 | + && $subsection->has_subsection($subsection_name, $recursive) |
|
| 1290 | + ) |
|
| 1291 | + ) { |
|
| 1292 | + return true; |
|
| 1293 | + } |
|
| 1294 | + } |
|
| 1295 | + return false; |
|
| 1296 | + } |
|
| 1297 | + |
|
| 1298 | + |
|
| 1299 | + |
|
| 1300 | + /** |
|
| 1301 | + * Just gets all validatable subsections to clean their sensitive data |
|
| 1302 | + * |
|
| 1303 | + * @throws EE_Error |
|
| 1304 | + */ |
|
| 1305 | + public function clean_sensitive_data() |
|
| 1306 | + { |
|
| 1307 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1308 | + $subsection->clean_sensitive_data(); |
|
| 1309 | + } |
|
| 1310 | + } |
|
| 1311 | + |
|
| 1312 | + |
|
| 1313 | + /** |
|
| 1314 | + * Sets the submission error message (aka validation error message for this form section and all sub-sections) |
|
| 1315 | + * @param string $form_submission_error_message |
|
| 1316 | + * @param EE_Form_Section_Validatable $form_section unused |
|
| 1317 | + * @throws EE_Error |
|
| 1318 | + */ |
|
| 1319 | + public function set_submission_error_message( |
|
| 1320 | + $form_submission_error_message = '' |
|
| 1321 | + ) { |
|
| 1322 | + $this->_form_submission_error_message = ! empty($form_submission_error_message) |
|
| 1323 | + ? $form_submission_error_message |
|
| 1324 | + : $this->getAllValidationErrorsString(); |
|
| 1325 | + } |
|
| 1326 | + |
|
| 1327 | + |
|
| 1328 | + /** |
|
| 1329 | + * Returns the cached error message. A default value is set for this during _validate(), |
|
| 1330 | + * (called during receive_form_submission) but it can be explicitly set using |
|
| 1331 | + * set_submission_error_message |
|
| 1332 | + * |
|
| 1333 | + * @return string |
|
| 1334 | + */ |
|
| 1335 | + public function submission_error_message() |
|
| 1336 | + { |
|
| 1337 | + return $this->_form_submission_error_message; |
|
| 1338 | + } |
|
| 1339 | + |
|
| 1340 | + |
|
| 1341 | + /** |
|
| 1342 | + * Sets a message to display if the data submitted to the form was valid. |
|
| 1343 | + * @param string $form_submission_success_message |
|
| 1344 | + */ |
|
| 1345 | + public function set_submission_success_message($form_submission_success_message = '') |
|
| 1346 | + { |
|
| 1347 | + $this->_form_submission_success_message = ! empty($form_submission_success_message) |
|
| 1348 | + ? $form_submission_success_message |
|
| 1349 | + : esc_html__('Form submitted successfully', 'event_espresso'); |
|
| 1350 | + } |
|
| 1351 | + |
|
| 1352 | + |
|
| 1353 | + /** |
|
| 1354 | + * Gets a message appropriate for display when the form is correctly submitted |
|
| 1355 | + * @return string |
|
| 1356 | + */ |
|
| 1357 | + public function submission_success_message() |
|
| 1358 | + { |
|
| 1359 | + return $this->_form_submission_success_message; |
|
| 1360 | + } |
|
| 1361 | + |
|
| 1362 | + |
|
| 1363 | + /** |
|
| 1364 | + * Returns the prefix that should be used on child of this form section for |
|
| 1365 | + * their html names. If this form section itself has a parent, prepends ITS |
|
| 1366 | + * prefix onto this form section's prefix. Used primarily by |
|
| 1367 | + * EE_Form_Input_Base::_set_default_html_name_if_empty |
|
| 1368 | + * |
|
| 1369 | + * @return string |
|
| 1370 | + * @throws EE_Error |
|
| 1371 | + */ |
|
| 1372 | + public function html_name_prefix() |
|
| 1373 | + { |
|
| 1374 | + if ($this->parent_section() instanceof EE_Form_Section_Proper) { |
|
| 1375 | + return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']'; |
|
| 1376 | + } |
|
| 1377 | + return $this->name(); |
|
| 1378 | + } |
|
| 1379 | + |
|
| 1380 | + |
|
| 1381 | + /** |
|
| 1382 | + * Gets the name, but first checks _construct_finalize has been called. If not, |
|
| 1383 | + * calls it (assumes there is no parent and that we want the name to be whatever |
|
| 1384 | + * was set, which is probably nothing, or the classname) |
|
| 1385 | + * |
|
| 1386 | + * @return string |
|
| 1387 | + * @throws EE_Error |
|
| 1388 | + */ |
|
| 1389 | + public function name() |
|
| 1390 | + { |
|
| 1391 | + $this->ensure_construct_finalized_called(); |
|
| 1392 | + return parent::name(); |
|
| 1393 | + } |
|
| 1394 | + |
|
| 1395 | + |
|
| 1396 | + /** |
|
| 1397 | + * @return EE_Form_Section_Proper |
|
| 1398 | + * @throws EE_Error |
|
| 1399 | + */ |
|
| 1400 | + public function parent_section() |
|
| 1401 | + { |
|
| 1402 | + $this->ensure_construct_finalized_called(); |
|
| 1403 | + return parent::parent_section(); |
|
| 1404 | + } |
|
| 1405 | + |
|
| 1406 | + |
|
| 1407 | + /** |
|
| 1408 | + * make sure construction finalized was called, otherwise children might not be ready |
|
| 1409 | + * |
|
| 1410 | + * @return void |
|
| 1411 | + * @throws EE_Error |
|
| 1412 | + */ |
|
| 1413 | + public function ensure_construct_finalized_called() |
|
| 1414 | + { |
|
| 1415 | + if (! $this->_construction_finalized) { |
|
| 1416 | + $this->_construct_finalize($this->_parent_section, $this->_name); |
|
| 1417 | + } |
|
| 1418 | + } |
|
| 1419 | + |
|
| 1420 | + |
|
| 1421 | + /** |
|
| 1422 | + * Checks if any of this form section's inputs, or any of its children's inputs, |
|
| 1423 | + * are in teh form data. If any are found, returns true. Else false |
|
| 1424 | + * |
|
| 1425 | + * @param array $req_data |
|
| 1426 | + * @return boolean |
|
| 1427 | + * @throws EE_Error |
|
| 1428 | + */ |
|
| 1429 | + public function form_data_present_in($req_data = null) |
|
| 1430 | + { |
|
| 1431 | + $req_data = $this->getCachedRequest($req_data); |
|
| 1432 | + foreach ($this->subsections() as $subsection) { |
|
| 1433 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1434 | + if ($subsection->form_data_present_in($req_data)) { |
|
| 1435 | + return true; |
|
| 1436 | + } |
|
| 1437 | + } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1438 | + if ($subsection->form_data_present_in($req_data)) { |
|
| 1439 | + return true; |
|
| 1440 | + } |
|
| 1441 | + } |
|
| 1442 | + } |
|
| 1443 | + return false; |
|
| 1444 | + } |
|
| 1445 | + |
|
| 1446 | + |
|
| 1447 | + /** |
|
| 1448 | + * Gets validation errors for this form section and subsections |
|
| 1449 | + * Similar to EE_Form_Section_Validatable::get_validation_errors() except this |
|
| 1450 | + * gets the validation errors for ALL subsection |
|
| 1451 | + * |
|
| 1452 | + * @return EE_Validation_Error[] |
|
| 1453 | + * @throws EE_Error |
|
| 1454 | + */ |
|
| 1455 | + public function get_validation_errors_accumulated() |
|
| 1456 | + { |
|
| 1457 | + $validation_errors = $this->get_validation_errors(); |
|
| 1458 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1459 | + if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1460 | + $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated(); |
|
| 1461 | + } else { |
|
| 1462 | + $validation_errors_on_this_subsection = $subsection->get_validation_errors(); |
|
| 1463 | + } |
|
| 1464 | + if ($validation_errors_on_this_subsection) { |
|
| 1465 | + $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection); |
|
| 1466 | + } |
|
| 1467 | + } |
|
| 1468 | + return $validation_errors; |
|
| 1469 | + } |
|
| 1470 | + |
|
| 1471 | + /** |
|
| 1472 | + * Fetch validation errors from children and grandchildren and puts them in a single string. |
|
| 1473 | + * This traverses the form section tree to generate this, but you probably want to instead use |
|
| 1474 | + * get_form_submission_error_message() which is usually this message cached (or a custom validation error message) |
|
| 1475 | + * |
|
| 1476 | + * @return string |
|
| 1477 | + * @since 4.9.59.p |
|
| 1478 | + */ |
|
| 1479 | + protected function getAllValidationErrorsString() |
|
| 1480 | + { |
|
| 1481 | + $submission_error_messages = array(); |
|
| 1482 | + // bad, bad, bad registrant |
|
| 1483 | + foreach ($this->get_validation_errors_accumulated() as $validation_error) { |
|
| 1484 | + if ($validation_error instanceof EE_Validation_Error) { |
|
| 1485 | + $form_section = $validation_error->get_form_section(); |
|
| 1486 | + if ($form_section instanceof EE_Form_Input_Base) { |
|
| 1487 | + $label = $validation_error->get_form_section()->html_label_text(); |
|
| 1488 | + } elseif ($form_section instanceof EE_Form_Section_Validatable) { |
|
| 1489 | + $label = $validation_error->get_form_section()->name(); |
|
| 1490 | + } else { |
|
| 1491 | + $label = esc_html__('Unknown', 'event_espresso'); |
|
| 1492 | + } |
|
| 1493 | + $submission_error_messages[] = sprintf( |
|
| 1494 | + __('%s : %s', 'event_espresso'), |
|
| 1495 | + $label, |
|
| 1496 | + $validation_error->getMessage() |
|
| 1497 | + ); |
|
| 1498 | + } |
|
| 1499 | + } |
|
| 1500 | + return implode('<br>', $submission_error_messages); |
|
| 1501 | + } |
|
| 1502 | + |
|
| 1503 | + |
|
| 1504 | + /** |
|
| 1505 | + * This isn't just the name of an input, it's a path pointing to an input. The |
|
| 1506 | + * path is similar to a folder path: slash (/) means to descend into a subsection, |
|
| 1507 | + * dot-dot-slash (../) means to ascend into the parent section. |
|
| 1508 | + * After a series of slashes and dot-dot-slashes, there should be the name of an input, |
|
| 1509 | + * which will be returned. |
|
| 1510 | + * Eg, if you want the related input to be conditional on a sibling input name 'foobar' |
|
| 1511 | + * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name |
|
| 1512 | + * 'baz', use '../baz'. If you want it to be conditional on a cousin input, |
|
| 1513 | + * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'. |
|
| 1514 | + * Etc |
|
| 1515 | + * |
|
| 1516 | + * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false |
|
| 1517 | + * @return EE_Form_Section_Base |
|
| 1518 | + * @throws EE_Error |
|
| 1519 | + */ |
|
| 1520 | + public function find_section_from_path($form_section_path) |
|
| 1521 | + { |
|
| 1522 | + // check if we can find the input from purely going straight up the tree |
|
| 1523 | + $input = parent::find_section_from_path($form_section_path); |
|
| 1524 | + if ($input instanceof EE_Form_Section_Base) { |
|
| 1525 | + return $input; |
|
| 1526 | + } |
|
| 1527 | + $next_slash_pos = strpos($form_section_path, '/'); |
|
| 1528 | + if ($next_slash_pos !== false) { |
|
| 1529 | + $child_section_name = substr($form_section_path, 0, $next_slash_pos); |
|
| 1530 | + $subpath = substr($form_section_path, $next_slash_pos + 1); |
|
| 1531 | + } else { |
|
| 1532 | + $child_section_name = $form_section_path; |
|
| 1533 | + $subpath = ''; |
|
| 1534 | + } |
|
| 1535 | + $child_section = $this->get_subsection($child_section_name); |
|
| 1536 | + if ($child_section instanceof EE_Form_Section_Base) { |
|
| 1537 | + return $child_section->find_section_from_path($subpath); |
|
| 1538 | + } |
|
| 1539 | + return null; |
|
| 1540 | + } |
|
| 1541 | 1541 | } |
@@ -17,2106 +17,2106 @@ |
||
| 17 | 17 | { |
| 18 | 18 | |
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * Used to reference when a registration has never been checked in. |
|
| 22 | - * |
|
| 23 | - * @deprecated use \EE_Checkin::status_checked_never instead |
|
| 24 | - * @type int |
|
| 25 | - */ |
|
| 26 | - const checkin_status_never = 2; |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * Used to reference when a registration has been checked in. |
|
| 30 | - * |
|
| 31 | - * @deprecated use \EE_Checkin::status_checked_in instead |
|
| 32 | - * @type int |
|
| 33 | - */ |
|
| 34 | - const checkin_status_in = 1; |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * Used to reference when a registration has been checked out. |
|
| 39 | - * |
|
| 40 | - * @deprecated use \EE_Checkin::status_checked_out instead |
|
| 41 | - * @type int |
|
| 42 | - */ |
|
| 43 | - const checkin_status_out = 0; |
|
| 44 | - |
|
| 45 | - |
|
| 46 | - /** |
|
| 47 | - * extra meta key for tracking reg status os trashed registrations |
|
| 48 | - * |
|
| 49 | - * @type string |
|
| 50 | - */ |
|
| 51 | - const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
| 52 | - |
|
| 53 | - |
|
| 54 | - /** |
|
| 55 | - * extra meta key for tracking if registration has reserved ticket |
|
| 56 | - * |
|
| 57 | - * @type string |
|
| 58 | - */ |
|
| 59 | - const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
| 60 | - |
|
| 61 | - |
|
| 62 | - /** |
|
| 63 | - * @param array $props_n_values incoming values |
|
| 64 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 65 | - * used.) |
|
| 66 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 67 | - * date_format and the second value is the time format |
|
| 68 | - * @return EE_Registration |
|
| 69 | - * @throws EE_Error |
|
| 70 | - */ |
|
| 71 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 72 | - { |
|
| 73 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 74 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 75 | - } |
|
| 76 | - |
|
| 77 | - |
|
| 78 | - /** |
|
| 79 | - * @param array $props_n_values incoming values from the database |
|
| 80 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 81 | - * the website will be used. |
|
| 82 | - * @return EE_Registration |
|
| 83 | - */ |
|
| 84 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 85 | - { |
|
| 86 | - return new self($props_n_values, true, $timezone); |
|
| 87 | - } |
|
| 88 | - |
|
| 89 | - |
|
| 90 | - /** |
|
| 91 | - * Set Event ID |
|
| 92 | - * |
|
| 93 | - * @param int $EVT_ID Event ID |
|
| 94 | - * @throws EE_Error |
|
| 95 | - * @throws RuntimeException |
|
| 96 | - */ |
|
| 97 | - public function set_event($EVT_ID = 0) |
|
| 98 | - { |
|
| 99 | - $this->set('EVT_ID', $EVT_ID); |
|
| 100 | - } |
|
| 101 | - |
|
| 102 | - |
|
| 103 | - /** |
|
| 104 | - * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
| 105 | - * be routed to internal methods |
|
| 106 | - * |
|
| 107 | - * @param string $field_name |
|
| 108 | - * @param mixed $field_value |
|
| 109 | - * @param bool $use_default |
|
| 110 | - * @throws EE_Error |
|
| 111 | - * @throws EntityNotFoundException |
|
| 112 | - * @throws InvalidArgumentException |
|
| 113 | - * @throws InvalidDataTypeException |
|
| 114 | - * @throws InvalidInterfaceException |
|
| 115 | - * @throws ReflectionException |
|
| 116 | - * @throws RuntimeException |
|
| 117 | - */ |
|
| 118 | - public function set($field_name, $field_value, $use_default = false) |
|
| 119 | - { |
|
| 120 | - switch ($field_name) { |
|
| 121 | - case 'REG_code': |
|
| 122 | - if (! empty($field_value) && $this->reg_code() === null) { |
|
| 123 | - $this->set_reg_code($field_value, $use_default); |
|
| 124 | - } |
|
| 125 | - break; |
|
| 126 | - case 'STS_ID': |
|
| 127 | - $this->set_status($field_value, $use_default); |
|
| 128 | - break; |
|
| 129 | - default: |
|
| 130 | - parent::set($field_name, $field_value, $use_default); |
|
| 131 | - } |
|
| 132 | - } |
|
| 133 | - |
|
| 134 | - |
|
| 135 | - /** |
|
| 136 | - * Set Status ID |
|
| 137 | - * updates the registration status and ALSO... |
|
| 138 | - * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
| 139 | - * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
| 140 | - * |
|
| 141 | - * @param string $new_STS_ID |
|
| 142 | - * @param boolean $use_default |
|
| 143 | - * @param ContextInterface|null $context |
|
| 144 | - * @return bool |
|
| 145 | - * @throws DomainException |
|
| 146 | - * @throws EE_Error |
|
| 147 | - * @throws EntityNotFoundException |
|
| 148 | - * @throws InvalidArgumentException |
|
| 149 | - * @throws InvalidDataTypeException |
|
| 150 | - * @throws InvalidInterfaceException |
|
| 151 | - * @throws ReflectionException |
|
| 152 | - * @throws RuntimeException |
|
| 153 | - * @throws UnexpectedEntityException |
|
| 154 | - */ |
|
| 155 | - public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null) |
|
| 156 | - { |
|
| 157 | - // get current REG_Status |
|
| 158 | - $old_STS_ID = $this->status_ID(); |
|
| 159 | - // if status has changed |
|
| 160 | - if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
| 161 | - && ! empty($old_STS_ID) // and that old status is actually set |
|
| 162 | - && ! empty($new_STS_ID) // as well as the new status |
|
| 163 | - && $this->ID() // ensure registration is in the db |
|
| 164 | - ) { |
|
| 165 | - // update internal status first |
|
| 166 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 167 | - // THEN handle other changes that occur when reg status changes |
|
| 168 | - // TO approved |
|
| 169 | - if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
| 170 | - // reserve a space by incrementing ticket and datetime sold values |
|
| 171 | - $this->reserveRegistrationSpace(); |
|
| 172 | - do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 173 | - // OR FROM approved |
|
| 174 | - } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
| 175 | - // release a space by decrementing ticket and datetime sold values |
|
| 176 | - $this->releaseRegistrationSpace(); |
|
| 177 | - do_action( |
|
| 178 | - 'AHEE__EE_Registration__set_status__from_approved', |
|
| 179 | - $this, |
|
| 180 | - $old_STS_ID, |
|
| 181 | - $new_STS_ID, |
|
| 182 | - $context |
|
| 183 | - ); |
|
| 184 | - } |
|
| 185 | - // update status |
|
| 186 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 187 | - $this->updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, $context); |
|
| 188 | - if ($this->statusChangeUpdatesTransaction($context)) { |
|
| 189 | - $this->updateTransactionAfterStatusChange(); |
|
| 190 | - } |
|
| 191 | - do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 192 | - return true; |
|
| 193 | - } |
|
| 194 | - // even though the old value matches the new value, it's still good to |
|
| 195 | - // allow the parent set method to have a say |
|
| 196 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 197 | - return true; |
|
| 198 | - } |
|
| 199 | - |
|
| 200 | - |
|
| 201 | - /** |
|
| 202 | - * update REGs and TXN when cancelled or declined registrations involved |
|
| 203 | - * |
|
| 204 | - * @param string $new_STS_ID |
|
| 205 | - * @param string $old_STS_ID |
|
| 206 | - * @param ContextInterface|null $context |
|
| 207 | - * @throws EE_Error |
|
| 208 | - * @throws InvalidArgumentException |
|
| 209 | - * @throws InvalidDataTypeException |
|
| 210 | - * @throws InvalidInterfaceException |
|
| 211 | - * @throws ReflectionException |
|
| 212 | - * @throws RuntimeException |
|
| 213 | - */ |
|
| 214 | - private function updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, ContextInterface $context = null) |
|
| 215 | - { |
|
| 216 | - // these reg statuses should not be considered in any calculations involving monies owing |
|
| 217 | - $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
| 218 | - // true if registration has been cancelled or declined |
|
| 219 | - $this->updateIfCanceled( |
|
| 220 | - $closed_reg_statuses, |
|
| 221 | - $new_STS_ID, |
|
| 222 | - $old_STS_ID, |
|
| 223 | - $context |
|
| 224 | - ); |
|
| 225 | - $this->updateIfReinstated( |
|
| 226 | - $closed_reg_statuses, |
|
| 227 | - $new_STS_ID, |
|
| 228 | - $old_STS_ID, |
|
| 229 | - $context |
|
| 230 | - ); |
|
| 231 | - } |
|
| 232 | - |
|
| 233 | - |
|
| 234 | - /** |
|
| 235 | - * update REGs and TXN when cancelled or declined registrations involved |
|
| 236 | - * |
|
| 237 | - * @param array $closed_reg_statuses |
|
| 238 | - * @param string $new_STS_ID |
|
| 239 | - * @param string $old_STS_ID |
|
| 240 | - * @param ContextInterface|null $context |
|
| 241 | - * @throws EE_Error |
|
| 242 | - * @throws InvalidArgumentException |
|
| 243 | - * @throws InvalidDataTypeException |
|
| 244 | - * @throws InvalidInterfaceException |
|
| 245 | - * @throws ReflectionException |
|
| 246 | - * @throws RuntimeException |
|
| 247 | - */ |
|
| 248 | - private function updateIfCanceled( |
|
| 249 | - array $closed_reg_statuses, |
|
| 250 | - $new_STS_ID, |
|
| 251 | - $old_STS_ID, |
|
| 252 | - ContextInterface $context = null |
|
| 253 | - ) { |
|
| 254 | - // true if registration has been cancelled or declined |
|
| 255 | - if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 256 | - && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 257 | - ) { |
|
| 258 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 259 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 260 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 261 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 262 | - // cancelled or declined registration |
|
| 263 | - $registration_processor->update_registration_after_being_canceled_or_declined( |
|
| 264 | - $this, |
|
| 265 | - $closed_reg_statuses |
|
| 266 | - ); |
|
| 267 | - $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
| 268 | - $this, |
|
| 269 | - $closed_reg_statuses, |
|
| 270 | - false |
|
| 271 | - ); |
|
| 272 | - do_action( |
|
| 273 | - 'AHEE__EE_Registration__set_status__canceled_or_declined', |
|
| 274 | - $this, |
|
| 275 | - $old_STS_ID, |
|
| 276 | - $new_STS_ID, |
|
| 277 | - $context |
|
| 278 | - ); |
|
| 279 | - return; |
|
| 280 | - } |
|
| 281 | - } |
|
| 282 | - |
|
| 283 | - |
|
| 284 | - /** |
|
| 285 | - * update REGs and TXN when cancelled or declined registrations involved |
|
| 286 | - * |
|
| 287 | - * @param array $closed_reg_statuses |
|
| 288 | - * @param string $new_STS_ID |
|
| 289 | - * @param string $old_STS_ID |
|
| 290 | - * @param ContextInterface|null $context |
|
| 291 | - * @throws EE_Error |
|
| 292 | - * @throws InvalidArgumentException |
|
| 293 | - * @throws InvalidDataTypeException |
|
| 294 | - * @throws InvalidInterfaceException |
|
| 295 | - * @throws ReflectionException |
|
| 296 | - */ |
|
| 297 | - private function updateIfReinstated( |
|
| 298 | - array $closed_reg_statuses, |
|
| 299 | - $new_STS_ID, |
|
| 300 | - $old_STS_ID, |
|
| 301 | - ContextInterface $context = null |
|
| 302 | - ) { |
|
| 303 | - // true if reinstating cancelled or declined registration |
|
| 304 | - if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 305 | - && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 306 | - ) { |
|
| 307 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 308 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 309 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 310 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 311 | - // reinstating cancelled or declined registration |
|
| 312 | - $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
| 313 | - $this, |
|
| 314 | - $closed_reg_statuses |
|
| 315 | - ); |
|
| 316 | - $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
| 317 | - $this, |
|
| 318 | - $closed_reg_statuses, |
|
| 319 | - false |
|
| 320 | - ); |
|
| 321 | - do_action( |
|
| 322 | - 'AHEE__EE_Registration__set_status__after_reinstated', |
|
| 323 | - $this, |
|
| 324 | - $old_STS_ID, |
|
| 325 | - $new_STS_ID, |
|
| 326 | - $context |
|
| 327 | - ); |
|
| 328 | - } |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - |
|
| 332 | - /** |
|
| 333 | - * @param ContextInterface|null $context |
|
| 334 | - * @return bool |
|
| 335 | - */ |
|
| 336 | - private function statusChangeUpdatesTransaction(ContextInterface $context = null) |
|
| 337 | - { |
|
| 338 | - $contexts_that_do_not_update_transaction = (array) apply_filters( |
|
| 339 | - 'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction', |
|
| 340 | - array('spco_reg_step_attendee_information_process_registrations'), |
|
| 341 | - $context, |
|
| 342 | - $this |
|
| 343 | - ); |
|
| 344 | - return ! ( |
|
| 345 | - $context instanceof ContextInterface |
|
| 346 | - && in_array($context->slug(), $contexts_that_do_not_update_transaction, true) |
|
| 347 | - ); |
|
| 348 | - } |
|
| 349 | - |
|
| 350 | - |
|
| 351 | - /** |
|
| 352 | - * @throws EE_Error |
|
| 353 | - * @throws EntityNotFoundException |
|
| 354 | - * @throws InvalidArgumentException |
|
| 355 | - * @throws InvalidDataTypeException |
|
| 356 | - * @throws InvalidInterfaceException |
|
| 357 | - * @throws ReflectionException |
|
| 358 | - * @throws RuntimeException |
|
| 359 | - */ |
|
| 360 | - private function updateTransactionAfterStatusChange() |
|
| 361 | - { |
|
| 362 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
| 363 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
| 364 | - $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
| 365 | - $this->transaction()->update_status_based_on_total_paid(true); |
|
| 366 | - } |
|
| 367 | - |
|
| 368 | - |
|
| 369 | - /** |
|
| 370 | - * get Status ID |
|
| 371 | - */ |
|
| 372 | - public function status_ID() |
|
| 373 | - { |
|
| 374 | - return $this->get('STS_ID'); |
|
| 375 | - } |
|
| 376 | - |
|
| 377 | - |
|
| 378 | - /** |
|
| 379 | - * Gets the ticket this registration is for |
|
| 380 | - * |
|
| 381 | - * @param boolean $include_archived whether to include archived tickets or not. |
|
| 382 | - * |
|
| 383 | - * @return EE_Ticket|EE_Base_Class |
|
| 384 | - * @throws EE_Error |
|
| 385 | - */ |
|
| 386 | - public function ticket($include_archived = true) |
|
| 387 | - { |
|
| 388 | - $query_params = array(); |
|
| 389 | - if ($include_archived) { |
|
| 390 | - $query_params['default_where_conditions'] = 'none'; |
|
| 391 | - } |
|
| 392 | - return $this->get_first_related('Ticket', $query_params); |
|
| 393 | - } |
|
| 394 | - |
|
| 395 | - |
|
| 396 | - /** |
|
| 397 | - * Gets the event this registration is for |
|
| 398 | - * |
|
| 399 | - * @return EE_Event |
|
| 400 | - * @throws EE_Error |
|
| 401 | - * @throws EntityNotFoundException |
|
| 402 | - */ |
|
| 403 | - public function event() |
|
| 404 | - { |
|
| 405 | - $event = $this->get_first_related('Event'); |
|
| 406 | - if (! $event instanceof \EE_Event) { |
|
| 407 | - throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
| 408 | - } |
|
| 409 | - return $event; |
|
| 410 | - } |
|
| 411 | - |
|
| 412 | - |
|
| 413 | - /** |
|
| 414 | - * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
| 415 | - * with the author of the event this registration is for. |
|
| 416 | - * |
|
| 417 | - * @since 4.5.0 |
|
| 418 | - * @return int |
|
| 419 | - * @throws EE_Error |
|
| 420 | - * @throws EntityNotFoundException |
|
| 421 | - */ |
|
| 422 | - public function wp_user() |
|
| 423 | - { |
|
| 424 | - $event = $this->event(); |
|
| 425 | - if ($event instanceof EE_Event) { |
|
| 426 | - return $event->wp_user(); |
|
| 427 | - } |
|
| 428 | - return 0; |
|
| 429 | - } |
|
| 430 | - |
|
| 431 | - |
|
| 432 | - /** |
|
| 433 | - * increments this registration's related ticket sold and corresponding datetime sold values |
|
| 434 | - * |
|
| 435 | - * @return void |
|
| 436 | - * @throws DomainException |
|
| 437 | - * @throws EE_Error |
|
| 438 | - * @throws EntityNotFoundException |
|
| 439 | - * @throws InvalidArgumentException |
|
| 440 | - * @throws InvalidDataTypeException |
|
| 441 | - * @throws InvalidInterfaceException |
|
| 442 | - * @throws ReflectionException |
|
| 443 | - * @throws UnexpectedEntityException |
|
| 444 | - */ |
|
| 445 | - private function reserveRegistrationSpace() |
|
| 446 | - { |
|
| 447 | - // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
| 448 | - // so stop tracking that this reg has a ticket reserved |
|
| 449 | - $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 450 | - $ticket = $this->ticket(); |
|
| 451 | - $ticket->increaseSold(); |
|
| 452 | - // possibly set event status to sold out |
|
| 453 | - $this->event()->perform_sold_out_status_check(); |
|
| 454 | - } |
|
| 455 | - |
|
| 456 | - |
|
| 457 | - /** |
|
| 458 | - * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
| 459 | - * |
|
| 460 | - * @return void |
|
| 461 | - * @throws DomainException |
|
| 462 | - * @throws EE_Error |
|
| 463 | - * @throws EntityNotFoundException |
|
| 464 | - * @throws InvalidArgumentException |
|
| 465 | - * @throws InvalidDataTypeException |
|
| 466 | - * @throws InvalidInterfaceException |
|
| 467 | - * @throws ReflectionException |
|
| 468 | - * @throws UnexpectedEntityException |
|
| 469 | - */ |
|
| 470 | - private function releaseRegistrationSpace() |
|
| 471 | - { |
|
| 472 | - $ticket = $this->ticket(); |
|
| 473 | - $ticket->decreaseSold(); |
|
| 474 | - // possibly change event status from sold out back to previous status |
|
| 475 | - $this->event()->perform_sold_out_status_check(); |
|
| 476 | - } |
|
| 477 | - |
|
| 478 | - |
|
| 479 | - /** |
|
| 480 | - * tracks this registration's ticket reservation in extra meta |
|
| 481 | - * and can increment related ticket reserved and corresponding datetime reserved values |
|
| 482 | - * |
|
| 483 | - * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
| 484 | - * @return void |
|
| 485 | - * @throws EE_Error |
|
| 486 | - * @throws InvalidArgumentException |
|
| 487 | - * @throws InvalidDataTypeException |
|
| 488 | - * @throws InvalidInterfaceException |
|
| 489 | - * @throws ReflectionException |
|
| 490 | - */ |
|
| 491 | - public function reserve_ticket($update_ticket = false, $source = 'unknown') |
|
| 492 | - { |
|
| 493 | - // only reserve ticket if space is not currently reserved |
|
| 494 | - if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) !== true) { |
|
| 495 | - $this->update_extra_meta('reserve_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 496 | - // IMPORTANT !!! |
|
| 497 | - // although checking $update_ticket first would be more efficient, |
|
| 498 | - // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 499 | - if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) |
|
| 500 | - && $update_ticket |
|
| 501 | - ) { |
|
| 502 | - $ticket = $this->ticket(); |
|
| 503 | - $ticket->increaseReserved(1, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 504 | - $ticket->save(); |
|
| 505 | - } |
|
| 506 | - } |
|
| 507 | - } |
|
| 508 | - |
|
| 509 | - |
|
| 510 | - /** |
|
| 511 | - * stops tracking this registration's ticket reservation in extra meta |
|
| 512 | - * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
| 513 | - * |
|
| 514 | - * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
| 515 | - * @return void |
|
| 516 | - * @throws EE_Error |
|
| 517 | - * @throws InvalidArgumentException |
|
| 518 | - * @throws InvalidDataTypeException |
|
| 519 | - * @throws InvalidInterfaceException |
|
| 520 | - * @throws ReflectionException |
|
| 521 | - */ |
|
| 522 | - public function release_reserved_ticket($update_ticket = false, $source = 'unknown') |
|
| 523 | - { |
|
| 524 | - // only release ticket if space is currently reserved |
|
| 525 | - if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) === true) { |
|
| 526 | - $this->update_extra_meta('release_reserved_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 527 | - // IMPORTANT !!! |
|
| 528 | - // although checking $update_ticket first would be more efficient, |
|
| 529 | - // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 530 | - if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, false) |
|
| 531 | - && $update_ticket |
|
| 532 | - ) { |
|
| 533 | - $ticket = $this->ticket(); |
|
| 534 | - $ticket->decreaseReserved(1, true, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 535 | - } |
|
| 536 | - } |
|
| 537 | - } |
|
| 538 | - |
|
| 539 | - |
|
| 540 | - /** |
|
| 541 | - * Set Attendee ID |
|
| 542 | - * |
|
| 543 | - * @param int $ATT_ID Attendee ID |
|
| 544 | - * @throws EE_Error |
|
| 545 | - * @throws RuntimeException |
|
| 546 | - */ |
|
| 547 | - public function set_attendee_id($ATT_ID = 0) |
|
| 548 | - { |
|
| 549 | - $this->set('ATT_ID', $ATT_ID); |
|
| 550 | - } |
|
| 551 | - |
|
| 552 | - |
|
| 553 | - /** |
|
| 554 | - * Set Transaction ID |
|
| 555 | - * |
|
| 556 | - * @param int $TXN_ID Transaction ID |
|
| 557 | - * @throws EE_Error |
|
| 558 | - * @throws RuntimeException |
|
| 559 | - */ |
|
| 560 | - public function set_transaction_id($TXN_ID = 0) |
|
| 561 | - { |
|
| 562 | - $this->set('TXN_ID', $TXN_ID); |
|
| 563 | - } |
|
| 564 | - |
|
| 565 | - |
|
| 566 | - /** |
|
| 567 | - * Set Session |
|
| 568 | - * |
|
| 569 | - * @param string $REG_session PHP Session ID |
|
| 570 | - * @throws EE_Error |
|
| 571 | - * @throws RuntimeException |
|
| 572 | - */ |
|
| 573 | - public function set_session($REG_session = '') |
|
| 574 | - { |
|
| 575 | - $this->set('REG_session', $REG_session); |
|
| 576 | - } |
|
| 577 | - |
|
| 578 | - |
|
| 579 | - /** |
|
| 580 | - * Set Registration URL Link |
|
| 581 | - * |
|
| 582 | - * @param string $REG_url_link Registration URL Link |
|
| 583 | - * @throws EE_Error |
|
| 584 | - * @throws RuntimeException |
|
| 585 | - */ |
|
| 586 | - public function set_reg_url_link($REG_url_link = '') |
|
| 587 | - { |
|
| 588 | - $this->set('REG_url_link', $REG_url_link); |
|
| 589 | - } |
|
| 590 | - |
|
| 591 | - |
|
| 592 | - /** |
|
| 593 | - * Set Attendee Counter |
|
| 594 | - * |
|
| 595 | - * @param int $REG_count Primary Attendee |
|
| 596 | - * @throws EE_Error |
|
| 597 | - * @throws RuntimeException |
|
| 598 | - */ |
|
| 599 | - public function set_count($REG_count = 1) |
|
| 600 | - { |
|
| 601 | - $this->set('REG_count', $REG_count); |
|
| 602 | - } |
|
| 603 | - |
|
| 604 | - |
|
| 605 | - /** |
|
| 606 | - * Set Group Size |
|
| 607 | - * |
|
| 608 | - * @param boolean $REG_group_size Group Registration |
|
| 609 | - * @throws EE_Error |
|
| 610 | - * @throws RuntimeException |
|
| 611 | - */ |
|
| 612 | - public function set_group_size($REG_group_size = false) |
|
| 613 | - { |
|
| 614 | - $this->set('REG_group_size', $REG_group_size); |
|
| 615 | - } |
|
| 616 | - |
|
| 617 | - |
|
| 618 | - /** |
|
| 619 | - * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
| 620 | - * EEM_Registration::status_id_not_approved |
|
| 621 | - * |
|
| 622 | - * @return boolean |
|
| 623 | - */ |
|
| 624 | - public function is_not_approved() |
|
| 625 | - { |
|
| 626 | - return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
| 627 | - } |
|
| 628 | - |
|
| 629 | - |
|
| 630 | - /** |
|
| 631 | - * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
| 632 | - * EEM_Registration::status_id_pending_payment |
|
| 633 | - * |
|
| 634 | - * @return boolean |
|
| 635 | - */ |
|
| 636 | - public function is_pending_payment() |
|
| 637 | - { |
|
| 638 | - return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
| 639 | - } |
|
| 640 | - |
|
| 641 | - |
|
| 642 | - /** |
|
| 643 | - * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
| 644 | - * |
|
| 645 | - * @return boolean |
|
| 646 | - */ |
|
| 647 | - public function is_approved() |
|
| 648 | - { |
|
| 649 | - return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
| 650 | - } |
|
| 651 | - |
|
| 652 | - |
|
| 653 | - /** |
|
| 654 | - * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
| 655 | - * |
|
| 656 | - * @return boolean |
|
| 657 | - */ |
|
| 658 | - public function is_cancelled() |
|
| 659 | - { |
|
| 660 | - return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
| 661 | - } |
|
| 662 | - |
|
| 663 | - |
|
| 664 | - /** |
|
| 665 | - * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
| 666 | - * |
|
| 667 | - * @return boolean |
|
| 668 | - */ |
|
| 669 | - public function is_declined() |
|
| 670 | - { |
|
| 671 | - return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
| 672 | - } |
|
| 673 | - |
|
| 674 | - |
|
| 675 | - /** |
|
| 676 | - * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
| 677 | - * EEM_Registration::status_id_incomplete |
|
| 678 | - * |
|
| 679 | - * @return boolean |
|
| 680 | - */ |
|
| 681 | - public function is_incomplete() |
|
| 682 | - { |
|
| 683 | - return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
| 684 | - } |
|
| 685 | - |
|
| 686 | - |
|
| 687 | - /** |
|
| 688 | - * Set Registration Date |
|
| 689 | - * |
|
| 690 | - * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
| 691 | - * Date |
|
| 692 | - * @throws EE_Error |
|
| 693 | - * @throws RuntimeException |
|
| 694 | - */ |
|
| 695 | - public function set_reg_date($REG_date = false) |
|
| 696 | - { |
|
| 697 | - $this->set('REG_date', $REG_date); |
|
| 698 | - } |
|
| 699 | - |
|
| 700 | - |
|
| 701 | - /** |
|
| 702 | - * Set final price owing for this registration after all ticket/price modifications |
|
| 703 | - * |
|
| 704 | - * @access public |
|
| 705 | - * @param float $REG_final_price |
|
| 706 | - * @throws EE_Error |
|
| 707 | - * @throws RuntimeException |
|
| 708 | - */ |
|
| 709 | - public function set_final_price($REG_final_price = 0.00) |
|
| 710 | - { |
|
| 711 | - $this->set('REG_final_price', $REG_final_price); |
|
| 712 | - } |
|
| 713 | - |
|
| 714 | - |
|
| 715 | - /** |
|
| 716 | - * Set amount paid towards this registration's final price |
|
| 717 | - * |
|
| 718 | - * @access public |
|
| 719 | - * @param float $REG_paid |
|
| 720 | - * @throws EE_Error |
|
| 721 | - * @throws RuntimeException |
|
| 722 | - */ |
|
| 723 | - public function set_paid($REG_paid = 0.00) |
|
| 724 | - { |
|
| 725 | - $this->set('REG_paid', $REG_paid); |
|
| 726 | - } |
|
| 727 | - |
|
| 728 | - |
|
| 729 | - /** |
|
| 730 | - * Attendee Is Going |
|
| 731 | - * |
|
| 732 | - * @param boolean $REG_att_is_going Attendee Is Going |
|
| 733 | - * @throws EE_Error |
|
| 734 | - * @throws RuntimeException |
|
| 735 | - */ |
|
| 736 | - public function set_att_is_going($REG_att_is_going = false) |
|
| 737 | - { |
|
| 738 | - $this->set('REG_att_is_going', $REG_att_is_going); |
|
| 739 | - } |
|
| 740 | - |
|
| 741 | - |
|
| 742 | - /** |
|
| 743 | - * Gets the related attendee |
|
| 744 | - * |
|
| 745 | - * @return EE_Attendee |
|
| 746 | - * @throws EE_Error |
|
| 747 | - */ |
|
| 748 | - public function attendee() |
|
| 749 | - { |
|
| 750 | - return $this->get_first_related('Attendee'); |
|
| 751 | - } |
|
| 752 | - |
|
| 753 | - /** |
|
| 754 | - * Gets the name of the attendee. |
|
| 755 | - * @since $VID:$ |
|
| 756 | - * @param bool $apply_html_entities set to true if you want to use HTML entities. |
|
| 757 | - * @return string |
|
| 758 | - * @throws EE_Error |
|
| 759 | - * @throws InvalidArgumentException |
|
| 760 | - * @throws InvalidDataTypeException |
|
| 761 | - * @throws InvalidInterfaceException |
|
| 762 | - * @throws ReflectionException |
|
| 763 | - */ |
|
| 764 | - public function attendeeName($apply_html_entities = false) |
|
| 765 | - { |
|
| 766 | - $attendee = $this->get_first_related('Attendee'); |
|
| 767 | - if ($attendee instanceof EE_Attendee) { |
|
| 768 | - $attendee_name = $attendee->full_name($apply_html_entities); |
|
| 769 | - } else { |
|
| 770 | - $attendee_name = esc_html__('Unknown', 'event_espresso'); |
|
| 771 | - } |
|
| 772 | - return $attendee_name; |
|
| 773 | - } |
|
| 774 | - |
|
| 775 | - |
|
| 776 | - /** |
|
| 777 | - * get Event ID |
|
| 778 | - */ |
|
| 779 | - public function event_ID() |
|
| 780 | - { |
|
| 781 | - return $this->get('EVT_ID'); |
|
| 782 | - } |
|
| 783 | - |
|
| 784 | - |
|
| 785 | - /** |
|
| 786 | - * get Event ID |
|
| 787 | - */ |
|
| 788 | - public function event_name() |
|
| 789 | - { |
|
| 790 | - $event = $this->event_obj(); |
|
| 791 | - if ($event) { |
|
| 792 | - return $event->name(); |
|
| 793 | - } else { |
|
| 794 | - return null; |
|
| 795 | - } |
|
| 796 | - } |
|
| 797 | - |
|
| 798 | - |
|
| 799 | - /** |
|
| 800 | - * Fetches the event this registration is for |
|
| 801 | - * |
|
| 802 | - * @return EE_Event |
|
| 803 | - * @throws EE_Error |
|
| 804 | - */ |
|
| 805 | - public function event_obj() |
|
| 806 | - { |
|
| 807 | - return $this->get_first_related('Event'); |
|
| 808 | - } |
|
| 809 | - |
|
| 810 | - |
|
| 811 | - /** |
|
| 812 | - * get Attendee ID |
|
| 813 | - */ |
|
| 814 | - public function attendee_ID() |
|
| 815 | - { |
|
| 816 | - return $this->get('ATT_ID'); |
|
| 817 | - } |
|
| 818 | - |
|
| 819 | - |
|
| 820 | - /** |
|
| 821 | - * get PHP Session ID |
|
| 822 | - */ |
|
| 823 | - public function session_ID() |
|
| 824 | - { |
|
| 825 | - return $this->get('REG_session'); |
|
| 826 | - } |
|
| 827 | - |
|
| 828 | - |
|
| 829 | - /** |
|
| 830 | - * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
| 831 | - * |
|
| 832 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 833 | - * @return string |
|
| 834 | - */ |
|
| 835 | - public function receipt_url($messenger = 'html') |
|
| 836 | - { |
|
| 837 | - |
|
| 838 | - /** |
|
| 839 | - * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
| 840 | - * already in use on old system. If there is then we just return the standard url for it. |
|
| 841 | - * |
|
| 842 | - * @since 4.5.0 |
|
| 843 | - */ |
|
| 844 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
| 845 | - $has_custom = EEH_Template::locate_template( |
|
| 846 | - $template_relative_path, |
|
| 847 | - array(), |
|
| 848 | - true, |
|
| 849 | - true, |
|
| 850 | - true |
|
| 851 | - ); |
|
| 852 | - |
|
| 853 | - if ($has_custom) { |
|
| 854 | - return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
| 855 | - } |
|
| 856 | - return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
| 857 | - } |
|
| 858 | - |
|
| 859 | - |
|
| 860 | - /** |
|
| 861 | - * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
| 862 | - * |
|
| 863 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 864 | - * @return string |
|
| 865 | - * @throws EE_Error |
|
| 866 | - */ |
|
| 867 | - public function invoice_url($messenger = 'html') |
|
| 868 | - { |
|
| 869 | - /** |
|
| 870 | - * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
| 871 | - * already in use on old system. If there is then we just return the standard url for it. |
|
| 872 | - * |
|
| 873 | - * @since 4.5.0 |
|
| 874 | - */ |
|
| 875 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
| 876 | - $has_custom = EEH_Template::locate_template( |
|
| 877 | - $template_relative_path, |
|
| 878 | - array(), |
|
| 879 | - true, |
|
| 880 | - true, |
|
| 881 | - true |
|
| 882 | - ); |
|
| 883 | - |
|
| 884 | - if ($has_custom) { |
|
| 885 | - if ($messenger == 'html') { |
|
| 886 | - return $this->invoice_url('launch'); |
|
| 887 | - } |
|
| 888 | - $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
| 889 | - |
|
| 890 | - $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
| 891 | - if ($messenger == 'html') { |
|
| 892 | - $query_args['html'] = true; |
|
| 893 | - } |
|
| 894 | - return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
| 895 | - } |
|
| 896 | - return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
| 897 | - } |
|
| 898 | - |
|
| 899 | - |
|
| 900 | - /** |
|
| 901 | - * get Registration URL Link |
|
| 902 | - * |
|
| 903 | - * @access public |
|
| 904 | - * @return string |
|
| 905 | - * @throws EE_Error |
|
| 906 | - */ |
|
| 907 | - public function reg_url_link() |
|
| 908 | - { |
|
| 909 | - return (string) $this->get('REG_url_link'); |
|
| 910 | - } |
|
| 911 | - |
|
| 912 | - |
|
| 913 | - /** |
|
| 914 | - * Echoes out invoice_url() |
|
| 915 | - * |
|
| 916 | - * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
| 917 | - * @return void |
|
| 918 | - * @throws EE_Error |
|
| 919 | - */ |
|
| 920 | - public function e_invoice_url($type = 'launch') |
|
| 921 | - { |
|
| 922 | - echo $this->invoice_url($type); |
|
| 923 | - } |
|
| 924 | - |
|
| 925 | - |
|
| 926 | - /** |
|
| 927 | - * Echoes out payment_overview_url |
|
| 928 | - */ |
|
| 929 | - public function e_payment_overview_url() |
|
| 930 | - { |
|
| 931 | - echo $this->payment_overview_url(); |
|
| 932 | - } |
|
| 933 | - |
|
| 934 | - |
|
| 935 | - /** |
|
| 936 | - * Gets the URL for the checkout payment options reg step |
|
| 937 | - * with this registration's REG_url_link added as a query parameter |
|
| 938 | - * |
|
| 939 | - * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
| 940 | - * payment overview url. |
|
| 941 | - * @return string |
|
| 942 | - * @throws InvalidInterfaceException |
|
| 943 | - * @throws InvalidDataTypeException |
|
| 944 | - * @throws EE_Error |
|
| 945 | - * @throws InvalidArgumentException |
|
| 946 | - */ |
|
| 947 | - public function payment_overview_url($clear_session = false) |
|
| 948 | - { |
|
| 949 | - return add_query_arg( |
|
| 950 | - (array) apply_filters( |
|
| 951 | - 'FHEE__EE_Registration__payment_overview_url__query_args', |
|
| 952 | - array( |
|
| 953 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
| 954 | - 'step' => 'payment_options', |
|
| 955 | - 'revisit' => true, |
|
| 956 | - 'clear_session' => (bool) $clear_session, |
|
| 957 | - ), |
|
| 958 | - $this |
|
| 959 | - ), |
|
| 960 | - EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 961 | - ); |
|
| 962 | - } |
|
| 963 | - |
|
| 964 | - |
|
| 965 | - /** |
|
| 966 | - * Gets the URL for the checkout attendee information reg step |
|
| 967 | - * with this registration's REG_url_link added as a query parameter |
|
| 968 | - * |
|
| 969 | - * @return string |
|
| 970 | - * @throws InvalidInterfaceException |
|
| 971 | - * @throws InvalidDataTypeException |
|
| 972 | - * @throws EE_Error |
|
| 973 | - * @throws InvalidArgumentException |
|
| 974 | - */ |
|
| 975 | - public function edit_attendee_information_url() |
|
| 976 | - { |
|
| 977 | - return add_query_arg( |
|
| 978 | - (array) apply_filters( |
|
| 979 | - 'FHEE__EE_Registration__edit_attendee_information_url__query_args', |
|
| 980 | - array( |
|
| 981 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
| 982 | - 'step' => 'attendee_information', |
|
| 983 | - 'revisit' => true, |
|
| 984 | - ), |
|
| 985 | - $this |
|
| 986 | - ), |
|
| 987 | - EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 988 | - ); |
|
| 989 | - } |
|
| 990 | - |
|
| 991 | - |
|
| 992 | - /** |
|
| 993 | - * Simply generates and returns the appropriate admin_url link to edit this registration |
|
| 994 | - * |
|
| 995 | - * @return string |
|
| 996 | - * @throws EE_Error |
|
| 997 | - */ |
|
| 998 | - public function get_admin_edit_url() |
|
| 999 | - { |
|
| 1000 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1001 | - array( |
|
| 1002 | - 'page' => 'espresso_registrations', |
|
| 1003 | - 'action' => 'view_registration', |
|
| 1004 | - '_REG_ID' => $this->ID(), |
|
| 1005 | - ), |
|
| 1006 | - admin_url('admin.php') |
|
| 1007 | - ); |
|
| 1008 | - } |
|
| 1009 | - |
|
| 1010 | - |
|
| 1011 | - /** |
|
| 1012 | - * is_primary_registrant? |
|
| 1013 | - */ |
|
| 1014 | - public function is_primary_registrant() |
|
| 1015 | - { |
|
| 1016 | - return $this->get('REG_count') === 1 ? true : false; |
|
| 1017 | - } |
|
| 1018 | - |
|
| 1019 | - |
|
| 1020 | - /** |
|
| 1021 | - * This returns the primary registration object for this registration group (which may be this object). |
|
| 1022 | - * |
|
| 1023 | - * @return EE_Registration |
|
| 1024 | - * @throws EE_Error |
|
| 1025 | - */ |
|
| 1026 | - public function get_primary_registration() |
|
| 1027 | - { |
|
| 1028 | - if ($this->is_primary_registrant()) { |
|
| 1029 | - return $this; |
|
| 1030 | - } |
|
| 1031 | - |
|
| 1032 | - // k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
| 1033 | - /** @var EE_Registration $primary_registrant */ |
|
| 1034 | - $primary_registrant = EEM_Registration::instance()->get_one( |
|
| 1035 | - array( |
|
| 1036 | - array( |
|
| 1037 | - 'TXN_ID' => $this->transaction_ID(), |
|
| 1038 | - 'REG_count' => 1, |
|
| 1039 | - ), |
|
| 1040 | - ) |
|
| 1041 | - ); |
|
| 1042 | - return $primary_registrant; |
|
| 1043 | - } |
|
| 1044 | - |
|
| 1045 | - |
|
| 1046 | - /** |
|
| 1047 | - * get Attendee Number |
|
| 1048 | - * |
|
| 1049 | - * @access public |
|
| 1050 | - */ |
|
| 1051 | - public function count() |
|
| 1052 | - { |
|
| 1053 | - return $this->get('REG_count'); |
|
| 1054 | - } |
|
| 1055 | - |
|
| 1056 | - |
|
| 1057 | - /** |
|
| 1058 | - * get Group Size |
|
| 1059 | - */ |
|
| 1060 | - public function group_size() |
|
| 1061 | - { |
|
| 1062 | - return $this->get('REG_group_size'); |
|
| 1063 | - } |
|
| 1064 | - |
|
| 1065 | - |
|
| 1066 | - /** |
|
| 1067 | - * get Registration Date |
|
| 1068 | - */ |
|
| 1069 | - public function date() |
|
| 1070 | - { |
|
| 1071 | - return $this->get('REG_date'); |
|
| 1072 | - } |
|
| 1073 | - |
|
| 1074 | - |
|
| 1075 | - /** |
|
| 1076 | - * gets a pretty date |
|
| 1077 | - * |
|
| 1078 | - * @param string $date_format |
|
| 1079 | - * @param string $time_format |
|
| 1080 | - * @return string |
|
| 1081 | - * @throws EE_Error |
|
| 1082 | - */ |
|
| 1083 | - public function pretty_date($date_format = null, $time_format = null) |
|
| 1084 | - { |
|
| 1085 | - return $this->get_datetime('REG_date', $date_format, $time_format); |
|
| 1086 | - } |
|
| 1087 | - |
|
| 1088 | - |
|
| 1089 | - /** |
|
| 1090 | - * final_price |
|
| 1091 | - * the registration's share of the transaction total, so that the |
|
| 1092 | - * sum of all the transaction's REG_final_prices equal the transaction's total |
|
| 1093 | - * |
|
| 1094 | - * @return float |
|
| 1095 | - * @throws EE_Error |
|
| 1096 | - */ |
|
| 1097 | - public function final_price() |
|
| 1098 | - { |
|
| 1099 | - return $this->get('REG_final_price'); |
|
| 1100 | - } |
|
| 1101 | - |
|
| 1102 | - |
|
| 1103 | - /** |
|
| 1104 | - * pretty_final_price |
|
| 1105 | - * final price as formatted string, with correct decimal places and currency symbol |
|
| 1106 | - * |
|
| 1107 | - * @return string |
|
| 1108 | - * @throws EE_Error |
|
| 1109 | - */ |
|
| 1110 | - public function pretty_final_price() |
|
| 1111 | - { |
|
| 1112 | - return $this->get_pretty('REG_final_price'); |
|
| 1113 | - } |
|
| 1114 | - |
|
| 1115 | - |
|
| 1116 | - /** |
|
| 1117 | - * get paid (yeah) |
|
| 1118 | - * |
|
| 1119 | - * @return float |
|
| 1120 | - * @throws EE_Error |
|
| 1121 | - */ |
|
| 1122 | - public function paid() |
|
| 1123 | - { |
|
| 1124 | - return $this->get('REG_paid'); |
|
| 1125 | - } |
|
| 1126 | - |
|
| 1127 | - |
|
| 1128 | - /** |
|
| 1129 | - * pretty_paid |
|
| 1130 | - * |
|
| 1131 | - * @return float |
|
| 1132 | - * @throws EE_Error |
|
| 1133 | - */ |
|
| 1134 | - public function pretty_paid() |
|
| 1135 | - { |
|
| 1136 | - return $this->get_pretty('REG_paid'); |
|
| 1137 | - } |
|
| 1138 | - |
|
| 1139 | - |
|
| 1140 | - /** |
|
| 1141 | - * owes_monies_and_can_pay |
|
| 1142 | - * whether or not this registration has monies owing and it's' status allows payment |
|
| 1143 | - * |
|
| 1144 | - * @param array $requires_payment |
|
| 1145 | - * @return bool |
|
| 1146 | - * @throws EE_Error |
|
| 1147 | - */ |
|
| 1148 | - public function owes_monies_and_can_pay($requires_payment = array()) |
|
| 1149 | - { |
|
| 1150 | - // these reg statuses require payment (if event is not free) |
|
| 1151 | - $requires_payment = ! empty($requires_payment) |
|
| 1152 | - ? $requires_payment |
|
| 1153 | - : EEM_Registration::reg_statuses_that_allow_payment(); |
|
| 1154 | - if (in_array($this->status_ID(), $requires_payment) && |
|
| 1155 | - $this->final_price() != 0 && |
|
| 1156 | - $this->final_price() != $this->paid() |
|
| 1157 | - ) { |
|
| 1158 | - return true; |
|
| 1159 | - } else { |
|
| 1160 | - return false; |
|
| 1161 | - } |
|
| 1162 | - } |
|
| 1163 | - |
|
| 1164 | - |
|
| 1165 | - /** |
|
| 1166 | - * Prints out the return value of $this->pretty_status() |
|
| 1167 | - * |
|
| 1168 | - * @param bool $show_icons |
|
| 1169 | - * @return void |
|
| 1170 | - * @throws EE_Error |
|
| 1171 | - */ |
|
| 1172 | - public function e_pretty_status($show_icons = false) |
|
| 1173 | - { |
|
| 1174 | - echo $this->pretty_status($show_icons); |
|
| 1175 | - } |
|
| 1176 | - |
|
| 1177 | - |
|
| 1178 | - /** |
|
| 1179 | - * Returns a nice version of the status for displaying to customers |
|
| 1180 | - * |
|
| 1181 | - * @param bool $show_icons |
|
| 1182 | - * @return string |
|
| 1183 | - * @throws EE_Error |
|
| 1184 | - */ |
|
| 1185 | - public function pretty_status($show_icons = false) |
|
| 1186 | - { |
|
| 1187 | - $status = EEM_Status::instance()->localized_status( |
|
| 1188 | - array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
| 1189 | - false, |
|
| 1190 | - 'sentence' |
|
| 1191 | - ); |
|
| 1192 | - $icon = ''; |
|
| 1193 | - switch ($this->status_ID()) { |
|
| 1194 | - case EEM_Registration::status_id_approved: |
|
| 1195 | - $icon = $show_icons |
|
| 1196 | - ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
| 1197 | - : ''; |
|
| 1198 | - break; |
|
| 1199 | - case EEM_Registration::status_id_pending_payment: |
|
| 1200 | - $icon = $show_icons |
|
| 1201 | - ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
| 1202 | - : ''; |
|
| 1203 | - break; |
|
| 1204 | - case EEM_Registration::status_id_not_approved: |
|
| 1205 | - $icon = $show_icons |
|
| 1206 | - ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
| 1207 | - : ''; |
|
| 1208 | - break; |
|
| 1209 | - case EEM_Registration::status_id_cancelled: |
|
| 1210 | - $icon = $show_icons |
|
| 1211 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
| 1212 | - : ''; |
|
| 1213 | - break; |
|
| 1214 | - case EEM_Registration::status_id_incomplete: |
|
| 1215 | - $icon = $show_icons |
|
| 1216 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
| 1217 | - : ''; |
|
| 1218 | - break; |
|
| 1219 | - case EEM_Registration::status_id_declined: |
|
| 1220 | - $icon = $show_icons |
|
| 1221 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
| 1222 | - : ''; |
|
| 1223 | - break; |
|
| 1224 | - case EEM_Registration::status_id_wait_list: |
|
| 1225 | - $icon = $show_icons |
|
| 1226 | - ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
| 1227 | - : ''; |
|
| 1228 | - break; |
|
| 1229 | - } |
|
| 1230 | - return $icon . $status[ $this->status_ID() ]; |
|
| 1231 | - } |
|
| 1232 | - |
|
| 1233 | - |
|
| 1234 | - /** |
|
| 1235 | - * get Attendee Is Going |
|
| 1236 | - */ |
|
| 1237 | - public function att_is_going() |
|
| 1238 | - { |
|
| 1239 | - return $this->get('REG_att_is_going'); |
|
| 1240 | - } |
|
| 1241 | - |
|
| 1242 | - |
|
| 1243 | - /** |
|
| 1244 | - * Gets related answers |
|
| 1245 | - * |
|
| 1246 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1247 | - * @return EE_Answer[] |
|
| 1248 | - * @throws EE_Error |
|
| 1249 | - */ |
|
| 1250 | - public function answers($query_params = null) |
|
| 1251 | - { |
|
| 1252 | - return $this->get_many_related('Answer', $query_params); |
|
| 1253 | - } |
|
| 1254 | - |
|
| 1255 | - |
|
| 1256 | - /** |
|
| 1257 | - * Gets the registration's answer value to the specified question |
|
| 1258 | - * (either the question's ID or a question object) |
|
| 1259 | - * |
|
| 1260 | - * @param EE_Question|int $question |
|
| 1261 | - * @param bool $pretty_value |
|
| 1262 | - * @return array|string if pretty_value= true, the result will always be a string |
|
| 1263 | - * (because the answer might be an array of answer values, so passing pretty_value=true |
|
| 1264 | - * will convert it into some kind of string) |
|
| 1265 | - * @throws EE_Error |
|
| 1266 | - */ |
|
| 1267 | - public function answer_value_to_question($question, $pretty_value = true) |
|
| 1268 | - { |
|
| 1269 | - $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
| 1270 | - return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
| 1271 | - } |
|
| 1272 | - |
|
| 1273 | - |
|
| 1274 | - /** |
|
| 1275 | - * question_groups |
|
| 1276 | - * returns an array of EE_Question_Group objects for this registration |
|
| 1277 | - * |
|
| 1278 | - * @return EE_Question_Group[] |
|
| 1279 | - * @throws EE_Error |
|
| 1280 | - * @throws InvalidArgumentException |
|
| 1281 | - * @throws InvalidDataTypeException |
|
| 1282 | - * @throws InvalidInterfaceException |
|
| 1283 | - * @throws ReflectionException |
|
| 1284 | - */ |
|
| 1285 | - public function question_groups() |
|
| 1286 | - { |
|
| 1287 | - return EEM_Event::instance()->get_question_groups_for_event($this->event_ID(), $this); |
|
| 1288 | - } |
|
| 1289 | - |
|
| 1290 | - |
|
| 1291 | - /** |
|
| 1292 | - * count_question_groups |
|
| 1293 | - * returns a count of the number of EE_Question_Group objects for this registration |
|
| 1294 | - * |
|
| 1295 | - * @return int |
|
| 1296 | - * @throws EE_Error |
|
| 1297 | - * @throws EntityNotFoundException |
|
| 1298 | - * @throws InvalidArgumentException |
|
| 1299 | - * @throws InvalidDataTypeException |
|
| 1300 | - * @throws InvalidInterfaceException |
|
| 1301 | - * @throws ReflectionException |
|
| 1302 | - */ |
|
| 1303 | - public function count_question_groups() |
|
| 1304 | - { |
|
| 1305 | - return EEM_Event::instance()->count_related( |
|
| 1306 | - $this->event_ID(), |
|
| 1307 | - 'Question_Group', |
|
| 1308 | - [ |
|
| 1309 | - [ |
|
| 1310 | - 'Event_Question_Group.' |
|
| 1311 | - . EEM_Event_Question_Group::instance()->fieldNameForContext($this->is_primary_registrant()) => true, |
|
| 1312 | - ] |
|
| 1313 | - ] |
|
| 1314 | - ); |
|
| 1315 | - } |
|
| 1316 | - |
|
| 1317 | - |
|
| 1318 | - /** |
|
| 1319 | - * Returns the registration date in the 'standard' string format |
|
| 1320 | - * (function may be improved in the future to allow for different formats and timezones) |
|
| 1321 | - * |
|
| 1322 | - * @return string |
|
| 1323 | - * @throws EE_Error |
|
| 1324 | - */ |
|
| 1325 | - public function reg_date() |
|
| 1326 | - { |
|
| 1327 | - return $this->get_datetime('REG_date'); |
|
| 1328 | - } |
|
| 1329 | - |
|
| 1330 | - |
|
| 1331 | - /** |
|
| 1332 | - * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
| 1333 | - * the ticket this registration purchased, or the datetime they have registered |
|
| 1334 | - * to attend) |
|
| 1335 | - * |
|
| 1336 | - * @return EE_Datetime_Ticket |
|
| 1337 | - * @throws EE_Error |
|
| 1338 | - */ |
|
| 1339 | - public function datetime_ticket() |
|
| 1340 | - { |
|
| 1341 | - return $this->get_first_related('Datetime_Ticket'); |
|
| 1342 | - } |
|
| 1343 | - |
|
| 1344 | - |
|
| 1345 | - /** |
|
| 1346 | - * Sets the registration's datetime_ticket. |
|
| 1347 | - * |
|
| 1348 | - * @param EE_Datetime_Ticket $datetime_ticket |
|
| 1349 | - * @return EE_Datetime_Ticket |
|
| 1350 | - * @throws EE_Error |
|
| 1351 | - */ |
|
| 1352 | - public function set_datetime_ticket($datetime_ticket) |
|
| 1353 | - { |
|
| 1354 | - return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
| 1355 | - } |
|
| 1356 | - |
|
| 1357 | - /** |
|
| 1358 | - * Gets deleted |
|
| 1359 | - * |
|
| 1360 | - * @return bool |
|
| 1361 | - * @throws EE_Error |
|
| 1362 | - */ |
|
| 1363 | - public function deleted() |
|
| 1364 | - { |
|
| 1365 | - return $this->get('REG_deleted'); |
|
| 1366 | - } |
|
| 1367 | - |
|
| 1368 | - /** |
|
| 1369 | - * Sets deleted |
|
| 1370 | - * |
|
| 1371 | - * @param boolean $deleted |
|
| 1372 | - * @return bool |
|
| 1373 | - * @throws EE_Error |
|
| 1374 | - * @throws RuntimeException |
|
| 1375 | - */ |
|
| 1376 | - public function set_deleted($deleted) |
|
| 1377 | - { |
|
| 1378 | - if ($deleted) { |
|
| 1379 | - $this->delete(); |
|
| 1380 | - } else { |
|
| 1381 | - $this->restore(); |
|
| 1382 | - } |
|
| 1383 | - } |
|
| 1384 | - |
|
| 1385 | - |
|
| 1386 | - /** |
|
| 1387 | - * Get the status object of this object |
|
| 1388 | - * |
|
| 1389 | - * @return EE_Status |
|
| 1390 | - * @throws EE_Error |
|
| 1391 | - */ |
|
| 1392 | - public function status_obj() |
|
| 1393 | - { |
|
| 1394 | - return $this->get_first_related('Status'); |
|
| 1395 | - } |
|
| 1396 | - |
|
| 1397 | - |
|
| 1398 | - /** |
|
| 1399 | - * Returns the number of times this registration has checked into any of the datetimes |
|
| 1400 | - * its available for |
|
| 1401 | - * |
|
| 1402 | - * @return int |
|
| 1403 | - * @throws EE_Error |
|
| 1404 | - */ |
|
| 1405 | - public function count_checkins() |
|
| 1406 | - { |
|
| 1407 | - return $this->get_model()->count_related($this, 'Checkin'); |
|
| 1408 | - } |
|
| 1409 | - |
|
| 1410 | - |
|
| 1411 | - /** |
|
| 1412 | - * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
| 1413 | - * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
| 1414 | - * |
|
| 1415 | - * @return int |
|
| 1416 | - * @throws EE_Error |
|
| 1417 | - */ |
|
| 1418 | - public function count_checkins_not_checkedout() |
|
| 1419 | - { |
|
| 1420 | - return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
| 1421 | - } |
|
| 1422 | - |
|
| 1423 | - |
|
| 1424 | - /** |
|
| 1425 | - * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
| 1426 | - * |
|
| 1427 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1428 | - * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
| 1429 | - * consider registration status as well as datetime access. |
|
| 1430 | - * @return bool |
|
| 1431 | - * @throws EE_Error |
|
| 1432 | - */ |
|
| 1433 | - public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
| 1434 | - { |
|
| 1435 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1436 | - |
|
| 1437 | - // first check registration status |
|
| 1438 | - if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
| 1439 | - return false; |
|
| 1440 | - } |
|
| 1441 | - // is there a datetime ticket that matches this dtt_ID? |
|
| 1442 | - if (! (EEM_Datetime_Ticket::instance()->exists( |
|
| 1443 | - array( |
|
| 1444 | - array( |
|
| 1445 | - 'TKT_ID' => $this->get('TKT_ID'), |
|
| 1446 | - 'DTT_ID' => $DTT_ID, |
|
| 1447 | - ), |
|
| 1448 | - ) |
|
| 1449 | - )) |
|
| 1450 | - ) { |
|
| 1451 | - return false; |
|
| 1452 | - } |
|
| 1453 | - |
|
| 1454 | - // final check is against TKT_uses |
|
| 1455 | - return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
| 1456 | - } |
|
| 1457 | - |
|
| 1458 | - |
|
| 1459 | - /** |
|
| 1460 | - * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
| 1461 | - * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
| 1462 | - * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
| 1463 | - * then return false. Otherwise return true. |
|
| 1464 | - * |
|
| 1465 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1466 | - * @return bool true means can checkin. false means cannot checkin. |
|
| 1467 | - * @throws EE_Error |
|
| 1468 | - */ |
|
| 1469 | - public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
| 1470 | - { |
|
| 1471 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1472 | - |
|
| 1473 | - if (! $DTT_ID) { |
|
| 1474 | - return false; |
|
| 1475 | - } |
|
| 1476 | - |
|
| 1477 | - $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
| 1478 | - |
|
| 1479 | - // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
| 1480 | - // check-in or not. |
|
| 1481 | - if (! $max_uses || $max_uses === EE_INF) { |
|
| 1482 | - return true; |
|
| 1483 | - } |
|
| 1484 | - |
|
| 1485 | - // does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
| 1486 | - // go ahead and toggle. |
|
| 1487 | - if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
| 1488 | - return true; |
|
| 1489 | - } |
|
| 1490 | - |
|
| 1491 | - // made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
| 1492 | - // disallows further check-ins. |
|
| 1493 | - $count_unique_dtt_checkins = EEM_Checkin::instance()->count( |
|
| 1494 | - array( |
|
| 1495 | - array( |
|
| 1496 | - 'REG_ID' => $this->ID(), |
|
| 1497 | - 'CHK_in' => true, |
|
| 1498 | - ), |
|
| 1499 | - ), |
|
| 1500 | - 'DTT_ID', |
|
| 1501 | - true |
|
| 1502 | - ); |
|
| 1503 | - // checkins have already reached their max number of uses |
|
| 1504 | - // so registrant can NOT checkin |
|
| 1505 | - if ($count_unique_dtt_checkins >= $max_uses) { |
|
| 1506 | - EE_Error::add_error( |
|
| 1507 | - esc_html__( |
|
| 1508 | - 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
| 1509 | - 'event_espresso' |
|
| 1510 | - ), |
|
| 1511 | - __FILE__, |
|
| 1512 | - __FUNCTION__, |
|
| 1513 | - __LINE__ |
|
| 1514 | - ); |
|
| 1515 | - return false; |
|
| 1516 | - } |
|
| 1517 | - return true; |
|
| 1518 | - } |
|
| 1519 | - |
|
| 1520 | - |
|
| 1521 | - /** |
|
| 1522 | - * toggle Check-in status for this registration |
|
| 1523 | - * Check-ins are toggled in the following order: |
|
| 1524 | - * never checked in -> checked in |
|
| 1525 | - * checked in -> checked out |
|
| 1526 | - * checked out -> checked in |
|
| 1527 | - * |
|
| 1528 | - * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
| 1529 | - * If not included or null, then it is assumed latest datetime is being toggled. |
|
| 1530 | - * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
| 1531 | - * can be checked in or not. Otherwise this forces change in checkin status. |
|
| 1532 | - * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
| 1533 | - * @throws EE_Error |
|
| 1534 | - */ |
|
| 1535 | - public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
| 1536 | - { |
|
| 1537 | - if (empty($DTT_ID)) { |
|
| 1538 | - $datetime = $this->get_latest_related_datetime(); |
|
| 1539 | - $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
| 1540 | - // verify the registration can checkin for the given DTT_ID |
|
| 1541 | - } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1542 | - EE_Error::add_error( |
|
| 1543 | - sprintf( |
|
| 1544 | - esc_html__( |
|
| 1545 | - 'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access', |
|
| 1546 | - 'event_espresso' |
|
| 1547 | - ), |
|
| 1548 | - $this->ID(), |
|
| 1549 | - $DTT_ID |
|
| 1550 | - ), |
|
| 1551 | - __FILE__, |
|
| 1552 | - __FUNCTION__, |
|
| 1553 | - __LINE__ |
|
| 1554 | - ); |
|
| 1555 | - return false; |
|
| 1556 | - } |
|
| 1557 | - $status_paths = array( |
|
| 1558 | - EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
| 1559 | - EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
| 1560 | - EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
| 1561 | - ); |
|
| 1562 | - // start by getting the current status so we know what status we'll be changing to. |
|
| 1563 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
| 1564 | - $status_to = $status_paths[ $cur_status ]; |
|
| 1565 | - // database only records true for checked IN or false for checked OUT |
|
| 1566 | - // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
| 1567 | - $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
| 1568 | - // add relation - note Check-ins are always creating new rows |
|
| 1569 | - // because we are keeping track of Check-ins over time. |
|
| 1570 | - // Eventually we'll probably want to show a list table |
|
| 1571 | - // for the individual Check-ins so that they can be managed. |
|
| 1572 | - $checkin = EE_Checkin::new_instance( |
|
| 1573 | - array( |
|
| 1574 | - 'REG_ID' => $this->ID(), |
|
| 1575 | - 'DTT_ID' => $DTT_ID, |
|
| 1576 | - 'CHK_in' => $new_status, |
|
| 1577 | - ) |
|
| 1578 | - ); |
|
| 1579 | - // if the record could not be saved then return false |
|
| 1580 | - if ($checkin->save() === 0) { |
|
| 1581 | - if (WP_DEBUG) { |
|
| 1582 | - global $wpdb; |
|
| 1583 | - $error = sprintf( |
|
| 1584 | - esc_html__( |
|
| 1585 | - 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
| 1586 | - 'event_espresso' |
|
| 1587 | - ), |
|
| 1588 | - '<br />', |
|
| 1589 | - $wpdb->last_error |
|
| 1590 | - ); |
|
| 1591 | - } else { |
|
| 1592 | - $error = esc_html__( |
|
| 1593 | - 'Registration check in update failed because of an unknown database error', |
|
| 1594 | - 'event_espresso' |
|
| 1595 | - ); |
|
| 1596 | - } |
|
| 1597 | - EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
| 1598 | - return false; |
|
| 1599 | - } |
|
| 1600 | - return $status_to; |
|
| 1601 | - } |
|
| 1602 | - |
|
| 1603 | - |
|
| 1604 | - /** |
|
| 1605 | - * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
| 1606 | - * "Latest" is defined by the `DTT_EVT_start` column. |
|
| 1607 | - * |
|
| 1608 | - * @return EE_Datetime|null |
|
| 1609 | - * @throws EE_Error |
|
| 1610 | - */ |
|
| 1611 | - public function get_latest_related_datetime() |
|
| 1612 | - { |
|
| 1613 | - return EEM_Datetime::instance()->get_one( |
|
| 1614 | - array( |
|
| 1615 | - array( |
|
| 1616 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1617 | - ), |
|
| 1618 | - 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
| 1619 | - ) |
|
| 1620 | - ); |
|
| 1621 | - } |
|
| 1622 | - |
|
| 1623 | - |
|
| 1624 | - /** |
|
| 1625 | - * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
| 1626 | - * "Earliest" is defined by the `DTT_EVT_start` column. |
|
| 1627 | - * |
|
| 1628 | - * @throws EE_Error |
|
| 1629 | - */ |
|
| 1630 | - public function get_earliest_related_datetime() |
|
| 1631 | - { |
|
| 1632 | - return EEM_Datetime::instance()->get_one( |
|
| 1633 | - array( |
|
| 1634 | - array( |
|
| 1635 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1636 | - ), |
|
| 1637 | - 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
| 1638 | - ) |
|
| 1639 | - ); |
|
| 1640 | - } |
|
| 1641 | - |
|
| 1642 | - |
|
| 1643 | - /** |
|
| 1644 | - * This method simply returns the check-in status for this registration and the given datetime. |
|
| 1645 | - * If neither the datetime nor the checkin values are provided as arguments, |
|
| 1646 | - * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
| 1647 | - * |
|
| 1648 | - * @param int $DTT_ID The ID of the datetime we're checking against |
|
| 1649 | - * (if empty we'll get the primary datetime for |
|
| 1650 | - * this registration (via event) and use it's ID); |
|
| 1651 | - * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
| 1652 | - * |
|
| 1653 | - * @return int Integer representing Check-in status. |
|
| 1654 | - * @throws EE_Error |
|
| 1655 | - */ |
|
| 1656 | - public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
| 1657 | - { |
|
| 1658 | - $checkin_query_params = array( |
|
| 1659 | - 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
| 1660 | - ); |
|
| 1661 | - |
|
| 1662 | - if ($DTT_ID > 0) { |
|
| 1663 | - $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
| 1664 | - } |
|
| 1665 | - |
|
| 1666 | - // get checkin object (if exists) |
|
| 1667 | - $checkin = $checkin instanceof EE_Checkin |
|
| 1668 | - ? $checkin |
|
| 1669 | - : $this->get_first_related('Checkin', $checkin_query_params); |
|
| 1670 | - if ($checkin instanceof EE_Checkin) { |
|
| 1671 | - if ($checkin->get('CHK_in')) { |
|
| 1672 | - return EE_Checkin::status_checked_in; // checked in |
|
| 1673 | - } |
|
| 1674 | - return EE_Checkin::status_checked_out; // had checked in but is now checked out. |
|
| 1675 | - } |
|
| 1676 | - return EE_Checkin::status_checked_never; // never been checked in |
|
| 1677 | - } |
|
| 1678 | - |
|
| 1679 | - |
|
| 1680 | - /** |
|
| 1681 | - * This method returns a localized message for the toggled Check-in message. |
|
| 1682 | - * |
|
| 1683 | - * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
| 1684 | - * then it is assumed Check-in for primary datetime was toggled. |
|
| 1685 | - * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
| 1686 | - * message can be customized with the attendee name. |
|
| 1687 | - * @return string internationalized message |
|
| 1688 | - * @throws EE_Error |
|
| 1689 | - */ |
|
| 1690 | - public function get_checkin_msg($DTT_ID, $error = false) |
|
| 1691 | - { |
|
| 1692 | - // let's get the attendee first so we can include the name of the attendee |
|
| 1693 | - $attendee = $this->get_first_related('Attendee'); |
|
| 1694 | - if ($attendee instanceof EE_Attendee) { |
|
| 1695 | - if ($error) { |
|
| 1696 | - return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
| 1697 | - } |
|
| 1698 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
| 1699 | - // what is the status message going to be? |
|
| 1700 | - switch ($cur_status) { |
|
| 1701 | - case EE_Checkin::status_checked_never: |
|
| 1702 | - return sprintf( |
|
| 1703 | - __("%s has been removed from Check-in records", "event_espresso"), |
|
| 1704 | - $attendee->full_name() |
|
| 1705 | - ); |
|
| 1706 | - break; |
|
| 1707 | - case EE_Checkin::status_checked_in: |
|
| 1708 | - return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
| 1709 | - break; |
|
| 1710 | - case EE_Checkin::status_checked_out: |
|
| 1711 | - return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
| 1712 | - break; |
|
| 1713 | - } |
|
| 1714 | - } |
|
| 1715 | - return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
| 1716 | - } |
|
| 1717 | - |
|
| 1718 | - |
|
| 1719 | - /** |
|
| 1720 | - * Returns the related EE_Transaction to this registration |
|
| 1721 | - * |
|
| 1722 | - * @return EE_Transaction |
|
| 1723 | - * @throws EE_Error |
|
| 1724 | - * @throws EntityNotFoundException |
|
| 1725 | - */ |
|
| 1726 | - public function transaction() |
|
| 1727 | - { |
|
| 1728 | - $transaction = $this->get_first_related('Transaction'); |
|
| 1729 | - if (! $transaction instanceof \EE_Transaction) { |
|
| 1730 | - throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
| 1731 | - } |
|
| 1732 | - return $transaction; |
|
| 1733 | - } |
|
| 1734 | - |
|
| 1735 | - |
|
| 1736 | - /** |
|
| 1737 | - * get Registration Code |
|
| 1738 | - */ |
|
| 1739 | - public function reg_code() |
|
| 1740 | - { |
|
| 1741 | - return $this->get('REG_code'); |
|
| 1742 | - } |
|
| 1743 | - |
|
| 1744 | - |
|
| 1745 | - /** |
|
| 1746 | - * get Transaction ID |
|
| 1747 | - */ |
|
| 1748 | - public function transaction_ID() |
|
| 1749 | - { |
|
| 1750 | - return $this->get('TXN_ID'); |
|
| 1751 | - } |
|
| 1752 | - |
|
| 1753 | - |
|
| 1754 | - /** |
|
| 1755 | - * @return int |
|
| 1756 | - * @throws EE_Error |
|
| 1757 | - */ |
|
| 1758 | - public function ticket_ID() |
|
| 1759 | - { |
|
| 1760 | - return $this->get('TKT_ID'); |
|
| 1761 | - } |
|
| 1762 | - |
|
| 1763 | - |
|
| 1764 | - /** |
|
| 1765 | - * Set Registration Code |
|
| 1766 | - * |
|
| 1767 | - * @access public |
|
| 1768 | - * @param string $REG_code Registration Code |
|
| 1769 | - * @param boolean $use_default |
|
| 1770 | - * @throws EE_Error |
|
| 1771 | - */ |
|
| 1772 | - public function set_reg_code($REG_code, $use_default = false) |
|
| 1773 | - { |
|
| 1774 | - if (empty($REG_code)) { |
|
| 1775 | - EE_Error::add_error( |
|
| 1776 | - esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
| 1777 | - __FILE__, |
|
| 1778 | - __FUNCTION__, |
|
| 1779 | - __LINE__ |
|
| 1780 | - ); |
|
| 1781 | - return; |
|
| 1782 | - } |
|
| 1783 | - if (! $this->reg_code()) { |
|
| 1784 | - parent::set('REG_code', $REG_code, $use_default); |
|
| 1785 | - } else { |
|
| 1786 | - EE_Error::doing_it_wrong( |
|
| 1787 | - __CLASS__ . '::' . __FUNCTION__, |
|
| 1788 | - esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
| 1789 | - '4.6.0' |
|
| 1790 | - ); |
|
| 1791 | - } |
|
| 1792 | - } |
|
| 1793 | - |
|
| 1794 | - |
|
| 1795 | - /** |
|
| 1796 | - * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
| 1797 | - * Note, if you want to just get all registrations in the same transaction (group), use: |
|
| 1798 | - * $registration->transaction()->registrations(); |
|
| 1799 | - * |
|
| 1800 | - * @since 4.5.0 |
|
| 1801 | - * @return EE_Registration[] or empty array if this isn't a group registration. |
|
| 1802 | - * @throws EE_Error |
|
| 1803 | - */ |
|
| 1804 | - public function get_all_other_registrations_in_group() |
|
| 1805 | - { |
|
| 1806 | - if ($this->group_size() < 2) { |
|
| 1807 | - return array(); |
|
| 1808 | - } |
|
| 1809 | - |
|
| 1810 | - $query[0] = array( |
|
| 1811 | - 'TXN_ID' => $this->transaction_ID(), |
|
| 1812 | - 'REG_ID' => array('!=', $this->ID()), |
|
| 1813 | - 'TKT_ID' => $this->ticket_ID(), |
|
| 1814 | - ); |
|
| 1815 | - /** @var EE_Registration[] $registrations */ |
|
| 1816 | - $registrations = $this->get_model()->get_all($query); |
|
| 1817 | - return $registrations; |
|
| 1818 | - } |
|
| 1819 | - |
|
| 1820 | - /** |
|
| 1821 | - * Return the link to the admin details for the object. |
|
| 1822 | - * |
|
| 1823 | - * @return string |
|
| 1824 | - * @throws EE_Error |
|
| 1825 | - */ |
|
| 1826 | - public function get_admin_details_link() |
|
| 1827 | - { |
|
| 1828 | - EE_Registry::instance()->load_helper('URL'); |
|
| 1829 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1830 | - array( |
|
| 1831 | - 'page' => 'espresso_registrations', |
|
| 1832 | - 'action' => 'view_registration', |
|
| 1833 | - '_REG_ID' => $this->ID(), |
|
| 1834 | - ), |
|
| 1835 | - admin_url('admin.php') |
|
| 1836 | - ); |
|
| 1837 | - } |
|
| 1838 | - |
|
| 1839 | - /** |
|
| 1840 | - * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
| 1841 | - * |
|
| 1842 | - * @return string |
|
| 1843 | - * @throws EE_Error |
|
| 1844 | - */ |
|
| 1845 | - public function get_admin_edit_link() |
|
| 1846 | - { |
|
| 1847 | - return $this->get_admin_details_link(); |
|
| 1848 | - } |
|
| 1849 | - |
|
| 1850 | - /** |
|
| 1851 | - * Returns the link to a settings page for the object. |
|
| 1852 | - * |
|
| 1853 | - * @return string |
|
| 1854 | - * @throws EE_Error |
|
| 1855 | - */ |
|
| 1856 | - public function get_admin_settings_link() |
|
| 1857 | - { |
|
| 1858 | - return $this->get_admin_details_link(); |
|
| 1859 | - } |
|
| 1860 | - |
|
| 1861 | - /** |
|
| 1862 | - * Returns the link to the "overview" for the object (typically the "list table" view). |
|
| 1863 | - * |
|
| 1864 | - * @return string |
|
| 1865 | - */ |
|
| 1866 | - public function get_admin_overview_link() |
|
| 1867 | - { |
|
| 1868 | - EE_Registry::instance()->load_helper('URL'); |
|
| 1869 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1870 | - array( |
|
| 1871 | - 'page' => 'espresso_registrations', |
|
| 1872 | - ), |
|
| 1873 | - admin_url('admin.php') |
|
| 1874 | - ); |
|
| 1875 | - } |
|
| 1876 | - |
|
| 1877 | - |
|
| 1878 | - /** |
|
| 1879 | - * @param array $query_params |
|
| 1880 | - * |
|
| 1881 | - * @return \EE_Registration[] |
|
| 1882 | - * @throws EE_Error |
|
| 1883 | - */ |
|
| 1884 | - public function payments($query_params = array()) |
|
| 1885 | - { |
|
| 1886 | - return $this->get_many_related('Payment', $query_params); |
|
| 1887 | - } |
|
| 1888 | - |
|
| 1889 | - |
|
| 1890 | - /** |
|
| 1891 | - * @param array $query_params |
|
| 1892 | - * |
|
| 1893 | - * @return \EE_Registration_Payment[] |
|
| 1894 | - * @throws EE_Error |
|
| 1895 | - */ |
|
| 1896 | - public function registration_payments($query_params = array()) |
|
| 1897 | - { |
|
| 1898 | - return $this->get_many_related('Registration_Payment', $query_params); |
|
| 1899 | - } |
|
| 1900 | - |
|
| 1901 | - |
|
| 1902 | - /** |
|
| 1903 | - * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
| 1904 | - * Note: if there are no payments on the registration there will be no payment method returned. |
|
| 1905 | - * |
|
| 1906 | - * @return EE_Payment_Method|null |
|
| 1907 | - */ |
|
| 1908 | - public function payment_method() |
|
| 1909 | - { |
|
| 1910 | - return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
| 1911 | - } |
|
| 1912 | - |
|
| 1913 | - |
|
| 1914 | - /** |
|
| 1915 | - * @return \EE_Line_Item |
|
| 1916 | - * @throws EntityNotFoundException |
|
| 1917 | - * @throws EE_Error |
|
| 1918 | - */ |
|
| 1919 | - public function ticket_line_item() |
|
| 1920 | - { |
|
| 1921 | - $ticket = $this->ticket(); |
|
| 1922 | - $transaction = $this->transaction(); |
|
| 1923 | - $line_item = null; |
|
| 1924 | - $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 1925 | - $transaction->total_line_item(), |
|
| 1926 | - 'Ticket', |
|
| 1927 | - array($ticket->ID()) |
|
| 1928 | - ); |
|
| 1929 | - foreach ($ticket_line_items as $ticket_line_item) { |
|
| 1930 | - if ($ticket_line_item instanceof \EE_Line_Item |
|
| 1931 | - && $ticket_line_item->OBJ_type() === 'Ticket' |
|
| 1932 | - && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
| 1933 | - ) { |
|
| 1934 | - $line_item = $ticket_line_item; |
|
| 1935 | - break; |
|
| 1936 | - } |
|
| 1937 | - } |
|
| 1938 | - if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1939 | - throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
| 1940 | - } |
|
| 1941 | - return $line_item; |
|
| 1942 | - } |
|
| 1943 | - |
|
| 1944 | - |
|
| 1945 | - /** |
|
| 1946 | - * Soft Deletes this model object. |
|
| 1947 | - * |
|
| 1948 | - * @return boolean | int |
|
| 1949 | - * @throws RuntimeException |
|
| 1950 | - * @throws EE_Error |
|
| 1951 | - */ |
|
| 1952 | - public function delete() |
|
| 1953 | - { |
|
| 1954 | - if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
| 1955 | - $this->set_status(EEM_Registration::status_id_cancelled); |
|
| 1956 | - } |
|
| 1957 | - return parent::delete(); |
|
| 1958 | - } |
|
| 1959 | - |
|
| 1960 | - |
|
| 1961 | - /** |
|
| 1962 | - * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
| 1963 | - * |
|
| 1964 | - * @throws EE_Error |
|
| 1965 | - * @throws RuntimeException |
|
| 1966 | - */ |
|
| 1967 | - public function restore() |
|
| 1968 | - { |
|
| 1969 | - $previous_status = $this->get_extra_meta( |
|
| 1970 | - EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
| 1971 | - true, |
|
| 1972 | - EEM_Registration::status_id_cancelled |
|
| 1973 | - ); |
|
| 1974 | - if ($previous_status) { |
|
| 1975 | - $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
| 1976 | - $this->set_status($previous_status); |
|
| 1977 | - } |
|
| 1978 | - return parent::restore(); |
|
| 1979 | - } |
|
| 1980 | - |
|
| 1981 | - |
|
| 1982 | - /** |
|
| 1983 | - * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price |
|
| 1984 | - * |
|
| 1985 | - * @param boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic |
|
| 1986 | - * depending on whether the reg status changes to or from "Approved" |
|
| 1987 | - * @return boolean whether the Registration status was updated |
|
| 1988 | - * @throws EE_Error |
|
| 1989 | - * @throws RuntimeException |
|
| 1990 | - */ |
|
| 1991 | - public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true) |
|
| 1992 | - { |
|
| 1993 | - $paid = $this->paid(); |
|
| 1994 | - $price = $this->final_price(); |
|
| 1995 | - switch (true) { |
|
| 1996 | - // overpaid or paid |
|
| 1997 | - case EEH_Money::compare_floats($paid, $price, '>'): |
|
| 1998 | - case EEH_Money::compare_floats($paid, $price): |
|
| 1999 | - $new_status = EEM_Registration::status_id_approved; |
|
| 2000 | - break; |
|
| 2001 | - // underpaid |
|
| 2002 | - case EEH_Money::compare_floats($paid, $price, '<'): |
|
| 2003 | - $new_status = EEM_Registration::status_id_pending_payment; |
|
| 2004 | - break; |
|
| 2005 | - // uhhh Houston... |
|
| 2006 | - default: |
|
| 2007 | - throw new RuntimeException( |
|
| 2008 | - esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso') |
|
| 2009 | - ); |
|
| 2010 | - } |
|
| 2011 | - if ($new_status !== $this->status_ID()) { |
|
| 2012 | - if ($trigger_set_status_logic) { |
|
| 2013 | - return $this->set_status($new_status); |
|
| 2014 | - } |
|
| 2015 | - parent::set('STS_ID', $new_status); |
|
| 2016 | - return true; |
|
| 2017 | - } |
|
| 2018 | - return false; |
|
| 2019 | - } |
|
| 2020 | - |
|
| 2021 | - |
|
| 2022 | - /*************************** DEPRECATED ***************************/ |
|
| 2023 | - |
|
| 2024 | - |
|
| 2025 | - /** |
|
| 2026 | - * @deprecated |
|
| 2027 | - * @since 4.7.0 |
|
| 2028 | - * @access public |
|
| 2029 | - */ |
|
| 2030 | - public function price_paid() |
|
| 2031 | - { |
|
| 2032 | - EE_Error::doing_it_wrong( |
|
| 2033 | - 'EE_Registration::price_paid()', |
|
| 2034 | - esc_html__( |
|
| 2035 | - 'This method is deprecated, please use EE_Registration::final_price() instead.', |
|
| 2036 | - 'event_espresso' |
|
| 2037 | - ), |
|
| 2038 | - '4.7.0' |
|
| 2039 | - ); |
|
| 2040 | - return $this->final_price(); |
|
| 2041 | - } |
|
| 2042 | - |
|
| 2043 | - |
|
| 2044 | - /** |
|
| 2045 | - * @deprecated |
|
| 2046 | - * @since 4.7.0 |
|
| 2047 | - * @access public |
|
| 2048 | - * @param float $REG_final_price |
|
| 2049 | - * @throws EE_Error |
|
| 2050 | - * @throws RuntimeException |
|
| 2051 | - */ |
|
| 2052 | - public function set_price_paid($REG_final_price = 0.00) |
|
| 2053 | - { |
|
| 2054 | - EE_Error::doing_it_wrong( |
|
| 2055 | - 'EE_Registration::set_price_paid()', |
|
| 2056 | - esc_html__( |
|
| 2057 | - 'This method is deprecated, please use EE_Registration::set_final_price() instead.', |
|
| 2058 | - 'event_espresso' |
|
| 2059 | - ), |
|
| 2060 | - '4.7.0' |
|
| 2061 | - ); |
|
| 2062 | - $this->set_final_price($REG_final_price); |
|
| 2063 | - } |
|
| 2064 | - |
|
| 2065 | - |
|
| 2066 | - /** |
|
| 2067 | - * @deprecated |
|
| 2068 | - * @since 4.7.0 |
|
| 2069 | - * @return string |
|
| 2070 | - * @throws EE_Error |
|
| 2071 | - */ |
|
| 2072 | - public function pretty_price_paid() |
|
| 2073 | - { |
|
| 2074 | - EE_Error::doing_it_wrong( |
|
| 2075 | - 'EE_Registration::pretty_price_paid()', |
|
| 2076 | - esc_html__( |
|
| 2077 | - 'This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
| 2078 | - 'event_espresso' |
|
| 2079 | - ), |
|
| 2080 | - '4.7.0' |
|
| 2081 | - ); |
|
| 2082 | - return $this->pretty_final_price(); |
|
| 2083 | - } |
|
| 2084 | - |
|
| 2085 | - |
|
| 2086 | - /** |
|
| 2087 | - * Gets the primary datetime related to this registration via the related Event to this registration |
|
| 2088 | - * |
|
| 2089 | - * @deprecated 4.9.17 |
|
| 2090 | - * @return EE_Datetime |
|
| 2091 | - * @throws EE_Error |
|
| 2092 | - * @throws EntityNotFoundException |
|
| 2093 | - */ |
|
| 2094 | - public function get_related_primary_datetime() |
|
| 2095 | - { |
|
| 2096 | - EE_Error::doing_it_wrong( |
|
| 2097 | - __METHOD__, |
|
| 2098 | - esc_html__( |
|
| 2099 | - 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
| 2100 | - 'event_espresso' |
|
| 2101 | - ), |
|
| 2102 | - '4.9.17', |
|
| 2103 | - '5.0.0' |
|
| 2104 | - ); |
|
| 2105 | - return $this->event()->primary_datetime(); |
|
| 2106 | - } |
|
| 2107 | - |
|
| 2108 | - /** |
|
| 2109 | - * Returns the contact's name (or "Unknown" if there is no contact.) |
|
| 2110 | - * @since $VID:$ |
|
| 2111 | - * @return string |
|
| 2112 | - * @throws EE_Error |
|
| 2113 | - * @throws InvalidArgumentException |
|
| 2114 | - * @throws InvalidDataTypeException |
|
| 2115 | - * @throws InvalidInterfaceException |
|
| 2116 | - * @throws ReflectionException |
|
| 2117 | - */ |
|
| 2118 | - public function name() |
|
| 2119 | - { |
|
| 2120 | - return $this->attendeeName(); |
|
| 2121 | - } |
|
| 20 | + /** |
|
| 21 | + * Used to reference when a registration has never been checked in. |
|
| 22 | + * |
|
| 23 | + * @deprecated use \EE_Checkin::status_checked_never instead |
|
| 24 | + * @type int |
|
| 25 | + */ |
|
| 26 | + const checkin_status_never = 2; |
|
| 27 | + |
|
| 28 | + /** |
|
| 29 | + * Used to reference when a registration has been checked in. |
|
| 30 | + * |
|
| 31 | + * @deprecated use \EE_Checkin::status_checked_in instead |
|
| 32 | + * @type int |
|
| 33 | + */ |
|
| 34 | + const checkin_status_in = 1; |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * Used to reference when a registration has been checked out. |
|
| 39 | + * |
|
| 40 | + * @deprecated use \EE_Checkin::status_checked_out instead |
|
| 41 | + * @type int |
|
| 42 | + */ |
|
| 43 | + const checkin_status_out = 0; |
|
| 44 | + |
|
| 45 | + |
|
| 46 | + /** |
|
| 47 | + * extra meta key for tracking reg status os trashed registrations |
|
| 48 | + * |
|
| 49 | + * @type string |
|
| 50 | + */ |
|
| 51 | + const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
| 52 | + |
|
| 53 | + |
|
| 54 | + /** |
|
| 55 | + * extra meta key for tracking if registration has reserved ticket |
|
| 56 | + * |
|
| 57 | + * @type string |
|
| 58 | + */ |
|
| 59 | + const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
| 60 | + |
|
| 61 | + |
|
| 62 | + /** |
|
| 63 | + * @param array $props_n_values incoming values |
|
| 64 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 65 | + * used.) |
|
| 66 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 67 | + * date_format and the second value is the time format |
|
| 68 | + * @return EE_Registration |
|
| 69 | + * @throws EE_Error |
|
| 70 | + */ |
|
| 71 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 72 | + { |
|
| 73 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 74 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 75 | + } |
|
| 76 | + |
|
| 77 | + |
|
| 78 | + /** |
|
| 79 | + * @param array $props_n_values incoming values from the database |
|
| 80 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 81 | + * the website will be used. |
|
| 82 | + * @return EE_Registration |
|
| 83 | + */ |
|
| 84 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 85 | + { |
|
| 86 | + return new self($props_n_values, true, $timezone); |
|
| 87 | + } |
|
| 88 | + |
|
| 89 | + |
|
| 90 | + /** |
|
| 91 | + * Set Event ID |
|
| 92 | + * |
|
| 93 | + * @param int $EVT_ID Event ID |
|
| 94 | + * @throws EE_Error |
|
| 95 | + * @throws RuntimeException |
|
| 96 | + */ |
|
| 97 | + public function set_event($EVT_ID = 0) |
|
| 98 | + { |
|
| 99 | + $this->set('EVT_ID', $EVT_ID); |
|
| 100 | + } |
|
| 101 | + |
|
| 102 | + |
|
| 103 | + /** |
|
| 104 | + * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
| 105 | + * be routed to internal methods |
|
| 106 | + * |
|
| 107 | + * @param string $field_name |
|
| 108 | + * @param mixed $field_value |
|
| 109 | + * @param bool $use_default |
|
| 110 | + * @throws EE_Error |
|
| 111 | + * @throws EntityNotFoundException |
|
| 112 | + * @throws InvalidArgumentException |
|
| 113 | + * @throws InvalidDataTypeException |
|
| 114 | + * @throws InvalidInterfaceException |
|
| 115 | + * @throws ReflectionException |
|
| 116 | + * @throws RuntimeException |
|
| 117 | + */ |
|
| 118 | + public function set($field_name, $field_value, $use_default = false) |
|
| 119 | + { |
|
| 120 | + switch ($field_name) { |
|
| 121 | + case 'REG_code': |
|
| 122 | + if (! empty($field_value) && $this->reg_code() === null) { |
|
| 123 | + $this->set_reg_code($field_value, $use_default); |
|
| 124 | + } |
|
| 125 | + break; |
|
| 126 | + case 'STS_ID': |
|
| 127 | + $this->set_status($field_value, $use_default); |
|
| 128 | + break; |
|
| 129 | + default: |
|
| 130 | + parent::set($field_name, $field_value, $use_default); |
|
| 131 | + } |
|
| 132 | + } |
|
| 133 | + |
|
| 134 | + |
|
| 135 | + /** |
|
| 136 | + * Set Status ID |
|
| 137 | + * updates the registration status and ALSO... |
|
| 138 | + * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
| 139 | + * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
| 140 | + * |
|
| 141 | + * @param string $new_STS_ID |
|
| 142 | + * @param boolean $use_default |
|
| 143 | + * @param ContextInterface|null $context |
|
| 144 | + * @return bool |
|
| 145 | + * @throws DomainException |
|
| 146 | + * @throws EE_Error |
|
| 147 | + * @throws EntityNotFoundException |
|
| 148 | + * @throws InvalidArgumentException |
|
| 149 | + * @throws InvalidDataTypeException |
|
| 150 | + * @throws InvalidInterfaceException |
|
| 151 | + * @throws ReflectionException |
|
| 152 | + * @throws RuntimeException |
|
| 153 | + * @throws UnexpectedEntityException |
|
| 154 | + */ |
|
| 155 | + public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null) |
|
| 156 | + { |
|
| 157 | + // get current REG_Status |
|
| 158 | + $old_STS_ID = $this->status_ID(); |
|
| 159 | + // if status has changed |
|
| 160 | + if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
| 161 | + && ! empty($old_STS_ID) // and that old status is actually set |
|
| 162 | + && ! empty($new_STS_ID) // as well as the new status |
|
| 163 | + && $this->ID() // ensure registration is in the db |
|
| 164 | + ) { |
|
| 165 | + // update internal status first |
|
| 166 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 167 | + // THEN handle other changes that occur when reg status changes |
|
| 168 | + // TO approved |
|
| 169 | + if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
| 170 | + // reserve a space by incrementing ticket and datetime sold values |
|
| 171 | + $this->reserveRegistrationSpace(); |
|
| 172 | + do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 173 | + // OR FROM approved |
|
| 174 | + } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
| 175 | + // release a space by decrementing ticket and datetime sold values |
|
| 176 | + $this->releaseRegistrationSpace(); |
|
| 177 | + do_action( |
|
| 178 | + 'AHEE__EE_Registration__set_status__from_approved', |
|
| 179 | + $this, |
|
| 180 | + $old_STS_ID, |
|
| 181 | + $new_STS_ID, |
|
| 182 | + $context |
|
| 183 | + ); |
|
| 184 | + } |
|
| 185 | + // update status |
|
| 186 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 187 | + $this->updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, $context); |
|
| 188 | + if ($this->statusChangeUpdatesTransaction($context)) { |
|
| 189 | + $this->updateTransactionAfterStatusChange(); |
|
| 190 | + } |
|
| 191 | + do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 192 | + return true; |
|
| 193 | + } |
|
| 194 | + // even though the old value matches the new value, it's still good to |
|
| 195 | + // allow the parent set method to have a say |
|
| 196 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 197 | + return true; |
|
| 198 | + } |
|
| 199 | + |
|
| 200 | + |
|
| 201 | + /** |
|
| 202 | + * update REGs and TXN when cancelled or declined registrations involved |
|
| 203 | + * |
|
| 204 | + * @param string $new_STS_ID |
|
| 205 | + * @param string $old_STS_ID |
|
| 206 | + * @param ContextInterface|null $context |
|
| 207 | + * @throws EE_Error |
|
| 208 | + * @throws InvalidArgumentException |
|
| 209 | + * @throws InvalidDataTypeException |
|
| 210 | + * @throws InvalidInterfaceException |
|
| 211 | + * @throws ReflectionException |
|
| 212 | + * @throws RuntimeException |
|
| 213 | + */ |
|
| 214 | + private function updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, ContextInterface $context = null) |
|
| 215 | + { |
|
| 216 | + // these reg statuses should not be considered in any calculations involving monies owing |
|
| 217 | + $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
| 218 | + // true if registration has been cancelled or declined |
|
| 219 | + $this->updateIfCanceled( |
|
| 220 | + $closed_reg_statuses, |
|
| 221 | + $new_STS_ID, |
|
| 222 | + $old_STS_ID, |
|
| 223 | + $context |
|
| 224 | + ); |
|
| 225 | + $this->updateIfReinstated( |
|
| 226 | + $closed_reg_statuses, |
|
| 227 | + $new_STS_ID, |
|
| 228 | + $old_STS_ID, |
|
| 229 | + $context |
|
| 230 | + ); |
|
| 231 | + } |
|
| 232 | + |
|
| 233 | + |
|
| 234 | + /** |
|
| 235 | + * update REGs and TXN when cancelled or declined registrations involved |
|
| 236 | + * |
|
| 237 | + * @param array $closed_reg_statuses |
|
| 238 | + * @param string $new_STS_ID |
|
| 239 | + * @param string $old_STS_ID |
|
| 240 | + * @param ContextInterface|null $context |
|
| 241 | + * @throws EE_Error |
|
| 242 | + * @throws InvalidArgumentException |
|
| 243 | + * @throws InvalidDataTypeException |
|
| 244 | + * @throws InvalidInterfaceException |
|
| 245 | + * @throws ReflectionException |
|
| 246 | + * @throws RuntimeException |
|
| 247 | + */ |
|
| 248 | + private function updateIfCanceled( |
|
| 249 | + array $closed_reg_statuses, |
|
| 250 | + $new_STS_ID, |
|
| 251 | + $old_STS_ID, |
|
| 252 | + ContextInterface $context = null |
|
| 253 | + ) { |
|
| 254 | + // true if registration has been cancelled or declined |
|
| 255 | + if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 256 | + && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 257 | + ) { |
|
| 258 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 259 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 260 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 261 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 262 | + // cancelled or declined registration |
|
| 263 | + $registration_processor->update_registration_after_being_canceled_or_declined( |
|
| 264 | + $this, |
|
| 265 | + $closed_reg_statuses |
|
| 266 | + ); |
|
| 267 | + $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
| 268 | + $this, |
|
| 269 | + $closed_reg_statuses, |
|
| 270 | + false |
|
| 271 | + ); |
|
| 272 | + do_action( |
|
| 273 | + 'AHEE__EE_Registration__set_status__canceled_or_declined', |
|
| 274 | + $this, |
|
| 275 | + $old_STS_ID, |
|
| 276 | + $new_STS_ID, |
|
| 277 | + $context |
|
| 278 | + ); |
|
| 279 | + return; |
|
| 280 | + } |
|
| 281 | + } |
|
| 282 | + |
|
| 283 | + |
|
| 284 | + /** |
|
| 285 | + * update REGs and TXN when cancelled or declined registrations involved |
|
| 286 | + * |
|
| 287 | + * @param array $closed_reg_statuses |
|
| 288 | + * @param string $new_STS_ID |
|
| 289 | + * @param string $old_STS_ID |
|
| 290 | + * @param ContextInterface|null $context |
|
| 291 | + * @throws EE_Error |
|
| 292 | + * @throws InvalidArgumentException |
|
| 293 | + * @throws InvalidDataTypeException |
|
| 294 | + * @throws InvalidInterfaceException |
|
| 295 | + * @throws ReflectionException |
|
| 296 | + */ |
|
| 297 | + private function updateIfReinstated( |
|
| 298 | + array $closed_reg_statuses, |
|
| 299 | + $new_STS_ID, |
|
| 300 | + $old_STS_ID, |
|
| 301 | + ContextInterface $context = null |
|
| 302 | + ) { |
|
| 303 | + // true if reinstating cancelled or declined registration |
|
| 304 | + if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 305 | + && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 306 | + ) { |
|
| 307 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 308 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 309 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 310 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 311 | + // reinstating cancelled or declined registration |
|
| 312 | + $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
| 313 | + $this, |
|
| 314 | + $closed_reg_statuses |
|
| 315 | + ); |
|
| 316 | + $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
| 317 | + $this, |
|
| 318 | + $closed_reg_statuses, |
|
| 319 | + false |
|
| 320 | + ); |
|
| 321 | + do_action( |
|
| 322 | + 'AHEE__EE_Registration__set_status__after_reinstated', |
|
| 323 | + $this, |
|
| 324 | + $old_STS_ID, |
|
| 325 | + $new_STS_ID, |
|
| 326 | + $context |
|
| 327 | + ); |
|
| 328 | + } |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + |
|
| 332 | + /** |
|
| 333 | + * @param ContextInterface|null $context |
|
| 334 | + * @return bool |
|
| 335 | + */ |
|
| 336 | + private function statusChangeUpdatesTransaction(ContextInterface $context = null) |
|
| 337 | + { |
|
| 338 | + $contexts_that_do_not_update_transaction = (array) apply_filters( |
|
| 339 | + 'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction', |
|
| 340 | + array('spco_reg_step_attendee_information_process_registrations'), |
|
| 341 | + $context, |
|
| 342 | + $this |
|
| 343 | + ); |
|
| 344 | + return ! ( |
|
| 345 | + $context instanceof ContextInterface |
|
| 346 | + && in_array($context->slug(), $contexts_that_do_not_update_transaction, true) |
|
| 347 | + ); |
|
| 348 | + } |
|
| 349 | + |
|
| 350 | + |
|
| 351 | + /** |
|
| 352 | + * @throws EE_Error |
|
| 353 | + * @throws EntityNotFoundException |
|
| 354 | + * @throws InvalidArgumentException |
|
| 355 | + * @throws InvalidDataTypeException |
|
| 356 | + * @throws InvalidInterfaceException |
|
| 357 | + * @throws ReflectionException |
|
| 358 | + * @throws RuntimeException |
|
| 359 | + */ |
|
| 360 | + private function updateTransactionAfterStatusChange() |
|
| 361 | + { |
|
| 362 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
| 363 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
| 364 | + $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
| 365 | + $this->transaction()->update_status_based_on_total_paid(true); |
|
| 366 | + } |
|
| 367 | + |
|
| 368 | + |
|
| 369 | + /** |
|
| 370 | + * get Status ID |
|
| 371 | + */ |
|
| 372 | + public function status_ID() |
|
| 373 | + { |
|
| 374 | + return $this->get('STS_ID'); |
|
| 375 | + } |
|
| 376 | + |
|
| 377 | + |
|
| 378 | + /** |
|
| 379 | + * Gets the ticket this registration is for |
|
| 380 | + * |
|
| 381 | + * @param boolean $include_archived whether to include archived tickets or not. |
|
| 382 | + * |
|
| 383 | + * @return EE_Ticket|EE_Base_Class |
|
| 384 | + * @throws EE_Error |
|
| 385 | + */ |
|
| 386 | + public function ticket($include_archived = true) |
|
| 387 | + { |
|
| 388 | + $query_params = array(); |
|
| 389 | + if ($include_archived) { |
|
| 390 | + $query_params['default_where_conditions'] = 'none'; |
|
| 391 | + } |
|
| 392 | + return $this->get_first_related('Ticket', $query_params); |
|
| 393 | + } |
|
| 394 | + |
|
| 395 | + |
|
| 396 | + /** |
|
| 397 | + * Gets the event this registration is for |
|
| 398 | + * |
|
| 399 | + * @return EE_Event |
|
| 400 | + * @throws EE_Error |
|
| 401 | + * @throws EntityNotFoundException |
|
| 402 | + */ |
|
| 403 | + public function event() |
|
| 404 | + { |
|
| 405 | + $event = $this->get_first_related('Event'); |
|
| 406 | + if (! $event instanceof \EE_Event) { |
|
| 407 | + throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
| 408 | + } |
|
| 409 | + return $event; |
|
| 410 | + } |
|
| 411 | + |
|
| 412 | + |
|
| 413 | + /** |
|
| 414 | + * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
| 415 | + * with the author of the event this registration is for. |
|
| 416 | + * |
|
| 417 | + * @since 4.5.0 |
|
| 418 | + * @return int |
|
| 419 | + * @throws EE_Error |
|
| 420 | + * @throws EntityNotFoundException |
|
| 421 | + */ |
|
| 422 | + public function wp_user() |
|
| 423 | + { |
|
| 424 | + $event = $this->event(); |
|
| 425 | + if ($event instanceof EE_Event) { |
|
| 426 | + return $event->wp_user(); |
|
| 427 | + } |
|
| 428 | + return 0; |
|
| 429 | + } |
|
| 430 | + |
|
| 431 | + |
|
| 432 | + /** |
|
| 433 | + * increments this registration's related ticket sold and corresponding datetime sold values |
|
| 434 | + * |
|
| 435 | + * @return void |
|
| 436 | + * @throws DomainException |
|
| 437 | + * @throws EE_Error |
|
| 438 | + * @throws EntityNotFoundException |
|
| 439 | + * @throws InvalidArgumentException |
|
| 440 | + * @throws InvalidDataTypeException |
|
| 441 | + * @throws InvalidInterfaceException |
|
| 442 | + * @throws ReflectionException |
|
| 443 | + * @throws UnexpectedEntityException |
|
| 444 | + */ |
|
| 445 | + private function reserveRegistrationSpace() |
|
| 446 | + { |
|
| 447 | + // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
| 448 | + // so stop tracking that this reg has a ticket reserved |
|
| 449 | + $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 450 | + $ticket = $this->ticket(); |
|
| 451 | + $ticket->increaseSold(); |
|
| 452 | + // possibly set event status to sold out |
|
| 453 | + $this->event()->perform_sold_out_status_check(); |
|
| 454 | + } |
|
| 455 | + |
|
| 456 | + |
|
| 457 | + /** |
|
| 458 | + * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
| 459 | + * |
|
| 460 | + * @return void |
|
| 461 | + * @throws DomainException |
|
| 462 | + * @throws EE_Error |
|
| 463 | + * @throws EntityNotFoundException |
|
| 464 | + * @throws InvalidArgumentException |
|
| 465 | + * @throws InvalidDataTypeException |
|
| 466 | + * @throws InvalidInterfaceException |
|
| 467 | + * @throws ReflectionException |
|
| 468 | + * @throws UnexpectedEntityException |
|
| 469 | + */ |
|
| 470 | + private function releaseRegistrationSpace() |
|
| 471 | + { |
|
| 472 | + $ticket = $this->ticket(); |
|
| 473 | + $ticket->decreaseSold(); |
|
| 474 | + // possibly change event status from sold out back to previous status |
|
| 475 | + $this->event()->perform_sold_out_status_check(); |
|
| 476 | + } |
|
| 477 | + |
|
| 478 | + |
|
| 479 | + /** |
|
| 480 | + * tracks this registration's ticket reservation in extra meta |
|
| 481 | + * and can increment related ticket reserved and corresponding datetime reserved values |
|
| 482 | + * |
|
| 483 | + * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
| 484 | + * @return void |
|
| 485 | + * @throws EE_Error |
|
| 486 | + * @throws InvalidArgumentException |
|
| 487 | + * @throws InvalidDataTypeException |
|
| 488 | + * @throws InvalidInterfaceException |
|
| 489 | + * @throws ReflectionException |
|
| 490 | + */ |
|
| 491 | + public function reserve_ticket($update_ticket = false, $source = 'unknown') |
|
| 492 | + { |
|
| 493 | + // only reserve ticket if space is not currently reserved |
|
| 494 | + if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) !== true) { |
|
| 495 | + $this->update_extra_meta('reserve_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 496 | + // IMPORTANT !!! |
|
| 497 | + // although checking $update_ticket first would be more efficient, |
|
| 498 | + // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 499 | + if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) |
|
| 500 | + && $update_ticket |
|
| 501 | + ) { |
|
| 502 | + $ticket = $this->ticket(); |
|
| 503 | + $ticket->increaseReserved(1, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 504 | + $ticket->save(); |
|
| 505 | + } |
|
| 506 | + } |
|
| 507 | + } |
|
| 508 | + |
|
| 509 | + |
|
| 510 | + /** |
|
| 511 | + * stops tracking this registration's ticket reservation in extra meta |
|
| 512 | + * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
| 513 | + * |
|
| 514 | + * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
| 515 | + * @return void |
|
| 516 | + * @throws EE_Error |
|
| 517 | + * @throws InvalidArgumentException |
|
| 518 | + * @throws InvalidDataTypeException |
|
| 519 | + * @throws InvalidInterfaceException |
|
| 520 | + * @throws ReflectionException |
|
| 521 | + */ |
|
| 522 | + public function release_reserved_ticket($update_ticket = false, $source = 'unknown') |
|
| 523 | + { |
|
| 524 | + // only release ticket if space is currently reserved |
|
| 525 | + if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) === true) { |
|
| 526 | + $this->update_extra_meta('release_reserved_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 527 | + // IMPORTANT !!! |
|
| 528 | + // although checking $update_ticket first would be more efficient, |
|
| 529 | + // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 530 | + if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, false) |
|
| 531 | + && $update_ticket |
|
| 532 | + ) { |
|
| 533 | + $ticket = $this->ticket(); |
|
| 534 | + $ticket->decreaseReserved(1, true, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 535 | + } |
|
| 536 | + } |
|
| 537 | + } |
|
| 538 | + |
|
| 539 | + |
|
| 540 | + /** |
|
| 541 | + * Set Attendee ID |
|
| 542 | + * |
|
| 543 | + * @param int $ATT_ID Attendee ID |
|
| 544 | + * @throws EE_Error |
|
| 545 | + * @throws RuntimeException |
|
| 546 | + */ |
|
| 547 | + public function set_attendee_id($ATT_ID = 0) |
|
| 548 | + { |
|
| 549 | + $this->set('ATT_ID', $ATT_ID); |
|
| 550 | + } |
|
| 551 | + |
|
| 552 | + |
|
| 553 | + /** |
|
| 554 | + * Set Transaction ID |
|
| 555 | + * |
|
| 556 | + * @param int $TXN_ID Transaction ID |
|
| 557 | + * @throws EE_Error |
|
| 558 | + * @throws RuntimeException |
|
| 559 | + */ |
|
| 560 | + public function set_transaction_id($TXN_ID = 0) |
|
| 561 | + { |
|
| 562 | + $this->set('TXN_ID', $TXN_ID); |
|
| 563 | + } |
|
| 564 | + |
|
| 565 | + |
|
| 566 | + /** |
|
| 567 | + * Set Session |
|
| 568 | + * |
|
| 569 | + * @param string $REG_session PHP Session ID |
|
| 570 | + * @throws EE_Error |
|
| 571 | + * @throws RuntimeException |
|
| 572 | + */ |
|
| 573 | + public function set_session($REG_session = '') |
|
| 574 | + { |
|
| 575 | + $this->set('REG_session', $REG_session); |
|
| 576 | + } |
|
| 577 | + |
|
| 578 | + |
|
| 579 | + /** |
|
| 580 | + * Set Registration URL Link |
|
| 581 | + * |
|
| 582 | + * @param string $REG_url_link Registration URL Link |
|
| 583 | + * @throws EE_Error |
|
| 584 | + * @throws RuntimeException |
|
| 585 | + */ |
|
| 586 | + public function set_reg_url_link($REG_url_link = '') |
|
| 587 | + { |
|
| 588 | + $this->set('REG_url_link', $REG_url_link); |
|
| 589 | + } |
|
| 590 | + |
|
| 591 | + |
|
| 592 | + /** |
|
| 593 | + * Set Attendee Counter |
|
| 594 | + * |
|
| 595 | + * @param int $REG_count Primary Attendee |
|
| 596 | + * @throws EE_Error |
|
| 597 | + * @throws RuntimeException |
|
| 598 | + */ |
|
| 599 | + public function set_count($REG_count = 1) |
|
| 600 | + { |
|
| 601 | + $this->set('REG_count', $REG_count); |
|
| 602 | + } |
|
| 603 | + |
|
| 604 | + |
|
| 605 | + /** |
|
| 606 | + * Set Group Size |
|
| 607 | + * |
|
| 608 | + * @param boolean $REG_group_size Group Registration |
|
| 609 | + * @throws EE_Error |
|
| 610 | + * @throws RuntimeException |
|
| 611 | + */ |
|
| 612 | + public function set_group_size($REG_group_size = false) |
|
| 613 | + { |
|
| 614 | + $this->set('REG_group_size', $REG_group_size); |
|
| 615 | + } |
|
| 616 | + |
|
| 617 | + |
|
| 618 | + /** |
|
| 619 | + * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
| 620 | + * EEM_Registration::status_id_not_approved |
|
| 621 | + * |
|
| 622 | + * @return boolean |
|
| 623 | + */ |
|
| 624 | + public function is_not_approved() |
|
| 625 | + { |
|
| 626 | + return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
| 627 | + } |
|
| 628 | + |
|
| 629 | + |
|
| 630 | + /** |
|
| 631 | + * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
| 632 | + * EEM_Registration::status_id_pending_payment |
|
| 633 | + * |
|
| 634 | + * @return boolean |
|
| 635 | + */ |
|
| 636 | + public function is_pending_payment() |
|
| 637 | + { |
|
| 638 | + return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
| 639 | + } |
|
| 640 | + |
|
| 641 | + |
|
| 642 | + /** |
|
| 643 | + * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
| 644 | + * |
|
| 645 | + * @return boolean |
|
| 646 | + */ |
|
| 647 | + public function is_approved() |
|
| 648 | + { |
|
| 649 | + return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
| 650 | + } |
|
| 651 | + |
|
| 652 | + |
|
| 653 | + /** |
|
| 654 | + * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
| 655 | + * |
|
| 656 | + * @return boolean |
|
| 657 | + */ |
|
| 658 | + public function is_cancelled() |
|
| 659 | + { |
|
| 660 | + return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
| 661 | + } |
|
| 662 | + |
|
| 663 | + |
|
| 664 | + /** |
|
| 665 | + * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
| 666 | + * |
|
| 667 | + * @return boolean |
|
| 668 | + */ |
|
| 669 | + public function is_declined() |
|
| 670 | + { |
|
| 671 | + return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
| 672 | + } |
|
| 673 | + |
|
| 674 | + |
|
| 675 | + /** |
|
| 676 | + * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
| 677 | + * EEM_Registration::status_id_incomplete |
|
| 678 | + * |
|
| 679 | + * @return boolean |
|
| 680 | + */ |
|
| 681 | + public function is_incomplete() |
|
| 682 | + { |
|
| 683 | + return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
| 684 | + } |
|
| 685 | + |
|
| 686 | + |
|
| 687 | + /** |
|
| 688 | + * Set Registration Date |
|
| 689 | + * |
|
| 690 | + * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
| 691 | + * Date |
|
| 692 | + * @throws EE_Error |
|
| 693 | + * @throws RuntimeException |
|
| 694 | + */ |
|
| 695 | + public function set_reg_date($REG_date = false) |
|
| 696 | + { |
|
| 697 | + $this->set('REG_date', $REG_date); |
|
| 698 | + } |
|
| 699 | + |
|
| 700 | + |
|
| 701 | + /** |
|
| 702 | + * Set final price owing for this registration after all ticket/price modifications |
|
| 703 | + * |
|
| 704 | + * @access public |
|
| 705 | + * @param float $REG_final_price |
|
| 706 | + * @throws EE_Error |
|
| 707 | + * @throws RuntimeException |
|
| 708 | + */ |
|
| 709 | + public function set_final_price($REG_final_price = 0.00) |
|
| 710 | + { |
|
| 711 | + $this->set('REG_final_price', $REG_final_price); |
|
| 712 | + } |
|
| 713 | + |
|
| 714 | + |
|
| 715 | + /** |
|
| 716 | + * Set amount paid towards this registration's final price |
|
| 717 | + * |
|
| 718 | + * @access public |
|
| 719 | + * @param float $REG_paid |
|
| 720 | + * @throws EE_Error |
|
| 721 | + * @throws RuntimeException |
|
| 722 | + */ |
|
| 723 | + public function set_paid($REG_paid = 0.00) |
|
| 724 | + { |
|
| 725 | + $this->set('REG_paid', $REG_paid); |
|
| 726 | + } |
|
| 727 | + |
|
| 728 | + |
|
| 729 | + /** |
|
| 730 | + * Attendee Is Going |
|
| 731 | + * |
|
| 732 | + * @param boolean $REG_att_is_going Attendee Is Going |
|
| 733 | + * @throws EE_Error |
|
| 734 | + * @throws RuntimeException |
|
| 735 | + */ |
|
| 736 | + public function set_att_is_going($REG_att_is_going = false) |
|
| 737 | + { |
|
| 738 | + $this->set('REG_att_is_going', $REG_att_is_going); |
|
| 739 | + } |
|
| 740 | + |
|
| 741 | + |
|
| 742 | + /** |
|
| 743 | + * Gets the related attendee |
|
| 744 | + * |
|
| 745 | + * @return EE_Attendee |
|
| 746 | + * @throws EE_Error |
|
| 747 | + */ |
|
| 748 | + public function attendee() |
|
| 749 | + { |
|
| 750 | + return $this->get_first_related('Attendee'); |
|
| 751 | + } |
|
| 752 | + |
|
| 753 | + /** |
|
| 754 | + * Gets the name of the attendee. |
|
| 755 | + * @since $VID:$ |
|
| 756 | + * @param bool $apply_html_entities set to true if you want to use HTML entities. |
|
| 757 | + * @return string |
|
| 758 | + * @throws EE_Error |
|
| 759 | + * @throws InvalidArgumentException |
|
| 760 | + * @throws InvalidDataTypeException |
|
| 761 | + * @throws InvalidInterfaceException |
|
| 762 | + * @throws ReflectionException |
|
| 763 | + */ |
|
| 764 | + public function attendeeName($apply_html_entities = false) |
|
| 765 | + { |
|
| 766 | + $attendee = $this->get_first_related('Attendee'); |
|
| 767 | + if ($attendee instanceof EE_Attendee) { |
|
| 768 | + $attendee_name = $attendee->full_name($apply_html_entities); |
|
| 769 | + } else { |
|
| 770 | + $attendee_name = esc_html__('Unknown', 'event_espresso'); |
|
| 771 | + } |
|
| 772 | + return $attendee_name; |
|
| 773 | + } |
|
| 774 | + |
|
| 775 | + |
|
| 776 | + /** |
|
| 777 | + * get Event ID |
|
| 778 | + */ |
|
| 779 | + public function event_ID() |
|
| 780 | + { |
|
| 781 | + return $this->get('EVT_ID'); |
|
| 782 | + } |
|
| 783 | + |
|
| 784 | + |
|
| 785 | + /** |
|
| 786 | + * get Event ID |
|
| 787 | + */ |
|
| 788 | + public function event_name() |
|
| 789 | + { |
|
| 790 | + $event = $this->event_obj(); |
|
| 791 | + if ($event) { |
|
| 792 | + return $event->name(); |
|
| 793 | + } else { |
|
| 794 | + return null; |
|
| 795 | + } |
|
| 796 | + } |
|
| 797 | + |
|
| 798 | + |
|
| 799 | + /** |
|
| 800 | + * Fetches the event this registration is for |
|
| 801 | + * |
|
| 802 | + * @return EE_Event |
|
| 803 | + * @throws EE_Error |
|
| 804 | + */ |
|
| 805 | + public function event_obj() |
|
| 806 | + { |
|
| 807 | + return $this->get_first_related('Event'); |
|
| 808 | + } |
|
| 809 | + |
|
| 810 | + |
|
| 811 | + /** |
|
| 812 | + * get Attendee ID |
|
| 813 | + */ |
|
| 814 | + public function attendee_ID() |
|
| 815 | + { |
|
| 816 | + return $this->get('ATT_ID'); |
|
| 817 | + } |
|
| 818 | + |
|
| 819 | + |
|
| 820 | + /** |
|
| 821 | + * get PHP Session ID |
|
| 822 | + */ |
|
| 823 | + public function session_ID() |
|
| 824 | + { |
|
| 825 | + return $this->get('REG_session'); |
|
| 826 | + } |
|
| 827 | + |
|
| 828 | + |
|
| 829 | + /** |
|
| 830 | + * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
| 831 | + * |
|
| 832 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 833 | + * @return string |
|
| 834 | + */ |
|
| 835 | + public function receipt_url($messenger = 'html') |
|
| 836 | + { |
|
| 837 | + |
|
| 838 | + /** |
|
| 839 | + * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
| 840 | + * already in use on old system. If there is then we just return the standard url for it. |
|
| 841 | + * |
|
| 842 | + * @since 4.5.0 |
|
| 843 | + */ |
|
| 844 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
| 845 | + $has_custom = EEH_Template::locate_template( |
|
| 846 | + $template_relative_path, |
|
| 847 | + array(), |
|
| 848 | + true, |
|
| 849 | + true, |
|
| 850 | + true |
|
| 851 | + ); |
|
| 852 | + |
|
| 853 | + if ($has_custom) { |
|
| 854 | + return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
| 855 | + } |
|
| 856 | + return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
| 857 | + } |
|
| 858 | + |
|
| 859 | + |
|
| 860 | + /** |
|
| 861 | + * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
| 862 | + * |
|
| 863 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 864 | + * @return string |
|
| 865 | + * @throws EE_Error |
|
| 866 | + */ |
|
| 867 | + public function invoice_url($messenger = 'html') |
|
| 868 | + { |
|
| 869 | + /** |
|
| 870 | + * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
| 871 | + * already in use on old system. If there is then we just return the standard url for it. |
|
| 872 | + * |
|
| 873 | + * @since 4.5.0 |
|
| 874 | + */ |
|
| 875 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
| 876 | + $has_custom = EEH_Template::locate_template( |
|
| 877 | + $template_relative_path, |
|
| 878 | + array(), |
|
| 879 | + true, |
|
| 880 | + true, |
|
| 881 | + true |
|
| 882 | + ); |
|
| 883 | + |
|
| 884 | + if ($has_custom) { |
|
| 885 | + if ($messenger == 'html') { |
|
| 886 | + return $this->invoice_url('launch'); |
|
| 887 | + } |
|
| 888 | + $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
| 889 | + |
|
| 890 | + $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
| 891 | + if ($messenger == 'html') { |
|
| 892 | + $query_args['html'] = true; |
|
| 893 | + } |
|
| 894 | + return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
| 895 | + } |
|
| 896 | + return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
| 897 | + } |
|
| 898 | + |
|
| 899 | + |
|
| 900 | + /** |
|
| 901 | + * get Registration URL Link |
|
| 902 | + * |
|
| 903 | + * @access public |
|
| 904 | + * @return string |
|
| 905 | + * @throws EE_Error |
|
| 906 | + */ |
|
| 907 | + public function reg_url_link() |
|
| 908 | + { |
|
| 909 | + return (string) $this->get('REG_url_link'); |
|
| 910 | + } |
|
| 911 | + |
|
| 912 | + |
|
| 913 | + /** |
|
| 914 | + * Echoes out invoice_url() |
|
| 915 | + * |
|
| 916 | + * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
| 917 | + * @return void |
|
| 918 | + * @throws EE_Error |
|
| 919 | + */ |
|
| 920 | + public function e_invoice_url($type = 'launch') |
|
| 921 | + { |
|
| 922 | + echo $this->invoice_url($type); |
|
| 923 | + } |
|
| 924 | + |
|
| 925 | + |
|
| 926 | + /** |
|
| 927 | + * Echoes out payment_overview_url |
|
| 928 | + */ |
|
| 929 | + public function e_payment_overview_url() |
|
| 930 | + { |
|
| 931 | + echo $this->payment_overview_url(); |
|
| 932 | + } |
|
| 933 | + |
|
| 934 | + |
|
| 935 | + /** |
|
| 936 | + * Gets the URL for the checkout payment options reg step |
|
| 937 | + * with this registration's REG_url_link added as a query parameter |
|
| 938 | + * |
|
| 939 | + * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
| 940 | + * payment overview url. |
|
| 941 | + * @return string |
|
| 942 | + * @throws InvalidInterfaceException |
|
| 943 | + * @throws InvalidDataTypeException |
|
| 944 | + * @throws EE_Error |
|
| 945 | + * @throws InvalidArgumentException |
|
| 946 | + */ |
|
| 947 | + public function payment_overview_url($clear_session = false) |
|
| 948 | + { |
|
| 949 | + return add_query_arg( |
|
| 950 | + (array) apply_filters( |
|
| 951 | + 'FHEE__EE_Registration__payment_overview_url__query_args', |
|
| 952 | + array( |
|
| 953 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
| 954 | + 'step' => 'payment_options', |
|
| 955 | + 'revisit' => true, |
|
| 956 | + 'clear_session' => (bool) $clear_session, |
|
| 957 | + ), |
|
| 958 | + $this |
|
| 959 | + ), |
|
| 960 | + EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 961 | + ); |
|
| 962 | + } |
|
| 963 | + |
|
| 964 | + |
|
| 965 | + /** |
|
| 966 | + * Gets the URL for the checkout attendee information reg step |
|
| 967 | + * with this registration's REG_url_link added as a query parameter |
|
| 968 | + * |
|
| 969 | + * @return string |
|
| 970 | + * @throws InvalidInterfaceException |
|
| 971 | + * @throws InvalidDataTypeException |
|
| 972 | + * @throws EE_Error |
|
| 973 | + * @throws InvalidArgumentException |
|
| 974 | + */ |
|
| 975 | + public function edit_attendee_information_url() |
|
| 976 | + { |
|
| 977 | + return add_query_arg( |
|
| 978 | + (array) apply_filters( |
|
| 979 | + 'FHEE__EE_Registration__edit_attendee_information_url__query_args', |
|
| 980 | + array( |
|
| 981 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
| 982 | + 'step' => 'attendee_information', |
|
| 983 | + 'revisit' => true, |
|
| 984 | + ), |
|
| 985 | + $this |
|
| 986 | + ), |
|
| 987 | + EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 988 | + ); |
|
| 989 | + } |
|
| 990 | + |
|
| 991 | + |
|
| 992 | + /** |
|
| 993 | + * Simply generates and returns the appropriate admin_url link to edit this registration |
|
| 994 | + * |
|
| 995 | + * @return string |
|
| 996 | + * @throws EE_Error |
|
| 997 | + */ |
|
| 998 | + public function get_admin_edit_url() |
|
| 999 | + { |
|
| 1000 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1001 | + array( |
|
| 1002 | + 'page' => 'espresso_registrations', |
|
| 1003 | + 'action' => 'view_registration', |
|
| 1004 | + '_REG_ID' => $this->ID(), |
|
| 1005 | + ), |
|
| 1006 | + admin_url('admin.php') |
|
| 1007 | + ); |
|
| 1008 | + } |
|
| 1009 | + |
|
| 1010 | + |
|
| 1011 | + /** |
|
| 1012 | + * is_primary_registrant? |
|
| 1013 | + */ |
|
| 1014 | + public function is_primary_registrant() |
|
| 1015 | + { |
|
| 1016 | + return $this->get('REG_count') === 1 ? true : false; |
|
| 1017 | + } |
|
| 1018 | + |
|
| 1019 | + |
|
| 1020 | + /** |
|
| 1021 | + * This returns the primary registration object for this registration group (which may be this object). |
|
| 1022 | + * |
|
| 1023 | + * @return EE_Registration |
|
| 1024 | + * @throws EE_Error |
|
| 1025 | + */ |
|
| 1026 | + public function get_primary_registration() |
|
| 1027 | + { |
|
| 1028 | + if ($this->is_primary_registrant()) { |
|
| 1029 | + return $this; |
|
| 1030 | + } |
|
| 1031 | + |
|
| 1032 | + // k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
| 1033 | + /** @var EE_Registration $primary_registrant */ |
|
| 1034 | + $primary_registrant = EEM_Registration::instance()->get_one( |
|
| 1035 | + array( |
|
| 1036 | + array( |
|
| 1037 | + 'TXN_ID' => $this->transaction_ID(), |
|
| 1038 | + 'REG_count' => 1, |
|
| 1039 | + ), |
|
| 1040 | + ) |
|
| 1041 | + ); |
|
| 1042 | + return $primary_registrant; |
|
| 1043 | + } |
|
| 1044 | + |
|
| 1045 | + |
|
| 1046 | + /** |
|
| 1047 | + * get Attendee Number |
|
| 1048 | + * |
|
| 1049 | + * @access public |
|
| 1050 | + */ |
|
| 1051 | + public function count() |
|
| 1052 | + { |
|
| 1053 | + return $this->get('REG_count'); |
|
| 1054 | + } |
|
| 1055 | + |
|
| 1056 | + |
|
| 1057 | + /** |
|
| 1058 | + * get Group Size |
|
| 1059 | + */ |
|
| 1060 | + public function group_size() |
|
| 1061 | + { |
|
| 1062 | + return $this->get('REG_group_size'); |
|
| 1063 | + } |
|
| 1064 | + |
|
| 1065 | + |
|
| 1066 | + /** |
|
| 1067 | + * get Registration Date |
|
| 1068 | + */ |
|
| 1069 | + public function date() |
|
| 1070 | + { |
|
| 1071 | + return $this->get('REG_date'); |
|
| 1072 | + } |
|
| 1073 | + |
|
| 1074 | + |
|
| 1075 | + /** |
|
| 1076 | + * gets a pretty date |
|
| 1077 | + * |
|
| 1078 | + * @param string $date_format |
|
| 1079 | + * @param string $time_format |
|
| 1080 | + * @return string |
|
| 1081 | + * @throws EE_Error |
|
| 1082 | + */ |
|
| 1083 | + public function pretty_date($date_format = null, $time_format = null) |
|
| 1084 | + { |
|
| 1085 | + return $this->get_datetime('REG_date', $date_format, $time_format); |
|
| 1086 | + } |
|
| 1087 | + |
|
| 1088 | + |
|
| 1089 | + /** |
|
| 1090 | + * final_price |
|
| 1091 | + * the registration's share of the transaction total, so that the |
|
| 1092 | + * sum of all the transaction's REG_final_prices equal the transaction's total |
|
| 1093 | + * |
|
| 1094 | + * @return float |
|
| 1095 | + * @throws EE_Error |
|
| 1096 | + */ |
|
| 1097 | + public function final_price() |
|
| 1098 | + { |
|
| 1099 | + return $this->get('REG_final_price'); |
|
| 1100 | + } |
|
| 1101 | + |
|
| 1102 | + |
|
| 1103 | + /** |
|
| 1104 | + * pretty_final_price |
|
| 1105 | + * final price as formatted string, with correct decimal places and currency symbol |
|
| 1106 | + * |
|
| 1107 | + * @return string |
|
| 1108 | + * @throws EE_Error |
|
| 1109 | + */ |
|
| 1110 | + public function pretty_final_price() |
|
| 1111 | + { |
|
| 1112 | + return $this->get_pretty('REG_final_price'); |
|
| 1113 | + } |
|
| 1114 | + |
|
| 1115 | + |
|
| 1116 | + /** |
|
| 1117 | + * get paid (yeah) |
|
| 1118 | + * |
|
| 1119 | + * @return float |
|
| 1120 | + * @throws EE_Error |
|
| 1121 | + */ |
|
| 1122 | + public function paid() |
|
| 1123 | + { |
|
| 1124 | + return $this->get('REG_paid'); |
|
| 1125 | + } |
|
| 1126 | + |
|
| 1127 | + |
|
| 1128 | + /** |
|
| 1129 | + * pretty_paid |
|
| 1130 | + * |
|
| 1131 | + * @return float |
|
| 1132 | + * @throws EE_Error |
|
| 1133 | + */ |
|
| 1134 | + public function pretty_paid() |
|
| 1135 | + { |
|
| 1136 | + return $this->get_pretty('REG_paid'); |
|
| 1137 | + } |
|
| 1138 | + |
|
| 1139 | + |
|
| 1140 | + /** |
|
| 1141 | + * owes_monies_and_can_pay |
|
| 1142 | + * whether or not this registration has monies owing and it's' status allows payment |
|
| 1143 | + * |
|
| 1144 | + * @param array $requires_payment |
|
| 1145 | + * @return bool |
|
| 1146 | + * @throws EE_Error |
|
| 1147 | + */ |
|
| 1148 | + public function owes_monies_and_can_pay($requires_payment = array()) |
|
| 1149 | + { |
|
| 1150 | + // these reg statuses require payment (if event is not free) |
|
| 1151 | + $requires_payment = ! empty($requires_payment) |
|
| 1152 | + ? $requires_payment |
|
| 1153 | + : EEM_Registration::reg_statuses_that_allow_payment(); |
|
| 1154 | + if (in_array($this->status_ID(), $requires_payment) && |
|
| 1155 | + $this->final_price() != 0 && |
|
| 1156 | + $this->final_price() != $this->paid() |
|
| 1157 | + ) { |
|
| 1158 | + return true; |
|
| 1159 | + } else { |
|
| 1160 | + return false; |
|
| 1161 | + } |
|
| 1162 | + } |
|
| 1163 | + |
|
| 1164 | + |
|
| 1165 | + /** |
|
| 1166 | + * Prints out the return value of $this->pretty_status() |
|
| 1167 | + * |
|
| 1168 | + * @param bool $show_icons |
|
| 1169 | + * @return void |
|
| 1170 | + * @throws EE_Error |
|
| 1171 | + */ |
|
| 1172 | + public function e_pretty_status($show_icons = false) |
|
| 1173 | + { |
|
| 1174 | + echo $this->pretty_status($show_icons); |
|
| 1175 | + } |
|
| 1176 | + |
|
| 1177 | + |
|
| 1178 | + /** |
|
| 1179 | + * Returns a nice version of the status for displaying to customers |
|
| 1180 | + * |
|
| 1181 | + * @param bool $show_icons |
|
| 1182 | + * @return string |
|
| 1183 | + * @throws EE_Error |
|
| 1184 | + */ |
|
| 1185 | + public function pretty_status($show_icons = false) |
|
| 1186 | + { |
|
| 1187 | + $status = EEM_Status::instance()->localized_status( |
|
| 1188 | + array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
| 1189 | + false, |
|
| 1190 | + 'sentence' |
|
| 1191 | + ); |
|
| 1192 | + $icon = ''; |
|
| 1193 | + switch ($this->status_ID()) { |
|
| 1194 | + case EEM_Registration::status_id_approved: |
|
| 1195 | + $icon = $show_icons |
|
| 1196 | + ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
| 1197 | + : ''; |
|
| 1198 | + break; |
|
| 1199 | + case EEM_Registration::status_id_pending_payment: |
|
| 1200 | + $icon = $show_icons |
|
| 1201 | + ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
| 1202 | + : ''; |
|
| 1203 | + break; |
|
| 1204 | + case EEM_Registration::status_id_not_approved: |
|
| 1205 | + $icon = $show_icons |
|
| 1206 | + ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
| 1207 | + : ''; |
|
| 1208 | + break; |
|
| 1209 | + case EEM_Registration::status_id_cancelled: |
|
| 1210 | + $icon = $show_icons |
|
| 1211 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
| 1212 | + : ''; |
|
| 1213 | + break; |
|
| 1214 | + case EEM_Registration::status_id_incomplete: |
|
| 1215 | + $icon = $show_icons |
|
| 1216 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
| 1217 | + : ''; |
|
| 1218 | + break; |
|
| 1219 | + case EEM_Registration::status_id_declined: |
|
| 1220 | + $icon = $show_icons |
|
| 1221 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
| 1222 | + : ''; |
|
| 1223 | + break; |
|
| 1224 | + case EEM_Registration::status_id_wait_list: |
|
| 1225 | + $icon = $show_icons |
|
| 1226 | + ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
| 1227 | + : ''; |
|
| 1228 | + break; |
|
| 1229 | + } |
|
| 1230 | + return $icon . $status[ $this->status_ID() ]; |
|
| 1231 | + } |
|
| 1232 | + |
|
| 1233 | + |
|
| 1234 | + /** |
|
| 1235 | + * get Attendee Is Going |
|
| 1236 | + */ |
|
| 1237 | + public function att_is_going() |
|
| 1238 | + { |
|
| 1239 | + return $this->get('REG_att_is_going'); |
|
| 1240 | + } |
|
| 1241 | + |
|
| 1242 | + |
|
| 1243 | + /** |
|
| 1244 | + * Gets related answers |
|
| 1245 | + * |
|
| 1246 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1247 | + * @return EE_Answer[] |
|
| 1248 | + * @throws EE_Error |
|
| 1249 | + */ |
|
| 1250 | + public function answers($query_params = null) |
|
| 1251 | + { |
|
| 1252 | + return $this->get_many_related('Answer', $query_params); |
|
| 1253 | + } |
|
| 1254 | + |
|
| 1255 | + |
|
| 1256 | + /** |
|
| 1257 | + * Gets the registration's answer value to the specified question |
|
| 1258 | + * (either the question's ID or a question object) |
|
| 1259 | + * |
|
| 1260 | + * @param EE_Question|int $question |
|
| 1261 | + * @param bool $pretty_value |
|
| 1262 | + * @return array|string if pretty_value= true, the result will always be a string |
|
| 1263 | + * (because the answer might be an array of answer values, so passing pretty_value=true |
|
| 1264 | + * will convert it into some kind of string) |
|
| 1265 | + * @throws EE_Error |
|
| 1266 | + */ |
|
| 1267 | + public function answer_value_to_question($question, $pretty_value = true) |
|
| 1268 | + { |
|
| 1269 | + $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
| 1270 | + return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
| 1271 | + } |
|
| 1272 | + |
|
| 1273 | + |
|
| 1274 | + /** |
|
| 1275 | + * question_groups |
|
| 1276 | + * returns an array of EE_Question_Group objects for this registration |
|
| 1277 | + * |
|
| 1278 | + * @return EE_Question_Group[] |
|
| 1279 | + * @throws EE_Error |
|
| 1280 | + * @throws InvalidArgumentException |
|
| 1281 | + * @throws InvalidDataTypeException |
|
| 1282 | + * @throws InvalidInterfaceException |
|
| 1283 | + * @throws ReflectionException |
|
| 1284 | + */ |
|
| 1285 | + public function question_groups() |
|
| 1286 | + { |
|
| 1287 | + return EEM_Event::instance()->get_question_groups_for_event($this->event_ID(), $this); |
|
| 1288 | + } |
|
| 1289 | + |
|
| 1290 | + |
|
| 1291 | + /** |
|
| 1292 | + * count_question_groups |
|
| 1293 | + * returns a count of the number of EE_Question_Group objects for this registration |
|
| 1294 | + * |
|
| 1295 | + * @return int |
|
| 1296 | + * @throws EE_Error |
|
| 1297 | + * @throws EntityNotFoundException |
|
| 1298 | + * @throws InvalidArgumentException |
|
| 1299 | + * @throws InvalidDataTypeException |
|
| 1300 | + * @throws InvalidInterfaceException |
|
| 1301 | + * @throws ReflectionException |
|
| 1302 | + */ |
|
| 1303 | + public function count_question_groups() |
|
| 1304 | + { |
|
| 1305 | + return EEM_Event::instance()->count_related( |
|
| 1306 | + $this->event_ID(), |
|
| 1307 | + 'Question_Group', |
|
| 1308 | + [ |
|
| 1309 | + [ |
|
| 1310 | + 'Event_Question_Group.' |
|
| 1311 | + . EEM_Event_Question_Group::instance()->fieldNameForContext($this->is_primary_registrant()) => true, |
|
| 1312 | + ] |
|
| 1313 | + ] |
|
| 1314 | + ); |
|
| 1315 | + } |
|
| 1316 | + |
|
| 1317 | + |
|
| 1318 | + /** |
|
| 1319 | + * Returns the registration date in the 'standard' string format |
|
| 1320 | + * (function may be improved in the future to allow for different formats and timezones) |
|
| 1321 | + * |
|
| 1322 | + * @return string |
|
| 1323 | + * @throws EE_Error |
|
| 1324 | + */ |
|
| 1325 | + public function reg_date() |
|
| 1326 | + { |
|
| 1327 | + return $this->get_datetime('REG_date'); |
|
| 1328 | + } |
|
| 1329 | + |
|
| 1330 | + |
|
| 1331 | + /** |
|
| 1332 | + * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
| 1333 | + * the ticket this registration purchased, or the datetime they have registered |
|
| 1334 | + * to attend) |
|
| 1335 | + * |
|
| 1336 | + * @return EE_Datetime_Ticket |
|
| 1337 | + * @throws EE_Error |
|
| 1338 | + */ |
|
| 1339 | + public function datetime_ticket() |
|
| 1340 | + { |
|
| 1341 | + return $this->get_first_related('Datetime_Ticket'); |
|
| 1342 | + } |
|
| 1343 | + |
|
| 1344 | + |
|
| 1345 | + /** |
|
| 1346 | + * Sets the registration's datetime_ticket. |
|
| 1347 | + * |
|
| 1348 | + * @param EE_Datetime_Ticket $datetime_ticket |
|
| 1349 | + * @return EE_Datetime_Ticket |
|
| 1350 | + * @throws EE_Error |
|
| 1351 | + */ |
|
| 1352 | + public function set_datetime_ticket($datetime_ticket) |
|
| 1353 | + { |
|
| 1354 | + return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
| 1355 | + } |
|
| 1356 | + |
|
| 1357 | + /** |
|
| 1358 | + * Gets deleted |
|
| 1359 | + * |
|
| 1360 | + * @return bool |
|
| 1361 | + * @throws EE_Error |
|
| 1362 | + */ |
|
| 1363 | + public function deleted() |
|
| 1364 | + { |
|
| 1365 | + return $this->get('REG_deleted'); |
|
| 1366 | + } |
|
| 1367 | + |
|
| 1368 | + /** |
|
| 1369 | + * Sets deleted |
|
| 1370 | + * |
|
| 1371 | + * @param boolean $deleted |
|
| 1372 | + * @return bool |
|
| 1373 | + * @throws EE_Error |
|
| 1374 | + * @throws RuntimeException |
|
| 1375 | + */ |
|
| 1376 | + public function set_deleted($deleted) |
|
| 1377 | + { |
|
| 1378 | + if ($deleted) { |
|
| 1379 | + $this->delete(); |
|
| 1380 | + } else { |
|
| 1381 | + $this->restore(); |
|
| 1382 | + } |
|
| 1383 | + } |
|
| 1384 | + |
|
| 1385 | + |
|
| 1386 | + /** |
|
| 1387 | + * Get the status object of this object |
|
| 1388 | + * |
|
| 1389 | + * @return EE_Status |
|
| 1390 | + * @throws EE_Error |
|
| 1391 | + */ |
|
| 1392 | + public function status_obj() |
|
| 1393 | + { |
|
| 1394 | + return $this->get_first_related('Status'); |
|
| 1395 | + } |
|
| 1396 | + |
|
| 1397 | + |
|
| 1398 | + /** |
|
| 1399 | + * Returns the number of times this registration has checked into any of the datetimes |
|
| 1400 | + * its available for |
|
| 1401 | + * |
|
| 1402 | + * @return int |
|
| 1403 | + * @throws EE_Error |
|
| 1404 | + */ |
|
| 1405 | + public function count_checkins() |
|
| 1406 | + { |
|
| 1407 | + return $this->get_model()->count_related($this, 'Checkin'); |
|
| 1408 | + } |
|
| 1409 | + |
|
| 1410 | + |
|
| 1411 | + /** |
|
| 1412 | + * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
| 1413 | + * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
| 1414 | + * |
|
| 1415 | + * @return int |
|
| 1416 | + * @throws EE_Error |
|
| 1417 | + */ |
|
| 1418 | + public function count_checkins_not_checkedout() |
|
| 1419 | + { |
|
| 1420 | + return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
| 1421 | + } |
|
| 1422 | + |
|
| 1423 | + |
|
| 1424 | + /** |
|
| 1425 | + * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
| 1426 | + * |
|
| 1427 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1428 | + * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
| 1429 | + * consider registration status as well as datetime access. |
|
| 1430 | + * @return bool |
|
| 1431 | + * @throws EE_Error |
|
| 1432 | + */ |
|
| 1433 | + public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
| 1434 | + { |
|
| 1435 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1436 | + |
|
| 1437 | + // first check registration status |
|
| 1438 | + if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
| 1439 | + return false; |
|
| 1440 | + } |
|
| 1441 | + // is there a datetime ticket that matches this dtt_ID? |
|
| 1442 | + if (! (EEM_Datetime_Ticket::instance()->exists( |
|
| 1443 | + array( |
|
| 1444 | + array( |
|
| 1445 | + 'TKT_ID' => $this->get('TKT_ID'), |
|
| 1446 | + 'DTT_ID' => $DTT_ID, |
|
| 1447 | + ), |
|
| 1448 | + ) |
|
| 1449 | + )) |
|
| 1450 | + ) { |
|
| 1451 | + return false; |
|
| 1452 | + } |
|
| 1453 | + |
|
| 1454 | + // final check is against TKT_uses |
|
| 1455 | + return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
| 1456 | + } |
|
| 1457 | + |
|
| 1458 | + |
|
| 1459 | + /** |
|
| 1460 | + * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
| 1461 | + * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
| 1462 | + * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
| 1463 | + * then return false. Otherwise return true. |
|
| 1464 | + * |
|
| 1465 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1466 | + * @return bool true means can checkin. false means cannot checkin. |
|
| 1467 | + * @throws EE_Error |
|
| 1468 | + */ |
|
| 1469 | + public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
| 1470 | + { |
|
| 1471 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1472 | + |
|
| 1473 | + if (! $DTT_ID) { |
|
| 1474 | + return false; |
|
| 1475 | + } |
|
| 1476 | + |
|
| 1477 | + $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
| 1478 | + |
|
| 1479 | + // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
| 1480 | + // check-in or not. |
|
| 1481 | + if (! $max_uses || $max_uses === EE_INF) { |
|
| 1482 | + return true; |
|
| 1483 | + } |
|
| 1484 | + |
|
| 1485 | + // does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
| 1486 | + // go ahead and toggle. |
|
| 1487 | + if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
| 1488 | + return true; |
|
| 1489 | + } |
|
| 1490 | + |
|
| 1491 | + // made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
| 1492 | + // disallows further check-ins. |
|
| 1493 | + $count_unique_dtt_checkins = EEM_Checkin::instance()->count( |
|
| 1494 | + array( |
|
| 1495 | + array( |
|
| 1496 | + 'REG_ID' => $this->ID(), |
|
| 1497 | + 'CHK_in' => true, |
|
| 1498 | + ), |
|
| 1499 | + ), |
|
| 1500 | + 'DTT_ID', |
|
| 1501 | + true |
|
| 1502 | + ); |
|
| 1503 | + // checkins have already reached their max number of uses |
|
| 1504 | + // so registrant can NOT checkin |
|
| 1505 | + if ($count_unique_dtt_checkins >= $max_uses) { |
|
| 1506 | + EE_Error::add_error( |
|
| 1507 | + esc_html__( |
|
| 1508 | + 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
| 1509 | + 'event_espresso' |
|
| 1510 | + ), |
|
| 1511 | + __FILE__, |
|
| 1512 | + __FUNCTION__, |
|
| 1513 | + __LINE__ |
|
| 1514 | + ); |
|
| 1515 | + return false; |
|
| 1516 | + } |
|
| 1517 | + return true; |
|
| 1518 | + } |
|
| 1519 | + |
|
| 1520 | + |
|
| 1521 | + /** |
|
| 1522 | + * toggle Check-in status for this registration |
|
| 1523 | + * Check-ins are toggled in the following order: |
|
| 1524 | + * never checked in -> checked in |
|
| 1525 | + * checked in -> checked out |
|
| 1526 | + * checked out -> checked in |
|
| 1527 | + * |
|
| 1528 | + * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
| 1529 | + * If not included or null, then it is assumed latest datetime is being toggled. |
|
| 1530 | + * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
| 1531 | + * can be checked in or not. Otherwise this forces change in checkin status. |
|
| 1532 | + * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
| 1533 | + * @throws EE_Error |
|
| 1534 | + */ |
|
| 1535 | + public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
| 1536 | + { |
|
| 1537 | + if (empty($DTT_ID)) { |
|
| 1538 | + $datetime = $this->get_latest_related_datetime(); |
|
| 1539 | + $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
| 1540 | + // verify the registration can checkin for the given DTT_ID |
|
| 1541 | + } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1542 | + EE_Error::add_error( |
|
| 1543 | + sprintf( |
|
| 1544 | + esc_html__( |
|
| 1545 | + 'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access', |
|
| 1546 | + 'event_espresso' |
|
| 1547 | + ), |
|
| 1548 | + $this->ID(), |
|
| 1549 | + $DTT_ID |
|
| 1550 | + ), |
|
| 1551 | + __FILE__, |
|
| 1552 | + __FUNCTION__, |
|
| 1553 | + __LINE__ |
|
| 1554 | + ); |
|
| 1555 | + return false; |
|
| 1556 | + } |
|
| 1557 | + $status_paths = array( |
|
| 1558 | + EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
| 1559 | + EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
| 1560 | + EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
| 1561 | + ); |
|
| 1562 | + // start by getting the current status so we know what status we'll be changing to. |
|
| 1563 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
| 1564 | + $status_to = $status_paths[ $cur_status ]; |
|
| 1565 | + // database only records true for checked IN or false for checked OUT |
|
| 1566 | + // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
| 1567 | + $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
| 1568 | + // add relation - note Check-ins are always creating new rows |
|
| 1569 | + // because we are keeping track of Check-ins over time. |
|
| 1570 | + // Eventually we'll probably want to show a list table |
|
| 1571 | + // for the individual Check-ins so that they can be managed. |
|
| 1572 | + $checkin = EE_Checkin::new_instance( |
|
| 1573 | + array( |
|
| 1574 | + 'REG_ID' => $this->ID(), |
|
| 1575 | + 'DTT_ID' => $DTT_ID, |
|
| 1576 | + 'CHK_in' => $new_status, |
|
| 1577 | + ) |
|
| 1578 | + ); |
|
| 1579 | + // if the record could not be saved then return false |
|
| 1580 | + if ($checkin->save() === 0) { |
|
| 1581 | + if (WP_DEBUG) { |
|
| 1582 | + global $wpdb; |
|
| 1583 | + $error = sprintf( |
|
| 1584 | + esc_html__( |
|
| 1585 | + 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
| 1586 | + 'event_espresso' |
|
| 1587 | + ), |
|
| 1588 | + '<br />', |
|
| 1589 | + $wpdb->last_error |
|
| 1590 | + ); |
|
| 1591 | + } else { |
|
| 1592 | + $error = esc_html__( |
|
| 1593 | + 'Registration check in update failed because of an unknown database error', |
|
| 1594 | + 'event_espresso' |
|
| 1595 | + ); |
|
| 1596 | + } |
|
| 1597 | + EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
| 1598 | + return false; |
|
| 1599 | + } |
|
| 1600 | + return $status_to; |
|
| 1601 | + } |
|
| 1602 | + |
|
| 1603 | + |
|
| 1604 | + /** |
|
| 1605 | + * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
| 1606 | + * "Latest" is defined by the `DTT_EVT_start` column. |
|
| 1607 | + * |
|
| 1608 | + * @return EE_Datetime|null |
|
| 1609 | + * @throws EE_Error |
|
| 1610 | + */ |
|
| 1611 | + public function get_latest_related_datetime() |
|
| 1612 | + { |
|
| 1613 | + return EEM_Datetime::instance()->get_one( |
|
| 1614 | + array( |
|
| 1615 | + array( |
|
| 1616 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1617 | + ), |
|
| 1618 | + 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
| 1619 | + ) |
|
| 1620 | + ); |
|
| 1621 | + } |
|
| 1622 | + |
|
| 1623 | + |
|
| 1624 | + /** |
|
| 1625 | + * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
| 1626 | + * "Earliest" is defined by the `DTT_EVT_start` column. |
|
| 1627 | + * |
|
| 1628 | + * @throws EE_Error |
|
| 1629 | + */ |
|
| 1630 | + public function get_earliest_related_datetime() |
|
| 1631 | + { |
|
| 1632 | + return EEM_Datetime::instance()->get_one( |
|
| 1633 | + array( |
|
| 1634 | + array( |
|
| 1635 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1636 | + ), |
|
| 1637 | + 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
| 1638 | + ) |
|
| 1639 | + ); |
|
| 1640 | + } |
|
| 1641 | + |
|
| 1642 | + |
|
| 1643 | + /** |
|
| 1644 | + * This method simply returns the check-in status for this registration and the given datetime. |
|
| 1645 | + * If neither the datetime nor the checkin values are provided as arguments, |
|
| 1646 | + * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
| 1647 | + * |
|
| 1648 | + * @param int $DTT_ID The ID of the datetime we're checking against |
|
| 1649 | + * (if empty we'll get the primary datetime for |
|
| 1650 | + * this registration (via event) and use it's ID); |
|
| 1651 | + * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
| 1652 | + * |
|
| 1653 | + * @return int Integer representing Check-in status. |
|
| 1654 | + * @throws EE_Error |
|
| 1655 | + */ |
|
| 1656 | + public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
| 1657 | + { |
|
| 1658 | + $checkin_query_params = array( |
|
| 1659 | + 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
| 1660 | + ); |
|
| 1661 | + |
|
| 1662 | + if ($DTT_ID > 0) { |
|
| 1663 | + $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
| 1664 | + } |
|
| 1665 | + |
|
| 1666 | + // get checkin object (if exists) |
|
| 1667 | + $checkin = $checkin instanceof EE_Checkin |
|
| 1668 | + ? $checkin |
|
| 1669 | + : $this->get_first_related('Checkin', $checkin_query_params); |
|
| 1670 | + if ($checkin instanceof EE_Checkin) { |
|
| 1671 | + if ($checkin->get('CHK_in')) { |
|
| 1672 | + return EE_Checkin::status_checked_in; // checked in |
|
| 1673 | + } |
|
| 1674 | + return EE_Checkin::status_checked_out; // had checked in but is now checked out. |
|
| 1675 | + } |
|
| 1676 | + return EE_Checkin::status_checked_never; // never been checked in |
|
| 1677 | + } |
|
| 1678 | + |
|
| 1679 | + |
|
| 1680 | + /** |
|
| 1681 | + * This method returns a localized message for the toggled Check-in message. |
|
| 1682 | + * |
|
| 1683 | + * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
| 1684 | + * then it is assumed Check-in for primary datetime was toggled. |
|
| 1685 | + * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
| 1686 | + * message can be customized with the attendee name. |
|
| 1687 | + * @return string internationalized message |
|
| 1688 | + * @throws EE_Error |
|
| 1689 | + */ |
|
| 1690 | + public function get_checkin_msg($DTT_ID, $error = false) |
|
| 1691 | + { |
|
| 1692 | + // let's get the attendee first so we can include the name of the attendee |
|
| 1693 | + $attendee = $this->get_first_related('Attendee'); |
|
| 1694 | + if ($attendee instanceof EE_Attendee) { |
|
| 1695 | + if ($error) { |
|
| 1696 | + return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
| 1697 | + } |
|
| 1698 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
| 1699 | + // what is the status message going to be? |
|
| 1700 | + switch ($cur_status) { |
|
| 1701 | + case EE_Checkin::status_checked_never: |
|
| 1702 | + return sprintf( |
|
| 1703 | + __("%s has been removed from Check-in records", "event_espresso"), |
|
| 1704 | + $attendee->full_name() |
|
| 1705 | + ); |
|
| 1706 | + break; |
|
| 1707 | + case EE_Checkin::status_checked_in: |
|
| 1708 | + return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
| 1709 | + break; |
|
| 1710 | + case EE_Checkin::status_checked_out: |
|
| 1711 | + return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
| 1712 | + break; |
|
| 1713 | + } |
|
| 1714 | + } |
|
| 1715 | + return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
| 1716 | + } |
|
| 1717 | + |
|
| 1718 | + |
|
| 1719 | + /** |
|
| 1720 | + * Returns the related EE_Transaction to this registration |
|
| 1721 | + * |
|
| 1722 | + * @return EE_Transaction |
|
| 1723 | + * @throws EE_Error |
|
| 1724 | + * @throws EntityNotFoundException |
|
| 1725 | + */ |
|
| 1726 | + public function transaction() |
|
| 1727 | + { |
|
| 1728 | + $transaction = $this->get_first_related('Transaction'); |
|
| 1729 | + if (! $transaction instanceof \EE_Transaction) { |
|
| 1730 | + throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
| 1731 | + } |
|
| 1732 | + return $transaction; |
|
| 1733 | + } |
|
| 1734 | + |
|
| 1735 | + |
|
| 1736 | + /** |
|
| 1737 | + * get Registration Code |
|
| 1738 | + */ |
|
| 1739 | + public function reg_code() |
|
| 1740 | + { |
|
| 1741 | + return $this->get('REG_code'); |
|
| 1742 | + } |
|
| 1743 | + |
|
| 1744 | + |
|
| 1745 | + /** |
|
| 1746 | + * get Transaction ID |
|
| 1747 | + */ |
|
| 1748 | + public function transaction_ID() |
|
| 1749 | + { |
|
| 1750 | + return $this->get('TXN_ID'); |
|
| 1751 | + } |
|
| 1752 | + |
|
| 1753 | + |
|
| 1754 | + /** |
|
| 1755 | + * @return int |
|
| 1756 | + * @throws EE_Error |
|
| 1757 | + */ |
|
| 1758 | + public function ticket_ID() |
|
| 1759 | + { |
|
| 1760 | + return $this->get('TKT_ID'); |
|
| 1761 | + } |
|
| 1762 | + |
|
| 1763 | + |
|
| 1764 | + /** |
|
| 1765 | + * Set Registration Code |
|
| 1766 | + * |
|
| 1767 | + * @access public |
|
| 1768 | + * @param string $REG_code Registration Code |
|
| 1769 | + * @param boolean $use_default |
|
| 1770 | + * @throws EE_Error |
|
| 1771 | + */ |
|
| 1772 | + public function set_reg_code($REG_code, $use_default = false) |
|
| 1773 | + { |
|
| 1774 | + if (empty($REG_code)) { |
|
| 1775 | + EE_Error::add_error( |
|
| 1776 | + esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
| 1777 | + __FILE__, |
|
| 1778 | + __FUNCTION__, |
|
| 1779 | + __LINE__ |
|
| 1780 | + ); |
|
| 1781 | + return; |
|
| 1782 | + } |
|
| 1783 | + if (! $this->reg_code()) { |
|
| 1784 | + parent::set('REG_code', $REG_code, $use_default); |
|
| 1785 | + } else { |
|
| 1786 | + EE_Error::doing_it_wrong( |
|
| 1787 | + __CLASS__ . '::' . __FUNCTION__, |
|
| 1788 | + esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
| 1789 | + '4.6.0' |
|
| 1790 | + ); |
|
| 1791 | + } |
|
| 1792 | + } |
|
| 1793 | + |
|
| 1794 | + |
|
| 1795 | + /** |
|
| 1796 | + * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
| 1797 | + * Note, if you want to just get all registrations in the same transaction (group), use: |
|
| 1798 | + * $registration->transaction()->registrations(); |
|
| 1799 | + * |
|
| 1800 | + * @since 4.5.0 |
|
| 1801 | + * @return EE_Registration[] or empty array if this isn't a group registration. |
|
| 1802 | + * @throws EE_Error |
|
| 1803 | + */ |
|
| 1804 | + public function get_all_other_registrations_in_group() |
|
| 1805 | + { |
|
| 1806 | + if ($this->group_size() < 2) { |
|
| 1807 | + return array(); |
|
| 1808 | + } |
|
| 1809 | + |
|
| 1810 | + $query[0] = array( |
|
| 1811 | + 'TXN_ID' => $this->transaction_ID(), |
|
| 1812 | + 'REG_ID' => array('!=', $this->ID()), |
|
| 1813 | + 'TKT_ID' => $this->ticket_ID(), |
|
| 1814 | + ); |
|
| 1815 | + /** @var EE_Registration[] $registrations */ |
|
| 1816 | + $registrations = $this->get_model()->get_all($query); |
|
| 1817 | + return $registrations; |
|
| 1818 | + } |
|
| 1819 | + |
|
| 1820 | + /** |
|
| 1821 | + * Return the link to the admin details for the object. |
|
| 1822 | + * |
|
| 1823 | + * @return string |
|
| 1824 | + * @throws EE_Error |
|
| 1825 | + */ |
|
| 1826 | + public function get_admin_details_link() |
|
| 1827 | + { |
|
| 1828 | + EE_Registry::instance()->load_helper('URL'); |
|
| 1829 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1830 | + array( |
|
| 1831 | + 'page' => 'espresso_registrations', |
|
| 1832 | + 'action' => 'view_registration', |
|
| 1833 | + '_REG_ID' => $this->ID(), |
|
| 1834 | + ), |
|
| 1835 | + admin_url('admin.php') |
|
| 1836 | + ); |
|
| 1837 | + } |
|
| 1838 | + |
|
| 1839 | + /** |
|
| 1840 | + * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
| 1841 | + * |
|
| 1842 | + * @return string |
|
| 1843 | + * @throws EE_Error |
|
| 1844 | + */ |
|
| 1845 | + public function get_admin_edit_link() |
|
| 1846 | + { |
|
| 1847 | + return $this->get_admin_details_link(); |
|
| 1848 | + } |
|
| 1849 | + |
|
| 1850 | + /** |
|
| 1851 | + * Returns the link to a settings page for the object. |
|
| 1852 | + * |
|
| 1853 | + * @return string |
|
| 1854 | + * @throws EE_Error |
|
| 1855 | + */ |
|
| 1856 | + public function get_admin_settings_link() |
|
| 1857 | + { |
|
| 1858 | + return $this->get_admin_details_link(); |
|
| 1859 | + } |
|
| 1860 | + |
|
| 1861 | + /** |
|
| 1862 | + * Returns the link to the "overview" for the object (typically the "list table" view). |
|
| 1863 | + * |
|
| 1864 | + * @return string |
|
| 1865 | + */ |
|
| 1866 | + public function get_admin_overview_link() |
|
| 1867 | + { |
|
| 1868 | + EE_Registry::instance()->load_helper('URL'); |
|
| 1869 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1870 | + array( |
|
| 1871 | + 'page' => 'espresso_registrations', |
|
| 1872 | + ), |
|
| 1873 | + admin_url('admin.php') |
|
| 1874 | + ); |
|
| 1875 | + } |
|
| 1876 | + |
|
| 1877 | + |
|
| 1878 | + /** |
|
| 1879 | + * @param array $query_params |
|
| 1880 | + * |
|
| 1881 | + * @return \EE_Registration[] |
|
| 1882 | + * @throws EE_Error |
|
| 1883 | + */ |
|
| 1884 | + public function payments($query_params = array()) |
|
| 1885 | + { |
|
| 1886 | + return $this->get_many_related('Payment', $query_params); |
|
| 1887 | + } |
|
| 1888 | + |
|
| 1889 | + |
|
| 1890 | + /** |
|
| 1891 | + * @param array $query_params |
|
| 1892 | + * |
|
| 1893 | + * @return \EE_Registration_Payment[] |
|
| 1894 | + * @throws EE_Error |
|
| 1895 | + */ |
|
| 1896 | + public function registration_payments($query_params = array()) |
|
| 1897 | + { |
|
| 1898 | + return $this->get_many_related('Registration_Payment', $query_params); |
|
| 1899 | + } |
|
| 1900 | + |
|
| 1901 | + |
|
| 1902 | + /** |
|
| 1903 | + * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
| 1904 | + * Note: if there are no payments on the registration there will be no payment method returned. |
|
| 1905 | + * |
|
| 1906 | + * @return EE_Payment_Method|null |
|
| 1907 | + */ |
|
| 1908 | + public function payment_method() |
|
| 1909 | + { |
|
| 1910 | + return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
| 1911 | + } |
|
| 1912 | + |
|
| 1913 | + |
|
| 1914 | + /** |
|
| 1915 | + * @return \EE_Line_Item |
|
| 1916 | + * @throws EntityNotFoundException |
|
| 1917 | + * @throws EE_Error |
|
| 1918 | + */ |
|
| 1919 | + public function ticket_line_item() |
|
| 1920 | + { |
|
| 1921 | + $ticket = $this->ticket(); |
|
| 1922 | + $transaction = $this->transaction(); |
|
| 1923 | + $line_item = null; |
|
| 1924 | + $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 1925 | + $transaction->total_line_item(), |
|
| 1926 | + 'Ticket', |
|
| 1927 | + array($ticket->ID()) |
|
| 1928 | + ); |
|
| 1929 | + foreach ($ticket_line_items as $ticket_line_item) { |
|
| 1930 | + if ($ticket_line_item instanceof \EE_Line_Item |
|
| 1931 | + && $ticket_line_item->OBJ_type() === 'Ticket' |
|
| 1932 | + && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
| 1933 | + ) { |
|
| 1934 | + $line_item = $ticket_line_item; |
|
| 1935 | + break; |
|
| 1936 | + } |
|
| 1937 | + } |
|
| 1938 | + if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1939 | + throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
| 1940 | + } |
|
| 1941 | + return $line_item; |
|
| 1942 | + } |
|
| 1943 | + |
|
| 1944 | + |
|
| 1945 | + /** |
|
| 1946 | + * Soft Deletes this model object. |
|
| 1947 | + * |
|
| 1948 | + * @return boolean | int |
|
| 1949 | + * @throws RuntimeException |
|
| 1950 | + * @throws EE_Error |
|
| 1951 | + */ |
|
| 1952 | + public function delete() |
|
| 1953 | + { |
|
| 1954 | + if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
| 1955 | + $this->set_status(EEM_Registration::status_id_cancelled); |
|
| 1956 | + } |
|
| 1957 | + return parent::delete(); |
|
| 1958 | + } |
|
| 1959 | + |
|
| 1960 | + |
|
| 1961 | + /** |
|
| 1962 | + * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
| 1963 | + * |
|
| 1964 | + * @throws EE_Error |
|
| 1965 | + * @throws RuntimeException |
|
| 1966 | + */ |
|
| 1967 | + public function restore() |
|
| 1968 | + { |
|
| 1969 | + $previous_status = $this->get_extra_meta( |
|
| 1970 | + EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
| 1971 | + true, |
|
| 1972 | + EEM_Registration::status_id_cancelled |
|
| 1973 | + ); |
|
| 1974 | + if ($previous_status) { |
|
| 1975 | + $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
| 1976 | + $this->set_status($previous_status); |
|
| 1977 | + } |
|
| 1978 | + return parent::restore(); |
|
| 1979 | + } |
|
| 1980 | + |
|
| 1981 | + |
|
| 1982 | + /** |
|
| 1983 | + * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price |
|
| 1984 | + * |
|
| 1985 | + * @param boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic |
|
| 1986 | + * depending on whether the reg status changes to or from "Approved" |
|
| 1987 | + * @return boolean whether the Registration status was updated |
|
| 1988 | + * @throws EE_Error |
|
| 1989 | + * @throws RuntimeException |
|
| 1990 | + */ |
|
| 1991 | + public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true) |
|
| 1992 | + { |
|
| 1993 | + $paid = $this->paid(); |
|
| 1994 | + $price = $this->final_price(); |
|
| 1995 | + switch (true) { |
|
| 1996 | + // overpaid or paid |
|
| 1997 | + case EEH_Money::compare_floats($paid, $price, '>'): |
|
| 1998 | + case EEH_Money::compare_floats($paid, $price): |
|
| 1999 | + $new_status = EEM_Registration::status_id_approved; |
|
| 2000 | + break; |
|
| 2001 | + // underpaid |
|
| 2002 | + case EEH_Money::compare_floats($paid, $price, '<'): |
|
| 2003 | + $new_status = EEM_Registration::status_id_pending_payment; |
|
| 2004 | + break; |
|
| 2005 | + // uhhh Houston... |
|
| 2006 | + default: |
|
| 2007 | + throw new RuntimeException( |
|
| 2008 | + esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso') |
|
| 2009 | + ); |
|
| 2010 | + } |
|
| 2011 | + if ($new_status !== $this->status_ID()) { |
|
| 2012 | + if ($trigger_set_status_logic) { |
|
| 2013 | + return $this->set_status($new_status); |
|
| 2014 | + } |
|
| 2015 | + parent::set('STS_ID', $new_status); |
|
| 2016 | + return true; |
|
| 2017 | + } |
|
| 2018 | + return false; |
|
| 2019 | + } |
|
| 2020 | + |
|
| 2021 | + |
|
| 2022 | + /*************************** DEPRECATED ***************************/ |
|
| 2023 | + |
|
| 2024 | + |
|
| 2025 | + /** |
|
| 2026 | + * @deprecated |
|
| 2027 | + * @since 4.7.0 |
|
| 2028 | + * @access public |
|
| 2029 | + */ |
|
| 2030 | + public function price_paid() |
|
| 2031 | + { |
|
| 2032 | + EE_Error::doing_it_wrong( |
|
| 2033 | + 'EE_Registration::price_paid()', |
|
| 2034 | + esc_html__( |
|
| 2035 | + 'This method is deprecated, please use EE_Registration::final_price() instead.', |
|
| 2036 | + 'event_espresso' |
|
| 2037 | + ), |
|
| 2038 | + '4.7.0' |
|
| 2039 | + ); |
|
| 2040 | + return $this->final_price(); |
|
| 2041 | + } |
|
| 2042 | + |
|
| 2043 | + |
|
| 2044 | + /** |
|
| 2045 | + * @deprecated |
|
| 2046 | + * @since 4.7.0 |
|
| 2047 | + * @access public |
|
| 2048 | + * @param float $REG_final_price |
|
| 2049 | + * @throws EE_Error |
|
| 2050 | + * @throws RuntimeException |
|
| 2051 | + */ |
|
| 2052 | + public function set_price_paid($REG_final_price = 0.00) |
|
| 2053 | + { |
|
| 2054 | + EE_Error::doing_it_wrong( |
|
| 2055 | + 'EE_Registration::set_price_paid()', |
|
| 2056 | + esc_html__( |
|
| 2057 | + 'This method is deprecated, please use EE_Registration::set_final_price() instead.', |
|
| 2058 | + 'event_espresso' |
|
| 2059 | + ), |
|
| 2060 | + '4.7.0' |
|
| 2061 | + ); |
|
| 2062 | + $this->set_final_price($REG_final_price); |
|
| 2063 | + } |
|
| 2064 | + |
|
| 2065 | + |
|
| 2066 | + /** |
|
| 2067 | + * @deprecated |
|
| 2068 | + * @since 4.7.0 |
|
| 2069 | + * @return string |
|
| 2070 | + * @throws EE_Error |
|
| 2071 | + */ |
|
| 2072 | + public function pretty_price_paid() |
|
| 2073 | + { |
|
| 2074 | + EE_Error::doing_it_wrong( |
|
| 2075 | + 'EE_Registration::pretty_price_paid()', |
|
| 2076 | + esc_html__( |
|
| 2077 | + 'This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
| 2078 | + 'event_espresso' |
|
| 2079 | + ), |
|
| 2080 | + '4.7.0' |
|
| 2081 | + ); |
|
| 2082 | + return $this->pretty_final_price(); |
|
| 2083 | + } |
|
| 2084 | + |
|
| 2085 | + |
|
| 2086 | + /** |
|
| 2087 | + * Gets the primary datetime related to this registration via the related Event to this registration |
|
| 2088 | + * |
|
| 2089 | + * @deprecated 4.9.17 |
|
| 2090 | + * @return EE_Datetime |
|
| 2091 | + * @throws EE_Error |
|
| 2092 | + * @throws EntityNotFoundException |
|
| 2093 | + */ |
|
| 2094 | + public function get_related_primary_datetime() |
|
| 2095 | + { |
|
| 2096 | + EE_Error::doing_it_wrong( |
|
| 2097 | + __METHOD__, |
|
| 2098 | + esc_html__( |
|
| 2099 | + 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
| 2100 | + 'event_espresso' |
|
| 2101 | + ), |
|
| 2102 | + '4.9.17', |
|
| 2103 | + '5.0.0' |
|
| 2104 | + ); |
|
| 2105 | + return $this->event()->primary_datetime(); |
|
| 2106 | + } |
|
| 2107 | + |
|
| 2108 | + /** |
|
| 2109 | + * Returns the contact's name (or "Unknown" if there is no contact.) |
|
| 2110 | + * @since $VID:$ |
|
| 2111 | + * @return string |
|
| 2112 | + * @throws EE_Error |
|
| 2113 | + * @throws InvalidArgumentException |
|
| 2114 | + * @throws InvalidDataTypeException |
|
| 2115 | + * @throws InvalidInterfaceException |
|
| 2116 | + * @throws ReflectionException |
|
| 2117 | + */ |
|
| 2118 | + public function name() |
|
| 2119 | + { |
|
| 2120 | + return $this->attendeeName(); |
|
| 2121 | + } |
|
| 2122 | 2122 | } |
@@ -16,1267 +16,1267 @@ |
||
| 16 | 16 | { |
| 17 | 17 | |
| 18 | 18 | |
| 19 | - /** |
|
| 20 | - * This is used to hold the reports template data which is setup early in the request. |
|
| 21 | - * |
|
| 22 | - * @type array |
|
| 23 | - */ |
|
| 24 | - protected $_reports_template_data = array(); |
|
| 19 | + /** |
|
| 20 | + * This is used to hold the reports template data which is setup early in the request. |
|
| 21 | + * |
|
| 22 | + * @type array |
|
| 23 | + */ |
|
| 24 | + protected $_reports_template_data = array(); |
|
| 25 | 25 | |
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * Extend_Registrations_Admin_Page constructor. |
|
| 29 | - * |
|
| 30 | - * @param bool $routing |
|
| 31 | - */ |
|
| 32 | - public function __construct($routing = true) |
|
| 33 | - { |
|
| 34 | - parent::__construct($routing); |
|
| 35 | - if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 37 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 38 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 39 | - } |
|
| 40 | - } |
|
| 27 | + /** |
|
| 28 | + * Extend_Registrations_Admin_Page constructor. |
|
| 29 | + * |
|
| 30 | + * @param bool $routing |
|
| 31 | + */ |
|
| 32 | + public function __construct($routing = true) |
|
| 33 | + { |
|
| 34 | + parent::__construct($routing); |
|
| 35 | + if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 37 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 38 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 39 | + } |
|
| 40 | + } |
|
| 41 | 41 | |
| 42 | 42 | |
| 43 | - /** |
|
| 44 | - * Extending page configuration. |
|
| 45 | - */ |
|
| 46 | - protected function _extend_page_config() |
|
| 47 | - { |
|
| 48 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 49 | - $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
| 50 | - ? $this->_req_data['_REG_ID'] |
|
| 51 | - : 0; |
|
| 52 | - $new_page_routes = array( |
|
| 53 | - 'reports' => array( |
|
| 54 | - 'func' => '_registration_reports', |
|
| 55 | - 'capability' => 'ee_read_registrations', |
|
| 56 | - ), |
|
| 57 | - 'registration_checkins' => array( |
|
| 58 | - 'func' => '_registration_checkin_list_table', |
|
| 59 | - 'capability' => 'ee_read_checkins', |
|
| 60 | - ), |
|
| 61 | - 'newsletter_selected_send' => array( |
|
| 62 | - 'func' => '_newsletter_selected_send', |
|
| 63 | - 'noheader' => true, |
|
| 64 | - 'capability' => 'ee_send_message', |
|
| 65 | - ), |
|
| 66 | - 'delete_checkin_rows' => array( |
|
| 67 | - 'func' => '_delete_checkin_rows', |
|
| 68 | - 'noheader' => true, |
|
| 69 | - 'capability' => 'ee_delete_checkins', |
|
| 70 | - ), |
|
| 71 | - 'delete_checkin_row' => array( |
|
| 72 | - 'func' => '_delete_checkin_row', |
|
| 73 | - 'noheader' => true, |
|
| 74 | - 'capability' => 'ee_delete_checkin', |
|
| 75 | - 'obj_id' => $reg_id, |
|
| 76 | - ), |
|
| 77 | - 'toggle_checkin_status' => array( |
|
| 78 | - 'func' => '_toggle_checkin_status', |
|
| 79 | - 'noheader' => true, |
|
| 80 | - 'capability' => 'ee_edit_checkin', |
|
| 81 | - 'obj_id' => $reg_id, |
|
| 82 | - ), |
|
| 83 | - 'toggle_checkin_status_bulk' => array( |
|
| 84 | - 'func' => '_toggle_checkin_status', |
|
| 85 | - 'noheader' => true, |
|
| 86 | - 'capability' => 'ee_edit_checkins', |
|
| 87 | - ), |
|
| 88 | - 'event_registrations' => array( |
|
| 89 | - 'func' => '_event_registrations_list_table', |
|
| 90 | - 'capability' => 'ee_read_checkins', |
|
| 91 | - ), |
|
| 92 | - 'registrations_checkin_report' => array( |
|
| 93 | - 'func' => '_registrations_checkin_report', |
|
| 94 | - 'noheader' => true, |
|
| 95 | - 'capability' => 'ee_read_registrations', |
|
| 96 | - ), |
|
| 97 | - ); |
|
| 98 | - $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
| 99 | - $new_page_config = array( |
|
| 100 | - 'reports' => array( |
|
| 101 | - 'nav' => array( |
|
| 102 | - 'label' => esc_html__('Reports', 'event_espresso'), |
|
| 103 | - 'order' => 30, |
|
| 104 | - ), |
|
| 105 | - 'help_tabs' => array( |
|
| 106 | - 'registrations_reports_help_tab' => array( |
|
| 107 | - 'title' => esc_html__('Registration Reports', 'event_espresso'), |
|
| 108 | - 'filename' => 'registrations_reports', |
|
| 109 | - ), |
|
| 110 | - ), |
|
| 111 | - /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
| 112 | - 'require_nonce' => false, |
|
| 113 | - ), |
|
| 114 | - 'event_registrations' => array( |
|
| 115 | - 'nav' => array( |
|
| 116 | - 'label' => esc_html__('Event Check-In', 'event_espresso'), |
|
| 117 | - 'order' => 10, |
|
| 118 | - 'persistent' => true, |
|
| 119 | - ), |
|
| 120 | - 'help_tabs' => array( |
|
| 121 | - 'registrations_event_checkin_help_tab' => array( |
|
| 122 | - 'title' => esc_html__('Registrations Event Check-In', 'event_espresso'), |
|
| 123 | - 'filename' => 'registrations_event_checkin', |
|
| 124 | - ), |
|
| 125 | - 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
| 126 | - 'title' => esc_html__('Event Check-In Table Column Headings', 'event_espresso'), |
|
| 127 | - 'filename' => 'registrations_event_checkin_table_column_headings', |
|
| 128 | - ), |
|
| 129 | - 'registrations_event_checkin_filters_help_tab' => array( |
|
| 130 | - 'title' => esc_html__('Event Check-In Filters', 'event_espresso'), |
|
| 131 | - 'filename' => 'registrations_event_checkin_filters', |
|
| 132 | - ), |
|
| 133 | - 'registrations_event_checkin_views_help_tab' => array( |
|
| 134 | - 'title' => esc_html__('Event Check-In Views', 'event_espresso'), |
|
| 135 | - 'filename' => 'registrations_event_checkin_views', |
|
| 136 | - ), |
|
| 137 | - 'registrations_event_checkin_other_help_tab' => array( |
|
| 138 | - 'title' => esc_html__('Event Check-In Other', 'event_espresso'), |
|
| 139 | - 'filename' => 'registrations_event_checkin_other', |
|
| 140 | - ), |
|
| 141 | - ), |
|
| 142 | - 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
| 143 | - 'qtips' => array('Registration_List_Table_Tips'), |
|
| 144 | - 'list_table' => 'EE_Event_Registrations_List_Table', |
|
| 145 | - 'metaboxes' => array(), |
|
| 146 | - 'require_nonce' => false, |
|
| 147 | - ), |
|
| 148 | - 'registration_checkins' => array( |
|
| 149 | - 'nav' => array( |
|
| 150 | - 'label' => esc_html__('Check-In Records', 'event_espresso'), |
|
| 151 | - 'order' => 15, |
|
| 152 | - 'persistent' => false, |
|
| 153 | - 'url' => '', |
|
| 154 | - ), |
|
| 155 | - 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
| 156 | - // 'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
| 157 | - 'metaboxes' => array(), |
|
| 158 | - 'require_nonce' => false, |
|
| 159 | - ), |
|
| 160 | - ); |
|
| 161 | - $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
| 162 | - $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
| 163 | - $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
| 164 | - } |
|
| 43 | + /** |
|
| 44 | + * Extending page configuration. |
|
| 45 | + */ |
|
| 46 | + protected function _extend_page_config() |
|
| 47 | + { |
|
| 48 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 49 | + $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
| 50 | + ? $this->_req_data['_REG_ID'] |
|
| 51 | + : 0; |
|
| 52 | + $new_page_routes = array( |
|
| 53 | + 'reports' => array( |
|
| 54 | + 'func' => '_registration_reports', |
|
| 55 | + 'capability' => 'ee_read_registrations', |
|
| 56 | + ), |
|
| 57 | + 'registration_checkins' => array( |
|
| 58 | + 'func' => '_registration_checkin_list_table', |
|
| 59 | + 'capability' => 'ee_read_checkins', |
|
| 60 | + ), |
|
| 61 | + 'newsletter_selected_send' => array( |
|
| 62 | + 'func' => '_newsletter_selected_send', |
|
| 63 | + 'noheader' => true, |
|
| 64 | + 'capability' => 'ee_send_message', |
|
| 65 | + ), |
|
| 66 | + 'delete_checkin_rows' => array( |
|
| 67 | + 'func' => '_delete_checkin_rows', |
|
| 68 | + 'noheader' => true, |
|
| 69 | + 'capability' => 'ee_delete_checkins', |
|
| 70 | + ), |
|
| 71 | + 'delete_checkin_row' => array( |
|
| 72 | + 'func' => '_delete_checkin_row', |
|
| 73 | + 'noheader' => true, |
|
| 74 | + 'capability' => 'ee_delete_checkin', |
|
| 75 | + 'obj_id' => $reg_id, |
|
| 76 | + ), |
|
| 77 | + 'toggle_checkin_status' => array( |
|
| 78 | + 'func' => '_toggle_checkin_status', |
|
| 79 | + 'noheader' => true, |
|
| 80 | + 'capability' => 'ee_edit_checkin', |
|
| 81 | + 'obj_id' => $reg_id, |
|
| 82 | + ), |
|
| 83 | + 'toggle_checkin_status_bulk' => array( |
|
| 84 | + 'func' => '_toggle_checkin_status', |
|
| 85 | + 'noheader' => true, |
|
| 86 | + 'capability' => 'ee_edit_checkins', |
|
| 87 | + ), |
|
| 88 | + 'event_registrations' => array( |
|
| 89 | + 'func' => '_event_registrations_list_table', |
|
| 90 | + 'capability' => 'ee_read_checkins', |
|
| 91 | + ), |
|
| 92 | + 'registrations_checkin_report' => array( |
|
| 93 | + 'func' => '_registrations_checkin_report', |
|
| 94 | + 'noheader' => true, |
|
| 95 | + 'capability' => 'ee_read_registrations', |
|
| 96 | + ), |
|
| 97 | + ); |
|
| 98 | + $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
| 99 | + $new_page_config = array( |
|
| 100 | + 'reports' => array( |
|
| 101 | + 'nav' => array( |
|
| 102 | + 'label' => esc_html__('Reports', 'event_espresso'), |
|
| 103 | + 'order' => 30, |
|
| 104 | + ), |
|
| 105 | + 'help_tabs' => array( |
|
| 106 | + 'registrations_reports_help_tab' => array( |
|
| 107 | + 'title' => esc_html__('Registration Reports', 'event_espresso'), |
|
| 108 | + 'filename' => 'registrations_reports', |
|
| 109 | + ), |
|
| 110 | + ), |
|
| 111 | + /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
| 112 | + 'require_nonce' => false, |
|
| 113 | + ), |
|
| 114 | + 'event_registrations' => array( |
|
| 115 | + 'nav' => array( |
|
| 116 | + 'label' => esc_html__('Event Check-In', 'event_espresso'), |
|
| 117 | + 'order' => 10, |
|
| 118 | + 'persistent' => true, |
|
| 119 | + ), |
|
| 120 | + 'help_tabs' => array( |
|
| 121 | + 'registrations_event_checkin_help_tab' => array( |
|
| 122 | + 'title' => esc_html__('Registrations Event Check-In', 'event_espresso'), |
|
| 123 | + 'filename' => 'registrations_event_checkin', |
|
| 124 | + ), |
|
| 125 | + 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
| 126 | + 'title' => esc_html__('Event Check-In Table Column Headings', 'event_espresso'), |
|
| 127 | + 'filename' => 'registrations_event_checkin_table_column_headings', |
|
| 128 | + ), |
|
| 129 | + 'registrations_event_checkin_filters_help_tab' => array( |
|
| 130 | + 'title' => esc_html__('Event Check-In Filters', 'event_espresso'), |
|
| 131 | + 'filename' => 'registrations_event_checkin_filters', |
|
| 132 | + ), |
|
| 133 | + 'registrations_event_checkin_views_help_tab' => array( |
|
| 134 | + 'title' => esc_html__('Event Check-In Views', 'event_espresso'), |
|
| 135 | + 'filename' => 'registrations_event_checkin_views', |
|
| 136 | + ), |
|
| 137 | + 'registrations_event_checkin_other_help_tab' => array( |
|
| 138 | + 'title' => esc_html__('Event Check-In Other', 'event_espresso'), |
|
| 139 | + 'filename' => 'registrations_event_checkin_other', |
|
| 140 | + ), |
|
| 141 | + ), |
|
| 142 | + 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
| 143 | + 'qtips' => array('Registration_List_Table_Tips'), |
|
| 144 | + 'list_table' => 'EE_Event_Registrations_List_Table', |
|
| 145 | + 'metaboxes' => array(), |
|
| 146 | + 'require_nonce' => false, |
|
| 147 | + ), |
|
| 148 | + 'registration_checkins' => array( |
|
| 149 | + 'nav' => array( |
|
| 150 | + 'label' => esc_html__('Check-In Records', 'event_espresso'), |
|
| 151 | + 'order' => 15, |
|
| 152 | + 'persistent' => false, |
|
| 153 | + 'url' => '', |
|
| 154 | + ), |
|
| 155 | + 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
| 156 | + // 'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
| 157 | + 'metaboxes' => array(), |
|
| 158 | + 'require_nonce' => false, |
|
| 159 | + ), |
|
| 160 | + ); |
|
| 161 | + $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
| 162 | + $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
| 163 | + $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
| 164 | + } |
|
| 165 | 165 | |
| 166 | 166 | |
| 167 | - /** |
|
| 168 | - * Ajax hooks for all routes in this page. |
|
| 169 | - */ |
|
| 170 | - protected function _ajax_hooks() |
|
| 171 | - { |
|
| 172 | - parent::_ajax_hooks(); |
|
| 173 | - add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
| 174 | - } |
|
| 167 | + /** |
|
| 168 | + * Ajax hooks for all routes in this page. |
|
| 169 | + */ |
|
| 170 | + protected function _ajax_hooks() |
|
| 171 | + { |
|
| 172 | + parent::_ajax_hooks(); |
|
| 173 | + add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
| 174 | + } |
|
| 175 | 175 | |
| 176 | 176 | |
| 177 | - /** |
|
| 178 | - * Global scripts for all routes in this page. |
|
| 179 | - */ |
|
| 180 | - public function load_scripts_styles() |
|
| 181 | - { |
|
| 182 | - parent::load_scripts_styles(); |
|
| 183 | - // if newsletter message type is active then let's add filter and load js for it. |
|
| 184 | - if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
| 185 | - // enqueue newsletter js |
|
| 186 | - wp_enqueue_script( |
|
| 187 | - 'ee-newsletter-trigger', |
|
| 188 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 189 | - array('ee-dialog'), |
|
| 190 | - EVENT_ESPRESSO_VERSION, |
|
| 191 | - true |
|
| 192 | - ); |
|
| 193 | - wp_enqueue_style( |
|
| 194 | - 'ee-newsletter-trigger-css', |
|
| 195 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 196 | - array(), |
|
| 197 | - EVENT_ESPRESSO_VERSION |
|
| 198 | - ); |
|
| 199 | - // hook in buttons for newsletter message type trigger. |
|
| 200 | - add_action( |
|
| 201 | - 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
| 202 | - array($this, 'add_newsletter_action_buttons'), |
|
| 203 | - 10 |
|
| 204 | - ); |
|
| 205 | - } |
|
| 206 | - } |
|
| 177 | + /** |
|
| 178 | + * Global scripts for all routes in this page. |
|
| 179 | + */ |
|
| 180 | + public function load_scripts_styles() |
|
| 181 | + { |
|
| 182 | + parent::load_scripts_styles(); |
|
| 183 | + // if newsletter message type is active then let's add filter and load js for it. |
|
| 184 | + if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
| 185 | + // enqueue newsletter js |
|
| 186 | + wp_enqueue_script( |
|
| 187 | + 'ee-newsletter-trigger', |
|
| 188 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 189 | + array('ee-dialog'), |
|
| 190 | + EVENT_ESPRESSO_VERSION, |
|
| 191 | + true |
|
| 192 | + ); |
|
| 193 | + wp_enqueue_style( |
|
| 194 | + 'ee-newsletter-trigger-css', |
|
| 195 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 196 | + array(), |
|
| 197 | + EVENT_ESPRESSO_VERSION |
|
| 198 | + ); |
|
| 199 | + // hook in buttons for newsletter message type trigger. |
|
| 200 | + add_action( |
|
| 201 | + 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
| 202 | + array($this, 'add_newsletter_action_buttons'), |
|
| 203 | + 10 |
|
| 204 | + ); |
|
| 205 | + } |
|
| 206 | + } |
|
| 207 | 207 | |
| 208 | 208 | |
| 209 | - /** |
|
| 210 | - * Scripts and styles for just the reports route. |
|
| 211 | - */ |
|
| 212 | - public function load_scripts_styles_reports() |
|
| 213 | - { |
|
| 214 | - wp_register_script( |
|
| 215 | - 'ee-reg-reports-js', |
|
| 216 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 217 | - array('google-charts'), |
|
| 218 | - EVENT_ESPRESSO_VERSION, |
|
| 219 | - true |
|
| 220 | - ); |
|
| 221 | - wp_enqueue_script('ee-reg-reports-js'); |
|
| 222 | - $this->_registration_reports_js_setup(); |
|
| 223 | - } |
|
| 209 | + /** |
|
| 210 | + * Scripts and styles for just the reports route. |
|
| 211 | + */ |
|
| 212 | + public function load_scripts_styles_reports() |
|
| 213 | + { |
|
| 214 | + wp_register_script( |
|
| 215 | + 'ee-reg-reports-js', |
|
| 216 | + REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 217 | + array('google-charts'), |
|
| 218 | + EVENT_ESPRESSO_VERSION, |
|
| 219 | + true |
|
| 220 | + ); |
|
| 221 | + wp_enqueue_script('ee-reg-reports-js'); |
|
| 222 | + $this->_registration_reports_js_setup(); |
|
| 223 | + } |
|
| 224 | 224 | |
| 225 | 225 | |
| 226 | - /** |
|
| 227 | - * Register screen options for event_registrations route. |
|
| 228 | - */ |
|
| 229 | - protected function _add_screen_options_event_registrations() |
|
| 230 | - { |
|
| 231 | - $this->_per_page_screen_option(); |
|
| 232 | - } |
|
| 226 | + /** |
|
| 227 | + * Register screen options for event_registrations route. |
|
| 228 | + */ |
|
| 229 | + protected function _add_screen_options_event_registrations() |
|
| 230 | + { |
|
| 231 | + $this->_per_page_screen_option(); |
|
| 232 | + } |
|
| 233 | 233 | |
| 234 | 234 | |
| 235 | - /** |
|
| 236 | - * Register screen options for registration_checkins route |
|
| 237 | - */ |
|
| 238 | - protected function _add_screen_options_registration_checkins() |
|
| 239 | - { |
|
| 240 | - $page_title = $this->_admin_page_title; |
|
| 241 | - $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso'); |
|
| 242 | - $this->_per_page_screen_option(); |
|
| 243 | - $this->_admin_page_title = $page_title; |
|
| 244 | - } |
|
| 235 | + /** |
|
| 236 | + * Register screen options for registration_checkins route |
|
| 237 | + */ |
|
| 238 | + protected function _add_screen_options_registration_checkins() |
|
| 239 | + { |
|
| 240 | + $page_title = $this->_admin_page_title; |
|
| 241 | + $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso'); |
|
| 242 | + $this->_per_page_screen_option(); |
|
| 243 | + $this->_admin_page_title = $page_title; |
|
| 244 | + } |
|
| 245 | 245 | |
| 246 | 246 | |
| 247 | - /** |
|
| 248 | - * Set views property for event_registrations route. |
|
| 249 | - */ |
|
| 250 | - protected function _set_list_table_views_event_registrations() |
|
| 251 | - { |
|
| 252 | - $this->_views = array( |
|
| 253 | - 'all' => array( |
|
| 254 | - 'slug' => 'all', |
|
| 255 | - 'label' => esc_html__('All', 'event_espresso'), |
|
| 256 | - 'count' => 0, |
|
| 257 | - 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
| 258 | - ? array() |
|
| 259 | - : array( |
|
| 260 | - 'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'), |
|
| 261 | - ), |
|
| 262 | - ), |
|
| 263 | - ); |
|
| 264 | - } |
|
| 247 | + /** |
|
| 248 | + * Set views property for event_registrations route. |
|
| 249 | + */ |
|
| 250 | + protected function _set_list_table_views_event_registrations() |
|
| 251 | + { |
|
| 252 | + $this->_views = array( |
|
| 253 | + 'all' => array( |
|
| 254 | + 'slug' => 'all', |
|
| 255 | + 'label' => esc_html__('All', 'event_espresso'), |
|
| 256 | + 'count' => 0, |
|
| 257 | + 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
| 258 | + ? array() |
|
| 259 | + : array( |
|
| 260 | + 'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'), |
|
| 261 | + ), |
|
| 262 | + ), |
|
| 263 | + ); |
|
| 264 | + } |
|
| 265 | 265 | |
| 266 | 266 | |
| 267 | - /** |
|
| 268 | - * Set views property for registration_checkins route. |
|
| 269 | - */ |
|
| 270 | - protected function _set_list_table_views_registration_checkins() |
|
| 271 | - { |
|
| 272 | - $this->_views = array( |
|
| 273 | - 'all' => array( |
|
| 274 | - 'slug' => 'all', |
|
| 275 | - 'label' => esc_html__('All', 'event_espresso'), |
|
| 276 | - 'count' => 0, |
|
| 277 | - 'bulk_action' => array('delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')), |
|
| 278 | - ), |
|
| 279 | - ); |
|
| 280 | - } |
|
| 267 | + /** |
|
| 268 | + * Set views property for registration_checkins route. |
|
| 269 | + */ |
|
| 270 | + protected function _set_list_table_views_registration_checkins() |
|
| 271 | + { |
|
| 272 | + $this->_views = array( |
|
| 273 | + 'all' => array( |
|
| 274 | + 'slug' => 'all', |
|
| 275 | + 'label' => esc_html__('All', 'event_espresso'), |
|
| 276 | + 'count' => 0, |
|
| 277 | + 'bulk_action' => array('delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')), |
|
| 278 | + ), |
|
| 279 | + ); |
|
| 280 | + } |
|
| 281 | 281 | |
| 282 | 282 | |
| 283 | - /** |
|
| 284 | - * callback for ajax action. |
|
| 285 | - * |
|
| 286 | - * @since 4.3.0 |
|
| 287 | - * @return void (JSON) |
|
| 288 | - * @throws EE_Error |
|
| 289 | - * @throws InvalidArgumentException |
|
| 290 | - * @throws InvalidDataTypeException |
|
| 291 | - * @throws InvalidInterfaceException |
|
| 292 | - */ |
|
| 293 | - public function get_newsletter_form_content() |
|
| 294 | - { |
|
| 295 | - // do a nonce check cause we're not coming in from an normal route here. |
|
| 296 | - $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
| 297 | - $this->_req_data['get_newsletter_form_content_nonce'] |
|
| 298 | - ) : ''; |
|
| 299 | - $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
| 300 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
| 301 | - // let's get the mtp for the incoming MTP_ ID |
|
| 302 | - if (! isset($this->_req_data['GRP_ID'])) { |
|
| 303 | - EE_Error::add_error( |
|
| 304 | - esc_html__( |
|
| 305 | - 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
|
| 306 | - 'event_espresso' |
|
| 307 | - ), |
|
| 308 | - __FILE__, |
|
| 309 | - __FUNCTION__, |
|
| 310 | - __LINE__ |
|
| 311 | - ); |
|
| 312 | - $this->_template_args['success'] = false; |
|
| 313 | - $this->_template_args['error'] = true; |
|
| 314 | - $this->_return_json(); |
|
| 315 | - } |
|
| 316 | - $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
| 317 | - if (! $MTPG instanceof EE_Message_Template_Group) { |
|
| 318 | - EE_Error::add_error( |
|
| 319 | - sprintf( |
|
| 320 | - esc_html__( |
|
| 321 | - 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
| 322 | - 'event_espresso' |
|
| 323 | - ), |
|
| 324 | - $this->_req_data['GRP_ID'] |
|
| 325 | - ), |
|
| 326 | - __FILE__, |
|
| 327 | - __FUNCTION__, |
|
| 328 | - __LINE__ |
|
| 329 | - ); |
|
| 330 | - $this->_template_args['success'] = false; |
|
| 331 | - $this->_template_args['error'] = true; |
|
| 332 | - $this->_return_json(); |
|
| 333 | - } |
|
| 334 | - $MTPs = $MTPG->context_templates(); |
|
| 335 | - $MTPs = $MTPs['attendee']; |
|
| 336 | - $template_fields = array(); |
|
| 337 | - /** @var EE_Message_Template $MTP */ |
|
| 338 | - foreach ($MTPs as $MTP) { |
|
| 339 | - $field = $MTP->get('MTP_template_field'); |
|
| 340 | - if ($field === 'content') { |
|
| 341 | - $content = $MTP->get('MTP_content'); |
|
| 342 | - if (! empty($content['newsletter_content'])) { |
|
| 343 | - $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
| 344 | - } |
|
| 345 | - continue; |
|
| 346 | - } |
|
| 347 | - $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
| 348 | - } |
|
| 349 | - $this->_template_args['success'] = true; |
|
| 350 | - $this->_template_args['error'] = false; |
|
| 351 | - $this->_template_args['data'] = array( |
|
| 352 | - 'batch_message_from' => isset($template_fields['from']) |
|
| 353 | - ? $template_fields['from'] |
|
| 354 | - : '', |
|
| 355 | - 'batch_message_subject' => isset($template_fields['subject']) |
|
| 356 | - ? $template_fields['subject'] |
|
| 357 | - : '', |
|
| 358 | - 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
| 359 | - ? $template_fields['newsletter_content'] |
|
| 360 | - : '', |
|
| 361 | - ); |
|
| 362 | - $this->_return_json(); |
|
| 363 | - } |
|
| 283 | + /** |
|
| 284 | + * callback for ajax action. |
|
| 285 | + * |
|
| 286 | + * @since 4.3.0 |
|
| 287 | + * @return void (JSON) |
|
| 288 | + * @throws EE_Error |
|
| 289 | + * @throws InvalidArgumentException |
|
| 290 | + * @throws InvalidDataTypeException |
|
| 291 | + * @throws InvalidInterfaceException |
|
| 292 | + */ |
|
| 293 | + public function get_newsletter_form_content() |
|
| 294 | + { |
|
| 295 | + // do a nonce check cause we're not coming in from an normal route here. |
|
| 296 | + $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
| 297 | + $this->_req_data['get_newsletter_form_content_nonce'] |
|
| 298 | + ) : ''; |
|
| 299 | + $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
| 300 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
| 301 | + // let's get the mtp for the incoming MTP_ ID |
|
| 302 | + if (! isset($this->_req_data['GRP_ID'])) { |
|
| 303 | + EE_Error::add_error( |
|
| 304 | + esc_html__( |
|
| 305 | + 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
|
| 306 | + 'event_espresso' |
|
| 307 | + ), |
|
| 308 | + __FILE__, |
|
| 309 | + __FUNCTION__, |
|
| 310 | + __LINE__ |
|
| 311 | + ); |
|
| 312 | + $this->_template_args['success'] = false; |
|
| 313 | + $this->_template_args['error'] = true; |
|
| 314 | + $this->_return_json(); |
|
| 315 | + } |
|
| 316 | + $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
| 317 | + if (! $MTPG instanceof EE_Message_Template_Group) { |
|
| 318 | + EE_Error::add_error( |
|
| 319 | + sprintf( |
|
| 320 | + esc_html__( |
|
| 321 | + 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
| 322 | + 'event_espresso' |
|
| 323 | + ), |
|
| 324 | + $this->_req_data['GRP_ID'] |
|
| 325 | + ), |
|
| 326 | + __FILE__, |
|
| 327 | + __FUNCTION__, |
|
| 328 | + __LINE__ |
|
| 329 | + ); |
|
| 330 | + $this->_template_args['success'] = false; |
|
| 331 | + $this->_template_args['error'] = true; |
|
| 332 | + $this->_return_json(); |
|
| 333 | + } |
|
| 334 | + $MTPs = $MTPG->context_templates(); |
|
| 335 | + $MTPs = $MTPs['attendee']; |
|
| 336 | + $template_fields = array(); |
|
| 337 | + /** @var EE_Message_Template $MTP */ |
|
| 338 | + foreach ($MTPs as $MTP) { |
|
| 339 | + $field = $MTP->get('MTP_template_field'); |
|
| 340 | + if ($field === 'content') { |
|
| 341 | + $content = $MTP->get('MTP_content'); |
|
| 342 | + if (! empty($content['newsletter_content'])) { |
|
| 343 | + $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
| 344 | + } |
|
| 345 | + continue; |
|
| 346 | + } |
|
| 347 | + $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
| 348 | + } |
|
| 349 | + $this->_template_args['success'] = true; |
|
| 350 | + $this->_template_args['error'] = false; |
|
| 351 | + $this->_template_args['data'] = array( |
|
| 352 | + 'batch_message_from' => isset($template_fields['from']) |
|
| 353 | + ? $template_fields['from'] |
|
| 354 | + : '', |
|
| 355 | + 'batch_message_subject' => isset($template_fields['subject']) |
|
| 356 | + ? $template_fields['subject'] |
|
| 357 | + : '', |
|
| 358 | + 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
| 359 | + ? $template_fields['newsletter_content'] |
|
| 360 | + : '', |
|
| 361 | + ); |
|
| 362 | + $this->_return_json(); |
|
| 363 | + } |
|
| 364 | 364 | |
| 365 | 365 | |
| 366 | - /** |
|
| 367 | - * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
| 368 | - * |
|
| 369 | - * @since 4.3.0 |
|
| 370 | - * @param EE_Admin_List_Table $list_table |
|
| 371 | - * @return void |
|
| 372 | - * @throws InvalidArgumentException |
|
| 373 | - * @throws InvalidDataTypeException |
|
| 374 | - * @throws InvalidInterfaceException |
|
| 375 | - */ |
|
| 376 | - public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
| 377 | - { |
|
| 378 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 379 | - 'ee_send_message', |
|
| 380 | - 'espresso_registrations_newsletter_selected_send' |
|
| 381 | - ) |
|
| 382 | - ) { |
|
| 383 | - return; |
|
| 384 | - } |
|
| 385 | - $routes_to_add_to = array( |
|
| 386 | - 'contact_list', |
|
| 387 | - 'event_registrations', |
|
| 388 | - 'default', |
|
| 389 | - ); |
|
| 390 | - if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
| 391 | - if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
| 392 | - || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
| 393 | - ) { |
|
| 394 | - echo ''; |
|
| 395 | - } else { |
|
| 396 | - $button_text = sprintf( |
|
| 397 | - esc_html__('Send Batch Message (%s selected)', 'event_espresso'), |
|
| 398 | - '<span class="send-selected-newsletter-count">0</span>' |
|
| 399 | - ); |
|
| 400 | - echo '<button id="selected-batch-send-trigger" class="button secondary-button">' |
|
| 401 | - . '<span class="dashicons dashicons-email "></span>' |
|
| 402 | - . $button_text |
|
| 403 | - . '</button>'; |
|
| 404 | - add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
| 405 | - } |
|
| 406 | - } |
|
| 407 | - } |
|
| 366 | + /** |
|
| 367 | + * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
| 368 | + * |
|
| 369 | + * @since 4.3.0 |
|
| 370 | + * @param EE_Admin_List_Table $list_table |
|
| 371 | + * @return void |
|
| 372 | + * @throws InvalidArgumentException |
|
| 373 | + * @throws InvalidDataTypeException |
|
| 374 | + * @throws InvalidInterfaceException |
|
| 375 | + */ |
|
| 376 | + public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
| 377 | + { |
|
| 378 | + if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 379 | + 'ee_send_message', |
|
| 380 | + 'espresso_registrations_newsletter_selected_send' |
|
| 381 | + ) |
|
| 382 | + ) { |
|
| 383 | + return; |
|
| 384 | + } |
|
| 385 | + $routes_to_add_to = array( |
|
| 386 | + 'contact_list', |
|
| 387 | + 'event_registrations', |
|
| 388 | + 'default', |
|
| 389 | + ); |
|
| 390 | + if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
| 391 | + if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
| 392 | + || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
| 393 | + ) { |
|
| 394 | + echo ''; |
|
| 395 | + } else { |
|
| 396 | + $button_text = sprintf( |
|
| 397 | + esc_html__('Send Batch Message (%s selected)', 'event_espresso'), |
|
| 398 | + '<span class="send-selected-newsletter-count">0</span>' |
|
| 399 | + ); |
|
| 400 | + echo '<button id="selected-batch-send-trigger" class="button secondary-button">' |
|
| 401 | + . '<span class="dashicons dashicons-email "></span>' |
|
| 402 | + . $button_text |
|
| 403 | + . '</button>'; |
|
| 404 | + add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
| 405 | + } |
|
| 406 | + } |
|
| 407 | + } |
|
| 408 | 408 | |
| 409 | 409 | |
| 410 | - /** |
|
| 411 | - * @throws DomainException |
|
| 412 | - * @throws EE_Error |
|
| 413 | - * @throws InvalidArgumentException |
|
| 414 | - * @throws InvalidDataTypeException |
|
| 415 | - * @throws InvalidInterfaceException |
|
| 416 | - */ |
|
| 417 | - public function newsletter_send_form_skeleton() |
|
| 418 | - { |
|
| 419 | - $list_table = $this->_list_table_object; |
|
| 420 | - $codes = array(); |
|
| 421 | - // need to templates for the newsletter message type for the template selector. |
|
| 422 | - $values[] = array('text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
| 423 | - $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
| 424 | - array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
| 425 | - ); |
|
| 426 | - foreach ($mtps as $mtp) { |
|
| 427 | - $name = $mtp->name(); |
|
| 428 | - $values[] = array( |
|
| 429 | - 'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name, |
|
| 430 | - 'id' => $mtp->ID(), |
|
| 431 | - ); |
|
| 432 | - } |
|
| 433 | - // need to get a list of shortcodes that are available for the newsletter message type. |
|
| 434 | - $shortcodes = EEH_MSG_Template::get_shortcodes( |
|
| 435 | - 'newsletter', |
|
| 436 | - 'email', |
|
| 437 | - array(), |
|
| 438 | - 'attendee', |
|
| 439 | - false |
|
| 440 | - ); |
|
| 441 | - foreach ($shortcodes as $field => $shortcode_array) { |
|
| 442 | - $available_shortcodes = array(); |
|
| 443 | - foreach ($shortcode_array as $shortcode => $shortcode_details) { |
|
| 444 | - $field_id = $field === '[NEWSLETTER_CONTENT]' |
|
| 445 | - ? 'content' |
|
| 446 | - : $field; |
|
| 447 | - $field_id = 'batch-message-' . strtolower($field_id); |
|
| 448 | - $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
|
| 449 | - . $shortcode |
|
| 450 | - . '" data-linked-input-id="' . $field_id . '">' |
|
| 451 | - . $shortcode |
|
| 452 | - . '</span>'; |
|
| 453 | - } |
|
| 454 | - $codes[ $field ] = implode(', ', $available_shortcodes); |
|
| 455 | - } |
|
| 456 | - $shortcodes = $codes; |
|
| 457 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 458 | - $form_template_args = array( |
|
| 459 | - 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
| 460 | - 'form_route' => 'newsletter_selected_send', |
|
| 461 | - 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
| 462 | - 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
| 463 | - 'redirect_back_to' => $this->_req_action, |
|
| 464 | - 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
| 465 | - 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
| 466 | - 'shortcodes' => $shortcodes, |
|
| 467 | - 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
| 468 | - ); |
|
| 469 | - EEH_Template::display_template($form_template, $form_template_args); |
|
| 470 | - } |
|
| 410 | + /** |
|
| 411 | + * @throws DomainException |
|
| 412 | + * @throws EE_Error |
|
| 413 | + * @throws InvalidArgumentException |
|
| 414 | + * @throws InvalidDataTypeException |
|
| 415 | + * @throws InvalidInterfaceException |
|
| 416 | + */ |
|
| 417 | + public function newsletter_send_form_skeleton() |
|
| 418 | + { |
|
| 419 | + $list_table = $this->_list_table_object; |
|
| 420 | + $codes = array(); |
|
| 421 | + // need to templates for the newsletter message type for the template selector. |
|
| 422 | + $values[] = array('text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
| 423 | + $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
| 424 | + array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
| 425 | + ); |
|
| 426 | + foreach ($mtps as $mtp) { |
|
| 427 | + $name = $mtp->name(); |
|
| 428 | + $values[] = array( |
|
| 429 | + 'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name, |
|
| 430 | + 'id' => $mtp->ID(), |
|
| 431 | + ); |
|
| 432 | + } |
|
| 433 | + // need to get a list of shortcodes that are available for the newsletter message type. |
|
| 434 | + $shortcodes = EEH_MSG_Template::get_shortcodes( |
|
| 435 | + 'newsletter', |
|
| 436 | + 'email', |
|
| 437 | + array(), |
|
| 438 | + 'attendee', |
|
| 439 | + false |
|
| 440 | + ); |
|
| 441 | + foreach ($shortcodes as $field => $shortcode_array) { |
|
| 442 | + $available_shortcodes = array(); |
|
| 443 | + foreach ($shortcode_array as $shortcode => $shortcode_details) { |
|
| 444 | + $field_id = $field === '[NEWSLETTER_CONTENT]' |
|
| 445 | + ? 'content' |
|
| 446 | + : $field; |
|
| 447 | + $field_id = 'batch-message-' . strtolower($field_id); |
|
| 448 | + $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
|
| 449 | + . $shortcode |
|
| 450 | + . '" data-linked-input-id="' . $field_id . '">' |
|
| 451 | + . $shortcode |
|
| 452 | + . '</span>'; |
|
| 453 | + } |
|
| 454 | + $codes[ $field ] = implode(', ', $available_shortcodes); |
|
| 455 | + } |
|
| 456 | + $shortcodes = $codes; |
|
| 457 | + $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 458 | + $form_template_args = array( |
|
| 459 | + 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
| 460 | + 'form_route' => 'newsletter_selected_send', |
|
| 461 | + 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
| 462 | + 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
| 463 | + 'redirect_back_to' => $this->_req_action, |
|
| 464 | + 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
| 465 | + 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
| 466 | + 'shortcodes' => $shortcodes, |
|
| 467 | + 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
| 468 | + ); |
|
| 469 | + EEH_Template::display_template($form_template, $form_template_args); |
|
| 470 | + } |
|
| 471 | 471 | |
| 472 | 472 | |
| 473 | - /** |
|
| 474 | - * Handles sending selected registrations/contacts a newsletter. |
|
| 475 | - * |
|
| 476 | - * @since 4.3.0 |
|
| 477 | - * @return void |
|
| 478 | - * @throws EE_Error |
|
| 479 | - * @throws InvalidArgumentException |
|
| 480 | - * @throws InvalidDataTypeException |
|
| 481 | - * @throws InvalidInterfaceException |
|
| 482 | - */ |
|
| 483 | - protected function _newsletter_selected_send() |
|
| 484 | - { |
|
| 485 | - $success = true; |
|
| 486 | - // first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
| 487 | - if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
| 488 | - EE_Error::add_error( |
|
| 489 | - esc_html__( |
|
| 490 | - 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
| 491 | - 'event_espresso' |
|
| 492 | - ), |
|
| 493 | - __FILE__, |
|
| 494 | - __FUNCTION__, |
|
| 495 | - __LINE__ |
|
| 496 | - ); |
|
| 497 | - $success = false; |
|
| 498 | - } |
|
| 499 | - if ($success) { |
|
| 500 | - // update Message template in case there are any changes |
|
| 501 | - $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
| 502 | - $this->_req_data['newsletter_mtp_selected'] |
|
| 503 | - ); |
|
| 504 | - $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
| 505 | - ? $Message_Template_Group->context_templates() |
|
| 506 | - : array(); |
|
| 507 | - if (empty($Message_Templates)) { |
|
| 508 | - EE_Error::add_error( |
|
| 509 | - esc_html__( |
|
| 510 | - 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
| 511 | - 'event_espresso' |
|
| 512 | - ), |
|
| 513 | - __FILE__, |
|
| 514 | - __FUNCTION__, |
|
| 515 | - __LINE__ |
|
| 516 | - ); |
|
| 517 | - } |
|
| 518 | - // let's just update the specific fields |
|
| 519 | - foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
| 520 | - if ($Message_Template instanceof EE_Message_Template) { |
|
| 521 | - $field = $Message_Template->get('MTP_template_field'); |
|
| 522 | - $content = $Message_Template->get('MTP_content'); |
|
| 523 | - $new_content = $content; |
|
| 524 | - switch ($field) { |
|
| 525 | - case 'from': |
|
| 526 | - $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
| 527 | - ? $this->_req_data['batch_message']['from'] |
|
| 528 | - : $content; |
|
| 529 | - break; |
|
| 530 | - case 'subject': |
|
| 531 | - $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
| 532 | - ? $this->_req_data['batch_message']['subject'] |
|
| 533 | - : $content; |
|
| 534 | - break; |
|
| 535 | - case 'content': |
|
| 536 | - $new_content = $content; |
|
| 537 | - $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
| 538 | - ? $this->_req_data['batch_message']['content'] |
|
| 539 | - : $content['newsletter_content']; |
|
| 540 | - break; |
|
| 541 | - default: |
|
| 542 | - // continue the foreach loop, we don't want to set $new_content nor save. |
|
| 543 | - continue 2; |
|
| 544 | - } |
|
| 545 | - $Message_Template->set('MTP_content', $new_content); |
|
| 546 | - $Message_Template->save(); |
|
| 547 | - } |
|
| 548 | - } |
|
| 549 | - // great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
| 550 | - $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
| 551 | - ? $this->_req_data['batch_message']['id_type'] |
|
| 552 | - : 'registration'; |
|
| 553 | - // id_type will affect how we assemble the ids. |
|
| 554 | - $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
| 555 | - ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
| 556 | - : array(); |
|
| 557 | - $registrations_used_for_contact_data = array(); |
|
| 558 | - // using switch because eventually we'll have other contexts that will be used for generating messages. |
|
| 559 | - switch ($id_type) { |
|
| 560 | - case 'registration': |
|
| 561 | - $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
| 562 | - array( |
|
| 563 | - array( |
|
| 564 | - 'REG_ID' => array('IN', $ids), |
|
| 565 | - ), |
|
| 566 | - ) |
|
| 567 | - ); |
|
| 568 | - break; |
|
| 569 | - case 'contact': |
|
| 570 | - $registrations_used_for_contact_data = EEM_Registration::instance() |
|
| 571 | - ->get_latest_registration_for_each_of_given_contacts( |
|
| 572 | - $ids |
|
| 573 | - ); |
|
| 574 | - break; |
|
| 575 | - } |
|
| 576 | - do_action_ref_array( |
|
| 577 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
| 578 | - array( |
|
| 579 | - $registrations_used_for_contact_data, |
|
| 580 | - $Message_Template_Group->ID(), |
|
| 581 | - ) |
|
| 582 | - ); |
|
| 583 | - // kept for backward compat, internally we no longer use this action. |
|
| 584 | - // @deprecated 4.8.36.rc.002 |
|
| 585 | - $contacts = $id_type === 'registration' |
|
| 586 | - ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
| 587 | - : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
| 588 | - do_action_ref_array( |
|
| 589 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
| 590 | - array( |
|
| 591 | - $contacts, |
|
| 592 | - $Message_Template_Group->ID(), |
|
| 593 | - ) |
|
| 594 | - ); |
|
| 595 | - } |
|
| 596 | - $query_args = array( |
|
| 597 | - 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
| 598 | - ? $this->_req_data['redirect_back_to'] |
|
| 599 | - : 'default', |
|
| 600 | - ); |
|
| 601 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 602 | - } |
|
| 473 | + /** |
|
| 474 | + * Handles sending selected registrations/contacts a newsletter. |
|
| 475 | + * |
|
| 476 | + * @since 4.3.0 |
|
| 477 | + * @return void |
|
| 478 | + * @throws EE_Error |
|
| 479 | + * @throws InvalidArgumentException |
|
| 480 | + * @throws InvalidDataTypeException |
|
| 481 | + * @throws InvalidInterfaceException |
|
| 482 | + */ |
|
| 483 | + protected function _newsletter_selected_send() |
|
| 484 | + { |
|
| 485 | + $success = true; |
|
| 486 | + // first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
| 487 | + if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
| 488 | + EE_Error::add_error( |
|
| 489 | + esc_html__( |
|
| 490 | + 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
| 491 | + 'event_espresso' |
|
| 492 | + ), |
|
| 493 | + __FILE__, |
|
| 494 | + __FUNCTION__, |
|
| 495 | + __LINE__ |
|
| 496 | + ); |
|
| 497 | + $success = false; |
|
| 498 | + } |
|
| 499 | + if ($success) { |
|
| 500 | + // update Message template in case there are any changes |
|
| 501 | + $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
| 502 | + $this->_req_data['newsletter_mtp_selected'] |
|
| 503 | + ); |
|
| 504 | + $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
| 505 | + ? $Message_Template_Group->context_templates() |
|
| 506 | + : array(); |
|
| 507 | + if (empty($Message_Templates)) { |
|
| 508 | + EE_Error::add_error( |
|
| 509 | + esc_html__( |
|
| 510 | + 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
| 511 | + 'event_espresso' |
|
| 512 | + ), |
|
| 513 | + __FILE__, |
|
| 514 | + __FUNCTION__, |
|
| 515 | + __LINE__ |
|
| 516 | + ); |
|
| 517 | + } |
|
| 518 | + // let's just update the specific fields |
|
| 519 | + foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
| 520 | + if ($Message_Template instanceof EE_Message_Template) { |
|
| 521 | + $field = $Message_Template->get('MTP_template_field'); |
|
| 522 | + $content = $Message_Template->get('MTP_content'); |
|
| 523 | + $new_content = $content; |
|
| 524 | + switch ($field) { |
|
| 525 | + case 'from': |
|
| 526 | + $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
| 527 | + ? $this->_req_data['batch_message']['from'] |
|
| 528 | + : $content; |
|
| 529 | + break; |
|
| 530 | + case 'subject': |
|
| 531 | + $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
| 532 | + ? $this->_req_data['batch_message']['subject'] |
|
| 533 | + : $content; |
|
| 534 | + break; |
|
| 535 | + case 'content': |
|
| 536 | + $new_content = $content; |
|
| 537 | + $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
| 538 | + ? $this->_req_data['batch_message']['content'] |
|
| 539 | + : $content['newsletter_content']; |
|
| 540 | + break; |
|
| 541 | + default: |
|
| 542 | + // continue the foreach loop, we don't want to set $new_content nor save. |
|
| 543 | + continue 2; |
|
| 544 | + } |
|
| 545 | + $Message_Template->set('MTP_content', $new_content); |
|
| 546 | + $Message_Template->save(); |
|
| 547 | + } |
|
| 548 | + } |
|
| 549 | + // great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
| 550 | + $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
| 551 | + ? $this->_req_data['batch_message']['id_type'] |
|
| 552 | + : 'registration'; |
|
| 553 | + // id_type will affect how we assemble the ids. |
|
| 554 | + $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
| 555 | + ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
| 556 | + : array(); |
|
| 557 | + $registrations_used_for_contact_data = array(); |
|
| 558 | + // using switch because eventually we'll have other contexts that will be used for generating messages. |
|
| 559 | + switch ($id_type) { |
|
| 560 | + case 'registration': |
|
| 561 | + $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
| 562 | + array( |
|
| 563 | + array( |
|
| 564 | + 'REG_ID' => array('IN', $ids), |
|
| 565 | + ), |
|
| 566 | + ) |
|
| 567 | + ); |
|
| 568 | + break; |
|
| 569 | + case 'contact': |
|
| 570 | + $registrations_used_for_contact_data = EEM_Registration::instance() |
|
| 571 | + ->get_latest_registration_for_each_of_given_contacts( |
|
| 572 | + $ids |
|
| 573 | + ); |
|
| 574 | + break; |
|
| 575 | + } |
|
| 576 | + do_action_ref_array( |
|
| 577 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
| 578 | + array( |
|
| 579 | + $registrations_used_for_contact_data, |
|
| 580 | + $Message_Template_Group->ID(), |
|
| 581 | + ) |
|
| 582 | + ); |
|
| 583 | + // kept for backward compat, internally we no longer use this action. |
|
| 584 | + // @deprecated 4.8.36.rc.002 |
|
| 585 | + $contacts = $id_type === 'registration' |
|
| 586 | + ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
| 587 | + : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
| 588 | + do_action_ref_array( |
|
| 589 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
| 590 | + array( |
|
| 591 | + $contacts, |
|
| 592 | + $Message_Template_Group->ID(), |
|
| 593 | + ) |
|
| 594 | + ); |
|
| 595 | + } |
|
| 596 | + $query_args = array( |
|
| 597 | + 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
| 598 | + ? $this->_req_data['redirect_back_to'] |
|
| 599 | + : 'default', |
|
| 600 | + ); |
|
| 601 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 602 | + } |
|
| 603 | 603 | |
| 604 | 604 | |
| 605 | - /** |
|
| 606 | - * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
| 607 | - * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
| 608 | - */ |
|
| 609 | - protected function _registration_reports_js_setup() |
|
| 610 | - { |
|
| 611 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
| 612 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
| 613 | - } |
|
| 605 | + /** |
|
| 606 | + * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
| 607 | + * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
| 608 | + */ |
|
| 609 | + protected function _registration_reports_js_setup() |
|
| 610 | + { |
|
| 611 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
| 612 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
| 613 | + } |
|
| 614 | 614 | |
| 615 | 615 | |
| 616 | - /** |
|
| 617 | - * generates Business Reports regarding Registrations |
|
| 618 | - * |
|
| 619 | - * @access protected |
|
| 620 | - * @return void |
|
| 621 | - * @throws DomainException |
|
| 622 | - */ |
|
| 623 | - protected function _registration_reports() |
|
| 624 | - { |
|
| 625 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 626 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 627 | - $template_path, |
|
| 628 | - $this->_reports_template_data, |
|
| 629 | - true |
|
| 630 | - ); |
|
| 631 | - // the final template wrapper |
|
| 632 | - $this->display_admin_page_with_no_sidebar(); |
|
| 633 | - } |
|
| 616 | + /** |
|
| 617 | + * generates Business Reports regarding Registrations |
|
| 618 | + * |
|
| 619 | + * @access protected |
|
| 620 | + * @return void |
|
| 621 | + * @throws DomainException |
|
| 622 | + */ |
|
| 623 | + protected function _registration_reports() |
|
| 624 | + { |
|
| 625 | + $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 626 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 627 | + $template_path, |
|
| 628 | + $this->_reports_template_data, |
|
| 629 | + true |
|
| 630 | + ); |
|
| 631 | + // the final template wrapper |
|
| 632 | + $this->display_admin_page_with_no_sidebar(); |
|
| 633 | + } |
|
| 634 | 634 | |
| 635 | 635 | |
| 636 | - /** |
|
| 637 | - * Generates Business Report showing total registrations per day. |
|
| 638 | - * |
|
| 639 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 640 | - * @return string |
|
| 641 | - * @throws EE_Error |
|
| 642 | - * @throws InvalidArgumentException |
|
| 643 | - * @throws InvalidDataTypeException |
|
| 644 | - * @throws InvalidInterfaceException |
|
| 645 | - */ |
|
| 646 | - private function _registrations_per_day_report($period = '-1 month') |
|
| 647 | - { |
|
| 648 | - $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
| 649 | - $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
| 650 | - $results = (array) $results; |
|
| 651 | - $regs = array(); |
|
| 652 | - $subtitle = ''; |
|
| 653 | - if ($results) { |
|
| 654 | - $column_titles = array(); |
|
| 655 | - $tracker = 0; |
|
| 656 | - foreach ($results as $result) { |
|
| 657 | - $report_column_values = array(); |
|
| 658 | - foreach ($result as $property_name => $property_value) { |
|
| 659 | - $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
| 660 | - : (int) $property_value; |
|
| 661 | - $report_column_values[] = $property_value; |
|
| 662 | - if ($tracker === 0) { |
|
| 663 | - if ($property_name === 'Registration_REG_date') { |
|
| 664 | - $column_titles[] = esc_html__( |
|
| 665 | - 'Date (only days with registrations are shown)', |
|
| 666 | - 'event_espresso' |
|
| 667 | - ); |
|
| 668 | - } else { |
|
| 669 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 670 | - } |
|
| 671 | - } |
|
| 672 | - } |
|
| 673 | - $tracker++; |
|
| 674 | - $regs[] = $report_column_values; |
|
| 675 | - } |
|
| 676 | - // make sure the column_titles is pushed to the beginning of the array |
|
| 677 | - array_unshift($regs, $column_titles); |
|
| 678 | - // setup the date range. |
|
| 679 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 680 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 681 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
| 682 | - $subtitle = sprintf( |
|
| 683 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 684 | - $beginning_date->format('Y-m-d'), |
|
| 685 | - $ending_date->format('Y-m-d') |
|
| 686 | - ); |
|
| 687 | - } |
|
| 688 | - $report_title = esc_html__('Total Registrations per Day', 'event_espresso'); |
|
| 689 | - $report_params = array( |
|
| 690 | - 'title' => $report_title, |
|
| 691 | - 'subtitle' => $subtitle, |
|
| 692 | - 'id' => $report_ID, |
|
| 693 | - 'regs' => $regs, |
|
| 694 | - 'noResults' => empty($regs), |
|
| 695 | - 'noRegsMsg' => sprintf( |
|
| 696 | - esc_html__( |
|
| 697 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
| 698 | - 'event_espresso' |
|
| 699 | - ), |
|
| 700 | - '<h2>' . $report_title . '</h2><p>', |
|
| 701 | - '</p>' |
|
| 702 | - ), |
|
| 703 | - ); |
|
| 704 | - wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
| 705 | - return $report_ID; |
|
| 706 | - } |
|
| 636 | + /** |
|
| 637 | + * Generates Business Report showing total registrations per day. |
|
| 638 | + * |
|
| 639 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 640 | + * @return string |
|
| 641 | + * @throws EE_Error |
|
| 642 | + * @throws InvalidArgumentException |
|
| 643 | + * @throws InvalidDataTypeException |
|
| 644 | + * @throws InvalidInterfaceException |
|
| 645 | + */ |
|
| 646 | + private function _registrations_per_day_report($period = '-1 month') |
|
| 647 | + { |
|
| 648 | + $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
| 649 | + $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
| 650 | + $results = (array) $results; |
|
| 651 | + $regs = array(); |
|
| 652 | + $subtitle = ''; |
|
| 653 | + if ($results) { |
|
| 654 | + $column_titles = array(); |
|
| 655 | + $tracker = 0; |
|
| 656 | + foreach ($results as $result) { |
|
| 657 | + $report_column_values = array(); |
|
| 658 | + foreach ($result as $property_name => $property_value) { |
|
| 659 | + $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
| 660 | + : (int) $property_value; |
|
| 661 | + $report_column_values[] = $property_value; |
|
| 662 | + if ($tracker === 0) { |
|
| 663 | + if ($property_name === 'Registration_REG_date') { |
|
| 664 | + $column_titles[] = esc_html__( |
|
| 665 | + 'Date (only days with registrations are shown)', |
|
| 666 | + 'event_espresso' |
|
| 667 | + ); |
|
| 668 | + } else { |
|
| 669 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 670 | + } |
|
| 671 | + } |
|
| 672 | + } |
|
| 673 | + $tracker++; |
|
| 674 | + $regs[] = $report_column_values; |
|
| 675 | + } |
|
| 676 | + // make sure the column_titles is pushed to the beginning of the array |
|
| 677 | + array_unshift($regs, $column_titles); |
|
| 678 | + // setup the date range. |
|
| 679 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 680 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 681 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
| 682 | + $subtitle = sprintf( |
|
| 683 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 684 | + $beginning_date->format('Y-m-d'), |
|
| 685 | + $ending_date->format('Y-m-d') |
|
| 686 | + ); |
|
| 687 | + } |
|
| 688 | + $report_title = esc_html__('Total Registrations per Day', 'event_espresso'); |
|
| 689 | + $report_params = array( |
|
| 690 | + 'title' => $report_title, |
|
| 691 | + 'subtitle' => $subtitle, |
|
| 692 | + 'id' => $report_ID, |
|
| 693 | + 'regs' => $regs, |
|
| 694 | + 'noResults' => empty($regs), |
|
| 695 | + 'noRegsMsg' => sprintf( |
|
| 696 | + esc_html__( |
|
| 697 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
| 698 | + 'event_espresso' |
|
| 699 | + ), |
|
| 700 | + '<h2>' . $report_title . '</h2><p>', |
|
| 701 | + '</p>' |
|
| 702 | + ), |
|
| 703 | + ); |
|
| 704 | + wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
| 705 | + return $report_ID; |
|
| 706 | + } |
|
| 707 | 707 | |
| 708 | 708 | |
| 709 | - /** |
|
| 710 | - * Generates Business Report showing total registrations per event. |
|
| 711 | - * |
|
| 712 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 713 | - * @return string |
|
| 714 | - * @throws EE_Error |
|
| 715 | - * @throws InvalidArgumentException |
|
| 716 | - * @throws InvalidDataTypeException |
|
| 717 | - * @throws InvalidInterfaceException |
|
| 718 | - */ |
|
| 719 | - private function _registrations_per_event_report($period = '-1 month') |
|
| 720 | - { |
|
| 721 | - $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
| 722 | - $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
| 723 | - $results = (array) $results; |
|
| 724 | - $regs = array(); |
|
| 725 | - $subtitle = ''; |
|
| 726 | - if ($results) { |
|
| 727 | - $column_titles = array(); |
|
| 728 | - $tracker = 0; |
|
| 729 | - foreach ($results as $result) { |
|
| 730 | - $report_column_values = array(); |
|
| 731 | - foreach ($result as $property_name => $property_value) { |
|
| 732 | - $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
| 733 | - $property_value, |
|
| 734 | - 4, |
|
| 735 | - '...' |
|
| 736 | - ) : (int) $property_value; |
|
| 737 | - $report_column_values[] = $property_value; |
|
| 738 | - if ($tracker === 0) { |
|
| 739 | - if ($property_name === 'Registration_Event') { |
|
| 740 | - $column_titles[] = esc_html__('Event', 'event_espresso'); |
|
| 741 | - } else { |
|
| 742 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 743 | - } |
|
| 744 | - } |
|
| 745 | - } |
|
| 746 | - $tracker++; |
|
| 747 | - $regs[] = $report_column_values; |
|
| 748 | - } |
|
| 749 | - // make sure the column_titles is pushed to the beginning of the array |
|
| 750 | - array_unshift($regs, $column_titles); |
|
| 751 | - // setup the date range. |
|
| 752 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 753 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 754 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
| 755 | - $subtitle = sprintf( |
|
| 756 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 757 | - $beginning_date->format('Y-m-d'), |
|
| 758 | - $ending_date->format('Y-m-d') |
|
| 759 | - ); |
|
| 760 | - } |
|
| 761 | - $report_title = esc_html__('Total Registrations per Event', 'event_espresso'); |
|
| 762 | - $report_params = array( |
|
| 763 | - 'title' => $report_title, |
|
| 764 | - 'subtitle' => $subtitle, |
|
| 765 | - 'id' => $report_ID, |
|
| 766 | - 'regs' => $regs, |
|
| 767 | - 'noResults' => empty($regs), |
|
| 768 | - 'noRegsMsg' => sprintf( |
|
| 769 | - esc_html__( |
|
| 770 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
| 771 | - 'event_espresso' |
|
| 772 | - ), |
|
| 773 | - '<h2>' . $report_title . '</h2><p>', |
|
| 774 | - '</p>' |
|
| 775 | - ), |
|
| 776 | - ); |
|
| 777 | - wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
| 778 | - return $report_ID; |
|
| 779 | - } |
|
| 709 | + /** |
|
| 710 | + * Generates Business Report showing total registrations per event. |
|
| 711 | + * |
|
| 712 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 713 | + * @return string |
|
| 714 | + * @throws EE_Error |
|
| 715 | + * @throws InvalidArgumentException |
|
| 716 | + * @throws InvalidDataTypeException |
|
| 717 | + * @throws InvalidInterfaceException |
|
| 718 | + */ |
|
| 719 | + private function _registrations_per_event_report($period = '-1 month') |
|
| 720 | + { |
|
| 721 | + $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
| 722 | + $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
| 723 | + $results = (array) $results; |
|
| 724 | + $regs = array(); |
|
| 725 | + $subtitle = ''; |
|
| 726 | + if ($results) { |
|
| 727 | + $column_titles = array(); |
|
| 728 | + $tracker = 0; |
|
| 729 | + foreach ($results as $result) { |
|
| 730 | + $report_column_values = array(); |
|
| 731 | + foreach ($result as $property_name => $property_value) { |
|
| 732 | + $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
| 733 | + $property_value, |
|
| 734 | + 4, |
|
| 735 | + '...' |
|
| 736 | + ) : (int) $property_value; |
|
| 737 | + $report_column_values[] = $property_value; |
|
| 738 | + if ($tracker === 0) { |
|
| 739 | + if ($property_name === 'Registration_Event') { |
|
| 740 | + $column_titles[] = esc_html__('Event', 'event_espresso'); |
|
| 741 | + } else { |
|
| 742 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 743 | + } |
|
| 744 | + } |
|
| 745 | + } |
|
| 746 | + $tracker++; |
|
| 747 | + $regs[] = $report_column_values; |
|
| 748 | + } |
|
| 749 | + // make sure the column_titles is pushed to the beginning of the array |
|
| 750 | + array_unshift($regs, $column_titles); |
|
| 751 | + // setup the date range. |
|
| 752 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 753 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 754 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
| 755 | + $subtitle = sprintf( |
|
| 756 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 757 | + $beginning_date->format('Y-m-d'), |
|
| 758 | + $ending_date->format('Y-m-d') |
|
| 759 | + ); |
|
| 760 | + } |
|
| 761 | + $report_title = esc_html__('Total Registrations per Event', 'event_espresso'); |
|
| 762 | + $report_params = array( |
|
| 763 | + 'title' => $report_title, |
|
| 764 | + 'subtitle' => $subtitle, |
|
| 765 | + 'id' => $report_ID, |
|
| 766 | + 'regs' => $regs, |
|
| 767 | + 'noResults' => empty($regs), |
|
| 768 | + 'noRegsMsg' => sprintf( |
|
| 769 | + esc_html__( |
|
| 770 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
| 771 | + 'event_espresso' |
|
| 772 | + ), |
|
| 773 | + '<h2>' . $report_title . '</h2><p>', |
|
| 774 | + '</p>' |
|
| 775 | + ), |
|
| 776 | + ); |
|
| 777 | + wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
| 778 | + return $report_ID; |
|
| 779 | + } |
|
| 780 | 780 | |
| 781 | 781 | |
| 782 | - /** |
|
| 783 | - * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
| 784 | - * |
|
| 785 | - * @access protected |
|
| 786 | - * @return void |
|
| 787 | - * @throws EE_Error |
|
| 788 | - * @throws InvalidArgumentException |
|
| 789 | - * @throws InvalidDataTypeException |
|
| 790 | - * @throws InvalidInterfaceException |
|
| 791 | - * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 792 | - */ |
|
| 793 | - protected function _registration_checkin_list_table() |
|
| 794 | - { |
|
| 795 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 796 | - $reg_id = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : null; |
|
| 797 | - /** @var EE_Registration $registration */ |
|
| 798 | - $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
| 799 | - if (! $registration instanceof EE_Registration) { |
|
| 800 | - throw new EE_Error( |
|
| 801 | - sprintf( |
|
| 802 | - esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
|
| 803 | - $reg_id |
|
| 804 | - ) |
|
| 805 | - ); |
|
| 806 | - } |
|
| 807 | - $attendee = $registration->attendee(); |
|
| 808 | - $this->_admin_page_title .= $this->get_action_link_or_button( |
|
| 809 | - 'new_registration', |
|
| 810 | - 'add-registrant', |
|
| 811 | - array('event_id' => $registration->event_ID()), |
|
| 812 | - 'add-new-h2' |
|
| 813 | - ); |
|
| 814 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 815 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 816 | - $legend_items = array( |
|
| 817 | - 'checkin' => array( |
|
| 818 | - 'class' => $checked_in->cssClasses(), |
|
| 819 | - 'desc' => $checked_in->legendLabel(), |
|
| 820 | - ), |
|
| 821 | - 'checkout' => array( |
|
| 822 | - 'class' => $checked_out->cssClasses(), |
|
| 823 | - 'desc' => $checked_out->legendLabel(), |
|
| 824 | - ), |
|
| 825 | - ); |
|
| 826 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 827 | - $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 828 | - /** @var EE_Datetime $datetime */ |
|
| 829 | - $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
| 830 | - $datetime_label = ''; |
|
| 831 | - if ($datetime instanceof EE_Datetime) { |
|
| 832 | - $datetime_label = $datetime->get_dtt_display_name(true); |
|
| 833 | - $datetime_label .= ! empty($datetime_label) |
|
| 834 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 835 | - : $datetime->get_dtt_display_name(); |
|
| 836 | - } |
|
| 837 | - $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
| 838 | - ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 839 | - array( |
|
| 840 | - 'action' => 'event_registrations', |
|
| 841 | - 'event_id' => $registration->event_ID(), |
|
| 842 | - 'DTT_ID' => $dtt_id, |
|
| 843 | - ), |
|
| 844 | - $this->_admin_base_url |
|
| 845 | - ) |
|
| 846 | - : ''; |
|
| 847 | - $datetime_link = ! empty($datetime_link) |
|
| 848 | - ? '<a href="' . $datetime_link . '">' |
|
| 849 | - . '<span id="checkin-dtt">' |
|
| 850 | - . $datetime_label |
|
| 851 | - . '</span></a>' |
|
| 852 | - : $datetime_label; |
|
| 853 | - $attendee_name = $attendee instanceof EE_Attendee |
|
| 854 | - ? $attendee->full_name() |
|
| 855 | - : ''; |
|
| 856 | - $attendee_link = $attendee instanceof EE_Attendee |
|
| 857 | - ? $attendee->get_admin_details_link() |
|
| 858 | - : ''; |
|
| 859 | - $attendee_link = ! empty($attendee_link) |
|
| 860 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 861 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 862 | - . '<span id="checkin-attendee-name">' |
|
| 863 | - . $attendee_name |
|
| 864 | - . '</span></a>' |
|
| 865 | - : ''; |
|
| 866 | - $event_link = $registration->event() instanceof EE_Event |
|
| 867 | - ? $registration->event()->get_admin_details_link() |
|
| 868 | - : ''; |
|
| 869 | - $event_link = ! empty($event_link) |
|
| 870 | - ? '<a href="' . $event_link . '"' |
|
| 871 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 872 | - . '<span id="checkin-event-name">' |
|
| 873 | - . $registration->event_name() |
|
| 874 | - . '</span>' |
|
| 875 | - . '</a>' |
|
| 876 | - : ''; |
|
| 877 | - $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
| 878 | - ? '<h2>' . sprintf( |
|
| 879 | - esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
| 880 | - $attendee_link, |
|
| 881 | - $datetime_link, |
|
| 882 | - $event_link |
|
| 883 | - ) . '</h2>' |
|
| 884 | - : ''; |
|
| 885 | - $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
| 886 | - ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
| 887 | - $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
| 888 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 889 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 890 | - } |
|
| 782 | + /** |
|
| 783 | + * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
| 784 | + * |
|
| 785 | + * @access protected |
|
| 786 | + * @return void |
|
| 787 | + * @throws EE_Error |
|
| 788 | + * @throws InvalidArgumentException |
|
| 789 | + * @throws InvalidDataTypeException |
|
| 790 | + * @throws InvalidInterfaceException |
|
| 791 | + * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 792 | + */ |
|
| 793 | + protected function _registration_checkin_list_table() |
|
| 794 | + { |
|
| 795 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 796 | + $reg_id = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : null; |
|
| 797 | + /** @var EE_Registration $registration */ |
|
| 798 | + $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
| 799 | + if (! $registration instanceof EE_Registration) { |
|
| 800 | + throw new EE_Error( |
|
| 801 | + sprintf( |
|
| 802 | + esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
|
| 803 | + $reg_id |
|
| 804 | + ) |
|
| 805 | + ); |
|
| 806 | + } |
|
| 807 | + $attendee = $registration->attendee(); |
|
| 808 | + $this->_admin_page_title .= $this->get_action_link_or_button( |
|
| 809 | + 'new_registration', |
|
| 810 | + 'add-registrant', |
|
| 811 | + array('event_id' => $registration->event_ID()), |
|
| 812 | + 'add-new-h2' |
|
| 813 | + ); |
|
| 814 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 815 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 816 | + $legend_items = array( |
|
| 817 | + 'checkin' => array( |
|
| 818 | + 'class' => $checked_in->cssClasses(), |
|
| 819 | + 'desc' => $checked_in->legendLabel(), |
|
| 820 | + ), |
|
| 821 | + 'checkout' => array( |
|
| 822 | + 'class' => $checked_out->cssClasses(), |
|
| 823 | + 'desc' => $checked_out->legendLabel(), |
|
| 824 | + ), |
|
| 825 | + ); |
|
| 826 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 827 | + $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 828 | + /** @var EE_Datetime $datetime */ |
|
| 829 | + $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
| 830 | + $datetime_label = ''; |
|
| 831 | + if ($datetime instanceof EE_Datetime) { |
|
| 832 | + $datetime_label = $datetime->get_dtt_display_name(true); |
|
| 833 | + $datetime_label .= ! empty($datetime_label) |
|
| 834 | + ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 835 | + : $datetime->get_dtt_display_name(); |
|
| 836 | + } |
|
| 837 | + $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
| 838 | + ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 839 | + array( |
|
| 840 | + 'action' => 'event_registrations', |
|
| 841 | + 'event_id' => $registration->event_ID(), |
|
| 842 | + 'DTT_ID' => $dtt_id, |
|
| 843 | + ), |
|
| 844 | + $this->_admin_base_url |
|
| 845 | + ) |
|
| 846 | + : ''; |
|
| 847 | + $datetime_link = ! empty($datetime_link) |
|
| 848 | + ? '<a href="' . $datetime_link . '">' |
|
| 849 | + . '<span id="checkin-dtt">' |
|
| 850 | + . $datetime_label |
|
| 851 | + . '</span></a>' |
|
| 852 | + : $datetime_label; |
|
| 853 | + $attendee_name = $attendee instanceof EE_Attendee |
|
| 854 | + ? $attendee->full_name() |
|
| 855 | + : ''; |
|
| 856 | + $attendee_link = $attendee instanceof EE_Attendee |
|
| 857 | + ? $attendee->get_admin_details_link() |
|
| 858 | + : ''; |
|
| 859 | + $attendee_link = ! empty($attendee_link) |
|
| 860 | + ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 861 | + . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 862 | + . '<span id="checkin-attendee-name">' |
|
| 863 | + . $attendee_name |
|
| 864 | + . '</span></a>' |
|
| 865 | + : ''; |
|
| 866 | + $event_link = $registration->event() instanceof EE_Event |
|
| 867 | + ? $registration->event()->get_admin_details_link() |
|
| 868 | + : ''; |
|
| 869 | + $event_link = ! empty($event_link) |
|
| 870 | + ? '<a href="' . $event_link . '"' |
|
| 871 | + . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 872 | + . '<span id="checkin-event-name">' |
|
| 873 | + . $registration->event_name() |
|
| 874 | + . '</span>' |
|
| 875 | + . '</a>' |
|
| 876 | + : ''; |
|
| 877 | + $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
| 878 | + ? '<h2>' . sprintf( |
|
| 879 | + esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
| 880 | + $attendee_link, |
|
| 881 | + $datetime_link, |
|
| 882 | + $event_link |
|
| 883 | + ) . '</h2>' |
|
| 884 | + : ''; |
|
| 885 | + $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
| 886 | + ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
| 887 | + $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
| 888 | + ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 889 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 890 | + } |
|
| 891 | 891 | |
| 892 | 892 | |
| 893 | - /** |
|
| 894 | - * toggle the Check-in status for the given registration (coming from ajax) |
|
| 895 | - * |
|
| 896 | - * @return void (JSON) |
|
| 897 | - * @throws EE_Error |
|
| 898 | - * @throws InvalidArgumentException |
|
| 899 | - * @throws InvalidDataTypeException |
|
| 900 | - * @throws InvalidInterfaceException |
|
| 901 | - */ |
|
| 902 | - public function toggle_checkin_status() |
|
| 903 | - { |
|
| 904 | - // first make sure we have the necessary data |
|
| 905 | - if (! isset($this->_req_data['_regid'])) { |
|
| 906 | - EE_Error::add_error( |
|
| 907 | - esc_html__( |
|
| 908 | - 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
|
| 909 | - 'event_espresso' |
|
| 910 | - ), |
|
| 911 | - __FILE__, |
|
| 912 | - __FUNCTION__, |
|
| 913 | - __LINE__ |
|
| 914 | - ); |
|
| 915 | - $this->_template_args['success'] = false; |
|
| 916 | - $this->_template_args['error'] = true; |
|
| 917 | - $this->_return_json(); |
|
| 918 | - }; |
|
| 919 | - // do a nonce check cause we're not coming in from an normal route here. |
|
| 920 | - $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
| 921 | - : ''; |
|
| 922 | - $nonce_ref = 'checkin_nonce'; |
|
| 923 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
| 924 | - // beautiful! Made it this far so let's get the status. |
|
| 925 | - $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
| 926 | - // setup new class to return via ajax |
|
| 927 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 928 | - $this->_template_args['success'] = true; |
|
| 929 | - $this->_return_json(); |
|
| 930 | - } |
|
| 893 | + /** |
|
| 894 | + * toggle the Check-in status for the given registration (coming from ajax) |
|
| 895 | + * |
|
| 896 | + * @return void (JSON) |
|
| 897 | + * @throws EE_Error |
|
| 898 | + * @throws InvalidArgumentException |
|
| 899 | + * @throws InvalidDataTypeException |
|
| 900 | + * @throws InvalidInterfaceException |
|
| 901 | + */ |
|
| 902 | + public function toggle_checkin_status() |
|
| 903 | + { |
|
| 904 | + // first make sure we have the necessary data |
|
| 905 | + if (! isset($this->_req_data['_regid'])) { |
|
| 906 | + EE_Error::add_error( |
|
| 907 | + esc_html__( |
|
| 908 | + 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
|
| 909 | + 'event_espresso' |
|
| 910 | + ), |
|
| 911 | + __FILE__, |
|
| 912 | + __FUNCTION__, |
|
| 913 | + __LINE__ |
|
| 914 | + ); |
|
| 915 | + $this->_template_args['success'] = false; |
|
| 916 | + $this->_template_args['error'] = true; |
|
| 917 | + $this->_return_json(); |
|
| 918 | + }; |
|
| 919 | + // do a nonce check cause we're not coming in from an normal route here. |
|
| 920 | + $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
| 921 | + : ''; |
|
| 922 | + $nonce_ref = 'checkin_nonce'; |
|
| 923 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
| 924 | + // beautiful! Made it this far so let's get the status. |
|
| 925 | + $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
| 926 | + // setup new class to return via ajax |
|
| 927 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 928 | + $this->_template_args['success'] = true; |
|
| 929 | + $this->_return_json(); |
|
| 930 | + } |
|
| 931 | 931 | |
| 932 | 932 | |
| 933 | - /** |
|
| 934 | - * handles toggling the checkin status for the registration, |
|
| 935 | - * |
|
| 936 | - * @access protected |
|
| 937 | - * @return int|void |
|
| 938 | - * @throws EE_Error |
|
| 939 | - * @throws InvalidArgumentException |
|
| 940 | - * @throws InvalidDataTypeException |
|
| 941 | - * @throws InvalidInterfaceException |
|
| 942 | - */ |
|
| 943 | - protected function _toggle_checkin_status() |
|
| 944 | - { |
|
| 945 | - // first let's get the query args out of the way for the redirect |
|
| 946 | - $query_args = array( |
|
| 947 | - 'action' => 'event_registrations', |
|
| 948 | - 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 949 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
| 950 | - ); |
|
| 951 | - $new_status = false; |
|
| 952 | - // bulk action check in toggle |
|
| 953 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 954 | - // cycle thru checkboxes |
|
| 955 | - while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 956 | - $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 957 | - $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
| 958 | - } |
|
| 959 | - } elseif (isset($this->_req_data['_regid'])) { |
|
| 960 | - // coming from ajax request |
|
| 961 | - $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
| 962 | - $query_args['DTT_ID'] = $DTT_ID; |
|
| 963 | - $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
| 964 | - } else { |
|
| 965 | - EE_Error::add_error( |
|
| 966 | - esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
| 967 | - __FILE__, |
|
| 968 | - __FUNCTION__, |
|
| 969 | - __LINE__ |
|
| 970 | - ); |
|
| 971 | - } |
|
| 972 | - if (defined('DOING_AJAX')) { |
|
| 973 | - return $new_status; |
|
| 974 | - } |
|
| 975 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 976 | - } |
|
| 933 | + /** |
|
| 934 | + * handles toggling the checkin status for the registration, |
|
| 935 | + * |
|
| 936 | + * @access protected |
|
| 937 | + * @return int|void |
|
| 938 | + * @throws EE_Error |
|
| 939 | + * @throws InvalidArgumentException |
|
| 940 | + * @throws InvalidDataTypeException |
|
| 941 | + * @throws InvalidInterfaceException |
|
| 942 | + */ |
|
| 943 | + protected function _toggle_checkin_status() |
|
| 944 | + { |
|
| 945 | + // first let's get the query args out of the way for the redirect |
|
| 946 | + $query_args = array( |
|
| 947 | + 'action' => 'event_registrations', |
|
| 948 | + 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 949 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
| 950 | + ); |
|
| 951 | + $new_status = false; |
|
| 952 | + // bulk action check in toggle |
|
| 953 | + if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 954 | + // cycle thru checkboxes |
|
| 955 | + while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 956 | + $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 957 | + $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
| 958 | + } |
|
| 959 | + } elseif (isset($this->_req_data['_regid'])) { |
|
| 960 | + // coming from ajax request |
|
| 961 | + $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
| 962 | + $query_args['DTT_ID'] = $DTT_ID; |
|
| 963 | + $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
| 964 | + } else { |
|
| 965 | + EE_Error::add_error( |
|
| 966 | + esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
| 967 | + __FILE__, |
|
| 968 | + __FUNCTION__, |
|
| 969 | + __LINE__ |
|
| 970 | + ); |
|
| 971 | + } |
|
| 972 | + if (defined('DOING_AJAX')) { |
|
| 973 | + return $new_status; |
|
| 974 | + } |
|
| 975 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 976 | + } |
|
| 977 | 977 | |
| 978 | 978 | |
| 979 | - /** |
|
| 980 | - * This is toggles a single Check-in for the given registration and datetime. |
|
| 981 | - * |
|
| 982 | - * @param int $REG_ID The registration we're toggling |
|
| 983 | - * @param int $DTT_ID The datetime we're toggling |
|
| 984 | - * @return int The new status toggled to. |
|
| 985 | - * @throws EE_Error |
|
| 986 | - * @throws InvalidArgumentException |
|
| 987 | - * @throws InvalidDataTypeException |
|
| 988 | - * @throws InvalidInterfaceException |
|
| 989 | - */ |
|
| 990 | - private function _toggle_checkin($REG_ID, $DTT_ID) |
|
| 991 | - { |
|
| 992 | - /** @var EE_Registration $REG */ |
|
| 993 | - $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
| 994 | - $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
| 995 | - if ($new_status !== false) { |
|
| 996 | - EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
| 997 | - } else { |
|
| 998 | - EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
| 999 | - $new_status = false; |
|
| 1000 | - } |
|
| 1001 | - return $new_status; |
|
| 1002 | - } |
|
| 979 | + /** |
|
| 980 | + * This is toggles a single Check-in for the given registration and datetime. |
|
| 981 | + * |
|
| 982 | + * @param int $REG_ID The registration we're toggling |
|
| 983 | + * @param int $DTT_ID The datetime we're toggling |
|
| 984 | + * @return int The new status toggled to. |
|
| 985 | + * @throws EE_Error |
|
| 986 | + * @throws InvalidArgumentException |
|
| 987 | + * @throws InvalidDataTypeException |
|
| 988 | + * @throws InvalidInterfaceException |
|
| 989 | + */ |
|
| 990 | + private function _toggle_checkin($REG_ID, $DTT_ID) |
|
| 991 | + { |
|
| 992 | + /** @var EE_Registration $REG */ |
|
| 993 | + $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
| 994 | + $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
| 995 | + if ($new_status !== false) { |
|
| 996 | + EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
| 997 | + } else { |
|
| 998 | + EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
| 999 | + $new_status = false; |
|
| 1000 | + } |
|
| 1001 | + return $new_status; |
|
| 1002 | + } |
|
| 1003 | 1003 | |
| 1004 | 1004 | |
| 1005 | - /** |
|
| 1006 | - * Takes care of deleting multiple EE_Checkin table rows |
|
| 1007 | - * |
|
| 1008 | - * @access protected |
|
| 1009 | - * @return void |
|
| 1010 | - * @throws EE_Error |
|
| 1011 | - * @throws InvalidArgumentException |
|
| 1012 | - * @throws InvalidDataTypeException |
|
| 1013 | - * @throws InvalidInterfaceException |
|
| 1014 | - */ |
|
| 1015 | - protected function _delete_checkin_rows() |
|
| 1016 | - { |
|
| 1017 | - $query_args = array( |
|
| 1018 | - 'action' => 'registration_checkins', |
|
| 1019 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1020 | - '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1021 | - ); |
|
| 1022 | - $errors = 0; |
|
| 1023 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1024 | - while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 1025 | - if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1026 | - $errors++; |
|
| 1027 | - } |
|
| 1028 | - } |
|
| 1029 | - } else { |
|
| 1030 | - EE_Error::add_error( |
|
| 1031 | - esc_html__( |
|
| 1032 | - 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
| 1033 | - 'event_espresso' |
|
| 1034 | - ), |
|
| 1035 | - __FILE__, |
|
| 1036 | - __FUNCTION__, |
|
| 1037 | - __LINE__ |
|
| 1038 | - ); |
|
| 1039 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1040 | - } |
|
| 1041 | - if ($errors > 0) { |
|
| 1042 | - EE_Error::add_error( |
|
| 1043 | - sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
| 1044 | - __FILE__, |
|
| 1045 | - __FUNCTION__, |
|
| 1046 | - __LINE__ |
|
| 1047 | - ); |
|
| 1048 | - } else { |
|
| 1049 | - EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
| 1050 | - } |
|
| 1051 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1052 | - } |
|
| 1005 | + /** |
|
| 1006 | + * Takes care of deleting multiple EE_Checkin table rows |
|
| 1007 | + * |
|
| 1008 | + * @access protected |
|
| 1009 | + * @return void |
|
| 1010 | + * @throws EE_Error |
|
| 1011 | + * @throws InvalidArgumentException |
|
| 1012 | + * @throws InvalidDataTypeException |
|
| 1013 | + * @throws InvalidInterfaceException |
|
| 1014 | + */ |
|
| 1015 | + protected function _delete_checkin_rows() |
|
| 1016 | + { |
|
| 1017 | + $query_args = array( |
|
| 1018 | + 'action' => 'registration_checkins', |
|
| 1019 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1020 | + '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1021 | + ); |
|
| 1022 | + $errors = 0; |
|
| 1023 | + if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1024 | + while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 1025 | + if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1026 | + $errors++; |
|
| 1027 | + } |
|
| 1028 | + } |
|
| 1029 | + } else { |
|
| 1030 | + EE_Error::add_error( |
|
| 1031 | + esc_html__( |
|
| 1032 | + 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
| 1033 | + 'event_espresso' |
|
| 1034 | + ), |
|
| 1035 | + __FILE__, |
|
| 1036 | + __FUNCTION__, |
|
| 1037 | + __LINE__ |
|
| 1038 | + ); |
|
| 1039 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1040 | + } |
|
| 1041 | + if ($errors > 0) { |
|
| 1042 | + EE_Error::add_error( |
|
| 1043 | + sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
| 1044 | + __FILE__, |
|
| 1045 | + __FUNCTION__, |
|
| 1046 | + __LINE__ |
|
| 1047 | + ); |
|
| 1048 | + } else { |
|
| 1049 | + EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
| 1050 | + } |
|
| 1051 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1052 | + } |
|
| 1053 | 1053 | |
| 1054 | 1054 | |
| 1055 | - /** |
|
| 1056 | - * Deletes a single EE_Checkin row |
|
| 1057 | - * |
|
| 1058 | - * @return void |
|
| 1059 | - * @throws EE_Error |
|
| 1060 | - * @throws InvalidArgumentException |
|
| 1061 | - * @throws InvalidDataTypeException |
|
| 1062 | - * @throws InvalidInterfaceException |
|
| 1063 | - */ |
|
| 1064 | - protected function _delete_checkin_row() |
|
| 1065 | - { |
|
| 1066 | - $query_args = array( |
|
| 1067 | - 'action' => 'registration_checkins', |
|
| 1068 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1069 | - '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1070 | - ); |
|
| 1071 | - if (! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | - if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1073 | - EE_Error::add_error( |
|
| 1074 | - esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
| 1075 | - __FILE__, |
|
| 1076 | - __FUNCTION__, |
|
| 1077 | - __LINE__ |
|
| 1078 | - ); |
|
| 1079 | - } else { |
|
| 1080 | - EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
| 1081 | - } |
|
| 1082 | - } else { |
|
| 1083 | - EE_Error::add_error( |
|
| 1084 | - esc_html__( |
|
| 1085 | - 'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', |
|
| 1086 | - 'event_espresso' |
|
| 1087 | - ), |
|
| 1088 | - __FILE__, |
|
| 1089 | - __FUNCTION__, |
|
| 1090 | - __LINE__ |
|
| 1091 | - ); |
|
| 1092 | - } |
|
| 1093 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1094 | - } |
|
| 1055 | + /** |
|
| 1056 | + * Deletes a single EE_Checkin row |
|
| 1057 | + * |
|
| 1058 | + * @return void |
|
| 1059 | + * @throws EE_Error |
|
| 1060 | + * @throws InvalidArgumentException |
|
| 1061 | + * @throws InvalidDataTypeException |
|
| 1062 | + * @throws InvalidInterfaceException |
|
| 1063 | + */ |
|
| 1064 | + protected function _delete_checkin_row() |
|
| 1065 | + { |
|
| 1066 | + $query_args = array( |
|
| 1067 | + 'action' => 'registration_checkins', |
|
| 1068 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1069 | + '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1070 | + ); |
|
| 1071 | + if (! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | + if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1073 | + EE_Error::add_error( |
|
| 1074 | + esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
| 1075 | + __FILE__, |
|
| 1076 | + __FUNCTION__, |
|
| 1077 | + __LINE__ |
|
| 1078 | + ); |
|
| 1079 | + } else { |
|
| 1080 | + EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
| 1081 | + } |
|
| 1082 | + } else { |
|
| 1083 | + EE_Error::add_error( |
|
| 1084 | + esc_html__( |
|
| 1085 | + 'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', |
|
| 1086 | + 'event_espresso' |
|
| 1087 | + ), |
|
| 1088 | + __FILE__, |
|
| 1089 | + __FUNCTION__, |
|
| 1090 | + __LINE__ |
|
| 1091 | + ); |
|
| 1092 | + } |
|
| 1093 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1094 | + } |
|
| 1095 | 1095 | |
| 1096 | 1096 | |
| 1097 | - /** |
|
| 1098 | - * generates HTML for the Event Registrations List Table |
|
| 1099 | - * |
|
| 1100 | - * @access protected |
|
| 1101 | - * @return void |
|
| 1102 | - * @throws EE_Error |
|
| 1103 | - * @throws InvalidArgumentException |
|
| 1104 | - * @throws InvalidDataTypeException |
|
| 1105 | - * @throws InvalidInterfaceException |
|
| 1106 | - */ |
|
| 1107 | - protected function _event_registrations_list_table() |
|
| 1108 | - { |
|
| 1109 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1110 | - $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
| 1111 | - ? $this->get_action_link_or_button( |
|
| 1112 | - 'new_registration', |
|
| 1113 | - 'add-registrant', |
|
| 1114 | - array('event_id' => $this->_req_data['event_id']), |
|
| 1115 | - 'add-new-h2', |
|
| 1116 | - '', |
|
| 1117 | - false |
|
| 1118 | - ) |
|
| 1119 | - : ''; |
|
| 1120 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 1121 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 1122 | - $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
| 1123 | - $legend_items = array( |
|
| 1124 | - 'star-icon' => array( |
|
| 1125 | - 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
| 1126 | - 'desc' => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'), |
|
| 1127 | - ), |
|
| 1128 | - 'checkin' => array( |
|
| 1129 | - 'class' => $checked_in->cssClasses(), |
|
| 1130 | - 'desc' => $checked_in->legendLabel(), |
|
| 1131 | - ), |
|
| 1132 | - 'checkout' => array( |
|
| 1133 | - 'class' => $checked_out->cssClasses(), |
|
| 1134 | - 'desc' => $checked_out->legendLabel(), |
|
| 1135 | - ), |
|
| 1136 | - 'nocheckinrecord' => array( |
|
| 1137 | - 'class' => $checked_never->cssClasses(), |
|
| 1138 | - 'desc' => $checked_never->legendLabel(), |
|
| 1139 | - ), |
|
| 1140 | - 'approved_status' => array( |
|
| 1141 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1142 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
| 1143 | - ), |
|
| 1144 | - 'cancelled_status' => array( |
|
| 1145 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1146 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
| 1147 | - ), |
|
| 1148 | - 'declined_status' => array( |
|
| 1149 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1150 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
| 1151 | - ), |
|
| 1152 | - 'not_approved' => array( |
|
| 1153 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1154 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
| 1155 | - ), |
|
| 1156 | - 'pending_status' => array( |
|
| 1157 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1158 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
| 1159 | - ), |
|
| 1160 | - 'wait_list' => array( |
|
| 1161 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1162 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
| 1163 | - ), |
|
| 1164 | - ); |
|
| 1165 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 1166 | - $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
| 1167 | - /** @var EE_Event $event */ |
|
| 1168 | - $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 1169 | - $this->_template_args['before_list_table'] = $event instanceof EE_Event |
|
| 1170 | - ? '<h2>' . sprintf( |
|
| 1171 | - esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
|
| 1172 | - EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
| 1173 | - ) . '</h2>' |
|
| 1174 | - : ''; |
|
| 1175 | - // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
|
| 1176 | - // the event. |
|
| 1177 | - $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
| 1178 | - $datetime = null; |
|
| 1179 | - if ($event instanceof EE_Event) { |
|
| 1180 | - $datetimes_on_event = $event->datetimes(); |
|
| 1181 | - if (count($datetimes_on_event) === 1) { |
|
| 1182 | - $datetime = reset($datetimes_on_event); |
|
| 1183 | - } |
|
| 1184 | - } |
|
| 1185 | - $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
| 1186 | - if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
| 1187 | - $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
| 1188 | - $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
| 1189 | - $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
| 1190 | - $this->_template_args['before_list_table'] .= $datetime->name(); |
|
| 1191 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1192 | - $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
| 1193 | - } |
|
| 1194 | - // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
|
| 1195 | - // column represents |
|
| 1196 | - if (! $datetime instanceof EE_Datetime) { |
|
| 1197 | - $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
| 1198 | - . esc_html__( |
|
| 1199 | - 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
| 1200 | - 'event_espresso' |
|
| 1201 | - ) |
|
| 1202 | - . '</p>'; |
|
| 1203 | - } |
|
| 1204 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 1205 | - } |
|
| 1097 | + /** |
|
| 1098 | + * generates HTML for the Event Registrations List Table |
|
| 1099 | + * |
|
| 1100 | + * @access protected |
|
| 1101 | + * @return void |
|
| 1102 | + * @throws EE_Error |
|
| 1103 | + * @throws InvalidArgumentException |
|
| 1104 | + * @throws InvalidDataTypeException |
|
| 1105 | + * @throws InvalidInterfaceException |
|
| 1106 | + */ |
|
| 1107 | + protected function _event_registrations_list_table() |
|
| 1108 | + { |
|
| 1109 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1110 | + $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
| 1111 | + ? $this->get_action_link_or_button( |
|
| 1112 | + 'new_registration', |
|
| 1113 | + 'add-registrant', |
|
| 1114 | + array('event_id' => $this->_req_data['event_id']), |
|
| 1115 | + 'add-new-h2', |
|
| 1116 | + '', |
|
| 1117 | + false |
|
| 1118 | + ) |
|
| 1119 | + : ''; |
|
| 1120 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 1121 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 1122 | + $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
| 1123 | + $legend_items = array( |
|
| 1124 | + 'star-icon' => array( |
|
| 1125 | + 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
| 1126 | + 'desc' => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'), |
|
| 1127 | + ), |
|
| 1128 | + 'checkin' => array( |
|
| 1129 | + 'class' => $checked_in->cssClasses(), |
|
| 1130 | + 'desc' => $checked_in->legendLabel(), |
|
| 1131 | + ), |
|
| 1132 | + 'checkout' => array( |
|
| 1133 | + 'class' => $checked_out->cssClasses(), |
|
| 1134 | + 'desc' => $checked_out->legendLabel(), |
|
| 1135 | + ), |
|
| 1136 | + 'nocheckinrecord' => array( |
|
| 1137 | + 'class' => $checked_never->cssClasses(), |
|
| 1138 | + 'desc' => $checked_never->legendLabel(), |
|
| 1139 | + ), |
|
| 1140 | + 'approved_status' => array( |
|
| 1141 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1142 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
| 1143 | + ), |
|
| 1144 | + 'cancelled_status' => array( |
|
| 1145 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1146 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
| 1147 | + ), |
|
| 1148 | + 'declined_status' => array( |
|
| 1149 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1150 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
| 1151 | + ), |
|
| 1152 | + 'not_approved' => array( |
|
| 1153 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1154 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
| 1155 | + ), |
|
| 1156 | + 'pending_status' => array( |
|
| 1157 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1158 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
| 1159 | + ), |
|
| 1160 | + 'wait_list' => array( |
|
| 1161 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1162 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
| 1163 | + ), |
|
| 1164 | + ); |
|
| 1165 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 1166 | + $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
| 1167 | + /** @var EE_Event $event */ |
|
| 1168 | + $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 1169 | + $this->_template_args['before_list_table'] = $event instanceof EE_Event |
|
| 1170 | + ? '<h2>' . sprintf( |
|
| 1171 | + esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
|
| 1172 | + EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
| 1173 | + ) . '</h2>' |
|
| 1174 | + : ''; |
|
| 1175 | + // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
|
| 1176 | + // the event. |
|
| 1177 | + $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
| 1178 | + $datetime = null; |
|
| 1179 | + if ($event instanceof EE_Event) { |
|
| 1180 | + $datetimes_on_event = $event->datetimes(); |
|
| 1181 | + if (count($datetimes_on_event) === 1) { |
|
| 1182 | + $datetime = reset($datetimes_on_event); |
|
| 1183 | + } |
|
| 1184 | + } |
|
| 1185 | + $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
| 1186 | + if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
| 1187 | + $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
| 1188 | + $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
| 1189 | + $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
| 1190 | + $this->_template_args['before_list_table'] .= $datetime->name(); |
|
| 1191 | + $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1192 | + $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
| 1193 | + } |
|
| 1194 | + // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
|
| 1195 | + // column represents |
|
| 1196 | + if (! $datetime instanceof EE_Datetime) { |
|
| 1197 | + $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
| 1198 | + . esc_html__( |
|
| 1199 | + 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
| 1200 | + 'event_espresso' |
|
| 1201 | + ) |
|
| 1202 | + . '</p>'; |
|
| 1203 | + } |
|
| 1204 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 1205 | + } |
|
| 1206 | 1206 | |
| 1207 | - /** |
|
| 1208 | - * Download the registrations check-in report (same as the normal registration report, but with different where |
|
| 1209 | - * conditions) |
|
| 1210 | - * |
|
| 1211 | - * @return void ends the request by a redirect or download |
|
| 1212 | - */ |
|
| 1213 | - public function _registrations_checkin_report() |
|
| 1214 | - { |
|
| 1215 | - $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
| 1216 | - } |
|
| 1207 | + /** |
|
| 1208 | + * Download the registrations check-in report (same as the normal registration report, but with different where |
|
| 1209 | + * conditions) |
|
| 1210 | + * |
|
| 1211 | + * @return void ends the request by a redirect or download |
|
| 1212 | + */ |
|
| 1213 | + public function _registrations_checkin_report() |
|
| 1214 | + { |
|
| 1215 | + $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
| 1216 | + } |
|
| 1217 | 1217 | |
| 1218 | - /** |
|
| 1219 | - * Gets the query params from the request, plus adds a where condition for the registration status, |
|
| 1220 | - * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
| 1221 | - * |
|
| 1222 | - * @param array $request |
|
| 1223 | - * @param int $per_page |
|
| 1224 | - * @param bool $count |
|
| 1225 | - * @return array |
|
| 1226 | - * @throws EE_Error |
|
| 1227 | - */ |
|
| 1228 | - protected function _get_checkin_query_params_from_request( |
|
| 1229 | - $request, |
|
| 1230 | - $per_page = 10, |
|
| 1231 | - $count = false |
|
| 1232 | - ) { |
|
| 1233 | - $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
| 1234 | - // unlike the regular registrations list table, |
|
| 1235 | - $status_ids_array = apply_filters( |
|
| 1236 | - 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
| 1237 | - array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
| 1238 | - ); |
|
| 1239 | - $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
| 1240 | - return $query_params; |
|
| 1241 | - } |
|
| 1218 | + /** |
|
| 1219 | + * Gets the query params from the request, plus adds a where condition for the registration status, |
|
| 1220 | + * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
| 1221 | + * |
|
| 1222 | + * @param array $request |
|
| 1223 | + * @param int $per_page |
|
| 1224 | + * @param bool $count |
|
| 1225 | + * @return array |
|
| 1226 | + * @throws EE_Error |
|
| 1227 | + */ |
|
| 1228 | + protected function _get_checkin_query_params_from_request( |
|
| 1229 | + $request, |
|
| 1230 | + $per_page = 10, |
|
| 1231 | + $count = false |
|
| 1232 | + ) { |
|
| 1233 | + $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
| 1234 | + // unlike the regular registrations list table, |
|
| 1235 | + $status_ids_array = apply_filters( |
|
| 1236 | + 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
| 1237 | + array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
| 1238 | + ); |
|
| 1239 | + $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
| 1240 | + return $query_params; |
|
| 1241 | + } |
|
| 1242 | 1242 | |
| 1243 | 1243 | |
| 1244 | - /** |
|
| 1245 | - * Gets registrations for an event |
|
| 1246 | - * |
|
| 1247 | - * @param int $per_page |
|
| 1248 | - * @param bool $count whether to return count or data. |
|
| 1249 | - * @param bool $trash |
|
| 1250 | - * @param string $orderby |
|
| 1251 | - * @return EE_Registration[]|int |
|
| 1252 | - * @throws EE_Error |
|
| 1253 | - * @throws InvalidArgumentException |
|
| 1254 | - * @throws InvalidDataTypeException |
|
| 1255 | - * @throws InvalidInterfaceException |
|
| 1256 | - */ |
|
| 1257 | - public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
| 1258 | - { |
|
| 1259 | - // normalize some request params that get setup by the parent `get_registrations` method. |
|
| 1260 | - $request = $this->_req_data; |
|
| 1261 | - $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
| 1262 | - $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1263 | - if ($trash) { |
|
| 1264 | - $request['status'] = 'trash'; |
|
| 1265 | - } |
|
| 1266 | - $query_params = $this->_get_checkin_query_params_from_request($request, $per_page, $count); |
|
| 1267 | - /** |
|
| 1268 | - * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
| 1269 | - * |
|
| 1270 | - * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
| 1271 | - * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1272 | - * or if you have the development copy of EE you can view this at the path: |
|
| 1273 | - * /docs/G--Model-System/model-query-params.md |
|
| 1274 | - */ |
|
| 1275 | - $query_params['group_by'] = ''; |
|
| 1244 | + /** |
|
| 1245 | + * Gets registrations for an event |
|
| 1246 | + * |
|
| 1247 | + * @param int $per_page |
|
| 1248 | + * @param bool $count whether to return count or data. |
|
| 1249 | + * @param bool $trash |
|
| 1250 | + * @param string $orderby |
|
| 1251 | + * @return EE_Registration[]|int |
|
| 1252 | + * @throws EE_Error |
|
| 1253 | + * @throws InvalidArgumentException |
|
| 1254 | + * @throws InvalidDataTypeException |
|
| 1255 | + * @throws InvalidInterfaceException |
|
| 1256 | + */ |
|
| 1257 | + public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
| 1258 | + { |
|
| 1259 | + // normalize some request params that get setup by the parent `get_registrations` method. |
|
| 1260 | + $request = $this->_req_data; |
|
| 1261 | + $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
| 1262 | + $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1263 | + if ($trash) { |
|
| 1264 | + $request['status'] = 'trash'; |
|
| 1265 | + } |
|
| 1266 | + $query_params = $this->_get_checkin_query_params_from_request($request, $per_page, $count); |
|
| 1267 | + /** |
|
| 1268 | + * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
| 1269 | + * |
|
| 1270 | + * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
| 1271 | + * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1272 | + * or if you have the development copy of EE you can view this at the path: |
|
| 1273 | + * /docs/G--Model-System/model-query-params.md |
|
| 1274 | + */ |
|
| 1275 | + $query_params['group_by'] = ''; |
|
| 1276 | 1276 | |
| 1277 | - return $count |
|
| 1278 | - ? EEM_Registration::instance()->count($query_params) |
|
| 1279 | - /** @type EE_Registration[] */ |
|
| 1280 | - : EEM_Registration::instance()->get_all($query_params); |
|
| 1281 | - } |
|
| 1277 | + return $count |
|
| 1278 | + ? EEM_Registration::instance()->count($query_params) |
|
| 1279 | + /** @type EE_Registration[] */ |
|
| 1280 | + : EEM_Registration::instance()->get_all($query_params); |
|
| 1281 | + } |
|
| 1282 | 1282 | } |
@@ -32,10 +32,10 @@ discard block |
||
| 32 | 32 | public function __construct($routing = true) |
| 33 | 33 | { |
| 34 | 34 | parent::__construct($routing); |
| 35 | - if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 37 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 38 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 35 | + if ( ! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'registrations/templates/'); |
|
| 37 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'registrations/assets/'); |
|
| 38 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registrations/assets/'); |
|
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 | |
@@ -45,7 +45,7 @@ discard block |
||
| 45 | 45 | */ |
| 46 | 46 | protected function _extend_page_config() |
| 47 | 47 | { |
| 48 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 48 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'registrations'; |
|
| 49 | 49 | $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
| 50 | 50 | ? $this->_req_data['_REG_ID'] |
| 51 | 51 | : 0; |
@@ -185,14 +185,14 @@ discard block |
||
| 185 | 185 | // enqueue newsletter js |
| 186 | 186 | wp_enqueue_script( |
| 187 | 187 | 'ee-newsletter-trigger', |
| 188 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 188 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.js', |
|
| 189 | 189 | array('ee-dialog'), |
| 190 | 190 | EVENT_ESPRESSO_VERSION, |
| 191 | 191 | true |
| 192 | 192 | ); |
| 193 | 193 | wp_enqueue_style( |
| 194 | 194 | 'ee-newsletter-trigger-css', |
| 195 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 195 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.css', |
|
| 196 | 196 | array(), |
| 197 | 197 | EVENT_ESPRESSO_VERSION |
| 198 | 198 | ); |
@@ -213,7 +213,7 @@ discard block |
||
| 213 | 213 | { |
| 214 | 214 | wp_register_script( |
| 215 | 215 | 'ee-reg-reports-js', |
| 216 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 216 | + REG_CAF_ASSETS_URL.'ee-registration-admin-reports.js', |
|
| 217 | 217 | array('google-charts'), |
| 218 | 218 | EVENT_ESPRESSO_VERSION, |
| 219 | 219 | true |
@@ -299,7 +299,7 @@ discard block |
||
| 299 | 299 | $nonce_ref = 'get_newsletter_form_content_nonce'; |
| 300 | 300 | $this->_verify_nonce($nonce, $nonce_ref); |
| 301 | 301 | // let's get the mtp for the incoming MTP_ ID |
| 302 | - if (! isset($this->_req_data['GRP_ID'])) { |
|
| 302 | + if ( ! isset($this->_req_data['GRP_ID'])) { |
|
| 303 | 303 | EE_Error::add_error( |
| 304 | 304 | esc_html__( |
| 305 | 305 | 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
@@ -314,7 +314,7 @@ discard block |
||
| 314 | 314 | $this->_return_json(); |
| 315 | 315 | } |
| 316 | 316 | $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
| 317 | - if (! $MTPG instanceof EE_Message_Template_Group) { |
|
| 317 | + if ( ! $MTPG instanceof EE_Message_Template_Group) { |
|
| 318 | 318 | EE_Error::add_error( |
| 319 | 319 | sprintf( |
| 320 | 320 | esc_html__( |
@@ -339,12 +339,12 @@ discard block |
||
| 339 | 339 | $field = $MTP->get('MTP_template_field'); |
| 340 | 340 | if ($field === 'content') { |
| 341 | 341 | $content = $MTP->get('MTP_content'); |
| 342 | - if (! empty($content['newsletter_content'])) { |
|
| 342 | + if ( ! empty($content['newsletter_content'])) { |
|
| 343 | 343 | $template_fields['newsletter_content'] = $content['newsletter_content']; |
| 344 | 344 | } |
| 345 | 345 | continue; |
| 346 | 346 | } |
| 347 | - $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
| 347 | + $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content'); |
|
| 348 | 348 | } |
| 349 | 349 | $this->_template_args['success'] = true; |
| 350 | 350 | $this->_template_args['error'] = false; |
@@ -375,7 +375,7 @@ discard block |
||
| 375 | 375 | */ |
| 376 | 376 | public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
| 377 | 377 | { |
| 378 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 378 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
| 379 | 379 | 'ee_send_message', |
| 380 | 380 | 'espresso_registrations_newsletter_selected_send' |
| 381 | 381 | ) |
@@ -444,17 +444,17 @@ discard block |
||
| 444 | 444 | $field_id = $field === '[NEWSLETTER_CONTENT]' |
| 445 | 445 | ? 'content' |
| 446 | 446 | : $field; |
| 447 | - $field_id = 'batch-message-' . strtolower($field_id); |
|
| 447 | + $field_id = 'batch-message-'.strtolower($field_id); |
|
| 448 | 448 | $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
| 449 | 449 | . $shortcode |
| 450 | - . '" data-linked-input-id="' . $field_id . '">' |
|
| 450 | + . '" data-linked-input-id="'.$field_id.'">' |
|
| 451 | 451 | . $shortcode |
| 452 | 452 | . '</span>'; |
| 453 | 453 | } |
| 454 | - $codes[ $field ] = implode(', ', $available_shortcodes); |
|
| 454 | + $codes[$field] = implode(', ', $available_shortcodes); |
|
| 455 | 455 | } |
| 456 | 456 | $shortcodes = $codes; |
| 457 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 457 | + $form_template = REG_CAF_TEMPLATE_PATH.'newsletter-send-form.template.php'; |
|
| 458 | 458 | $form_template_args = array( |
| 459 | 459 | 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
| 460 | 460 | 'form_route' => 'newsletter_selected_send', |
@@ -622,7 +622,7 @@ discard block |
||
| 622 | 622 | */ |
| 623 | 623 | protected function _registration_reports() |
| 624 | 624 | { |
| 625 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 625 | + $template_path = EE_ADMIN_TEMPLATE.'admin_reports.template.php'; |
|
| 626 | 626 | $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
| 627 | 627 | $template_path, |
| 628 | 628 | $this->_reports_template_data, |
@@ -677,7 +677,7 @@ discard block |
||
| 677 | 677 | array_unshift($regs, $column_titles); |
| 678 | 678 | // setup the date range. |
| 679 | 679 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
| 680 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 680 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
| 681 | 681 | $ending_date = new DateTime("now", $DateTimeZone); |
| 682 | 682 | $subtitle = sprintf( |
| 683 | 683 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -697,7 +697,7 @@ discard block |
||
| 697 | 697 | '%sThere are currently no registration records in the last month for this report.%s', |
| 698 | 698 | 'event_espresso' |
| 699 | 699 | ), |
| 700 | - '<h2>' . $report_title . '</h2><p>', |
|
| 700 | + '<h2>'.$report_title.'</h2><p>', |
|
| 701 | 701 | '</p>' |
| 702 | 702 | ), |
| 703 | 703 | ); |
@@ -750,7 +750,7 @@ discard block |
||
| 750 | 750 | array_unshift($regs, $column_titles); |
| 751 | 751 | // setup the date range. |
| 752 | 752 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
| 753 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 753 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
| 754 | 754 | $ending_date = new DateTime("now", $DateTimeZone); |
| 755 | 755 | $subtitle = sprintf( |
| 756 | 756 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -770,7 +770,7 @@ discard block |
||
| 770 | 770 | '%sThere are currently no registration records in the last month for this report.%s', |
| 771 | 771 | 'event_espresso' |
| 772 | 772 | ), |
| 773 | - '<h2>' . $report_title . '</h2><p>', |
|
| 773 | + '<h2>'.$report_title.'</h2><p>', |
|
| 774 | 774 | '</p>' |
| 775 | 775 | ), |
| 776 | 776 | ); |
@@ -796,7 +796,7 @@ discard block |
||
| 796 | 796 | $reg_id = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : null; |
| 797 | 797 | /** @var EE_Registration $registration */ |
| 798 | 798 | $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
| 799 | - if (! $registration instanceof EE_Registration) { |
|
| 799 | + if ( ! $registration instanceof EE_Registration) { |
|
| 800 | 800 | throw new EE_Error( |
| 801 | 801 | sprintf( |
| 802 | 802 | esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
@@ -831,7 +831,7 @@ discard block |
||
| 831 | 831 | if ($datetime instanceof EE_Datetime) { |
| 832 | 832 | $datetime_label = $datetime->get_dtt_display_name(true); |
| 833 | 833 | $datetime_label .= ! empty($datetime_label) |
| 834 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 834 | + ? ' ('.$datetime->get_dtt_display_name().')' |
|
| 835 | 835 | : $datetime->get_dtt_display_name(); |
| 836 | 836 | } |
| 837 | 837 | $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
@@ -845,7 +845,7 @@ discard block |
||
| 845 | 845 | ) |
| 846 | 846 | : ''; |
| 847 | 847 | $datetime_link = ! empty($datetime_link) |
| 848 | - ? '<a href="' . $datetime_link . '">' |
|
| 848 | + ? '<a href="'.$datetime_link.'">' |
|
| 849 | 849 | . '<span id="checkin-dtt">' |
| 850 | 850 | . $datetime_label |
| 851 | 851 | . '</span></a>' |
@@ -857,8 +857,8 @@ discard block |
||
| 857 | 857 | ? $attendee->get_admin_details_link() |
| 858 | 858 | : ''; |
| 859 | 859 | $attendee_link = ! empty($attendee_link) |
| 860 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 861 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 860 | + ? '<a href="'.$attendee->get_admin_details_link().'"' |
|
| 861 | + . ' title="'.esc_html__('Click for attendee details', 'event_espresso').'">' |
|
| 862 | 862 | . '<span id="checkin-attendee-name">' |
| 863 | 863 | . $attendee_name |
| 864 | 864 | . '</span></a>' |
@@ -867,25 +867,25 @@ discard block |
||
| 867 | 867 | ? $registration->event()->get_admin_details_link() |
| 868 | 868 | : ''; |
| 869 | 869 | $event_link = ! empty($event_link) |
| 870 | - ? '<a href="' . $event_link . '"' |
|
| 871 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 870 | + ? '<a href="'.$event_link.'"' |
|
| 871 | + . ' title="'.esc_html__('Click here to edit event.', 'event_espresso').'">' |
|
| 872 | 872 | . '<span id="checkin-event-name">' |
| 873 | 873 | . $registration->event_name() |
| 874 | 874 | . '</span>' |
| 875 | 875 | . '</a>' |
| 876 | 876 | : ''; |
| 877 | 877 | $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
| 878 | - ? '<h2>' . sprintf( |
|
| 878 | + ? '<h2>'.sprintf( |
|
| 879 | 879 | esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
| 880 | 880 | $attendee_link, |
| 881 | 881 | $datetime_link, |
| 882 | 882 | $event_link |
| 883 | - ) . '</h2>' |
|
| 883 | + ).'</h2>' |
|
| 884 | 884 | : ''; |
| 885 | 885 | $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
| 886 | - ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
| 886 | + ? '<input type="hidden" name="_REG_ID" value="'.$reg_id.'">' : ''; |
|
| 887 | 887 | $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
| 888 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 888 | + ? '<input type="hidden" name="DTT_ID" value="'.$dtt_id.'">' : ''; |
|
| 889 | 889 | $this->display_admin_list_table_page_with_no_sidebar(); |
| 890 | 890 | } |
| 891 | 891 | |
@@ -902,7 +902,7 @@ discard block |
||
| 902 | 902 | public function toggle_checkin_status() |
| 903 | 903 | { |
| 904 | 904 | // first make sure we have the necessary data |
| 905 | - if (! isset($this->_req_data['_regid'])) { |
|
| 905 | + if ( ! isset($this->_req_data['_regid'])) { |
|
| 906 | 906 | EE_Error::add_error( |
| 907 | 907 | esc_html__( |
| 908 | 908 | 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
@@ -924,7 +924,7 @@ discard block |
||
| 924 | 924 | // beautiful! Made it this far so let's get the status. |
| 925 | 925 | $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
| 926 | 926 | // setup new class to return via ajax |
| 927 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 927 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin '.$new_status->cssClasses(); |
|
| 928 | 928 | $this->_template_args['success'] = true; |
| 929 | 929 | $this->_return_json(); |
| 930 | 930 | } |
@@ -950,7 +950,7 @@ discard block |
||
| 950 | 950 | ); |
| 951 | 951 | $new_status = false; |
| 952 | 952 | // bulk action check in toggle |
| 953 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 953 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 954 | 954 | // cycle thru checkboxes |
| 955 | 955 | while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
| 956 | 956 | $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
@@ -1020,9 +1020,9 @@ discard block |
||
| 1020 | 1020 | '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
| 1021 | 1021 | ); |
| 1022 | 1022 | $errors = 0; |
| 1023 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1023 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1024 | 1024 | while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
| 1025 | - if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1025 | + if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1026 | 1026 | $errors++; |
| 1027 | 1027 | } |
| 1028 | 1028 | } |
@@ -1068,8 +1068,8 @@ discard block |
||
| 1068 | 1068 | 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
| 1069 | 1069 | '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
| 1070 | 1070 | ); |
| 1071 | - if (! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | - if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1071 | + if ( ! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | + if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1073 | 1073 | EE_Error::add_error( |
| 1074 | 1074 | esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
| 1075 | 1075 | __FILE__, |
@@ -1138,27 +1138,27 @@ discard block |
||
| 1138 | 1138 | 'desc' => $checked_never->legendLabel(), |
| 1139 | 1139 | ), |
| 1140 | 1140 | 'approved_status' => array( |
| 1141 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1141 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_approved, |
|
| 1142 | 1142 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
| 1143 | 1143 | ), |
| 1144 | 1144 | 'cancelled_status' => array( |
| 1145 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1145 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_cancelled, |
|
| 1146 | 1146 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
| 1147 | 1147 | ), |
| 1148 | 1148 | 'declined_status' => array( |
| 1149 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1149 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_declined, |
|
| 1150 | 1150 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
| 1151 | 1151 | ), |
| 1152 | 1152 | 'not_approved' => array( |
| 1153 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1153 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_not_approved, |
|
| 1154 | 1154 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
| 1155 | 1155 | ), |
| 1156 | 1156 | 'pending_status' => array( |
| 1157 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1157 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_pending_payment, |
|
| 1158 | 1158 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
| 1159 | 1159 | ), |
| 1160 | 1160 | 'wait_list' => array( |
| 1161 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1161 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_wait_list, |
|
| 1162 | 1162 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
| 1163 | 1163 | ), |
| 1164 | 1164 | ); |
@@ -1167,10 +1167,10 @@ discard block |
||
| 1167 | 1167 | /** @var EE_Event $event */ |
| 1168 | 1168 | $event = EEM_Event::instance()->get_one_by_ID($event_id); |
| 1169 | 1169 | $this->_template_args['before_list_table'] = $event instanceof EE_Event |
| 1170 | - ? '<h2>' . sprintf( |
|
| 1170 | + ? '<h2>'.sprintf( |
|
| 1171 | 1171 | esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
| 1172 | 1172 | EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
| 1173 | - ) . '</h2>' |
|
| 1173 | + ).'</h2>' |
|
| 1174 | 1174 | : ''; |
| 1175 | 1175 | // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
| 1176 | 1176 | // the event. |
@@ -1188,12 +1188,12 @@ discard block |
||
| 1188 | 1188 | $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
| 1189 | 1189 | $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
| 1190 | 1190 | $this->_template_args['before_list_table'] .= $datetime->name(); |
| 1191 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1191 | + $this->_template_args['before_list_table'] .= ' ( '.$datetime->date_and_time_range().' )'; |
|
| 1192 | 1192 | $this->_template_args['before_list_table'] .= '</span></h2>'; |
| 1193 | 1193 | } |
| 1194 | 1194 | // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
| 1195 | 1195 | // column represents |
| 1196 | - if (! $datetime instanceof EE_Datetime) { |
|
| 1196 | + if ( ! $datetime instanceof EE_Datetime) { |
|
| 1197 | 1197 | $this->_template_args['before_list_table'] .= '<br><p class="description">' |
| 1198 | 1198 | . esc_html__( |
| 1199 | 1199 | 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
@@ -1,11 +1,8 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | -use EventEspresso\admin_pages\events\form_sections\ConfirmEventDeletionForm; |
|
| 4 | 3 | use EventEspresso\core\exceptions\InvalidDataTypeException; |
| 5 | 4 | use EventEspresso\core\exceptions\InvalidInterfaceException; |
| 6 | -use EventEspresso\core\exceptions\UnexpectedEntityException; |
|
| 7 | 5 | use EventEspresso\core\services\orm\tree_traversal\NodeGroupDao; |
| 8 | -use EventEspresso\core\services\orm\tree_traversal\ModelObjNode; |
|
| 9 | 6 | |
| 10 | 7 | /** |
| 11 | 8 | * Events_Admin_Page |
@@ -577,11 +577,11 @@ discard block |
||
| 577 | 577 | { |
| 578 | 578 | wp_register_style( |
| 579 | 579 | 'events-admin-css', |
| 580 | - EVENTS_ASSETS_URL . 'events-admin-page.css', |
|
| 580 | + EVENTS_ASSETS_URL.'events-admin-page.css', |
|
| 581 | 581 | array(), |
| 582 | 582 | EVENT_ESPRESSO_VERSION |
| 583 | 583 | ); |
| 584 | - wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 584 | + wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL.'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 585 | 585 | wp_enqueue_style('events-admin-css'); |
| 586 | 586 | wp_enqueue_style('ee-cat-admin'); |
| 587 | 587 | // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details |
@@ -589,7 +589,7 @@ discard block |
||
| 589 | 589 | // scripts |
| 590 | 590 | wp_register_script( |
| 591 | 591 | 'event_editor_js', |
| 592 | - EVENTS_ASSETS_URL . 'event_editor.js', |
|
| 592 | + EVENTS_ASSETS_URL.'event_editor.js', |
|
| 593 | 593 | array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'), |
| 594 | 594 | EVENT_ESPRESSO_VERSION, |
| 595 | 595 | true |
@@ -615,7 +615,7 @@ discard block |
||
| 615 | 615 | wp_enqueue_style('espresso-ui-theme'); |
| 616 | 616 | wp_register_style( |
| 617 | 617 | 'event-editor-css', |
| 618 | - EVENTS_ASSETS_URL . 'event-editor.css', |
|
| 618 | + EVENTS_ASSETS_URL.'event-editor.css', |
|
| 619 | 619 | array('ee-admin-css'), |
| 620 | 620 | EVENT_ESPRESSO_VERSION |
| 621 | 621 | ); |
@@ -623,7 +623,7 @@ discard block |
||
| 623 | 623 | // scripts |
| 624 | 624 | wp_register_script( |
| 625 | 625 | 'event-datetime-metabox', |
| 626 | - EVENTS_ASSETS_URL . 'event-datetime-metabox.js', |
|
| 626 | + EVENTS_ASSETS_URL.'event-datetime-metabox.js', |
|
| 627 | 627 | array('event_editor_js', 'ee-datepicker'), |
| 628 | 628 | EVENT_ESPRESSO_VERSION |
| 629 | 629 | ); |
@@ -692,7 +692,7 @@ discard block |
||
| 692 | 692 | public function verify_event_edit($event = null, $req_type = '') |
| 693 | 693 | { |
| 694 | 694 | // don't need to do this when processing |
| 695 | - if (! empty($req_type)) { |
|
| 695 | + if ( ! empty($req_type)) { |
|
| 696 | 696 | return; |
| 697 | 697 | } |
| 698 | 698 | // no event? |
@@ -701,7 +701,7 @@ discard block |
||
| 701 | 701 | $event = $this->_cpt_model_obj; |
| 702 | 702 | } |
| 703 | 703 | // STILL no event? |
| 704 | - if (! $event instanceof EE_Event) { |
|
| 704 | + if ( ! $event instanceof EE_Event) { |
|
| 705 | 705 | return; |
| 706 | 706 | } |
| 707 | 707 | $orig_status = $event->status(); |
@@ -739,7 +739,7 @@ discard block |
||
| 739 | 739 | ); |
| 740 | 740 | } |
| 741 | 741 | // now we need to determine if the event has any tickets on sale. If not then we dont' show the error |
| 742 | - if (! $event->tickets_on_sale()) { |
|
| 742 | + if ( ! $event->tickets_on_sale()) { |
|
| 743 | 743 | return; |
| 744 | 744 | } |
| 745 | 745 | // made it here so show warning |
@@ -784,7 +784,7 @@ discard block |
||
| 784 | 784 | { |
| 785 | 785 | $has_timezone_string = get_option('timezone_string'); |
| 786 | 786 | // only nag them about setting their timezone if it's their first event, and they haven't already done it |
| 787 | - if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) { |
|
| 787 | + if ( ! $has_timezone_string && ! EEM_Event::instance()->exists(array())) { |
|
| 788 | 788 | EE_Error::add_attention( |
| 789 | 789 | sprintf( |
| 790 | 790 | __( |
@@ -868,31 +868,31 @@ discard block |
||
| 868 | 868 | $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items); |
| 869 | 869 | $statuses = array( |
| 870 | 870 | 'sold_out_status' => array( |
| 871 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out, |
|
| 871 | + 'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::sold_out, |
|
| 872 | 872 | 'desc' => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'), |
| 873 | 873 | ), |
| 874 | 874 | 'active_status' => array( |
| 875 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active, |
|
| 875 | + 'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::active, |
|
| 876 | 876 | 'desc' => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'), |
| 877 | 877 | ), |
| 878 | 878 | 'upcoming_status' => array( |
| 879 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming, |
|
| 879 | + 'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::upcoming, |
|
| 880 | 880 | 'desc' => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'), |
| 881 | 881 | ), |
| 882 | 882 | 'postponed_status' => array( |
| 883 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed, |
|
| 883 | + 'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::postponed, |
|
| 884 | 884 | 'desc' => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'), |
| 885 | 885 | ), |
| 886 | 886 | 'cancelled_status' => array( |
| 887 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled, |
|
| 887 | + 'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::cancelled, |
|
| 888 | 888 | 'desc' => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'), |
| 889 | 889 | ), |
| 890 | 890 | 'expired_status' => array( |
| 891 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired, |
|
| 891 | + 'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::expired, |
|
| 892 | 892 | 'desc' => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'), |
| 893 | 893 | ), |
| 894 | 894 | 'inactive_status' => array( |
| 895 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive, |
|
| 895 | + 'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::inactive, |
|
| 896 | 896 | 'desc' => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'), |
| 897 | 897 | ), |
| 898 | 898 | ); |
@@ -906,7 +906,7 @@ discard block |
||
| 906 | 906 | */ |
| 907 | 907 | private function _event_model() |
| 908 | 908 | { |
| 909 | - if (! $this->_event_model instanceof EEM_Event) { |
|
| 909 | + if ( ! $this->_event_model instanceof EEM_Event) { |
|
| 910 | 910 | $this->_event_model = EE_Registry::instance()->load_model('Event'); |
| 911 | 911 | } |
| 912 | 912 | return $this->_event_model; |
@@ -926,7 +926,7 @@ discard block |
||
| 926 | 926 | public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug) |
| 927 | 927 | { |
| 928 | 928 | // make sure this is only when editing |
| 929 | - if (! empty($id)) { |
|
| 929 | + if ( ! empty($id)) { |
|
| 930 | 930 | $post = get_post($id); |
| 931 | 931 | $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#" tabindex="-1">' |
| 932 | 932 | . esc_html__('Shortcode', 'event_espresso') |
@@ -960,7 +960,7 @@ discard block |
||
| 960 | 960 | 'button' |
| 961 | 961 | ); |
| 962 | 962 | $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items()); |
| 963 | - $this->_admin_page_title .= ' ' . $this->get_action_link_or_button( |
|
| 963 | + $this->_admin_page_title .= ' '.$this->get_action_link_or_button( |
|
| 964 | 964 | 'create_new', |
| 965 | 965 | 'add', |
| 966 | 966 | array(), |
@@ -1100,7 +1100,7 @@ discard block |
||
| 1100 | 1100 | */ |
| 1101 | 1101 | protected function _default_venue_update(\EE_Event $evtobj, $data) |
| 1102 | 1102 | { |
| 1103 | - require_once(EE_MODELS . 'EEM_Venue.model.php'); |
|
| 1103 | + require_once(EE_MODELS.'EEM_Venue.model.php'); |
|
| 1104 | 1104 | $venue_model = EE_Registry::instance()->load_model('Venue'); |
| 1105 | 1105 | $rows_affected = null; |
| 1106 | 1106 | $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null; |
@@ -1131,7 +1131,7 @@ discard block |
||
| 1131 | 1131 | 'status' => 'publish', |
| 1132 | 1132 | ); |
| 1133 | 1133 | // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out. |
| 1134 | - if (! empty($venue_id)) { |
|
| 1134 | + if ( ! empty($venue_id)) { |
|
| 1135 | 1135 | $update_where = array($venue_model->primary_key_name() => $venue_id); |
| 1136 | 1136 | $rows_affected = $venue_model->update($venue_array, array($update_where)); |
| 1137 | 1137 | // we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present. |
@@ -1173,7 +1173,7 @@ discard block |
||
| 1173 | 1173 | 'DTT_order' => $row, |
| 1174 | 1174 | ); |
| 1175 | 1175 | // if we have an id then let's get existing object first and then set the new values. Otherwise we instantiate a new object for save. |
| 1176 | - if (! empty($dtt['DTT_ID'])) { |
|
| 1176 | + if ( ! empty($dtt['DTT_ID'])) { |
|
| 1177 | 1177 | $DTM = EE_Registry::instance() |
| 1178 | 1178 | ->load_model('Datetime', array($evtobj->get_timezone())) |
| 1179 | 1179 | ->get_one_by_ID($dtt['DTT_ID']); |
@@ -1183,7 +1183,7 @@ discard block |
||
| 1183 | 1183 | $DTM->set($field, $value); |
| 1184 | 1184 | } |
| 1185 | 1185 | // make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it. We need to do this so we dont' TRASH the parent DTT. |
| 1186 | - $saved_dtts[ $DTM->ID() ] = $DTM; |
|
| 1186 | + $saved_dtts[$DTM->ID()] = $DTM; |
|
| 1187 | 1187 | } else { |
| 1188 | 1188 | $DTM = EE_Registry::instance()->load_class( |
| 1189 | 1189 | 'Datetime', |
@@ -1216,14 +1216,14 @@ discard block |
||
| 1216 | 1216 | foreach ($data['edit_tickets'] as $row => $tkt) { |
| 1217 | 1217 | $incoming_date_formats = array('Y-m-d', 'h:i a'); |
| 1218 | 1218 | $update_prices = false; |
| 1219 | - $ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount']) |
|
| 1220 | - ? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0; |
|
| 1219 | + $ticket_price = isset($data['edit_prices'][$row][1]['PRC_amount']) |
|
| 1220 | + ? $data['edit_prices'][$row][1]['PRC_amount'] : 0; |
|
| 1221 | 1221 | // trim inputs to ensure any excess whitespace is removed. |
| 1222 | 1222 | $tkt = array_map('trim', $tkt); |
| 1223 | 1223 | if (empty($tkt['TKT_start_date'])) { |
| 1224 | 1224 | // let's use now in the set timezone. |
| 1225 | 1225 | $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone())); |
| 1226 | - $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]); |
|
| 1226 | + $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0].' '.$incoming_date_formats[1]); |
|
| 1227 | 1227 | } |
| 1228 | 1228 | if (empty($tkt['TKT_end_date'])) { |
| 1229 | 1229 | // use the start date of the first datetime |
@@ -1258,7 +1258,7 @@ discard block |
||
| 1258 | 1258 | // if we have a TKT_ID then we need to get that existing TKT_obj and update it |
| 1259 | 1259 | // we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified. |
| 1260 | 1260 | // keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived. |
| 1261 | - if (! empty($tkt['TKT_ID'])) { |
|
| 1261 | + if ( ! empty($tkt['TKT_ID'])) { |
|
| 1262 | 1262 | $TKT = EE_Registry::instance() |
| 1263 | 1263 | ->load_model('Ticket', array($evtobj->get_timezone())) |
| 1264 | 1264 | ->get_one_by_ID($tkt['TKT_ID']); |
@@ -1293,7 +1293,7 @@ discard block |
||
| 1293 | 1293 | $TKT->set('TKT_deleted', 1); |
| 1294 | 1294 | $TKT->save(); |
| 1295 | 1295 | // make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine. |
| 1296 | - $saved_tickets[ $TKT->ID() ] = $TKT; |
|
| 1296 | + $saved_tickets[$TKT->ID()] = $TKT; |
|
| 1297 | 1297 | // create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it. |
| 1298 | 1298 | $TKT = clone $TKT; |
| 1299 | 1299 | $TKT->set('TKT_ID', 0); |
@@ -1338,9 +1338,9 @@ discard block |
||
| 1338 | 1338 | } |
| 1339 | 1339 | // initially let's add the ticket to the dtt |
| 1340 | 1340 | $saved_dtt->_add_relation_to($TKT, 'Ticket'); |
| 1341 | - $saved_tickets[ $TKT->ID() ] = $TKT; |
|
| 1341 | + $saved_tickets[$TKT->ID()] = $TKT; |
|
| 1342 | 1342 | // add prices to ticket |
| 1343 | - $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices); |
|
| 1343 | + $this->_add_prices_to_ticket($data['edit_prices'][$row], $TKT, $update_prices); |
|
| 1344 | 1344 | } |
| 1345 | 1345 | // however now we need to handle permanently deleting tickets via the ui. Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold. However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db. |
| 1346 | 1346 | $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets; |
@@ -1497,7 +1497,7 @@ discard block |
||
| 1497 | 1497 | $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean(); |
| 1498 | 1498 | // load template |
| 1499 | 1499 | EEH_Template::display_template( |
| 1500 | - EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php', |
|
| 1500 | + EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php', |
|
| 1501 | 1501 | $publish_box_extra_args |
| 1502 | 1502 | ); |
| 1503 | 1503 | } |
@@ -1589,7 +1589,7 @@ discard block |
||
| 1589 | 1589 | 'default_where_conditions' => 'none', |
| 1590 | 1590 | ) |
| 1591 | 1591 | ); |
| 1592 | - if (! empty($related_tickets)) { |
|
| 1592 | + if ( ! empty($related_tickets)) { |
|
| 1593 | 1593 | $template_args['total_ticket_rows'] = count($related_tickets); |
| 1594 | 1594 | $row = 0; |
| 1595 | 1595 | foreach ($related_tickets as $ticket) { |
@@ -1623,7 +1623,7 @@ discard block |
||
| 1623 | 1623 | ); |
| 1624 | 1624 | $template = apply_filters( |
| 1625 | 1625 | 'FHEE__Events_Admin_Page__ticket_metabox__template', |
| 1626 | - EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php' |
|
| 1626 | + EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php' |
|
| 1627 | 1627 | ); |
| 1628 | 1628 | EEH_Template::display_template($template, $template_args); |
| 1629 | 1629 | } |
@@ -1641,7 +1641,7 @@ discard block |
||
| 1641 | 1641 | private function _get_ticket_row($ticket, $skeleton = false, $row = 0) |
| 1642 | 1642 | { |
| 1643 | 1643 | $template_args = array( |
| 1644 | - 'tkt_status_class' => ' tkt-status-' . $ticket->ticket_status(), |
|
| 1644 | + 'tkt_status_class' => ' tkt-status-'.$ticket->ticket_status(), |
|
| 1645 | 1645 | 'tkt_archive_class' => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived' |
| 1646 | 1646 | : '', |
| 1647 | 1647 | 'ticketrow' => $skeleton ? 'TICKETNUM' : $row, |
@@ -1653,10 +1653,10 @@ discard block |
||
| 1653 | 1653 | 'TKT_qty' => $ticket->get_pretty('TKT_qty', 'input'), |
| 1654 | 1654 | 'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets', |
| 1655 | 1655 | 'TKT_sold' => $skeleton ? 0 : $ticket->get('TKT_sold'), |
| 1656 | - 'trash_icon' => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted'))) |
|
| 1657 | - && (! empty($ticket) && $ticket->get('TKT_sold') === 0) |
|
| 1656 | + 'trash_icon' => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted'))) |
|
| 1657 | + && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0) |
|
| 1658 | 1658 | ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon', |
| 1659 | - 'disabled' => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? '' |
|
| 1659 | + 'disabled' => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? '' |
|
| 1660 | 1660 | : ' disabled=disabled', |
| 1661 | 1661 | ); |
| 1662 | 1662 | $price = $ticket->ID() !== 0 |
@@ -1683,7 +1683,7 @@ discard block |
||
| 1683 | 1683 | array('order_by' => array('DTT_EVT_start' => 'ASC')) |
| 1684 | 1684 | ) |
| 1685 | 1685 | : null; |
| 1686 | - if (! empty($earliest_dtt)) { |
|
| 1686 | + if ( ! empty($earliest_dtt)) { |
|
| 1687 | 1687 | $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a'); |
| 1688 | 1688 | } else { |
| 1689 | 1689 | $template_args['TKT_end_date'] = date( |
@@ -1695,7 +1695,7 @@ discard block |
||
| 1695 | 1695 | $template_args = array_merge($template_args, $price_args); |
| 1696 | 1696 | $template = apply_filters( |
| 1697 | 1697 | 'FHEE__Events_Admin_Page__get_ticket_row__template', |
| 1698 | - EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php', |
|
| 1698 | + EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php', |
|
| 1699 | 1699 | $ticket |
| 1700 | 1700 | ); |
| 1701 | 1701 | return EEH_Template::display_template($template, $template_args, true); |
@@ -1749,7 +1749,7 @@ discard block |
||
| 1749 | 1749 | $default_reg_status_values |
| 1750 | 1750 | ); |
| 1751 | 1751 | EEH_Template::display_template( |
| 1752 | - EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php', |
|
| 1752 | + EVENTS_TEMPLATE_PATH.'event_registration_options.template.php', |
|
| 1753 | 1753 | $template_args |
| 1754 | 1754 | ); |
| 1755 | 1755 | } |
@@ -1771,7 +1771,7 @@ discard block |
||
| 1771 | 1771 | { |
| 1772 | 1772 | $EEME = $this->_event_model(); |
| 1773 | 1773 | $offset = ($current_page - 1) * $per_page; |
| 1774 | - $limit = $count ? null : $offset . ',' . $per_page; |
|
| 1774 | + $limit = $count ? null : $offset.','.$per_page; |
|
| 1775 | 1775 | $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID'; |
| 1776 | 1776 | $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC"; |
| 1777 | 1777 | if (isset($this->_req_data['month_range'])) { |
@@ -1800,7 +1800,7 @@ discard block |
||
| 1800 | 1800 | // categories? |
| 1801 | 1801 | $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0 |
| 1802 | 1802 | ? $this->_req_data['EVT_CAT'] : null; |
| 1803 | - if (! empty($category)) { |
|
| 1803 | + if ( ! empty($category)) { |
|
| 1804 | 1804 | $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY; |
| 1805 | 1805 | $where['Term_Taxonomy.term_id'] = $category; |
| 1806 | 1806 | } |
@@ -1808,7 +1808,7 @@ discard block |
||
| 1808 | 1808 | $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start'); |
| 1809 | 1809 | if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') { |
| 1810 | 1810 | $DateTime = new DateTime( |
| 1811 | - $year_r . '-' . $month_r . '-01 00:00:00', |
|
| 1811 | + $year_r.'-'.$month_r.'-01 00:00:00', |
|
| 1812 | 1812 | new DateTimeZone(EEM_Datetime::instance()->get_timezone()) |
| 1813 | 1813 | ); |
| 1814 | 1814 | $start = $DateTime->format(implode(' ', $start_formats)); |
@@ -1834,11 +1834,11 @@ discard block |
||
| 1834 | 1834 | ->format(implode(' ', $start_formats)); |
| 1835 | 1835 | $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end)); |
| 1836 | 1836 | } |
| 1837 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) { |
|
| 1837 | + if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) { |
|
| 1838 | 1838 | $where['EVT_wp_user'] = get_current_user_id(); |
| 1839 | 1839 | } else { |
| 1840 | - if (! isset($where['status'])) { |
|
| 1841 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) { |
|
| 1840 | + if ( ! isset($where['status'])) { |
|
| 1841 | + if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) { |
|
| 1842 | 1842 | $where['OR'] = array( |
| 1843 | 1843 | 'status*restrict_private' => array('!=', 'private'), |
| 1844 | 1844 | 'AND' => array( |
@@ -1858,7 +1858,7 @@ discard block |
||
| 1858 | 1858 | } |
| 1859 | 1859 | // search query handling |
| 1860 | 1860 | if (isset($this->_req_data['s'])) { |
| 1861 | - $search_string = '%' . $this->_req_data['s'] . '%'; |
|
| 1861 | + $search_string = '%'.$this->_req_data['s'].'%'; |
|
| 1862 | 1862 | $where['OR'] = array( |
| 1863 | 1863 | 'EVT_name' => array('LIKE', $search_string), |
| 1864 | 1864 | 'EVT_desc' => array('LIKE', $search_string), |
@@ -1953,7 +1953,7 @@ discard block |
||
| 1953 | 1953 | // clean status |
| 1954 | 1954 | $event_status = sanitize_key($event_status); |
| 1955 | 1955 | // grab status |
| 1956 | - if (! empty($event_status)) { |
|
| 1956 | + if ( ! empty($event_status)) { |
|
| 1957 | 1957 | $success = $this->_change_event_status($EVT_ID, $event_status); |
| 1958 | 1958 | } else { |
| 1959 | 1959 | $success = false; |
@@ -1990,7 +1990,7 @@ discard block |
||
| 1990 | 1990 | // clean status |
| 1991 | 1991 | $event_status = sanitize_key($event_status); |
| 1992 | 1992 | // grab status |
| 1993 | - if (! empty($event_status)) { |
|
| 1993 | + if ( ! empty($event_status)) { |
|
| 1994 | 1994 | $success = true; |
| 1995 | 1995 | // determine the event id and set to array. |
| 1996 | 1996 | $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array(); |
@@ -2037,7 +2037,7 @@ discard block |
||
| 2037 | 2037 | private function _change_event_status($EVT_ID = 0, $event_status = '') |
| 2038 | 2038 | { |
| 2039 | 2039 | // grab event id |
| 2040 | - if (! $EVT_ID) { |
|
| 2040 | + if ( ! $EVT_ID) { |
|
| 2041 | 2041 | $msg = esc_html__( |
| 2042 | 2042 | 'An error occurred. No Event ID or an invalid Event ID was received.', |
| 2043 | 2043 | 'event_espresso' |
@@ -2107,7 +2107,7 @@ discard block |
||
| 2107 | 2107 | */ |
| 2108 | 2108 | protected function getModelObjNodeGroupPersister() |
| 2109 | 2109 | { |
| 2110 | - if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) { |
|
| 2110 | + if ( ! $this->model_obj_node_group_persister instanceof NodeGroupDao) { |
|
| 2111 | 2111 | $this->model_obj_node_group_persister = $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao'); |
| 2112 | 2112 | } |
| 2113 | 2113 | return $this->model_obj_node_group_persister; |
@@ -2358,7 +2358,7 @@ discard block |
||
| 2358 | 2358 | . esc_html__( |
| 2359 | 2359 | 'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.', |
| 2360 | 2360 | 'event_espresso' |
| 2361 | - ) . '</strong>'; |
|
| 2361 | + ).'</strong>'; |
|
| 2362 | 2362 | $this->display_admin_caf_preview_page('template_settings_tab'); |
| 2363 | 2363 | } |
| 2364 | 2364 | |
@@ -2378,12 +2378,12 @@ discard block |
||
| 2378 | 2378 | // set default category object |
| 2379 | 2379 | $this->_set_empty_category_object(); |
| 2380 | 2380 | // only set if we've got an id |
| 2381 | - if (! isset($this->_req_data['EVT_CAT_ID'])) { |
|
| 2381 | + if ( ! isset($this->_req_data['EVT_CAT_ID'])) { |
|
| 2382 | 2382 | return; |
| 2383 | 2383 | } |
| 2384 | 2384 | $category_id = absint($this->_req_data['EVT_CAT_ID']); |
| 2385 | 2385 | $term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
| 2386 | - if (! empty($term)) { |
|
| 2386 | + if ( ! empty($term)) { |
|
| 2387 | 2387 | $this->_category->category_name = $term->name; |
| 2388 | 2388 | $this->_category->category_identifier = $term->slug; |
| 2389 | 2389 | $this->_category->category_desc = $term->description; |
@@ -2411,7 +2411,7 @@ discard block |
||
| 2411 | 2411 | { |
| 2412 | 2412 | do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
| 2413 | 2413 | $this->_search_btn_label = esc_html__('Categories', 'event_espresso'); |
| 2414 | - $this->_admin_page_title .= ' ' . $this->get_action_link_or_button( |
|
| 2414 | + $this->_admin_page_title .= ' '.$this->get_action_link_or_button( |
|
| 2415 | 2415 | 'add_category', |
| 2416 | 2416 | 'add_category', |
| 2417 | 2417 | array(), |
@@ -2485,7 +2485,7 @@ discard block |
||
| 2485 | 2485 | 'disable' => '', |
| 2486 | 2486 | 'disabled_message' => false, |
| 2487 | 2487 | ); |
| 2488 | - $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php'; |
|
| 2488 | + $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php'; |
|
| 2489 | 2489 | return EEH_Template::display_template($template, $template_args, true); |
| 2490 | 2490 | } |
| 2491 | 2491 | |
@@ -2570,7 +2570,7 @@ discard block |
||
| 2570 | 2570 | $insert_ids = $update |
| 2571 | 2571 | ? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args) |
| 2572 | 2572 | : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args); |
| 2573 | - if (! is_array($insert_ids)) { |
|
| 2573 | + if ( ! is_array($insert_ids)) { |
|
| 2574 | 2574 | $msg = esc_html__( |
| 2575 | 2575 | 'An error occurred and the category has not been saved to the database.', |
| 2576 | 2576 | 'event_espresso' |
@@ -2601,7 +2601,7 @@ discard block |
||
| 2601 | 2601 | $limit = ($current_page - 1) * $per_page; |
| 2602 | 2602 | $where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
| 2603 | 2603 | if (isset($this->_req_data['s'])) { |
| 2604 | - $sstr = '%' . $this->_req_data['s'] . '%'; |
|
| 2604 | + $sstr = '%'.$this->_req_data['s'].'%'; |
|
| 2605 | 2605 | $where['OR'] = array( |
| 2606 | 2606 | 'Term.name' => array('LIKE', $sstr), |
| 2607 | 2607 | 'description' => array('LIKE', $sstr), |
@@ -2610,7 +2610,7 @@ discard block |
||
| 2610 | 2610 | $query_params = array( |
| 2611 | 2611 | $where, |
| 2612 | 2612 | 'order_by' => array($orderby => $order), |
| 2613 | - 'limit' => $limit . ',' . $per_page, |
|
| 2613 | + 'limit' => $limit.','.$per_page, |
|
| 2614 | 2614 | 'force_join' => array('Term'), |
| 2615 | 2615 | ); |
| 2616 | 2616 | $categories = $count |
@@ -19,2637 +19,2637 @@ |
||
| 19 | 19 | class Events_Admin_Page extends EE_Admin_Page_CPT |
| 20 | 20 | { |
| 21 | 21 | |
| 22 | - /** |
|
| 23 | - * This will hold the event object for event_details screen. |
|
| 24 | - * |
|
| 25 | - * @access protected |
|
| 26 | - * @var EE_Event $_event |
|
| 27 | - */ |
|
| 28 | - protected $_event; |
|
| 29 | - |
|
| 30 | - |
|
| 31 | - /** |
|
| 32 | - * This will hold the category object for category_details screen. |
|
| 33 | - * |
|
| 34 | - * @var stdClass $_category |
|
| 35 | - */ |
|
| 36 | - protected $_category; |
|
| 37 | - |
|
| 38 | - |
|
| 39 | - /** |
|
| 40 | - * This will hold the event model instance |
|
| 41 | - * |
|
| 42 | - * @var EEM_Event $_event_model |
|
| 43 | - */ |
|
| 44 | - protected $_event_model; |
|
| 45 | - |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * @var EE_Event |
|
| 49 | - */ |
|
| 50 | - protected $_cpt_model_obj = false; |
|
| 51 | - |
|
| 52 | - |
|
| 53 | - /** |
|
| 54 | - * @var NodeGroupDao |
|
| 55 | - */ |
|
| 56 | - protected $model_obj_node_group_persister; |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * Initialize page props for this admin page group. |
|
| 60 | - */ |
|
| 61 | - protected function _init_page_props() |
|
| 62 | - { |
|
| 63 | - $this->page_slug = EVENTS_PG_SLUG; |
|
| 64 | - $this->page_label = EVENTS_LABEL; |
|
| 65 | - $this->_admin_base_url = EVENTS_ADMIN_URL; |
|
| 66 | - $this->_admin_base_path = EVENTS_ADMIN; |
|
| 67 | - $this->_cpt_model_names = array( |
|
| 68 | - 'create_new' => 'EEM_Event', |
|
| 69 | - 'edit' => 'EEM_Event', |
|
| 70 | - ); |
|
| 71 | - $this->_cpt_edit_routes = array( |
|
| 72 | - 'espresso_events' => 'edit', |
|
| 73 | - ); |
|
| 74 | - add_action( |
|
| 75 | - 'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object', |
|
| 76 | - array($this, 'verify_event_edit'), |
|
| 77 | - 10, |
|
| 78 | - 2 |
|
| 79 | - ); |
|
| 80 | - } |
|
| 81 | - |
|
| 82 | - |
|
| 83 | - /** |
|
| 84 | - * Sets the ajax hooks used for this admin page group. |
|
| 85 | - */ |
|
| 86 | - protected function _ajax_hooks() |
|
| 87 | - { |
|
| 88 | - add_action('wp_ajax_ee_save_timezone_setting', array($this, 'save_timezonestring_setting')); |
|
| 89 | - } |
|
| 90 | - |
|
| 91 | - |
|
| 92 | - /** |
|
| 93 | - * Sets the page properties for this admin page group. |
|
| 94 | - */ |
|
| 95 | - protected function _define_page_props() |
|
| 96 | - { |
|
| 97 | - $this->_admin_page_title = EVENTS_LABEL; |
|
| 98 | - $this->_labels = array( |
|
| 99 | - 'buttons' => array( |
|
| 100 | - 'add' => esc_html__('Add New Event', 'event_espresso'), |
|
| 101 | - 'edit' => esc_html__('Edit Event', 'event_espresso'), |
|
| 102 | - 'delete' => esc_html__('Delete Event', 'event_espresso'), |
|
| 103 | - 'add_category' => esc_html__('Add New Category', 'event_espresso'), |
|
| 104 | - 'edit_category' => esc_html__('Edit Category', 'event_espresso'), |
|
| 105 | - 'delete_category' => esc_html__('Delete Category', 'event_espresso'), |
|
| 106 | - ), |
|
| 107 | - 'editor_title' => array( |
|
| 108 | - 'espresso_events' => esc_html__('Enter event title here', 'event_espresso'), |
|
| 109 | - ), |
|
| 110 | - 'publishbox' => array( |
|
| 111 | - 'create_new' => esc_html__('Save New Event', 'event_espresso'), |
|
| 112 | - 'edit' => esc_html__('Update Event', 'event_espresso'), |
|
| 113 | - 'add_category' => esc_html__('Save New Category', 'event_espresso'), |
|
| 114 | - 'edit_category' => esc_html__('Update Category', 'event_espresso'), |
|
| 115 | - 'template_settings' => esc_html__('Update Settings', 'event_espresso'), |
|
| 116 | - ), |
|
| 117 | - ); |
|
| 118 | - } |
|
| 119 | - |
|
| 120 | - |
|
| 121 | - /** |
|
| 122 | - * Sets the page routes property for this admin page group. |
|
| 123 | - */ |
|
| 124 | - protected function _set_page_routes() |
|
| 125 | - { |
|
| 126 | - // load formatter helper |
|
| 127 | - // load field generator helper |
|
| 128 | - // is there a evt_id in the request? |
|
| 129 | - $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID']) |
|
| 130 | - ? $this->_req_data['EVT_ID'] |
|
| 131 | - : 0; |
|
| 132 | - $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id; |
|
| 133 | - $this->_page_routes = array( |
|
| 134 | - 'default' => array( |
|
| 135 | - 'func' => '_events_overview_list_table', |
|
| 136 | - 'capability' => 'ee_read_events', |
|
| 137 | - ), |
|
| 138 | - 'create_new' => array( |
|
| 139 | - 'func' => '_create_new_cpt_item', |
|
| 140 | - 'capability' => 'ee_edit_events', |
|
| 141 | - ), |
|
| 142 | - 'edit' => array( |
|
| 143 | - 'func' => '_edit_cpt_item', |
|
| 144 | - 'capability' => 'ee_edit_event', |
|
| 145 | - 'obj_id' => $evt_id, |
|
| 146 | - ), |
|
| 147 | - 'copy_event' => array( |
|
| 148 | - 'func' => '_copy_events', |
|
| 149 | - 'capability' => 'ee_edit_event', |
|
| 150 | - 'obj_id' => $evt_id, |
|
| 151 | - 'noheader' => true, |
|
| 152 | - ), |
|
| 153 | - 'trash_event' => array( |
|
| 154 | - 'func' => '_trash_or_restore_event', |
|
| 155 | - 'args' => array('event_status' => 'trash'), |
|
| 156 | - 'capability' => 'ee_delete_event', |
|
| 157 | - 'obj_id' => $evt_id, |
|
| 158 | - 'noheader' => true, |
|
| 159 | - ), |
|
| 160 | - 'trash_events' => array( |
|
| 161 | - 'func' => '_trash_or_restore_events', |
|
| 162 | - 'args' => array('event_status' => 'trash'), |
|
| 163 | - 'capability' => 'ee_delete_events', |
|
| 164 | - 'noheader' => true, |
|
| 165 | - ), |
|
| 166 | - 'restore_event' => array( |
|
| 167 | - 'func' => '_trash_or_restore_event', |
|
| 168 | - 'args' => array('event_status' => 'draft'), |
|
| 169 | - 'capability' => 'ee_delete_event', |
|
| 170 | - 'obj_id' => $evt_id, |
|
| 171 | - 'noheader' => true, |
|
| 172 | - ), |
|
| 173 | - 'restore_events' => array( |
|
| 174 | - 'func' => '_trash_or_restore_events', |
|
| 175 | - 'args' => array('event_status' => 'draft'), |
|
| 176 | - 'capability' => 'ee_delete_events', |
|
| 177 | - 'noheader' => true, |
|
| 178 | - ), |
|
| 179 | - 'delete_event' => array( |
|
| 180 | - 'func' => '_delete_event', |
|
| 181 | - 'capability' => 'ee_delete_event', |
|
| 182 | - 'obj_id' => $evt_id, |
|
| 183 | - 'noheader' => true, |
|
| 184 | - ), |
|
| 185 | - 'delete_events' => array( |
|
| 186 | - 'func' => '_delete_events', |
|
| 187 | - 'capability' => 'ee_delete_events', |
|
| 188 | - 'noheader' => true, |
|
| 189 | - ), |
|
| 190 | - 'view_report' => array( |
|
| 191 | - 'func' => '_view_report', |
|
| 192 | - 'capablity' => 'ee_edit_events', |
|
| 193 | - ), |
|
| 194 | - 'default_event_settings' => array( |
|
| 195 | - 'func' => '_default_event_settings', |
|
| 196 | - 'capability' => 'manage_options', |
|
| 197 | - ), |
|
| 198 | - 'update_default_event_settings' => array( |
|
| 199 | - 'func' => '_update_default_event_settings', |
|
| 200 | - 'capability' => 'manage_options', |
|
| 201 | - 'noheader' => true, |
|
| 202 | - ), |
|
| 203 | - 'template_settings' => array( |
|
| 204 | - 'func' => '_template_settings', |
|
| 205 | - 'capability' => 'manage_options', |
|
| 206 | - ), |
|
| 207 | - // event category tab related |
|
| 208 | - 'add_category' => array( |
|
| 209 | - 'func' => '_category_details', |
|
| 210 | - 'capability' => 'ee_edit_event_category', |
|
| 211 | - 'args' => array('add'), |
|
| 212 | - ), |
|
| 213 | - 'edit_category' => array( |
|
| 214 | - 'func' => '_category_details', |
|
| 215 | - 'capability' => 'ee_edit_event_category', |
|
| 216 | - 'args' => array('edit'), |
|
| 217 | - ), |
|
| 218 | - 'delete_categories' => array( |
|
| 219 | - 'func' => '_delete_categories', |
|
| 220 | - 'capability' => 'ee_delete_event_category', |
|
| 221 | - 'noheader' => true, |
|
| 222 | - ), |
|
| 223 | - 'delete_category' => array( |
|
| 224 | - 'func' => '_delete_categories', |
|
| 225 | - 'capability' => 'ee_delete_event_category', |
|
| 226 | - 'noheader' => true, |
|
| 227 | - ), |
|
| 228 | - 'insert_category' => array( |
|
| 229 | - 'func' => '_insert_or_update_category', |
|
| 230 | - 'args' => array('new_category' => true), |
|
| 231 | - 'capability' => 'ee_edit_event_category', |
|
| 232 | - 'noheader' => true, |
|
| 233 | - ), |
|
| 234 | - 'update_category' => array( |
|
| 235 | - 'func' => '_insert_or_update_category', |
|
| 236 | - 'args' => array('new_category' => false), |
|
| 237 | - 'capability' => 'ee_edit_event_category', |
|
| 238 | - 'noheader' => true, |
|
| 239 | - ), |
|
| 240 | - 'category_list' => array( |
|
| 241 | - 'func' => '_category_list_table', |
|
| 242 | - 'capability' => 'ee_manage_event_categories', |
|
| 243 | - ), |
|
| 244 | - 'preview_deletion' => [ |
|
| 245 | - 'func' => 'previewDeletion', |
|
| 246 | - 'capability' => 'ee_delete_events', |
|
| 247 | - ], |
|
| 248 | - 'confirm_deletion' => [ |
|
| 249 | - 'func' => 'confirmDeletion', |
|
| 250 | - 'capability' => 'ee_delete_events', |
|
| 251 | - 'noheader' => true, |
|
| 252 | - ] |
|
| 253 | - ); |
|
| 254 | - } |
|
| 255 | - |
|
| 256 | - |
|
| 257 | - /** |
|
| 258 | - * Set the _page_config property for this admin page group. |
|
| 259 | - */ |
|
| 260 | - protected function _set_page_config() |
|
| 261 | - { |
|
| 262 | - $this->_page_config = array( |
|
| 263 | - 'default' => array( |
|
| 264 | - 'nav' => array( |
|
| 265 | - 'label' => esc_html__('Overview', 'event_espresso'), |
|
| 266 | - 'order' => 10, |
|
| 267 | - ), |
|
| 268 | - 'list_table' => 'Events_Admin_List_Table', |
|
| 269 | - 'help_tabs' => array( |
|
| 270 | - 'events_overview_help_tab' => array( |
|
| 271 | - 'title' => esc_html__('Events Overview', 'event_espresso'), |
|
| 272 | - 'filename' => 'events_overview', |
|
| 273 | - ), |
|
| 274 | - 'events_overview_table_column_headings_help_tab' => array( |
|
| 275 | - 'title' => esc_html__('Events Overview Table Column Headings', 'event_espresso'), |
|
| 276 | - 'filename' => 'events_overview_table_column_headings', |
|
| 277 | - ), |
|
| 278 | - 'events_overview_filters_help_tab' => array( |
|
| 279 | - 'title' => esc_html__('Events Overview Filters', 'event_espresso'), |
|
| 280 | - 'filename' => 'events_overview_filters', |
|
| 281 | - ), |
|
| 282 | - 'events_overview_view_help_tab' => array( |
|
| 283 | - 'title' => esc_html__('Events Overview Views', 'event_espresso'), |
|
| 284 | - 'filename' => 'events_overview_views', |
|
| 285 | - ), |
|
| 286 | - 'events_overview_other_help_tab' => array( |
|
| 287 | - 'title' => esc_html__('Events Overview Other', 'event_espresso'), |
|
| 288 | - 'filename' => 'events_overview_other', |
|
| 289 | - ), |
|
| 290 | - ), |
|
| 291 | - 'help_tour' => array( |
|
| 292 | - 'Event_Overview_Help_Tour', |
|
| 293 | - // 'New_Features_Test_Help_Tour' for testing multiple help tour |
|
| 294 | - ), |
|
| 295 | - 'qtips' => array( |
|
| 296 | - 'EE_Event_List_Table_Tips', |
|
| 297 | - ), |
|
| 298 | - 'require_nonce' => false, |
|
| 299 | - ), |
|
| 300 | - 'create_new' => array( |
|
| 301 | - 'nav' => array( |
|
| 302 | - 'label' => esc_html__('Add Event', 'event_espresso'), |
|
| 303 | - 'order' => 5, |
|
| 304 | - 'persistent' => false, |
|
| 305 | - ), |
|
| 306 | - 'metaboxes' => array('_register_event_editor_meta_boxes'), |
|
| 307 | - 'help_tabs' => array( |
|
| 308 | - 'event_editor_help_tab' => array( |
|
| 309 | - 'title' => esc_html__('Event Editor', 'event_espresso'), |
|
| 310 | - 'filename' => 'event_editor', |
|
| 311 | - ), |
|
| 312 | - 'event_editor_title_richtexteditor_help_tab' => array( |
|
| 313 | - 'title' => esc_html__('Event Title & Rich Text Editor', 'event_espresso'), |
|
| 314 | - 'filename' => 'event_editor_title_richtexteditor', |
|
| 315 | - ), |
|
| 316 | - 'event_editor_venue_details_help_tab' => array( |
|
| 317 | - 'title' => esc_html__('Event Venue Details', 'event_espresso'), |
|
| 318 | - 'filename' => 'event_editor_venue_details', |
|
| 319 | - ), |
|
| 320 | - 'event_editor_event_datetimes_help_tab' => array( |
|
| 321 | - 'title' => esc_html__('Event Datetimes', 'event_espresso'), |
|
| 322 | - 'filename' => 'event_editor_event_datetimes', |
|
| 323 | - ), |
|
| 324 | - 'event_editor_event_tickets_help_tab' => array( |
|
| 325 | - 'title' => esc_html__('Event Tickets', 'event_espresso'), |
|
| 326 | - 'filename' => 'event_editor_event_tickets', |
|
| 327 | - ), |
|
| 328 | - 'event_editor_event_registration_options_help_tab' => array( |
|
| 329 | - 'title' => esc_html__('Event Registration Options', 'event_espresso'), |
|
| 330 | - 'filename' => 'event_editor_event_registration_options', |
|
| 331 | - ), |
|
| 332 | - 'event_editor_tags_categories_help_tab' => array( |
|
| 333 | - 'title' => esc_html__('Event Tags & Categories', 'event_espresso'), |
|
| 334 | - 'filename' => 'event_editor_tags_categories', |
|
| 335 | - ), |
|
| 336 | - 'event_editor_questions_registrants_help_tab' => array( |
|
| 337 | - 'title' => esc_html__('Questions for Registrants', 'event_espresso'), |
|
| 338 | - 'filename' => 'event_editor_questions_registrants', |
|
| 339 | - ), |
|
| 340 | - 'event_editor_save_new_event_help_tab' => array( |
|
| 341 | - 'title' => esc_html__('Save New Event', 'event_espresso'), |
|
| 342 | - 'filename' => 'event_editor_save_new_event', |
|
| 343 | - ), |
|
| 344 | - 'event_editor_other_help_tab' => array( |
|
| 345 | - 'title' => esc_html__('Event Other', 'event_espresso'), |
|
| 346 | - 'filename' => 'event_editor_other', |
|
| 347 | - ), |
|
| 348 | - ), |
|
| 349 | - 'help_tour' => array( |
|
| 350 | - 'Event_Editor_Help_Tour', |
|
| 351 | - ), |
|
| 352 | - 'qtips' => array('EE_Event_Editor_Decaf_Tips'), |
|
| 353 | - 'require_nonce' => false, |
|
| 354 | - ), |
|
| 355 | - 'edit' => array( |
|
| 356 | - 'nav' => array( |
|
| 357 | - 'label' => esc_html__('Edit Event', 'event_espresso'), |
|
| 358 | - 'order' => 5, |
|
| 359 | - 'persistent' => false, |
|
| 360 | - 'url' => isset($this->_req_data['post']) |
|
| 361 | - ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 362 | - array('post' => $this->_req_data['post'], 'action' => 'edit'), |
|
| 363 | - $this->_current_page_view_url |
|
| 364 | - ) |
|
| 365 | - : $this->_admin_base_url, |
|
| 366 | - ), |
|
| 367 | - 'metaboxes' => array('_register_event_editor_meta_boxes'), |
|
| 368 | - 'help_tabs' => array( |
|
| 369 | - 'event_editor_help_tab' => array( |
|
| 370 | - 'title' => esc_html__('Event Editor', 'event_espresso'), |
|
| 371 | - 'filename' => 'event_editor', |
|
| 372 | - ), |
|
| 373 | - 'event_editor_title_richtexteditor_help_tab' => array( |
|
| 374 | - 'title' => esc_html__('Event Title & Rich Text Editor', 'event_espresso'), |
|
| 375 | - 'filename' => 'event_editor_title_richtexteditor', |
|
| 376 | - ), |
|
| 377 | - 'event_editor_venue_details_help_tab' => array( |
|
| 378 | - 'title' => esc_html__('Event Venue Details', 'event_espresso'), |
|
| 379 | - 'filename' => 'event_editor_venue_details', |
|
| 380 | - ), |
|
| 381 | - 'event_editor_event_datetimes_help_tab' => array( |
|
| 382 | - 'title' => esc_html__('Event Datetimes', 'event_espresso'), |
|
| 383 | - 'filename' => 'event_editor_event_datetimes', |
|
| 384 | - ), |
|
| 385 | - 'event_editor_event_tickets_help_tab' => array( |
|
| 386 | - 'title' => esc_html__('Event Tickets', 'event_espresso'), |
|
| 387 | - 'filename' => 'event_editor_event_tickets', |
|
| 388 | - ), |
|
| 389 | - 'event_editor_event_registration_options_help_tab' => array( |
|
| 390 | - 'title' => esc_html__('Event Registration Options', 'event_espresso'), |
|
| 391 | - 'filename' => 'event_editor_event_registration_options', |
|
| 392 | - ), |
|
| 393 | - 'event_editor_tags_categories_help_tab' => array( |
|
| 394 | - 'title' => esc_html__('Event Tags & Categories', 'event_espresso'), |
|
| 395 | - 'filename' => 'event_editor_tags_categories', |
|
| 396 | - ), |
|
| 397 | - 'event_editor_questions_registrants_help_tab' => array( |
|
| 398 | - 'title' => esc_html__('Questions for Registrants', 'event_espresso'), |
|
| 399 | - 'filename' => 'event_editor_questions_registrants', |
|
| 400 | - ), |
|
| 401 | - 'event_editor_save_new_event_help_tab' => array( |
|
| 402 | - 'title' => esc_html__('Save New Event', 'event_espresso'), |
|
| 403 | - 'filename' => 'event_editor_save_new_event', |
|
| 404 | - ), |
|
| 405 | - 'event_editor_other_help_tab' => array( |
|
| 406 | - 'title' => esc_html__('Event Other', 'event_espresso'), |
|
| 407 | - 'filename' => 'event_editor_other', |
|
| 408 | - ), |
|
| 409 | - ), |
|
| 410 | - 'qtips' => array('EE_Event_Editor_Decaf_Tips'), |
|
| 411 | - 'require_nonce' => false, |
|
| 412 | - ), |
|
| 413 | - 'default_event_settings' => array( |
|
| 414 | - 'nav' => array( |
|
| 415 | - 'label' => esc_html__('Default Settings', 'event_espresso'), |
|
| 416 | - 'order' => 40, |
|
| 417 | - ), |
|
| 418 | - 'metaboxes' => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')), |
|
| 419 | - 'labels' => array( |
|
| 420 | - 'publishbox' => esc_html__('Update Settings', 'event_espresso'), |
|
| 421 | - ), |
|
| 422 | - 'help_tabs' => array( |
|
| 423 | - 'default_settings_help_tab' => array( |
|
| 424 | - 'title' => esc_html__('Default Event Settings', 'event_espresso'), |
|
| 425 | - 'filename' => 'events_default_settings', |
|
| 426 | - ), |
|
| 427 | - 'default_settings_status_help_tab' => array( |
|
| 428 | - 'title' => esc_html__('Default Registration Status', 'event_espresso'), |
|
| 429 | - 'filename' => 'events_default_settings_status', |
|
| 430 | - ), |
|
| 431 | - 'default_maximum_tickets_help_tab' => array( |
|
| 432 | - 'title' => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'), |
|
| 433 | - 'filename' => 'events_default_settings_max_tickets', |
|
| 434 | - ), |
|
| 435 | - ), |
|
| 436 | - 'help_tour' => array('Event_Default_Settings_Help_Tour'), |
|
| 437 | - 'require_nonce' => false, |
|
| 438 | - ), |
|
| 439 | - // template settings |
|
| 440 | - 'template_settings' => array( |
|
| 441 | - 'nav' => array( |
|
| 442 | - 'label' => esc_html__('Templates', 'event_espresso'), |
|
| 443 | - 'order' => 30, |
|
| 444 | - ), |
|
| 445 | - 'metaboxes' => $this->_default_espresso_metaboxes, |
|
| 446 | - 'help_tabs' => array( |
|
| 447 | - 'general_settings_templates_help_tab' => array( |
|
| 448 | - 'title' => esc_html__('Templates', 'event_espresso'), |
|
| 449 | - 'filename' => 'general_settings_templates', |
|
| 450 | - ), |
|
| 451 | - ), |
|
| 452 | - 'help_tour' => array('Templates_Help_Tour'), |
|
| 453 | - 'require_nonce' => false, |
|
| 454 | - ), |
|
| 455 | - // event category stuff |
|
| 456 | - 'add_category' => array( |
|
| 457 | - 'nav' => array( |
|
| 458 | - 'label' => esc_html__('Add Category', 'event_espresso'), |
|
| 459 | - 'order' => 15, |
|
| 460 | - 'persistent' => false, |
|
| 461 | - ), |
|
| 462 | - 'help_tabs' => array( |
|
| 463 | - 'add_category_help_tab' => array( |
|
| 464 | - 'title' => esc_html__('Add New Event Category', 'event_espresso'), |
|
| 465 | - 'filename' => 'events_add_category', |
|
| 466 | - ), |
|
| 467 | - ), |
|
| 468 | - 'help_tour' => array('Event_Add_Category_Help_Tour'), |
|
| 469 | - 'metaboxes' => array('_publish_post_box'), |
|
| 470 | - 'require_nonce' => false, |
|
| 471 | - ), |
|
| 472 | - 'edit_category' => array( |
|
| 473 | - 'nav' => array( |
|
| 474 | - 'label' => esc_html__('Edit Category', 'event_espresso'), |
|
| 475 | - 'order' => 15, |
|
| 476 | - 'persistent' => false, |
|
| 477 | - 'url' => isset($this->_req_data['EVT_CAT_ID']) |
|
| 478 | - ? add_query_arg( |
|
| 479 | - array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']), |
|
| 480 | - $this->_current_page_view_url |
|
| 481 | - ) |
|
| 482 | - : $this->_admin_base_url, |
|
| 483 | - ), |
|
| 484 | - 'help_tabs' => array( |
|
| 485 | - 'edit_category_help_tab' => array( |
|
| 486 | - 'title' => esc_html__('Edit Event Category', 'event_espresso'), |
|
| 487 | - 'filename' => 'events_edit_category', |
|
| 488 | - ), |
|
| 489 | - ), |
|
| 490 | - /*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/ |
|
| 491 | - 'metaboxes' => array('_publish_post_box'), |
|
| 492 | - 'require_nonce' => false, |
|
| 493 | - ), |
|
| 494 | - 'category_list' => array( |
|
| 495 | - 'nav' => array( |
|
| 496 | - 'label' => esc_html__('Categories', 'event_espresso'), |
|
| 497 | - 'order' => 20, |
|
| 498 | - ), |
|
| 499 | - 'list_table' => 'Event_Categories_Admin_List_Table', |
|
| 500 | - 'help_tabs' => array( |
|
| 501 | - 'events_categories_help_tab' => array( |
|
| 502 | - 'title' => esc_html__('Event Categories', 'event_espresso'), |
|
| 503 | - 'filename' => 'events_categories', |
|
| 504 | - ), |
|
| 505 | - 'events_categories_table_column_headings_help_tab' => array( |
|
| 506 | - 'title' => esc_html__('Event Categories Table Column Headings', 'event_espresso'), |
|
| 507 | - 'filename' => 'events_categories_table_column_headings', |
|
| 508 | - ), |
|
| 509 | - 'events_categories_view_help_tab' => array( |
|
| 510 | - 'title' => esc_html__('Event Categories Views', 'event_espresso'), |
|
| 511 | - 'filename' => 'events_categories_views', |
|
| 512 | - ), |
|
| 513 | - 'events_categories_other_help_tab' => array( |
|
| 514 | - 'title' => esc_html__('Event Categories Other', 'event_espresso'), |
|
| 515 | - 'filename' => 'events_categories_other', |
|
| 516 | - ), |
|
| 517 | - ), |
|
| 518 | - 'help_tour' => array( |
|
| 519 | - 'Event_Categories_Help_Tour', |
|
| 520 | - ), |
|
| 521 | - 'metaboxes' => $this->_default_espresso_metaboxes, |
|
| 522 | - 'require_nonce' => false, |
|
| 523 | - ), |
|
| 524 | - 'preview_deletion' => array( |
|
| 525 | - 'nav' => array( |
|
| 526 | - 'label' => esc_html__('Preview Deletion', 'event_espresso'), |
|
| 527 | - 'order' => 15, |
|
| 528 | - 'persistent' => false, |
|
| 529 | - ), |
|
| 530 | - 'require_nonce' => false |
|
| 531 | - ) |
|
| 532 | - ); |
|
| 533 | - } |
|
| 534 | - |
|
| 535 | - |
|
| 536 | - /** |
|
| 537 | - * Used to register any global screen options if necessary for every route in this admin page group. |
|
| 538 | - */ |
|
| 539 | - protected function _add_screen_options() |
|
| 540 | - { |
|
| 541 | - } |
|
| 542 | - |
|
| 543 | - |
|
| 544 | - /** |
|
| 545 | - * Implementing the screen options for the 'default' route. |
|
| 546 | - */ |
|
| 547 | - protected function _add_screen_options_default() |
|
| 548 | - { |
|
| 549 | - $this->_per_page_screen_option(); |
|
| 550 | - } |
|
| 551 | - |
|
| 552 | - |
|
| 553 | - /** |
|
| 554 | - * Implementing screen options for the category list route. |
|
| 555 | - */ |
|
| 556 | - protected function _add_screen_options_category_list() |
|
| 557 | - { |
|
| 558 | - $page_title = $this->_admin_page_title; |
|
| 559 | - $this->_admin_page_title = esc_html__('Categories', 'event_espresso'); |
|
| 560 | - $this->_per_page_screen_option(); |
|
| 561 | - $this->_admin_page_title = $page_title; |
|
| 562 | - } |
|
| 563 | - |
|
| 564 | - |
|
| 565 | - /** |
|
| 566 | - * Used to register any global feature pointers for the admin page group. |
|
| 567 | - */ |
|
| 568 | - protected function _add_feature_pointers() |
|
| 569 | - { |
|
| 570 | - } |
|
| 571 | - |
|
| 572 | - |
|
| 573 | - /** |
|
| 574 | - * Registers and enqueues any global scripts and styles for the entire admin page group. |
|
| 575 | - */ |
|
| 576 | - public function load_scripts_styles() |
|
| 577 | - { |
|
| 578 | - wp_register_style( |
|
| 579 | - 'events-admin-css', |
|
| 580 | - EVENTS_ASSETS_URL . 'events-admin-page.css', |
|
| 581 | - array(), |
|
| 582 | - EVENT_ESPRESSO_VERSION |
|
| 583 | - ); |
|
| 584 | - wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 585 | - wp_enqueue_style('events-admin-css'); |
|
| 586 | - wp_enqueue_style('ee-cat-admin'); |
|
| 587 | - // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details |
|
| 588 | - // registers for all views |
|
| 589 | - // scripts |
|
| 590 | - wp_register_script( |
|
| 591 | - 'event_editor_js', |
|
| 592 | - EVENTS_ASSETS_URL . 'event_editor.js', |
|
| 593 | - array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'), |
|
| 594 | - EVENT_ESPRESSO_VERSION, |
|
| 595 | - true |
|
| 596 | - ); |
|
| 597 | - } |
|
| 598 | - |
|
| 599 | - |
|
| 600 | - /** |
|
| 601 | - * Enqueuing scripts and styles specific to this view |
|
| 602 | - */ |
|
| 603 | - public function load_scripts_styles_create_new() |
|
| 604 | - { |
|
| 605 | - $this->load_scripts_styles_edit(); |
|
| 606 | - } |
|
| 607 | - |
|
| 608 | - |
|
| 609 | - /** |
|
| 610 | - * Enqueuing scripts and styles specific to this view |
|
| 611 | - */ |
|
| 612 | - public function load_scripts_styles_edit() |
|
| 613 | - { |
|
| 614 | - // styles |
|
| 615 | - wp_enqueue_style('espresso-ui-theme'); |
|
| 616 | - wp_register_style( |
|
| 617 | - 'event-editor-css', |
|
| 618 | - EVENTS_ASSETS_URL . 'event-editor.css', |
|
| 619 | - array('ee-admin-css'), |
|
| 620 | - EVENT_ESPRESSO_VERSION |
|
| 621 | - ); |
|
| 622 | - wp_enqueue_style('event-editor-css'); |
|
| 623 | - // scripts |
|
| 624 | - wp_register_script( |
|
| 625 | - 'event-datetime-metabox', |
|
| 626 | - EVENTS_ASSETS_URL . 'event-datetime-metabox.js', |
|
| 627 | - array('event_editor_js', 'ee-datepicker'), |
|
| 628 | - EVENT_ESPRESSO_VERSION |
|
| 629 | - ); |
|
| 630 | - wp_enqueue_script('event-datetime-metabox'); |
|
| 631 | - } |
|
| 632 | - |
|
| 633 | - |
|
| 634 | - /** |
|
| 635 | - * Populating the _views property for the category list table view. |
|
| 636 | - */ |
|
| 637 | - protected function _set_list_table_views_category_list() |
|
| 638 | - { |
|
| 639 | - $this->_views = array( |
|
| 640 | - 'all' => array( |
|
| 641 | - 'slug' => 'all', |
|
| 642 | - 'label' => esc_html__('All', 'event_espresso'), |
|
| 643 | - 'count' => 0, |
|
| 644 | - 'bulk_action' => array( |
|
| 645 | - 'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'), |
|
| 646 | - ), |
|
| 647 | - ), |
|
| 648 | - ); |
|
| 649 | - } |
|
| 650 | - |
|
| 651 | - |
|
| 652 | - /** |
|
| 653 | - * For adding anything that fires on the admin_init hook for any route within this admin page group. |
|
| 654 | - */ |
|
| 655 | - public function admin_init() |
|
| 656 | - { |
|
| 657 | - EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__( |
|
| 658 | - 'Do you really want to delete this image? Please remember to update your event to complete the removal.', |
|
| 659 | - 'event_espresso' |
|
| 660 | - ); |
|
| 661 | - } |
|
| 662 | - |
|
| 663 | - |
|
| 664 | - /** |
|
| 665 | - * For adding anything that should be triggered on the admin_notices hook for any route within this admin page |
|
| 666 | - * group. |
|
| 667 | - */ |
|
| 668 | - public function admin_notices() |
|
| 669 | - { |
|
| 670 | - } |
|
| 671 | - |
|
| 672 | - |
|
| 673 | - /** |
|
| 674 | - * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within |
|
| 675 | - * this admin page group. |
|
| 676 | - */ |
|
| 677 | - public function admin_footer_scripts() |
|
| 678 | - { |
|
| 679 | - } |
|
| 680 | - |
|
| 681 | - |
|
| 682 | - /** |
|
| 683 | - * Call this function to verify if an event is public and has tickets for sale. If it does, then we need to show a |
|
| 684 | - * warning (via EE_Error::add_error()); |
|
| 685 | - * |
|
| 686 | - * @param EE_Event $event Event object |
|
| 687 | - * @param string $req_type |
|
| 688 | - * @return void |
|
| 689 | - * @throws EE_Error |
|
| 690 | - * @access public |
|
| 691 | - */ |
|
| 692 | - public function verify_event_edit($event = null, $req_type = '') |
|
| 693 | - { |
|
| 694 | - // don't need to do this when processing |
|
| 695 | - if (! empty($req_type)) { |
|
| 696 | - return; |
|
| 697 | - } |
|
| 698 | - // no event? |
|
| 699 | - if (empty($event)) { |
|
| 700 | - // set event |
|
| 701 | - $event = $this->_cpt_model_obj; |
|
| 702 | - } |
|
| 703 | - // STILL no event? |
|
| 704 | - if (! $event instanceof EE_Event) { |
|
| 705 | - return; |
|
| 706 | - } |
|
| 707 | - $orig_status = $event->status(); |
|
| 708 | - // first check if event is active. |
|
| 709 | - if ($orig_status === EEM_Event::cancelled |
|
| 710 | - || $orig_status === EEM_Event::postponed |
|
| 711 | - || $event->is_expired() |
|
| 712 | - || $event->is_inactive() |
|
| 713 | - ) { |
|
| 714 | - return; |
|
| 715 | - } |
|
| 716 | - // made it here so it IS active... next check that any of the tickets are sold. |
|
| 717 | - if ($event->is_sold_out(true)) { |
|
| 718 | - if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) { |
|
| 719 | - EE_Error::add_attention( |
|
| 720 | - sprintf( |
|
| 721 | - esc_html__( |
|
| 722 | - 'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event. However, this change is not permanent until you update the event. You can change the status back to something else before updating if you wish.', |
|
| 723 | - 'event_espresso' |
|
| 724 | - ), |
|
| 725 | - EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence') |
|
| 726 | - ) |
|
| 727 | - ); |
|
| 728 | - } |
|
| 729 | - return; |
|
| 730 | - } elseif ($orig_status === EEM_Event::sold_out) { |
|
| 731 | - EE_Error::add_attention( |
|
| 732 | - sprintf( |
|
| 733 | - esc_html__( |
|
| 734 | - 'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets. However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.', |
|
| 735 | - 'event_espresso' |
|
| 736 | - ), |
|
| 737 | - EEH_Template::pretty_status($event->status(), false, 'sentence') |
|
| 738 | - ) |
|
| 739 | - ); |
|
| 740 | - } |
|
| 741 | - // now we need to determine if the event has any tickets on sale. If not then we dont' show the error |
|
| 742 | - if (! $event->tickets_on_sale()) { |
|
| 743 | - return; |
|
| 744 | - } |
|
| 745 | - // made it here so show warning |
|
| 746 | - $this->_edit_event_warning(); |
|
| 747 | - } |
|
| 748 | - |
|
| 749 | - |
|
| 750 | - /** |
|
| 751 | - * This is the text used for when an event is being edited that is public and has tickets for sale. |
|
| 752 | - * When needed, hook this into a EE_Error::add_error() notice. |
|
| 753 | - * |
|
| 754 | - * @access protected |
|
| 755 | - * @return void |
|
| 756 | - */ |
|
| 757 | - protected function _edit_event_warning() |
|
| 758 | - { |
|
| 759 | - // we don't want to add warnings during these requests |
|
| 760 | - if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') { |
|
| 761 | - return; |
|
| 762 | - } |
|
| 763 | - EE_Error::add_attention( |
|
| 764 | - sprintf( |
|
| 765 | - esc_html__( |
|
| 766 | - 'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s', |
|
| 767 | - 'event_espresso' |
|
| 768 | - ), |
|
| 769 | - '<a class="espresso-help-tab-lnk">', |
|
| 770 | - '</a>' |
|
| 771 | - ) |
|
| 772 | - ); |
|
| 773 | - } |
|
| 774 | - |
|
| 775 | - |
|
| 776 | - /** |
|
| 777 | - * When a user is creating a new event, notify them if they haven't set their timezone. |
|
| 778 | - * Otherwise, do the normal logic |
|
| 779 | - * |
|
| 780 | - * @return string |
|
| 781 | - * @throws \EE_Error |
|
| 782 | - */ |
|
| 783 | - protected function _create_new_cpt_item() |
|
| 784 | - { |
|
| 785 | - $has_timezone_string = get_option('timezone_string'); |
|
| 786 | - // only nag them about setting their timezone if it's their first event, and they haven't already done it |
|
| 787 | - if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) { |
|
| 788 | - EE_Error::add_attention( |
|
| 789 | - sprintf( |
|
| 790 | - __( |
|
| 791 | - 'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s', |
|
| 792 | - 'event_espresso' |
|
| 793 | - ), |
|
| 794 | - '<br>', |
|
| 795 | - '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">' |
|
| 796 | - . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale()) |
|
| 797 | - . '</select>', |
|
| 798 | - '<button class="button button-secondary timezone-submit">', |
|
| 799 | - '</button><span class="spinner"></span>' |
|
| 800 | - ), |
|
| 801 | - __FILE__, |
|
| 802 | - __FUNCTION__, |
|
| 803 | - __LINE__ |
|
| 804 | - ); |
|
| 805 | - } |
|
| 806 | - return parent::_create_new_cpt_item(); |
|
| 807 | - } |
|
| 808 | - |
|
| 809 | - |
|
| 810 | - /** |
|
| 811 | - * Sets the _views property for the default route in this admin page group. |
|
| 812 | - */ |
|
| 813 | - protected function _set_list_table_views_default() |
|
| 814 | - { |
|
| 815 | - $this->_views = array( |
|
| 816 | - 'all' => array( |
|
| 817 | - 'slug' => 'all', |
|
| 818 | - 'label' => esc_html__('View All Events', 'event_espresso'), |
|
| 819 | - 'count' => 0, |
|
| 820 | - 'bulk_action' => array( |
|
| 821 | - 'trash_events' => esc_html__('Move to Trash', 'event_espresso'), |
|
| 822 | - ), |
|
| 823 | - ), |
|
| 824 | - 'draft' => array( |
|
| 825 | - 'slug' => 'draft', |
|
| 826 | - 'label' => esc_html__('Draft', 'event_espresso'), |
|
| 827 | - 'count' => 0, |
|
| 828 | - 'bulk_action' => array( |
|
| 829 | - 'trash_events' => esc_html__('Move to Trash', 'event_espresso'), |
|
| 830 | - ), |
|
| 831 | - ), |
|
| 832 | - ); |
|
| 833 | - if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) { |
|
| 834 | - $this->_views['trash'] = array( |
|
| 835 | - 'slug' => 'trash', |
|
| 836 | - 'label' => esc_html__('Trash', 'event_espresso'), |
|
| 837 | - 'count' => 0, |
|
| 838 | - 'bulk_action' => array( |
|
| 839 | - 'restore_events' => esc_html__('Restore From Trash', 'event_espresso'), |
|
| 840 | - 'delete_events' => esc_html__('Delete Permanently', 'event_espresso'), |
|
| 841 | - ), |
|
| 842 | - ); |
|
| 843 | - } |
|
| 844 | - } |
|
| 845 | - |
|
| 846 | - |
|
| 847 | - /** |
|
| 848 | - * Provides the legend item array for the default list table view. |
|
| 849 | - * |
|
| 850 | - * @return array |
|
| 851 | - */ |
|
| 852 | - protected function _event_legend_items() |
|
| 853 | - { |
|
| 854 | - $items = array( |
|
| 855 | - 'view_details' => array( |
|
| 856 | - 'class' => 'dashicons dashicons-search', |
|
| 857 | - 'desc' => esc_html__('View Event', 'event_espresso'), |
|
| 858 | - ), |
|
| 859 | - 'edit_event' => array( |
|
| 860 | - 'class' => 'ee-icon ee-icon-calendar-edit', |
|
| 861 | - 'desc' => esc_html__('Edit Event Details', 'event_espresso'), |
|
| 862 | - ), |
|
| 863 | - 'view_attendees' => array( |
|
| 864 | - 'class' => 'dashicons dashicons-groups', |
|
| 865 | - 'desc' => esc_html__('View Registrations for Event', 'event_espresso'), |
|
| 866 | - ), |
|
| 867 | - ); |
|
| 868 | - $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items); |
|
| 869 | - $statuses = array( |
|
| 870 | - 'sold_out_status' => array( |
|
| 871 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out, |
|
| 872 | - 'desc' => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'), |
|
| 873 | - ), |
|
| 874 | - 'active_status' => array( |
|
| 875 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active, |
|
| 876 | - 'desc' => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'), |
|
| 877 | - ), |
|
| 878 | - 'upcoming_status' => array( |
|
| 879 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming, |
|
| 880 | - 'desc' => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'), |
|
| 881 | - ), |
|
| 882 | - 'postponed_status' => array( |
|
| 883 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed, |
|
| 884 | - 'desc' => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'), |
|
| 885 | - ), |
|
| 886 | - 'cancelled_status' => array( |
|
| 887 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled, |
|
| 888 | - 'desc' => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'), |
|
| 889 | - ), |
|
| 890 | - 'expired_status' => array( |
|
| 891 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired, |
|
| 892 | - 'desc' => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'), |
|
| 893 | - ), |
|
| 894 | - 'inactive_status' => array( |
|
| 895 | - 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive, |
|
| 896 | - 'desc' => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'), |
|
| 897 | - ), |
|
| 898 | - ); |
|
| 899 | - $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses); |
|
| 900 | - return array_merge($items, $statuses); |
|
| 901 | - } |
|
| 902 | - |
|
| 903 | - |
|
| 904 | - /** |
|
| 905 | - * @return EEM_Event |
|
| 906 | - */ |
|
| 907 | - private function _event_model() |
|
| 908 | - { |
|
| 909 | - if (! $this->_event_model instanceof EEM_Event) { |
|
| 910 | - $this->_event_model = EE_Registry::instance()->load_model('Event'); |
|
| 911 | - } |
|
| 912 | - return $this->_event_model; |
|
| 913 | - } |
|
| 914 | - |
|
| 915 | - |
|
| 916 | - /** |
|
| 917 | - * Adds extra buttons to the WP CPT permalink field row. |
|
| 918 | - * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter. |
|
| 919 | - * |
|
| 920 | - * @param string $return the current html |
|
| 921 | - * @param int $id the post id for the page |
|
| 922 | - * @param string $new_title What the title is |
|
| 923 | - * @param string $new_slug what the slug is |
|
| 924 | - * @return string The new html string for the permalink area |
|
| 925 | - */ |
|
| 926 | - public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug) |
|
| 927 | - { |
|
| 928 | - // make sure this is only when editing |
|
| 929 | - if (! empty($id)) { |
|
| 930 | - $post = get_post($id); |
|
| 931 | - $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#" tabindex="-1">' |
|
| 932 | - . esc_html__('Shortcode', 'event_espresso') |
|
| 933 | - . '</a> '; |
|
| 934 | - $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id=' |
|
| 935 | - . $post->ID |
|
| 936 | - . ']">'; |
|
| 937 | - } |
|
| 938 | - return $return; |
|
| 939 | - } |
|
| 940 | - |
|
| 941 | - |
|
| 942 | - /** |
|
| 943 | - * _events_overview_list_table |
|
| 944 | - * This contains the logic for showing the events_overview list |
|
| 945 | - * |
|
| 946 | - * @access protected |
|
| 947 | - * @return void |
|
| 948 | - * @throws \EE_Error |
|
| 949 | - */ |
|
| 950 | - protected function _events_overview_list_table() |
|
| 951 | - { |
|
| 952 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 953 | - $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table']) |
|
| 954 | - ? (array) $this->_template_args['after_list_table'] |
|
| 955 | - : array(); |
|
| 956 | - $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br() |
|
| 957 | - . EEH_Template::get_button_or_link( |
|
| 958 | - get_post_type_archive_link('espresso_events'), |
|
| 959 | - esc_html__("View Event Archive Page", "event_espresso"), |
|
| 960 | - 'button' |
|
| 961 | - ); |
|
| 962 | - $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items()); |
|
| 963 | - $this->_admin_page_title .= ' ' . $this->get_action_link_or_button( |
|
| 964 | - 'create_new', |
|
| 965 | - 'add', |
|
| 966 | - array(), |
|
| 967 | - 'add-new-h2' |
|
| 968 | - ); |
|
| 969 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 970 | - } |
|
| 971 | - |
|
| 972 | - |
|
| 973 | - /** |
|
| 974 | - * this allows for extra misc actions in the default WP publish box |
|
| 975 | - * |
|
| 976 | - * @return void |
|
| 977 | - */ |
|
| 978 | - public function extra_misc_actions_publish_box() |
|
| 979 | - { |
|
| 980 | - $this->_generate_publish_box_extra_content(); |
|
| 981 | - } |
|
| 982 | - |
|
| 983 | - |
|
| 984 | - /** |
|
| 985 | - * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been |
|
| 986 | - * saved. |
|
| 987 | - * Typically you would use this to save any additional data. |
|
| 988 | - * Keep in mind also that "save_post" runs on EVERY post update to the database. |
|
| 989 | - * ALSO very important. When a post transitions from scheduled to published, |
|
| 990 | - * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from |
|
| 991 | - * other meta saves. So MAKE sure that you handle this accordingly. |
|
| 992 | - * |
|
| 993 | - * @access protected |
|
| 994 | - * @abstract |
|
| 995 | - * @param string $post_id The ID of the cpt that was saved (so you can link relationally) |
|
| 996 | - * @param object $post The post object of the cpt that was saved. |
|
| 997 | - * @return void |
|
| 998 | - * @throws \EE_Error |
|
| 999 | - */ |
|
| 1000 | - protected function _insert_update_cpt_item($post_id, $post) |
|
| 1001 | - { |
|
| 1002 | - if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') { |
|
| 1003 | - // get out we're not processing an event save. |
|
| 1004 | - return; |
|
| 1005 | - } |
|
| 1006 | - $event_values = array( |
|
| 1007 | - 'EVT_display_desc' => ! empty($this->_req_data['display_desc']) ? 1 : 0, |
|
| 1008 | - 'EVT_display_ticket_selector' => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0, |
|
| 1009 | - 'EVT_additional_limit' => min( |
|
| 1010 | - apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255), |
|
| 1011 | - ! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null |
|
| 1012 | - ), |
|
| 1013 | - 'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status']) |
|
| 1014 | - ? $this->_req_data['EVT_default_registration_status'] |
|
| 1015 | - : EE_Registry::instance()->CFG->registration->default_STS_ID, |
|
| 1016 | - 'EVT_member_only' => ! empty($this->_req_data['member_only']) ? 1 : 0, |
|
| 1017 | - 'EVT_allow_overflow' => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0, |
|
| 1018 | - 'EVT_timezone_string' => ! empty($this->_req_data['timezone_string']) |
|
| 1019 | - ? $this->_req_data['timezone_string'] : null, |
|
| 1020 | - 'EVT_external_URL' => ! empty($this->_req_data['externalURL']) |
|
| 1021 | - ? $this->_req_data['externalURL'] : null, |
|
| 1022 | - 'EVT_phone' => ! empty($this->_req_data['event_phone']) |
|
| 1023 | - ? $this->_req_data['event_phone'] : null, |
|
| 1024 | - ); |
|
| 1025 | - // update event |
|
| 1026 | - $success = $this->_event_model()->update_by_ID($event_values, $post_id); |
|
| 1027 | - // get event_object for other metaboxes... though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id! |
|
| 1028 | - $get_one_where = array( |
|
| 1029 | - $this->_event_model()->primary_key_name() => $post_id, |
|
| 1030 | - 'OR' => array( |
|
| 1031 | - 'status' => $post->post_status, |
|
| 1032 | - // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db, |
|
| 1033 | - // but the returned object here has a status of "publish", so use the original post status as well |
|
| 1034 | - 'status*1' => $this->_req_data['original_post_status'], |
|
| 1035 | - ), |
|
| 1036 | - ); |
|
| 1037 | - $event = $this->_event_model()->get_one(array($get_one_where)); |
|
| 1038 | - // the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons. |
|
| 1039 | - $event_update_callbacks = apply_filters( |
|
| 1040 | - 'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks', |
|
| 1041 | - array( |
|
| 1042 | - array($this, '_default_venue_update'), |
|
| 1043 | - array($this, '_default_tickets_update'), |
|
| 1044 | - ) |
|
| 1045 | - ); |
|
| 1046 | - $att_success = true; |
|
| 1047 | - foreach ($event_update_callbacks as $e_callback) { |
|
| 1048 | - $_success = is_callable($e_callback) |
|
| 1049 | - ? call_user_func($e_callback, $event, $this->_req_data) |
|
| 1050 | - : false; |
|
| 1051 | - // if ANY of these updates fail then we want the appropriate global error message |
|
| 1052 | - $att_success = ! $att_success ? $att_success : $_success; |
|
| 1053 | - } |
|
| 1054 | - // any errors? |
|
| 1055 | - if ($success && false === $att_success) { |
|
| 1056 | - EE_Error::add_error( |
|
| 1057 | - esc_html__( |
|
| 1058 | - 'Event Details saved successfully but something went wrong with saving attachments.', |
|
| 1059 | - 'event_espresso' |
|
| 1060 | - ), |
|
| 1061 | - __FILE__, |
|
| 1062 | - __FUNCTION__, |
|
| 1063 | - __LINE__ |
|
| 1064 | - ); |
|
| 1065 | - } elseif ($success === false) { |
|
| 1066 | - EE_Error::add_error( |
|
| 1067 | - esc_html__('Event Details did not save successfully.', 'event_espresso'), |
|
| 1068 | - __FILE__, |
|
| 1069 | - __FUNCTION__, |
|
| 1070 | - __LINE__ |
|
| 1071 | - ); |
|
| 1072 | - } |
|
| 1073 | - } |
|
| 1074 | - |
|
| 1075 | - |
|
| 1076 | - /** |
|
| 1077 | - * @see parent::restore_item() |
|
| 1078 | - * @param int $post_id |
|
| 1079 | - * @param int $revision_id |
|
| 1080 | - */ |
|
| 1081 | - protected function _restore_cpt_item($post_id, $revision_id) |
|
| 1082 | - { |
|
| 1083 | - // copy existing event meta to new post |
|
| 1084 | - $post_evt = $this->_event_model()->get_one_by_ID($post_id); |
|
| 1085 | - if ($post_evt instanceof EE_Event) { |
|
| 1086 | - // meta revision restore |
|
| 1087 | - $post_evt->restore_revision($revision_id); |
|
| 1088 | - // related objs restore |
|
| 1089 | - $post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price')); |
|
| 1090 | - } |
|
| 1091 | - } |
|
| 1092 | - |
|
| 1093 | - |
|
| 1094 | - /** |
|
| 1095 | - * Attach the venue to the Event |
|
| 1096 | - * |
|
| 1097 | - * @param \EE_Event $evtobj Event Object to add the venue to |
|
| 1098 | - * @param array $data The request data from the form |
|
| 1099 | - * @return bool Success or fail. |
|
| 1100 | - */ |
|
| 1101 | - protected function _default_venue_update(\EE_Event $evtobj, $data) |
|
| 1102 | - { |
|
| 1103 | - require_once(EE_MODELS . 'EEM_Venue.model.php'); |
|
| 1104 | - $venue_model = EE_Registry::instance()->load_model('Venue'); |
|
| 1105 | - $rows_affected = null; |
|
| 1106 | - $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null; |
|
| 1107 | - // very important. If we don't have a venue name... |
|
| 1108 | - // then we'll get out because not necessary to create empty venue |
|
| 1109 | - if (empty($data['venue_title'])) { |
|
| 1110 | - return false; |
|
| 1111 | - } |
|
| 1112 | - $venue_array = array( |
|
| 1113 | - 'VNU_wp_user' => $evtobj->get('EVT_wp_user'), |
|
| 1114 | - 'VNU_name' => ! empty($data['venue_title']) ? $data['venue_title'] : null, |
|
| 1115 | - 'VNU_desc' => ! empty($data['venue_description']) ? $data['venue_description'] : null, |
|
| 1116 | - 'VNU_identifier' => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null, |
|
| 1117 | - 'VNU_short_desc' => ! empty($data['venue_short_description']) ? $data['venue_short_description'] |
|
| 1118 | - : null, |
|
| 1119 | - 'VNU_address' => ! empty($data['address']) ? $data['address'] : null, |
|
| 1120 | - 'VNU_address2' => ! empty($data['address2']) ? $data['address2'] : null, |
|
| 1121 | - 'VNU_city' => ! empty($data['city']) ? $data['city'] : null, |
|
| 1122 | - 'STA_ID' => ! empty($data['state']) ? $data['state'] : null, |
|
| 1123 | - 'CNT_ISO' => ! empty($data['countries']) ? $data['countries'] : null, |
|
| 1124 | - 'VNU_zip' => ! empty($data['zip']) ? $data['zip'] : null, |
|
| 1125 | - 'VNU_phone' => ! empty($data['venue_phone']) ? $data['venue_phone'] : null, |
|
| 1126 | - 'VNU_capacity' => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null, |
|
| 1127 | - 'VNU_url' => ! empty($data['venue_url']) ? $data['venue_url'] : null, |
|
| 1128 | - 'VNU_virtual_phone' => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null, |
|
| 1129 | - 'VNU_virtual_url' => ! empty($data['virtual_url']) ? $data['virtual_url'] : null, |
|
| 1130 | - 'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0, |
|
| 1131 | - 'status' => 'publish', |
|
| 1132 | - ); |
|
| 1133 | - // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out. |
|
| 1134 | - if (! empty($venue_id)) { |
|
| 1135 | - $update_where = array($venue_model->primary_key_name() => $venue_id); |
|
| 1136 | - $rows_affected = $venue_model->update($venue_array, array($update_where)); |
|
| 1137 | - // we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present. |
|
| 1138 | - $evtobj->_add_relation_to($venue_id, 'Venue'); |
|
| 1139 | - return $rows_affected > 0 ? true : false; |
|
| 1140 | - } else { |
|
| 1141 | - // we insert the venue |
|
| 1142 | - $venue_id = $venue_model->insert($venue_array); |
|
| 1143 | - $evtobj->_add_relation_to($venue_id, 'Venue'); |
|
| 1144 | - return ! empty($venue_id) ? true : false; |
|
| 1145 | - } |
|
| 1146 | - // when we have the ancestor come in it's already been handled by the revision save. |
|
| 1147 | - } |
|
| 1148 | - |
|
| 1149 | - |
|
| 1150 | - /** |
|
| 1151 | - * Handles saving everything related to Tickets (datetimes, tickets, prices) |
|
| 1152 | - * |
|
| 1153 | - * @param EE_Event $evtobj The Event object we're attaching data to |
|
| 1154 | - * @param array $data The request data from the form |
|
| 1155 | - * @return array |
|
| 1156 | - */ |
|
| 1157 | - protected function _default_tickets_update(EE_Event $evtobj, $data) |
|
| 1158 | - { |
|
| 1159 | - $success = true; |
|
| 1160 | - $saved_dtt = null; |
|
| 1161 | - $saved_tickets = array(); |
|
| 1162 | - $incoming_date_formats = array('Y-m-d', 'h:i a'); |
|
| 1163 | - foreach ($data['edit_event_datetimes'] as $row => $dtt) { |
|
| 1164 | - // trim all values to ensure any excess whitespace is removed. |
|
| 1165 | - $dtt = array_map('trim', $dtt); |
|
| 1166 | - $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end'] |
|
| 1167 | - : $dtt['DTT_EVT_start']; |
|
| 1168 | - $datetime_values = array( |
|
| 1169 | - 'DTT_ID' => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null, |
|
| 1170 | - 'DTT_EVT_start' => $dtt['DTT_EVT_start'], |
|
| 1171 | - 'DTT_EVT_end' => $dtt['DTT_EVT_end'], |
|
| 1172 | - 'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'], |
|
| 1173 | - 'DTT_order' => $row, |
|
| 1174 | - ); |
|
| 1175 | - // if we have an id then let's get existing object first and then set the new values. Otherwise we instantiate a new object for save. |
|
| 1176 | - if (! empty($dtt['DTT_ID'])) { |
|
| 1177 | - $DTM = EE_Registry::instance() |
|
| 1178 | - ->load_model('Datetime', array($evtobj->get_timezone())) |
|
| 1179 | - ->get_one_by_ID($dtt['DTT_ID']); |
|
| 1180 | - $DTM->set_date_format($incoming_date_formats[0]); |
|
| 1181 | - $DTM->set_time_format($incoming_date_formats[1]); |
|
| 1182 | - foreach ($datetime_values as $field => $value) { |
|
| 1183 | - $DTM->set($field, $value); |
|
| 1184 | - } |
|
| 1185 | - // make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it. We need to do this so we dont' TRASH the parent DTT. |
|
| 1186 | - $saved_dtts[ $DTM->ID() ] = $DTM; |
|
| 1187 | - } else { |
|
| 1188 | - $DTM = EE_Registry::instance()->load_class( |
|
| 1189 | - 'Datetime', |
|
| 1190 | - array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats), |
|
| 1191 | - false, |
|
| 1192 | - false |
|
| 1193 | - ); |
|
| 1194 | - foreach ($datetime_values as $field => $value) { |
|
| 1195 | - $DTM->set($field, $value); |
|
| 1196 | - } |
|
| 1197 | - } |
|
| 1198 | - $DTM->save(); |
|
| 1199 | - $DTT = $evtobj->_add_relation_to($DTM, 'Datetime'); |
|
| 1200 | - // load DTT helper |
|
| 1201 | - // before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date. |
|
| 1202 | - if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) { |
|
| 1203 | - $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start')); |
|
| 1204 | - $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days'); |
|
| 1205 | - $DTT->save(); |
|
| 1206 | - } |
|
| 1207 | - // now we got to make sure we add the new DTT_ID to the $saved_dtts array because it is possible there was a new one created for the autosave. |
|
| 1208 | - $saved_dtt = $DTT; |
|
| 1209 | - $success = ! $success ? $success : $DTT; |
|
| 1210 | - // if ANY of these updates fail then we want the appropriate global error message. |
|
| 1211 | - // //todo this is actually sucky we need a better error message but this is what it is for now. |
|
| 1212 | - } |
|
| 1213 | - // no dtts get deleted so we don't do any of that logic here. |
|
| 1214 | - // update tickets next |
|
| 1215 | - $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array(); |
|
| 1216 | - foreach ($data['edit_tickets'] as $row => $tkt) { |
|
| 1217 | - $incoming_date_formats = array('Y-m-d', 'h:i a'); |
|
| 1218 | - $update_prices = false; |
|
| 1219 | - $ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount']) |
|
| 1220 | - ? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0; |
|
| 1221 | - // trim inputs to ensure any excess whitespace is removed. |
|
| 1222 | - $tkt = array_map('trim', $tkt); |
|
| 1223 | - if (empty($tkt['TKT_start_date'])) { |
|
| 1224 | - // let's use now in the set timezone. |
|
| 1225 | - $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone())); |
|
| 1226 | - $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]); |
|
| 1227 | - } |
|
| 1228 | - if (empty($tkt['TKT_end_date'])) { |
|
| 1229 | - // use the start date of the first datetime |
|
| 1230 | - $dtt = $evtobj->first_datetime(); |
|
| 1231 | - $tkt['TKT_end_date'] = $dtt->start_date_and_time( |
|
| 1232 | - $incoming_date_formats[0], |
|
| 1233 | - $incoming_date_formats[1] |
|
| 1234 | - ); |
|
| 1235 | - } |
|
| 1236 | - $TKT_values = array( |
|
| 1237 | - 'TKT_ID' => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null, |
|
| 1238 | - 'TTM_ID' => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0, |
|
| 1239 | - 'TKT_name' => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '', |
|
| 1240 | - 'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '', |
|
| 1241 | - 'TKT_start_date' => $tkt['TKT_start_date'], |
|
| 1242 | - 'TKT_end_date' => $tkt['TKT_end_date'], |
|
| 1243 | - 'TKT_qty' => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'], |
|
| 1244 | - 'TKT_uses' => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'], |
|
| 1245 | - 'TKT_min' => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'], |
|
| 1246 | - 'TKT_max' => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'], |
|
| 1247 | - 'TKT_row' => $row, |
|
| 1248 | - 'TKT_order' => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row, |
|
| 1249 | - 'TKT_price' => $ticket_price, |
|
| 1250 | - ); |
|
| 1251 | - // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well. |
|
| 1252 | - if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) { |
|
| 1253 | - $TKT_values['TKT_ID'] = 0; |
|
| 1254 | - $TKT_values['TKT_is_default'] = 0; |
|
| 1255 | - $TKT_values['TKT_price'] = $ticket_price; |
|
| 1256 | - $update_prices = true; |
|
| 1257 | - } |
|
| 1258 | - // if we have a TKT_ID then we need to get that existing TKT_obj and update it |
|
| 1259 | - // we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified. |
|
| 1260 | - // keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived. |
|
| 1261 | - if (! empty($tkt['TKT_ID'])) { |
|
| 1262 | - $TKT = EE_Registry::instance() |
|
| 1263 | - ->load_model('Ticket', array($evtobj->get_timezone())) |
|
| 1264 | - ->get_one_by_ID($tkt['TKT_ID']); |
|
| 1265 | - if ($TKT instanceof EE_Ticket) { |
|
| 1266 | - $ticket_sold = $TKT->count_related( |
|
| 1267 | - 'Registration', |
|
| 1268 | - array( |
|
| 1269 | - array( |
|
| 1270 | - 'STS_ID' => array( |
|
| 1271 | - 'NOT IN', |
|
| 1272 | - array(EEM_Registration::status_id_incomplete), |
|
| 1273 | - ), |
|
| 1274 | - ), |
|
| 1275 | - ) |
|
| 1276 | - ) > 0 ? true : false; |
|
| 1277 | - // let's just check the total price for the existing ticket and determine if it matches the new total price. if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket. |
|
| 1278 | - $create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price') |
|
| 1279 | - && ! $TKT->get('TKT_deleted'); |
|
| 1280 | - $TKT->set_date_format($incoming_date_formats[0]); |
|
| 1281 | - $TKT->set_time_format($incoming_date_formats[1]); |
|
| 1282 | - // set new values |
|
| 1283 | - foreach ($TKT_values as $field => $value) { |
|
| 1284 | - if ($field == 'TKT_qty') { |
|
| 1285 | - $TKT->set_qty($value); |
|
| 1286 | - } else { |
|
| 1287 | - $TKT->set($field, $value); |
|
| 1288 | - } |
|
| 1289 | - } |
|
| 1290 | - // if $create_new_TKT is false then we can safely update the existing ticket. Otherwise we have to create a new ticket. |
|
| 1291 | - if ($create_new_TKT) { |
|
| 1292 | - // archive the old ticket first |
|
| 1293 | - $TKT->set('TKT_deleted', 1); |
|
| 1294 | - $TKT->save(); |
|
| 1295 | - // make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine. |
|
| 1296 | - $saved_tickets[ $TKT->ID() ] = $TKT; |
|
| 1297 | - // create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it. |
|
| 1298 | - $TKT = clone $TKT; |
|
| 1299 | - $TKT->set('TKT_ID', 0); |
|
| 1300 | - $TKT->set('TKT_deleted', 0); |
|
| 1301 | - $TKT->set('TKT_price', $ticket_price); |
|
| 1302 | - $TKT->set('TKT_sold', 0); |
|
| 1303 | - // now we need to make sure that $new prices are created as well and attached to new ticket. |
|
| 1304 | - $update_prices = true; |
|
| 1305 | - } |
|
| 1306 | - // make sure price is set if it hasn't been already |
|
| 1307 | - $TKT->set('TKT_price', $ticket_price); |
|
| 1308 | - } |
|
| 1309 | - } else { |
|
| 1310 | - // no TKT_id so a new TKT |
|
| 1311 | - $TKT_values['TKT_price'] = $ticket_price; |
|
| 1312 | - $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false); |
|
| 1313 | - if ($TKT instanceof EE_Ticket) { |
|
| 1314 | - // need to reset values to properly account for the date formats |
|
| 1315 | - $TKT->set_date_format($incoming_date_formats[0]); |
|
| 1316 | - $TKT->set_time_format($incoming_date_formats[1]); |
|
| 1317 | - $TKT->set_timezone($evtobj->get_timezone()); |
|
| 1318 | - // set new values |
|
| 1319 | - foreach ($TKT_values as $field => $value) { |
|
| 1320 | - if ($field == 'TKT_qty') { |
|
| 1321 | - $TKT->set_qty($value); |
|
| 1322 | - } else { |
|
| 1323 | - $TKT->set($field, $value); |
|
| 1324 | - } |
|
| 1325 | - } |
|
| 1326 | - $update_prices = true; |
|
| 1327 | - } |
|
| 1328 | - } |
|
| 1329 | - // cap ticket qty by datetime reg limits |
|
| 1330 | - $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit'))); |
|
| 1331 | - // update ticket. |
|
| 1332 | - $TKT->save(); |
|
| 1333 | - // before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date. |
|
| 1334 | - if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) { |
|
| 1335 | - $TKT->set('TKT_end_date', $TKT->get('TKT_start_date')); |
|
| 1336 | - $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days'); |
|
| 1337 | - $TKT->save(); |
|
| 1338 | - } |
|
| 1339 | - // initially let's add the ticket to the dtt |
|
| 1340 | - $saved_dtt->_add_relation_to($TKT, 'Ticket'); |
|
| 1341 | - $saved_tickets[ $TKT->ID() ] = $TKT; |
|
| 1342 | - // add prices to ticket |
|
| 1343 | - $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices); |
|
| 1344 | - } |
|
| 1345 | - // however now we need to handle permanently deleting tickets via the ui. Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold. However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db. |
|
| 1346 | - $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets; |
|
| 1347 | - $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets)); |
|
| 1348 | - foreach ($tickets_removed as $id) { |
|
| 1349 | - $id = absint($id); |
|
| 1350 | - // get the ticket for this id |
|
| 1351 | - $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id); |
|
| 1352 | - // need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold) |
|
| 1353 | - $dtts = $tkt_to_remove->get_many_related('Datetime'); |
|
| 1354 | - foreach ($dtts as $dtt) { |
|
| 1355 | - $tkt_to_remove->_remove_relation_to($dtt, 'Datetime'); |
|
| 1356 | - } |
|
| 1357 | - // need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived)) |
|
| 1358 | - $tkt_to_remove->delete_related_permanently('Price'); |
|
| 1359 | - // finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships) |
|
| 1360 | - $tkt_to_remove->delete_permanently(); |
|
| 1361 | - } |
|
| 1362 | - return array($saved_dtt, $saved_tickets); |
|
| 1363 | - } |
|
| 1364 | - |
|
| 1365 | - |
|
| 1366 | - /** |
|
| 1367 | - * This attaches a list of given prices to a ticket. |
|
| 1368 | - * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change |
|
| 1369 | - * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old |
|
| 1370 | - * price info and prices are automatically "archived" via the ticket. |
|
| 1371 | - * |
|
| 1372 | - * @access private |
|
| 1373 | - * @param array $prices Array of prices from the form. |
|
| 1374 | - * @param EE_Ticket $ticket EE_Ticket object that prices are being attached to. |
|
| 1375 | - * @param bool $new_prices Whether attach existing incoming prices or create new ones. |
|
| 1376 | - * @return void |
|
| 1377 | - */ |
|
| 1378 | - private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false) |
|
| 1379 | - { |
|
| 1380 | - foreach ($prices as $row => $prc) { |
|
| 1381 | - $PRC_values = array( |
|
| 1382 | - 'PRC_ID' => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null, |
|
| 1383 | - 'PRT_ID' => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null, |
|
| 1384 | - 'PRC_amount' => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0, |
|
| 1385 | - 'PRC_name' => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '', |
|
| 1386 | - 'PRC_desc' => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '', |
|
| 1387 | - 'PRC_is_default' => 0, // make sure prices are NOT set as default from this context |
|
| 1388 | - 'PRC_order' => $row, |
|
| 1389 | - ); |
|
| 1390 | - if ($new_prices || empty($PRC_values['PRC_ID'])) { |
|
| 1391 | - $PRC_values['PRC_ID'] = 0; |
|
| 1392 | - $PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false); |
|
| 1393 | - } else { |
|
| 1394 | - $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']); |
|
| 1395 | - // update this price with new values |
|
| 1396 | - foreach ($PRC_values as $field => $newprc) { |
|
| 1397 | - $PRC->set($field, $newprc); |
|
| 1398 | - } |
|
| 1399 | - $PRC->save(); |
|
| 1400 | - } |
|
| 1401 | - $ticket->_add_relation_to($PRC, 'Price'); |
|
| 1402 | - } |
|
| 1403 | - } |
|
| 1404 | - |
|
| 1405 | - |
|
| 1406 | - /** |
|
| 1407 | - * Add in our autosave ajax handlers |
|
| 1408 | - * |
|
| 1409 | - */ |
|
| 1410 | - protected function _ee_autosave_create_new() |
|
| 1411 | - { |
|
| 1412 | - } |
|
| 1413 | - |
|
| 1414 | - |
|
| 1415 | - /** |
|
| 1416 | - * More autosave handlers. |
|
| 1417 | - */ |
|
| 1418 | - protected function _ee_autosave_edit() |
|
| 1419 | - { |
|
| 1420 | - return; // TEMPORARILY EXITING CAUSE THIS IS A TODO |
|
| 1421 | - } |
|
| 1422 | - |
|
| 1423 | - |
|
| 1424 | - /** |
|
| 1425 | - * _generate_publish_box_extra_content |
|
| 1426 | - */ |
|
| 1427 | - private function _generate_publish_box_extra_content() |
|
| 1428 | - { |
|
| 1429 | - // load formatter helper |
|
| 1430 | - // args for getting related registrations |
|
| 1431 | - $approved_query_args = array( |
|
| 1432 | - array( |
|
| 1433 | - 'REG_deleted' => 0, |
|
| 1434 | - 'STS_ID' => EEM_Registration::status_id_approved, |
|
| 1435 | - ), |
|
| 1436 | - ); |
|
| 1437 | - $not_approved_query_args = array( |
|
| 1438 | - array( |
|
| 1439 | - 'REG_deleted' => 0, |
|
| 1440 | - 'STS_ID' => EEM_Registration::status_id_not_approved, |
|
| 1441 | - ), |
|
| 1442 | - ); |
|
| 1443 | - $pending_payment_query_args = array( |
|
| 1444 | - array( |
|
| 1445 | - 'REG_deleted' => 0, |
|
| 1446 | - 'STS_ID' => EEM_Registration::status_id_pending_payment, |
|
| 1447 | - ), |
|
| 1448 | - ); |
|
| 1449 | - // publish box |
|
| 1450 | - $publish_box_extra_args = array( |
|
| 1451 | - 'view_approved_reg_url' => add_query_arg( |
|
| 1452 | - array( |
|
| 1453 | - 'action' => 'default', |
|
| 1454 | - 'event_id' => $this->_cpt_model_obj->ID(), |
|
| 1455 | - '_reg_status' => EEM_Registration::status_id_approved, |
|
| 1456 | - ), |
|
| 1457 | - REG_ADMIN_URL |
|
| 1458 | - ), |
|
| 1459 | - 'view_not_approved_reg_url' => add_query_arg( |
|
| 1460 | - array( |
|
| 1461 | - 'action' => 'default', |
|
| 1462 | - 'event_id' => $this->_cpt_model_obj->ID(), |
|
| 1463 | - '_reg_status' => EEM_Registration::status_id_not_approved, |
|
| 1464 | - ), |
|
| 1465 | - REG_ADMIN_URL |
|
| 1466 | - ), |
|
| 1467 | - 'view_pending_payment_reg_url' => add_query_arg( |
|
| 1468 | - array( |
|
| 1469 | - 'action' => 'default', |
|
| 1470 | - 'event_id' => $this->_cpt_model_obj->ID(), |
|
| 1471 | - '_reg_status' => EEM_Registration::status_id_pending_payment, |
|
| 1472 | - ), |
|
| 1473 | - REG_ADMIN_URL |
|
| 1474 | - ), |
|
| 1475 | - 'approved_regs' => $this->_cpt_model_obj->count_related( |
|
| 1476 | - 'Registration', |
|
| 1477 | - $approved_query_args |
|
| 1478 | - ), |
|
| 1479 | - 'not_approved_regs' => $this->_cpt_model_obj->count_related( |
|
| 1480 | - 'Registration', |
|
| 1481 | - $not_approved_query_args |
|
| 1482 | - ), |
|
| 1483 | - 'pending_payment_regs' => $this->_cpt_model_obj->count_related( |
|
| 1484 | - 'Registration', |
|
| 1485 | - $pending_payment_query_args |
|
| 1486 | - ), |
|
| 1487 | - 'misc_pub_section_class' => apply_filters( |
|
| 1488 | - 'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class', |
|
| 1489 | - 'misc-pub-section' |
|
| 1490 | - ), |
|
| 1491 | - ); |
|
| 1492 | - ob_start(); |
|
| 1493 | - do_action( |
|
| 1494 | - 'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add', |
|
| 1495 | - $this->_cpt_model_obj |
|
| 1496 | - ); |
|
| 1497 | - $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean(); |
|
| 1498 | - // load template |
|
| 1499 | - EEH_Template::display_template( |
|
| 1500 | - EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php', |
|
| 1501 | - $publish_box_extra_args |
|
| 1502 | - ); |
|
| 1503 | - } |
|
| 1504 | - |
|
| 1505 | - |
|
| 1506 | - /** |
|
| 1507 | - * @return EE_Event |
|
| 1508 | - */ |
|
| 1509 | - public function get_event_object() |
|
| 1510 | - { |
|
| 1511 | - return $this->_cpt_model_obj; |
|
| 1512 | - } |
|
| 1513 | - |
|
| 1514 | - |
|
| 1515 | - |
|
| 1516 | - |
|
| 1517 | - /** METABOXES * */ |
|
| 1518 | - /** |
|
| 1519 | - * _register_event_editor_meta_boxes |
|
| 1520 | - * add all metaboxes related to the event_editor |
|
| 1521 | - * |
|
| 1522 | - * @return void |
|
| 1523 | - */ |
|
| 1524 | - protected function _register_event_editor_meta_boxes() |
|
| 1525 | - { |
|
| 1526 | - $this->verify_cpt_object(); |
|
| 1527 | - add_meta_box( |
|
| 1528 | - 'espresso_event_editor_tickets', |
|
| 1529 | - esc_html__('Event Datetime & Ticket', 'event_espresso'), |
|
| 1530 | - array($this, 'ticket_metabox'), |
|
| 1531 | - $this->page_slug, |
|
| 1532 | - 'normal', |
|
| 1533 | - 'high' |
|
| 1534 | - ); |
|
| 1535 | - add_meta_box( |
|
| 1536 | - 'espresso_event_editor_event_options', |
|
| 1537 | - esc_html__('Event Registration Options', 'event_espresso'), |
|
| 1538 | - array($this, 'registration_options_meta_box'), |
|
| 1539 | - $this->page_slug, |
|
| 1540 | - 'side', |
|
| 1541 | - 'default' |
|
| 1542 | - ); |
|
| 1543 | - // NOTE: if you're looking for other metaboxes in here, |
|
| 1544 | - // where a metabox has a related management page in the admin |
|
| 1545 | - // you will find it setup in the related management page's "_Hooks" file. |
|
| 1546 | - // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php". |
|
| 1547 | - } |
|
| 1548 | - |
|
| 1549 | - |
|
| 1550 | - /** |
|
| 1551 | - * @throws DomainException |
|
| 1552 | - * @throws EE_Error |
|
| 1553 | - */ |
|
| 1554 | - public function ticket_metabox() |
|
| 1555 | - { |
|
| 1556 | - $existing_datetime_ids = $existing_ticket_ids = array(); |
|
| 1557 | - // defaults for template args |
|
| 1558 | - $template_args = array( |
|
| 1559 | - 'existing_datetime_ids' => '', |
|
| 1560 | - 'event_datetime_help_link' => '', |
|
| 1561 | - 'ticket_options_help_link' => '', |
|
| 1562 | - 'time' => null, |
|
| 1563 | - 'ticket_rows' => '', |
|
| 1564 | - 'existing_ticket_ids' => '', |
|
| 1565 | - 'total_ticket_rows' => 1, |
|
| 1566 | - 'ticket_js_structure' => '', |
|
| 1567 | - 'trash_icon' => 'ee-lock-icon', |
|
| 1568 | - 'disabled' => '', |
|
| 1569 | - ); |
|
| 1570 | - $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null; |
|
| 1571 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1572 | - /** |
|
| 1573 | - * 1. Start with retrieving Datetimes |
|
| 1574 | - * 2. Fore each datetime get related tickets |
|
| 1575 | - * 3. For each ticket get related prices |
|
| 1576 | - */ |
|
| 1577 | - $times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id); |
|
| 1578 | - /** @type EE_Datetime $first_datetime */ |
|
| 1579 | - $first_datetime = reset($times); |
|
| 1580 | - // do we get related tickets? |
|
| 1581 | - if ($first_datetime instanceof EE_Datetime |
|
| 1582 | - && $first_datetime->ID() !== 0 |
|
| 1583 | - ) { |
|
| 1584 | - $existing_datetime_ids[] = $first_datetime->get('DTT_ID'); |
|
| 1585 | - $template_args['time'] = $first_datetime; |
|
| 1586 | - $related_tickets = $first_datetime->tickets( |
|
| 1587 | - array( |
|
| 1588 | - array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)), |
|
| 1589 | - 'default_where_conditions' => 'none', |
|
| 1590 | - ) |
|
| 1591 | - ); |
|
| 1592 | - if (! empty($related_tickets)) { |
|
| 1593 | - $template_args['total_ticket_rows'] = count($related_tickets); |
|
| 1594 | - $row = 0; |
|
| 1595 | - foreach ($related_tickets as $ticket) { |
|
| 1596 | - $existing_ticket_ids[] = $ticket->get('TKT_ID'); |
|
| 1597 | - $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row); |
|
| 1598 | - $row++; |
|
| 1599 | - } |
|
| 1600 | - } else { |
|
| 1601 | - $template_args['total_ticket_rows'] = 1; |
|
| 1602 | - /** @type EE_Ticket $ticket */ |
|
| 1603 | - $ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object(); |
|
| 1604 | - $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket); |
|
| 1605 | - } |
|
| 1606 | - } else { |
|
| 1607 | - $template_args['time'] = $times[0]; |
|
| 1608 | - /** @type EE_Ticket $ticket */ |
|
| 1609 | - $ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets(); |
|
| 1610 | - $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]); |
|
| 1611 | - // NOTE: we're just sending the first default row |
|
| 1612 | - // (decaf can't manage default tickets so this should be sufficient); |
|
| 1613 | - } |
|
| 1614 | - $template_args['event_datetime_help_link'] = $this->_get_help_tab_link( |
|
| 1615 | - 'event_editor_event_datetimes_help_tab' |
|
| 1616 | - ); |
|
| 1617 | - $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info'); |
|
| 1618 | - $template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids); |
|
| 1619 | - $template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids); |
|
| 1620 | - $template_args['ticket_js_structure'] = $this->_get_ticket_row( |
|
| 1621 | - EE_Registry::instance()->load_model('Ticket')->create_default_object(), |
|
| 1622 | - true |
|
| 1623 | - ); |
|
| 1624 | - $template = apply_filters( |
|
| 1625 | - 'FHEE__Events_Admin_Page__ticket_metabox__template', |
|
| 1626 | - EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php' |
|
| 1627 | - ); |
|
| 1628 | - EEH_Template::display_template($template, $template_args); |
|
| 1629 | - } |
|
| 1630 | - |
|
| 1631 | - |
|
| 1632 | - /** |
|
| 1633 | - * Setup an individual ticket form for the decaf event editor page |
|
| 1634 | - * |
|
| 1635 | - * @access private |
|
| 1636 | - * @param EE_Ticket $ticket the ticket object |
|
| 1637 | - * @param boolean $skeleton whether we're generating a skeleton for js manipulation |
|
| 1638 | - * @param int $row |
|
| 1639 | - * @return string generated html for the ticket row. |
|
| 1640 | - */ |
|
| 1641 | - private function _get_ticket_row($ticket, $skeleton = false, $row = 0) |
|
| 1642 | - { |
|
| 1643 | - $template_args = array( |
|
| 1644 | - 'tkt_status_class' => ' tkt-status-' . $ticket->ticket_status(), |
|
| 1645 | - 'tkt_archive_class' => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived' |
|
| 1646 | - : '', |
|
| 1647 | - 'ticketrow' => $skeleton ? 'TICKETNUM' : $row, |
|
| 1648 | - 'TKT_ID' => $ticket->get('TKT_ID'), |
|
| 1649 | - 'TKT_name' => $ticket->get('TKT_name'), |
|
| 1650 | - 'TKT_start_date' => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'), |
|
| 1651 | - 'TKT_end_date' => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'), |
|
| 1652 | - 'TKT_is_default' => $ticket->get('TKT_is_default'), |
|
| 1653 | - 'TKT_qty' => $ticket->get_pretty('TKT_qty', 'input'), |
|
| 1654 | - 'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets', |
|
| 1655 | - 'TKT_sold' => $skeleton ? 0 : $ticket->get('TKT_sold'), |
|
| 1656 | - 'trash_icon' => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted'))) |
|
| 1657 | - && (! empty($ticket) && $ticket->get('TKT_sold') === 0) |
|
| 1658 | - ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon', |
|
| 1659 | - 'disabled' => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? '' |
|
| 1660 | - : ' disabled=disabled', |
|
| 1661 | - ); |
|
| 1662 | - $price = $ticket->ID() !== 0 |
|
| 1663 | - ? $ticket->get_first_related('Price', array('default_where_conditions' => 'none')) |
|
| 1664 | - : EE_Registry::instance()->load_model('Price')->create_default_object(); |
|
| 1665 | - $price_args = array( |
|
| 1666 | - 'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign, |
|
| 1667 | - 'PRC_amount' => $price->get('PRC_amount'), |
|
| 1668 | - 'PRT_ID' => $price->get('PRT_ID'), |
|
| 1669 | - 'PRC_ID' => $price->get('PRC_ID'), |
|
| 1670 | - 'PRC_is_default' => $price->get('PRC_is_default'), |
|
| 1671 | - ); |
|
| 1672 | - // make sure we have default start and end dates if skeleton |
|
| 1673 | - // handle rows that should NOT be empty |
|
| 1674 | - if (empty($template_args['TKT_start_date'])) { |
|
| 1675 | - // if empty then the start date will be now. |
|
| 1676 | - $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp')); |
|
| 1677 | - } |
|
| 1678 | - if (empty($template_args['TKT_end_date'])) { |
|
| 1679 | - // get the earliest datetime (if present); |
|
| 1680 | - $earliest_dtt = $this->_cpt_model_obj->ID() > 0 |
|
| 1681 | - ? $this->_cpt_model_obj->get_first_related( |
|
| 1682 | - 'Datetime', |
|
| 1683 | - array('order_by' => array('DTT_EVT_start' => 'ASC')) |
|
| 1684 | - ) |
|
| 1685 | - : null; |
|
| 1686 | - if (! empty($earliest_dtt)) { |
|
| 1687 | - $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a'); |
|
| 1688 | - } else { |
|
| 1689 | - $template_args['TKT_end_date'] = date( |
|
| 1690 | - 'Y-m-d h:i a', |
|
| 1691 | - mktime(0, 0, 0, date("m"), date("d") + 7, date("Y")) |
|
| 1692 | - ); |
|
| 1693 | - } |
|
| 1694 | - } |
|
| 1695 | - $template_args = array_merge($template_args, $price_args); |
|
| 1696 | - $template = apply_filters( |
|
| 1697 | - 'FHEE__Events_Admin_Page__get_ticket_row__template', |
|
| 1698 | - EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php', |
|
| 1699 | - $ticket |
|
| 1700 | - ); |
|
| 1701 | - return EEH_Template::display_template($template, $template_args, true); |
|
| 1702 | - } |
|
| 1703 | - |
|
| 1704 | - |
|
| 1705 | - /** |
|
| 1706 | - * @throws DomainException |
|
| 1707 | - */ |
|
| 1708 | - public function registration_options_meta_box() |
|
| 1709 | - { |
|
| 1710 | - $yes_no_values = array( |
|
| 1711 | - array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')), |
|
| 1712 | - array('id' => false, 'text' => esc_html__('No', 'event_espresso')), |
|
| 1713 | - ); |
|
| 1714 | - $default_reg_status_values = EEM_Registration::reg_status_array( |
|
| 1715 | - array( |
|
| 1716 | - EEM_Registration::status_id_cancelled, |
|
| 1717 | - EEM_Registration::status_id_declined, |
|
| 1718 | - EEM_Registration::status_id_incomplete, |
|
| 1719 | - ), |
|
| 1720 | - true |
|
| 1721 | - ); |
|
| 1722 | - // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active()); |
|
| 1723 | - $template_args['_event'] = $this->_cpt_model_obj; |
|
| 1724 | - $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false); |
|
| 1725 | - $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit(); |
|
| 1726 | - $template_args['default_registration_status'] = EEH_Form_Fields::select_input( |
|
| 1727 | - 'default_reg_status', |
|
| 1728 | - $default_reg_status_values, |
|
| 1729 | - $this->_cpt_model_obj->default_registration_status() |
|
| 1730 | - ); |
|
| 1731 | - $template_args['display_description'] = EEH_Form_Fields::select_input( |
|
| 1732 | - 'display_desc', |
|
| 1733 | - $yes_no_values, |
|
| 1734 | - $this->_cpt_model_obj->display_description() |
|
| 1735 | - ); |
|
| 1736 | - $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input( |
|
| 1737 | - 'display_ticket_selector', |
|
| 1738 | - $yes_no_values, |
|
| 1739 | - $this->_cpt_model_obj->display_ticket_selector(), |
|
| 1740 | - '', |
|
| 1741 | - '', |
|
| 1742 | - false |
|
| 1743 | - ); |
|
| 1744 | - $template_args['additional_registration_options'] = apply_filters( |
|
| 1745 | - 'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options', |
|
| 1746 | - '', |
|
| 1747 | - $template_args, |
|
| 1748 | - $yes_no_values, |
|
| 1749 | - $default_reg_status_values |
|
| 1750 | - ); |
|
| 1751 | - EEH_Template::display_template( |
|
| 1752 | - EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php', |
|
| 1753 | - $template_args |
|
| 1754 | - ); |
|
| 1755 | - } |
|
| 1756 | - |
|
| 1757 | - |
|
| 1758 | - /** |
|
| 1759 | - * _get_events() |
|
| 1760 | - * This method simply returns all the events (for the given _view and paging) |
|
| 1761 | - * |
|
| 1762 | - * @access public |
|
| 1763 | - * @param int $per_page count of items per page (20 default); |
|
| 1764 | - * @param int $current_page what is the current page being viewed. |
|
| 1765 | - * @param bool $count if TRUE then we just return a count of ALL events matching the given _view. |
|
| 1766 | - * If FALSE then we return an array of event objects |
|
| 1767 | - * that match the given _view and paging parameters. |
|
| 1768 | - * @return array an array of event objects. |
|
| 1769 | - */ |
|
| 1770 | - public function get_events($per_page = 10, $current_page = 1, $count = false) |
|
| 1771 | - { |
|
| 1772 | - $EEME = $this->_event_model(); |
|
| 1773 | - $offset = ($current_page - 1) * $per_page; |
|
| 1774 | - $limit = $count ? null : $offset . ',' . $per_page; |
|
| 1775 | - $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID'; |
|
| 1776 | - $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC"; |
|
| 1777 | - if (isset($this->_req_data['month_range'])) { |
|
| 1778 | - $pieces = explode(' ', $this->_req_data['month_range'], 3); |
|
| 1779 | - // simulate the FIRST day of the month, that fixes issues for months like February |
|
| 1780 | - // where PHP doesn't know what to assume for date. |
|
| 1781 | - // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437 |
|
| 1782 | - $month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : ''; |
|
| 1783 | - $year_r = ! empty($pieces[1]) ? $pieces[1] : ''; |
|
| 1784 | - } |
|
| 1785 | - $where = array(); |
|
| 1786 | - $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null; |
|
| 1787 | - // determine what post_status our condition will have for the query. |
|
| 1788 | - switch ($status) { |
|
| 1789 | - case 'month': |
|
| 1790 | - case 'today': |
|
| 1791 | - case null: |
|
| 1792 | - case 'all': |
|
| 1793 | - break; |
|
| 1794 | - case 'draft': |
|
| 1795 | - $where['status'] = array('IN', array('draft', 'auto-draft')); |
|
| 1796 | - break; |
|
| 1797 | - default: |
|
| 1798 | - $where['status'] = $status; |
|
| 1799 | - } |
|
| 1800 | - // categories? |
|
| 1801 | - $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0 |
|
| 1802 | - ? $this->_req_data['EVT_CAT'] : null; |
|
| 1803 | - if (! empty($category)) { |
|
| 1804 | - $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY; |
|
| 1805 | - $where['Term_Taxonomy.term_id'] = $category; |
|
| 1806 | - } |
|
| 1807 | - // date where conditions |
|
| 1808 | - $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start'); |
|
| 1809 | - if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') { |
|
| 1810 | - $DateTime = new DateTime( |
|
| 1811 | - $year_r . '-' . $month_r . '-01 00:00:00', |
|
| 1812 | - new DateTimeZone(EEM_Datetime::instance()->get_timezone()) |
|
| 1813 | - ); |
|
| 1814 | - $start = $DateTime->format(implode(' ', $start_formats)); |
|
| 1815 | - $end = $DateTime->setDate( |
|
| 1816 | - $year_r, |
|
| 1817 | - $month_r, |
|
| 1818 | - $DateTime |
|
| 1819 | - ->format('t') |
|
| 1820 | - )->setTime(23, 59, 59) |
|
| 1821 | - ->format(implode(' ', $start_formats)); |
|
| 1822 | - $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end)); |
|
| 1823 | - } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') { |
|
| 1824 | - $DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone())); |
|
| 1825 | - $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats)); |
|
| 1826 | - $end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats)); |
|
| 1827 | - $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end)); |
|
| 1828 | - } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') { |
|
| 1829 | - $now = date('Y-m-01'); |
|
| 1830 | - $DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone())); |
|
| 1831 | - $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats)); |
|
| 1832 | - $end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t')) |
|
| 1833 | - ->setTime(23, 59, 59) |
|
| 1834 | - ->format(implode(' ', $start_formats)); |
|
| 1835 | - $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end)); |
|
| 1836 | - } |
|
| 1837 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) { |
|
| 1838 | - $where['EVT_wp_user'] = get_current_user_id(); |
|
| 1839 | - } else { |
|
| 1840 | - if (! isset($where['status'])) { |
|
| 1841 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) { |
|
| 1842 | - $where['OR'] = array( |
|
| 1843 | - 'status*restrict_private' => array('!=', 'private'), |
|
| 1844 | - 'AND' => array( |
|
| 1845 | - 'status*inclusive' => array('=', 'private'), |
|
| 1846 | - 'EVT_wp_user' => get_current_user_id(), |
|
| 1847 | - ), |
|
| 1848 | - ); |
|
| 1849 | - } |
|
| 1850 | - } |
|
| 1851 | - } |
|
| 1852 | - if (isset($this->_req_data['EVT_wp_user'])) { |
|
| 1853 | - if ($this->_req_data['EVT_wp_user'] != get_current_user_id() |
|
| 1854 | - && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events') |
|
| 1855 | - ) { |
|
| 1856 | - $where['EVT_wp_user'] = $this->_req_data['EVT_wp_user']; |
|
| 1857 | - } |
|
| 1858 | - } |
|
| 1859 | - // search query handling |
|
| 1860 | - if (isset($this->_req_data['s'])) { |
|
| 1861 | - $search_string = '%' . $this->_req_data['s'] . '%'; |
|
| 1862 | - $where['OR'] = array( |
|
| 1863 | - 'EVT_name' => array('LIKE', $search_string), |
|
| 1864 | - 'EVT_desc' => array('LIKE', $search_string), |
|
| 1865 | - 'EVT_short_desc' => array('LIKE', $search_string), |
|
| 1866 | - ); |
|
| 1867 | - } |
|
| 1868 | - // filter events by venue. |
|
| 1869 | - if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) { |
|
| 1870 | - $where['Venue.VNU_ID'] = absint($this->_req_data['venue']); |
|
| 1871 | - } |
|
| 1872 | - $where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data); |
|
| 1873 | - $query_params = apply_filters( |
|
| 1874 | - 'FHEE__Events_Admin_Page__get_events__query_params', |
|
| 1875 | - array( |
|
| 1876 | - $where, |
|
| 1877 | - 'limit' => $limit, |
|
| 1878 | - 'order_by' => $orderby, |
|
| 1879 | - 'order' => $order, |
|
| 1880 | - 'group_by' => 'EVT_ID', |
|
| 1881 | - ), |
|
| 1882 | - $this->_req_data |
|
| 1883 | - ); |
|
| 1884 | - // let's first check if we have special requests coming in. |
|
| 1885 | - if (isset($this->_req_data['active_status'])) { |
|
| 1886 | - switch ($this->_req_data['active_status']) { |
|
| 1887 | - case 'upcoming': |
|
| 1888 | - return $EEME->get_upcoming_events($query_params, $count); |
|
| 1889 | - break; |
|
| 1890 | - case 'expired': |
|
| 1891 | - return $EEME->get_expired_events($query_params, $count); |
|
| 1892 | - break; |
|
| 1893 | - case 'active': |
|
| 1894 | - return $EEME->get_active_events($query_params, $count); |
|
| 1895 | - break; |
|
| 1896 | - case 'inactive': |
|
| 1897 | - return $EEME->get_inactive_events($query_params, $count); |
|
| 1898 | - break; |
|
| 1899 | - } |
|
| 1900 | - } |
|
| 1901 | - |
|
| 1902 | - $events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params); |
|
| 1903 | - return $events; |
|
| 1904 | - } |
|
| 1905 | - |
|
| 1906 | - |
|
| 1907 | - /** |
|
| 1908 | - * handling for WordPress CPT actions (trash, restore, delete) |
|
| 1909 | - * |
|
| 1910 | - * @param string $post_id |
|
| 1911 | - */ |
|
| 1912 | - public function trash_cpt_item($post_id) |
|
| 1913 | - { |
|
| 1914 | - $this->_req_data['EVT_ID'] = $post_id; |
|
| 1915 | - $this->_trash_or_restore_event('trash', false); |
|
| 1916 | - } |
|
| 1917 | - |
|
| 1918 | - |
|
| 1919 | - /** |
|
| 1920 | - * @param string $post_id |
|
| 1921 | - */ |
|
| 1922 | - public function restore_cpt_item($post_id) |
|
| 1923 | - { |
|
| 1924 | - $this->_req_data['EVT_ID'] = $post_id; |
|
| 1925 | - $this->_trash_or_restore_event('draft', false); |
|
| 1926 | - } |
|
| 1927 | - |
|
| 1928 | - |
|
| 1929 | - /** |
|
| 1930 | - * @param string $post_id |
|
| 1931 | - */ |
|
| 1932 | - public function delete_cpt_item($post_id) |
|
| 1933 | - { |
|
| 1934 | - throw new EE_Error(esc_html__('Please contact Event Espresso support with the details of the steps taken to produce this error.', 'event_espresso')); |
|
| 1935 | - $this->_req_data['EVT_ID'] = $post_id; |
|
| 1936 | - $this->_delete_event(); |
|
| 1937 | - } |
|
| 1938 | - |
|
| 1939 | - |
|
| 1940 | - /** |
|
| 1941 | - * _trash_or_restore_event |
|
| 1942 | - * |
|
| 1943 | - * @access protected |
|
| 1944 | - * @param string $event_status |
|
| 1945 | - * @param bool $redirect_after |
|
| 1946 | - */ |
|
| 1947 | - protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true) |
|
| 1948 | - { |
|
| 1949 | - // determine the event id and set to array. |
|
| 1950 | - $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false; |
|
| 1951 | - // loop thru events |
|
| 1952 | - if ($EVT_ID) { |
|
| 1953 | - // clean status |
|
| 1954 | - $event_status = sanitize_key($event_status); |
|
| 1955 | - // grab status |
|
| 1956 | - if (! empty($event_status)) { |
|
| 1957 | - $success = $this->_change_event_status($EVT_ID, $event_status); |
|
| 1958 | - } else { |
|
| 1959 | - $success = false; |
|
| 1960 | - $msg = esc_html__( |
|
| 1961 | - 'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.', |
|
| 1962 | - 'event_espresso' |
|
| 1963 | - ); |
|
| 1964 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 1965 | - } |
|
| 1966 | - } else { |
|
| 1967 | - $success = false; |
|
| 1968 | - $msg = esc_html__( |
|
| 1969 | - 'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.', |
|
| 1970 | - 'event_espresso' |
|
| 1971 | - ); |
|
| 1972 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 1973 | - } |
|
| 1974 | - $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash'; |
|
| 1975 | - if ($redirect_after) { |
|
| 1976 | - $this->_redirect_after_action($success, 'Event', $action, array('action' => 'default')); |
|
| 1977 | - } |
|
| 1978 | - } |
|
| 1979 | - |
|
| 1980 | - |
|
| 1981 | - /** |
|
| 1982 | - * _trash_or_restore_events |
|
| 1983 | - * |
|
| 1984 | - * @access protected |
|
| 1985 | - * @param string $event_status |
|
| 1986 | - * @return void |
|
| 1987 | - */ |
|
| 1988 | - protected function _trash_or_restore_events($event_status = 'trash') |
|
| 1989 | - { |
|
| 1990 | - // clean status |
|
| 1991 | - $event_status = sanitize_key($event_status); |
|
| 1992 | - // grab status |
|
| 1993 | - if (! empty($event_status)) { |
|
| 1994 | - $success = true; |
|
| 1995 | - // determine the event id and set to array. |
|
| 1996 | - $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array(); |
|
| 1997 | - // loop thru events |
|
| 1998 | - foreach ($EVT_IDs as $EVT_ID) { |
|
| 1999 | - if ($EVT_ID = absint($EVT_ID)) { |
|
| 2000 | - $results = $this->_change_event_status($EVT_ID, $event_status); |
|
| 2001 | - $success = $results !== false ? $success : false; |
|
| 2002 | - } else { |
|
| 2003 | - $msg = sprintf( |
|
| 2004 | - esc_html__( |
|
| 2005 | - 'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.', |
|
| 2006 | - 'event_espresso' |
|
| 2007 | - ), |
|
| 2008 | - $EVT_ID |
|
| 2009 | - ); |
|
| 2010 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2011 | - $success = false; |
|
| 2012 | - } |
|
| 2013 | - } |
|
| 2014 | - } else { |
|
| 2015 | - $success = false; |
|
| 2016 | - $msg = esc_html__( |
|
| 2017 | - 'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.', |
|
| 2018 | - 'event_espresso' |
|
| 2019 | - ); |
|
| 2020 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2021 | - } |
|
| 2022 | - // in order to force a pluralized result message we need to send back a success status greater than 1 |
|
| 2023 | - $success = $success ? 2 : false; |
|
| 2024 | - $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash'; |
|
| 2025 | - $this->_redirect_after_action($success, 'Events', $action, array('action' => 'default')); |
|
| 2026 | - } |
|
| 2027 | - |
|
| 2028 | - |
|
| 2029 | - /** |
|
| 2030 | - * _trash_or_restore_events |
|
| 2031 | - * |
|
| 2032 | - * @access private |
|
| 2033 | - * @param int $EVT_ID |
|
| 2034 | - * @param string $event_status |
|
| 2035 | - * @return bool |
|
| 2036 | - */ |
|
| 2037 | - private function _change_event_status($EVT_ID = 0, $event_status = '') |
|
| 2038 | - { |
|
| 2039 | - // grab event id |
|
| 2040 | - if (! $EVT_ID) { |
|
| 2041 | - $msg = esc_html__( |
|
| 2042 | - 'An error occurred. No Event ID or an invalid Event ID was received.', |
|
| 2043 | - 'event_espresso' |
|
| 2044 | - ); |
|
| 2045 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2046 | - return false; |
|
| 2047 | - } |
|
| 2048 | - $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID); |
|
| 2049 | - // clean status |
|
| 2050 | - $event_status = sanitize_key($event_status); |
|
| 2051 | - // grab status |
|
| 2052 | - if (empty($event_status)) { |
|
| 2053 | - $msg = esc_html__( |
|
| 2054 | - 'An error occurred. No Event Status or an invalid Event Status was received.', |
|
| 2055 | - 'event_espresso' |
|
| 2056 | - ); |
|
| 2057 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2058 | - return false; |
|
| 2059 | - } |
|
| 2060 | - // was event trashed or restored ? |
|
| 2061 | - switch ($event_status) { |
|
| 2062 | - case 'draft': |
|
| 2063 | - $action = 'restored from the trash'; |
|
| 2064 | - $hook = 'AHEE_event_restored_from_trash'; |
|
| 2065 | - break; |
|
| 2066 | - case 'trash': |
|
| 2067 | - $action = 'moved to the trash'; |
|
| 2068 | - $hook = 'AHEE_event_moved_to_trash'; |
|
| 2069 | - break; |
|
| 2070 | - default: |
|
| 2071 | - $action = 'updated'; |
|
| 2072 | - $hook = false; |
|
| 2073 | - } |
|
| 2074 | - // use class to change status |
|
| 2075 | - $this->_cpt_model_obj->set_status($event_status); |
|
| 2076 | - $success = $this->_cpt_model_obj->save(); |
|
| 2077 | - if ($success === false) { |
|
| 2078 | - $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action); |
|
| 2079 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2080 | - return false; |
|
| 2081 | - } |
|
| 2082 | - if ($hook) { |
|
| 2083 | - do_action($hook); |
|
| 2084 | - } |
|
| 2085 | - return true; |
|
| 2086 | - } |
|
| 2087 | - |
|
| 2088 | - |
|
| 2089 | - /** |
|
| 2090 | - * _delete_event |
|
| 2091 | - * |
|
| 2092 | - * @access protected |
|
| 2093 | - * @param bool $redirect_after |
|
| 2094 | - */ |
|
| 2095 | - protected function _delete_event() |
|
| 2096 | - { |
|
| 2097 | - $this->generateDeletionPreview(isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : array()); |
|
| 2098 | - } |
|
| 2099 | - |
|
| 2100 | - /** |
|
| 2101 | - * Gets the tree traversal batch persister. |
|
| 2102 | - * @since $VID:$ |
|
| 2103 | - * @return NodeGroupDao |
|
| 2104 | - * @throws InvalidArgumentException |
|
| 2105 | - * @throws InvalidDataTypeException |
|
| 2106 | - * @throws InvalidInterfaceException |
|
| 2107 | - */ |
|
| 2108 | - protected function getModelObjNodeGroupPersister() |
|
| 2109 | - { |
|
| 2110 | - if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) { |
|
| 2111 | - $this->model_obj_node_group_persister = $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao'); |
|
| 2112 | - } |
|
| 2113 | - return $this->model_obj_node_group_persister; |
|
| 2114 | - } |
|
| 2115 | - |
|
| 2116 | - /** |
|
| 2117 | - * _delete_events |
|
| 2118 | - * |
|
| 2119 | - * @access protected |
|
| 2120 | - * @return void |
|
| 2121 | - */ |
|
| 2122 | - protected function _delete_events() |
|
| 2123 | - { |
|
| 2124 | - $this->generateDeletionPreview(isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array()); |
|
| 2125 | - } |
|
| 2126 | - |
|
| 2127 | - protected function generateDeletionPreview($event_ids) |
|
| 2128 | - { |
|
| 2129 | - $event_ids = (array) $event_ids; |
|
| 2130 | - // Set a code we can use to reference this deletion task in the batch jobs and preview page. |
|
| 2131 | - $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode(); |
|
| 2132 | - $return_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 2133 | - [ |
|
| 2134 | - 'action' => 'preview_deletion', |
|
| 2135 | - 'deletion_job_code' => $deletion_job_code, |
|
| 2136 | - ], |
|
| 2137 | - $this->_admin_base_url |
|
| 2138 | - ); |
|
| 2139 | - $event_ids = array_map( |
|
| 2140 | - 'intval', |
|
| 2141 | - $event_ids |
|
| 2142 | - ); |
|
| 2143 | - |
|
| 2144 | - EEH_URL::safeRedirectAndExit( |
|
| 2145 | - EE_Admin_Page::add_query_args_and_nonce( |
|
| 2146 | - array( |
|
| 2147 | - 'page' => 'espresso_batch', |
|
| 2148 | - 'batch' => EED_Batch::batch_job, |
|
| 2149 | - 'EVT_IDs' => $event_ids, |
|
| 2150 | - 'deletion_job_code' => $deletion_job_code, |
|
| 2151 | - 'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'), |
|
| 2152 | - 'return_url' => urlencode($return_url), |
|
| 2153 | - ), |
|
| 2154 | - admin_url() |
|
| 2155 | - ) |
|
| 2156 | - ); |
|
| 2157 | - } |
|
| 2158 | - |
|
| 2159 | - /** |
|
| 2160 | - * Checks for a POST submission |
|
| 2161 | - * @since $VID:$ |
|
| 2162 | - */ |
|
| 2163 | - protected function confirmDeletion() |
|
| 2164 | - { |
|
| 2165 | - $deletion_redirect_logic = $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'); |
|
| 2166 | - $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url()); |
|
| 2167 | - } |
|
| 2168 | - |
|
| 2169 | - /** |
|
| 2170 | - * A page for users to preview what exactly will be deleted, and confirm they want to delete it. |
|
| 2171 | - * @since $VID:$ |
|
| 2172 | - * @throws EE_Error |
|
| 2173 | - */ |
|
| 2174 | - protected function previewDeletion() |
|
| 2175 | - { |
|
| 2176 | - $preview_deletion_logic = $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'); |
|
| 2177 | - $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url())); |
|
| 2178 | - $this->display_admin_page_with_no_sidebar(); |
|
| 2179 | - } |
|
| 2180 | - |
|
| 2181 | - /** |
|
| 2182 | - * get total number of events |
|
| 2183 | - * |
|
| 2184 | - * @access public |
|
| 2185 | - * @return int |
|
| 2186 | - */ |
|
| 2187 | - public function total_events() |
|
| 2188 | - { |
|
| 2189 | - $count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true); |
|
| 2190 | - return $count; |
|
| 2191 | - } |
|
| 2192 | - |
|
| 2193 | - |
|
| 2194 | - /** |
|
| 2195 | - * get total number of draft events |
|
| 2196 | - * |
|
| 2197 | - * @access public |
|
| 2198 | - * @return int |
|
| 2199 | - */ |
|
| 2200 | - public function total_events_draft() |
|
| 2201 | - { |
|
| 2202 | - $where = array( |
|
| 2203 | - 'status' => array('IN', array('draft', 'auto-draft')), |
|
| 2204 | - ); |
|
| 2205 | - $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true); |
|
| 2206 | - return $count; |
|
| 2207 | - } |
|
| 2208 | - |
|
| 2209 | - |
|
| 2210 | - /** |
|
| 2211 | - * get total number of trashed events |
|
| 2212 | - * |
|
| 2213 | - * @access public |
|
| 2214 | - * @return int |
|
| 2215 | - */ |
|
| 2216 | - public function total_trashed_events() |
|
| 2217 | - { |
|
| 2218 | - $where = array( |
|
| 2219 | - 'status' => 'trash', |
|
| 2220 | - ); |
|
| 2221 | - $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true); |
|
| 2222 | - return $count; |
|
| 2223 | - } |
|
| 2224 | - |
|
| 2225 | - |
|
| 2226 | - /** |
|
| 2227 | - * _default_event_settings |
|
| 2228 | - * This generates the Default Settings Tab |
|
| 2229 | - * |
|
| 2230 | - * @return void |
|
| 2231 | - * @throws EE_Error |
|
| 2232 | - */ |
|
| 2233 | - protected function _default_event_settings() |
|
| 2234 | - { |
|
| 2235 | - $this->_set_add_edit_form_tags('update_default_event_settings'); |
|
| 2236 | - $this->_set_publish_post_box_vars(null, false, false, null, false); |
|
| 2237 | - $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html(); |
|
| 2238 | - $this->display_admin_page_with_sidebar(); |
|
| 2239 | - } |
|
| 2240 | - |
|
| 2241 | - |
|
| 2242 | - /** |
|
| 2243 | - * Return the form for event settings. |
|
| 2244 | - * |
|
| 2245 | - * @return EE_Form_Section_Proper |
|
| 2246 | - * @throws EE_Error |
|
| 2247 | - */ |
|
| 2248 | - protected function _default_event_settings_form() |
|
| 2249 | - { |
|
| 2250 | - $registration_config = EE_Registry::instance()->CFG->registration; |
|
| 2251 | - $registration_stati_for_selection = EEM_Registration::reg_status_array( |
|
| 2252 | - // exclude |
|
| 2253 | - array( |
|
| 2254 | - EEM_Registration::status_id_cancelled, |
|
| 2255 | - EEM_Registration::status_id_declined, |
|
| 2256 | - EEM_Registration::status_id_incomplete, |
|
| 2257 | - EEM_Registration::status_id_wait_list, |
|
| 2258 | - ), |
|
| 2259 | - true |
|
| 2260 | - ); |
|
| 2261 | - return new EE_Form_Section_Proper( |
|
| 2262 | - array( |
|
| 2263 | - 'name' => 'update_default_event_settings', |
|
| 2264 | - 'html_id' => 'update_default_event_settings', |
|
| 2265 | - 'html_class' => 'form-table', |
|
| 2266 | - 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
| 2267 | - 'subsections' => apply_filters( |
|
| 2268 | - 'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections', |
|
| 2269 | - array( |
|
| 2270 | - 'default_reg_status' => new EE_Select_Input( |
|
| 2271 | - $registration_stati_for_selection, |
|
| 2272 | - array( |
|
| 2273 | - 'default' => isset($registration_config->default_STS_ID) |
|
| 2274 | - && array_key_exists( |
|
| 2275 | - $registration_config->default_STS_ID, |
|
| 2276 | - $registration_stati_for_selection |
|
| 2277 | - ) |
|
| 2278 | - ? sanitize_text_field($registration_config->default_STS_ID) |
|
| 2279 | - : EEM_Registration::status_id_pending_payment, |
|
| 2280 | - 'html_label_text' => esc_html__('Default Registration Status', 'event_espresso') |
|
| 2281 | - . EEH_Template::get_help_tab_link( |
|
| 2282 | - 'default_settings_status_help_tab' |
|
| 2283 | - ), |
|
| 2284 | - 'html_help_text' => esc_html__( |
|
| 2285 | - 'This setting allows you to preselect what the default registration status setting is when creating an event. Note that changing this setting does NOT retroactively apply it to existing events.', |
|
| 2286 | - 'event_espresso' |
|
| 2287 | - ), |
|
| 2288 | - ) |
|
| 2289 | - ), |
|
| 2290 | - 'default_max_tickets' => new EE_Integer_Input( |
|
| 2291 | - array( |
|
| 2292 | - 'default' => isset($registration_config->default_maximum_number_of_tickets) |
|
| 2293 | - ? $registration_config->default_maximum_number_of_tickets |
|
| 2294 | - : EEM_Event::get_default_additional_limit(), |
|
| 2295 | - 'html_label_text' => esc_html__( |
|
| 2296 | - 'Default Maximum Tickets Allowed Per Order:', |
|
| 2297 | - 'event_espresso' |
|
| 2298 | - ) |
|
| 2299 | - . EEH_Template::get_help_tab_link( |
|
| 2300 | - 'default_maximum_tickets_help_tab"' |
|
| 2301 | - ), |
|
| 2302 | - 'html_help_text' => esc_html__( |
|
| 2303 | - 'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.', |
|
| 2304 | - 'event_espresso' |
|
| 2305 | - ), |
|
| 2306 | - ) |
|
| 2307 | - ), |
|
| 2308 | - ) |
|
| 2309 | - ), |
|
| 2310 | - ) |
|
| 2311 | - ); |
|
| 2312 | - } |
|
| 2313 | - |
|
| 2314 | - |
|
| 2315 | - /** |
|
| 2316 | - * _update_default_event_settings |
|
| 2317 | - * |
|
| 2318 | - * @access protected |
|
| 2319 | - * @return void |
|
| 2320 | - * @throws EE_Error |
|
| 2321 | - */ |
|
| 2322 | - protected function _update_default_event_settings() |
|
| 2323 | - { |
|
| 2324 | - $registration_config = EE_Registry::instance()->CFG->registration; |
|
| 2325 | - $form = $this->_default_event_settings_form(); |
|
| 2326 | - if ($form->was_submitted()) { |
|
| 2327 | - $form->receive_form_submission(); |
|
| 2328 | - if ($form->is_valid()) { |
|
| 2329 | - $valid_data = $form->valid_data(); |
|
| 2330 | - if (isset($valid_data['default_reg_status'])) { |
|
| 2331 | - $registration_config->default_STS_ID = $valid_data['default_reg_status']; |
|
| 2332 | - } |
|
| 2333 | - if (isset($valid_data['default_max_tickets'])) { |
|
| 2334 | - $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets']; |
|
| 2335 | - } |
|
| 2336 | - // update because data was valid! |
|
| 2337 | - EE_Registry::instance()->CFG->update_espresso_config(); |
|
| 2338 | - EE_Error::overwrite_success(); |
|
| 2339 | - EE_Error::add_success( |
|
| 2340 | - __('Default Event Settings were updated', 'event_espresso') |
|
| 2341 | - ); |
|
| 2342 | - } |
|
| 2343 | - } |
|
| 2344 | - $this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true); |
|
| 2345 | - } |
|
| 2346 | - |
|
| 2347 | - |
|
| 2348 | - /************* Templates *************/ |
|
| 2349 | - protected function _template_settings() |
|
| 2350 | - { |
|
| 2351 | - $this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso'); |
|
| 2352 | - $this->_template_args['preview_img'] = '<img src="' |
|
| 2353 | - . EVENTS_ASSETS_URL |
|
| 2354 | - . '/images/' |
|
| 2355 | - . 'caffeinated_template_features.jpg" alt="' |
|
| 2356 | - . esc_attr__('Template Settings Preview screenshot', 'event_espresso') |
|
| 2357 | - . '" />'; |
|
| 2358 | - $this->_template_args['preview_text'] = '<strong>' |
|
| 2359 | - . esc_html__( |
|
| 2360 | - 'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.', |
|
| 2361 | - 'event_espresso' |
|
| 2362 | - ) . '</strong>'; |
|
| 2363 | - $this->display_admin_caf_preview_page('template_settings_tab'); |
|
| 2364 | - } |
|
| 2365 | - |
|
| 2366 | - |
|
| 2367 | - /** Event Category Stuff **/ |
|
| 2368 | - /** |
|
| 2369 | - * set the _category property with the category object for the loaded page. |
|
| 2370 | - * |
|
| 2371 | - * @access private |
|
| 2372 | - * @return void |
|
| 2373 | - */ |
|
| 2374 | - private function _set_category_object() |
|
| 2375 | - { |
|
| 2376 | - if (isset($this->_category->id) && ! empty($this->_category->id)) { |
|
| 2377 | - return; |
|
| 2378 | - } //already have the category object so get out. |
|
| 2379 | - // set default category object |
|
| 2380 | - $this->_set_empty_category_object(); |
|
| 2381 | - // only set if we've got an id |
|
| 2382 | - if (! isset($this->_req_data['EVT_CAT_ID'])) { |
|
| 2383 | - return; |
|
| 2384 | - } |
|
| 2385 | - $category_id = absint($this->_req_data['EVT_CAT_ID']); |
|
| 2386 | - $term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
|
| 2387 | - if (! empty($term)) { |
|
| 2388 | - $this->_category->category_name = $term->name; |
|
| 2389 | - $this->_category->category_identifier = $term->slug; |
|
| 2390 | - $this->_category->category_desc = $term->description; |
|
| 2391 | - $this->_category->id = $term->term_id; |
|
| 2392 | - $this->_category->parent = $term->parent; |
|
| 2393 | - } |
|
| 2394 | - } |
|
| 2395 | - |
|
| 2396 | - |
|
| 2397 | - /** |
|
| 2398 | - * Clears out category properties. |
|
| 2399 | - */ |
|
| 2400 | - private function _set_empty_category_object() |
|
| 2401 | - { |
|
| 2402 | - $this->_category = new stdClass(); |
|
| 2403 | - $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = ''; |
|
| 2404 | - $this->_category->id = $this->_category->parent = 0; |
|
| 2405 | - } |
|
| 2406 | - |
|
| 2407 | - |
|
| 2408 | - /** |
|
| 2409 | - * @throws EE_Error |
|
| 2410 | - */ |
|
| 2411 | - protected function _category_list_table() |
|
| 2412 | - { |
|
| 2413 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2414 | - $this->_search_btn_label = esc_html__('Categories', 'event_espresso'); |
|
| 2415 | - $this->_admin_page_title .= ' ' . $this->get_action_link_or_button( |
|
| 2416 | - 'add_category', |
|
| 2417 | - 'add_category', |
|
| 2418 | - array(), |
|
| 2419 | - 'add-new-h2' |
|
| 2420 | - ); |
|
| 2421 | - $this->display_admin_list_table_page_with_sidebar(); |
|
| 2422 | - } |
|
| 2423 | - |
|
| 2424 | - |
|
| 2425 | - /** |
|
| 2426 | - * Output category details view. |
|
| 2427 | - */ |
|
| 2428 | - protected function _category_details($view) |
|
| 2429 | - { |
|
| 2430 | - // load formatter helper |
|
| 2431 | - // load field generator helper |
|
| 2432 | - $route = $view == 'edit' ? 'update_category' : 'insert_category'; |
|
| 2433 | - $this->_set_add_edit_form_tags($route); |
|
| 2434 | - $this->_set_category_object(); |
|
| 2435 | - $id = ! empty($this->_category->id) ? $this->_category->id : ''; |
|
| 2436 | - $delete_action = 'delete_category'; |
|
| 2437 | - // custom redirect |
|
| 2438 | - $redirect = EE_Admin_Page::add_query_args_and_nonce( |
|
| 2439 | - array('action' => 'category_list'), |
|
| 2440 | - $this->_admin_base_url |
|
| 2441 | - ); |
|
| 2442 | - $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect); |
|
| 2443 | - // take care of contents |
|
| 2444 | - $this->_template_args['admin_page_content'] = $this->_category_details_content(); |
|
| 2445 | - $this->display_admin_page_with_sidebar(); |
|
| 2446 | - } |
|
| 2447 | - |
|
| 2448 | - |
|
| 2449 | - /** |
|
| 2450 | - * Output category details content. |
|
| 2451 | - */ |
|
| 2452 | - protected function _category_details_content() |
|
| 2453 | - { |
|
| 2454 | - $editor_args['category_desc'] = array( |
|
| 2455 | - 'type' => 'wp_editor', |
|
| 2456 | - 'value' => EEH_Formatter::admin_format_content($this->_category->category_desc), |
|
| 2457 | - 'class' => 'my_editor_custom', |
|
| 2458 | - 'wpeditor_args' => array('media_buttons' => false), |
|
| 2459 | - ); |
|
| 2460 | - $_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array'); |
|
| 2461 | - $all_terms = get_terms( |
|
| 2462 | - array(EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY), |
|
| 2463 | - array('hide_empty' => 0, 'exclude' => array($this->_category->id)) |
|
| 2464 | - ); |
|
| 2465 | - // setup category select for term parents. |
|
| 2466 | - $category_select_values[] = array( |
|
| 2467 | - 'text' => esc_html__('No Parent', 'event_espresso'), |
|
| 2468 | - 'id' => 0, |
|
| 2469 | - ); |
|
| 2470 | - foreach ($all_terms as $term) { |
|
| 2471 | - $category_select_values[] = array( |
|
| 2472 | - 'text' => $term->name, |
|
| 2473 | - 'id' => $term->term_id, |
|
| 2474 | - ); |
|
| 2475 | - } |
|
| 2476 | - $category_select = EEH_Form_Fields::select_input( |
|
| 2477 | - 'category_parent', |
|
| 2478 | - $category_select_values, |
|
| 2479 | - $this->_category->parent |
|
| 2480 | - ); |
|
| 2481 | - $template_args = array( |
|
| 2482 | - 'category' => $this->_category, |
|
| 2483 | - 'category_select' => $category_select, |
|
| 2484 | - 'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'), |
|
| 2485 | - 'category_desc_editor' => $_wp_editor['category_desc']['field'], |
|
| 2486 | - 'disable' => '', |
|
| 2487 | - 'disabled_message' => false, |
|
| 2488 | - ); |
|
| 2489 | - $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php'; |
|
| 2490 | - return EEH_Template::display_template($template, $template_args, true); |
|
| 2491 | - } |
|
| 2492 | - |
|
| 2493 | - |
|
| 2494 | - /** |
|
| 2495 | - * Handles deleting categories. |
|
| 2496 | - */ |
|
| 2497 | - protected function _delete_categories() |
|
| 2498 | - { |
|
| 2499 | - $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID'] |
|
| 2500 | - : (array) $this->_req_data['category_id']; |
|
| 2501 | - foreach ($cat_ids as $cat_id) { |
|
| 2502 | - $this->_delete_category($cat_id); |
|
| 2503 | - } |
|
| 2504 | - // doesn't matter what page we're coming from... we're going to the same place after delete. |
|
| 2505 | - $query_args = array( |
|
| 2506 | - 'action' => 'category_list', |
|
| 2507 | - ); |
|
| 2508 | - $this->_redirect_after_action(0, '', '', $query_args); |
|
| 2509 | - } |
|
| 2510 | - |
|
| 2511 | - |
|
| 2512 | - /** |
|
| 2513 | - * Handles deleting specific category. |
|
| 2514 | - * |
|
| 2515 | - * @param int $cat_id |
|
| 2516 | - */ |
|
| 2517 | - protected function _delete_category($cat_id) |
|
| 2518 | - { |
|
| 2519 | - $cat_id = absint($cat_id); |
|
| 2520 | - wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
|
| 2521 | - } |
|
| 2522 | - |
|
| 2523 | - |
|
| 2524 | - /** |
|
| 2525 | - * Handles triggering the update or insertion of a new category. |
|
| 2526 | - * |
|
| 2527 | - * @param bool $new_category true means we're triggering the insert of a new category. |
|
| 2528 | - */ |
|
| 2529 | - protected function _insert_or_update_category($new_category) |
|
| 2530 | - { |
|
| 2531 | - $cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true); |
|
| 2532 | - $success = 0; // we already have a success message so lets not send another. |
|
| 2533 | - if ($cat_id) { |
|
| 2534 | - $query_args = array( |
|
| 2535 | - 'action' => 'edit_category', |
|
| 2536 | - 'EVT_CAT_ID' => $cat_id, |
|
| 2537 | - ); |
|
| 2538 | - } else { |
|
| 2539 | - $query_args = array('action' => 'add_category'); |
|
| 2540 | - } |
|
| 2541 | - $this->_redirect_after_action($success, '', '', $query_args, true); |
|
| 2542 | - } |
|
| 2543 | - |
|
| 2544 | - |
|
| 2545 | - /** |
|
| 2546 | - * Inserts or updates category |
|
| 2547 | - * |
|
| 2548 | - * @param bool $update (true indicates we're updating a category). |
|
| 2549 | - * @return bool|mixed|string |
|
| 2550 | - */ |
|
| 2551 | - private function _insert_category($update = false) |
|
| 2552 | - { |
|
| 2553 | - $cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : ''; |
|
| 2554 | - $category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : ''; |
|
| 2555 | - $category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : ''; |
|
| 2556 | - $category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0; |
|
| 2557 | - if (empty($category_name)) { |
|
| 2558 | - $msg = esc_html__('You must add a name for the category.', 'event_espresso'); |
|
| 2559 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2560 | - return false; |
|
| 2561 | - } |
|
| 2562 | - $term_args = array( |
|
| 2563 | - 'name' => $category_name, |
|
| 2564 | - 'description' => $category_desc, |
|
| 2565 | - 'parent' => $category_parent, |
|
| 2566 | - ); |
|
| 2567 | - // was the category_identifier input disabled? |
|
| 2568 | - if (isset($this->_req_data['category_identifier'])) { |
|
| 2569 | - $term_args['slug'] = $this->_req_data['category_identifier']; |
|
| 2570 | - } |
|
| 2571 | - $insert_ids = $update |
|
| 2572 | - ? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args) |
|
| 2573 | - : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args); |
|
| 2574 | - if (! is_array($insert_ids)) { |
|
| 2575 | - $msg = esc_html__( |
|
| 2576 | - 'An error occurred and the category has not been saved to the database.', |
|
| 2577 | - 'event_espresso' |
|
| 2578 | - ); |
|
| 2579 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2580 | - } else { |
|
| 2581 | - $cat_id = $insert_ids['term_id']; |
|
| 2582 | - $msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name); |
|
| 2583 | - EE_Error::add_success($msg); |
|
| 2584 | - } |
|
| 2585 | - return $cat_id; |
|
| 2586 | - } |
|
| 2587 | - |
|
| 2588 | - |
|
| 2589 | - /** |
|
| 2590 | - * Gets categories or count of categories matching the arguments in the request. |
|
| 2591 | - * |
|
| 2592 | - * @param int $per_page |
|
| 2593 | - * @param int $current_page |
|
| 2594 | - * @param bool $count |
|
| 2595 | - * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int |
|
| 2596 | - */ |
|
| 2597 | - public function get_categories($per_page = 10, $current_page = 1, $count = false) |
|
| 2598 | - { |
|
| 2599 | - // testing term stuff |
|
| 2600 | - $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id'; |
|
| 2601 | - $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC'; |
|
| 2602 | - $limit = ($current_page - 1) * $per_page; |
|
| 2603 | - $where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
|
| 2604 | - if (isset($this->_req_data['s'])) { |
|
| 2605 | - $sstr = '%' . $this->_req_data['s'] . '%'; |
|
| 2606 | - $where['OR'] = array( |
|
| 2607 | - 'Term.name' => array('LIKE', $sstr), |
|
| 2608 | - 'description' => array('LIKE', $sstr), |
|
| 2609 | - ); |
|
| 2610 | - } |
|
| 2611 | - $query_params = array( |
|
| 2612 | - $where, |
|
| 2613 | - 'order_by' => array($orderby => $order), |
|
| 2614 | - 'limit' => $limit . ',' . $per_page, |
|
| 2615 | - 'force_join' => array('Term'), |
|
| 2616 | - ); |
|
| 2617 | - $categories = $count |
|
| 2618 | - ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id') |
|
| 2619 | - : EEM_Term_Taxonomy::instance()->get_all($query_params); |
|
| 2620 | - return $categories; |
|
| 2621 | - } |
|
| 2622 | - |
|
| 2623 | - /* end category stuff */ |
|
| 2624 | - /**************/ |
|
| 2625 | - |
|
| 2626 | - |
|
| 2627 | - /** |
|
| 2628 | - * Callback for the `ee_save_timezone_setting` ajax action. |
|
| 2629 | - * |
|
| 2630 | - * @throws EE_Error |
|
| 2631 | - */ |
|
| 2632 | - public function save_timezonestring_setting() |
|
| 2633 | - { |
|
| 2634 | - $timezone_string = isset($this->_req_data['timezone_selected']) |
|
| 2635 | - ? $this->_req_data['timezone_selected'] |
|
| 2636 | - : ''; |
|
| 2637 | - if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) { |
|
| 2638 | - EE_Error::add_error( |
|
| 2639 | - esc_html__('An invalid timezone string submitted.', 'event_espresso'), |
|
| 2640 | - __FILE__, |
|
| 2641 | - __FUNCTION__, |
|
| 2642 | - __LINE__ |
|
| 2643 | - ); |
|
| 2644 | - $this->_template_args['error'] = true; |
|
| 2645 | - $this->_return_json(); |
|
| 2646 | - } |
|
| 2647 | - |
|
| 2648 | - update_option('timezone_string', $timezone_string); |
|
| 2649 | - EE_Error::add_success( |
|
| 2650 | - esc_html__('Your timezone string was updated.', 'event_espresso') |
|
| 2651 | - ); |
|
| 2652 | - $this->_template_args['success'] = true; |
|
| 2653 | - $this->_return_json(true, array('action' => 'create_new')); |
|
| 2654 | - } |
|
| 22 | + /** |
|
| 23 | + * This will hold the event object for event_details screen. |
|
| 24 | + * |
|
| 25 | + * @access protected |
|
| 26 | + * @var EE_Event $_event |
|
| 27 | + */ |
|
| 28 | + protected $_event; |
|
| 29 | + |
|
| 30 | + |
|
| 31 | + /** |
|
| 32 | + * This will hold the category object for category_details screen. |
|
| 33 | + * |
|
| 34 | + * @var stdClass $_category |
|
| 35 | + */ |
|
| 36 | + protected $_category; |
|
| 37 | + |
|
| 38 | + |
|
| 39 | + /** |
|
| 40 | + * This will hold the event model instance |
|
| 41 | + * |
|
| 42 | + * @var EEM_Event $_event_model |
|
| 43 | + */ |
|
| 44 | + protected $_event_model; |
|
| 45 | + |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * @var EE_Event |
|
| 49 | + */ |
|
| 50 | + protected $_cpt_model_obj = false; |
|
| 51 | + |
|
| 52 | + |
|
| 53 | + /** |
|
| 54 | + * @var NodeGroupDao |
|
| 55 | + */ |
|
| 56 | + protected $model_obj_node_group_persister; |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * Initialize page props for this admin page group. |
|
| 60 | + */ |
|
| 61 | + protected function _init_page_props() |
|
| 62 | + { |
|
| 63 | + $this->page_slug = EVENTS_PG_SLUG; |
|
| 64 | + $this->page_label = EVENTS_LABEL; |
|
| 65 | + $this->_admin_base_url = EVENTS_ADMIN_URL; |
|
| 66 | + $this->_admin_base_path = EVENTS_ADMIN; |
|
| 67 | + $this->_cpt_model_names = array( |
|
| 68 | + 'create_new' => 'EEM_Event', |
|
| 69 | + 'edit' => 'EEM_Event', |
|
| 70 | + ); |
|
| 71 | + $this->_cpt_edit_routes = array( |
|
| 72 | + 'espresso_events' => 'edit', |
|
| 73 | + ); |
|
| 74 | + add_action( |
|
| 75 | + 'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object', |
|
| 76 | + array($this, 'verify_event_edit'), |
|
| 77 | + 10, |
|
| 78 | + 2 |
|
| 79 | + ); |
|
| 80 | + } |
|
| 81 | + |
|
| 82 | + |
|
| 83 | + /** |
|
| 84 | + * Sets the ajax hooks used for this admin page group. |
|
| 85 | + */ |
|
| 86 | + protected function _ajax_hooks() |
|
| 87 | + { |
|
| 88 | + add_action('wp_ajax_ee_save_timezone_setting', array($this, 'save_timezonestring_setting')); |
|
| 89 | + } |
|
| 90 | + |
|
| 91 | + |
|
| 92 | + /** |
|
| 93 | + * Sets the page properties for this admin page group. |
|
| 94 | + */ |
|
| 95 | + protected function _define_page_props() |
|
| 96 | + { |
|
| 97 | + $this->_admin_page_title = EVENTS_LABEL; |
|
| 98 | + $this->_labels = array( |
|
| 99 | + 'buttons' => array( |
|
| 100 | + 'add' => esc_html__('Add New Event', 'event_espresso'), |
|
| 101 | + 'edit' => esc_html__('Edit Event', 'event_espresso'), |
|
| 102 | + 'delete' => esc_html__('Delete Event', 'event_espresso'), |
|
| 103 | + 'add_category' => esc_html__('Add New Category', 'event_espresso'), |
|
| 104 | + 'edit_category' => esc_html__('Edit Category', 'event_espresso'), |
|
| 105 | + 'delete_category' => esc_html__('Delete Category', 'event_espresso'), |
|
| 106 | + ), |
|
| 107 | + 'editor_title' => array( |
|
| 108 | + 'espresso_events' => esc_html__('Enter event title here', 'event_espresso'), |
|
| 109 | + ), |
|
| 110 | + 'publishbox' => array( |
|
| 111 | + 'create_new' => esc_html__('Save New Event', 'event_espresso'), |
|
| 112 | + 'edit' => esc_html__('Update Event', 'event_espresso'), |
|
| 113 | + 'add_category' => esc_html__('Save New Category', 'event_espresso'), |
|
| 114 | + 'edit_category' => esc_html__('Update Category', 'event_espresso'), |
|
| 115 | + 'template_settings' => esc_html__('Update Settings', 'event_espresso'), |
|
| 116 | + ), |
|
| 117 | + ); |
|
| 118 | + } |
|
| 119 | + |
|
| 120 | + |
|
| 121 | + /** |
|
| 122 | + * Sets the page routes property for this admin page group. |
|
| 123 | + */ |
|
| 124 | + protected function _set_page_routes() |
|
| 125 | + { |
|
| 126 | + // load formatter helper |
|
| 127 | + // load field generator helper |
|
| 128 | + // is there a evt_id in the request? |
|
| 129 | + $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID']) |
|
| 130 | + ? $this->_req_data['EVT_ID'] |
|
| 131 | + : 0; |
|
| 132 | + $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id; |
|
| 133 | + $this->_page_routes = array( |
|
| 134 | + 'default' => array( |
|
| 135 | + 'func' => '_events_overview_list_table', |
|
| 136 | + 'capability' => 'ee_read_events', |
|
| 137 | + ), |
|
| 138 | + 'create_new' => array( |
|
| 139 | + 'func' => '_create_new_cpt_item', |
|
| 140 | + 'capability' => 'ee_edit_events', |
|
| 141 | + ), |
|
| 142 | + 'edit' => array( |
|
| 143 | + 'func' => '_edit_cpt_item', |
|
| 144 | + 'capability' => 'ee_edit_event', |
|
| 145 | + 'obj_id' => $evt_id, |
|
| 146 | + ), |
|
| 147 | + 'copy_event' => array( |
|
| 148 | + 'func' => '_copy_events', |
|
| 149 | + 'capability' => 'ee_edit_event', |
|
| 150 | + 'obj_id' => $evt_id, |
|
| 151 | + 'noheader' => true, |
|
| 152 | + ), |
|
| 153 | + 'trash_event' => array( |
|
| 154 | + 'func' => '_trash_or_restore_event', |
|
| 155 | + 'args' => array('event_status' => 'trash'), |
|
| 156 | + 'capability' => 'ee_delete_event', |
|
| 157 | + 'obj_id' => $evt_id, |
|
| 158 | + 'noheader' => true, |
|
| 159 | + ), |
|
| 160 | + 'trash_events' => array( |
|
| 161 | + 'func' => '_trash_or_restore_events', |
|
| 162 | + 'args' => array('event_status' => 'trash'), |
|
| 163 | + 'capability' => 'ee_delete_events', |
|
| 164 | + 'noheader' => true, |
|
| 165 | + ), |
|
| 166 | + 'restore_event' => array( |
|
| 167 | + 'func' => '_trash_or_restore_event', |
|
| 168 | + 'args' => array('event_status' => 'draft'), |
|
| 169 | + 'capability' => 'ee_delete_event', |
|
| 170 | + 'obj_id' => $evt_id, |
|
| 171 | + 'noheader' => true, |
|
| 172 | + ), |
|
| 173 | + 'restore_events' => array( |
|
| 174 | + 'func' => '_trash_or_restore_events', |
|
| 175 | + 'args' => array('event_status' => 'draft'), |
|
| 176 | + 'capability' => 'ee_delete_events', |
|
| 177 | + 'noheader' => true, |
|
| 178 | + ), |
|
| 179 | + 'delete_event' => array( |
|
| 180 | + 'func' => '_delete_event', |
|
| 181 | + 'capability' => 'ee_delete_event', |
|
| 182 | + 'obj_id' => $evt_id, |
|
| 183 | + 'noheader' => true, |
|
| 184 | + ), |
|
| 185 | + 'delete_events' => array( |
|
| 186 | + 'func' => '_delete_events', |
|
| 187 | + 'capability' => 'ee_delete_events', |
|
| 188 | + 'noheader' => true, |
|
| 189 | + ), |
|
| 190 | + 'view_report' => array( |
|
| 191 | + 'func' => '_view_report', |
|
| 192 | + 'capablity' => 'ee_edit_events', |
|
| 193 | + ), |
|
| 194 | + 'default_event_settings' => array( |
|
| 195 | + 'func' => '_default_event_settings', |
|
| 196 | + 'capability' => 'manage_options', |
|
| 197 | + ), |
|
| 198 | + 'update_default_event_settings' => array( |
|
| 199 | + 'func' => '_update_default_event_settings', |
|
| 200 | + 'capability' => 'manage_options', |
|
| 201 | + 'noheader' => true, |
|
| 202 | + ), |
|
| 203 | + 'template_settings' => array( |
|
| 204 | + 'func' => '_template_settings', |
|
| 205 | + 'capability' => 'manage_options', |
|
| 206 | + ), |
|
| 207 | + // event category tab related |
|
| 208 | + 'add_category' => array( |
|
| 209 | + 'func' => '_category_details', |
|
| 210 | + 'capability' => 'ee_edit_event_category', |
|
| 211 | + 'args' => array('add'), |
|
| 212 | + ), |
|
| 213 | + 'edit_category' => array( |
|
| 214 | + 'func' => '_category_details', |
|
| 215 | + 'capability' => 'ee_edit_event_category', |
|
| 216 | + 'args' => array('edit'), |
|
| 217 | + ), |
|
| 218 | + 'delete_categories' => array( |
|
| 219 | + 'func' => '_delete_categories', |
|
| 220 | + 'capability' => 'ee_delete_event_category', |
|
| 221 | + 'noheader' => true, |
|
| 222 | + ), |
|
| 223 | + 'delete_category' => array( |
|
| 224 | + 'func' => '_delete_categories', |
|
| 225 | + 'capability' => 'ee_delete_event_category', |
|
| 226 | + 'noheader' => true, |
|
| 227 | + ), |
|
| 228 | + 'insert_category' => array( |
|
| 229 | + 'func' => '_insert_or_update_category', |
|
| 230 | + 'args' => array('new_category' => true), |
|
| 231 | + 'capability' => 'ee_edit_event_category', |
|
| 232 | + 'noheader' => true, |
|
| 233 | + ), |
|
| 234 | + 'update_category' => array( |
|
| 235 | + 'func' => '_insert_or_update_category', |
|
| 236 | + 'args' => array('new_category' => false), |
|
| 237 | + 'capability' => 'ee_edit_event_category', |
|
| 238 | + 'noheader' => true, |
|
| 239 | + ), |
|
| 240 | + 'category_list' => array( |
|
| 241 | + 'func' => '_category_list_table', |
|
| 242 | + 'capability' => 'ee_manage_event_categories', |
|
| 243 | + ), |
|
| 244 | + 'preview_deletion' => [ |
|
| 245 | + 'func' => 'previewDeletion', |
|
| 246 | + 'capability' => 'ee_delete_events', |
|
| 247 | + ], |
|
| 248 | + 'confirm_deletion' => [ |
|
| 249 | + 'func' => 'confirmDeletion', |
|
| 250 | + 'capability' => 'ee_delete_events', |
|
| 251 | + 'noheader' => true, |
|
| 252 | + ] |
|
| 253 | + ); |
|
| 254 | + } |
|
| 255 | + |
|
| 256 | + |
|
| 257 | + /** |
|
| 258 | + * Set the _page_config property for this admin page group. |
|
| 259 | + */ |
|
| 260 | + protected function _set_page_config() |
|
| 261 | + { |
|
| 262 | + $this->_page_config = array( |
|
| 263 | + 'default' => array( |
|
| 264 | + 'nav' => array( |
|
| 265 | + 'label' => esc_html__('Overview', 'event_espresso'), |
|
| 266 | + 'order' => 10, |
|
| 267 | + ), |
|
| 268 | + 'list_table' => 'Events_Admin_List_Table', |
|
| 269 | + 'help_tabs' => array( |
|
| 270 | + 'events_overview_help_tab' => array( |
|
| 271 | + 'title' => esc_html__('Events Overview', 'event_espresso'), |
|
| 272 | + 'filename' => 'events_overview', |
|
| 273 | + ), |
|
| 274 | + 'events_overview_table_column_headings_help_tab' => array( |
|
| 275 | + 'title' => esc_html__('Events Overview Table Column Headings', 'event_espresso'), |
|
| 276 | + 'filename' => 'events_overview_table_column_headings', |
|
| 277 | + ), |
|
| 278 | + 'events_overview_filters_help_tab' => array( |
|
| 279 | + 'title' => esc_html__('Events Overview Filters', 'event_espresso'), |
|
| 280 | + 'filename' => 'events_overview_filters', |
|
| 281 | + ), |
|
| 282 | + 'events_overview_view_help_tab' => array( |
|
| 283 | + 'title' => esc_html__('Events Overview Views', 'event_espresso'), |
|
| 284 | + 'filename' => 'events_overview_views', |
|
| 285 | + ), |
|
| 286 | + 'events_overview_other_help_tab' => array( |
|
| 287 | + 'title' => esc_html__('Events Overview Other', 'event_espresso'), |
|
| 288 | + 'filename' => 'events_overview_other', |
|
| 289 | + ), |
|
| 290 | + ), |
|
| 291 | + 'help_tour' => array( |
|
| 292 | + 'Event_Overview_Help_Tour', |
|
| 293 | + // 'New_Features_Test_Help_Tour' for testing multiple help tour |
|
| 294 | + ), |
|
| 295 | + 'qtips' => array( |
|
| 296 | + 'EE_Event_List_Table_Tips', |
|
| 297 | + ), |
|
| 298 | + 'require_nonce' => false, |
|
| 299 | + ), |
|
| 300 | + 'create_new' => array( |
|
| 301 | + 'nav' => array( |
|
| 302 | + 'label' => esc_html__('Add Event', 'event_espresso'), |
|
| 303 | + 'order' => 5, |
|
| 304 | + 'persistent' => false, |
|
| 305 | + ), |
|
| 306 | + 'metaboxes' => array('_register_event_editor_meta_boxes'), |
|
| 307 | + 'help_tabs' => array( |
|
| 308 | + 'event_editor_help_tab' => array( |
|
| 309 | + 'title' => esc_html__('Event Editor', 'event_espresso'), |
|
| 310 | + 'filename' => 'event_editor', |
|
| 311 | + ), |
|
| 312 | + 'event_editor_title_richtexteditor_help_tab' => array( |
|
| 313 | + 'title' => esc_html__('Event Title & Rich Text Editor', 'event_espresso'), |
|
| 314 | + 'filename' => 'event_editor_title_richtexteditor', |
|
| 315 | + ), |
|
| 316 | + 'event_editor_venue_details_help_tab' => array( |
|
| 317 | + 'title' => esc_html__('Event Venue Details', 'event_espresso'), |
|
| 318 | + 'filename' => 'event_editor_venue_details', |
|
| 319 | + ), |
|
| 320 | + 'event_editor_event_datetimes_help_tab' => array( |
|
| 321 | + 'title' => esc_html__('Event Datetimes', 'event_espresso'), |
|
| 322 | + 'filename' => 'event_editor_event_datetimes', |
|
| 323 | + ), |
|
| 324 | + 'event_editor_event_tickets_help_tab' => array( |
|
| 325 | + 'title' => esc_html__('Event Tickets', 'event_espresso'), |
|
| 326 | + 'filename' => 'event_editor_event_tickets', |
|
| 327 | + ), |
|
| 328 | + 'event_editor_event_registration_options_help_tab' => array( |
|
| 329 | + 'title' => esc_html__('Event Registration Options', 'event_espresso'), |
|
| 330 | + 'filename' => 'event_editor_event_registration_options', |
|
| 331 | + ), |
|
| 332 | + 'event_editor_tags_categories_help_tab' => array( |
|
| 333 | + 'title' => esc_html__('Event Tags & Categories', 'event_espresso'), |
|
| 334 | + 'filename' => 'event_editor_tags_categories', |
|
| 335 | + ), |
|
| 336 | + 'event_editor_questions_registrants_help_tab' => array( |
|
| 337 | + 'title' => esc_html__('Questions for Registrants', 'event_espresso'), |
|
| 338 | + 'filename' => 'event_editor_questions_registrants', |
|
| 339 | + ), |
|
| 340 | + 'event_editor_save_new_event_help_tab' => array( |
|
| 341 | + 'title' => esc_html__('Save New Event', 'event_espresso'), |
|
| 342 | + 'filename' => 'event_editor_save_new_event', |
|
| 343 | + ), |
|
| 344 | + 'event_editor_other_help_tab' => array( |
|
| 345 | + 'title' => esc_html__('Event Other', 'event_espresso'), |
|
| 346 | + 'filename' => 'event_editor_other', |
|
| 347 | + ), |
|
| 348 | + ), |
|
| 349 | + 'help_tour' => array( |
|
| 350 | + 'Event_Editor_Help_Tour', |
|
| 351 | + ), |
|
| 352 | + 'qtips' => array('EE_Event_Editor_Decaf_Tips'), |
|
| 353 | + 'require_nonce' => false, |
|
| 354 | + ), |
|
| 355 | + 'edit' => array( |
|
| 356 | + 'nav' => array( |
|
| 357 | + 'label' => esc_html__('Edit Event', 'event_espresso'), |
|
| 358 | + 'order' => 5, |
|
| 359 | + 'persistent' => false, |
|
| 360 | + 'url' => isset($this->_req_data['post']) |
|
| 361 | + ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 362 | + array('post' => $this->_req_data['post'], 'action' => 'edit'), |
|
| 363 | + $this->_current_page_view_url |
|
| 364 | + ) |
|
| 365 | + : $this->_admin_base_url, |
|
| 366 | + ), |
|
| 367 | + 'metaboxes' => array('_register_event_editor_meta_boxes'), |
|
| 368 | + 'help_tabs' => array( |
|
| 369 | + 'event_editor_help_tab' => array( |
|
| 370 | + 'title' => esc_html__('Event Editor', 'event_espresso'), |
|
| 371 | + 'filename' => 'event_editor', |
|
| 372 | + ), |
|
| 373 | + 'event_editor_title_richtexteditor_help_tab' => array( |
|
| 374 | + 'title' => esc_html__('Event Title & Rich Text Editor', 'event_espresso'), |
|
| 375 | + 'filename' => 'event_editor_title_richtexteditor', |
|
| 376 | + ), |
|
| 377 | + 'event_editor_venue_details_help_tab' => array( |
|
| 378 | + 'title' => esc_html__('Event Venue Details', 'event_espresso'), |
|
| 379 | + 'filename' => 'event_editor_venue_details', |
|
| 380 | + ), |
|
| 381 | + 'event_editor_event_datetimes_help_tab' => array( |
|
| 382 | + 'title' => esc_html__('Event Datetimes', 'event_espresso'), |
|
| 383 | + 'filename' => 'event_editor_event_datetimes', |
|
| 384 | + ), |
|
| 385 | + 'event_editor_event_tickets_help_tab' => array( |
|
| 386 | + 'title' => esc_html__('Event Tickets', 'event_espresso'), |
|
| 387 | + 'filename' => 'event_editor_event_tickets', |
|
| 388 | + ), |
|
| 389 | + 'event_editor_event_registration_options_help_tab' => array( |
|
| 390 | + 'title' => esc_html__('Event Registration Options', 'event_espresso'), |
|
| 391 | + 'filename' => 'event_editor_event_registration_options', |
|
| 392 | + ), |
|
| 393 | + 'event_editor_tags_categories_help_tab' => array( |
|
| 394 | + 'title' => esc_html__('Event Tags & Categories', 'event_espresso'), |
|
| 395 | + 'filename' => 'event_editor_tags_categories', |
|
| 396 | + ), |
|
| 397 | + 'event_editor_questions_registrants_help_tab' => array( |
|
| 398 | + 'title' => esc_html__('Questions for Registrants', 'event_espresso'), |
|
| 399 | + 'filename' => 'event_editor_questions_registrants', |
|
| 400 | + ), |
|
| 401 | + 'event_editor_save_new_event_help_tab' => array( |
|
| 402 | + 'title' => esc_html__('Save New Event', 'event_espresso'), |
|
| 403 | + 'filename' => 'event_editor_save_new_event', |
|
| 404 | + ), |
|
| 405 | + 'event_editor_other_help_tab' => array( |
|
| 406 | + 'title' => esc_html__('Event Other', 'event_espresso'), |
|
| 407 | + 'filename' => 'event_editor_other', |
|
| 408 | + ), |
|
| 409 | + ), |
|
| 410 | + 'qtips' => array('EE_Event_Editor_Decaf_Tips'), |
|
| 411 | + 'require_nonce' => false, |
|
| 412 | + ), |
|
| 413 | + 'default_event_settings' => array( |
|
| 414 | + 'nav' => array( |
|
| 415 | + 'label' => esc_html__('Default Settings', 'event_espresso'), |
|
| 416 | + 'order' => 40, |
|
| 417 | + ), |
|
| 418 | + 'metaboxes' => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')), |
|
| 419 | + 'labels' => array( |
|
| 420 | + 'publishbox' => esc_html__('Update Settings', 'event_espresso'), |
|
| 421 | + ), |
|
| 422 | + 'help_tabs' => array( |
|
| 423 | + 'default_settings_help_tab' => array( |
|
| 424 | + 'title' => esc_html__('Default Event Settings', 'event_espresso'), |
|
| 425 | + 'filename' => 'events_default_settings', |
|
| 426 | + ), |
|
| 427 | + 'default_settings_status_help_tab' => array( |
|
| 428 | + 'title' => esc_html__('Default Registration Status', 'event_espresso'), |
|
| 429 | + 'filename' => 'events_default_settings_status', |
|
| 430 | + ), |
|
| 431 | + 'default_maximum_tickets_help_tab' => array( |
|
| 432 | + 'title' => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'), |
|
| 433 | + 'filename' => 'events_default_settings_max_tickets', |
|
| 434 | + ), |
|
| 435 | + ), |
|
| 436 | + 'help_tour' => array('Event_Default_Settings_Help_Tour'), |
|
| 437 | + 'require_nonce' => false, |
|
| 438 | + ), |
|
| 439 | + // template settings |
|
| 440 | + 'template_settings' => array( |
|
| 441 | + 'nav' => array( |
|
| 442 | + 'label' => esc_html__('Templates', 'event_espresso'), |
|
| 443 | + 'order' => 30, |
|
| 444 | + ), |
|
| 445 | + 'metaboxes' => $this->_default_espresso_metaboxes, |
|
| 446 | + 'help_tabs' => array( |
|
| 447 | + 'general_settings_templates_help_tab' => array( |
|
| 448 | + 'title' => esc_html__('Templates', 'event_espresso'), |
|
| 449 | + 'filename' => 'general_settings_templates', |
|
| 450 | + ), |
|
| 451 | + ), |
|
| 452 | + 'help_tour' => array('Templates_Help_Tour'), |
|
| 453 | + 'require_nonce' => false, |
|
| 454 | + ), |
|
| 455 | + // event category stuff |
|
| 456 | + 'add_category' => array( |
|
| 457 | + 'nav' => array( |
|
| 458 | + 'label' => esc_html__('Add Category', 'event_espresso'), |
|
| 459 | + 'order' => 15, |
|
| 460 | + 'persistent' => false, |
|
| 461 | + ), |
|
| 462 | + 'help_tabs' => array( |
|
| 463 | + 'add_category_help_tab' => array( |
|
| 464 | + 'title' => esc_html__('Add New Event Category', 'event_espresso'), |
|
| 465 | + 'filename' => 'events_add_category', |
|
| 466 | + ), |
|
| 467 | + ), |
|
| 468 | + 'help_tour' => array('Event_Add_Category_Help_Tour'), |
|
| 469 | + 'metaboxes' => array('_publish_post_box'), |
|
| 470 | + 'require_nonce' => false, |
|
| 471 | + ), |
|
| 472 | + 'edit_category' => array( |
|
| 473 | + 'nav' => array( |
|
| 474 | + 'label' => esc_html__('Edit Category', 'event_espresso'), |
|
| 475 | + 'order' => 15, |
|
| 476 | + 'persistent' => false, |
|
| 477 | + 'url' => isset($this->_req_data['EVT_CAT_ID']) |
|
| 478 | + ? add_query_arg( |
|
| 479 | + array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']), |
|
| 480 | + $this->_current_page_view_url |
|
| 481 | + ) |
|
| 482 | + : $this->_admin_base_url, |
|
| 483 | + ), |
|
| 484 | + 'help_tabs' => array( |
|
| 485 | + 'edit_category_help_tab' => array( |
|
| 486 | + 'title' => esc_html__('Edit Event Category', 'event_espresso'), |
|
| 487 | + 'filename' => 'events_edit_category', |
|
| 488 | + ), |
|
| 489 | + ), |
|
| 490 | + /*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/ |
|
| 491 | + 'metaboxes' => array('_publish_post_box'), |
|
| 492 | + 'require_nonce' => false, |
|
| 493 | + ), |
|
| 494 | + 'category_list' => array( |
|
| 495 | + 'nav' => array( |
|
| 496 | + 'label' => esc_html__('Categories', 'event_espresso'), |
|
| 497 | + 'order' => 20, |
|
| 498 | + ), |
|
| 499 | + 'list_table' => 'Event_Categories_Admin_List_Table', |
|
| 500 | + 'help_tabs' => array( |
|
| 501 | + 'events_categories_help_tab' => array( |
|
| 502 | + 'title' => esc_html__('Event Categories', 'event_espresso'), |
|
| 503 | + 'filename' => 'events_categories', |
|
| 504 | + ), |
|
| 505 | + 'events_categories_table_column_headings_help_tab' => array( |
|
| 506 | + 'title' => esc_html__('Event Categories Table Column Headings', 'event_espresso'), |
|
| 507 | + 'filename' => 'events_categories_table_column_headings', |
|
| 508 | + ), |
|
| 509 | + 'events_categories_view_help_tab' => array( |
|
| 510 | + 'title' => esc_html__('Event Categories Views', 'event_espresso'), |
|
| 511 | + 'filename' => 'events_categories_views', |
|
| 512 | + ), |
|
| 513 | + 'events_categories_other_help_tab' => array( |
|
| 514 | + 'title' => esc_html__('Event Categories Other', 'event_espresso'), |
|
| 515 | + 'filename' => 'events_categories_other', |
|
| 516 | + ), |
|
| 517 | + ), |
|
| 518 | + 'help_tour' => array( |
|
| 519 | + 'Event_Categories_Help_Tour', |
|
| 520 | + ), |
|
| 521 | + 'metaboxes' => $this->_default_espresso_metaboxes, |
|
| 522 | + 'require_nonce' => false, |
|
| 523 | + ), |
|
| 524 | + 'preview_deletion' => array( |
|
| 525 | + 'nav' => array( |
|
| 526 | + 'label' => esc_html__('Preview Deletion', 'event_espresso'), |
|
| 527 | + 'order' => 15, |
|
| 528 | + 'persistent' => false, |
|
| 529 | + ), |
|
| 530 | + 'require_nonce' => false |
|
| 531 | + ) |
|
| 532 | + ); |
|
| 533 | + } |
|
| 534 | + |
|
| 535 | + |
|
| 536 | + /** |
|
| 537 | + * Used to register any global screen options if necessary for every route in this admin page group. |
|
| 538 | + */ |
|
| 539 | + protected function _add_screen_options() |
|
| 540 | + { |
|
| 541 | + } |
|
| 542 | + |
|
| 543 | + |
|
| 544 | + /** |
|
| 545 | + * Implementing the screen options for the 'default' route. |
|
| 546 | + */ |
|
| 547 | + protected function _add_screen_options_default() |
|
| 548 | + { |
|
| 549 | + $this->_per_page_screen_option(); |
|
| 550 | + } |
|
| 551 | + |
|
| 552 | + |
|
| 553 | + /** |
|
| 554 | + * Implementing screen options for the category list route. |
|
| 555 | + */ |
|
| 556 | + protected function _add_screen_options_category_list() |
|
| 557 | + { |
|
| 558 | + $page_title = $this->_admin_page_title; |
|
| 559 | + $this->_admin_page_title = esc_html__('Categories', 'event_espresso'); |
|
| 560 | + $this->_per_page_screen_option(); |
|
| 561 | + $this->_admin_page_title = $page_title; |
|
| 562 | + } |
|
| 563 | + |
|
| 564 | + |
|
| 565 | + /** |
|
| 566 | + * Used to register any global feature pointers for the admin page group. |
|
| 567 | + */ |
|
| 568 | + protected function _add_feature_pointers() |
|
| 569 | + { |
|
| 570 | + } |
|
| 571 | + |
|
| 572 | + |
|
| 573 | + /** |
|
| 574 | + * Registers and enqueues any global scripts and styles for the entire admin page group. |
|
| 575 | + */ |
|
| 576 | + public function load_scripts_styles() |
|
| 577 | + { |
|
| 578 | + wp_register_style( |
|
| 579 | + 'events-admin-css', |
|
| 580 | + EVENTS_ASSETS_URL . 'events-admin-page.css', |
|
| 581 | + array(), |
|
| 582 | + EVENT_ESPRESSO_VERSION |
|
| 583 | + ); |
|
| 584 | + wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION); |
|
| 585 | + wp_enqueue_style('events-admin-css'); |
|
| 586 | + wp_enqueue_style('ee-cat-admin'); |
|
| 587 | + // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details |
|
| 588 | + // registers for all views |
|
| 589 | + // scripts |
|
| 590 | + wp_register_script( |
|
| 591 | + 'event_editor_js', |
|
| 592 | + EVENTS_ASSETS_URL . 'event_editor.js', |
|
| 593 | + array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'), |
|
| 594 | + EVENT_ESPRESSO_VERSION, |
|
| 595 | + true |
|
| 596 | + ); |
|
| 597 | + } |
|
| 598 | + |
|
| 599 | + |
|
| 600 | + /** |
|
| 601 | + * Enqueuing scripts and styles specific to this view |
|
| 602 | + */ |
|
| 603 | + public function load_scripts_styles_create_new() |
|
| 604 | + { |
|
| 605 | + $this->load_scripts_styles_edit(); |
|
| 606 | + } |
|
| 607 | + |
|
| 608 | + |
|
| 609 | + /** |
|
| 610 | + * Enqueuing scripts and styles specific to this view |
|
| 611 | + */ |
|
| 612 | + public function load_scripts_styles_edit() |
|
| 613 | + { |
|
| 614 | + // styles |
|
| 615 | + wp_enqueue_style('espresso-ui-theme'); |
|
| 616 | + wp_register_style( |
|
| 617 | + 'event-editor-css', |
|
| 618 | + EVENTS_ASSETS_URL . 'event-editor.css', |
|
| 619 | + array('ee-admin-css'), |
|
| 620 | + EVENT_ESPRESSO_VERSION |
|
| 621 | + ); |
|
| 622 | + wp_enqueue_style('event-editor-css'); |
|
| 623 | + // scripts |
|
| 624 | + wp_register_script( |
|
| 625 | + 'event-datetime-metabox', |
|
| 626 | + EVENTS_ASSETS_URL . 'event-datetime-metabox.js', |
|
| 627 | + array('event_editor_js', 'ee-datepicker'), |
|
| 628 | + EVENT_ESPRESSO_VERSION |
|
| 629 | + ); |
|
| 630 | + wp_enqueue_script('event-datetime-metabox'); |
|
| 631 | + } |
|
| 632 | + |
|
| 633 | + |
|
| 634 | + /** |
|
| 635 | + * Populating the _views property for the category list table view. |
|
| 636 | + */ |
|
| 637 | + protected function _set_list_table_views_category_list() |
|
| 638 | + { |
|
| 639 | + $this->_views = array( |
|
| 640 | + 'all' => array( |
|
| 641 | + 'slug' => 'all', |
|
| 642 | + 'label' => esc_html__('All', 'event_espresso'), |
|
| 643 | + 'count' => 0, |
|
| 644 | + 'bulk_action' => array( |
|
| 645 | + 'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'), |
|
| 646 | + ), |
|
| 647 | + ), |
|
| 648 | + ); |
|
| 649 | + } |
|
| 650 | + |
|
| 651 | + |
|
| 652 | + /** |
|
| 653 | + * For adding anything that fires on the admin_init hook for any route within this admin page group. |
|
| 654 | + */ |
|
| 655 | + public function admin_init() |
|
| 656 | + { |
|
| 657 | + EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__( |
|
| 658 | + 'Do you really want to delete this image? Please remember to update your event to complete the removal.', |
|
| 659 | + 'event_espresso' |
|
| 660 | + ); |
|
| 661 | + } |
|
| 662 | + |
|
| 663 | + |
|
| 664 | + /** |
|
| 665 | + * For adding anything that should be triggered on the admin_notices hook for any route within this admin page |
|
| 666 | + * group. |
|
| 667 | + */ |
|
| 668 | + public function admin_notices() |
|
| 669 | + { |
|
| 670 | + } |
|
| 671 | + |
|
| 672 | + |
|
| 673 | + /** |
|
| 674 | + * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within |
|
| 675 | + * this admin page group. |
|
| 676 | + */ |
|
| 677 | + public function admin_footer_scripts() |
|
| 678 | + { |
|
| 679 | + } |
|
| 680 | + |
|
| 681 | + |
|
| 682 | + /** |
|
| 683 | + * Call this function to verify if an event is public and has tickets for sale. If it does, then we need to show a |
|
| 684 | + * warning (via EE_Error::add_error()); |
|
| 685 | + * |
|
| 686 | + * @param EE_Event $event Event object |
|
| 687 | + * @param string $req_type |
|
| 688 | + * @return void |
|
| 689 | + * @throws EE_Error |
|
| 690 | + * @access public |
|
| 691 | + */ |
|
| 692 | + public function verify_event_edit($event = null, $req_type = '') |
|
| 693 | + { |
|
| 694 | + // don't need to do this when processing |
|
| 695 | + if (! empty($req_type)) { |
|
| 696 | + return; |
|
| 697 | + } |
|
| 698 | + // no event? |
|
| 699 | + if (empty($event)) { |
|
| 700 | + // set event |
|
| 701 | + $event = $this->_cpt_model_obj; |
|
| 702 | + } |
|
| 703 | + // STILL no event? |
|
| 704 | + if (! $event instanceof EE_Event) { |
|
| 705 | + return; |
|
| 706 | + } |
|
| 707 | + $orig_status = $event->status(); |
|
| 708 | + // first check if event is active. |
|
| 709 | + if ($orig_status === EEM_Event::cancelled |
|
| 710 | + || $orig_status === EEM_Event::postponed |
|
| 711 | + || $event->is_expired() |
|
| 712 | + || $event->is_inactive() |
|
| 713 | + ) { |
|
| 714 | + return; |
|
| 715 | + } |
|
| 716 | + // made it here so it IS active... next check that any of the tickets are sold. |
|
| 717 | + if ($event->is_sold_out(true)) { |
|
| 718 | + if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) { |
|
| 719 | + EE_Error::add_attention( |
|
| 720 | + sprintf( |
|
| 721 | + esc_html__( |
|
| 722 | + 'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event. However, this change is not permanent until you update the event. You can change the status back to something else before updating if you wish.', |
|
| 723 | + 'event_espresso' |
|
| 724 | + ), |
|
| 725 | + EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence') |
|
| 726 | + ) |
|
| 727 | + ); |
|
| 728 | + } |
|
| 729 | + return; |
|
| 730 | + } elseif ($orig_status === EEM_Event::sold_out) { |
|
| 731 | + EE_Error::add_attention( |
|
| 732 | + sprintf( |
|
| 733 | + esc_html__( |
|
| 734 | + 'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets. However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.', |
|
| 735 | + 'event_espresso' |
|
| 736 | + ), |
|
| 737 | + EEH_Template::pretty_status($event->status(), false, 'sentence') |
|
| 738 | + ) |
|
| 739 | + ); |
|
| 740 | + } |
|
| 741 | + // now we need to determine if the event has any tickets on sale. If not then we dont' show the error |
|
| 742 | + if (! $event->tickets_on_sale()) { |
|
| 743 | + return; |
|
| 744 | + } |
|
| 745 | + // made it here so show warning |
|
| 746 | + $this->_edit_event_warning(); |
|
| 747 | + } |
|
| 748 | + |
|
| 749 | + |
|
| 750 | + /** |
|
| 751 | + * This is the text used for when an event is being edited that is public and has tickets for sale. |
|
| 752 | + * When needed, hook this into a EE_Error::add_error() notice. |
|
| 753 | + * |
|
| 754 | + * @access protected |
|
| 755 | + * @return void |
|
| 756 | + */ |
|
| 757 | + protected function _edit_event_warning() |
|
| 758 | + { |
|
| 759 | + // we don't want to add warnings during these requests |
|
| 760 | + if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') { |
|
| 761 | + return; |
|
| 762 | + } |
|
| 763 | + EE_Error::add_attention( |
|
| 764 | + sprintf( |
|
| 765 | + esc_html__( |
|
| 766 | + 'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s', |
|
| 767 | + 'event_espresso' |
|
| 768 | + ), |
|
| 769 | + '<a class="espresso-help-tab-lnk">', |
|
| 770 | + '</a>' |
|
| 771 | + ) |
|
| 772 | + ); |
|
| 773 | + } |
|
| 774 | + |
|
| 775 | + |
|
| 776 | + /** |
|
| 777 | + * When a user is creating a new event, notify them if they haven't set their timezone. |
|
| 778 | + * Otherwise, do the normal logic |
|
| 779 | + * |
|
| 780 | + * @return string |
|
| 781 | + * @throws \EE_Error |
|
| 782 | + */ |
|
| 783 | + protected function _create_new_cpt_item() |
|
| 784 | + { |
|
| 785 | + $has_timezone_string = get_option('timezone_string'); |
|
| 786 | + // only nag them about setting their timezone if it's their first event, and they haven't already done it |
|
| 787 | + if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) { |
|
| 788 | + EE_Error::add_attention( |
|
| 789 | + sprintf( |
|
| 790 | + __( |
|
| 791 | + 'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s', |
|
| 792 | + 'event_espresso' |
|
| 793 | + ), |
|
| 794 | + '<br>', |
|
| 795 | + '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">' |
|
| 796 | + . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale()) |
|
| 797 | + . '</select>', |
|
| 798 | + '<button class="button button-secondary timezone-submit">', |
|
| 799 | + '</button><span class="spinner"></span>' |
|
| 800 | + ), |
|
| 801 | + __FILE__, |
|
| 802 | + __FUNCTION__, |
|
| 803 | + __LINE__ |
|
| 804 | + ); |
|
| 805 | + } |
|
| 806 | + return parent::_create_new_cpt_item(); |
|
| 807 | + } |
|
| 808 | + |
|
| 809 | + |
|
| 810 | + /** |
|
| 811 | + * Sets the _views property for the default route in this admin page group. |
|
| 812 | + */ |
|
| 813 | + protected function _set_list_table_views_default() |
|
| 814 | + { |
|
| 815 | + $this->_views = array( |
|
| 816 | + 'all' => array( |
|
| 817 | + 'slug' => 'all', |
|
| 818 | + 'label' => esc_html__('View All Events', 'event_espresso'), |
|
| 819 | + 'count' => 0, |
|
| 820 | + 'bulk_action' => array( |
|
| 821 | + 'trash_events' => esc_html__('Move to Trash', 'event_espresso'), |
|
| 822 | + ), |
|
| 823 | + ), |
|
| 824 | + 'draft' => array( |
|
| 825 | + 'slug' => 'draft', |
|
| 826 | + 'label' => esc_html__('Draft', 'event_espresso'), |
|
| 827 | + 'count' => 0, |
|
| 828 | + 'bulk_action' => array( |
|
| 829 | + 'trash_events' => esc_html__('Move to Trash', 'event_espresso'), |
|
| 830 | + ), |
|
| 831 | + ), |
|
| 832 | + ); |
|
| 833 | + if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) { |
|
| 834 | + $this->_views['trash'] = array( |
|
| 835 | + 'slug' => 'trash', |
|
| 836 | + 'label' => esc_html__('Trash', 'event_espresso'), |
|
| 837 | + 'count' => 0, |
|
| 838 | + 'bulk_action' => array( |
|
| 839 | + 'restore_events' => esc_html__('Restore From Trash', 'event_espresso'), |
|
| 840 | + 'delete_events' => esc_html__('Delete Permanently', 'event_espresso'), |
|
| 841 | + ), |
|
| 842 | + ); |
|
| 843 | + } |
|
| 844 | + } |
|
| 845 | + |
|
| 846 | + |
|
| 847 | + /** |
|
| 848 | + * Provides the legend item array for the default list table view. |
|
| 849 | + * |
|
| 850 | + * @return array |
|
| 851 | + */ |
|
| 852 | + protected function _event_legend_items() |
|
| 853 | + { |
|
| 854 | + $items = array( |
|
| 855 | + 'view_details' => array( |
|
| 856 | + 'class' => 'dashicons dashicons-search', |
|
| 857 | + 'desc' => esc_html__('View Event', 'event_espresso'), |
|
| 858 | + ), |
|
| 859 | + 'edit_event' => array( |
|
| 860 | + 'class' => 'ee-icon ee-icon-calendar-edit', |
|
| 861 | + 'desc' => esc_html__('Edit Event Details', 'event_espresso'), |
|
| 862 | + ), |
|
| 863 | + 'view_attendees' => array( |
|
| 864 | + 'class' => 'dashicons dashicons-groups', |
|
| 865 | + 'desc' => esc_html__('View Registrations for Event', 'event_espresso'), |
|
| 866 | + ), |
|
| 867 | + ); |
|
| 868 | + $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items); |
|
| 869 | + $statuses = array( |
|
| 870 | + 'sold_out_status' => array( |
|
| 871 | + 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out, |
|
| 872 | + 'desc' => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'), |
|
| 873 | + ), |
|
| 874 | + 'active_status' => array( |
|
| 875 | + 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active, |
|
| 876 | + 'desc' => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'), |
|
| 877 | + ), |
|
| 878 | + 'upcoming_status' => array( |
|
| 879 | + 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming, |
|
| 880 | + 'desc' => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'), |
|
| 881 | + ), |
|
| 882 | + 'postponed_status' => array( |
|
| 883 | + 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed, |
|
| 884 | + 'desc' => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'), |
|
| 885 | + ), |
|
| 886 | + 'cancelled_status' => array( |
|
| 887 | + 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled, |
|
| 888 | + 'desc' => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'), |
|
| 889 | + ), |
|
| 890 | + 'expired_status' => array( |
|
| 891 | + 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired, |
|
| 892 | + 'desc' => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'), |
|
| 893 | + ), |
|
| 894 | + 'inactive_status' => array( |
|
| 895 | + 'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive, |
|
| 896 | + 'desc' => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'), |
|
| 897 | + ), |
|
| 898 | + ); |
|
| 899 | + $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses); |
|
| 900 | + return array_merge($items, $statuses); |
|
| 901 | + } |
|
| 902 | + |
|
| 903 | + |
|
| 904 | + /** |
|
| 905 | + * @return EEM_Event |
|
| 906 | + */ |
|
| 907 | + private function _event_model() |
|
| 908 | + { |
|
| 909 | + if (! $this->_event_model instanceof EEM_Event) { |
|
| 910 | + $this->_event_model = EE_Registry::instance()->load_model('Event'); |
|
| 911 | + } |
|
| 912 | + return $this->_event_model; |
|
| 913 | + } |
|
| 914 | + |
|
| 915 | + |
|
| 916 | + /** |
|
| 917 | + * Adds extra buttons to the WP CPT permalink field row. |
|
| 918 | + * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter. |
|
| 919 | + * |
|
| 920 | + * @param string $return the current html |
|
| 921 | + * @param int $id the post id for the page |
|
| 922 | + * @param string $new_title What the title is |
|
| 923 | + * @param string $new_slug what the slug is |
|
| 924 | + * @return string The new html string for the permalink area |
|
| 925 | + */ |
|
| 926 | + public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug) |
|
| 927 | + { |
|
| 928 | + // make sure this is only when editing |
|
| 929 | + if (! empty($id)) { |
|
| 930 | + $post = get_post($id); |
|
| 931 | + $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#" tabindex="-1">' |
|
| 932 | + . esc_html__('Shortcode', 'event_espresso') |
|
| 933 | + . '</a> '; |
|
| 934 | + $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id=' |
|
| 935 | + . $post->ID |
|
| 936 | + . ']">'; |
|
| 937 | + } |
|
| 938 | + return $return; |
|
| 939 | + } |
|
| 940 | + |
|
| 941 | + |
|
| 942 | + /** |
|
| 943 | + * _events_overview_list_table |
|
| 944 | + * This contains the logic for showing the events_overview list |
|
| 945 | + * |
|
| 946 | + * @access protected |
|
| 947 | + * @return void |
|
| 948 | + * @throws \EE_Error |
|
| 949 | + */ |
|
| 950 | + protected function _events_overview_list_table() |
|
| 951 | + { |
|
| 952 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 953 | + $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table']) |
|
| 954 | + ? (array) $this->_template_args['after_list_table'] |
|
| 955 | + : array(); |
|
| 956 | + $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br() |
|
| 957 | + . EEH_Template::get_button_or_link( |
|
| 958 | + get_post_type_archive_link('espresso_events'), |
|
| 959 | + esc_html__("View Event Archive Page", "event_espresso"), |
|
| 960 | + 'button' |
|
| 961 | + ); |
|
| 962 | + $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items()); |
|
| 963 | + $this->_admin_page_title .= ' ' . $this->get_action_link_or_button( |
|
| 964 | + 'create_new', |
|
| 965 | + 'add', |
|
| 966 | + array(), |
|
| 967 | + 'add-new-h2' |
|
| 968 | + ); |
|
| 969 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 970 | + } |
|
| 971 | + |
|
| 972 | + |
|
| 973 | + /** |
|
| 974 | + * this allows for extra misc actions in the default WP publish box |
|
| 975 | + * |
|
| 976 | + * @return void |
|
| 977 | + */ |
|
| 978 | + public function extra_misc_actions_publish_box() |
|
| 979 | + { |
|
| 980 | + $this->_generate_publish_box_extra_content(); |
|
| 981 | + } |
|
| 982 | + |
|
| 983 | + |
|
| 984 | + /** |
|
| 985 | + * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been |
|
| 986 | + * saved. |
|
| 987 | + * Typically you would use this to save any additional data. |
|
| 988 | + * Keep in mind also that "save_post" runs on EVERY post update to the database. |
|
| 989 | + * ALSO very important. When a post transitions from scheduled to published, |
|
| 990 | + * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from |
|
| 991 | + * other meta saves. So MAKE sure that you handle this accordingly. |
|
| 992 | + * |
|
| 993 | + * @access protected |
|
| 994 | + * @abstract |
|
| 995 | + * @param string $post_id The ID of the cpt that was saved (so you can link relationally) |
|
| 996 | + * @param object $post The post object of the cpt that was saved. |
|
| 997 | + * @return void |
|
| 998 | + * @throws \EE_Error |
|
| 999 | + */ |
|
| 1000 | + protected function _insert_update_cpt_item($post_id, $post) |
|
| 1001 | + { |
|
| 1002 | + if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') { |
|
| 1003 | + // get out we're not processing an event save. |
|
| 1004 | + return; |
|
| 1005 | + } |
|
| 1006 | + $event_values = array( |
|
| 1007 | + 'EVT_display_desc' => ! empty($this->_req_data['display_desc']) ? 1 : 0, |
|
| 1008 | + 'EVT_display_ticket_selector' => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0, |
|
| 1009 | + 'EVT_additional_limit' => min( |
|
| 1010 | + apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255), |
|
| 1011 | + ! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null |
|
| 1012 | + ), |
|
| 1013 | + 'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status']) |
|
| 1014 | + ? $this->_req_data['EVT_default_registration_status'] |
|
| 1015 | + : EE_Registry::instance()->CFG->registration->default_STS_ID, |
|
| 1016 | + 'EVT_member_only' => ! empty($this->_req_data['member_only']) ? 1 : 0, |
|
| 1017 | + 'EVT_allow_overflow' => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0, |
|
| 1018 | + 'EVT_timezone_string' => ! empty($this->_req_data['timezone_string']) |
|
| 1019 | + ? $this->_req_data['timezone_string'] : null, |
|
| 1020 | + 'EVT_external_URL' => ! empty($this->_req_data['externalURL']) |
|
| 1021 | + ? $this->_req_data['externalURL'] : null, |
|
| 1022 | + 'EVT_phone' => ! empty($this->_req_data['event_phone']) |
|
| 1023 | + ? $this->_req_data['event_phone'] : null, |
|
| 1024 | + ); |
|
| 1025 | + // update event |
|
| 1026 | + $success = $this->_event_model()->update_by_ID($event_values, $post_id); |
|
| 1027 | + // get event_object for other metaboxes... though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id! |
|
| 1028 | + $get_one_where = array( |
|
| 1029 | + $this->_event_model()->primary_key_name() => $post_id, |
|
| 1030 | + 'OR' => array( |
|
| 1031 | + 'status' => $post->post_status, |
|
| 1032 | + // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db, |
|
| 1033 | + // but the returned object here has a status of "publish", so use the original post status as well |
|
| 1034 | + 'status*1' => $this->_req_data['original_post_status'], |
|
| 1035 | + ), |
|
| 1036 | + ); |
|
| 1037 | + $event = $this->_event_model()->get_one(array($get_one_where)); |
|
| 1038 | + // the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons. |
|
| 1039 | + $event_update_callbacks = apply_filters( |
|
| 1040 | + 'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks', |
|
| 1041 | + array( |
|
| 1042 | + array($this, '_default_venue_update'), |
|
| 1043 | + array($this, '_default_tickets_update'), |
|
| 1044 | + ) |
|
| 1045 | + ); |
|
| 1046 | + $att_success = true; |
|
| 1047 | + foreach ($event_update_callbacks as $e_callback) { |
|
| 1048 | + $_success = is_callable($e_callback) |
|
| 1049 | + ? call_user_func($e_callback, $event, $this->_req_data) |
|
| 1050 | + : false; |
|
| 1051 | + // if ANY of these updates fail then we want the appropriate global error message |
|
| 1052 | + $att_success = ! $att_success ? $att_success : $_success; |
|
| 1053 | + } |
|
| 1054 | + // any errors? |
|
| 1055 | + if ($success && false === $att_success) { |
|
| 1056 | + EE_Error::add_error( |
|
| 1057 | + esc_html__( |
|
| 1058 | + 'Event Details saved successfully but something went wrong with saving attachments.', |
|
| 1059 | + 'event_espresso' |
|
| 1060 | + ), |
|
| 1061 | + __FILE__, |
|
| 1062 | + __FUNCTION__, |
|
| 1063 | + __LINE__ |
|
| 1064 | + ); |
|
| 1065 | + } elseif ($success === false) { |
|
| 1066 | + EE_Error::add_error( |
|
| 1067 | + esc_html__('Event Details did not save successfully.', 'event_espresso'), |
|
| 1068 | + __FILE__, |
|
| 1069 | + __FUNCTION__, |
|
| 1070 | + __LINE__ |
|
| 1071 | + ); |
|
| 1072 | + } |
|
| 1073 | + } |
|
| 1074 | + |
|
| 1075 | + |
|
| 1076 | + /** |
|
| 1077 | + * @see parent::restore_item() |
|
| 1078 | + * @param int $post_id |
|
| 1079 | + * @param int $revision_id |
|
| 1080 | + */ |
|
| 1081 | + protected function _restore_cpt_item($post_id, $revision_id) |
|
| 1082 | + { |
|
| 1083 | + // copy existing event meta to new post |
|
| 1084 | + $post_evt = $this->_event_model()->get_one_by_ID($post_id); |
|
| 1085 | + if ($post_evt instanceof EE_Event) { |
|
| 1086 | + // meta revision restore |
|
| 1087 | + $post_evt->restore_revision($revision_id); |
|
| 1088 | + // related objs restore |
|
| 1089 | + $post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price')); |
|
| 1090 | + } |
|
| 1091 | + } |
|
| 1092 | + |
|
| 1093 | + |
|
| 1094 | + /** |
|
| 1095 | + * Attach the venue to the Event |
|
| 1096 | + * |
|
| 1097 | + * @param \EE_Event $evtobj Event Object to add the venue to |
|
| 1098 | + * @param array $data The request data from the form |
|
| 1099 | + * @return bool Success or fail. |
|
| 1100 | + */ |
|
| 1101 | + protected function _default_venue_update(\EE_Event $evtobj, $data) |
|
| 1102 | + { |
|
| 1103 | + require_once(EE_MODELS . 'EEM_Venue.model.php'); |
|
| 1104 | + $venue_model = EE_Registry::instance()->load_model('Venue'); |
|
| 1105 | + $rows_affected = null; |
|
| 1106 | + $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null; |
|
| 1107 | + // very important. If we don't have a venue name... |
|
| 1108 | + // then we'll get out because not necessary to create empty venue |
|
| 1109 | + if (empty($data['venue_title'])) { |
|
| 1110 | + return false; |
|
| 1111 | + } |
|
| 1112 | + $venue_array = array( |
|
| 1113 | + 'VNU_wp_user' => $evtobj->get('EVT_wp_user'), |
|
| 1114 | + 'VNU_name' => ! empty($data['venue_title']) ? $data['venue_title'] : null, |
|
| 1115 | + 'VNU_desc' => ! empty($data['venue_description']) ? $data['venue_description'] : null, |
|
| 1116 | + 'VNU_identifier' => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null, |
|
| 1117 | + 'VNU_short_desc' => ! empty($data['venue_short_description']) ? $data['venue_short_description'] |
|
| 1118 | + : null, |
|
| 1119 | + 'VNU_address' => ! empty($data['address']) ? $data['address'] : null, |
|
| 1120 | + 'VNU_address2' => ! empty($data['address2']) ? $data['address2'] : null, |
|
| 1121 | + 'VNU_city' => ! empty($data['city']) ? $data['city'] : null, |
|
| 1122 | + 'STA_ID' => ! empty($data['state']) ? $data['state'] : null, |
|
| 1123 | + 'CNT_ISO' => ! empty($data['countries']) ? $data['countries'] : null, |
|
| 1124 | + 'VNU_zip' => ! empty($data['zip']) ? $data['zip'] : null, |
|
| 1125 | + 'VNU_phone' => ! empty($data['venue_phone']) ? $data['venue_phone'] : null, |
|
| 1126 | + 'VNU_capacity' => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null, |
|
| 1127 | + 'VNU_url' => ! empty($data['venue_url']) ? $data['venue_url'] : null, |
|
| 1128 | + 'VNU_virtual_phone' => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null, |
|
| 1129 | + 'VNU_virtual_url' => ! empty($data['virtual_url']) ? $data['virtual_url'] : null, |
|
| 1130 | + 'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0, |
|
| 1131 | + 'status' => 'publish', |
|
| 1132 | + ); |
|
| 1133 | + // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out. |
|
| 1134 | + if (! empty($venue_id)) { |
|
| 1135 | + $update_where = array($venue_model->primary_key_name() => $venue_id); |
|
| 1136 | + $rows_affected = $venue_model->update($venue_array, array($update_where)); |
|
| 1137 | + // we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present. |
|
| 1138 | + $evtobj->_add_relation_to($venue_id, 'Venue'); |
|
| 1139 | + return $rows_affected > 0 ? true : false; |
|
| 1140 | + } else { |
|
| 1141 | + // we insert the venue |
|
| 1142 | + $venue_id = $venue_model->insert($venue_array); |
|
| 1143 | + $evtobj->_add_relation_to($venue_id, 'Venue'); |
|
| 1144 | + return ! empty($venue_id) ? true : false; |
|
| 1145 | + } |
|
| 1146 | + // when we have the ancestor come in it's already been handled by the revision save. |
|
| 1147 | + } |
|
| 1148 | + |
|
| 1149 | + |
|
| 1150 | + /** |
|
| 1151 | + * Handles saving everything related to Tickets (datetimes, tickets, prices) |
|
| 1152 | + * |
|
| 1153 | + * @param EE_Event $evtobj The Event object we're attaching data to |
|
| 1154 | + * @param array $data The request data from the form |
|
| 1155 | + * @return array |
|
| 1156 | + */ |
|
| 1157 | + protected function _default_tickets_update(EE_Event $evtobj, $data) |
|
| 1158 | + { |
|
| 1159 | + $success = true; |
|
| 1160 | + $saved_dtt = null; |
|
| 1161 | + $saved_tickets = array(); |
|
| 1162 | + $incoming_date_formats = array('Y-m-d', 'h:i a'); |
|
| 1163 | + foreach ($data['edit_event_datetimes'] as $row => $dtt) { |
|
| 1164 | + // trim all values to ensure any excess whitespace is removed. |
|
| 1165 | + $dtt = array_map('trim', $dtt); |
|
| 1166 | + $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end'] |
|
| 1167 | + : $dtt['DTT_EVT_start']; |
|
| 1168 | + $datetime_values = array( |
|
| 1169 | + 'DTT_ID' => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null, |
|
| 1170 | + 'DTT_EVT_start' => $dtt['DTT_EVT_start'], |
|
| 1171 | + 'DTT_EVT_end' => $dtt['DTT_EVT_end'], |
|
| 1172 | + 'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'], |
|
| 1173 | + 'DTT_order' => $row, |
|
| 1174 | + ); |
|
| 1175 | + // if we have an id then let's get existing object first and then set the new values. Otherwise we instantiate a new object for save. |
|
| 1176 | + if (! empty($dtt['DTT_ID'])) { |
|
| 1177 | + $DTM = EE_Registry::instance() |
|
| 1178 | + ->load_model('Datetime', array($evtobj->get_timezone())) |
|
| 1179 | + ->get_one_by_ID($dtt['DTT_ID']); |
|
| 1180 | + $DTM->set_date_format($incoming_date_formats[0]); |
|
| 1181 | + $DTM->set_time_format($incoming_date_formats[1]); |
|
| 1182 | + foreach ($datetime_values as $field => $value) { |
|
| 1183 | + $DTM->set($field, $value); |
|
| 1184 | + } |
|
| 1185 | + // make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it. We need to do this so we dont' TRASH the parent DTT. |
|
| 1186 | + $saved_dtts[ $DTM->ID() ] = $DTM; |
|
| 1187 | + } else { |
|
| 1188 | + $DTM = EE_Registry::instance()->load_class( |
|
| 1189 | + 'Datetime', |
|
| 1190 | + array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats), |
|
| 1191 | + false, |
|
| 1192 | + false |
|
| 1193 | + ); |
|
| 1194 | + foreach ($datetime_values as $field => $value) { |
|
| 1195 | + $DTM->set($field, $value); |
|
| 1196 | + } |
|
| 1197 | + } |
|
| 1198 | + $DTM->save(); |
|
| 1199 | + $DTT = $evtobj->_add_relation_to($DTM, 'Datetime'); |
|
| 1200 | + // load DTT helper |
|
| 1201 | + // before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date. |
|
| 1202 | + if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) { |
|
| 1203 | + $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start')); |
|
| 1204 | + $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days'); |
|
| 1205 | + $DTT->save(); |
|
| 1206 | + } |
|
| 1207 | + // now we got to make sure we add the new DTT_ID to the $saved_dtts array because it is possible there was a new one created for the autosave. |
|
| 1208 | + $saved_dtt = $DTT; |
|
| 1209 | + $success = ! $success ? $success : $DTT; |
|
| 1210 | + // if ANY of these updates fail then we want the appropriate global error message. |
|
| 1211 | + // //todo this is actually sucky we need a better error message but this is what it is for now. |
|
| 1212 | + } |
|
| 1213 | + // no dtts get deleted so we don't do any of that logic here. |
|
| 1214 | + // update tickets next |
|
| 1215 | + $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array(); |
|
| 1216 | + foreach ($data['edit_tickets'] as $row => $tkt) { |
|
| 1217 | + $incoming_date_formats = array('Y-m-d', 'h:i a'); |
|
| 1218 | + $update_prices = false; |
|
| 1219 | + $ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount']) |
|
| 1220 | + ? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0; |
|
| 1221 | + // trim inputs to ensure any excess whitespace is removed. |
|
| 1222 | + $tkt = array_map('trim', $tkt); |
|
| 1223 | + if (empty($tkt['TKT_start_date'])) { |
|
| 1224 | + // let's use now in the set timezone. |
|
| 1225 | + $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone())); |
|
| 1226 | + $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]); |
|
| 1227 | + } |
|
| 1228 | + if (empty($tkt['TKT_end_date'])) { |
|
| 1229 | + // use the start date of the first datetime |
|
| 1230 | + $dtt = $evtobj->first_datetime(); |
|
| 1231 | + $tkt['TKT_end_date'] = $dtt->start_date_and_time( |
|
| 1232 | + $incoming_date_formats[0], |
|
| 1233 | + $incoming_date_formats[1] |
|
| 1234 | + ); |
|
| 1235 | + } |
|
| 1236 | + $TKT_values = array( |
|
| 1237 | + 'TKT_ID' => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null, |
|
| 1238 | + 'TTM_ID' => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0, |
|
| 1239 | + 'TKT_name' => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '', |
|
| 1240 | + 'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '', |
|
| 1241 | + 'TKT_start_date' => $tkt['TKT_start_date'], |
|
| 1242 | + 'TKT_end_date' => $tkt['TKT_end_date'], |
|
| 1243 | + 'TKT_qty' => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'], |
|
| 1244 | + 'TKT_uses' => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'], |
|
| 1245 | + 'TKT_min' => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'], |
|
| 1246 | + 'TKT_max' => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'], |
|
| 1247 | + 'TKT_row' => $row, |
|
| 1248 | + 'TKT_order' => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row, |
|
| 1249 | + 'TKT_price' => $ticket_price, |
|
| 1250 | + ); |
|
| 1251 | + // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well. |
|
| 1252 | + if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) { |
|
| 1253 | + $TKT_values['TKT_ID'] = 0; |
|
| 1254 | + $TKT_values['TKT_is_default'] = 0; |
|
| 1255 | + $TKT_values['TKT_price'] = $ticket_price; |
|
| 1256 | + $update_prices = true; |
|
| 1257 | + } |
|
| 1258 | + // if we have a TKT_ID then we need to get that existing TKT_obj and update it |
|
| 1259 | + // we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified. |
|
| 1260 | + // keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived. |
|
| 1261 | + if (! empty($tkt['TKT_ID'])) { |
|
| 1262 | + $TKT = EE_Registry::instance() |
|
| 1263 | + ->load_model('Ticket', array($evtobj->get_timezone())) |
|
| 1264 | + ->get_one_by_ID($tkt['TKT_ID']); |
|
| 1265 | + if ($TKT instanceof EE_Ticket) { |
|
| 1266 | + $ticket_sold = $TKT->count_related( |
|
| 1267 | + 'Registration', |
|
| 1268 | + array( |
|
| 1269 | + array( |
|
| 1270 | + 'STS_ID' => array( |
|
| 1271 | + 'NOT IN', |
|
| 1272 | + array(EEM_Registration::status_id_incomplete), |
|
| 1273 | + ), |
|
| 1274 | + ), |
|
| 1275 | + ) |
|
| 1276 | + ) > 0 ? true : false; |
|
| 1277 | + // let's just check the total price for the existing ticket and determine if it matches the new total price. if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket. |
|
| 1278 | + $create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price') |
|
| 1279 | + && ! $TKT->get('TKT_deleted'); |
|
| 1280 | + $TKT->set_date_format($incoming_date_formats[0]); |
|
| 1281 | + $TKT->set_time_format($incoming_date_formats[1]); |
|
| 1282 | + // set new values |
|
| 1283 | + foreach ($TKT_values as $field => $value) { |
|
| 1284 | + if ($field == 'TKT_qty') { |
|
| 1285 | + $TKT->set_qty($value); |
|
| 1286 | + } else { |
|
| 1287 | + $TKT->set($field, $value); |
|
| 1288 | + } |
|
| 1289 | + } |
|
| 1290 | + // if $create_new_TKT is false then we can safely update the existing ticket. Otherwise we have to create a new ticket. |
|
| 1291 | + if ($create_new_TKT) { |
|
| 1292 | + // archive the old ticket first |
|
| 1293 | + $TKT->set('TKT_deleted', 1); |
|
| 1294 | + $TKT->save(); |
|
| 1295 | + // make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine. |
|
| 1296 | + $saved_tickets[ $TKT->ID() ] = $TKT; |
|
| 1297 | + // create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it. |
|
| 1298 | + $TKT = clone $TKT; |
|
| 1299 | + $TKT->set('TKT_ID', 0); |
|
| 1300 | + $TKT->set('TKT_deleted', 0); |
|
| 1301 | + $TKT->set('TKT_price', $ticket_price); |
|
| 1302 | + $TKT->set('TKT_sold', 0); |
|
| 1303 | + // now we need to make sure that $new prices are created as well and attached to new ticket. |
|
| 1304 | + $update_prices = true; |
|
| 1305 | + } |
|
| 1306 | + // make sure price is set if it hasn't been already |
|
| 1307 | + $TKT->set('TKT_price', $ticket_price); |
|
| 1308 | + } |
|
| 1309 | + } else { |
|
| 1310 | + // no TKT_id so a new TKT |
|
| 1311 | + $TKT_values['TKT_price'] = $ticket_price; |
|
| 1312 | + $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false); |
|
| 1313 | + if ($TKT instanceof EE_Ticket) { |
|
| 1314 | + // need to reset values to properly account for the date formats |
|
| 1315 | + $TKT->set_date_format($incoming_date_formats[0]); |
|
| 1316 | + $TKT->set_time_format($incoming_date_formats[1]); |
|
| 1317 | + $TKT->set_timezone($evtobj->get_timezone()); |
|
| 1318 | + // set new values |
|
| 1319 | + foreach ($TKT_values as $field => $value) { |
|
| 1320 | + if ($field == 'TKT_qty') { |
|
| 1321 | + $TKT->set_qty($value); |
|
| 1322 | + } else { |
|
| 1323 | + $TKT->set($field, $value); |
|
| 1324 | + } |
|
| 1325 | + } |
|
| 1326 | + $update_prices = true; |
|
| 1327 | + } |
|
| 1328 | + } |
|
| 1329 | + // cap ticket qty by datetime reg limits |
|
| 1330 | + $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit'))); |
|
| 1331 | + // update ticket. |
|
| 1332 | + $TKT->save(); |
|
| 1333 | + // before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date. |
|
| 1334 | + if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) { |
|
| 1335 | + $TKT->set('TKT_end_date', $TKT->get('TKT_start_date')); |
|
| 1336 | + $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days'); |
|
| 1337 | + $TKT->save(); |
|
| 1338 | + } |
|
| 1339 | + // initially let's add the ticket to the dtt |
|
| 1340 | + $saved_dtt->_add_relation_to($TKT, 'Ticket'); |
|
| 1341 | + $saved_tickets[ $TKT->ID() ] = $TKT; |
|
| 1342 | + // add prices to ticket |
|
| 1343 | + $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices); |
|
| 1344 | + } |
|
| 1345 | + // however now we need to handle permanently deleting tickets via the ui. Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold. However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db. |
|
| 1346 | + $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets; |
|
| 1347 | + $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets)); |
|
| 1348 | + foreach ($tickets_removed as $id) { |
|
| 1349 | + $id = absint($id); |
|
| 1350 | + // get the ticket for this id |
|
| 1351 | + $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id); |
|
| 1352 | + // need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold) |
|
| 1353 | + $dtts = $tkt_to_remove->get_many_related('Datetime'); |
|
| 1354 | + foreach ($dtts as $dtt) { |
|
| 1355 | + $tkt_to_remove->_remove_relation_to($dtt, 'Datetime'); |
|
| 1356 | + } |
|
| 1357 | + // need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived)) |
|
| 1358 | + $tkt_to_remove->delete_related_permanently('Price'); |
|
| 1359 | + // finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships) |
|
| 1360 | + $tkt_to_remove->delete_permanently(); |
|
| 1361 | + } |
|
| 1362 | + return array($saved_dtt, $saved_tickets); |
|
| 1363 | + } |
|
| 1364 | + |
|
| 1365 | + |
|
| 1366 | + /** |
|
| 1367 | + * This attaches a list of given prices to a ticket. |
|
| 1368 | + * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change |
|
| 1369 | + * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old |
|
| 1370 | + * price info and prices are automatically "archived" via the ticket. |
|
| 1371 | + * |
|
| 1372 | + * @access private |
|
| 1373 | + * @param array $prices Array of prices from the form. |
|
| 1374 | + * @param EE_Ticket $ticket EE_Ticket object that prices are being attached to. |
|
| 1375 | + * @param bool $new_prices Whether attach existing incoming prices or create new ones. |
|
| 1376 | + * @return void |
|
| 1377 | + */ |
|
| 1378 | + private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false) |
|
| 1379 | + { |
|
| 1380 | + foreach ($prices as $row => $prc) { |
|
| 1381 | + $PRC_values = array( |
|
| 1382 | + 'PRC_ID' => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null, |
|
| 1383 | + 'PRT_ID' => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null, |
|
| 1384 | + 'PRC_amount' => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0, |
|
| 1385 | + 'PRC_name' => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '', |
|
| 1386 | + 'PRC_desc' => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '', |
|
| 1387 | + 'PRC_is_default' => 0, // make sure prices are NOT set as default from this context |
|
| 1388 | + 'PRC_order' => $row, |
|
| 1389 | + ); |
|
| 1390 | + if ($new_prices || empty($PRC_values['PRC_ID'])) { |
|
| 1391 | + $PRC_values['PRC_ID'] = 0; |
|
| 1392 | + $PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false); |
|
| 1393 | + } else { |
|
| 1394 | + $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']); |
|
| 1395 | + // update this price with new values |
|
| 1396 | + foreach ($PRC_values as $field => $newprc) { |
|
| 1397 | + $PRC->set($field, $newprc); |
|
| 1398 | + } |
|
| 1399 | + $PRC->save(); |
|
| 1400 | + } |
|
| 1401 | + $ticket->_add_relation_to($PRC, 'Price'); |
|
| 1402 | + } |
|
| 1403 | + } |
|
| 1404 | + |
|
| 1405 | + |
|
| 1406 | + /** |
|
| 1407 | + * Add in our autosave ajax handlers |
|
| 1408 | + * |
|
| 1409 | + */ |
|
| 1410 | + protected function _ee_autosave_create_new() |
|
| 1411 | + { |
|
| 1412 | + } |
|
| 1413 | + |
|
| 1414 | + |
|
| 1415 | + /** |
|
| 1416 | + * More autosave handlers. |
|
| 1417 | + */ |
|
| 1418 | + protected function _ee_autosave_edit() |
|
| 1419 | + { |
|
| 1420 | + return; // TEMPORARILY EXITING CAUSE THIS IS A TODO |
|
| 1421 | + } |
|
| 1422 | + |
|
| 1423 | + |
|
| 1424 | + /** |
|
| 1425 | + * _generate_publish_box_extra_content |
|
| 1426 | + */ |
|
| 1427 | + private function _generate_publish_box_extra_content() |
|
| 1428 | + { |
|
| 1429 | + // load formatter helper |
|
| 1430 | + // args for getting related registrations |
|
| 1431 | + $approved_query_args = array( |
|
| 1432 | + array( |
|
| 1433 | + 'REG_deleted' => 0, |
|
| 1434 | + 'STS_ID' => EEM_Registration::status_id_approved, |
|
| 1435 | + ), |
|
| 1436 | + ); |
|
| 1437 | + $not_approved_query_args = array( |
|
| 1438 | + array( |
|
| 1439 | + 'REG_deleted' => 0, |
|
| 1440 | + 'STS_ID' => EEM_Registration::status_id_not_approved, |
|
| 1441 | + ), |
|
| 1442 | + ); |
|
| 1443 | + $pending_payment_query_args = array( |
|
| 1444 | + array( |
|
| 1445 | + 'REG_deleted' => 0, |
|
| 1446 | + 'STS_ID' => EEM_Registration::status_id_pending_payment, |
|
| 1447 | + ), |
|
| 1448 | + ); |
|
| 1449 | + // publish box |
|
| 1450 | + $publish_box_extra_args = array( |
|
| 1451 | + 'view_approved_reg_url' => add_query_arg( |
|
| 1452 | + array( |
|
| 1453 | + 'action' => 'default', |
|
| 1454 | + 'event_id' => $this->_cpt_model_obj->ID(), |
|
| 1455 | + '_reg_status' => EEM_Registration::status_id_approved, |
|
| 1456 | + ), |
|
| 1457 | + REG_ADMIN_URL |
|
| 1458 | + ), |
|
| 1459 | + 'view_not_approved_reg_url' => add_query_arg( |
|
| 1460 | + array( |
|
| 1461 | + 'action' => 'default', |
|
| 1462 | + 'event_id' => $this->_cpt_model_obj->ID(), |
|
| 1463 | + '_reg_status' => EEM_Registration::status_id_not_approved, |
|
| 1464 | + ), |
|
| 1465 | + REG_ADMIN_URL |
|
| 1466 | + ), |
|
| 1467 | + 'view_pending_payment_reg_url' => add_query_arg( |
|
| 1468 | + array( |
|
| 1469 | + 'action' => 'default', |
|
| 1470 | + 'event_id' => $this->_cpt_model_obj->ID(), |
|
| 1471 | + '_reg_status' => EEM_Registration::status_id_pending_payment, |
|
| 1472 | + ), |
|
| 1473 | + REG_ADMIN_URL |
|
| 1474 | + ), |
|
| 1475 | + 'approved_regs' => $this->_cpt_model_obj->count_related( |
|
| 1476 | + 'Registration', |
|
| 1477 | + $approved_query_args |
|
| 1478 | + ), |
|
| 1479 | + 'not_approved_regs' => $this->_cpt_model_obj->count_related( |
|
| 1480 | + 'Registration', |
|
| 1481 | + $not_approved_query_args |
|
| 1482 | + ), |
|
| 1483 | + 'pending_payment_regs' => $this->_cpt_model_obj->count_related( |
|
| 1484 | + 'Registration', |
|
| 1485 | + $pending_payment_query_args |
|
| 1486 | + ), |
|
| 1487 | + 'misc_pub_section_class' => apply_filters( |
|
| 1488 | + 'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class', |
|
| 1489 | + 'misc-pub-section' |
|
| 1490 | + ), |
|
| 1491 | + ); |
|
| 1492 | + ob_start(); |
|
| 1493 | + do_action( |
|
| 1494 | + 'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add', |
|
| 1495 | + $this->_cpt_model_obj |
|
| 1496 | + ); |
|
| 1497 | + $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean(); |
|
| 1498 | + // load template |
|
| 1499 | + EEH_Template::display_template( |
|
| 1500 | + EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php', |
|
| 1501 | + $publish_box_extra_args |
|
| 1502 | + ); |
|
| 1503 | + } |
|
| 1504 | + |
|
| 1505 | + |
|
| 1506 | + /** |
|
| 1507 | + * @return EE_Event |
|
| 1508 | + */ |
|
| 1509 | + public function get_event_object() |
|
| 1510 | + { |
|
| 1511 | + return $this->_cpt_model_obj; |
|
| 1512 | + } |
|
| 1513 | + |
|
| 1514 | + |
|
| 1515 | + |
|
| 1516 | + |
|
| 1517 | + /** METABOXES * */ |
|
| 1518 | + /** |
|
| 1519 | + * _register_event_editor_meta_boxes |
|
| 1520 | + * add all metaboxes related to the event_editor |
|
| 1521 | + * |
|
| 1522 | + * @return void |
|
| 1523 | + */ |
|
| 1524 | + protected function _register_event_editor_meta_boxes() |
|
| 1525 | + { |
|
| 1526 | + $this->verify_cpt_object(); |
|
| 1527 | + add_meta_box( |
|
| 1528 | + 'espresso_event_editor_tickets', |
|
| 1529 | + esc_html__('Event Datetime & Ticket', 'event_espresso'), |
|
| 1530 | + array($this, 'ticket_metabox'), |
|
| 1531 | + $this->page_slug, |
|
| 1532 | + 'normal', |
|
| 1533 | + 'high' |
|
| 1534 | + ); |
|
| 1535 | + add_meta_box( |
|
| 1536 | + 'espresso_event_editor_event_options', |
|
| 1537 | + esc_html__('Event Registration Options', 'event_espresso'), |
|
| 1538 | + array($this, 'registration_options_meta_box'), |
|
| 1539 | + $this->page_slug, |
|
| 1540 | + 'side', |
|
| 1541 | + 'default' |
|
| 1542 | + ); |
|
| 1543 | + // NOTE: if you're looking for other metaboxes in here, |
|
| 1544 | + // where a metabox has a related management page in the admin |
|
| 1545 | + // you will find it setup in the related management page's "_Hooks" file. |
|
| 1546 | + // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php". |
|
| 1547 | + } |
|
| 1548 | + |
|
| 1549 | + |
|
| 1550 | + /** |
|
| 1551 | + * @throws DomainException |
|
| 1552 | + * @throws EE_Error |
|
| 1553 | + */ |
|
| 1554 | + public function ticket_metabox() |
|
| 1555 | + { |
|
| 1556 | + $existing_datetime_ids = $existing_ticket_ids = array(); |
|
| 1557 | + // defaults for template args |
|
| 1558 | + $template_args = array( |
|
| 1559 | + 'existing_datetime_ids' => '', |
|
| 1560 | + 'event_datetime_help_link' => '', |
|
| 1561 | + 'ticket_options_help_link' => '', |
|
| 1562 | + 'time' => null, |
|
| 1563 | + 'ticket_rows' => '', |
|
| 1564 | + 'existing_ticket_ids' => '', |
|
| 1565 | + 'total_ticket_rows' => 1, |
|
| 1566 | + 'ticket_js_structure' => '', |
|
| 1567 | + 'trash_icon' => 'ee-lock-icon', |
|
| 1568 | + 'disabled' => '', |
|
| 1569 | + ); |
|
| 1570 | + $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null; |
|
| 1571 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1572 | + /** |
|
| 1573 | + * 1. Start with retrieving Datetimes |
|
| 1574 | + * 2. Fore each datetime get related tickets |
|
| 1575 | + * 3. For each ticket get related prices |
|
| 1576 | + */ |
|
| 1577 | + $times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id); |
|
| 1578 | + /** @type EE_Datetime $first_datetime */ |
|
| 1579 | + $first_datetime = reset($times); |
|
| 1580 | + // do we get related tickets? |
|
| 1581 | + if ($first_datetime instanceof EE_Datetime |
|
| 1582 | + && $first_datetime->ID() !== 0 |
|
| 1583 | + ) { |
|
| 1584 | + $existing_datetime_ids[] = $first_datetime->get('DTT_ID'); |
|
| 1585 | + $template_args['time'] = $first_datetime; |
|
| 1586 | + $related_tickets = $first_datetime->tickets( |
|
| 1587 | + array( |
|
| 1588 | + array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)), |
|
| 1589 | + 'default_where_conditions' => 'none', |
|
| 1590 | + ) |
|
| 1591 | + ); |
|
| 1592 | + if (! empty($related_tickets)) { |
|
| 1593 | + $template_args['total_ticket_rows'] = count($related_tickets); |
|
| 1594 | + $row = 0; |
|
| 1595 | + foreach ($related_tickets as $ticket) { |
|
| 1596 | + $existing_ticket_ids[] = $ticket->get('TKT_ID'); |
|
| 1597 | + $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row); |
|
| 1598 | + $row++; |
|
| 1599 | + } |
|
| 1600 | + } else { |
|
| 1601 | + $template_args['total_ticket_rows'] = 1; |
|
| 1602 | + /** @type EE_Ticket $ticket */ |
|
| 1603 | + $ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object(); |
|
| 1604 | + $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket); |
|
| 1605 | + } |
|
| 1606 | + } else { |
|
| 1607 | + $template_args['time'] = $times[0]; |
|
| 1608 | + /** @type EE_Ticket $ticket */ |
|
| 1609 | + $ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets(); |
|
| 1610 | + $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]); |
|
| 1611 | + // NOTE: we're just sending the first default row |
|
| 1612 | + // (decaf can't manage default tickets so this should be sufficient); |
|
| 1613 | + } |
|
| 1614 | + $template_args['event_datetime_help_link'] = $this->_get_help_tab_link( |
|
| 1615 | + 'event_editor_event_datetimes_help_tab' |
|
| 1616 | + ); |
|
| 1617 | + $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info'); |
|
| 1618 | + $template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids); |
|
| 1619 | + $template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids); |
|
| 1620 | + $template_args['ticket_js_structure'] = $this->_get_ticket_row( |
|
| 1621 | + EE_Registry::instance()->load_model('Ticket')->create_default_object(), |
|
| 1622 | + true |
|
| 1623 | + ); |
|
| 1624 | + $template = apply_filters( |
|
| 1625 | + 'FHEE__Events_Admin_Page__ticket_metabox__template', |
|
| 1626 | + EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php' |
|
| 1627 | + ); |
|
| 1628 | + EEH_Template::display_template($template, $template_args); |
|
| 1629 | + } |
|
| 1630 | + |
|
| 1631 | + |
|
| 1632 | + /** |
|
| 1633 | + * Setup an individual ticket form for the decaf event editor page |
|
| 1634 | + * |
|
| 1635 | + * @access private |
|
| 1636 | + * @param EE_Ticket $ticket the ticket object |
|
| 1637 | + * @param boolean $skeleton whether we're generating a skeleton for js manipulation |
|
| 1638 | + * @param int $row |
|
| 1639 | + * @return string generated html for the ticket row. |
|
| 1640 | + */ |
|
| 1641 | + private function _get_ticket_row($ticket, $skeleton = false, $row = 0) |
|
| 1642 | + { |
|
| 1643 | + $template_args = array( |
|
| 1644 | + 'tkt_status_class' => ' tkt-status-' . $ticket->ticket_status(), |
|
| 1645 | + 'tkt_archive_class' => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived' |
|
| 1646 | + : '', |
|
| 1647 | + 'ticketrow' => $skeleton ? 'TICKETNUM' : $row, |
|
| 1648 | + 'TKT_ID' => $ticket->get('TKT_ID'), |
|
| 1649 | + 'TKT_name' => $ticket->get('TKT_name'), |
|
| 1650 | + 'TKT_start_date' => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'), |
|
| 1651 | + 'TKT_end_date' => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'), |
|
| 1652 | + 'TKT_is_default' => $ticket->get('TKT_is_default'), |
|
| 1653 | + 'TKT_qty' => $ticket->get_pretty('TKT_qty', 'input'), |
|
| 1654 | + 'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets', |
|
| 1655 | + 'TKT_sold' => $skeleton ? 0 : $ticket->get('TKT_sold'), |
|
| 1656 | + 'trash_icon' => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted'))) |
|
| 1657 | + && (! empty($ticket) && $ticket->get('TKT_sold') === 0) |
|
| 1658 | + ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon', |
|
| 1659 | + 'disabled' => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? '' |
|
| 1660 | + : ' disabled=disabled', |
|
| 1661 | + ); |
|
| 1662 | + $price = $ticket->ID() !== 0 |
|
| 1663 | + ? $ticket->get_first_related('Price', array('default_where_conditions' => 'none')) |
|
| 1664 | + : EE_Registry::instance()->load_model('Price')->create_default_object(); |
|
| 1665 | + $price_args = array( |
|
| 1666 | + 'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign, |
|
| 1667 | + 'PRC_amount' => $price->get('PRC_amount'), |
|
| 1668 | + 'PRT_ID' => $price->get('PRT_ID'), |
|
| 1669 | + 'PRC_ID' => $price->get('PRC_ID'), |
|
| 1670 | + 'PRC_is_default' => $price->get('PRC_is_default'), |
|
| 1671 | + ); |
|
| 1672 | + // make sure we have default start and end dates if skeleton |
|
| 1673 | + // handle rows that should NOT be empty |
|
| 1674 | + if (empty($template_args['TKT_start_date'])) { |
|
| 1675 | + // if empty then the start date will be now. |
|
| 1676 | + $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp')); |
|
| 1677 | + } |
|
| 1678 | + if (empty($template_args['TKT_end_date'])) { |
|
| 1679 | + // get the earliest datetime (if present); |
|
| 1680 | + $earliest_dtt = $this->_cpt_model_obj->ID() > 0 |
|
| 1681 | + ? $this->_cpt_model_obj->get_first_related( |
|
| 1682 | + 'Datetime', |
|
| 1683 | + array('order_by' => array('DTT_EVT_start' => 'ASC')) |
|
| 1684 | + ) |
|
| 1685 | + : null; |
|
| 1686 | + if (! empty($earliest_dtt)) { |
|
| 1687 | + $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a'); |
|
| 1688 | + } else { |
|
| 1689 | + $template_args['TKT_end_date'] = date( |
|
| 1690 | + 'Y-m-d h:i a', |
|
| 1691 | + mktime(0, 0, 0, date("m"), date("d") + 7, date("Y")) |
|
| 1692 | + ); |
|
| 1693 | + } |
|
| 1694 | + } |
|
| 1695 | + $template_args = array_merge($template_args, $price_args); |
|
| 1696 | + $template = apply_filters( |
|
| 1697 | + 'FHEE__Events_Admin_Page__get_ticket_row__template', |
|
| 1698 | + EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php', |
|
| 1699 | + $ticket |
|
| 1700 | + ); |
|
| 1701 | + return EEH_Template::display_template($template, $template_args, true); |
|
| 1702 | + } |
|
| 1703 | + |
|
| 1704 | + |
|
| 1705 | + /** |
|
| 1706 | + * @throws DomainException |
|
| 1707 | + */ |
|
| 1708 | + public function registration_options_meta_box() |
|
| 1709 | + { |
|
| 1710 | + $yes_no_values = array( |
|
| 1711 | + array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')), |
|
| 1712 | + array('id' => false, 'text' => esc_html__('No', 'event_espresso')), |
|
| 1713 | + ); |
|
| 1714 | + $default_reg_status_values = EEM_Registration::reg_status_array( |
|
| 1715 | + array( |
|
| 1716 | + EEM_Registration::status_id_cancelled, |
|
| 1717 | + EEM_Registration::status_id_declined, |
|
| 1718 | + EEM_Registration::status_id_incomplete, |
|
| 1719 | + ), |
|
| 1720 | + true |
|
| 1721 | + ); |
|
| 1722 | + // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active()); |
|
| 1723 | + $template_args['_event'] = $this->_cpt_model_obj; |
|
| 1724 | + $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false); |
|
| 1725 | + $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit(); |
|
| 1726 | + $template_args['default_registration_status'] = EEH_Form_Fields::select_input( |
|
| 1727 | + 'default_reg_status', |
|
| 1728 | + $default_reg_status_values, |
|
| 1729 | + $this->_cpt_model_obj->default_registration_status() |
|
| 1730 | + ); |
|
| 1731 | + $template_args['display_description'] = EEH_Form_Fields::select_input( |
|
| 1732 | + 'display_desc', |
|
| 1733 | + $yes_no_values, |
|
| 1734 | + $this->_cpt_model_obj->display_description() |
|
| 1735 | + ); |
|
| 1736 | + $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input( |
|
| 1737 | + 'display_ticket_selector', |
|
| 1738 | + $yes_no_values, |
|
| 1739 | + $this->_cpt_model_obj->display_ticket_selector(), |
|
| 1740 | + '', |
|
| 1741 | + '', |
|
| 1742 | + false |
|
| 1743 | + ); |
|
| 1744 | + $template_args['additional_registration_options'] = apply_filters( |
|
| 1745 | + 'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options', |
|
| 1746 | + '', |
|
| 1747 | + $template_args, |
|
| 1748 | + $yes_no_values, |
|
| 1749 | + $default_reg_status_values |
|
| 1750 | + ); |
|
| 1751 | + EEH_Template::display_template( |
|
| 1752 | + EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php', |
|
| 1753 | + $template_args |
|
| 1754 | + ); |
|
| 1755 | + } |
|
| 1756 | + |
|
| 1757 | + |
|
| 1758 | + /** |
|
| 1759 | + * _get_events() |
|
| 1760 | + * This method simply returns all the events (for the given _view and paging) |
|
| 1761 | + * |
|
| 1762 | + * @access public |
|
| 1763 | + * @param int $per_page count of items per page (20 default); |
|
| 1764 | + * @param int $current_page what is the current page being viewed. |
|
| 1765 | + * @param bool $count if TRUE then we just return a count of ALL events matching the given _view. |
|
| 1766 | + * If FALSE then we return an array of event objects |
|
| 1767 | + * that match the given _view and paging parameters. |
|
| 1768 | + * @return array an array of event objects. |
|
| 1769 | + */ |
|
| 1770 | + public function get_events($per_page = 10, $current_page = 1, $count = false) |
|
| 1771 | + { |
|
| 1772 | + $EEME = $this->_event_model(); |
|
| 1773 | + $offset = ($current_page - 1) * $per_page; |
|
| 1774 | + $limit = $count ? null : $offset . ',' . $per_page; |
|
| 1775 | + $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID'; |
|
| 1776 | + $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC"; |
|
| 1777 | + if (isset($this->_req_data['month_range'])) { |
|
| 1778 | + $pieces = explode(' ', $this->_req_data['month_range'], 3); |
|
| 1779 | + // simulate the FIRST day of the month, that fixes issues for months like February |
|
| 1780 | + // where PHP doesn't know what to assume for date. |
|
| 1781 | + // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437 |
|
| 1782 | + $month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : ''; |
|
| 1783 | + $year_r = ! empty($pieces[1]) ? $pieces[1] : ''; |
|
| 1784 | + } |
|
| 1785 | + $where = array(); |
|
| 1786 | + $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null; |
|
| 1787 | + // determine what post_status our condition will have for the query. |
|
| 1788 | + switch ($status) { |
|
| 1789 | + case 'month': |
|
| 1790 | + case 'today': |
|
| 1791 | + case null: |
|
| 1792 | + case 'all': |
|
| 1793 | + break; |
|
| 1794 | + case 'draft': |
|
| 1795 | + $where['status'] = array('IN', array('draft', 'auto-draft')); |
|
| 1796 | + break; |
|
| 1797 | + default: |
|
| 1798 | + $where['status'] = $status; |
|
| 1799 | + } |
|
| 1800 | + // categories? |
|
| 1801 | + $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0 |
|
| 1802 | + ? $this->_req_data['EVT_CAT'] : null; |
|
| 1803 | + if (! empty($category)) { |
|
| 1804 | + $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY; |
|
| 1805 | + $where['Term_Taxonomy.term_id'] = $category; |
|
| 1806 | + } |
|
| 1807 | + // date where conditions |
|
| 1808 | + $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start'); |
|
| 1809 | + if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') { |
|
| 1810 | + $DateTime = new DateTime( |
|
| 1811 | + $year_r . '-' . $month_r . '-01 00:00:00', |
|
| 1812 | + new DateTimeZone(EEM_Datetime::instance()->get_timezone()) |
|
| 1813 | + ); |
|
| 1814 | + $start = $DateTime->format(implode(' ', $start_formats)); |
|
| 1815 | + $end = $DateTime->setDate( |
|
| 1816 | + $year_r, |
|
| 1817 | + $month_r, |
|
| 1818 | + $DateTime |
|
| 1819 | + ->format('t') |
|
| 1820 | + )->setTime(23, 59, 59) |
|
| 1821 | + ->format(implode(' ', $start_formats)); |
|
| 1822 | + $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end)); |
|
| 1823 | + } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') { |
|
| 1824 | + $DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone())); |
|
| 1825 | + $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats)); |
|
| 1826 | + $end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats)); |
|
| 1827 | + $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end)); |
|
| 1828 | + } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') { |
|
| 1829 | + $now = date('Y-m-01'); |
|
| 1830 | + $DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone())); |
|
| 1831 | + $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats)); |
|
| 1832 | + $end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t')) |
|
| 1833 | + ->setTime(23, 59, 59) |
|
| 1834 | + ->format(implode(' ', $start_formats)); |
|
| 1835 | + $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end)); |
|
| 1836 | + } |
|
| 1837 | + if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) { |
|
| 1838 | + $where['EVT_wp_user'] = get_current_user_id(); |
|
| 1839 | + } else { |
|
| 1840 | + if (! isset($where['status'])) { |
|
| 1841 | + if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) { |
|
| 1842 | + $where['OR'] = array( |
|
| 1843 | + 'status*restrict_private' => array('!=', 'private'), |
|
| 1844 | + 'AND' => array( |
|
| 1845 | + 'status*inclusive' => array('=', 'private'), |
|
| 1846 | + 'EVT_wp_user' => get_current_user_id(), |
|
| 1847 | + ), |
|
| 1848 | + ); |
|
| 1849 | + } |
|
| 1850 | + } |
|
| 1851 | + } |
|
| 1852 | + if (isset($this->_req_data['EVT_wp_user'])) { |
|
| 1853 | + if ($this->_req_data['EVT_wp_user'] != get_current_user_id() |
|
| 1854 | + && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events') |
|
| 1855 | + ) { |
|
| 1856 | + $where['EVT_wp_user'] = $this->_req_data['EVT_wp_user']; |
|
| 1857 | + } |
|
| 1858 | + } |
|
| 1859 | + // search query handling |
|
| 1860 | + if (isset($this->_req_data['s'])) { |
|
| 1861 | + $search_string = '%' . $this->_req_data['s'] . '%'; |
|
| 1862 | + $where['OR'] = array( |
|
| 1863 | + 'EVT_name' => array('LIKE', $search_string), |
|
| 1864 | + 'EVT_desc' => array('LIKE', $search_string), |
|
| 1865 | + 'EVT_short_desc' => array('LIKE', $search_string), |
|
| 1866 | + ); |
|
| 1867 | + } |
|
| 1868 | + // filter events by venue. |
|
| 1869 | + if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) { |
|
| 1870 | + $where['Venue.VNU_ID'] = absint($this->_req_data['venue']); |
|
| 1871 | + } |
|
| 1872 | + $where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data); |
|
| 1873 | + $query_params = apply_filters( |
|
| 1874 | + 'FHEE__Events_Admin_Page__get_events__query_params', |
|
| 1875 | + array( |
|
| 1876 | + $where, |
|
| 1877 | + 'limit' => $limit, |
|
| 1878 | + 'order_by' => $orderby, |
|
| 1879 | + 'order' => $order, |
|
| 1880 | + 'group_by' => 'EVT_ID', |
|
| 1881 | + ), |
|
| 1882 | + $this->_req_data |
|
| 1883 | + ); |
|
| 1884 | + // let's first check if we have special requests coming in. |
|
| 1885 | + if (isset($this->_req_data['active_status'])) { |
|
| 1886 | + switch ($this->_req_data['active_status']) { |
|
| 1887 | + case 'upcoming': |
|
| 1888 | + return $EEME->get_upcoming_events($query_params, $count); |
|
| 1889 | + break; |
|
| 1890 | + case 'expired': |
|
| 1891 | + return $EEME->get_expired_events($query_params, $count); |
|
| 1892 | + break; |
|
| 1893 | + case 'active': |
|
| 1894 | + return $EEME->get_active_events($query_params, $count); |
|
| 1895 | + break; |
|
| 1896 | + case 'inactive': |
|
| 1897 | + return $EEME->get_inactive_events($query_params, $count); |
|
| 1898 | + break; |
|
| 1899 | + } |
|
| 1900 | + } |
|
| 1901 | + |
|
| 1902 | + $events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params); |
|
| 1903 | + return $events; |
|
| 1904 | + } |
|
| 1905 | + |
|
| 1906 | + |
|
| 1907 | + /** |
|
| 1908 | + * handling for WordPress CPT actions (trash, restore, delete) |
|
| 1909 | + * |
|
| 1910 | + * @param string $post_id |
|
| 1911 | + */ |
|
| 1912 | + public function trash_cpt_item($post_id) |
|
| 1913 | + { |
|
| 1914 | + $this->_req_data['EVT_ID'] = $post_id; |
|
| 1915 | + $this->_trash_or_restore_event('trash', false); |
|
| 1916 | + } |
|
| 1917 | + |
|
| 1918 | + |
|
| 1919 | + /** |
|
| 1920 | + * @param string $post_id |
|
| 1921 | + */ |
|
| 1922 | + public function restore_cpt_item($post_id) |
|
| 1923 | + { |
|
| 1924 | + $this->_req_data['EVT_ID'] = $post_id; |
|
| 1925 | + $this->_trash_or_restore_event('draft', false); |
|
| 1926 | + } |
|
| 1927 | + |
|
| 1928 | + |
|
| 1929 | + /** |
|
| 1930 | + * @param string $post_id |
|
| 1931 | + */ |
|
| 1932 | + public function delete_cpt_item($post_id) |
|
| 1933 | + { |
|
| 1934 | + throw new EE_Error(esc_html__('Please contact Event Espresso support with the details of the steps taken to produce this error.', 'event_espresso')); |
|
| 1935 | + $this->_req_data['EVT_ID'] = $post_id; |
|
| 1936 | + $this->_delete_event(); |
|
| 1937 | + } |
|
| 1938 | + |
|
| 1939 | + |
|
| 1940 | + /** |
|
| 1941 | + * _trash_or_restore_event |
|
| 1942 | + * |
|
| 1943 | + * @access protected |
|
| 1944 | + * @param string $event_status |
|
| 1945 | + * @param bool $redirect_after |
|
| 1946 | + */ |
|
| 1947 | + protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true) |
|
| 1948 | + { |
|
| 1949 | + // determine the event id and set to array. |
|
| 1950 | + $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false; |
|
| 1951 | + // loop thru events |
|
| 1952 | + if ($EVT_ID) { |
|
| 1953 | + // clean status |
|
| 1954 | + $event_status = sanitize_key($event_status); |
|
| 1955 | + // grab status |
|
| 1956 | + if (! empty($event_status)) { |
|
| 1957 | + $success = $this->_change_event_status($EVT_ID, $event_status); |
|
| 1958 | + } else { |
|
| 1959 | + $success = false; |
|
| 1960 | + $msg = esc_html__( |
|
| 1961 | + 'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.', |
|
| 1962 | + 'event_espresso' |
|
| 1963 | + ); |
|
| 1964 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 1965 | + } |
|
| 1966 | + } else { |
|
| 1967 | + $success = false; |
|
| 1968 | + $msg = esc_html__( |
|
| 1969 | + 'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.', |
|
| 1970 | + 'event_espresso' |
|
| 1971 | + ); |
|
| 1972 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 1973 | + } |
|
| 1974 | + $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash'; |
|
| 1975 | + if ($redirect_after) { |
|
| 1976 | + $this->_redirect_after_action($success, 'Event', $action, array('action' => 'default')); |
|
| 1977 | + } |
|
| 1978 | + } |
|
| 1979 | + |
|
| 1980 | + |
|
| 1981 | + /** |
|
| 1982 | + * _trash_or_restore_events |
|
| 1983 | + * |
|
| 1984 | + * @access protected |
|
| 1985 | + * @param string $event_status |
|
| 1986 | + * @return void |
|
| 1987 | + */ |
|
| 1988 | + protected function _trash_or_restore_events($event_status = 'trash') |
|
| 1989 | + { |
|
| 1990 | + // clean status |
|
| 1991 | + $event_status = sanitize_key($event_status); |
|
| 1992 | + // grab status |
|
| 1993 | + if (! empty($event_status)) { |
|
| 1994 | + $success = true; |
|
| 1995 | + // determine the event id and set to array. |
|
| 1996 | + $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array(); |
|
| 1997 | + // loop thru events |
|
| 1998 | + foreach ($EVT_IDs as $EVT_ID) { |
|
| 1999 | + if ($EVT_ID = absint($EVT_ID)) { |
|
| 2000 | + $results = $this->_change_event_status($EVT_ID, $event_status); |
|
| 2001 | + $success = $results !== false ? $success : false; |
|
| 2002 | + } else { |
|
| 2003 | + $msg = sprintf( |
|
| 2004 | + esc_html__( |
|
| 2005 | + 'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.', |
|
| 2006 | + 'event_espresso' |
|
| 2007 | + ), |
|
| 2008 | + $EVT_ID |
|
| 2009 | + ); |
|
| 2010 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2011 | + $success = false; |
|
| 2012 | + } |
|
| 2013 | + } |
|
| 2014 | + } else { |
|
| 2015 | + $success = false; |
|
| 2016 | + $msg = esc_html__( |
|
| 2017 | + 'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.', |
|
| 2018 | + 'event_espresso' |
|
| 2019 | + ); |
|
| 2020 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2021 | + } |
|
| 2022 | + // in order to force a pluralized result message we need to send back a success status greater than 1 |
|
| 2023 | + $success = $success ? 2 : false; |
|
| 2024 | + $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash'; |
|
| 2025 | + $this->_redirect_after_action($success, 'Events', $action, array('action' => 'default')); |
|
| 2026 | + } |
|
| 2027 | + |
|
| 2028 | + |
|
| 2029 | + /** |
|
| 2030 | + * _trash_or_restore_events |
|
| 2031 | + * |
|
| 2032 | + * @access private |
|
| 2033 | + * @param int $EVT_ID |
|
| 2034 | + * @param string $event_status |
|
| 2035 | + * @return bool |
|
| 2036 | + */ |
|
| 2037 | + private function _change_event_status($EVT_ID = 0, $event_status = '') |
|
| 2038 | + { |
|
| 2039 | + // grab event id |
|
| 2040 | + if (! $EVT_ID) { |
|
| 2041 | + $msg = esc_html__( |
|
| 2042 | + 'An error occurred. No Event ID or an invalid Event ID was received.', |
|
| 2043 | + 'event_espresso' |
|
| 2044 | + ); |
|
| 2045 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2046 | + return false; |
|
| 2047 | + } |
|
| 2048 | + $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID); |
|
| 2049 | + // clean status |
|
| 2050 | + $event_status = sanitize_key($event_status); |
|
| 2051 | + // grab status |
|
| 2052 | + if (empty($event_status)) { |
|
| 2053 | + $msg = esc_html__( |
|
| 2054 | + 'An error occurred. No Event Status or an invalid Event Status was received.', |
|
| 2055 | + 'event_espresso' |
|
| 2056 | + ); |
|
| 2057 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2058 | + return false; |
|
| 2059 | + } |
|
| 2060 | + // was event trashed or restored ? |
|
| 2061 | + switch ($event_status) { |
|
| 2062 | + case 'draft': |
|
| 2063 | + $action = 'restored from the trash'; |
|
| 2064 | + $hook = 'AHEE_event_restored_from_trash'; |
|
| 2065 | + break; |
|
| 2066 | + case 'trash': |
|
| 2067 | + $action = 'moved to the trash'; |
|
| 2068 | + $hook = 'AHEE_event_moved_to_trash'; |
|
| 2069 | + break; |
|
| 2070 | + default: |
|
| 2071 | + $action = 'updated'; |
|
| 2072 | + $hook = false; |
|
| 2073 | + } |
|
| 2074 | + // use class to change status |
|
| 2075 | + $this->_cpt_model_obj->set_status($event_status); |
|
| 2076 | + $success = $this->_cpt_model_obj->save(); |
|
| 2077 | + if ($success === false) { |
|
| 2078 | + $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action); |
|
| 2079 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2080 | + return false; |
|
| 2081 | + } |
|
| 2082 | + if ($hook) { |
|
| 2083 | + do_action($hook); |
|
| 2084 | + } |
|
| 2085 | + return true; |
|
| 2086 | + } |
|
| 2087 | + |
|
| 2088 | + |
|
| 2089 | + /** |
|
| 2090 | + * _delete_event |
|
| 2091 | + * |
|
| 2092 | + * @access protected |
|
| 2093 | + * @param bool $redirect_after |
|
| 2094 | + */ |
|
| 2095 | + protected function _delete_event() |
|
| 2096 | + { |
|
| 2097 | + $this->generateDeletionPreview(isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : array()); |
|
| 2098 | + } |
|
| 2099 | + |
|
| 2100 | + /** |
|
| 2101 | + * Gets the tree traversal batch persister. |
|
| 2102 | + * @since $VID:$ |
|
| 2103 | + * @return NodeGroupDao |
|
| 2104 | + * @throws InvalidArgumentException |
|
| 2105 | + * @throws InvalidDataTypeException |
|
| 2106 | + * @throws InvalidInterfaceException |
|
| 2107 | + */ |
|
| 2108 | + protected function getModelObjNodeGroupPersister() |
|
| 2109 | + { |
|
| 2110 | + if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) { |
|
| 2111 | + $this->model_obj_node_group_persister = $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao'); |
|
| 2112 | + } |
|
| 2113 | + return $this->model_obj_node_group_persister; |
|
| 2114 | + } |
|
| 2115 | + |
|
| 2116 | + /** |
|
| 2117 | + * _delete_events |
|
| 2118 | + * |
|
| 2119 | + * @access protected |
|
| 2120 | + * @return void |
|
| 2121 | + */ |
|
| 2122 | + protected function _delete_events() |
|
| 2123 | + { |
|
| 2124 | + $this->generateDeletionPreview(isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array()); |
|
| 2125 | + } |
|
| 2126 | + |
|
| 2127 | + protected function generateDeletionPreview($event_ids) |
|
| 2128 | + { |
|
| 2129 | + $event_ids = (array) $event_ids; |
|
| 2130 | + // Set a code we can use to reference this deletion task in the batch jobs and preview page. |
|
| 2131 | + $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode(); |
|
| 2132 | + $return_url = EE_Admin_Page::add_query_args_and_nonce( |
|
| 2133 | + [ |
|
| 2134 | + 'action' => 'preview_deletion', |
|
| 2135 | + 'deletion_job_code' => $deletion_job_code, |
|
| 2136 | + ], |
|
| 2137 | + $this->_admin_base_url |
|
| 2138 | + ); |
|
| 2139 | + $event_ids = array_map( |
|
| 2140 | + 'intval', |
|
| 2141 | + $event_ids |
|
| 2142 | + ); |
|
| 2143 | + |
|
| 2144 | + EEH_URL::safeRedirectAndExit( |
|
| 2145 | + EE_Admin_Page::add_query_args_and_nonce( |
|
| 2146 | + array( |
|
| 2147 | + 'page' => 'espresso_batch', |
|
| 2148 | + 'batch' => EED_Batch::batch_job, |
|
| 2149 | + 'EVT_IDs' => $event_ids, |
|
| 2150 | + 'deletion_job_code' => $deletion_job_code, |
|
| 2151 | + 'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'), |
|
| 2152 | + 'return_url' => urlencode($return_url), |
|
| 2153 | + ), |
|
| 2154 | + admin_url() |
|
| 2155 | + ) |
|
| 2156 | + ); |
|
| 2157 | + } |
|
| 2158 | + |
|
| 2159 | + /** |
|
| 2160 | + * Checks for a POST submission |
|
| 2161 | + * @since $VID:$ |
|
| 2162 | + */ |
|
| 2163 | + protected function confirmDeletion() |
|
| 2164 | + { |
|
| 2165 | + $deletion_redirect_logic = $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'); |
|
| 2166 | + $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url()); |
|
| 2167 | + } |
|
| 2168 | + |
|
| 2169 | + /** |
|
| 2170 | + * A page for users to preview what exactly will be deleted, and confirm they want to delete it. |
|
| 2171 | + * @since $VID:$ |
|
| 2172 | + * @throws EE_Error |
|
| 2173 | + */ |
|
| 2174 | + protected function previewDeletion() |
|
| 2175 | + { |
|
| 2176 | + $preview_deletion_logic = $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'); |
|
| 2177 | + $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url())); |
|
| 2178 | + $this->display_admin_page_with_no_sidebar(); |
|
| 2179 | + } |
|
| 2180 | + |
|
| 2181 | + /** |
|
| 2182 | + * get total number of events |
|
| 2183 | + * |
|
| 2184 | + * @access public |
|
| 2185 | + * @return int |
|
| 2186 | + */ |
|
| 2187 | + public function total_events() |
|
| 2188 | + { |
|
| 2189 | + $count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true); |
|
| 2190 | + return $count; |
|
| 2191 | + } |
|
| 2192 | + |
|
| 2193 | + |
|
| 2194 | + /** |
|
| 2195 | + * get total number of draft events |
|
| 2196 | + * |
|
| 2197 | + * @access public |
|
| 2198 | + * @return int |
|
| 2199 | + */ |
|
| 2200 | + public function total_events_draft() |
|
| 2201 | + { |
|
| 2202 | + $where = array( |
|
| 2203 | + 'status' => array('IN', array('draft', 'auto-draft')), |
|
| 2204 | + ); |
|
| 2205 | + $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true); |
|
| 2206 | + return $count; |
|
| 2207 | + } |
|
| 2208 | + |
|
| 2209 | + |
|
| 2210 | + /** |
|
| 2211 | + * get total number of trashed events |
|
| 2212 | + * |
|
| 2213 | + * @access public |
|
| 2214 | + * @return int |
|
| 2215 | + */ |
|
| 2216 | + public function total_trashed_events() |
|
| 2217 | + { |
|
| 2218 | + $where = array( |
|
| 2219 | + 'status' => 'trash', |
|
| 2220 | + ); |
|
| 2221 | + $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true); |
|
| 2222 | + return $count; |
|
| 2223 | + } |
|
| 2224 | + |
|
| 2225 | + |
|
| 2226 | + /** |
|
| 2227 | + * _default_event_settings |
|
| 2228 | + * This generates the Default Settings Tab |
|
| 2229 | + * |
|
| 2230 | + * @return void |
|
| 2231 | + * @throws EE_Error |
|
| 2232 | + */ |
|
| 2233 | + protected function _default_event_settings() |
|
| 2234 | + { |
|
| 2235 | + $this->_set_add_edit_form_tags('update_default_event_settings'); |
|
| 2236 | + $this->_set_publish_post_box_vars(null, false, false, null, false); |
|
| 2237 | + $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html(); |
|
| 2238 | + $this->display_admin_page_with_sidebar(); |
|
| 2239 | + } |
|
| 2240 | + |
|
| 2241 | + |
|
| 2242 | + /** |
|
| 2243 | + * Return the form for event settings. |
|
| 2244 | + * |
|
| 2245 | + * @return EE_Form_Section_Proper |
|
| 2246 | + * @throws EE_Error |
|
| 2247 | + */ |
|
| 2248 | + protected function _default_event_settings_form() |
|
| 2249 | + { |
|
| 2250 | + $registration_config = EE_Registry::instance()->CFG->registration; |
|
| 2251 | + $registration_stati_for_selection = EEM_Registration::reg_status_array( |
|
| 2252 | + // exclude |
|
| 2253 | + array( |
|
| 2254 | + EEM_Registration::status_id_cancelled, |
|
| 2255 | + EEM_Registration::status_id_declined, |
|
| 2256 | + EEM_Registration::status_id_incomplete, |
|
| 2257 | + EEM_Registration::status_id_wait_list, |
|
| 2258 | + ), |
|
| 2259 | + true |
|
| 2260 | + ); |
|
| 2261 | + return new EE_Form_Section_Proper( |
|
| 2262 | + array( |
|
| 2263 | + 'name' => 'update_default_event_settings', |
|
| 2264 | + 'html_id' => 'update_default_event_settings', |
|
| 2265 | + 'html_class' => 'form-table', |
|
| 2266 | + 'layout_strategy' => new EE_Admin_Two_Column_Layout(), |
|
| 2267 | + 'subsections' => apply_filters( |
|
| 2268 | + 'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections', |
|
| 2269 | + array( |
|
| 2270 | + 'default_reg_status' => new EE_Select_Input( |
|
| 2271 | + $registration_stati_for_selection, |
|
| 2272 | + array( |
|
| 2273 | + 'default' => isset($registration_config->default_STS_ID) |
|
| 2274 | + && array_key_exists( |
|
| 2275 | + $registration_config->default_STS_ID, |
|
| 2276 | + $registration_stati_for_selection |
|
| 2277 | + ) |
|
| 2278 | + ? sanitize_text_field($registration_config->default_STS_ID) |
|
| 2279 | + : EEM_Registration::status_id_pending_payment, |
|
| 2280 | + 'html_label_text' => esc_html__('Default Registration Status', 'event_espresso') |
|
| 2281 | + . EEH_Template::get_help_tab_link( |
|
| 2282 | + 'default_settings_status_help_tab' |
|
| 2283 | + ), |
|
| 2284 | + 'html_help_text' => esc_html__( |
|
| 2285 | + 'This setting allows you to preselect what the default registration status setting is when creating an event. Note that changing this setting does NOT retroactively apply it to existing events.', |
|
| 2286 | + 'event_espresso' |
|
| 2287 | + ), |
|
| 2288 | + ) |
|
| 2289 | + ), |
|
| 2290 | + 'default_max_tickets' => new EE_Integer_Input( |
|
| 2291 | + array( |
|
| 2292 | + 'default' => isset($registration_config->default_maximum_number_of_tickets) |
|
| 2293 | + ? $registration_config->default_maximum_number_of_tickets |
|
| 2294 | + : EEM_Event::get_default_additional_limit(), |
|
| 2295 | + 'html_label_text' => esc_html__( |
|
| 2296 | + 'Default Maximum Tickets Allowed Per Order:', |
|
| 2297 | + 'event_espresso' |
|
| 2298 | + ) |
|
| 2299 | + . EEH_Template::get_help_tab_link( |
|
| 2300 | + 'default_maximum_tickets_help_tab"' |
|
| 2301 | + ), |
|
| 2302 | + 'html_help_text' => esc_html__( |
|
| 2303 | + 'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.', |
|
| 2304 | + 'event_espresso' |
|
| 2305 | + ), |
|
| 2306 | + ) |
|
| 2307 | + ), |
|
| 2308 | + ) |
|
| 2309 | + ), |
|
| 2310 | + ) |
|
| 2311 | + ); |
|
| 2312 | + } |
|
| 2313 | + |
|
| 2314 | + |
|
| 2315 | + /** |
|
| 2316 | + * _update_default_event_settings |
|
| 2317 | + * |
|
| 2318 | + * @access protected |
|
| 2319 | + * @return void |
|
| 2320 | + * @throws EE_Error |
|
| 2321 | + */ |
|
| 2322 | + protected function _update_default_event_settings() |
|
| 2323 | + { |
|
| 2324 | + $registration_config = EE_Registry::instance()->CFG->registration; |
|
| 2325 | + $form = $this->_default_event_settings_form(); |
|
| 2326 | + if ($form->was_submitted()) { |
|
| 2327 | + $form->receive_form_submission(); |
|
| 2328 | + if ($form->is_valid()) { |
|
| 2329 | + $valid_data = $form->valid_data(); |
|
| 2330 | + if (isset($valid_data['default_reg_status'])) { |
|
| 2331 | + $registration_config->default_STS_ID = $valid_data['default_reg_status']; |
|
| 2332 | + } |
|
| 2333 | + if (isset($valid_data['default_max_tickets'])) { |
|
| 2334 | + $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets']; |
|
| 2335 | + } |
|
| 2336 | + // update because data was valid! |
|
| 2337 | + EE_Registry::instance()->CFG->update_espresso_config(); |
|
| 2338 | + EE_Error::overwrite_success(); |
|
| 2339 | + EE_Error::add_success( |
|
| 2340 | + __('Default Event Settings were updated', 'event_espresso') |
|
| 2341 | + ); |
|
| 2342 | + } |
|
| 2343 | + } |
|
| 2344 | + $this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true); |
|
| 2345 | + } |
|
| 2346 | + |
|
| 2347 | + |
|
| 2348 | + /************* Templates *************/ |
|
| 2349 | + protected function _template_settings() |
|
| 2350 | + { |
|
| 2351 | + $this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso'); |
|
| 2352 | + $this->_template_args['preview_img'] = '<img src="' |
|
| 2353 | + . EVENTS_ASSETS_URL |
|
| 2354 | + . '/images/' |
|
| 2355 | + . 'caffeinated_template_features.jpg" alt="' |
|
| 2356 | + . esc_attr__('Template Settings Preview screenshot', 'event_espresso') |
|
| 2357 | + . '" />'; |
|
| 2358 | + $this->_template_args['preview_text'] = '<strong>' |
|
| 2359 | + . esc_html__( |
|
| 2360 | + 'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.', |
|
| 2361 | + 'event_espresso' |
|
| 2362 | + ) . '</strong>'; |
|
| 2363 | + $this->display_admin_caf_preview_page('template_settings_tab'); |
|
| 2364 | + } |
|
| 2365 | + |
|
| 2366 | + |
|
| 2367 | + /** Event Category Stuff **/ |
|
| 2368 | + /** |
|
| 2369 | + * set the _category property with the category object for the loaded page. |
|
| 2370 | + * |
|
| 2371 | + * @access private |
|
| 2372 | + * @return void |
|
| 2373 | + */ |
|
| 2374 | + private function _set_category_object() |
|
| 2375 | + { |
|
| 2376 | + if (isset($this->_category->id) && ! empty($this->_category->id)) { |
|
| 2377 | + return; |
|
| 2378 | + } //already have the category object so get out. |
|
| 2379 | + // set default category object |
|
| 2380 | + $this->_set_empty_category_object(); |
|
| 2381 | + // only set if we've got an id |
|
| 2382 | + if (! isset($this->_req_data['EVT_CAT_ID'])) { |
|
| 2383 | + return; |
|
| 2384 | + } |
|
| 2385 | + $category_id = absint($this->_req_data['EVT_CAT_ID']); |
|
| 2386 | + $term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
|
| 2387 | + if (! empty($term)) { |
|
| 2388 | + $this->_category->category_name = $term->name; |
|
| 2389 | + $this->_category->category_identifier = $term->slug; |
|
| 2390 | + $this->_category->category_desc = $term->description; |
|
| 2391 | + $this->_category->id = $term->term_id; |
|
| 2392 | + $this->_category->parent = $term->parent; |
|
| 2393 | + } |
|
| 2394 | + } |
|
| 2395 | + |
|
| 2396 | + |
|
| 2397 | + /** |
|
| 2398 | + * Clears out category properties. |
|
| 2399 | + */ |
|
| 2400 | + private function _set_empty_category_object() |
|
| 2401 | + { |
|
| 2402 | + $this->_category = new stdClass(); |
|
| 2403 | + $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = ''; |
|
| 2404 | + $this->_category->id = $this->_category->parent = 0; |
|
| 2405 | + } |
|
| 2406 | + |
|
| 2407 | + |
|
| 2408 | + /** |
|
| 2409 | + * @throws EE_Error |
|
| 2410 | + */ |
|
| 2411 | + protected function _category_list_table() |
|
| 2412 | + { |
|
| 2413 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 2414 | + $this->_search_btn_label = esc_html__('Categories', 'event_espresso'); |
|
| 2415 | + $this->_admin_page_title .= ' ' . $this->get_action_link_or_button( |
|
| 2416 | + 'add_category', |
|
| 2417 | + 'add_category', |
|
| 2418 | + array(), |
|
| 2419 | + 'add-new-h2' |
|
| 2420 | + ); |
|
| 2421 | + $this->display_admin_list_table_page_with_sidebar(); |
|
| 2422 | + } |
|
| 2423 | + |
|
| 2424 | + |
|
| 2425 | + /** |
|
| 2426 | + * Output category details view. |
|
| 2427 | + */ |
|
| 2428 | + protected function _category_details($view) |
|
| 2429 | + { |
|
| 2430 | + // load formatter helper |
|
| 2431 | + // load field generator helper |
|
| 2432 | + $route = $view == 'edit' ? 'update_category' : 'insert_category'; |
|
| 2433 | + $this->_set_add_edit_form_tags($route); |
|
| 2434 | + $this->_set_category_object(); |
|
| 2435 | + $id = ! empty($this->_category->id) ? $this->_category->id : ''; |
|
| 2436 | + $delete_action = 'delete_category'; |
|
| 2437 | + // custom redirect |
|
| 2438 | + $redirect = EE_Admin_Page::add_query_args_and_nonce( |
|
| 2439 | + array('action' => 'category_list'), |
|
| 2440 | + $this->_admin_base_url |
|
| 2441 | + ); |
|
| 2442 | + $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect); |
|
| 2443 | + // take care of contents |
|
| 2444 | + $this->_template_args['admin_page_content'] = $this->_category_details_content(); |
|
| 2445 | + $this->display_admin_page_with_sidebar(); |
|
| 2446 | + } |
|
| 2447 | + |
|
| 2448 | + |
|
| 2449 | + /** |
|
| 2450 | + * Output category details content. |
|
| 2451 | + */ |
|
| 2452 | + protected function _category_details_content() |
|
| 2453 | + { |
|
| 2454 | + $editor_args['category_desc'] = array( |
|
| 2455 | + 'type' => 'wp_editor', |
|
| 2456 | + 'value' => EEH_Formatter::admin_format_content($this->_category->category_desc), |
|
| 2457 | + 'class' => 'my_editor_custom', |
|
| 2458 | + 'wpeditor_args' => array('media_buttons' => false), |
|
| 2459 | + ); |
|
| 2460 | + $_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array'); |
|
| 2461 | + $all_terms = get_terms( |
|
| 2462 | + array(EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY), |
|
| 2463 | + array('hide_empty' => 0, 'exclude' => array($this->_category->id)) |
|
| 2464 | + ); |
|
| 2465 | + // setup category select for term parents. |
|
| 2466 | + $category_select_values[] = array( |
|
| 2467 | + 'text' => esc_html__('No Parent', 'event_espresso'), |
|
| 2468 | + 'id' => 0, |
|
| 2469 | + ); |
|
| 2470 | + foreach ($all_terms as $term) { |
|
| 2471 | + $category_select_values[] = array( |
|
| 2472 | + 'text' => $term->name, |
|
| 2473 | + 'id' => $term->term_id, |
|
| 2474 | + ); |
|
| 2475 | + } |
|
| 2476 | + $category_select = EEH_Form_Fields::select_input( |
|
| 2477 | + 'category_parent', |
|
| 2478 | + $category_select_values, |
|
| 2479 | + $this->_category->parent |
|
| 2480 | + ); |
|
| 2481 | + $template_args = array( |
|
| 2482 | + 'category' => $this->_category, |
|
| 2483 | + 'category_select' => $category_select, |
|
| 2484 | + 'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'), |
|
| 2485 | + 'category_desc_editor' => $_wp_editor['category_desc']['field'], |
|
| 2486 | + 'disable' => '', |
|
| 2487 | + 'disabled_message' => false, |
|
| 2488 | + ); |
|
| 2489 | + $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php'; |
|
| 2490 | + return EEH_Template::display_template($template, $template_args, true); |
|
| 2491 | + } |
|
| 2492 | + |
|
| 2493 | + |
|
| 2494 | + /** |
|
| 2495 | + * Handles deleting categories. |
|
| 2496 | + */ |
|
| 2497 | + protected function _delete_categories() |
|
| 2498 | + { |
|
| 2499 | + $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID'] |
|
| 2500 | + : (array) $this->_req_data['category_id']; |
|
| 2501 | + foreach ($cat_ids as $cat_id) { |
|
| 2502 | + $this->_delete_category($cat_id); |
|
| 2503 | + } |
|
| 2504 | + // doesn't matter what page we're coming from... we're going to the same place after delete. |
|
| 2505 | + $query_args = array( |
|
| 2506 | + 'action' => 'category_list', |
|
| 2507 | + ); |
|
| 2508 | + $this->_redirect_after_action(0, '', '', $query_args); |
|
| 2509 | + } |
|
| 2510 | + |
|
| 2511 | + |
|
| 2512 | + /** |
|
| 2513 | + * Handles deleting specific category. |
|
| 2514 | + * |
|
| 2515 | + * @param int $cat_id |
|
| 2516 | + */ |
|
| 2517 | + protected function _delete_category($cat_id) |
|
| 2518 | + { |
|
| 2519 | + $cat_id = absint($cat_id); |
|
| 2520 | + wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
|
| 2521 | + } |
|
| 2522 | + |
|
| 2523 | + |
|
| 2524 | + /** |
|
| 2525 | + * Handles triggering the update or insertion of a new category. |
|
| 2526 | + * |
|
| 2527 | + * @param bool $new_category true means we're triggering the insert of a new category. |
|
| 2528 | + */ |
|
| 2529 | + protected function _insert_or_update_category($new_category) |
|
| 2530 | + { |
|
| 2531 | + $cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true); |
|
| 2532 | + $success = 0; // we already have a success message so lets not send another. |
|
| 2533 | + if ($cat_id) { |
|
| 2534 | + $query_args = array( |
|
| 2535 | + 'action' => 'edit_category', |
|
| 2536 | + 'EVT_CAT_ID' => $cat_id, |
|
| 2537 | + ); |
|
| 2538 | + } else { |
|
| 2539 | + $query_args = array('action' => 'add_category'); |
|
| 2540 | + } |
|
| 2541 | + $this->_redirect_after_action($success, '', '', $query_args, true); |
|
| 2542 | + } |
|
| 2543 | + |
|
| 2544 | + |
|
| 2545 | + /** |
|
| 2546 | + * Inserts or updates category |
|
| 2547 | + * |
|
| 2548 | + * @param bool $update (true indicates we're updating a category). |
|
| 2549 | + * @return bool|mixed|string |
|
| 2550 | + */ |
|
| 2551 | + private function _insert_category($update = false) |
|
| 2552 | + { |
|
| 2553 | + $cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : ''; |
|
| 2554 | + $category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : ''; |
|
| 2555 | + $category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : ''; |
|
| 2556 | + $category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0; |
|
| 2557 | + if (empty($category_name)) { |
|
| 2558 | + $msg = esc_html__('You must add a name for the category.', 'event_espresso'); |
|
| 2559 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2560 | + return false; |
|
| 2561 | + } |
|
| 2562 | + $term_args = array( |
|
| 2563 | + 'name' => $category_name, |
|
| 2564 | + 'description' => $category_desc, |
|
| 2565 | + 'parent' => $category_parent, |
|
| 2566 | + ); |
|
| 2567 | + // was the category_identifier input disabled? |
|
| 2568 | + if (isset($this->_req_data['category_identifier'])) { |
|
| 2569 | + $term_args['slug'] = $this->_req_data['category_identifier']; |
|
| 2570 | + } |
|
| 2571 | + $insert_ids = $update |
|
| 2572 | + ? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args) |
|
| 2573 | + : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args); |
|
| 2574 | + if (! is_array($insert_ids)) { |
|
| 2575 | + $msg = esc_html__( |
|
| 2576 | + 'An error occurred and the category has not been saved to the database.', |
|
| 2577 | + 'event_espresso' |
|
| 2578 | + ); |
|
| 2579 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 2580 | + } else { |
|
| 2581 | + $cat_id = $insert_ids['term_id']; |
|
| 2582 | + $msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name); |
|
| 2583 | + EE_Error::add_success($msg); |
|
| 2584 | + } |
|
| 2585 | + return $cat_id; |
|
| 2586 | + } |
|
| 2587 | + |
|
| 2588 | + |
|
| 2589 | + /** |
|
| 2590 | + * Gets categories or count of categories matching the arguments in the request. |
|
| 2591 | + * |
|
| 2592 | + * @param int $per_page |
|
| 2593 | + * @param int $current_page |
|
| 2594 | + * @param bool $count |
|
| 2595 | + * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int |
|
| 2596 | + */ |
|
| 2597 | + public function get_categories($per_page = 10, $current_page = 1, $count = false) |
|
| 2598 | + { |
|
| 2599 | + // testing term stuff |
|
| 2600 | + $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id'; |
|
| 2601 | + $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC'; |
|
| 2602 | + $limit = ($current_page - 1) * $per_page; |
|
| 2603 | + $where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY); |
|
| 2604 | + if (isset($this->_req_data['s'])) { |
|
| 2605 | + $sstr = '%' . $this->_req_data['s'] . '%'; |
|
| 2606 | + $where['OR'] = array( |
|
| 2607 | + 'Term.name' => array('LIKE', $sstr), |
|
| 2608 | + 'description' => array('LIKE', $sstr), |
|
| 2609 | + ); |
|
| 2610 | + } |
|
| 2611 | + $query_params = array( |
|
| 2612 | + $where, |
|
| 2613 | + 'order_by' => array($orderby => $order), |
|
| 2614 | + 'limit' => $limit . ',' . $per_page, |
|
| 2615 | + 'force_join' => array('Term'), |
|
| 2616 | + ); |
|
| 2617 | + $categories = $count |
|
| 2618 | + ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id') |
|
| 2619 | + : EEM_Term_Taxonomy::instance()->get_all($query_params); |
|
| 2620 | + return $categories; |
|
| 2621 | + } |
|
| 2622 | + |
|
| 2623 | + /* end category stuff */ |
|
| 2624 | + /**************/ |
|
| 2625 | + |
|
| 2626 | + |
|
| 2627 | + /** |
|
| 2628 | + * Callback for the `ee_save_timezone_setting` ajax action. |
|
| 2629 | + * |
|
| 2630 | + * @throws EE_Error |
|
| 2631 | + */ |
|
| 2632 | + public function save_timezonestring_setting() |
|
| 2633 | + { |
|
| 2634 | + $timezone_string = isset($this->_req_data['timezone_selected']) |
|
| 2635 | + ? $this->_req_data['timezone_selected'] |
|
| 2636 | + : ''; |
|
| 2637 | + if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) { |
|
| 2638 | + EE_Error::add_error( |
|
| 2639 | + esc_html__('An invalid timezone string submitted.', 'event_espresso'), |
|
| 2640 | + __FILE__, |
|
| 2641 | + __FUNCTION__, |
|
| 2642 | + __LINE__ |
|
| 2643 | + ); |
|
| 2644 | + $this->_template_args['error'] = true; |
|
| 2645 | + $this->_return_json(); |
|
| 2646 | + } |
|
| 2647 | + |
|
| 2648 | + update_option('timezone_string', $timezone_string); |
|
| 2649 | + EE_Error::add_success( |
|
| 2650 | + esc_html__('Your timezone string was updated.', 'event_espresso') |
|
| 2651 | + ); |
|
| 2652 | + $this->_template_args['success'] = true; |
|
| 2653 | + $this->_return_json(true, array('action' => 'create_new')); |
|
| 2654 | + } |
|
| 2655 | 2655 | } |
@@ -4,21 +4,13 @@ |
||
| 4 | 4 | |
| 5 | 5 | use EE_Change_Log; |
| 6 | 6 | use EE_Registry; |
| 7 | -use EEM_Event; |
|
| 8 | -use EEM_Price; |
|
| 9 | -use EEM_Ticket; |
|
| 10 | -use EventEspresso\core\exceptions\InvalidClassException; |
|
| 11 | -use EventEspresso\core\exceptions\InvalidDataTypeException; |
|
| 12 | -use EventEspresso\core\exceptions\InvalidInterfaceException; |
|
| 13 | 7 | use EventEspresso\core\exceptions\UnexpectedEntityException; |
| 14 | -use EventEspresso\core\services\loaders\LoaderFactory; |
|
| 15 | 8 | use EventEspresso\core\services\orm\tree_traversal\NodeGroupDao; |
| 16 | 9 | use EventEspresso\core\services\orm\tree_traversal\ModelObjNode; |
| 17 | 10 | use EventEspressoBatchRequest\Helpers\BatchRequestException; |
| 18 | 11 | use EventEspressoBatchRequest\Helpers\JobParameters; |
| 19 | 12 | use EventEspressoBatchRequest\Helpers\JobStepResponse; |
| 20 | 13 | use EventEspressoBatchRequest\JobHandlerBaseClasses\JobHandler; |
| 21 | -use InvalidArgumentException; |
|
| 22 | 14 | |
| 23 | 15 | /** |
| 24 | 16 | * Class EventDeletion |
@@ -32,158 +32,158 @@ |
||
| 32 | 32 | */ |
| 33 | 33 | class ExecuteBatchDeletion extends JobHandler |
| 34 | 34 | { |
| 35 | - /** |
|
| 36 | - * @var NodeGroupDao |
|
| 37 | - */ |
|
| 38 | - protected $model_obj_node_group_persister; |
|
| 39 | - public function __construct(NodeGroupDao $model_obj_node_group_persister) |
|
| 40 | - { |
|
| 41 | - $this->model_obj_node_group_persister = $model_obj_node_group_persister; |
|
| 42 | - } |
|
| 35 | + /** |
|
| 36 | + * @var NodeGroupDao |
|
| 37 | + */ |
|
| 38 | + protected $model_obj_node_group_persister; |
|
| 39 | + public function __construct(NodeGroupDao $model_obj_node_group_persister) |
|
| 40 | + { |
|
| 41 | + $this->model_obj_node_group_persister = $model_obj_node_group_persister; |
|
| 42 | + } |
|
| 43 | 43 | |
| 44 | 44 | |
| 45 | - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
| 46 | - /** |
|
| 47 | - * |
|
| 48 | - * @param JobParameters $job_parameters |
|
| 49 | - * @throws BatchRequestException |
|
| 50 | - * @return JobStepResponse |
|
| 51 | - */ |
|
| 52 | - public function create_job(JobParameters $job_parameters) |
|
| 53 | - { |
|
| 54 | - $deletion_job_code = $job_parameters->request_datum('deletion_job_code', null); |
|
| 55 | - $roots = $this->model_obj_node_group_persister->getModelObjNodesInGroup($deletion_job_code); |
|
| 56 | - if ($roots === null) { |
|
| 57 | - throw new UnexpectedEntityException($roots, 'array', esc_html__('The job seems to be stale. Please press the back button in your browser twice.', 'event_espresso')); |
|
| 58 | - } |
|
| 59 | - $models_and_ids_to_delete = []; |
|
| 60 | - foreach ($roots as $root) { |
|
| 61 | - if (! $root instanceof ModelObjNode) { |
|
| 62 | - throw new UnexpectedEntityException($root, 'ModelObjNode'); |
|
| 63 | - } |
|
| 64 | - $models_and_ids_to_delete = array_replace_recursive($models_and_ids_to_delete, $root->getIds()); |
|
| 65 | - } |
|
| 66 | - $job_parameters->set_extra_data( |
|
| 67 | - [ |
|
| 68 | - 'models_and_ids_to_delete' => $models_and_ids_to_delete |
|
| 69 | - ] |
|
| 70 | - ); |
|
| 71 | - // Find the job's actual size. |
|
| 72 | - $job_size = 0; |
|
| 73 | - foreach ($models_and_ids_to_delete as $model_name => $ids) { |
|
| 74 | - $job_size += count($ids); |
|
| 75 | - } |
|
| 76 | - $job_parameters->set_job_size($job_size); |
|
| 77 | - return new JobStepResponse( |
|
| 78 | - $job_parameters, |
|
| 79 | - esc_html__('Beginning to delete items...', 'event_espresso') |
|
| 80 | - ); |
|
| 81 | - } |
|
| 45 | + // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
| 46 | + /** |
|
| 47 | + * |
|
| 48 | + * @param JobParameters $job_parameters |
|
| 49 | + * @throws BatchRequestException |
|
| 50 | + * @return JobStepResponse |
|
| 51 | + */ |
|
| 52 | + public function create_job(JobParameters $job_parameters) |
|
| 53 | + { |
|
| 54 | + $deletion_job_code = $job_parameters->request_datum('deletion_job_code', null); |
|
| 55 | + $roots = $this->model_obj_node_group_persister->getModelObjNodesInGroup($deletion_job_code); |
|
| 56 | + if ($roots === null) { |
|
| 57 | + throw new UnexpectedEntityException($roots, 'array', esc_html__('The job seems to be stale. Please press the back button in your browser twice.', 'event_espresso')); |
|
| 58 | + } |
|
| 59 | + $models_and_ids_to_delete = []; |
|
| 60 | + foreach ($roots as $root) { |
|
| 61 | + if (! $root instanceof ModelObjNode) { |
|
| 62 | + throw new UnexpectedEntityException($root, 'ModelObjNode'); |
|
| 63 | + } |
|
| 64 | + $models_and_ids_to_delete = array_replace_recursive($models_and_ids_to_delete, $root->getIds()); |
|
| 65 | + } |
|
| 66 | + $job_parameters->set_extra_data( |
|
| 67 | + [ |
|
| 68 | + 'models_and_ids_to_delete' => $models_and_ids_to_delete |
|
| 69 | + ] |
|
| 70 | + ); |
|
| 71 | + // Find the job's actual size. |
|
| 72 | + $job_size = 0; |
|
| 73 | + foreach ($models_and_ids_to_delete as $model_name => $ids) { |
|
| 74 | + $job_size += count($ids); |
|
| 75 | + } |
|
| 76 | + $job_parameters->set_job_size($job_size); |
|
| 77 | + return new JobStepResponse( |
|
| 78 | + $job_parameters, |
|
| 79 | + esc_html__('Beginning to delete items...', 'event_espresso') |
|
| 80 | + ); |
|
| 81 | + } |
|
| 82 | 82 | |
| 83 | - /** |
|
| 84 | - * Performs another step of the job |
|
| 85 | - * @param JobParameters $job_parameters |
|
| 86 | - * @param int $batch_size |
|
| 87 | - * @return JobStepResponse |
|
| 88 | - * @throws BatchRequestException |
|
| 89 | - */ |
|
| 90 | - public function continue_job(JobParameters $job_parameters, $batch_size = 50) |
|
| 91 | - { |
|
| 92 | - // We already have the items IDs. So deleting is really fast. Let's speed it up. |
|
| 93 | - $batch_size *= 10; |
|
| 94 | - $units_processed = 0; |
|
| 95 | - $models_and_ids_to_delete = $job_parameters->extra_datum('models_and_ids_to_delete', []); |
|
| 96 | - // Build a new list of everything leftover after this request's of deletions. |
|
| 97 | - $models_and_ids_remaining = []; |
|
| 98 | - foreach ($models_and_ids_to_delete as $model_name => $ids_to_delete) { |
|
| 99 | - if ($units_processed < $batch_size) { |
|
| 100 | - $model = EE_Registry::instance()->load_model($model_name); |
|
| 101 | - $ids_to_delete_this_query = array_slice($ids_to_delete, 0, $batch_size - $units_processed, true); |
|
| 102 | - if ($model->has_primary_key_field()) { |
|
| 103 | - $where_conditions = [ |
|
| 104 | - $model->primary_key_name() => [ |
|
| 105 | - 'IN', |
|
| 106 | - $ids_to_delete_this_query |
|
| 107 | - ] |
|
| 108 | - ]; |
|
| 109 | - } else { |
|
| 110 | - $where_conditions = [ |
|
| 111 | - 'OR' => [] |
|
| 112 | - ]; |
|
| 113 | - foreach ($ids_to_delete_this_query as $index_primary_key_string) { |
|
| 114 | - $keys_n_values = $model->parse_index_primary_key_string($index_primary_key_string); |
|
| 115 | - $where_conditions['OR'][ 'AND*' . $index_primary_key_string ] = $keys_n_values; |
|
| 116 | - } |
|
| 117 | - } |
|
| 118 | - // Deleting time! |
|
| 119 | - // The model's deletion method reports every ROW deleted, and in the case of CPT models that will be |
|
| 120 | - // two rows deleted for event CPT item. So don't rely on it for the count of items deleted. |
|
| 121 | - $model->delete_permanently( |
|
| 122 | - [ |
|
| 123 | - $where_conditions |
|
| 124 | - ], |
|
| 125 | - false |
|
| 126 | - ); |
|
| 127 | - $units_processed += count($ids_to_delete_this_query); |
|
| 128 | - $remaining_ids = array_diff_key($ids_to_delete, $ids_to_delete_this_query); |
|
| 129 | - // If there's any more from this model, we'll do them next time. |
|
| 130 | - if (count($remaining_ids) > 0) { |
|
| 131 | - $models_and_ids_remaining[ $model_name ] = $remaining_ids; |
|
| 132 | - } |
|
| 133 | - } else { |
|
| 134 | - $models_and_ids_remaining[ $model_name ] = $models_and_ids_to_delete[ $model_name ]; |
|
| 135 | - } |
|
| 136 | - } |
|
| 137 | - $job_parameters->mark_processed($units_processed); |
|
| 138 | - // All done deleting for this request. Is there anything to do next time? |
|
| 139 | - if (empty($models_and_ids_remaining)) { |
|
| 140 | - $job_parameters->set_status(JobParameters::status_complete); |
|
| 141 | - return new JobStepResponse( |
|
| 142 | - $job_parameters, |
|
| 143 | - esc_html__('Deletion complete.', 'event_espresso') |
|
| 144 | - ); |
|
| 145 | - } |
|
| 146 | - $job_parameters->add_extra_data('models_and_ids_to_delete', $models_and_ids_remaining); |
|
| 147 | - return new JobStepResponse( |
|
| 148 | - $job_parameters, |
|
| 149 | - sprintf( |
|
| 150 | - esc_html__('Deleted %d items.', 'event_espresso'), |
|
| 151 | - $units_processed |
|
| 152 | - ) |
|
| 153 | - ); |
|
| 154 | - } |
|
| 83 | + /** |
|
| 84 | + * Performs another step of the job |
|
| 85 | + * @param JobParameters $job_parameters |
|
| 86 | + * @param int $batch_size |
|
| 87 | + * @return JobStepResponse |
|
| 88 | + * @throws BatchRequestException |
|
| 89 | + */ |
|
| 90 | + public function continue_job(JobParameters $job_parameters, $batch_size = 50) |
|
| 91 | + { |
|
| 92 | + // We already have the items IDs. So deleting is really fast. Let's speed it up. |
|
| 93 | + $batch_size *= 10; |
|
| 94 | + $units_processed = 0; |
|
| 95 | + $models_and_ids_to_delete = $job_parameters->extra_datum('models_and_ids_to_delete', []); |
|
| 96 | + // Build a new list of everything leftover after this request's of deletions. |
|
| 97 | + $models_and_ids_remaining = []; |
|
| 98 | + foreach ($models_and_ids_to_delete as $model_name => $ids_to_delete) { |
|
| 99 | + if ($units_processed < $batch_size) { |
|
| 100 | + $model = EE_Registry::instance()->load_model($model_name); |
|
| 101 | + $ids_to_delete_this_query = array_slice($ids_to_delete, 0, $batch_size - $units_processed, true); |
|
| 102 | + if ($model->has_primary_key_field()) { |
|
| 103 | + $where_conditions = [ |
|
| 104 | + $model->primary_key_name() => [ |
|
| 105 | + 'IN', |
|
| 106 | + $ids_to_delete_this_query |
|
| 107 | + ] |
|
| 108 | + ]; |
|
| 109 | + } else { |
|
| 110 | + $where_conditions = [ |
|
| 111 | + 'OR' => [] |
|
| 112 | + ]; |
|
| 113 | + foreach ($ids_to_delete_this_query as $index_primary_key_string) { |
|
| 114 | + $keys_n_values = $model->parse_index_primary_key_string($index_primary_key_string); |
|
| 115 | + $where_conditions['OR'][ 'AND*' . $index_primary_key_string ] = $keys_n_values; |
|
| 116 | + } |
|
| 117 | + } |
|
| 118 | + // Deleting time! |
|
| 119 | + // The model's deletion method reports every ROW deleted, and in the case of CPT models that will be |
|
| 120 | + // two rows deleted for event CPT item. So don't rely on it for the count of items deleted. |
|
| 121 | + $model->delete_permanently( |
|
| 122 | + [ |
|
| 123 | + $where_conditions |
|
| 124 | + ], |
|
| 125 | + false |
|
| 126 | + ); |
|
| 127 | + $units_processed += count($ids_to_delete_this_query); |
|
| 128 | + $remaining_ids = array_diff_key($ids_to_delete, $ids_to_delete_this_query); |
|
| 129 | + // If there's any more from this model, we'll do them next time. |
|
| 130 | + if (count($remaining_ids) > 0) { |
|
| 131 | + $models_and_ids_remaining[ $model_name ] = $remaining_ids; |
|
| 132 | + } |
|
| 133 | + } else { |
|
| 134 | + $models_and_ids_remaining[ $model_name ] = $models_and_ids_to_delete[ $model_name ]; |
|
| 135 | + } |
|
| 136 | + } |
|
| 137 | + $job_parameters->mark_processed($units_processed); |
|
| 138 | + // All done deleting for this request. Is there anything to do next time? |
|
| 139 | + if (empty($models_and_ids_remaining)) { |
|
| 140 | + $job_parameters->set_status(JobParameters::status_complete); |
|
| 141 | + return new JobStepResponse( |
|
| 142 | + $job_parameters, |
|
| 143 | + esc_html__('Deletion complete.', 'event_espresso') |
|
| 144 | + ); |
|
| 145 | + } |
|
| 146 | + $job_parameters->add_extra_data('models_and_ids_to_delete', $models_and_ids_remaining); |
|
| 147 | + return new JobStepResponse( |
|
| 148 | + $job_parameters, |
|
| 149 | + sprintf( |
|
| 150 | + esc_html__('Deleted %d items.', 'event_espresso'), |
|
| 151 | + $units_processed |
|
| 152 | + ) |
|
| 153 | + ); |
|
| 154 | + } |
|
| 155 | 155 | |
| 156 | - /** |
|
| 157 | - * Performs any clean-up logic when we know the job is completed |
|
| 158 | - * @param JobParameters $job_parameters |
|
| 159 | - * @return JobStepResponse |
|
| 160 | - */ |
|
| 161 | - public function cleanup_job(JobParameters $job_parameters) |
|
| 162 | - { |
|
| 163 | - $this->model_obj_node_group_persister->deleteModelObjNodesInGroup( |
|
| 164 | - $job_parameters->request_datum('deletion_job_code') |
|
| 165 | - ); |
|
| 166 | - // For backwards compatibility with how we used to delete events, make sure we still trigger the old action. |
|
| 167 | - $models_and_ids_to_delete = $job_parameters->extra_datum('models_and_ids_to_delete', []); |
|
| 168 | - foreach ($models_and_ids_to_delete['Event'] as $event_id) { |
|
| 169 | - // Create a log entry so we know who and when this event was permanently deleted. |
|
| 170 | - (EE_Change_Log::new_instance( |
|
| 171 | - [ |
|
| 172 | - 'OBJ_ID' => $event_id, |
|
| 173 | - 'OBJ_type' => 'Event', |
|
| 174 | - 'LOG_message' => sprintf( |
|
| 175 | - esc_html__('Event %1$d permanently deleted using ExecuteBatchDeletion.', 'event_espresso'), |
|
| 176 | - $event_id |
|
| 177 | - ) |
|
| 178 | - ] |
|
| 179 | - ))->save(); |
|
| 180 | - do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $event_id); |
|
| 181 | - } |
|
| 182 | - return new JobStepResponse( |
|
| 183 | - $job_parameters, |
|
| 184 | - esc_html__('All done', 'event_espresso') |
|
| 185 | - ); |
|
| 186 | - } |
|
| 156 | + /** |
|
| 157 | + * Performs any clean-up logic when we know the job is completed |
|
| 158 | + * @param JobParameters $job_parameters |
|
| 159 | + * @return JobStepResponse |
|
| 160 | + */ |
|
| 161 | + public function cleanup_job(JobParameters $job_parameters) |
|
| 162 | + { |
|
| 163 | + $this->model_obj_node_group_persister->deleteModelObjNodesInGroup( |
|
| 164 | + $job_parameters->request_datum('deletion_job_code') |
|
| 165 | + ); |
|
| 166 | + // For backwards compatibility with how we used to delete events, make sure we still trigger the old action. |
|
| 167 | + $models_and_ids_to_delete = $job_parameters->extra_datum('models_and_ids_to_delete', []); |
|
| 168 | + foreach ($models_and_ids_to_delete['Event'] as $event_id) { |
|
| 169 | + // Create a log entry so we know who and when this event was permanently deleted. |
|
| 170 | + (EE_Change_Log::new_instance( |
|
| 171 | + [ |
|
| 172 | + 'OBJ_ID' => $event_id, |
|
| 173 | + 'OBJ_type' => 'Event', |
|
| 174 | + 'LOG_message' => sprintf( |
|
| 175 | + esc_html__('Event %1$d permanently deleted using ExecuteBatchDeletion.', 'event_espresso'), |
|
| 176 | + $event_id |
|
| 177 | + ) |
|
| 178 | + ] |
|
| 179 | + ))->save(); |
|
| 180 | + do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $event_id); |
|
| 181 | + } |
|
| 182 | + return new JobStepResponse( |
|
| 183 | + $job_parameters, |
|
| 184 | + esc_html__('All done', 'event_espresso') |
|
| 185 | + ); |
|
| 186 | + } |
|
| 187 | 187 | } |
| 188 | 188 | // End of file EventDeletion.php |
| 189 | 189 | // Location: EventEspressoBatchRequest\JobHandlers/EventDeletion.php |
@@ -58,7 +58,7 @@ discard block |
||
| 58 | 58 | } |
| 59 | 59 | $models_and_ids_to_delete = []; |
| 60 | 60 | foreach ($roots as $root) { |
| 61 | - if (! $root instanceof ModelObjNode) { |
|
| 61 | + if ( ! $root instanceof ModelObjNode) { |
|
| 62 | 62 | throw new UnexpectedEntityException($root, 'ModelObjNode'); |
| 63 | 63 | } |
| 64 | 64 | $models_and_ids_to_delete = array_replace_recursive($models_and_ids_to_delete, $root->getIds()); |
@@ -112,7 +112,7 @@ discard block |
||
| 112 | 112 | ]; |
| 113 | 113 | foreach ($ids_to_delete_this_query as $index_primary_key_string) { |
| 114 | 114 | $keys_n_values = $model->parse_index_primary_key_string($index_primary_key_string); |
| 115 | - $where_conditions['OR'][ 'AND*' . $index_primary_key_string ] = $keys_n_values; |
|
| 115 | + $where_conditions['OR']['AND*'.$index_primary_key_string] = $keys_n_values; |
|
| 116 | 116 | } |
| 117 | 117 | } |
| 118 | 118 | // Deleting time! |
@@ -128,10 +128,10 @@ discard block |
||
| 128 | 128 | $remaining_ids = array_diff_key($ids_to_delete, $ids_to_delete_this_query); |
| 129 | 129 | // If there's any more from this model, we'll do them next time. |
| 130 | 130 | if (count($remaining_ids) > 0) { |
| 131 | - $models_and_ids_remaining[ $model_name ] = $remaining_ids; |
|
| 131 | + $models_and_ids_remaining[$model_name] = $remaining_ids; |
|
| 132 | 132 | } |
| 133 | 133 | } else { |
| 134 | - $models_and_ids_remaining[ $model_name ] = $models_and_ids_to_delete[ $model_name ]; |
|
| 134 | + $models_and_ids_remaining[$model_name] = $models_and_ids_to_delete[$model_name]; |
|
| 135 | 135 | } |
| 136 | 136 | } |
| 137 | 137 | $job_parameters->mark_processed($units_processed); |
@@ -6,7 +6,6 @@ |
||
| 6 | 6 | use EEM_Price; |
| 7 | 7 | use EEM_Ticket; |
| 8 | 8 | use EventEspresso\core\exceptions\InvalidClassException; |
| 9 | -use EventEspresso\core\services\loaders\LoaderFactory; |
|
| 10 | 9 | use EventEspresso\core\services\orm\tree_traversal\ModelObjNode; |
| 11 | 10 | use EventEspresso\core\services\orm\tree_traversal\NodeGroupDao; |
| 12 | 11 | use EventEspressoBatchRequest\Helpers\BatchRequestException; |
@@ -28,145 +28,145 @@ |
||
| 28 | 28 | class PreviewEventDeletion extends JobHandler |
| 29 | 29 | { |
| 30 | 30 | |
| 31 | - /** |
|
| 32 | - * @var NodeGroupDao |
|
| 33 | - */ |
|
| 34 | - protected $model_obj_node_group_persister; |
|
| 35 | - public function __construct(NodeGroupDao $model_obj_node_group_persister) |
|
| 36 | - { |
|
| 37 | - $this->model_obj_node_group_persister = $model_obj_node_group_persister; |
|
| 38 | - } |
|
| 31 | + /** |
|
| 32 | + * @var NodeGroupDao |
|
| 33 | + */ |
|
| 34 | + protected $model_obj_node_group_persister; |
|
| 35 | + public function __construct(NodeGroupDao $model_obj_node_group_persister) |
|
| 36 | + { |
|
| 37 | + $this->model_obj_node_group_persister = $model_obj_node_group_persister; |
|
| 38 | + } |
|
| 39 | 39 | |
| 40 | - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
| 41 | - /** |
|
| 42 | - * |
|
| 43 | - * @param JobParameters $job_parameters |
|
| 44 | - * @throws BatchRequestException |
|
| 45 | - * @return JobStepResponse |
|
| 46 | - */ |
|
| 47 | - public function create_job(JobParameters $job_parameters) |
|
| 48 | - { |
|
| 49 | - // Set the "root" model objects we will want to delete (record their ID and model) |
|
| 50 | - $event_ids = $job_parameters->request_datum('EVT_IDs', array()); |
|
| 51 | - // Find all the root nodes to delete (this isn't just events, because there's other data, like related tickets, |
|
| 52 | - // prices, message templates, etc, whose model definition doesn't make them dependent on events. But, |
|
| 53 | - // we have no UI to access them independent of events, so they may as well get deleted too.) |
|
| 54 | - $model_objects_to_delete = []; |
|
| 55 | - foreach ($event_ids as $event_id) { |
|
| 56 | - $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 57 | - // Also, we want to delete their related, non-global, tickets, prices and message templates |
|
| 58 | - $related_non_global_tickets = EEM_Ticket::instance()->get_all_deleted_and_undeleted( |
|
| 59 | - [ |
|
| 60 | - [ |
|
| 61 | - 'TKT_is_default' => false, |
|
| 62 | - 'Datetime.EVT_ID' => $event_id |
|
| 63 | - ] |
|
| 64 | - ] |
|
| 65 | - ); |
|
| 66 | - $related_non_global_prices = EEM_Price::instance()->get_all_deleted_and_undeleted( |
|
| 67 | - [ |
|
| 68 | - [ |
|
| 69 | - 'PRC_is_default' => false, |
|
| 70 | - 'Ticket.Datetime.EVT_ID' => $event_id |
|
| 71 | - ] |
|
| 72 | - ] |
|
| 73 | - ); |
|
| 74 | - $model_objects_to_delete = array_merge( |
|
| 75 | - $model_objects_to_delete, |
|
| 76 | - [$event], |
|
| 77 | - $related_non_global_tickets, |
|
| 78 | - $related_non_global_prices |
|
| 79 | - ); |
|
| 80 | - } |
|
| 81 | - $roots = []; |
|
| 82 | - foreach ($model_objects_to_delete as $model_object) { |
|
| 83 | - $roots[] = new ModelObjNode($model_object->ID(), $model_object->get_model()); |
|
| 84 | - } |
|
| 85 | - $job_parameters->add_extra_data('roots', $roots); |
|
| 86 | - // Set an estimate of how long this will take (we're discovering as we go, so it seems impossible to give |
|
| 87 | - // an accurate count.) |
|
| 88 | - $estimated_work_per_model_obj = 100; |
|
| 89 | - $job_parameters->set_job_size(count($roots) * $estimated_work_per_model_obj); |
|
| 90 | - return new JobStepResponse( |
|
| 91 | - $job_parameters, |
|
| 92 | - esc_html__('Generating preview of data to be deleted...', 'event_espresso') |
|
| 93 | - ); |
|
| 94 | - } |
|
| 40 | + // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
| 41 | + /** |
|
| 42 | + * |
|
| 43 | + * @param JobParameters $job_parameters |
|
| 44 | + * @throws BatchRequestException |
|
| 45 | + * @return JobStepResponse |
|
| 46 | + */ |
|
| 47 | + public function create_job(JobParameters $job_parameters) |
|
| 48 | + { |
|
| 49 | + // Set the "root" model objects we will want to delete (record their ID and model) |
|
| 50 | + $event_ids = $job_parameters->request_datum('EVT_IDs', array()); |
|
| 51 | + // Find all the root nodes to delete (this isn't just events, because there's other data, like related tickets, |
|
| 52 | + // prices, message templates, etc, whose model definition doesn't make them dependent on events. But, |
|
| 53 | + // we have no UI to access them independent of events, so they may as well get deleted too.) |
|
| 54 | + $model_objects_to_delete = []; |
|
| 55 | + foreach ($event_ids as $event_id) { |
|
| 56 | + $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 57 | + // Also, we want to delete their related, non-global, tickets, prices and message templates |
|
| 58 | + $related_non_global_tickets = EEM_Ticket::instance()->get_all_deleted_and_undeleted( |
|
| 59 | + [ |
|
| 60 | + [ |
|
| 61 | + 'TKT_is_default' => false, |
|
| 62 | + 'Datetime.EVT_ID' => $event_id |
|
| 63 | + ] |
|
| 64 | + ] |
|
| 65 | + ); |
|
| 66 | + $related_non_global_prices = EEM_Price::instance()->get_all_deleted_and_undeleted( |
|
| 67 | + [ |
|
| 68 | + [ |
|
| 69 | + 'PRC_is_default' => false, |
|
| 70 | + 'Ticket.Datetime.EVT_ID' => $event_id |
|
| 71 | + ] |
|
| 72 | + ] |
|
| 73 | + ); |
|
| 74 | + $model_objects_to_delete = array_merge( |
|
| 75 | + $model_objects_to_delete, |
|
| 76 | + [$event], |
|
| 77 | + $related_non_global_tickets, |
|
| 78 | + $related_non_global_prices |
|
| 79 | + ); |
|
| 80 | + } |
|
| 81 | + $roots = []; |
|
| 82 | + foreach ($model_objects_to_delete as $model_object) { |
|
| 83 | + $roots[] = new ModelObjNode($model_object->ID(), $model_object->get_model()); |
|
| 84 | + } |
|
| 85 | + $job_parameters->add_extra_data('roots', $roots); |
|
| 86 | + // Set an estimate of how long this will take (we're discovering as we go, so it seems impossible to give |
|
| 87 | + // an accurate count.) |
|
| 88 | + $estimated_work_per_model_obj = 100; |
|
| 89 | + $job_parameters->set_job_size(count($roots) * $estimated_work_per_model_obj); |
|
| 90 | + return new JobStepResponse( |
|
| 91 | + $job_parameters, |
|
| 92 | + esc_html__('Generating preview of data to be deleted...', 'event_espresso') |
|
| 93 | + ); |
|
| 94 | + } |
|
| 95 | 95 | |
| 96 | - /** |
|
| 97 | - * Performs another step of the job |
|
| 98 | - * @param JobParameters $job_parameters |
|
| 99 | - * @param int $batch_size |
|
| 100 | - * @return JobStepResponse |
|
| 101 | - * @throws BatchRequestException |
|
| 102 | - */ |
|
| 103 | - public function continue_job(JobParameters $job_parameters, $batch_size = 50) |
|
| 104 | - { |
|
| 105 | - // Serializing and unserializing is what really makes this drag on (eg on localhost, the ajax requests took |
|
| 106 | - // about 4 seconds when the batch size was 250, but 3 seconds when the batch size was 50. So like |
|
| 107 | - // 50% of the request is just serializing and unserializing.) So, make the batches much bigger. |
|
| 108 | - $batch_size *= 3; |
|
| 109 | - $units_processed = 0; |
|
| 110 | - foreach ($job_parameters->extra_datum('roots', array()) as $root_node) { |
|
| 111 | - if ($units_processed >= $batch_size) { |
|
| 112 | - break; |
|
| 113 | - } |
|
| 114 | - if (! $root_node instanceof ModelObjNode) { |
|
| 115 | - throw new InvalidClassException('ModelObjNode'); |
|
| 116 | - } |
|
| 117 | - if ($root_node->isComplete()) { |
|
| 118 | - continue; |
|
| 119 | - } |
|
| 120 | - $units_processed += $root_node->visit($batch_size - $units_processed); |
|
| 121 | - } |
|
| 122 | - $job_parameters->mark_processed($units_processed); |
|
| 123 | - // If the most-recently processed root node is complete, we must be all done because we're doing them |
|
| 124 | - // sequentially. |
|
| 125 | - if (isset($root_node) && $root_node instanceof ModelObjNode && $root_node->isComplete()) { |
|
| 126 | - $job_parameters->set_status(JobParameters::status_complete); |
|
| 127 | - // Show a full progress bar. |
|
| 128 | - $job_parameters->set_units_processed($job_parameters->job_size()); |
|
| 129 | - $deletion_job_code = $job_parameters->request_datum('deletion_job_code'); |
|
| 130 | - $this->model_obj_node_group_persister->persistModelObjNodesGroup( |
|
| 131 | - $job_parameters->extra_datum('roots'), |
|
| 132 | - $deletion_job_code |
|
| 133 | - ); |
|
| 134 | - return new JobStepResponse( |
|
| 135 | - $job_parameters, |
|
| 136 | - esc_html__('Finished identifying items for deletion.', 'event_espresso'), |
|
| 137 | - [ |
|
| 138 | - 'deletion_job_code' => $deletion_job_code |
|
| 139 | - ] |
|
| 140 | - ); |
|
| 141 | - } else { |
|
| 142 | - // Because the job size was a guess, it may have likely been provden wrong. We don't want to show more work |
|
| 143 | - // done than we originally said there would be. So adjust the estimate. |
|
| 144 | - if (($job_parameters->units_processed() / $job_parameters->job_size()) > .8) { |
|
| 145 | - $job_parameters->set_job_size($job_parameters->job_size() * 2); |
|
| 146 | - } |
|
| 147 | - return new JobStepResponse( |
|
| 148 | - $job_parameters, |
|
| 149 | - sprintf( |
|
| 150 | - esc_html__('Identified %d items for deletion.', 'event_espresso'), |
|
| 151 | - $units_processed |
|
| 152 | - ) |
|
| 153 | - ); |
|
| 154 | - } |
|
| 155 | - } |
|
| 96 | + /** |
|
| 97 | + * Performs another step of the job |
|
| 98 | + * @param JobParameters $job_parameters |
|
| 99 | + * @param int $batch_size |
|
| 100 | + * @return JobStepResponse |
|
| 101 | + * @throws BatchRequestException |
|
| 102 | + */ |
|
| 103 | + public function continue_job(JobParameters $job_parameters, $batch_size = 50) |
|
| 104 | + { |
|
| 105 | + // Serializing and unserializing is what really makes this drag on (eg on localhost, the ajax requests took |
|
| 106 | + // about 4 seconds when the batch size was 250, but 3 seconds when the batch size was 50. So like |
|
| 107 | + // 50% of the request is just serializing and unserializing.) So, make the batches much bigger. |
|
| 108 | + $batch_size *= 3; |
|
| 109 | + $units_processed = 0; |
|
| 110 | + foreach ($job_parameters->extra_datum('roots', array()) as $root_node) { |
|
| 111 | + if ($units_processed >= $batch_size) { |
|
| 112 | + break; |
|
| 113 | + } |
|
| 114 | + if (! $root_node instanceof ModelObjNode) { |
|
| 115 | + throw new InvalidClassException('ModelObjNode'); |
|
| 116 | + } |
|
| 117 | + if ($root_node->isComplete()) { |
|
| 118 | + continue; |
|
| 119 | + } |
|
| 120 | + $units_processed += $root_node->visit($batch_size - $units_processed); |
|
| 121 | + } |
|
| 122 | + $job_parameters->mark_processed($units_processed); |
|
| 123 | + // If the most-recently processed root node is complete, we must be all done because we're doing them |
|
| 124 | + // sequentially. |
|
| 125 | + if (isset($root_node) && $root_node instanceof ModelObjNode && $root_node->isComplete()) { |
|
| 126 | + $job_parameters->set_status(JobParameters::status_complete); |
|
| 127 | + // Show a full progress bar. |
|
| 128 | + $job_parameters->set_units_processed($job_parameters->job_size()); |
|
| 129 | + $deletion_job_code = $job_parameters->request_datum('deletion_job_code'); |
|
| 130 | + $this->model_obj_node_group_persister->persistModelObjNodesGroup( |
|
| 131 | + $job_parameters->extra_datum('roots'), |
|
| 132 | + $deletion_job_code |
|
| 133 | + ); |
|
| 134 | + return new JobStepResponse( |
|
| 135 | + $job_parameters, |
|
| 136 | + esc_html__('Finished identifying items for deletion.', 'event_espresso'), |
|
| 137 | + [ |
|
| 138 | + 'deletion_job_code' => $deletion_job_code |
|
| 139 | + ] |
|
| 140 | + ); |
|
| 141 | + } else { |
|
| 142 | + // Because the job size was a guess, it may have likely been provden wrong. We don't want to show more work |
|
| 143 | + // done than we originally said there would be. So adjust the estimate. |
|
| 144 | + if (($job_parameters->units_processed() / $job_parameters->job_size()) > .8) { |
|
| 145 | + $job_parameters->set_job_size($job_parameters->job_size() * 2); |
|
| 146 | + } |
|
| 147 | + return new JobStepResponse( |
|
| 148 | + $job_parameters, |
|
| 149 | + sprintf( |
|
| 150 | + esc_html__('Identified %d items for deletion.', 'event_espresso'), |
|
| 151 | + $units_processed |
|
| 152 | + ) |
|
| 153 | + ); |
|
| 154 | + } |
|
| 155 | + } |
|
| 156 | 156 | |
| 157 | - /** |
|
| 158 | - * Performs any clean-up logic when we know the job is completed |
|
| 159 | - * @param JobParameters $job_parameters |
|
| 160 | - * @return JobStepResponse |
|
| 161 | - */ |
|
| 162 | - public function cleanup_job(JobParameters $job_parameters) |
|
| 163 | - { |
|
| 164 | - // Nothing much to do. We can't delete the option with the built tree because we may need it in a moment for the deletion |
|
| 165 | - return new JobStepResponse( |
|
| 166 | - $job_parameters, |
|
| 167 | - esc_html__('All done', 'event_espresso') |
|
| 168 | - ); |
|
| 169 | - } |
|
| 157 | + /** |
|
| 158 | + * Performs any clean-up logic when we know the job is completed |
|
| 159 | + * @param JobParameters $job_parameters |
|
| 160 | + * @return JobStepResponse |
|
| 161 | + */ |
|
| 162 | + public function cleanup_job(JobParameters $job_parameters) |
|
| 163 | + { |
|
| 164 | + // Nothing much to do. We can't delete the option with the built tree because we may need it in a moment for the deletion |
|
| 165 | + return new JobStepResponse( |
|
| 166 | + $job_parameters, |
|
| 167 | + esc_html__('All done', 'event_espresso') |
|
| 168 | + ); |
|
| 169 | + } |
|
| 170 | 170 | } |
| 171 | 171 | // End of file EventDeletion.php |
| 172 | 172 | // Location: EventEspressoBatchRequest\JobHandlers/EventDeletion.php |
@@ -111,7 +111,7 @@ |
||
| 111 | 111 | if ($units_processed >= $batch_size) { |
| 112 | 112 | break; |
| 113 | 113 | } |
| 114 | - if (! $root_node instanceof ModelObjNode) { |
|
| 114 | + if ( ! $root_node instanceof ModelObjNode) { |
|
| 115 | 115 | throw new InvalidClassException('ModelObjNode'); |
| 116 | 116 | } |
| 117 | 117 | if ($root_node->isComplete()) { |
@@ -1,68 +1,68 @@ discard block |
||
| 1 | 1 | <h2><?php esc_html_e('Please Confirm You Want to Permanently Delete the Following Data', 'event_espresso'); ?></h2> |
| 2 | 2 | <h3> |
| 3 | 3 | <?php |
| 4 | - printf( |
|
| 5 | - esc_html( |
|
| 6 | - // translators: 1: number of events |
|
| 7 | - _n('%1$d Event', '%1$d Events', count($events), 'event_espresso') |
|
| 8 | - ), |
|
| 9 | - count($events) |
|
| 10 | - ); |
|
| 11 | - ?> |
|
| 4 | + printf( |
|
| 5 | + esc_html( |
|
| 6 | + // translators: 1: number of events |
|
| 7 | + _n('%1$d Event', '%1$d Events', count($events), 'event_espresso') |
|
| 8 | + ), |
|
| 9 | + count($events) |
|
| 10 | + ); |
|
| 11 | + ?> |
|
| 12 | 12 | </h3> |
| 13 | 13 | <ul> |
| 14 | 14 | <?php |
| 15 | - foreach ($events as $event) { |
|
| 16 | - ?> |
|
| 15 | + foreach ($events as $event) { |
|
| 16 | + ?> |
|
| 17 | 17 | <li> |
| 18 | 18 | <?php echo $event->name(); ?> |
| 19 | 19 | </li> |
| 20 | 20 | <?php |
| 21 | - } |
|
| 22 | - ?> |
|
| 21 | + } |
|
| 22 | + ?> |
|
| 23 | 23 | </ul> |
| 24 | 24 | <h3> |
| 25 | 25 | <?php |
| 26 | - printf( |
|
| 27 | - esc_html( |
|
| 28 | - // translators: 1: number of datetimes |
|
| 29 | - _n('%1$d Datetime', '%1$d Datetimes', count($datetimes), 'event_espresso') |
|
| 30 | - ), |
|
| 31 | - count($datetimes) |
|
| 32 | - ); |
|
| 33 | - ?> |
|
| 26 | + printf( |
|
| 27 | + esc_html( |
|
| 28 | + // translators: 1: number of datetimes |
|
| 29 | + _n('%1$d Datetime', '%1$d Datetimes', count($datetimes), 'event_espresso') |
|
| 30 | + ), |
|
| 31 | + count($datetimes) |
|
| 32 | + ); |
|
| 33 | + ?> |
|
| 34 | 34 | </h3> |
| 35 | 35 | <ul> |
| 36 | 36 | <?php |
| 37 | - foreach ($datetimes as $datetime) { |
|
| 38 | - ?> |
|
| 37 | + foreach ($datetimes as $datetime) { |
|
| 38 | + ?> |
|
| 39 | 39 | <li> |
| 40 | 40 | <?php echo $datetime->get_dtt_display_name(true); ?> |
| 41 | 41 | </li> |
| 42 | 42 | <?php |
| 43 | - } |
|
| 44 | - ?> |
|
| 43 | + } |
|
| 44 | + ?> |
|
| 45 | 45 | </ul> |
| 46 | 46 | <h3> |
| 47 | 47 | <?php |
| 48 | - printf( |
|
| 49 | - esc_html( |
|
| 50 | - _n('%1$d Registration', '%1$d Registrations', $reg_count, 'event_espresso') |
|
| 51 | - ), |
|
| 52 | - $reg_count |
|
| 53 | - ); |
|
| 54 | - ?> |
|
| 48 | + printf( |
|
| 49 | + esc_html( |
|
| 50 | + _n('%1$d Registration', '%1$d Registrations', $reg_count, 'event_espresso') |
|
| 51 | + ), |
|
| 52 | + $reg_count |
|
| 53 | + ); |
|
| 54 | + ?> |
|
| 55 | 55 | </h3> |
| 56 | 56 | <?php |
| 57 | 57 | if ($reg_count > count($registrations)) { |
| 58 | - ?> |
|
| 58 | + ?> |
|
| 59 | 59 | <p class="notice"> |
| 60 | 60 | <?php |
| 61 | - printf( |
|
| 62 | - esc_html__('Only showing first %1$d.', 'event_espresso'), |
|
| 63 | - count($registrations) |
|
| 64 | - ); |
|
| 65 | - ?> |
|
| 61 | + printf( |
|
| 62 | + esc_html__('Only showing first %1$d.', 'event_espresso'), |
|
| 63 | + count($registrations) |
|
| 64 | + ); |
|
| 65 | + ?> |
|
| 66 | 66 | </p> |
| 67 | 67 | <?php |
| 68 | 68 | } |
@@ -70,22 +70,22 @@ discard block |
||
| 70 | 70 | <p><?php esc_html_e('Note: contacts will not be deleted, only their registrations for the enumerated events. You can delete the contacts afterwards if you like.', 'event_espresso'); ?></p> |
| 71 | 71 | <ul> |
| 72 | 72 | <?php |
| 73 | - foreach ($registrations as $registration) { |
|
| 74 | - ?> |
|
| 73 | + foreach ($registrations as $registration) { |
|
| 74 | + ?> |
|
| 75 | 75 | <li> |
| 76 | 76 | <?php |
| 77 | - printf( |
|
| 78 | - esc_html( |
|
| 79 | - _x('%1$s (%2$d of %3$d)', 'Registration name (number of count)', 'event_espresso') |
|
| 80 | - ), |
|
| 81 | - $registration->attendeeName(true), |
|
| 82 | - $registration->count(), |
|
| 83 | - $registration->group_size() |
|
| 84 | - ); ?> |
|
| 77 | + printf( |
|
| 78 | + esc_html( |
|
| 79 | + _x('%1$s (%2$d of %3$d)', 'Registration name (number of count)', 'event_espresso') |
|
| 80 | + ), |
|
| 81 | + $registration->attendeeName(true), |
|
| 82 | + $registration->count(), |
|
| 83 | + $registration->group_size() |
|
| 84 | + ); ?> |
|
| 85 | 85 | </li> |
| 86 | 86 | <?php |
| 87 | - } |
|
| 88 | - ?> |
|
| 87 | + } |
|
| 88 | + ?> |
|
| 89 | 89 | </ul> |
| 90 | 90 | <form action="<?php echo $form_url; ?>" method="POST"> |
| 91 | 91 | <?php echo $form->get_html_and_js(); ?> |
@@ -22,112 +22,112 @@ |
||
| 22 | 22 | */ |
| 23 | 23 | class NodeGroupDao |
| 24 | 24 | { |
| 25 | - /** |
|
| 26 | - * @since $VID:$ |
|
| 27 | - * @return mixed|void |
|
| 28 | - */ |
|
| 29 | - public function generateGroupCode() |
|
| 30 | - { |
|
| 31 | - return wp_generate_password(6, false); |
|
| 32 | - } |
|
| 25 | + /** |
|
| 26 | + * @since $VID:$ |
|
| 27 | + * @return mixed|void |
|
| 28 | + */ |
|
| 29 | + public function generateGroupCode() |
|
| 30 | + { |
|
| 31 | + return wp_generate_password(6, false); |
|
| 32 | + } |
|
| 33 | 33 | |
| 34 | - /** |
|
| 35 | - * Gets the string we put in front of the WP Option name used to store the jobs. |
|
| 36 | - * @since $VID:$ |
|
| 37 | - * @return string |
|
| 38 | - */ |
|
| 39 | - private function getOptionPrefix() |
|
| 40 | - { |
|
| 41 | - return 'ee_deletion_'; |
|
| 42 | - } |
|
| 34 | + /** |
|
| 35 | + * Gets the string we put in front of the WP Option name used to store the jobs. |
|
| 36 | + * @since $VID:$ |
|
| 37 | + * @return string |
|
| 38 | + */ |
|
| 39 | + private function getOptionPrefix() |
|
| 40 | + { |
|
| 41 | + return 'ee_deletion_'; |
|
| 42 | + } |
|
| 43 | 43 | |
| 44 | - /** |
|
| 45 | - * @since $VID:$ |
|
| 46 | - * @param $code |
|
| 47 | - * @return ModelObjNode[] |
|
| 48 | - * @throws UnexpectedEntityException |
|
| 49 | - */ |
|
| 50 | - public function getModelObjNodesInGroup($code) |
|
| 51 | - { |
|
| 52 | - if (! $code) { |
|
| 53 | - throw new Exception(esc_html__('We aren’t sure which job you are performing. Please press back in your browser and try again.', 'event_espresso')); |
|
| 54 | - } |
|
| 55 | - $deletion_data = get_option($this->getOptionPrefix() . $code, []); |
|
| 56 | - foreach ($deletion_data as $root) { |
|
| 57 | - if (! $root instanceof ModelObjNode) { |
|
| 58 | - throw new UnexpectedEntityException($root, 'ModelObjNode'); |
|
| 59 | - } |
|
| 60 | - } |
|
| 61 | - return $deletion_data; |
|
| 62 | - } |
|
| 44 | + /** |
|
| 45 | + * @since $VID:$ |
|
| 46 | + * @param $code |
|
| 47 | + * @return ModelObjNode[] |
|
| 48 | + * @throws UnexpectedEntityException |
|
| 49 | + */ |
|
| 50 | + public function getModelObjNodesInGroup($code) |
|
| 51 | + { |
|
| 52 | + if (! $code) { |
|
| 53 | + throw new Exception(esc_html__('We aren’t sure which job you are performing. Please press back in your browser and try again.', 'event_espresso')); |
|
| 54 | + } |
|
| 55 | + $deletion_data = get_option($this->getOptionPrefix() . $code, []); |
|
| 56 | + foreach ($deletion_data as $root) { |
|
| 57 | + if (! $root instanceof ModelObjNode) { |
|
| 58 | + throw new UnexpectedEntityException($root, 'ModelObjNode'); |
|
| 59 | + } |
|
| 60 | + } |
|
| 61 | + return $deletion_data; |
|
| 62 | + } |
|
| 63 | 63 | |
| 64 | - /** |
|
| 65 | - * Gets an array indicating what database rows are contained in the job. |
|
| 66 | - * Each top-level key is a model name, and its value is an array of IDs. |
|
| 67 | - * @since $VID:$ |
|
| 68 | - * @param ModelObjNode[] $model_obj_nodes |
|
| 69 | - * @return array |
|
| 70 | - * @throws EE_Error |
|
| 71 | - * @throws InvalidDataTypeException |
|
| 72 | - * @throws InvalidInterfaceException |
|
| 73 | - * @throws InvalidArgumentException |
|
| 74 | - * @throws ReflectionException |
|
| 75 | - */ |
|
| 76 | - public function getModelsAndIdsContainedIn($model_obj_nodes) |
|
| 77 | - { |
|
| 78 | - $models_and_ids_to_delete = []; |
|
| 79 | - foreach ($model_obj_nodes as $root) { |
|
| 80 | - $models_and_ids_to_delete = array_replace_recursive($models_and_ids_to_delete, $root->getIds()); |
|
| 81 | - } |
|
| 82 | - return $models_and_ids_to_delete; |
|
| 83 | - } |
|
| 64 | + /** |
|
| 65 | + * Gets an array indicating what database rows are contained in the job. |
|
| 66 | + * Each top-level key is a model name, and its value is an array of IDs. |
|
| 67 | + * @since $VID:$ |
|
| 68 | + * @param ModelObjNode[] $model_obj_nodes |
|
| 69 | + * @return array |
|
| 70 | + * @throws EE_Error |
|
| 71 | + * @throws InvalidDataTypeException |
|
| 72 | + * @throws InvalidInterfaceException |
|
| 73 | + * @throws InvalidArgumentException |
|
| 74 | + * @throws ReflectionException |
|
| 75 | + */ |
|
| 76 | + public function getModelsAndIdsContainedIn($model_obj_nodes) |
|
| 77 | + { |
|
| 78 | + $models_and_ids_to_delete = []; |
|
| 79 | + foreach ($model_obj_nodes as $root) { |
|
| 80 | + $models_and_ids_to_delete = array_replace_recursive($models_and_ids_to_delete, $root->getIds()); |
|
| 81 | + } |
|
| 82 | + return $models_and_ids_to_delete; |
|
| 83 | + } |
|
| 84 | 84 | |
| 85 | - /** |
|
| 86 | - * Gets an array indicating what database rows are contained in the job. |
|
| 87 | - * Each top-level key is a model name, and its value is an array of IDs. |
|
| 88 | - * @since $VID:$ |
|
| 89 | - * @param string $code |
|
| 90 | - * @return array |
|
| 91 | - * @throws EE_Error |
|
| 92 | - * @throws InvalidArgumentException |
|
| 93 | - * @throws InvalidDataTypeException |
|
| 94 | - * @throws InvalidInterfaceException |
|
| 95 | - * @throws ReflectionException |
|
| 96 | - * @throws UnexpectedEntityException |
|
| 97 | - */ |
|
| 98 | - public function getModelsAndIdsFromGroup($code) |
|
| 99 | - { |
|
| 100 | - $model_obj_nodes = $this->getModelObjNodesInGroup($code); |
|
| 101 | - return $this->getModelsAndIdsContainedIn($model_obj_nodes); |
|
| 102 | - } |
|
| 85 | + /** |
|
| 86 | + * Gets an array indicating what database rows are contained in the job. |
|
| 87 | + * Each top-level key is a model name, and its value is an array of IDs. |
|
| 88 | + * @since $VID:$ |
|
| 89 | + * @param string $code |
|
| 90 | + * @return array |
|
| 91 | + * @throws EE_Error |
|
| 92 | + * @throws InvalidArgumentException |
|
| 93 | + * @throws InvalidDataTypeException |
|
| 94 | + * @throws InvalidInterfaceException |
|
| 95 | + * @throws ReflectionException |
|
| 96 | + * @throws UnexpectedEntityException |
|
| 97 | + */ |
|
| 98 | + public function getModelsAndIdsFromGroup($code) |
|
| 99 | + { |
|
| 100 | + $model_obj_nodes = $this->getModelObjNodesInGroup($code); |
|
| 101 | + return $this->getModelsAndIdsContainedIn($model_obj_nodes); |
|
| 102 | + } |
|
| 103 | 103 | |
| 104 | - /** |
|
| 105 | - * Persists the ModelObjNodes for future requests, using the code for reference. |
|
| 106 | - * @since $VID:$ |
|
| 107 | - * @param ModelObjNode[] $model_obj_nodes |
|
| 108 | - * @param string $code |
|
| 109 | - * @return bool |
|
| 110 | - */ |
|
| 111 | - public function persistModelObjNodesGroup($model_obj_nodes, $code) |
|
| 112 | - { |
|
| 113 | - return add_option( |
|
| 114 | - $this->getOptionPrefix() . $code, |
|
| 115 | - $model_obj_nodes, |
|
| 116 | - null, |
|
| 117 | - 'no' |
|
| 118 | - ); |
|
| 119 | - } |
|
| 104 | + /** |
|
| 105 | + * Persists the ModelObjNodes for future requests, using the code for reference. |
|
| 106 | + * @since $VID:$ |
|
| 107 | + * @param ModelObjNode[] $model_obj_nodes |
|
| 108 | + * @param string $code |
|
| 109 | + * @return bool |
|
| 110 | + */ |
|
| 111 | + public function persistModelObjNodesGroup($model_obj_nodes, $code) |
|
| 112 | + { |
|
| 113 | + return add_option( |
|
| 114 | + $this->getOptionPrefix() . $code, |
|
| 115 | + $model_obj_nodes, |
|
| 116 | + null, |
|
| 117 | + 'no' |
|
| 118 | + ); |
|
| 119 | + } |
|
| 120 | 120 | |
| 121 | - /** |
|
| 122 | - * Forgets about the group of ModelObjNodes. Doesn't delete the rows in the database they reference though. |
|
| 123 | - * @since $VID:$ |
|
| 124 | - * @param $code |
|
| 125 | - * @return bool |
|
| 126 | - */ |
|
| 127 | - public function deleteModelObjNodesInGroup($code) |
|
| 128 | - { |
|
| 129 | - return delete_option($this->getOptionPrefix() . $code); |
|
| 130 | - } |
|
| 121 | + /** |
|
| 122 | + * Forgets about the group of ModelObjNodes. Doesn't delete the rows in the database they reference though. |
|
| 123 | + * @since $VID:$ |
|
| 124 | + * @param $code |
|
| 125 | + * @return bool |
|
| 126 | + */ |
|
| 127 | + public function deleteModelObjNodesInGroup($code) |
|
| 128 | + { |
|
| 129 | + return delete_option($this->getOptionPrefix() . $code); |
|
| 130 | + } |
|
| 131 | 131 | } |
| 132 | 132 | // End of file NodeGroupDao.php |
| 133 | 133 | // Location: EventEspresso\core\services\orm\tree_traversal/NodeGroupDao.php |
@@ -49,12 +49,12 @@ discard block |
||
| 49 | 49 | */ |
| 50 | 50 | public function getModelObjNodesInGroup($code) |
| 51 | 51 | { |
| 52 | - if (! $code) { |
|
| 52 | + if ( ! $code) { |
|
| 53 | 53 | throw new Exception(esc_html__('We aren’t sure which job you are performing. Please press back in your browser and try again.', 'event_espresso')); |
| 54 | 54 | } |
| 55 | - $deletion_data = get_option($this->getOptionPrefix() . $code, []); |
|
| 55 | + $deletion_data = get_option($this->getOptionPrefix().$code, []); |
|
| 56 | 56 | foreach ($deletion_data as $root) { |
| 57 | - if (! $root instanceof ModelObjNode) { |
|
| 57 | + if ( ! $root instanceof ModelObjNode) { |
|
| 58 | 58 | throw new UnexpectedEntityException($root, 'ModelObjNode'); |
| 59 | 59 | } |
| 60 | 60 | } |
@@ -111,7 +111,7 @@ discard block |
||
| 111 | 111 | public function persistModelObjNodesGroup($model_obj_nodes, $code) |
| 112 | 112 | { |
| 113 | 113 | return add_option( |
| 114 | - $this->getOptionPrefix() . $code, |
|
| 114 | + $this->getOptionPrefix().$code, |
|
| 115 | 115 | $model_obj_nodes, |
| 116 | 116 | null, |
| 117 | 117 | 'no' |
@@ -126,7 +126,7 @@ discard block |
||
| 126 | 126 | */ |
| 127 | 127 | public function deleteModelObjNodesInGroup($code) |
| 128 | 128 | { |
| 129 | - return delete_option($this->getOptionPrefix() . $code); |
|
| 129 | + return delete_option($this->getOptionPrefix().$code); |
|
| 130 | 130 | } |
| 131 | 131 | } |
| 132 | 132 | // End of file NodeGroupDao.php |