@@ -15,1821 +15,1821 @@ |
||
| 15 | 15 | { |
| 16 | 16 | |
| 17 | 17 | |
| 18 | - /** |
|
| 19 | - * Used to reference when a registration has never been checked in. |
|
| 20 | - * |
|
| 21 | - * @deprecated use \EE_Checkin::status_checked_never instead |
|
| 22 | - * @type int |
|
| 23 | - */ |
|
| 24 | - const checkin_status_never = 2; |
|
| 25 | - |
|
| 26 | - /** |
|
| 27 | - * Used to reference when a registration has been checked in. |
|
| 28 | - * |
|
| 29 | - * @deprecated use \EE_Checkin::status_checked_in instead |
|
| 30 | - * @type int |
|
| 31 | - */ |
|
| 32 | - const checkin_status_in = 1; |
|
| 33 | - |
|
| 34 | - |
|
| 35 | - /** |
|
| 36 | - * Used to reference when a registration has been checked out. |
|
| 37 | - * |
|
| 38 | - * @deprecated use \EE_Checkin::status_checked_out instead |
|
| 39 | - * @type int |
|
| 40 | - */ |
|
| 41 | - const checkin_status_out = 0; |
|
| 42 | - |
|
| 43 | - |
|
| 44 | - /** |
|
| 45 | - * extra meta key for tracking reg status os trashed registrations |
|
| 46 | - * |
|
| 47 | - * @type string |
|
| 48 | - */ |
|
| 49 | - const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
| 50 | - |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * extra meta key for tracking if registration has reserved ticket |
|
| 54 | - * |
|
| 55 | - * @type string |
|
| 56 | - */ |
|
| 57 | - const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
| 58 | - |
|
| 59 | - |
|
| 60 | - /** |
|
| 61 | - * @param array $props_n_values incoming values |
|
| 62 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 63 | - * used.) |
|
| 64 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 65 | - * date_format and the second value is the time format |
|
| 66 | - * @return EE_Registration |
|
| 67 | - * @throws EE_Error |
|
| 68 | - */ |
|
| 69 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 70 | - { |
|
| 71 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 72 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 73 | - } |
|
| 74 | - |
|
| 75 | - |
|
| 76 | - /** |
|
| 77 | - * @param array $props_n_values incoming values from the database |
|
| 78 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 79 | - * the website will be used. |
|
| 80 | - * @return EE_Registration |
|
| 81 | - */ |
|
| 82 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 83 | - { |
|
| 84 | - return new self($props_n_values, true, $timezone); |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - |
|
| 88 | - /** |
|
| 89 | - * Set Event ID |
|
| 90 | - * |
|
| 91 | - * @param int $EVT_ID Event ID |
|
| 92 | - * @throws EE_Error |
|
| 93 | - * @throws RuntimeException |
|
| 94 | - */ |
|
| 95 | - public function set_event($EVT_ID = 0) |
|
| 96 | - { |
|
| 97 | - $this->set('EVT_ID', $EVT_ID); |
|
| 98 | - } |
|
| 99 | - |
|
| 100 | - |
|
| 101 | - /** |
|
| 102 | - * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
| 103 | - * be routed to internal methods |
|
| 104 | - * |
|
| 105 | - * @param string $field_name |
|
| 106 | - * @param mixed $field_value |
|
| 107 | - * @param bool $use_default |
|
| 108 | - * @throws \EE_Error |
|
| 109 | - * @throws \RuntimeException |
|
| 110 | - */ |
|
| 111 | - public function set($field_name, $field_value, $use_default = false) |
|
| 112 | - { |
|
| 113 | - switch ($field_name) { |
|
| 114 | - case 'REG_code': |
|
| 115 | - if (! empty($field_value) && $this->reg_code() === null) { |
|
| 116 | - $this->set_reg_code($field_value, $use_default); |
|
| 117 | - } |
|
| 118 | - break; |
|
| 119 | - case 'STS_ID': |
|
| 120 | - $this->set_status($field_value, $use_default); |
|
| 121 | - break; |
|
| 122 | - default: |
|
| 123 | - parent::set($field_name, $field_value, $use_default); |
|
| 124 | - } |
|
| 125 | - } |
|
| 126 | - |
|
| 127 | - |
|
| 128 | - /** |
|
| 129 | - * Set Status ID |
|
| 130 | - * updates the registration status and ALSO... |
|
| 131 | - * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
| 132 | - * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
| 133 | - * |
|
| 134 | - * @param string $new_STS_ID |
|
| 135 | - * @param boolean $use_default |
|
| 136 | - * @return bool |
|
| 137 | - * @throws \RuntimeException |
|
| 138 | - * @throws \EE_Error |
|
| 139 | - */ |
|
| 140 | - public function set_status($new_STS_ID = null, $use_default = false) |
|
| 141 | - { |
|
| 142 | - // get current REG_Status |
|
| 143 | - $old_STS_ID = $this->status_ID(); |
|
| 144 | - // if status has changed |
|
| 145 | - if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
| 146 | - && ! empty($old_STS_ID) // and that old status is actually set |
|
| 147 | - && ! empty($new_STS_ID) // as well as the new status |
|
| 148 | - && $this->ID() // ensure registration is in the db |
|
| 149 | - ) { |
|
| 150 | - // TO approved |
|
| 151 | - if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
| 152 | - // reserve a space by incrementing ticket and datetime sold values |
|
| 153 | - $this->_reserve_registration_space(); |
|
| 154 | - do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID); |
|
| 155 | - // OR FROM approved |
|
| 156 | - } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
| 157 | - // release a space by decrementing ticket and datetime sold values |
|
| 158 | - $this->_release_registration_space(); |
|
| 159 | - do_action('AHEE__EE_Registration__set_status__from_approved', $this, $old_STS_ID, $new_STS_ID); |
|
| 160 | - } |
|
| 161 | - // update status |
|
| 162 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 163 | - $this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID); |
|
| 164 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
| 165 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
| 166 | - $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
| 167 | - $this->transaction()->update_status_based_on_total_paid(true); |
|
| 168 | - do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID); |
|
| 169 | - return true; |
|
| 170 | - } |
|
| 171 | - //even though the old value matches the new value, it's still good to |
|
| 172 | - //allow the parent set method to have a say |
|
| 173 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 174 | - return true; |
|
| 175 | - } |
|
| 176 | - |
|
| 177 | - |
|
| 178 | - /** |
|
| 179 | - * update REGs and TXN when cancelled or declined registrations involved |
|
| 180 | - * |
|
| 181 | - * @param string $new_STS_ID |
|
| 182 | - * @param string $old_STS_ID |
|
| 183 | - * @throws \EE_Error |
|
| 184 | - */ |
|
| 185 | - private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID) |
|
| 186 | - { |
|
| 187 | - // these reg statuses should not be considered in any calculations involving monies owing |
|
| 188 | - $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
| 189 | - // true if registration has been cancelled or declined |
|
| 190 | - if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 191 | - && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 192 | - ) { |
|
| 193 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 194 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 195 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 196 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 197 | - // cancelled or declined registration |
|
| 198 | - $registration_processor->update_registration_after_being_canceled_or_declined( |
|
| 199 | - $this, |
|
| 200 | - $closed_reg_statuses |
|
| 201 | - ); |
|
| 202 | - $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
| 203 | - $this, |
|
| 204 | - $closed_reg_statuses, |
|
| 205 | - false |
|
| 206 | - ); |
|
| 207 | - do_action('AHEE__EE_Registration__set_status__canceled_or_declined', $this, $old_STS_ID, $new_STS_ID); |
|
| 208 | - return; |
|
| 209 | - } |
|
| 210 | - // true if reinstating cancelled or declined registration |
|
| 211 | - if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 212 | - && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 213 | - ) { |
|
| 214 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 215 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 216 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 217 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 218 | - // reinstating cancelled or declined registration |
|
| 219 | - $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
| 220 | - $this, |
|
| 221 | - $closed_reg_statuses |
|
| 222 | - ); |
|
| 223 | - $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
| 224 | - $this, |
|
| 225 | - $closed_reg_statuses, |
|
| 226 | - false |
|
| 227 | - ); |
|
| 228 | - do_action('AHEE__EE_Registration__set_status__after_reinstated', $this, $old_STS_ID, $new_STS_ID); |
|
| 229 | - } |
|
| 230 | - } |
|
| 231 | - |
|
| 232 | - |
|
| 233 | - /** |
|
| 234 | - * get Status ID |
|
| 235 | - */ |
|
| 236 | - public function status_ID() |
|
| 237 | - { |
|
| 238 | - return $this->get('STS_ID'); |
|
| 239 | - } |
|
| 240 | - |
|
| 241 | - |
|
| 242 | - /** |
|
| 243 | - * increments this registration's related ticket sold and corresponding datetime sold values |
|
| 244 | - * |
|
| 245 | - * @return void |
|
| 246 | - * @throws EE_Error |
|
| 247 | - * @throws EntityNotFoundException |
|
| 248 | - */ |
|
| 249 | - private function _reserve_registration_space() |
|
| 250 | - { |
|
| 251 | - // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
| 252 | - // so stop tracking that this reg has a ticket reserved |
|
| 253 | - $this->release_reserved_ticket(); |
|
| 254 | - $ticket = $this->ticket(); |
|
| 255 | - $ticket->increase_sold(); |
|
| 256 | - $ticket->save(); |
|
| 257 | - // possibly set event status to sold out |
|
| 258 | - $this->event()->perform_sold_out_status_check(); |
|
| 259 | - } |
|
| 260 | - |
|
| 261 | - |
|
| 262 | - /** |
|
| 263 | - * Gets the ticket this registration is for |
|
| 264 | - * |
|
| 265 | - * @param boolean $include_archived whether to include archived tickets or not. |
|
| 266 | - * @return EE_Ticket|EE_Base_Class |
|
| 267 | - * @throws \EE_Error |
|
| 268 | - */ |
|
| 269 | - public function ticket($include_archived = true) |
|
| 270 | - { |
|
| 271 | - $query_params = array(); |
|
| 272 | - if ($include_archived) { |
|
| 273 | - $query_params['default_where_conditions'] = 'none'; |
|
| 274 | - } |
|
| 275 | - return $this->get_first_related('Ticket', $query_params); |
|
| 276 | - } |
|
| 277 | - |
|
| 278 | - |
|
| 279 | - /** |
|
| 280 | - * Gets the event this registration is for |
|
| 281 | - * |
|
| 282 | - * @return EE_Event |
|
| 283 | - * @throws EE_Error |
|
| 284 | - * @throws EntityNotFoundException |
|
| 285 | - */ |
|
| 286 | - public function event() |
|
| 287 | - { |
|
| 288 | - $event = $this->get_first_related('Event'); |
|
| 289 | - if (! $event instanceof \EE_Event) { |
|
| 290 | - throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
| 291 | - } |
|
| 292 | - return $event; |
|
| 293 | - } |
|
| 294 | - |
|
| 295 | - |
|
| 296 | - /** |
|
| 297 | - * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
| 298 | - * with the author of the event this registration is for. |
|
| 299 | - * |
|
| 300 | - * @since 4.5.0 |
|
| 301 | - * @return int |
|
| 302 | - * @throws EE_Error |
|
| 303 | - * @throws EntityNotFoundException |
|
| 304 | - */ |
|
| 305 | - public function wp_user() |
|
| 306 | - { |
|
| 307 | - $event = $this->event(); |
|
| 308 | - if ($event instanceof EE_Event) { |
|
| 309 | - return $event->wp_user(); |
|
| 310 | - } |
|
| 311 | - return 0; |
|
| 312 | - } |
|
| 313 | - |
|
| 314 | - |
|
| 315 | - /** |
|
| 316 | - * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
| 317 | - * |
|
| 318 | - * @return void |
|
| 319 | - * @throws \EE_Error |
|
| 320 | - */ |
|
| 321 | - private function _release_registration_space() |
|
| 322 | - { |
|
| 323 | - $ticket = $this->ticket(); |
|
| 324 | - $ticket->decrease_sold(); |
|
| 325 | - $ticket->save(); |
|
| 326 | - } |
|
| 327 | - |
|
| 328 | - |
|
| 329 | - /** |
|
| 330 | - * tracks this registration's ticket reservation in extra meta |
|
| 331 | - * and can increment related ticket reserved and corresponding datetime reserved values |
|
| 332 | - * |
|
| 333 | - * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
| 334 | - * @return void |
|
| 335 | - * @throws \EE_Error |
|
| 336 | - */ |
|
| 337 | - public function reserve_ticket($update_ticket = false) |
|
| 338 | - { |
|
| 339 | - if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) === false) { |
|
| 340 | - // PLZ NOTE: although checking $update_ticket first would be more efficient, |
|
| 341 | - // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 342 | - if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) && $update_ticket) { |
|
| 343 | - $ticket = $this->ticket(); |
|
| 344 | - $ticket->increase_reserved(); |
|
| 345 | - $ticket->save(); |
|
| 346 | - } |
|
| 347 | - } |
|
| 348 | - } |
|
| 349 | - |
|
| 350 | - |
|
| 351 | - /** |
|
| 352 | - * stops tracking this registration's ticket reservation in extra meta |
|
| 353 | - * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
| 354 | - * |
|
| 355 | - * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
| 356 | - * @return void |
|
| 357 | - * @throws \EE_Error |
|
| 358 | - */ |
|
| 359 | - public function release_reserved_ticket($update_ticket = false) |
|
| 360 | - { |
|
| 361 | - if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) !== false) { |
|
| 362 | - // PLZ NOTE: although checking $update_ticket first would be more efficient, |
|
| 363 | - // we NEED to ALWAYS call delete_extra_meta(), which is why that is done first |
|
| 364 | - if ($this->delete_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY) && $update_ticket) { |
|
| 365 | - $ticket = $this->ticket(); |
|
| 366 | - $ticket->decrease_reserved(); |
|
| 367 | - $ticket->save(); |
|
| 368 | - } |
|
| 369 | - } |
|
| 370 | - } |
|
| 371 | - |
|
| 372 | - |
|
| 373 | - /** |
|
| 374 | - * Set Attendee ID |
|
| 375 | - * |
|
| 376 | - * @param int $ATT_ID Attendee ID |
|
| 377 | - * @throws EE_Error |
|
| 378 | - * @throws RuntimeException |
|
| 379 | - */ |
|
| 380 | - public function set_attendee_id($ATT_ID = 0) |
|
| 381 | - { |
|
| 382 | - $this->set('ATT_ID', $ATT_ID); |
|
| 383 | - } |
|
| 384 | - |
|
| 385 | - |
|
| 386 | - /** |
|
| 387 | - * Set Transaction ID |
|
| 388 | - * |
|
| 389 | - * @param int $TXN_ID Transaction ID |
|
| 390 | - * @throws EE_Error |
|
| 391 | - * @throws RuntimeException |
|
| 392 | - */ |
|
| 393 | - public function set_transaction_id($TXN_ID = 0) |
|
| 394 | - { |
|
| 395 | - $this->set('TXN_ID', $TXN_ID); |
|
| 396 | - } |
|
| 397 | - |
|
| 398 | - |
|
| 399 | - /** |
|
| 400 | - * Set Session |
|
| 401 | - * |
|
| 402 | - * @param string $REG_session PHP Session ID |
|
| 403 | - * @throws EE_Error |
|
| 404 | - * @throws RuntimeException |
|
| 405 | - */ |
|
| 406 | - public function set_session($REG_session = '') |
|
| 407 | - { |
|
| 408 | - $this->set('REG_session', $REG_session); |
|
| 409 | - } |
|
| 410 | - |
|
| 411 | - |
|
| 412 | - /** |
|
| 413 | - * Set Registration URL Link |
|
| 414 | - * |
|
| 415 | - * @param string $REG_url_link Registration URL Link |
|
| 416 | - * @throws EE_Error |
|
| 417 | - * @throws RuntimeException |
|
| 418 | - */ |
|
| 419 | - public function set_reg_url_link($REG_url_link = '') |
|
| 420 | - { |
|
| 421 | - $this->set('REG_url_link', $REG_url_link); |
|
| 422 | - } |
|
| 423 | - |
|
| 424 | - |
|
| 425 | - /** |
|
| 426 | - * Set Attendee Counter |
|
| 427 | - * |
|
| 428 | - * @param int $REG_count Primary Attendee |
|
| 429 | - * @throws EE_Error |
|
| 430 | - * @throws RuntimeException |
|
| 431 | - */ |
|
| 432 | - public function set_count($REG_count = 1) |
|
| 433 | - { |
|
| 434 | - $this->set('REG_count', $REG_count); |
|
| 435 | - } |
|
| 436 | - |
|
| 437 | - |
|
| 438 | - /** |
|
| 439 | - * Set Group Size |
|
| 440 | - * |
|
| 441 | - * @param boolean $REG_group_size Group Registration |
|
| 442 | - * @throws EE_Error |
|
| 443 | - * @throws RuntimeException |
|
| 444 | - */ |
|
| 445 | - public function set_group_size($REG_group_size = false) |
|
| 446 | - { |
|
| 447 | - $this->set('REG_group_size', $REG_group_size); |
|
| 448 | - } |
|
| 449 | - |
|
| 450 | - |
|
| 451 | - /** |
|
| 452 | - * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
| 453 | - * EEM_Registration::status_id_not_approved |
|
| 454 | - * |
|
| 455 | - * @return boolean |
|
| 456 | - */ |
|
| 457 | - public function is_not_approved() |
|
| 458 | - { |
|
| 459 | - return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
| 460 | - } |
|
| 461 | - |
|
| 462 | - |
|
| 463 | - /** |
|
| 464 | - * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
| 465 | - * EEM_Registration::status_id_pending_payment |
|
| 466 | - * |
|
| 467 | - * @return boolean |
|
| 468 | - */ |
|
| 469 | - public function is_pending_payment() |
|
| 470 | - { |
|
| 471 | - return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
| 472 | - } |
|
| 473 | - |
|
| 474 | - |
|
| 475 | - /** |
|
| 476 | - * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
| 477 | - * |
|
| 478 | - * @return boolean |
|
| 479 | - */ |
|
| 480 | - public function is_approved() |
|
| 481 | - { |
|
| 482 | - return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
| 483 | - } |
|
| 484 | - |
|
| 485 | - |
|
| 486 | - /** |
|
| 487 | - * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
| 488 | - * |
|
| 489 | - * @return boolean |
|
| 490 | - */ |
|
| 491 | - public function is_cancelled() |
|
| 492 | - { |
|
| 493 | - return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
| 494 | - } |
|
| 495 | - |
|
| 496 | - |
|
| 497 | - /** |
|
| 498 | - * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
| 499 | - * |
|
| 500 | - * @return boolean |
|
| 501 | - */ |
|
| 502 | - public function is_declined() |
|
| 503 | - { |
|
| 504 | - return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
| 505 | - } |
|
| 506 | - |
|
| 507 | - |
|
| 508 | - /** |
|
| 509 | - * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
| 510 | - * EEM_Registration::status_id_incomplete |
|
| 511 | - * |
|
| 512 | - * @return boolean |
|
| 513 | - */ |
|
| 514 | - public function is_incomplete() |
|
| 515 | - { |
|
| 516 | - return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
| 517 | - } |
|
| 518 | - |
|
| 519 | - |
|
| 520 | - /** |
|
| 521 | - * Set Registration Date |
|
| 522 | - * |
|
| 523 | - * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
| 524 | - * Date |
|
| 525 | - * @throws EE_Error |
|
| 526 | - * @throws RuntimeException |
|
| 527 | - */ |
|
| 528 | - public function set_reg_date($REG_date = false) |
|
| 529 | - { |
|
| 530 | - $this->set('REG_date', $REG_date); |
|
| 531 | - } |
|
| 532 | - |
|
| 533 | - |
|
| 534 | - /** |
|
| 535 | - * Set final price owing for this registration after all ticket/price modifications |
|
| 536 | - * |
|
| 537 | - * @access public |
|
| 538 | - * @param float $REG_final_price |
|
| 539 | - * @throws EE_Error |
|
| 540 | - * @throws RuntimeException |
|
| 541 | - */ |
|
| 542 | - public function set_final_price($REG_final_price = 0.00) |
|
| 543 | - { |
|
| 544 | - $this->set('REG_final_price', $REG_final_price); |
|
| 545 | - } |
|
| 546 | - |
|
| 547 | - |
|
| 548 | - /** |
|
| 549 | - * Set amount paid towards this registration's final price |
|
| 550 | - * |
|
| 551 | - * @access public |
|
| 552 | - * @param float $REG_paid |
|
| 553 | - * @throws EE_Error |
|
| 554 | - * @throws RuntimeException |
|
| 555 | - */ |
|
| 556 | - public function set_paid($REG_paid = 0.00) |
|
| 557 | - { |
|
| 558 | - $this->set('REG_paid', $REG_paid); |
|
| 559 | - } |
|
| 560 | - |
|
| 561 | - |
|
| 562 | - /** |
|
| 563 | - * Attendee Is Going |
|
| 564 | - * |
|
| 565 | - * @param boolean $REG_att_is_going Attendee Is Going |
|
| 566 | - * @throws EE_Error |
|
| 567 | - * @throws RuntimeException |
|
| 568 | - */ |
|
| 569 | - public function set_att_is_going($REG_att_is_going = false) |
|
| 570 | - { |
|
| 571 | - $this->set('REG_att_is_going', $REG_att_is_going); |
|
| 572 | - } |
|
| 573 | - |
|
| 574 | - |
|
| 575 | - /** |
|
| 576 | - * Gets the related attendee |
|
| 577 | - * |
|
| 578 | - * @return EE_Attendee |
|
| 579 | - * @throws EE_Error |
|
| 580 | - */ |
|
| 581 | - public function attendee() |
|
| 582 | - { |
|
| 583 | - return $this->get_first_related('Attendee'); |
|
| 584 | - } |
|
| 585 | - |
|
| 586 | - |
|
| 587 | - /** |
|
| 588 | - * get Event ID |
|
| 589 | - */ |
|
| 590 | - public function event_ID() |
|
| 591 | - { |
|
| 592 | - return $this->get('EVT_ID'); |
|
| 593 | - } |
|
| 594 | - |
|
| 595 | - |
|
| 596 | - /** |
|
| 597 | - * get Event ID |
|
| 598 | - */ |
|
| 599 | - public function event_name() |
|
| 600 | - { |
|
| 601 | - $event = $this->event_obj(); |
|
| 602 | - if ($event) { |
|
| 603 | - return $event->name(); |
|
| 604 | - } else { |
|
| 605 | - return null; |
|
| 606 | - } |
|
| 607 | - } |
|
| 608 | - |
|
| 609 | - |
|
| 610 | - /** |
|
| 611 | - * Fetches the event this registration is for |
|
| 612 | - * |
|
| 613 | - * @return EE_Event |
|
| 614 | - * @throws EE_Error |
|
| 615 | - */ |
|
| 616 | - public function event_obj() |
|
| 617 | - { |
|
| 618 | - return $this->get_first_related('Event'); |
|
| 619 | - } |
|
| 620 | - |
|
| 621 | - |
|
| 622 | - /** |
|
| 623 | - * get Attendee ID |
|
| 624 | - */ |
|
| 625 | - public function attendee_ID() |
|
| 626 | - { |
|
| 627 | - return $this->get('ATT_ID'); |
|
| 628 | - } |
|
| 629 | - |
|
| 630 | - |
|
| 631 | - /** |
|
| 632 | - * get PHP Session ID |
|
| 633 | - */ |
|
| 634 | - public function session_ID() |
|
| 635 | - { |
|
| 636 | - return $this->get('REG_session'); |
|
| 637 | - } |
|
| 638 | - |
|
| 639 | - |
|
| 640 | - /** |
|
| 641 | - * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
| 642 | - * |
|
| 643 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 644 | - * @return string |
|
| 645 | - */ |
|
| 646 | - public function receipt_url($messenger = 'html') |
|
| 647 | - { |
|
| 648 | - |
|
| 649 | - /** |
|
| 650 | - * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
| 651 | - * already in use on old system. If there is then we just return the standard url for it. |
|
| 652 | - * |
|
| 653 | - * @since 4.5.0 |
|
| 654 | - */ |
|
| 655 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
| 656 | - $has_custom = EEH_Template::locate_template( |
|
| 657 | - $template_relative_path, |
|
| 658 | - array(), |
|
| 659 | - true, |
|
| 660 | - true, |
|
| 661 | - true |
|
| 662 | - ); |
|
| 663 | - |
|
| 664 | - if ($has_custom) { |
|
| 665 | - return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
| 666 | - } |
|
| 667 | - return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
| 668 | - } |
|
| 669 | - |
|
| 670 | - |
|
| 671 | - /** |
|
| 672 | - * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
| 673 | - * |
|
| 674 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 675 | - * @return string |
|
| 676 | - * @throws EE_Error |
|
| 677 | - */ |
|
| 678 | - public function invoice_url($messenger = 'html') |
|
| 679 | - { |
|
| 680 | - /** |
|
| 681 | - * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
| 682 | - * already in use on old system. If there is then we just return the standard url for it. |
|
| 683 | - * |
|
| 684 | - * @since 4.5.0 |
|
| 685 | - */ |
|
| 686 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
| 687 | - $has_custom = EEH_Template::locate_template( |
|
| 688 | - $template_relative_path, |
|
| 689 | - array(), |
|
| 690 | - true, |
|
| 691 | - true, |
|
| 692 | - true |
|
| 693 | - ); |
|
| 694 | - |
|
| 695 | - if ($has_custom) { |
|
| 696 | - if ($messenger == 'html') { |
|
| 697 | - return $this->invoice_url('launch'); |
|
| 698 | - } |
|
| 699 | - $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
| 700 | - |
|
| 701 | - $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
| 702 | - if ($messenger == 'html') { |
|
| 703 | - $query_args['html'] = true; |
|
| 704 | - } |
|
| 705 | - return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
| 706 | - } |
|
| 707 | - return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
| 708 | - } |
|
| 709 | - |
|
| 710 | - |
|
| 711 | - /** |
|
| 712 | - * get Registration URL Link |
|
| 713 | - * |
|
| 714 | - * @access public |
|
| 715 | - * @return string |
|
| 716 | - * @throws \EE_Error |
|
| 717 | - */ |
|
| 718 | - public function reg_url_link() |
|
| 719 | - { |
|
| 720 | - return (string) $this->get('REG_url_link'); |
|
| 721 | - } |
|
| 722 | - |
|
| 723 | - |
|
| 724 | - /** |
|
| 725 | - * Echoes out invoice_url() |
|
| 726 | - * |
|
| 727 | - * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
| 728 | - * @return void |
|
| 729 | - * @throws EE_Error |
|
| 730 | - */ |
|
| 731 | - public function e_invoice_url($type = 'launch') |
|
| 732 | - { |
|
| 733 | - echo $this->invoice_url($type); |
|
| 734 | - } |
|
| 735 | - |
|
| 736 | - |
|
| 737 | - /** |
|
| 738 | - * Echoes out payment_overview_url |
|
| 739 | - */ |
|
| 740 | - public function e_payment_overview_url() |
|
| 741 | - { |
|
| 742 | - echo $this->payment_overview_url(); |
|
| 743 | - } |
|
| 744 | - |
|
| 745 | - |
|
| 746 | - /** |
|
| 747 | - * Gets the URL of the thank you page with this registration REG_url_link added as |
|
| 748 | - * a query parameter |
|
| 749 | - * |
|
| 750 | - * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
| 751 | - * payment overview url. |
|
| 752 | - * @return string |
|
| 753 | - * @throws EE_Error |
|
| 754 | - */ |
|
| 755 | - public function payment_overview_url($clear_session = false) |
|
| 756 | - { |
|
| 757 | - return add_query_arg(array( |
|
| 758 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
| 759 | - 'step' => 'payment_options', |
|
| 760 | - 'revisit' => true, |
|
| 761 | - 'clear_session' => (bool) $clear_session |
|
| 762 | - ), EE_Registry::instance()->CFG->core->reg_page_url()); |
|
| 763 | - } |
|
| 764 | - |
|
| 765 | - |
|
| 766 | - /** |
|
| 767 | - * Gets the URL of the thank you page with this registration REG_url_link added as |
|
| 768 | - * a query parameter |
|
| 769 | - * |
|
| 770 | - * @return string |
|
| 771 | - * @throws EE_Error |
|
| 772 | - */ |
|
| 773 | - public function edit_attendee_information_url() |
|
| 774 | - { |
|
| 775 | - return add_query_arg(array( |
|
| 776 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
| 777 | - 'step' => 'attendee_information', |
|
| 778 | - 'revisit' => true, |
|
| 779 | - ), EE_Registry::instance()->CFG->core->reg_page_url()); |
|
| 780 | - } |
|
| 781 | - |
|
| 782 | - |
|
| 783 | - /** |
|
| 784 | - * Simply generates and returns the appropriate admin_url link to edit this registration |
|
| 785 | - * |
|
| 786 | - * @return string |
|
| 787 | - * @throws EE_Error |
|
| 788 | - */ |
|
| 789 | - public function get_admin_edit_url() |
|
| 790 | - { |
|
| 791 | - return EEH_URL::add_query_args_and_nonce(array( |
|
| 792 | - 'page' => 'espresso_registrations', |
|
| 793 | - 'action' => 'view_registration', |
|
| 794 | - '_REG_ID' => $this->ID(), |
|
| 795 | - ), admin_url('admin.php')); |
|
| 796 | - } |
|
| 797 | - |
|
| 798 | - |
|
| 799 | - /** |
|
| 800 | - * is_primary_registrant? |
|
| 801 | - */ |
|
| 802 | - public function is_primary_registrant() |
|
| 803 | - { |
|
| 804 | - return $this->get('REG_count') == 1 ? true : false; |
|
| 805 | - } |
|
| 806 | - |
|
| 807 | - |
|
| 808 | - /** |
|
| 809 | - * This returns the primary registration object for this registration group (which may be this object). |
|
| 810 | - * |
|
| 811 | - * @return EE_Registration |
|
| 812 | - * @throws EE_Error |
|
| 813 | - */ |
|
| 814 | - public function get_primary_registration() |
|
| 815 | - { |
|
| 816 | - if ($this->is_primary_registrant()) { |
|
| 817 | - return $this; |
|
| 818 | - } |
|
| 819 | - |
|
| 820 | - //k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
| 821 | - /** @var EE_Registration $primary_registrant */ |
|
| 822 | - $primary_registrant = EEM_Registration::instance()->get_one(array( |
|
| 823 | - array( |
|
| 824 | - 'TXN_ID' => $this->transaction_ID(), |
|
| 825 | - 'REG_count' => 1, |
|
| 826 | - ), |
|
| 827 | - )); |
|
| 828 | - return $primary_registrant; |
|
| 829 | - } |
|
| 830 | - |
|
| 831 | - |
|
| 832 | - /** |
|
| 833 | - * get Attendee Number |
|
| 834 | - * |
|
| 835 | - * @access public |
|
| 836 | - */ |
|
| 837 | - public function count() |
|
| 838 | - { |
|
| 839 | - return $this->get('REG_count'); |
|
| 840 | - } |
|
| 841 | - |
|
| 842 | - |
|
| 843 | - /** |
|
| 844 | - * get Group Size |
|
| 845 | - */ |
|
| 846 | - public function group_size() |
|
| 847 | - { |
|
| 848 | - return $this->get('REG_group_size'); |
|
| 849 | - } |
|
| 850 | - |
|
| 851 | - |
|
| 852 | - /** |
|
| 853 | - * get Registration Date |
|
| 854 | - */ |
|
| 855 | - public function date() |
|
| 856 | - { |
|
| 857 | - return $this->get('REG_date'); |
|
| 858 | - } |
|
| 859 | - |
|
| 860 | - |
|
| 861 | - /** |
|
| 862 | - * gets a pretty date |
|
| 863 | - * |
|
| 864 | - * @param string $date_format |
|
| 865 | - * @param string $time_format |
|
| 866 | - * @return string |
|
| 867 | - * @throws EE_Error |
|
| 868 | - */ |
|
| 869 | - public function pretty_date($date_format = null, $time_format = null) |
|
| 870 | - { |
|
| 871 | - return $this->get_datetime('REG_date', $date_format, $time_format); |
|
| 872 | - } |
|
| 873 | - |
|
| 874 | - |
|
| 875 | - /** |
|
| 876 | - * final_price |
|
| 877 | - * the registration's share of the transaction total, so that the |
|
| 878 | - * sum of all the transaction's REG_final_prices equal the transaction's total |
|
| 879 | - * |
|
| 880 | - * @return float |
|
| 881 | - * @throws EE_Error |
|
| 882 | - */ |
|
| 883 | - public function final_price() |
|
| 884 | - { |
|
| 885 | - return $this->get('REG_final_price'); |
|
| 886 | - } |
|
| 887 | - |
|
| 888 | - |
|
| 889 | - /** |
|
| 890 | - * pretty_final_price |
|
| 891 | - * final price as formatted string, with correct decimal places and currency symbol |
|
| 892 | - * |
|
| 893 | - * @return string |
|
| 894 | - * @throws EE_Error |
|
| 895 | - */ |
|
| 896 | - public function pretty_final_price() |
|
| 897 | - { |
|
| 898 | - return $this->get_pretty('REG_final_price'); |
|
| 899 | - } |
|
| 900 | - |
|
| 901 | - |
|
| 902 | - /** |
|
| 903 | - * get paid (yeah) |
|
| 904 | - * |
|
| 905 | - * @return float |
|
| 906 | - * @throws EE_Error |
|
| 907 | - */ |
|
| 908 | - public function paid() |
|
| 909 | - { |
|
| 910 | - return $this->get('REG_paid'); |
|
| 911 | - } |
|
| 912 | - |
|
| 913 | - |
|
| 914 | - /** |
|
| 915 | - * pretty_paid |
|
| 916 | - * |
|
| 917 | - * @return float |
|
| 918 | - * @throws EE_Error |
|
| 919 | - */ |
|
| 920 | - public function pretty_paid() |
|
| 921 | - { |
|
| 922 | - return $this->get_pretty('REG_paid'); |
|
| 923 | - } |
|
| 924 | - |
|
| 925 | - |
|
| 926 | - /** |
|
| 927 | - * owes_monies_and_can_pay |
|
| 928 | - * whether or not this registration has monies owing and it's' status allows payment |
|
| 929 | - * |
|
| 930 | - * @param array $requires_payment |
|
| 931 | - * @return bool |
|
| 932 | - * @throws EE_Error |
|
| 933 | - */ |
|
| 934 | - public function owes_monies_and_can_pay($requires_payment = array()) |
|
| 935 | - { |
|
| 936 | - // these reg statuses require payment (if event is not free) |
|
| 937 | - $requires_payment = ! empty($requires_payment) |
|
| 938 | - ? $requires_payment |
|
| 939 | - : EEM_Registration::reg_statuses_that_allow_payment(); |
|
| 940 | - if (in_array($this->status_ID(), $requires_payment) && |
|
| 941 | - $this->final_price() != 0 && |
|
| 942 | - $this->final_price() != $this->paid() |
|
| 943 | - ) { |
|
| 944 | - return true; |
|
| 945 | - } else { |
|
| 946 | - return false; |
|
| 947 | - } |
|
| 948 | - } |
|
| 949 | - |
|
| 950 | - |
|
| 951 | - /** |
|
| 952 | - * Prints out the return value of $this->pretty_status() |
|
| 953 | - * |
|
| 954 | - * @param bool $show_icons |
|
| 955 | - * @return void |
|
| 956 | - * @throws EE_Error |
|
| 957 | - */ |
|
| 958 | - public function e_pretty_status($show_icons = false) |
|
| 959 | - { |
|
| 960 | - echo $this->pretty_status($show_icons); |
|
| 961 | - } |
|
| 962 | - |
|
| 963 | - |
|
| 964 | - /** |
|
| 965 | - * Returns a nice version of the status for displaying to customers |
|
| 966 | - * |
|
| 967 | - * @param bool $show_icons |
|
| 968 | - * @return string |
|
| 969 | - * @throws EE_Error |
|
| 970 | - */ |
|
| 971 | - public function pretty_status($show_icons = false) |
|
| 972 | - { |
|
| 973 | - $status = EEM_Status::instance()->localized_status( |
|
| 974 | - array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
| 975 | - false, |
|
| 976 | - 'sentence' |
|
| 977 | - ); |
|
| 978 | - $icon = ''; |
|
| 979 | - switch ($this->status_ID()) { |
|
| 980 | - case EEM_Registration::status_id_approved: |
|
| 981 | - $icon = $show_icons |
|
| 982 | - ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
| 983 | - : ''; |
|
| 984 | - break; |
|
| 985 | - case EEM_Registration::status_id_pending_payment: |
|
| 986 | - $icon = $show_icons |
|
| 987 | - ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
| 988 | - : ''; |
|
| 989 | - break; |
|
| 990 | - case EEM_Registration::status_id_not_approved: |
|
| 991 | - $icon = $show_icons |
|
| 992 | - ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
| 993 | - : ''; |
|
| 994 | - break; |
|
| 995 | - case EEM_Registration::status_id_cancelled: |
|
| 996 | - $icon = $show_icons |
|
| 997 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
| 998 | - : ''; |
|
| 999 | - break; |
|
| 1000 | - case EEM_Registration::status_id_incomplete: |
|
| 1001 | - $icon = $show_icons |
|
| 1002 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
| 1003 | - : ''; |
|
| 1004 | - break; |
|
| 1005 | - case EEM_Registration::status_id_declined: |
|
| 1006 | - $icon = $show_icons |
|
| 1007 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
| 1008 | - : ''; |
|
| 1009 | - break; |
|
| 1010 | - case EEM_Registration::status_id_wait_list: |
|
| 1011 | - $icon = $show_icons |
|
| 1012 | - ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
| 1013 | - : ''; |
|
| 1014 | - break; |
|
| 1015 | - } |
|
| 1016 | - return $icon . $status[$this->status_ID()]; |
|
| 1017 | - } |
|
| 1018 | - |
|
| 1019 | - |
|
| 1020 | - /** |
|
| 1021 | - * get Attendee Is Going |
|
| 1022 | - */ |
|
| 1023 | - public function att_is_going() |
|
| 1024 | - { |
|
| 1025 | - return $this->get('REG_att_is_going'); |
|
| 1026 | - } |
|
| 1027 | - |
|
| 1028 | - |
|
| 1029 | - /** |
|
| 1030 | - * Gets related answers |
|
| 1031 | - * |
|
| 1032 | - * @param array $query_params like EEM_Base::get_all |
|
| 1033 | - * @return EE_Answer[] |
|
| 1034 | - * @throws EE_Error |
|
| 1035 | - */ |
|
| 1036 | - public function answers($query_params = null) |
|
| 1037 | - { |
|
| 1038 | - return $this->get_many_related('Answer', $query_params); |
|
| 1039 | - } |
|
| 1040 | - |
|
| 1041 | - |
|
| 1042 | - /** |
|
| 1043 | - * Gets the registration's answer value to the specified question |
|
| 1044 | - * (either the question's ID or a question object) |
|
| 1045 | - * |
|
| 1046 | - * @param EE_Question|int $question |
|
| 1047 | - * @param bool $pretty_value |
|
| 1048 | - * @return array|string if pretty_value= true, the result will always be a string |
|
| 1049 | - * (because the answer might be an array of answer values, so passing pretty_value=true |
|
| 1050 | - * will convert it into some kind of string) |
|
| 1051 | - * @throws EE_Error |
|
| 1052 | - */ |
|
| 1053 | - public function answer_value_to_question($question, $pretty_value = true) |
|
| 1054 | - { |
|
| 1055 | - $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
| 1056 | - return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
| 1057 | - } |
|
| 1058 | - |
|
| 1059 | - |
|
| 1060 | - /** |
|
| 1061 | - * question_groups |
|
| 1062 | - * returns an array of EE_Question_Group objects for this registration |
|
| 1063 | - * |
|
| 1064 | - * @return EE_Question_Group[] |
|
| 1065 | - * @throws EE_Error |
|
| 1066 | - * @throws EntityNotFoundException |
|
| 1067 | - */ |
|
| 1068 | - public function question_groups() |
|
| 1069 | - { |
|
| 1070 | - $question_groups = array(); |
|
| 1071 | - if ($this->event() instanceof EE_Event) { |
|
| 1072 | - $question_groups = $this->event()->question_groups( |
|
| 1073 | - array( |
|
| 1074 | - array( |
|
| 1075 | - 'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false, |
|
| 1076 | - ), |
|
| 1077 | - 'order_by' => array('QSG_order' => 'ASC'), |
|
| 1078 | - ) |
|
| 1079 | - ); |
|
| 1080 | - } |
|
| 1081 | - return $question_groups; |
|
| 1082 | - } |
|
| 1083 | - |
|
| 1084 | - |
|
| 1085 | - /** |
|
| 1086 | - * count_question_groups |
|
| 1087 | - * returns a count of the number of EE_Question_Group objects for this registration |
|
| 1088 | - * |
|
| 1089 | - * @return int |
|
| 1090 | - * @throws EE_Error |
|
| 1091 | - * @throws EntityNotFoundException |
|
| 1092 | - */ |
|
| 1093 | - public function count_question_groups() |
|
| 1094 | - { |
|
| 1095 | - $qg_count = 0; |
|
| 1096 | - if ($this->event() instanceof EE_Event) { |
|
| 1097 | - $qg_count = $this->event()->count_related( |
|
| 1098 | - 'Question_Group', |
|
| 1099 | - array( |
|
| 1100 | - array( |
|
| 1101 | - 'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false, |
|
| 1102 | - ), |
|
| 1103 | - ) |
|
| 1104 | - ); |
|
| 1105 | - } |
|
| 1106 | - return $qg_count; |
|
| 1107 | - } |
|
| 1108 | - |
|
| 1109 | - |
|
| 1110 | - /** |
|
| 1111 | - * Returns the registration date in the 'standard' string format |
|
| 1112 | - * (function may be improved in the future to allow for different formats and timezones) |
|
| 1113 | - * |
|
| 1114 | - * @return string |
|
| 1115 | - * @throws EE_Error |
|
| 1116 | - */ |
|
| 1117 | - public function reg_date() |
|
| 1118 | - { |
|
| 1119 | - return $this->get_datetime('REG_date'); |
|
| 1120 | - } |
|
| 1121 | - |
|
| 1122 | - |
|
| 1123 | - /** |
|
| 1124 | - * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
| 1125 | - * the ticket this registration purchased, or the datetime they have registered |
|
| 1126 | - * to attend) |
|
| 1127 | - * |
|
| 1128 | - * @return EE_Datetime_Ticket |
|
| 1129 | - * @throws EE_Error |
|
| 1130 | - */ |
|
| 1131 | - public function datetime_ticket() |
|
| 1132 | - { |
|
| 1133 | - return $this->get_first_related('Datetime_Ticket'); |
|
| 1134 | - } |
|
| 1135 | - |
|
| 1136 | - |
|
| 1137 | - /** |
|
| 1138 | - * Sets the registration's datetime_ticket. |
|
| 1139 | - * |
|
| 1140 | - * @param EE_Datetime_Ticket $datetime_ticket |
|
| 1141 | - * @return EE_Datetime_Ticket |
|
| 1142 | - * @throws EE_Error |
|
| 1143 | - */ |
|
| 1144 | - public function set_datetime_ticket($datetime_ticket) |
|
| 1145 | - { |
|
| 1146 | - return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
| 1147 | - } |
|
| 1148 | - |
|
| 1149 | - /** |
|
| 1150 | - * Gets deleted |
|
| 1151 | - * |
|
| 1152 | - * @return bool |
|
| 1153 | - * @throws EE_Error |
|
| 1154 | - */ |
|
| 1155 | - public function deleted() |
|
| 1156 | - { |
|
| 1157 | - return $this->get('REG_deleted'); |
|
| 1158 | - } |
|
| 1159 | - |
|
| 1160 | - /** |
|
| 1161 | - * Sets deleted |
|
| 1162 | - * |
|
| 1163 | - * @param boolean $deleted |
|
| 1164 | - * @return bool |
|
| 1165 | - * @throws EE_Error |
|
| 1166 | - * @throws RuntimeException |
|
| 1167 | - */ |
|
| 1168 | - public function set_deleted($deleted) |
|
| 1169 | - { |
|
| 1170 | - if ($deleted) { |
|
| 1171 | - $this->delete(); |
|
| 1172 | - } else { |
|
| 1173 | - $this->restore(); |
|
| 1174 | - } |
|
| 1175 | - } |
|
| 1176 | - |
|
| 1177 | - |
|
| 1178 | - /** |
|
| 1179 | - * Get the status object of this object |
|
| 1180 | - * |
|
| 1181 | - * @return EE_Status |
|
| 1182 | - * @throws EE_Error |
|
| 1183 | - */ |
|
| 1184 | - public function status_obj() |
|
| 1185 | - { |
|
| 1186 | - return $this->get_first_related('Status'); |
|
| 1187 | - } |
|
| 1188 | - |
|
| 1189 | - |
|
| 1190 | - /** |
|
| 1191 | - * Returns the number of times this registration has checked into any of the datetimes |
|
| 1192 | - * its available for |
|
| 1193 | - * |
|
| 1194 | - * @return int |
|
| 1195 | - * @throws EE_Error |
|
| 1196 | - */ |
|
| 1197 | - public function count_checkins() |
|
| 1198 | - { |
|
| 1199 | - return $this->get_model()->count_related($this, 'Checkin'); |
|
| 1200 | - } |
|
| 1201 | - |
|
| 1202 | - |
|
| 1203 | - /** |
|
| 1204 | - * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
| 1205 | - * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
| 1206 | - * |
|
| 1207 | - * @return int |
|
| 1208 | - * @throws EE_Error |
|
| 1209 | - */ |
|
| 1210 | - public function count_checkins_not_checkedout() |
|
| 1211 | - { |
|
| 1212 | - return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
| 1213 | - } |
|
| 1214 | - |
|
| 1215 | - |
|
| 1216 | - /** |
|
| 1217 | - * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
| 1218 | - * |
|
| 1219 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1220 | - * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
| 1221 | - * consider registration status as well as datetime access. |
|
| 1222 | - * @return bool |
|
| 1223 | - * @throws EE_Error |
|
| 1224 | - */ |
|
| 1225 | - public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
| 1226 | - { |
|
| 1227 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1228 | - |
|
| 1229 | - //first check registration status |
|
| 1230 | - if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
| 1231 | - return false; |
|
| 1232 | - } |
|
| 1233 | - //is there a datetime ticket that matches this dtt_ID? |
|
| 1234 | - if (! (EEM_Datetime_Ticket::instance()->exists(array( |
|
| 1235 | - array( |
|
| 1236 | - 'TKT_ID' => $this->get('TKT_ID'), |
|
| 1237 | - 'DTT_ID' => $DTT_ID, |
|
| 1238 | - ), |
|
| 1239 | - ))) |
|
| 1240 | - ) { |
|
| 1241 | - return false; |
|
| 1242 | - } |
|
| 1243 | - |
|
| 1244 | - //final check is against TKT_uses |
|
| 1245 | - return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
| 1246 | - } |
|
| 1247 | - |
|
| 1248 | - |
|
| 1249 | - /** |
|
| 1250 | - * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
| 1251 | - * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
| 1252 | - * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
| 1253 | - * then return false. Otherwise return true. |
|
| 1254 | - * |
|
| 1255 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1256 | - * @return bool true means can checkin. false means cannot checkin. |
|
| 1257 | - * @throws EE_Error |
|
| 1258 | - */ |
|
| 1259 | - public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
| 1260 | - { |
|
| 1261 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1262 | - |
|
| 1263 | - if (! $DTT_ID) { |
|
| 1264 | - return false; |
|
| 1265 | - } |
|
| 1266 | - |
|
| 1267 | - $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
| 1268 | - |
|
| 1269 | - // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
| 1270 | - // check-in or not. |
|
| 1271 | - if (! $max_uses || $max_uses === EE_INF) { |
|
| 1272 | - return true; |
|
| 1273 | - } |
|
| 1274 | - |
|
| 1275 | - //does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
| 1276 | - //go ahead and toggle. |
|
| 1277 | - if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
| 1278 | - return true; |
|
| 1279 | - } |
|
| 1280 | - |
|
| 1281 | - //made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
| 1282 | - //disallows further check-ins. |
|
| 1283 | - $count_unique_dtt_checkins = EEM_Checkin::instance()->count(array( |
|
| 1284 | - array( |
|
| 1285 | - 'REG_ID' => $this->ID(), |
|
| 1286 | - 'CHK_in' => true, |
|
| 1287 | - ), |
|
| 1288 | - ), 'DTT_ID', true); |
|
| 1289 | - // checkins have already reached their max number of uses |
|
| 1290 | - // so registrant can NOT checkin |
|
| 1291 | - if ($count_unique_dtt_checkins >= $max_uses) { |
|
| 1292 | - EE_Error::add_error( |
|
| 1293 | - esc_html__( |
|
| 1294 | - 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
| 1295 | - 'event_espresso' |
|
| 1296 | - ), |
|
| 1297 | - __FILE__, |
|
| 1298 | - __FUNCTION__, |
|
| 1299 | - __LINE__ |
|
| 1300 | - ); |
|
| 1301 | - return false; |
|
| 1302 | - } |
|
| 1303 | - return true; |
|
| 1304 | - } |
|
| 1305 | - |
|
| 1306 | - |
|
| 1307 | - /** |
|
| 1308 | - * toggle Check-in status for this registration |
|
| 1309 | - * Check-ins are toggled in the following order: |
|
| 1310 | - * never checked in -> checked in |
|
| 1311 | - * checked in -> checked out |
|
| 1312 | - * checked out -> checked in |
|
| 1313 | - * |
|
| 1314 | - * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
| 1315 | - * If not included or null, then it is assumed latest datetime is being toggled. |
|
| 1316 | - * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
| 1317 | - * can be checked in or not. Otherwise this forces change in checkin status. |
|
| 1318 | - * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
| 1319 | - * @throws EE_Error |
|
| 1320 | - */ |
|
| 1321 | - public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
| 1322 | - { |
|
| 1323 | - if (empty($DTT_ID)) { |
|
| 1324 | - $datetime = $this->get_latest_related_datetime(); |
|
| 1325 | - $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
| 1326 | - // verify the registration can checkin for the given DTT_ID |
|
| 1327 | - } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1328 | - EE_Error::add_error( |
|
| 1329 | - sprintf( |
|
| 1330 | - esc_html__( |
|
| 1331 | - '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', |
|
| 1332 | - 'event_espresso' |
|
| 1333 | - ), |
|
| 1334 | - $this->ID(), |
|
| 1335 | - $DTT_ID |
|
| 1336 | - ), |
|
| 1337 | - __FILE__, |
|
| 1338 | - __FUNCTION__, |
|
| 1339 | - __LINE__ |
|
| 1340 | - ); |
|
| 1341 | - return false; |
|
| 1342 | - } |
|
| 1343 | - $status_paths = array( |
|
| 1344 | - EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
| 1345 | - EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
| 1346 | - EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
| 1347 | - ); |
|
| 1348 | - //start by getting the current status so we know what status we'll be changing to. |
|
| 1349 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
| 1350 | - $status_to = $status_paths[$cur_status]; |
|
| 1351 | - // database only records true for checked IN or false for checked OUT |
|
| 1352 | - // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
| 1353 | - $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
| 1354 | - // add relation - note Check-ins are always creating new rows |
|
| 1355 | - // because we are keeping track of Check-ins over time. |
|
| 1356 | - // Eventually we'll probably want to show a list table |
|
| 1357 | - // for the individual Check-ins so that they can be managed. |
|
| 1358 | - $checkin = EE_Checkin::new_instance(array( |
|
| 1359 | - 'REG_ID' => $this->ID(), |
|
| 1360 | - 'DTT_ID' => $DTT_ID, |
|
| 1361 | - 'CHK_in' => $new_status, |
|
| 1362 | - )); |
|
| 1363 | - // if the record could not be saved then return false |
|
| 1364 | - if ($checkin->save() === 0) { |
|
| 1365 | - if (WP_DEBUG) { |
|
| 1366 | - global $wpdb; |
|
| 1367 | - $error = sprintf( |
|
| 1368 | - esc_html__( |
|
| 1369 | - 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
| 1370 | - 'event_espresso' |
|
| 1371 | - ), |
|
| 1372 | - '<br />', |
|
| 1373 | - $wpdb->last_error |
|
| 1374 | - ); |
|
| 1375 | - } else { |
|
| 1376 | - $error = esc_html__( |
|
| 1377 | - 'Registration check in update failed because of an unknown database error', |
|
| 1378 | - 'event_espresso' |
|
| 1379 | - ); |
|
| 1380 | - } |
|
| 1381 | - EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
| 1382 | - return false; |
|
| 1383 | - } |
|
| 1384 | - return $status_to; |
|
| 1385 | - } |
|
| 1386 | - |
|
| 1387 | - |
|
| 1388 | - /** |
|
| 1389 | - * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
| 1390 | - * "Latest" is defined by the `DTT_EVT_start` column. |
|
| 1391 | - * |
|
| 1392 | - * @return EE_Datetime|null |
|
| 1393 | - * @throws \EE_Error |
|
| 1394 | - */ |
|
| 1395 | - public function get_latest_related_datetime() |
|
| 1396 | - { |
|
| 1397 | - return EEM_Datetime::instance()->get_one( |
|
| 1398 | - array( |
|
| 1399 | - array( |
|
| 1400 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1401 | - ), |
|
| 1402 | - 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
| 1403 | - ) |
|
| 1404 | - ); |
|
| 1405 | - } |
|
| 1406 | - |
|
| 1407 | - |
|
| 1408 | - /** |
|
| 1409 | - * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
| 1410 | - * "Earliest" is defined by the `DTT_EVT_start` column. |
|
| 1411 | - * |
|
| 1412 | - * @throws \EE_Error |
|
| 1413 | - */ |
|
| 1414 | - public function get_earliest_related_datetime() |
|
| 1415 | - { |
|
| 1416 | - return EEM_Datetime::instance()->get_one( |
|
| 1417 | - array( |
|
| 1418 | - array( |
|
| 1419 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1420 | - ), |
|
| 1421 | - 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
| 1422 | - ) |
|
| 1423 | - ); |
|
| 1424 | - } |
|
| 1425 | - |
|
| 1426 | - |
|
| 1427 | - /** |
|
| 1428 | - * This method simply returns the check-in status for this registration and the given datetime. |
|
| 1429 | - * If neither the datetime nor the checkin values are provided as arguments, |
|
| 1430 | - * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
| 1431 | - * |
|
| 1432 | - * @param int $DTT_ID The ID of the datetime we're checking against |
|
| 1433 | - * (if empty we'll get the primary datetime for |
|
| 1434 | - * this registration (via event) and use it's ID); |
|
| 1435 | - * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
| 1436 | - * @return int Integer representing Check-in status. |
|
| 1437 | - * @throws \EE_Error |
|
| 1438 | - */ |
|
| 1439 | - public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
| 1440 | - { |
|
| 1441 | - $checkin_query_params = array( |
|
| 1442 | - 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
| 1443 | - ); |
|
| 1444 | - |
|
| 1445 | - if ($DTT_ID > 0) { |
|
| 1446 | - $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
| 1447 | - } |
|
| 1448 | - |
|
| 1449 | - //get checkin object (if exists) |
|
| 1450 | - $checkin = $checkin instanceof EE_Checkin |
|
| 1451 | - ? $checkin |
|
| 1452 | - : $this->get_first_related('Checkin', $checkin_query_params); |
|
| 1453 | - if ($checkin instanceof EE_Checkin) { |
|
| 1454 | - if ($checkin->get('CHK_in')) { |
|
| 1455 | - return EE_Checkin::status_checked_in; //checked in |
|
| 1456 | - } |
|
| 1457 | - return EE_Checkin::status_checked_out; //had checked in but is now checked out. |
|
| 1458 | - } |
|
| 1459 | - return EE_Checkin::status_checked_never; //never been checked in |
|
| 1460 | - } |
|
| 1461 | - |
|
| 1462 | - |
|
| 1463 | - /** |
|
| 1464 | - * This method returns a localized message for the toggled Check-in message. |
|
| 1465 | - * |
|
| 1466 | - * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
| 1467 | - * then it is assumed Check-in for primary datetime was toggled. |
|
| 1468 | - * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
| 1469 | - * message can be customized with the attendee name. |
|
| 1470 | - * @return string internationalized message |
|
| 1471 | - * @throws EE_Error |
|
| 1472 | - */ |
|
| 1473 | - public function get_checkin_msg($DTT_ID, $error = false) |
|
| 1474 | - { |
|
| 1475 | - //let's get the attendee first so we can include the name of the attendee |
|
| 1476 | - $attendee = $this->get_first_related('Attendee'); |
|
| 1477 | - if ($attendee instanceof EE_Attendee) { |
|
| 1478 | - if ($error) { |
|
| 1479 | - return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
| 1480 | - } |
|
| 1481 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
| 1482 | - //what is the status message going to be? |
|
| 1483 | - switch ($cur_status) { |
|
| 1484 | - case EE_Checkin::status_checked_never: |
|
| 1485 | - return sprintf(__("%s has been removed from Check-in records", "event_espresso"), |
|
| 1486 | - $attendee->full_name()); |
|
| 1487 | - break; |
|
| 1488 | - case EE_Checkin::status_checked_in: |
|
| 1489 | - return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
| 1490 | - break; |
|
| 1491 | - case EE_Checkin::status_checked_out: |
|
| 1492 | - return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
| 1493 | - break; |
|
| 1494 | - } |
|
| 1495 | - } |
|
| 1496 | - return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
| 1497 | - } |
|
| 1498 | - |
|
| 1499 | - |
|
| 1500 | - /** |
|
| 1501 | - * Returns the related EE_Transaction to this registration |
|
| 1502 | - * |
|
| 1503 | - * @return EE_Transaction |
|
| 1504 | - * @throws EE_Error |
|
| 1505 | - * @throws EntityNotFoundException |
|
| 1506 | - */ |
|
| 1507 | - public function transaction() |
|
| 1508 | - { |
|
| 1509 | - $transaction = $this->get_first_related('Transaction'); |
|
| 1510 | - if (! $transaction instanceof \EE_Transaction) { |
|
| 1511 | - throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
| 1512 | - } |
|
| 1513 | - return $transaction; |
|
| 1514 | - } |
|
| 1515 | - |
|
| 1516 | - |
|
| 1517 | - /** |
|
| 1518 | - * get Registration Code |
|
| 1519 | - */ |
|
| 1520 | - public function reg_code() |
|
| 1521 | - { |
|
| 1522 | - return $this->get('REG_code'); |
|
| 1523 | - } |
|
| 1524 | - |
|
| 1525 | - |
|
| 1526 | - /** |
|
| 1527 | - * get Transaction ID |
|
| 1528 | - */ |
|
| 1529 | - public function transaction_ID() |
|
| 1530 | - { |
|
| 1531 | - return $this->get('TXN_ID'); |
|
| 1532 | - } |
|
| 1533 | - |
|
| 1534 | - |
|
| 1535 | - /** |
|
| 1536 | - * @return int |
|
| 1537 | - * @throws EE_Error |
|
| 1538 | - */ |
|
| 1539 | - public function ticket_ID() |
|
| 1540 | - { |
|
| 1541 | - return $this->get('TKT_ID'); |
|
| 1542 | - } |
|
| 1543 | - |
|
| 1544 | - |
|
| 1545 | - /** |
|
| 1546 | - * Set Registration Code |
|
| 1547 | - * |
|
| 1548 | - * @access public |
|
| 1549 | - * @param string $REG_code Registration Code |
|
| 1550 | - * @param boolean $use_default |
|
| 1551 | - * @throws EE_Error |
|
| 1552 | - */ |
|
| 1553 | - public function set_reg_code($REG_code, $use_default = false) |
|
| 1554 | - { |
|
| 1555 | - if (empty($REG_code)) { |
|
| 1556 | - EE_Error::add_error( |
|
| 1557 | - esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
| 1558 | - __FILE__, |
|
| 1559 | - __FUNCTION__, |
|
| 1560 | - __LINE__ |
|
| 1561 | - ); |
|
| 1562 | - return; |
|
| 1563 | - } |
|
| 1564 | - if (! $this->reg_code()) { |
|
| 1565 | - parent::set('REG_code', $REG_code, $use_default); |
|
| 1566 | - } else { |
|
| 1567 | - EE_Error::doing_it_wrong( |
|
| 1568 | - __CLASS__ . '::' . __FUNCTION__, |
|
| 1569 | - esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
| 1570 | - '4.6.0' |
|
| 1571 | - ); |
|
| 1572 | - } |
|
| 1573 | - } |
|
| 1574 | - |
|
| 1575 | - |
|
| 1576 | - /** |
|
| 1577 | - * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
| 1578 | - * Note, if you want to just get all registrations in the same transaction (group), use: |
|
| 1579 | - * $registration->transaction()->registrations(); |
|
| 1580 | - * |
|
| 1581 | - * @since 4.5.0 |
|
| 1582 | - * @return EE_Registration[] or empty array if this isn't a group registration. |
|
| 1583 | - * @throws EE_Error |
|
| 1584 | - */ |
|
| 1585 | - public function get_all_other_registrations_in_group() |
|
| 1586 | - { |
|
| 1587 | - if ($this->group_size() < 2) { |
|
| 1588 | - return array(); |
|
| 1589 | - } |
|
| 1590 | - |
|
| 1591 | - $query[0] = array( |
|
| 1592 | - 'TXN_ID' => $this->transaction_ID(), |
|
| 1593 | - 'REG_ID' => array('!=', $this->ID()), |
|
| 1594 | - 'TKT_ID' => $this->ticket_ID(), |
|
| 1595 | - ); |
|
| 1596 | - /** @var EE_Registration[] $registrations */ |
|
| 1597 | - $registrations = $this->get_model()->get_all($query); |
|
| 1598 | - return $registrations; |
|
| 1599 | - } |
|
| 1600 | - |
|
| 1601 | - /** |
|
| 1602 | - * Return the link to the admin details for the object. |
|
| 1603 | - * |
|
| 1604 | - * @return string |
|
| 1605 | - * @throws EE_Error |
|
| 1606 | - */ |
|
| 1607 | - public function get_admin_details_link() |
|
| 1608 | - { |
|
| 1609 | - EE_Registry::instance()->load_helper('URL'); |
|
| 1610 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1611 | - array( |
|
| 1612 | - 'page' => 'espresso_registrations', |
|
| 1613 | - 'action' => 'view_registration', |
|
| 1614 | - '_REG_ID' => $this->ID(), |
|
| 1615 | - ), |
|
| 1616 | - admin_url('admin.php') |
|
| 1617 | - ); |
|
| 1618 | - } |
|
| 1619 | - |
|
| 1620 | - /** |
|
| 1621 | - * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
| 1622 | - * |
|
| 1623 | - * @return string |
|
| 1624 | - * @throws EE_Error |
|
| 1625 | - */ |
|
| 1626 | - public function get_admin_edit_link() |
|
| 1627 | - { |
|
| 1628 | - return $this->get_admin_details_link(); |
|
| 1629 | - } |
|
| 1630 | - |
|
| 1631 | - /** |
|
| 1632 | - * Returns the link to a settings page for the object. |
|
| 1633 | - * |
|
| 1634 | - * @return string |
|
| 1635 | - * @throws EE_Error |
|
| 1636 | - */ |
|
| 1637 | - public function get_admin_settings_link() |
|
| 1638 | - { |
|
| 1639 | - return $this->get_admin_details_link(); |
|
| 1640 | - } |
|
| 1641 | - |
|
| 1642 | - /** |
|
| 1643 | - * Returns the link to the "overview" for the object (typically the "list table" view). |
|
| 1644 | - * |
|
| 1645 | - * @return string |
|
| 1646 | - */ |
|
| 1647 | - public function get_admin_overview_link() |
|
| 1648 | - { |
|
| 1649 | - EE_Registry::instance()->load_helper('URL'); |
|
| 1650 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1651 | - array( |
|
| 1652 | - 'page' => 'espresso_registrations', |
|
| 1653 | - ), |
|
| 1654 | - admin_url('admin.php') |
|
| 1655 | - ); |
|
| 1656 | - } |
|
| 1657 | - |
|
| 1658 | - |
|
| 1659 | - /** |
|
| 1660 | - * @param array $query_params |
|
| 1661 | - * @return \EE_Registration[] |
|
| 1662 | - * @throws \EE_Error |
|
| 1663 | - */ |
|
| 1664 | - public function payments($query_params = array()) |
|
| 1665 | - { |
|
| 1666 | - return $this->get_many_related('Payment', $query_params); |
|
| 1667 | - } |
|
| 1668 | - |
|
| 1669 | - |
|
| 1670 | - /** |
|
| 1671 | - * @param array $query_params |
|
| 1672 | - * @return \EE_Registration_Payment[] |
|
| 1673 | - * @throws \EE_Error |
|
| 1674 | - */ |
|
| 1675 | - public function registration_payments($query_params = array()) |
|
| 1676 | - { |
|
| 1677 | - return $this->get_many_related('Registration_Payment', $query_params); |
|
| 1678 | - } |
|
| 1679 | - |
|
| 1680 | - |
|
| 1681 | - /** |
|
| 1682 | - * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
| 1683 | - * Note: if there are no payments on the registration there will be no payment method returned. |
|
| 1684 | - * |
|
| 1685 | - * @return EE_Payment_Method|null |
|
| 1686 | - */ |
|
| 1687 | - public function payment_method() |
|
| 1688 | - { |
|
| 1689 | - return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
| 1690 | - } |
|
| 1691 | - |
|
| 1692 | - |
|
| 1693 | - /** |
|
| 1694 | - * @return \EE_Line_Item |
|
| 1695 | - * @throws EntityNotFoundException |
|
| 1696 | - * @throws \EE_Error |
|
| 1697 | - */ |
|
| 1698 | - public function ticket_line_item() |
|
| 1699 | - { |
|
| 1700 | - $ticket = $this->ticket(); |
|
| 1701 | - $transaction = $this->transaction(); |
|
| 1702 | - $line_item = null; |
|
| 1703 | - $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 1704 | - $transaction->total_line_item(), |
|
| 1705 | - 'Ticket', |
|
| 1706 | - array($ticket->ID()) |
|
| 1707 | - ); |
|
| 1708 | - foreach ($ticket_line_items as $ticket_line_item) { |
|
| 1709 | - if ( |
|
| 1710 | - $ticket_line_item instanceof \EE_Line_Item |
|
| 1711 | - && $ticket_line_item->OBJ_type() === 'Ticket' |
|
| 1712 | - && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
| 1713 | - ) { |
|
| 1714 | - $line_item = $ticket_line_item; |
|
| 1715 | - break; |
|
| 1716 | - } |
|
| 1717 | - } |
|
| 1718 | - if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1719 | - throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
| 1720 | - } |
|
| 1721 | - return $line_item; |
|
| 1722 | - } |
|
| 1723 | - |
|
| 1724 | - |
|
| 1725 | - /** |
|
| 1726 | - * Soft Deletes this model object. |
|
| 1727 | - * |
|
| 1728 | - * @return boolean | int |
|
| 1729 | - * @throws \RuntimeException |
|
| 1730 | - * @throws \EE_Error |
|
| 1731 | - */ |
|
| 1732 | - public function delete() |
|
| 1733 | - { |
|
| 1734 | - if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
| 1735 | - $this->set_status(EEM_Registration::status_id_cancelled); |
|
| 1736 | - } |
|
| 1737 | - return parent::delete(); |
|
| 1738 | - } |
|
| 1739 | - |
|
| 1740 | - |
|
| 1741 | - /** |
|
| 1742 | - * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
| 1743 | - * |
|
| 1744 | - * @throws \EE_Error |
|
| 1745 | - * @throws \RuntimeException |
|
| 1746 | - */ |
|
| 1747 | - public function restore() |
|
| 1748 | - { |
|
| 1749 | - $previous_status = $this->get_extra_meta( |
|
| 1750 | - EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
| 1751 | - true, |
|
| 1752 | - EEM_Registration::status_id_cancelled |
|
| 1753 | - ); |
|
| 1754 | - if ($previous_status) { |
|
| 1755 | - $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
| 1756 | - $this->set_status($previous_status); |
|
| 1757 | - } |
|
| 1758 | - return parent::restore(); |
|
| 1759 | - } |
|
| 1760 | - |
|
| 1761 | - |
|
| 1762 | - |
|
| 1763 | - /*************************** DEPRECATED ***************************/ |
|
| 1764 | - |
|
| 1765 | - |
|
| 1766 | - /** |
|
| 1767 | - * @deprecated |
|
| 1768 | - * @since 4.7.0 |
|
| 1769 | - * @access public |
|
| 1770 | - */ |
|
| 1771 | - public function price_paid() |
|
| 1772 | - { |
|
| 1773 | - EE_Error::doing_it_wrong('EE_Registration::price_paid()', |
|
| 1774 | - esc_html__('This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso'), |
|
| 1775 | - '4.7.0'); |
|
| 1776 | - return $this->final_price(); |
|
| 1777 | - } |
|
| 1778 | - |
|
| 1779 | - |
|
| 1780 | - /** |
|
| 1781 | - * @deprecated |
|
| 1782 | - * @since 4.7.0 |
|
| 1783 | - * @access public |
|
| 1784 | - * @param float $REG_final_price |
|
| 1785 | - * @throws EE_Error |
|
| 1786 | - * @throws RuntimeException |
|
| 1787 | - */ |
|
| 1788 | - public function set_price_paid($REG_final_price = 0.00) |
|
| 1789 | - { |
|
| 1790 | - EE_Error::doing_it_wrong('EE_Registration::set_price_paid()', |
|
| 1791 | - esc_html__('This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso'), |
|
| 1792 | - '4.7.0'); |
|
| 1793 | - $this->set_final_price($REG_final_price); |
|
| 1794 | - } |
|
| 1795 | - |
|
| 1796 | - |
|
| 1797 | - /** |
|
| 1798 | - * @deprecated |
|
| 1799 | - * @since 4.7.0 |
|
| 1800 | - * @return string |
|
| 1801 | - * @throws EE_Error |
|
| 1802 | - */ |
|
| 1803 | - public function pretty_price_paid() |
|
| 1804 | - { |
|
| 1805 | - EE_Error::doing_it_wrong('EE_Registration::pretty_price_paid()', |
|
| 1806 | - esc_html__('This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
| 1807 | - 'event_espresso'), '4.7.0'); |
|
| 1808 | - return $this->pretty_final_price(); |
|
| 1809 | - } |
|
| 1810 | - |
|
| 1811 | - |
|
| 1812 | - /** |
|
| 1813 | - * Gets the primary datetime related to this registration via the related Event to this registration |
|
| 1814 | - * |
|
| 1815 | - * @deprecated 4.9.17 |
|
| 1816 | - * @return EE_Datetime |
|
| 1817 | - * @throws EE_Error |
|
| 1818 | - * @throws EntityNotFoundException |
|
| 1819 | - */ |
|
| 1820 | - public function get_related_primary_datetime() |
|
| 1821 | - { |
|
| 1822 | - EE_Error::doing_it_wrong( |
|
| 1823 | - __METHOD__, |
|
| 1824 | - esc_html__( |
|
| 1825 | - 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
| 1826 | - 'event_espresso' |
|
| 1827 | - ), |
|
| 1828 | - '4.9.17', |
|
| 1829 | - '5.0.0' |
|
| 1830 | - ); |
|
| 1831 | - return $this->event()->primary_datetime(); |
|
| 1832 | - } |
|
| 18 | + /** |
|
| 19 | + * Used to reference when a registration has never been checked in. |
|
| 20 | + * |
|
| 21 | + * @deprecated use \EE_Checkin::status_checked_never instead |
|
| 22 | + * @type int |
|
| 23 | + */ |
|
| 24 | + const checkin_status_never = 2; |
|
| 25 | + |
|
| 26 | + /** |
|
| 27 | + * Used to reference when a registration has been checked in. |
|
| 28 | + * |
|
| 29 | + * @deprecated use \EE_Checkin::status_checked_in instead |
|
| 30 | + * @type int |
|
| 31 | + */ |
|
| 32 | + const checkin_status_in = 1; |
|
| 33 | + |
|
| 34 | + |
|
| 35 | + /** |
|
| 36 | + * Used to reference when a registration has been checked out. |
|
| 37 | + * |
|
| 38 | + * @deprecated use \EE_Checkin::status_checked_out instead |
|
| 39 | + * @type int |
|
| 40 | + */ |
|
| 41 | + const checkin_status_out = 0; |
|
| 42 | + |
|
| 43 | + |
|
| 44 | + /** |
|
| 45 | + * extra meta key for tracking reg status os trashed registrations |
|
| 46 | + * |
|
| 47 | + * @type string |
|
| 48 | + */ |
|
| 49 | + const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
| 50 | + |
|
| 51 | + |
|
| 52 | + /** |
|
| 53 | + * extra meta key for tracking if registration has reserved ticket |
|
| 54 | + * |
|
| 55 | + * @type string |
|
| 56 | + */ |
|
| 57 | + const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
| 58 | + |
|
| 59 | + |
|
| 60 | + /** |
|
| 61 | + * @param array $props_n_values incoming values |
|
| 62 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 63 | + * used.) |
|
| 64 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 65 | + * date_format and the second value is the time format |
|
| 66 | + * @return EE_Registration |
|
| 67 | + * @throws EE_Error |
|
| 68 | + */ |
|
| 69 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 70 | + { |
|
| 71 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 72 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + |
|
| 76 | + /** |
|
| 77 | + * @param array $props_n_values incoming values from the database |
|
| 78 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 79 | + * the website will be used. |
|
| 80 | + * @return EE_Registration |
|
| 81 | + */ |
|
| 82 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 83 | + { |
|
| 84 | + return new self($props_n_values, true, $timezone); |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + |
|
| 88 | + /** |
|
| 89 | + * Set Event ID |
|
| 90 | + * |
|
| 91 | + * @param int $EVT_ID Event ID |
|
| 92 | + * @throws EE_Error |
|
| 93 | + * @throws RuntimeException |
|
| 94 | + */ |
|
| 95 | + public function set_event($EVT_ID = 0) |
|
| 96 | + { |
|
| 97 | + $this->set('EVT_ID', $EVT_ID); |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + |
|
| 101 | + /** |
|
| 102 | + * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
| 103 | + * be routed to internal methods |
|
| 104 | + * |
|
| 105 | + * @param string $field_name |
|
| 106 | + * @param mixed $field_value |
|
| 107 | + * @param bool $use_default |
|
| 108 | + * @throws \EE_Error |
|
| 109 | + * @throws \RuntimeException |
|
| 110 | + */ |
|
| 111 | + public function set($field_name, $field_value, $use_default = false) |
|
| 112 | + { |
|
| 113 | + switch ($field_name) { |
|
| 114 | + case 'REG_code': |
|
| 115 | + if (! empty($field_value) && $this->reg_code() === null) { |
|
| 116 | + $this->set_reg_code($field_value, $use_default); |
|
| 117 | + } |
|
| 118 | + break; |
|
| 119 | + case 'STS_ID': |
|
| 120 | + $this->set_status($field_value, $use_default); |
|
| 121 | + break; |
|
| 122 | + default: |
|
| 123 | + parent::set($field_name, $field_value, $use_default); |
|
| 124 | + } |
|
| 125 | + } |
|
| 126 | + |
|
| 127 | + |
|
| 128 | + /** |
|
| 129 | + * Set Status ID |
|
| 130 | + * updates the registration status and ALSO... |
|
| 131 | + * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
| 132 | + * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
| 133 | + * |
|
| 134 | + * @param string $new_STS_ID |
|
| 135 | + * @param boolean $use_default |
|
| 136 | + * @return bool |
|
| 137 | + * @throws \RuntimeException |
|
| 138 | + * @throws \EE_Error |
|
| 139 | + */ |
|
| 140 | + public function set_status($new_STS_ID = null, $use_default = false) |
|
| 141 | + { |
|
| 142 | + // get current REG_Status |
|
| 143 | + $old_STS_ID = $this->status_ID(); |
|
| 144 | + // if status has changed |
|
| 145 | + if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
| 146 | + && ! empty($old_STS_ID) // and that old status is actually set |
|
| 147 | + && ! empty($new_STS_ID) // as well as the new status |
|
| 148 | + && $this->ID() // ensure registration is in the db |
|
| 149 | + ) { |
|
| 150 | + // TO approved |
|
| 151 | + if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
| 152 | + // reserve a space by incrementing ticket and datetime sold values |
|
| 153 | + $this->_reserve_registration_space(); |
|
| 154 | + do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID); |
|
| 155 | + // OR FROM approved |
|
| 156 | + } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
| 157 | + // release a space by decrementing ticket and datetime sold values |
|
| 158 | + $this->_release_registration_space(); |
|
| 159 | + do_action('AHEE__EE_Registration__set_status__from_approved', $this, $old_STS_ID, $new_STS_ID); |
|
| 160 | + } |
|
| 161 | + // update status |
|
| 162 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 163 | + $this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID); |
|
| 164 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
| 165 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
| 166 | + $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
| 167 | + $this->transaction()->update_status_based_on_total_paid(true); |
|
| 168 | + do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID); |
|
| 169 | + return true; |
|
| 170 | + } |
|
| 171 | + //even though the old value matches the new value, it's still good to |
|
| 172 | + //allow the parent set method to have a say |
|
| 173 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 174 | + return true; |
|
| 175 | + } |
|
| 176 | + |
|
| 177 | + |
|
| 178 | + /** |
|
| 179 | + * update REGs and TXN when cancelled or declined registrations involved |
|
| 180 | + * |
|
| 181 | + * @param string $new_STS_ID |
|
| 182 | + * @param string $old_STS_ID |
|
| 183 | + * @throws \EE_Error |
|
| 184 | + */ |
|
| 185 | + private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID) |
|
| 186 | + { |
|
| 187 | + // these reg statuses should not be considered in any calculations involving monies owing |
|
| 188 | + $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
| 189 | + // true if registration has been cancelled or declined |
|
| 190 | + if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 191 | + && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 192 | + ) { |
|
| 193 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 194 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 195 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 196 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 197 | + // cancelled or declined registration |
|
| 198 | + $registration_processor->update_registration_after_being_canceled_or_declined( |
|
| 199 | + $this, |
|
| 200 | + $closed_reg_statuses |
|
| 201 | + ); |
|
| 202 | + $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
| 203 | + $this, |
|
| 204 | + $closed_reg_statuses, |
|
| 205 | + false |
|
| 206 | + ); |
|
| 207 | + do_action('AHEE__EE_Registration__set_status__canceled_or_declined', $this, $old_STS_ID, $new_STS_ID); |
|
| 208 | + return; |
|
| 209 | + } |
|
| 210 | + // true if reinstating cancelled or declined registration |
|
| 211 | + if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 212 | + && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 213 | + ) { |
|
| 214 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 215 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 216 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 217 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 218 | + // reinstating cancelled or declined registration |
|
| 219 | + $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
| 220 | + $this, |
|
| 221 | + $closed_reg_statuses |
|
| 222 | + ); |
|
| 223 | + $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
| 224 | + $this, |
|
| 225 | + $closed_reg_statuses, |
|
| 226 | + false |
|
| 227 | + ); |
|
| 228 | + do_action('AHEE__EE_Registration__set_status__after_reinstated', $this, $old_STS_ID, $new_STS_ID); |
|
| 229 | + } |
|
| 230 | + } |
|
| 231 | + |
|
| 232 | + |
|
| 233 | + /** |
|
| 234 | + * get Status ID |
|
| 235 | + */ |
|
| 236 | + public function status_ID() |
|
| 237 | + { |
|
| 238 | + return $this->get('STS_ID'); |
|
| 239 | + } |
|
| 240 | + |
|
| 241 | + |
|
| 242 | + /** |
|
| 243 | + * increments this registration's related ticket sold and corresponding datetime sold values |
|
| 244 | + * |
|
| 245 | + * @return void |
|
| 246 | + * @throws EE_Error |
|
| 247 | + * @throws EntityNotFoundException |
|
| 248 | + */ |
|
| 249 | + private function _reserve_registration_space() |
|
| 250 | + { |
|
| 251 | + // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
| 252 | + // so stop tracking that this reg has a ticket reserved |
|
| 253 | + $this->release_reserved_ticket(); |
|
| 254 | + $ticket = $this->ticket(); |
|
| 255 | + $ticket->increase_sold(); |
|
| 256 | + $ticket->save(); |
|
| 257 | + // possibly set event status to sold out |
|
| 258 | + $this->event()->perform_sold_out_status_check(); |
|
| 259 | + } |
|
| 260 | + |
|
| 261 | + |
|
| 262 | + /** |
|
| 263 | + * Gets the ticket this registration is for |
|
| 264 | + * |
|
| 265 | + * @param boolean $include_archived whether to include archived tickets or not. |
|
| 266 | + * @return EE_Ticket|EE_Base_Class |
|
| 267 | + * @throws \EE_Error |
|
| 268 | + */ |
|
| 269 | + public function ticket($include_archived = true) |
|
| 270 | + { |
|
| 271 | + $query_params = array(); |
|
| 272 | + if ($include_archived) { |
|
| 273 | + $query_params['default_where_conditions'] = 'none'; |
|
| 274 | + } |
|
| 275 | + return $this->get_first_related('Ticket', $query_params); |
|
| 276 | + } |
|
| 277 | + |
|
| 278 | + |
|
| 279 | + /** |
|
| 280 | + * Gets the event this registration is for |
|
| 281 | + * |
|
| 282 | + * @return EE_Event |
|
| 283 | + * @throws EE_Error |
|
| 284 | + * @throws EntityNotFoundException |
|
| 285 | + */ |
|
| 286 | + public function event() |
|
| 287 | + { |
|
| 288 | + $event = $this->get_first_related('Event'); |
|
| 289 | + if (! $event instanceof \EE_Event) { |
|
| 290 | + throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
| 291 | + } |
|
| 292 | + return $event; |
|
| 293 | + } |
|
| 294 | + |
|
| 295 | + |
|
| 296 | + /** |
|
| 297 | + * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
| 298 | + * with the author of the event this registration is for. |
|
| 299 | + * |
|
| 300 | + * @since 4.5.0 |
|
| 301 | + * @return int |
|
| 302 | + * @throws EE_Error |
|
| 303 | + * @throws EntityNotFoundException |
|
| 304 | + */ |
|
| 305 | + public function wp_user() |
|
| 306 | + { |
|
| 307 | + $event = $this->event(); |
|
| 308 | + if ($event instanceof EE_Event) { |
|
| 309 | + return $event->wp_user(); |
|
| 310 | + } |
|
| 311 | + return 0; |
|
| 312 | + } |
|
| 313 | + |
|
| 314 | + |
|
| 315 | + /** |
|
| 316 | + * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
| 317 | + * |
|
| 318 | + * @return void |
|
| 319 | + * @throws \EE_Error |
|
| 320 | + */ |
|
| 321 | + private function _release_registration_space() |
|
| 322 | + { |
|
| 323 | + $ticket = $this->ticket(); |
|
| 324 | + $ticket->decrease_sold(); |
|
| 325 | + $ticket->save(); |
|
| 326 | + } |
|
| 327 | + |
|
| 328 | + |
|
| 329 | + /** |
|
| 330 | + * tracks this registration's ticket reservation in extra meta |
|
| 331 | + * and can increment related ticket reserved and corresponding datetime reserved values |
|
| 332 | + * |
|
| 333 | + * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
| 334 | + * @return void |
|
| 335 | + * @throws \EE_Error |
|
| 336 | + */ |
|
| 337 | + public function reserve_ticket($update_ticket = false) |
|
| 338 | + { |
|
| 339 | + if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) === false) { |
|
| 340 | + // PLZ NOTE: although checking $update_ticket first would be more efficient, |
|
| 341 | + // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 342 | + if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) && $update_ticket) { |
|
| 343 | + $ticket = $this->ticket(); |
|
| 344 | + $ticket->increase_reserved(); |
|
| 345 | + $ticket->save(); |
|
| 346 | + } |
|
| 347 | + } |
|
| 348 | + } |
|
| 349 | + |
|
| 350 | + |
|
| 351 | + /** |
|
| 352 | + * stops tracking this registration's ticket reservation in extra meta |
|
| 353 | + * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
| 354 | + * |
|
| 355 | + * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
| 356 | + * @return void |
|
| 357 | + * @throws \EE_Error |
|
| 358 | + */ |
|
| 359 | + public function release_reserved_ticket($update_ticket = false) |
|
| 360 | + { |
|
| 361 | + if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) !== false) { |
|
| 362 | + // PLZ NOTE: although checking $update_ticket first would be more efficient, |
|
| 363 | + // we NEED to ALWAYS call delete_extra_meta(), which is why that is done first |
|
| 364 | + if ($this->delete_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY) && $update_ticket) { |
|
| 365 | + $ticket = $this->ticket(); |
|
| 366 | + $ticket->decrease_reserved(); |
|
| 367 | + $ticket->save(); |
|
| 368 | + } |
|
| 369 | + } |
|
| 370 | + } |
|
| 371 | + |
|
| 372 | + |
|
| 373 | + /** |
|
| 374 | + * Set Attendee ID |
|
| 375 | + * |
|
| 376 | + * @param int $ATT_ID Attendee ID |
|
| 377 | + * @throws EE_Error |
|
| 378 | + * @throws RuntimeException |
|
| 379 | + */ |
|
| 380 | + public function set_attendee_id($ATT_ID = 0) |
|
| 381 | + { |
|
| 382 | + $this->set('ATT_ID', $ATT_ID); |
|
| 383 | + } |
|
| 384 | + |
|
| 385 | + |
|
| 386 | + /** |
|
| 387 | + * Set Transaction ID |
|
| 388 | + * |
|
| 389 | + * @param int $TXN_ID Transaction ID |
|
| 390 | + * @throws EE_Error |
|
| 391 | + * @throws RuntimeException |
|
| 392 | + */ |
|
| 393 | + public function set_transaction_id($TXN_ID = 0) |
|
| 394 | + { |
|
| 395 | + $this->set('TXN_ID', $TXN_ID); |
|
| 396 | + } |
|
| 397 | + |
|
| 398 | + |
|
| 399 | + /** |
|
| 400 | + * Set Session |
|
| 401 | + * |
|
| 402 | + * @param string $REG_session PHP Session ID |
|
| 403 | + * @throws EE_Error |
|
| 404 | + * @throws RuntimeException |
|
| 405 | + */ |
|
| 406 | + public function set_session($REG_session = '') |
|
| 407 | + { |
|
| 408 | + $this->set('REG_session', $REG_session); |
|
| 409 | + } |
|
| 410 | + |
|
| 411 | + |
|
| 412 | + /** |
|
| 413 | + * Set Registration URL Link |
|
| 414 | + * |
|
| 415 | + * @param string $REG_url_link Registration URL Link |
|
| 416 | + * @throws EE_Error |
|
| 417 | + * @throws RuntimeException |
|
| 418 | + */ |
|
| 419 | + public function set_reg_url_link($REG_url_link = '') |
|
| 420 | + { |
|
| 421 | + $this->set('REG_url_link', $REG_url_link); |
|
| 422 | + } |
|
| 423 | + |
|
| 424 | + |
|
| 425 | + /** |
|
| 426 | + * Set Attendee Counter |
|
| 427 | + * |
|
| 428 | + * @param int $REG_count Primary Attendee |
|
| 429 | + * @throws EE_Error |
|
| 430 | + * @throws RuntimeException |
|
| 431 | + */ |
|
| 432 | + public function set_count($REG_count = 1) |
|
| 433 | + { |
|
| 434 | + $this->set('REG_count', $REG_count); |
|
| 435 | + } |
|
| 436 | + |
|
| 437 | + |
|
| 438 | + /** |
|
| 439 | + * Set Group Size |
|
| 440 | + * |
|
| 441 | + * @param boolean $REG_group_size Group Registration |
|
| 442 | + * @throws EE_Error |
|
| 443 | + * @throws RuntimeException |
|
| 444 | + */ |
|
| 445 | + public function set_group_size($REG_group_size = false) |
|
| 446 | + { |
|
| 447 | + $this->set('REG_group_size', $REG_group_size); |
|
| 448 | + } |
|
| 449 | + |
|
| 450 | + |
|
| 451 | + /** |
|
| 452 | + * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
| 453 | + * EEM_Registration::status_id_not_approved |
|
| 454 | + * |
|
| 455 | + * @return boolean |
|
| 456 | + */ |
|
| 457 | + public function is_not_approved() |
|
| 458 | + { |
|
| 459 | + return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
| 460 | + } |
|
| 461 | + |
|
| 462 | + |
|
| 463 | + /** |
|
| 464 | + * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
| 465 | + * EEM_Registration::status_id_pending_payment |
|
| 466 | + * |
|
| 467 | + * @return boolean |
|
| 468 | + */ |
|
| 469 | + public function is_pending_payment() |
|
| 470 | + { |
|
| 471 | + return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
| 472 | + } |
|
| 473 | + |
|
| 474 | + |
|
| 475 | + /** |
|
| 476 | + * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
| 477 | + * |
|
| 478 | + * @return boolean |
|
| 479 | + */ |
|
| 480 | + public function is_approved() |
|
| 481 | + { |
|
| 482 | + return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
| 483 | + } |
|
| 484 | + |
|
| 485 | + |
|
| 486 | + /** |
|
| 487 | + * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
| 488 | + * |
|
| 489 | + * @return boolean |
|
| 490 | + */ |
|
| 491 | + public function is_cancelled() |
|
| 492 | + { |
|
| 493 | + return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
| 494 | + } |
|
| 495 | + |
|
| 496 | + |
|
| 497 | + /** |
|
| 498 | + * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
| 499 | + * |
|
| 500 | + * @return boolean |
|
| 501 | + */ |
|
| 502 | + public function is_declined() |
|
| 503 | + { |
|
| 504 | + return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
| 505 | + } |
|
| 506 | + |
|
| 507 | + |
|
| 508 | + /** |
|
| 509 | + * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
| 510 | + * EEM_Registration::status_id_incomplete |
|
| 511 | + * |
|
| 512 | + * @return boolean |
|
| 513 | + */ |
|
| 514 | + public function is_incomplete() |
|
| 515 | + { |
|
| 516 | + return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
| 517 | + } |
|
| 518 | + |
|
| 519 | + |
|
| 520 | + /** |
|
| 521 | + * Set Registration Date |
|
| 522 | + * |
|
| 523 | + * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
| 524 | + * Date |
|
| 525 | + * @throws EE_Error |
|
| 526 | + * @throws RuntimeException |
|
| 527 | + */ |
|
| 528 | + public function set_reg_date($REG_date = false) |
|
| 529 | + { |
|
| 530 | + $this->set('REG_date', $REG_date); |
|
| 531 | + } |
|
| 532 | + |
|
| 533 | + |
|
| 534 | + /** |
|
| 535 | + * Set final price owing for this registration after all ticket/price modifications |
|
| 536 | + * |
|
| 537 | + * @access public |
|
| 538 | + * @param float $REG_final_price |
|
| 539 | + * @throws EE_Error |
|
| 540 | + * @throws RuntimeException |
|
| 541 | + */ |
|
| 542 | + public function set_final_price($REG_final_price = 0.00) |
|
| 543 | + { |
|
| 544 | + $this->set('REG_final_price', $REG_final_price); |
|
| 545 | + } |
|
| 546 | + |
|
| 547 | + |
|
| 548 | + /** |
|
| 549 | + * Set amount paid towards this registration's final price |
|
| 550 | + * |
|
| 551 | + * @access public |
|
| 552 | + * @param float $REG_paid |
|
| 553 | + * @throws EE_Error |
|
| 554 | + * @throws RuntimeException |
|
| 555 | + */ |
|
| 556 | + public function set_paid($REG_paid = 0.00) |
|
| 557 | + { |
|
| 558 | + $this->set('REG_paid', $REG_paid); |
|
| 559 | + } |
|
| 560 | + |
|
| 561 | + |
|
| 562 | + /** |
|
| 563 | + * Attendee Is Going |
|
| 564 | + * |
|
| 565 | + * @param boolean $REG_att_is_going Attendee Is Going |
|
| 566 | + * @throws EE_Error |
|
| 567 | + * @throws RuntimeException |
|
| 568 | + */ |
|
| 569 | + public function set_att_is_going($REG_att_is_going = false) |
|
| 570 | + { |
|
| 571 | + $this->set('REG_att_is_going', $REG_att_is_going); |
|
| 572 | + } |
|
| 573 | + |
|
| 574 | + |
|
| 575 | + /** |
|
| 576 | + * Gets the related attendee |
|
| 577 | + * |
|
| 578 | + * @return EE_Attendee |
|
| 579 | + * @throws EE_Error |
|
| 580 | + */ |
|
| 581 | + public function attendee() |
|
| 582 | + { |
|
| 583 | + return $this->get_first_related('Attendee'); |
|
| 584 | + } |
|
| 585 | + |
|
| 586 | + |
|
| 587 | + /** |
|
| 588 | + * get Event ID |
|
| 589 | + */ |
|
| 590 | + public function event_ID() |
|
| 591 | + { |
|
| 592 | + return $this->get('EVT_ID'); |
|
| 593 | + } |
|
| 594 | + |
|
| 595 | + |
|
| 596 | + /** |
|
| 597 | + * get Event ID |
|
| 598 | + */ |
|
| 599 | + public function event_name() |
|
| 600 | + { |
|
| 601 | + $event = $this->event_obj(); |
|
| 602 | + if ($event) { |
|
| 603 | + return $event->name(); |
|
| 604 | + } else { |
|
| 605 | + return null; |
|
| 606 | + } |
|
| 607 | + } |
|
| 608 | + |
|
| 609 | + |
|
| 610 | + /** |
|
| 611 | + * Fetches the event this registration is for |
|
| 612 | + * |
|
| 613 | + * @return EE_Event |
|
| 614 | + * @throws EE_Error |
|
| 615 | + */ |
|
| 616 | + public function event_obj() |
|
| 617 | + { |
|
| 618 | + return $this->get_first_related('Event'); |
|
| 619 | + } |
|
| 620 | + |
|
| 621 | + |
|
| 622 | + /** |
|
| 623 | + * get Attendee ID |
|
| 624 | + */ |
|
| 625 | + public function attendee_ID() |
|
| 626 | + { |
|
| 627 | + return $this->get('ATT_ID'); |
|
| 628 | + } |
|
| 629 | + |
|
| 630 | + |
|
| 631 | + /** |
|
| 632 | + * get PHP Session ID |
|
| 633 | + */ |
|
| 634 | + public function session_ID() |
|
| 635 | + { |
|
| 636 | + return $this->get('REG_session'); |
|
| 637 | + } |
|
| 638 | + |
|
| 639 | + |
|
| 640 | + /** |
|
| 641 | + * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
| 642 | + * |
|
| 643 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 644 | + * @return string |
|
| 645 | + */ |
|
| 646 | + public function receipt_url($messenger = 'html') |
|
| 647 | + { |
|
| 648 | + |
|
| 649 | + /** |
|
| 650 | + * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
| 651 | + * already in use on old system. If there is then we just return the standard url for it. |
|
| 652 | + * |
|
| 653 | + * @since 4.5.0 |
|
| 654 | + */ |
|
| 655 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
| 656 | + $has_custom = EEH_Template::locate_template( |
|
| 657 | + $template_relative_path, |
|
| 658 | + array(), |
|
| 659 | + true, |
|
| 660 | + true, |
|
| 661 | + true |
|
| 662 | + ); |
|
| 663 | + |
|
| 664 | + if ($has_custom) { |
|
| 665 | + return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
| 666 | + } |
|
| 667 | + return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
| 668 | + } |
|
| 669 | + |
|
| 670 | + |
|
| 671 | + /** |
|
| 672 | + * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
| 673 | + * |
|
| 674 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 675 | + * @return string |
|
| 676 | + * @throws EE_Error |
|
| 677 | + */ |
|
| 678 | + public function invoice_url($messenger = 'html') |
|
| 679 | + { |
|
| 680 | + /** |
|
| 681 | + * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
| 682 | + * already in use on old system. If there is then we just return the standard url for it. |
|
| 683 | + * |
|
| 684 | + * @since 4.5.0 |
|
| 685 | + */ |
|
| 686 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
| 687 | + $has_custom = EEH_Template::locate_template( |
|
| 688 | + $template_relative_path, |
|
| 689 | + array(), |
|
| 690 | + true, |
|
| 691 | + true, |
|
| 692 | + true |
|
| 693 | + ); |
|
| 694 | + |
|
| 695 | + if ($has_custom) { |
|
| 696 | + if ($messenger == 'html') { |
|
| 697 | + return $this->invoice_url('launch'); |
|
| 698 | + } |
|
| 699 | + $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
| 700 | + |
|
| 701 | + $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
| 702 | + if ($messenger == 'html') { |
|
| 703 | + $query_args['html'] = true; |
|
| 704 | + } |
|
| 705 | + return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
| 706 | + } |
|
| 707 | + return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
| 708 | + } |
|
| 709 | + |
|
| 710 | + |
|
| 711 | + /** |
|
| 712 | + * get Registration URL Link |
|
| 713 | + * |
|
| 714 | + * @access public |
|
| 715 | + * @return string |
|
| 716 | + * @throws \EE_Error |
|
| 717 | + */ |
|
| 718 | + public function reg_url_link() |
|
| 719 | + { |
|
| 720 | + return (string) $this->get('REG_url_link'); |
|
| 721 | + } |
|
| 722 | + |
|
| 723 | + |
|
| 724 | + /** |
|
| 725 | + * Echoes out invoice_url() |
|
| 726 | + * |
|
| 727 | + * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
| 728 | + * @return void |
|
| 729 | + * @throws EE_Error |
|
| 730 | + */ |
|
| 731 | + public function e_invoice_url($type = 'launch') |
|
| 732 | + { |
|
| 733 | + echo $this->invoice_url($type); |
|
| 734 | + } |
|
| 735 | + |
|
| 736 | + |
|
| 737 | + /** |
|
| 738 | + * Echoes out payment_overview_url |
|
| 739 | + */ |
|
| 740 | + public function e_payment_overview_url() |
|
| 741 | + { |
|
| 742 | + echo $this->payment_overview_url(); |
|
| 743 | + } |
|
| 744 | + |
|
| 745 | + |
|
| 746 | + /** |
|
| 747 | + * Gets the URL of the thank you page with this registration REG_url_link added as |
|
| 748 | + * a query parameter |
|
| 749 | + * |
|
| 750 | + * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
| 751 | + * payment overview url. |
|
| 752 | + * @return string |
|
| 753 | + * @throws EE_Error |
|
| 754 | + */ |
|
| 755 | + public function payment_overview_url($clear_session = false) |
|
| 756 | + { |
|
| 757 | + return add_query_arg(array( |
|
| 758 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
| 759 | + 'step' => 'payment_options', |
|
| 760 | + 'revisit' => true, |
|
| 761 | + 'clear_session' => (bool) $clear_session |
|
| 762 | + ), EE_Registry::instance()->CFG->core->reg_page_url()); |
|
| 763 | + } |
|
| 764 | + |
|
| 765 | + |
|
| 766 | + /** |
|
| 767 | + * Gets the URL of the thank you page with this registration REG_url_link added as |
|
| 768 | + * a query parameter |
|
| 769 | + * |
|
| 770 | + * @return string |
|
| 771 | + * @throws EE_Error |
|
| 772 | + */ |
|
| 773 | + public function edit_attendee_information_url() |
|
| 774 | + { |
|
| 775 | + return add_query_arg(array( |
|
| 776 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
| 777 | + 'step' => 'attendee_information', |
|
| 778 | + 'revisit' => true, |
|
| 779 | + ), EE_Registry::instance()->CFG->core->reg_page_url()); |
|
| 780 | + } |
|
| 781 | + |
|
| 782 | + |
|
| 783 | + /** |
|
| 784 | + * Simply generates and returns the appropriate admin_url link to edit this registration |
|
| 785 | + * |
|
| 786 | + * @return string |
|
| 787 | + * @throws EE_Error |
|
| 788 | + */ |
|
| 789 | + public function get_admin_edit_url() |
|
| 790 | + { |
|
| 791 | + return EEH_URL::add_query_args_and_nonce(array( |
|
| 792 | + 'page' => 'espresso_registrations', |
|
| 793 | + 'action' => 'view_registration', |
|
| 794 | + '_REG_ID' => $this->ID(), |
|
| 795 | + ), admin_url('admin.php')); |
|
| 796 | + } |
|
| 797 | + |
|
| 798 | + |
|
| 799 | + /** |
|
| 800 | + * is_primary_registrant? |
|
| 801 | + */ |
|
| 802 | + public function is_primary_registrant() |
|
| 803 | + { |
|
| 804 | + return $this->get('REG_count') == 1 ? true : false; |
|
| 805 | + } |
|
| 806 | + |
|
| 807 | + |
|
| 808 | + /** |
|
| 809 | + * This returns the primary registration object for this registration group (which may be this object). |
|
| 810 | + * |
|
| 811 | + * @return EE_Registration |
|
| 812 | + * @throws EE_Error |
|
| 813 | + */ |
|
| 814 | + public function get_primary_registration() |
|
| 815 | + { |
|
| 816 | + if ($this->is_primary_registrant()) { |
|
| 817 | + return $this; |
|
| 818 | + } |
|
| 819 | + |
|
| 820 | + //k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
| 821 | + /** @var EE_Registration $primary_registrant */ |
|
| 822 | + $primary_registrant = EEM_Registration::instance()->get_one(array( |
|
| 823 | + array( |
|
| 824 | + 'TXN_ID' => $this->transaction_ID(), |
|
| 825 | + 'REG_count' => 1, |
|
| 826 | + ), |
|
| 827 | + )); |
|
| 828 | + return $primary_registrant; |
|
| 829 | + } |
|
| 830 | + |
|
| 831 | + |
|
| 832 | + /** |
|
| 833 | + * get Attendee Number |
|
| 834 | + * |
|
| 835 | + * @access public |
|
| 836 | + */ |
|
| 837 | + public function count() |
|
| 838 | + { |
|
| 839 | + return $this->get('REG_count'); |
|
| 840 | + } |
|
| 841 | + |
|
| 842 | + |
|
| 843 | + /** |
|
| 844 | + * get Group Size |
|
| 845 | + */ |
|
| 846 | + public function group_size() |
|
| 847 | + { |
|
| 848 | + return $this->get('REG_group_size'); |
|
| 849 | + } |
|
| 850 | + |
|
| 851 | + |
|
| 852 | + /** |
|
| 853 | + * get Registration Date |
|
| 854 | + */ |
|
| 855 | + public function date() |
|
| 856 | + { |
|
| 857 | + return $this->get('REG_date'); |
|
| 858 | + } |
|
| 859 | + |
|
| 860 | + |
|
| 861 | + /** |
|
| 862 | + * gets a pretty date |
|
| 863 | + * |
|
| 864 | + * @param string $date_format |
|
| 865 | + * @param string $time_format |
|
| 866 | + * @return string |
|
| 867 | + * @throws EE_Error |
|
| 868 | + */ |
|
| 869 | + public function pretty_date($date_format = null, $time_format = null) |
|
| 870 | + { |
|
| 871 | + return $this->get_datetime('REG_date', $date_format, $time_format); |
|
| 872 | + } |
|
| 873 | + |
|
| 874 | + |
|
| 875 | + /** |
|
| 876 | + * final_price |
|
| 877 | + * the registration's share of the transaction total, so that the |
|
| 878 | + * sum of all the transaction's REG_final_prices equal the transaction's total |
|
| 879 | + * |
|
| 880 | + * @return float |
|
| 881 | + * @throws EE_Error |
|
| 882 | + */ |
|
| 883 | + public function final_price() |
|
| 884 | + { |
|
| 885 | + return $this->get('REG_final_price'); |
|
| 886 | + } |
|
| 887 | + |
|
| 888 | + |
|
| 889 | + /** |
|
| 890 | + * pretty_final_price |
|
| 891 | + * final price as formatted string, with correct decimal places and currency symbol |
|
| 892 | + * |
|
| 893 | + * @return string |
|
| 894 | + * @throws EE_Error |
|
| 895 | + */ |
|
| 896 | + public function pretty_final_price() |
|
| 897 | + { |
|
| 898 | + return $this->get_pretty('REG_final_price'); |
|
| 899 | + } |
|
| 900 | + |
|
| 901 | + |
|
| 902 | + /** |
|
| 903 | + * get paid (yeah) |
|
| 904 | + * |
|
| 905 | + * @return float |
|
| 906 | + * @throws EE_Error |
|
| 907 | + */ |
|
| 908 | + public function paid() |
|
| 909 | + { |
|
| 910 | + return $this->get('REG_paid'); |
|
| 911 | + } |
|
| 912 | + |
|
| 913 | + |
|
| 914 | + /** |
|
| 915 | + * pretty_paid |
|
| 916 | + * |
|
| 917 | + * @return float |
|
| 918 | + * @throws EE_Error |
|
| 919 | + */ |
|
| 920 | + public function pretty_paid() |
|
| 921 | + { |
|
| 922 | + return $this->get_pretty('REG_paid'); |
|
| 923 | + } |
|
| 924 | + |
|
| 925 | + |
|
| 926 | + /** |
|
| 927 | + * owes_monies_and_can_pay |
|
| 928 | + * whether or not this registration has monies owing and it's' status allows payment |
|
| 929 | + * |
|
| 930 | + * @param array $requires_payment |
|
| 931 | + * @return bool |
|
| 932 | + * @throws EE_Error |
|
| 933 | + */ |
|
| 934 | + public function owes_monies_and_can_pay($requires_payment = array()) |
|
| 935 | + { |
|
| 936 | + // these reg statuses require payment (if event is not free) |
|
| 937 | + $requires_payment = ! empty($requires_payment) |
|
| 938 | + ? $requires_payment |
|
| 939 | + : EEM_Registration::reg_statuses_that_allow_payment(); |
|
| 940 | + if (in_array($this->status_ID(), $requires_payment) && |
|
| 941 | + $this->final_price() != 0 && |
|
| 942 | + $this->final_price() != $this->paid() |
|
| 943 | + ) { |
|
| 944 | + return true; |
|
| 945 | + } else { |
|
| 946 | + return false; |
|
| 947 | + } |
|
| 948 | + } |
|
| 949 | + |
|
| 950 | + |
|
| 951 | + /** |
|
| 952 | + * Prints out the return value of $this->pretty_status() |
|
| 953 | + * |
|
| 954 | + * @param bool $show_icons |
|
| 955 | + * @return void |
|
| 956 | + * @throws EE_Error |
|
| 957 | + */ |
|
| 958 | + public function e_pretty_status($show_icons = false) |
|
| 959 | + { |
|
| 960 | + echo $this->pretty_status($show_icons); |
|
| 961 | + } |
|
| 962 | + |
|
| 963 | + |
|
| 964 | + /** |
|
| 965 | + * Returns a nice version of the status for displaying to customers |
|
| 966 | + * |
|
| 967 | + * @param bool $show_icons |
|
| 968 | + * @return string |
|
| 969 | + * @throws EE_Error |
|
| 970 | + */ |
|
| 971 | + public function pretty_status($show_icons = false) |
|
| 972 | + { |
|
| 973 | + $status = EEM_Status::instance()->localized_status( |
|
| 974 | + array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
| 975 | + false, |
|
| 976 | + 'sentence' |
|
| 977 | + ); |
|
| 978 | + $icon = ''; |
|
| 979 | + switch ($this->status_ID()) { |
|
| 980 | + case EEM_Registration::status_id_approved: |
|
| 981 | + $icon = $show_icons |
|
| 982 | + ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
| 983 | + : ''; |
|
| 984 | + break; |
|
| 985 | + case EEM_Registration::status_id_pending_payment: |
|
| 986 | + $icon = $show_icons |
|
| 987 | + ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
| 988 | + : ''; |
|
| 989 | + break; |
|
| 990 | + case EEM_Registration::status_id_not_approved: |
|
| 991 | + $icon = $show_icons |
|
| 992 | + ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
| 993 | + : ''; |
|
| 994 | + break; |
|
| 995 | + case EEM_Registration::status_id_cancelled: |
|
| 996 | + $icon = $show_icons |
|
| 997 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
| 998 | + : ''; |
|
| 999 | + break; |
|
| 1000 | + case EEM_Registration::status_id_incomplete: |
|
| 1001 | + $icon = $show_icons |
|
| 1002 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
| 1003 | + : ''; |
|
| 1004 | + break; |
|
| 1005 | + case EEM_Registration::status_id_declined: |
|
| 1006 | + $icon = $show_icons |
|
| 1007 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
| 1008 | + : ''; |
|
| 1009 | + break; |
|
| 1010 | + case EEM_Registration::status_id_wait_list: |
|
| 1011 | + $icon = $show_icons |
|
| 1012 | + ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
| 1013 | + : ''; |
|
| 1014 | + break; |
|
| 1015 | + } |
|
| 1016 | + return $icon . $status[$this->status_ID()]; |
|
| 1017 | + } |
|
| 1018 | + |
|
| 1019 | + |
|
| 1020 | + /** |
|
| 1021 | + * get Attendee Is Going |
|
| 1022 | + */ |
|
| 1023 | + public function att_is_going() |
|
| 1024 | + { |
|
| 1025 | + return $this->get('REG_att_is_going'); |
|
| 1026 | + } |
|
| 1027 | + |
|
| 1028 | + |
|
| 1029 | + /** |
|
| 1030 | + * Gets related answers |
|
| 1031 | + * |
|
| 1032 | + * @param array $query_params like EEM_Base::get_all |
|
| 1033 | + * @return EE_Answer[] |
|
| 1034 | + * @throws EE_Error |
|
| 1035 | + */ |
|
| 1036 | + public function answers($query_params = null) |
|
| 1037 | + { |
|
| 1038 | + return $this->get_many_related('Answer', $query_params); |
|
| 1039 | + } |
|
| 1040 | + |
|
| 1041 | + |
|
| 1042 | + /** |
|
| 1043 | + * Gets the registration's answer value to the specified question |
|
| 1044 | + * (either the question's ID or a question object) |
|
| 1045 | + * |
|
| 1046 | + * @param EE_Question|int $question |
|
| 1047 | + * @param bool $pretty_value |
|
| 1048 | + * @return array|string if pretty_value= true, the result will always be a string |
|
| 1049 | + * (because the answer might be an array of answer values, so passing pretty_value=true |
|
| 1050 | + * will convert it into some kind of string) |
|
| 1051 | + * @throws EE_Error |
|
| 1052 | + */ |
|
| 1053 | + public function answer_value_to_question($question, $pretty_value = true) |
|
| 1054 | + { |
|
| 1055 | + $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
| 1056 | + return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
| 1057 | + } |
|
| 1058 | + |
|
| 1059 | + |
|
| 1060 | + /** |
|
| 1061 | + * question_groups |
|
| 1062 | + * returns an array of EE_Question_Group objects for this registration |
|
| 1063 | + * |
|
| 1064 | + * @return EE_Question_Group[] |
|
| 1065 | + * @throws EE_Error |
|
| 1066 | + * @throws EntityNotFoundException |
|
| 1067 | + */ |
|
| 1068 | + public function question_groups() |
|
| 1069 | + { |
|
| 1070 | + $question_groups = array(); |
|
| 1071 | + if ($this->event() instanceof EE_Event) { |
|
| 1072 | + $question_groups = $this->event()->question_groups( |
|
| 1073 | + array( |
|
| 1074 | + array( |
|
| 1075 | + 'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false, |
|
| 1076 | + ), |
|
| 1077 | + 'order_by' => array('QSG_order' => 'ASC'), |
|
| 1078 | + ) |
|
| 1079 | + ); |
|
| 1080 | + } |
|
| 1081 | + return $question_groups; |
|
| 1082 | + } |
|
| 1083 | + |
|
| 1084 | + |
|
| 1085 | + /** |
|
| 1086 | + * count_question_groups |
|
| 1087 | + * returns a count of the number of EE_Question_Group objects for this registration |
|
| 1088 | + * |
|
| 1089 | + * @return int |
|
| 1090 | + * @throws EE_Error |
|
| 1091 | + * @throws EntityNotFoundException |
|
| 1092 | + */ |
|
| 1093 | + public function count_question_groups() |
|
| 1094 | + { |
|
| 1095 | + $qg_count = 0; |
|
| 1096 | + if ($this->event() instanceof EE_Event) { |
|
| 1097 | + $qg_count = $this->event()->count_related( |
|
| 1098 | + 'Question_Group', |
|
| 1099 | + array( |
|
| 1100 | + array( |
|
| 1101 | + 'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false, |
|
| 1102 | + ), |
|
| 1103 | + ) |
|
| 1104 | + ); |
|
| 1105 | + } |
|
| 1106 | + return $qg_count; |
|
| 1107 | + } |
|
| 1108 | + |
|
| 1109 | + |
|
| 1110 | + /** |
|
| 1111 | + * Returns the registration date in the 'standard' string format |
|
| 1112 | + * (function may be improved in the future to allow for different formats and timezones) |
|
| 1113 | + * |
|
| 1114 | + * @return string |
|
| 1115 | + * @throws EE_Error |
|
| 1116 | + */ |
|
| 1117 | + public function reg_date() |
|
| 1118 | + { |
|
| 1119 | + return $this->get_datetime('REG_date'); |
|
| 1120 | + } |
|
| 1121 | + |
|
| 1122 | + |
|
| 1123 | + /** |
|
| 1124 | + * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
| 1125 | + * the ticket this registration purchased, or the datetime they have registered |
|
| 1126 | + * to attend) |
|
| 1127 | + * |
|
| 1128 | + * @return EE_Datetime_Ticket |
|
| 1129 | + * @throws EE_Error |
|
| 1130 | + */ |
|
| 1131 | + public function datetime_ticket() |
|
| 1132 | + { |
|
| 1133 | + return $this->get_first_related('Datetime_Ticket'); |
|
| 1134 | + } |
|
| 1135 | + |
|
| 1136 | + |
|
| 1137 | + /** |
|
| 1138 | + * Sets the registration's datetime_ticket. |
|
| 1139 | + * |
|
| 1140 | + * @param EE_Datetime_Ticket $datetime_ticket |
|
| 1141 | + * @return EE_Datetime_Ticket |
|
| 1142 | + * @throws EE_Error |
|
| 1143 | + */ |
|
| 1144 | + public function set_datetime_ticket($datetime_ticket) |
|
| 1145 | + { |
|
| 1146 | + return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
| 1147 | + } |
|
| 1148 | + |
|
| 1149 | + /** |
|
| 1150 | + * Gets deleted |
|
| 1151 | + * |
|
| 1152 | + * @return bool |
|
| 1153 | + * @throws EE_Error |
|
| 1154 | + */ |
|
| 1155 | + public function deleted() |
|
| 1156 | + { |
|
| 1157 | + return $this->get('REG_deleted'); |
|
| 1158 | + } |
|
| 1159 | + |
|
| 1160 | + /** |
|
| 1161 | + * Sets deleted |
|
| 1162 | + * |
|
| 1163 | + * @param boolean $deleted |
|
| 1164 | + * @return bool |
|
| 1165 | + * @throws EE_Error |
|
| 1166 | + * @throws RuntimeException |
|
| 1167 | + */ |
|
| 1168 | + public function set_deleted($deleted) |
|
| 1169 | + { |
|
| 1170 | + if ($deleted) { |
|
| 1171 | + $this->delete(); |
|
| 1172 | + } else { |
|
| 1173 | + $this->restore(); |
|
| 1174 | + } |
|
| 1175 | + } |
|
| 1176 | + |
|
| 1177 | + |
|
| 1178 | + /** |
|
| 1179 | + * Get the status object of this object |
|
| 1180 | + * |
|
| 1181 | + * @return EE_Status |
|
| 1182 | + * @throws EE_Error |
|
| 1183 | + */ |
|
| 1184 | + public function status_obj() |
|
| 1185 | + { |
|
| 1186 | + return $this->get_first_related('Status'); |
|
| 1187 | + } |
|
| 1188 | + |
|
| 1189 | + |
|
| 1190 | + /** |
|
| 1191 | + * Returns the number of times this registration has checked into any of the datetimes |
|
| 1192 | + * its available for |
|
| 1193 | + * |
|
| 1194 | + * @return int |
|
| 1195 | + * @throws EE_Error |
|
| 1196 | + */ |
|
| 1197 | + public function count_checkins() |
|
| 1198 | + { |
|
| 1199 | + return $this->get_model()->count_related($this, 'Checkin'); |
|
| 1200 | + } |
|
| 1201 | + |
|
| 1202 | + |
|
| 1203 | + /** |
|
| 1204 | + * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
| 1205 | + * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
| 1206 | + * |
|
| 1207 | + * @return int |
|
| 1208 | + * @throws EE_Error |
|
| 1209 | + */ |
|
| 1210 | + public function count_checkins_not_checkedout() |
|
| 1211 | + { |
|
| 1212 | + return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
| 1213 | + } |
|
| 1214 | + |
|
| 1215 | + |
|
| 1216 | + /** |
|
| 1217 | + * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
| 1218 | + * |
|
| 1219 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1220 | + * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
| 1221 | + * consider registration status as well as datetime access. |
|
| 1222 | + * @return bool |
|
| 1223 | + * @throws EE_Error |
|
| 1224 | + */ |
|
| 1225 | + public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
| 1226 | + { |
|
| 1227 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1228 | + |
|
| 1229 | + //first check registration status |
|
| 1230 | + if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
| 1231 | + return false; |
|
| 1232 | + } |
|
| 1233 | + //is there a datetime ticket that matches this dtt_ID? |
|
| 1234 | + if (! (EEM_Datetime_Ticket::instance()->exists(array( |
|
| 1235 | + array( |
|
| 1236 | + 'TKT_ID' => $this->get('TKT_ID'), |
|
| 1237 | + 'DTT_ID' => $DTT_ID, |
|
| 1238 | + ), |
|
| 1239 | + ))) |
|
| 1240 | + ) { |
|
| 1241 | + return false; |
|
| 1242 | + } |
|
| 1243 | + |
|
| 1244 | + //final check is against TKT_uses |
|
| 1245 | + return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
| 1246 | + } |
|
| 1247 | + |
|
| 1248 | + |
|
| 1249 | + /** |
|
| 1250 | + * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
| 1251 | + * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
| 1252 | + * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
| 1253 | + * then return false. Otherwise return true. |
|
| 1254 | + * |
|
| 1255 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1256 | + * @return bool true means can checkin. false means cannot checkin. |
|
| 1257 | + * @throws EE_Error |
|
| 1258 | + */ |
|
| 1259 | + public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
| 1260 | + { |
|
| 1261 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1262 | + |
|
| 1263 | + if (! $DTT_ID) { |
|
| 1264 | + return false; |
|
| 1265 | + } |
|
| 1266 | + |
|
| 1267 | + $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
| 1268 | + |
|
| 1269 | + // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
| 1270 | + // check-in or not. |
|
| 1271 | + if (! $max_uses || $max_uses === EE_INF) { |
|
| 1272 | + return true; |
|
| 1273 | + } |
|
| 1274 | + |
|
| 1275 | + //does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
| 1276 | + //go ahead and toggle. |
|
| 1277 | + if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
| 1278 | + return true; |
|
| 1279 | + } |
|
| 1280 | + |
|
| 1281 | + //made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
| 1282 | + //disallows further check-ins. |
|
| 1283 | + $count_unique_dtt_checkins = EEM_Checkin::instance()->count(array( |
|
| 1284 | + array( |
|
| 1285 | + 'REG_ID' => $this->ID(), |
|
| 1286 | + 'CHK_in' => true, |
|
| 1287 | + ), |
|
| 1288 | + ), 'DTT_ID', true); |
|
| 1289 | + // checkins have already reached their max number of uses |
|
| 1290 | + // so registrant can NOT checkin |
|
| 1291 | + if ($count_unique_dtt_checkins >= $max_uses) { |
|
| 1292 | + EE_Error::add_error( |
|
| 1293 | + esc_html__( |
|
| 1294 | + 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
| 1295 | + 'event_espresso' |
|
| 1296 | + ), |
|
| 1297 | + __FILE__, |
|
| 1298 | + __FUNCTION__, |
|
| 1299 | + __LINE__ |
|
| 1300 | + ); |
|
| 1301 | + return false; |
|
| 1302 | + } |
|
| 1303 | + return true; |
|
| 1304 | + } |
|
| 1305 | + |
|
| 1306 | + |
|
| 1307 | + /** |
|
| 1308 | + * toggle Check-in status for this registration |
|
| 1309 | + * Check-ins are toggled in the following order: |
|
| 1310 | + * never checked in -> checked in |
|
| 1311 | + * checked in -> checked out |
|
| 1312 | + * checked out -> checked in |
|
| 1313 | + * |
|
| 1314 | + * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
| 1315 | + * If not included or null, then it is assumed latest datetime is being toggled. |
|
| 1316 | + * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
| 1317 | + * can be checked in or not. Otherwise this forces change in checkin status. |
|
| 1318 | + * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
| 1319 | + * @throws EE_Error |
|
| 1320 | + */ |
|
| 1321 | + public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
| 1322 | + { |
|
| 1323 | + if (empty($DTT_ID)) { |
|
| 1324 | + $datetime = $this->get_latest_related_datetime(); |
|
| 1325 | + $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
| 1326 | + // verify the registration can checkin for the given DTT_ID |
|
| 1327 | + } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1328 | + EE_Error::add_error( |
|
| 1329 | + sprintf( |
|
| 1330 | + esc_html__( |
|
| 1331 | + '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', |
|
| 1332 | + 'event_espresso' |
|
| 1333 | + ), |
|
| 1334 | + $this->ID(), |
|
| 1335 | + $DTT_ID |
|
| 1336 | + ), |
|
| 1337 | + __FILE__, |
|
| 1338 | + __FUNCTION__, |
|
| 1339 | + __LINE__ |
|
| 1340 | + ); |
|
| 1341 | + return false; |
|
| 1342 | + } |
|
| 1343 | + $status_paths = array( |
|
| 1344 | + EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
| 1345 | + EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
| 1346 | + EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
| 1347 | + ); |
|
| 1348 | + //start by getting the current status so we know what status we'll be changing to. |
|
| 1349 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
| 1350 | + $status_to = $status_paths[$cur_status]; |
|
| 1351 | + // database only records true for checked IN or false for checked OUT |
|
| 1352 | + // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
| 1353 | + $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
| 1354 | + // add relation - note Check-ins are always creating new rows |
|
| 1355 | + // because we are keeping track of Check-ins over time. |
|
| 1356 | + // Eventually we'll probably want to show a list table |
|
| 1357 | + // for the individual Check-ins so that they can be managed. |
|
| 1358 | + $checkin = EE_Checkin::new_instance(array( |
|
| 1359 | + 'REG_ID' => $this->ID(), |
|
| 1360 | + 'DTT_ID' => $DTT_ID, |
|
| 1361 | + 'CHK_in' => $new_status, |
|
| 1362 | + )); |
|
| 1363 | + // if the record could not be saved then return false |
|
| 1364 | + if ($checkin->save() === 0) { |
|
| 1365 | + if (WP_DEBUG) { |
|
| 1366 | + global $wpdb; |
|
| 1367 | + $error = sprintf( |
|
| 1368 | + esc_html__( |
|
| 1369 | + 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
| 1370 | + 'event_espresso' |
|
| 1371 | + ), |
|
| 1372 | + '<br />', |
|
| 1373 | + $wpdb->last_error |
|
| 1374 | + ); |
|
| 1375 | + } else { |
|
| 1376 | + $error = esc_html__( |
|
| 1377 | + 'Registration check in update failed because of an unknown database error', |
|
| 1378 | + 'event_espresso' |
|
| 1379 | + ); |
|
| 1380 | + } |
|
| 1381 | + EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
| 1382 | + return false; |
|
| 1383 | + } |
|
| 1384 | + return $status_to; |
|
| 1385 | + } |
|
| 1386 | + |
|
| 1387 | + |
|
| 1388 | + /** |
|
| 1389 | + * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
| 1390 | + * "Latest" is defined by the `DTT_EVT_start` column. |
|
| 1391 | + * |
|
| 1392 | + * @return EE_Datetime|null |
|
| 1393 | + * @throws \EE_Error |
|
| 1394 | + */ |
|
| 1395 | + public function get_latest_related_datetime() |
|
| 1396 | + { |
|
| 1397 | + return EEM_Datetime::instance()->get_one( |
|
| 1398 | + array( |
|
| 1399 | + array( |
|
| 1400 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1401 | + ), |
|
| 1402 | + 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
| 1403 | + ) |
|
| 1404 | + ); |
|
| 1405 | + } |
|
| 1406 | + |
|
| 1407 | + |
|
| 1408 | + /** |
|
| 1409 | + * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
| 1410 | + * "Earliest" is defined by the `DTT_EVT_start` column. |
|
| 1411 | + * |
|
| 1412 | + * @throws \EE_Error |
|
| 1413 | + */ |
|
| 1414 | + public function get_earliest_related_datetime() |
|
| 1415 | + { |
|
| 1416 | + return EEM_Datetime::instance()->get_one( |
|
| 1417 | + array( |
|
| 1418 | + array( |
|
| 1419 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1420 | + ), |
|
| 1421 | + 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
| 1422 | + ) |
|
| 1423 | + ); |
|
| 1424 | + } |
|
| 1425 | + |
|
| 1426 | + |
|
| 1427 | + /** |
|
| 1428 | + * This method simply returns the check-in status for this registration and the given datetime. |
|
| 1429 | + * If neither the datetime nor the checkin values are provided as arguments, |
|
| 1430 | + * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
| 1431 | + * |
|
| 1432 | + * @param int $DTT_ID The ID of the datetime we're checking against |
|
| 1433 | + * (if empty we'll get the primary datetime for |
|
| 1434 | + * this registration (via event) and use it's ID); |
|
| 1435 | + * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
| 1436 | + * @return int Integer representing Check-in status. |
|
| 1437 | + * @throws \EE_Error |
|
| 1438 | + */ |
|
| 1439 | + public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
| 1440 | + { |
|
| 1441 | + $checkin_query_params = array( |
|
| 1442 | + 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
| 1443 | + ); |
|
| 1444 | + |
|
| 1445 | + if ($DTT_ID > 0) { |
|
| 1446 | + $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
| 1447 | + } |
|
| 1448 | + |
|
| 1449 | + //get checkin object (if exists) |
|
| 1450 | + $checkin = $checkin instanceof EE_Checkin |
|
| 1451 | + ? $checkin |
|
| 1452 | + : $this->get_first_related('Checkin', $checkin_query_params); |
|
| 1453 | + if ($checkin instanceof EE_Checkin) { |
|
| 1454 | + if ($checkin->get('CHK_in')) { |
|
| 1455 | + return EE_Checkin::status_checked_in; //checked in |
|
| 1456 | + } |
|
| 1457 | + return EE_Checkin::status_checked_out; //had checked in but is now checked out. |
|
| 1458 | + } |
|
| 1459 | + return EE_Checkin::status_checked_never; //never been checked in |
|
| 1460 | + } |
|
| 1461 | + |
|
| 1462 | + |
|
| 1463 | + /** |
|
| 1464 | + * This method returns a localized message for the toggled Check-in message. |
|
| 1465 | + * |
|
| 1466 | + * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
| 1467 | + * then it is assumed Check-in for primary datetime was toggled. |
|
| 1468 | + * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
| 1469 | + * message can be customized with the attendee name. |
|
| 1470 | + * @return string internationalized message |
|
| 1471 | + * @throws EE_Error |
|
| 1472 | + */ |
|
| 1473 | + public function get_checkin_msg($DTT_ID, $error = false) |
|
| 1474 | + { |
|
| 1475 | + //let's get the attendee first so we can include the name of the attendee |
|
| 1476 | + $attendee = $this->get_first_related('Attendee'); |
|
| 1477 | + if ($attendee instanceof EE_Attendee) { |
|
| 1478 | + if ($error) { |
|
| 1479 | + return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
| 1480 | + } |
|
| 1481 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
| 1482 | + //what is the status message going to be? |
|
| 1483 | + switch ($cur_status) { |
|
| 1484 | + case EE_Checkin::status_checked_never: |
|
| 1485 | + return sprintf(__("%s has been removed from Check-in records", "event_espresso"), |
|
| 1486 | + $attendee->full_name()); |
|
| 1487 | + break; |
|
| 1488 | + case EE_Checkin::status_checked_in: |
|
| 1489 | + return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
| 1490 | + break; |
|
| 1491 | + case EE_Checkin::status_checked_out: |
|
| 1492 | + return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
| 1493 | + break; |
|
| 1494 | + } |
|
| 1495 | + } |
|
| 1496 | + return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
| 1497 | + } |
|
| 1498 | + |
|
| 1499 | + |
|
| 1500 | + /** |
|
| 1501 | + * Returns the related EE_Transaction to this registration |
|
| 1502 | + * |
|
| 1503 | + * @return EE_Transaction |
|
| 1504 | + * @throws EE_Error |
|
| 1505 | + * @throws EntityNotFoundException |
|
| 1506 | + */ |
|
| 1507 | + public function transaction() |
|
| 1508 | + { |
|
| 1509 | + $transaction = $this->get_first_related('Transaction'); |
|
| 1510 | + if (! $transaction instanceof \EE_Transaction) { |
|
| 1511 | + throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
| 1512 | + } |
|
| 1513 | + return $transaction; |
|
| 1514 | + } |
|
| 1515 | + |
|
| 1516 | + |
|
| 1517 | + /** |
|
| 1518 | + * get Registration Code |
|
| 1519 | + */ |
|
| 1520 | + public function reg_code() |
|
| 1521 | + { |
|
| 1522 | + return $this->get('REG_code'); |
|
| 1523 | + } |
|
| 1524 | + |
|
| 1525 | + |
|
| 1526 | + /** |
|
| 1527 | + * get Transaction ID |
|
| 1528 | + */ |
|
| 1529 | + public function transaction_ID() |
|
| 1530 | + { |
|
| 1531 | + return $this->get('TXN_ID'); |
|
| 1532 | + } |
|
| 1533 | + |
|
| 1534 | + |
|
| 1535 | + /** |
|
| 1536 | + * @return int |
|
| 1537 | + * @throws EE_Error |
|
| 1538 | + */ |
|
| 1539 | + public function ticket_ID() |
|
| 1540 | + { |
|
| 1541 | + return $this->get('TKT_ID'); |
|
| 1542 | + } |
|
| 1543 | + |
|
| 1544 | + |
|
| 1545 | + /** |
|
| 1546 | + * Set Registration Code |
|
| 1547 | + * |
|
| 1548 | + * @access public |
|
| 1549 | + * @param string $REG_code Registration Code |
|
| 1550 | + * @param boolean $use_default |
|
| 1551 | + * @throws EE_Error |
|
| 1552 | + */ |
|
| 1553 | + public function set_reg_code($REG_code, $use_default = false) |
|
| 1554 | + { |
|
| 1555 | + if (empty($REG_code)) { |
|
| 1556 | + EE_Error::add_error( |
|
| 1557 | + esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
| 1558 | + __FILE__, |
|
| 1559 | + __FUNCTION__, |
|
| 1560 | + __LINE__ |
|
| 1561 | + ); |
|
| 1562 | + return; |
|
| 1563 | + } |
|
| 1564 | + if (! $this->reg_code()) { |
|
| 1565 | + parent::set('REG_code', $REG_code, $use_default); |
|
| 1566 | + } else { |
|
| 1567 | + EE_Error::doing_it_wrong( |
|
| 1568 | + __CLASS__ . '::' . __FUNCTION__, |
|
| 1569 | + esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
| 1570 | + '4.6.0' |
|
| 1571 | + ); |
|
| 1572 | + } |
|
| 1573 | + } |
|
| 1574 | + |
|
| 1575 | + |
|
| 1576 | + /** |
|
| 1577 | + * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
| 1578 | + * Note, if you want to just get all registrations in the same transaction (group), use: |
|
| 1579 | + * $registration->transaction()->registrations(); |
|
| 1580 | + * |
|
| 1581 | + * @since 4.5.0 |
|
| 1582 | + * @return EE_Registration[] or empty array if this isn't a group registration. |
|
| 1583 | + * @throws EE_Error |
|
| 1584 | + */ |
|
| 1585 | + public function get_all_other_registrations_in_group() |
|
| 1586 | + { |
|
| 1587 | + if ($this->group_size() < 2) { |
|
| 1588 | + return array(); |
|
| 1589 | + } |
|
| 1590 | + |
|
| 1591 | + $query[0] = array( |
|
| 1592 | + 'TXN_ID' => $this->transaction_ID(), |
|
| 1593 | + 'REG_ID' => array('!=', $this->ID()), |
|
| 1594 | + 'TKT_ID' => $this->ticket_ID(), |
|
| 1595 | + ); |
|
| 1596 | + /** @var EE_Registration[] $registrations */ |
|
| 1597 | + $registrations = $this->get_model()->get_all($query); |
|
| 1598 | + return $registrations; |
|
| 1599 | + } |
|
| 1600 | + |
|
| 1601 | + /** |
|
| 1602 | + * Return the link to the admin details for the object. |
|
| 1603 | + * |
|
| 1604 | + * @return string |
|
| 1605 | + * @throws EE_Error |
|
| 1606 | + */ |
|
| 1607 | + public function get_admin_details_link() |
|
| 1608 | + { |
|
| 1609 | + EE_Registry::instance()->load_helper('URL'); |
|
| 1610 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1611 | + array( |
|
| 1612 | + 'page' => 'espresso_registrations', |
|
| 1613 | + 'action' => 'view_registration', |
|
| 1614 | + '_REG_ID' => $this->ID(), |
|
| 1615 | + ), |
|
| 1616 | + admin_url('admin.php') |
|
| 1617 | + ); |
|
| 1618 | + } |
|
| 1619 | + |
|
| 1620 | + /** |
|
| 1621 | + * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
| 1622 | + * |
|
| 1623 | + * @return string |
|
| 1624 | + * @throws EE_Error |
|
| 1625 | + */ |
|
| 1626 | + public function get_admin_edit_link() |
|
| 1627 | + { |
|
| 1628 | + return $this->get_admin_details_link(); |
|
| 1629 | + } |
|
| 1630 | + |
|
| 1631 | + /** |
|
| 1632 | + * Returns the link to a settings page for the object. |
|
| 1633 | + * |
|
| 1634 | + * @return string |
|
| 1635 | + * @throws EE_Error |
|
| 1636 | + */ |
|
| 1637 | + public function get_admin_settings_link() |
|
| 1638 | + { |
|
| 1639 | + return $this->get_admin_details_link(); |
|
| 1640 | + } |
|
| 1641 | + |
|
| 1642 | + /** |
|
| 1643 | + * Returns the link to the "overview" for the object (typically the "list table" view). |
|
| 1644 | + * |
|
| 1645 | + * @return string |
|
| 1646 | + */ |
|
| 1647 | + public function get_admin_overview_link() |
|
| 1648 | + { |
|
| 1649 | + EE_Registry::instance()->load_helper('URL'); |
|
| 1650 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1651 | + array( |
|
| 1652 | + 'page' => 'espresso_registrations', |
|
| 1653 | + ), |
|
| 1654 | + admin_url('admin.php') |
|
| 1655 | + ); |
|
| 1656 | + } |
|
| 1657 | + |
|
| 1658 | + |
|
| 1659 | + /** |
|
| 1660 | + * @param array $query_params |
|
| 1661 | + * @return \EE_Registration[] |
|
| 1662 | + * @throws \EE_Error |
|
| 1663 | + */ |
|
| 1664 | + public function payments($query_params = array()) |
|
| 1665 | + { |
|
| 1666 | + return $this->get_many_related('Payment', $query_params); |
|
| 1667 | + } |
|
| 1668 | + |
|
| 1669 | + |
|
| 1670 | + /** |
|
| 1671 | + * @param array $query_params |
|
| 1672 | + * @return \EE_Registration_Payment[] |
|
| 1673 | + * @throws \EE_Error |
|
| 1674 | + */ |
|
| 1675 | + public function registration_payments($query_params = array()) |
|
| 1676 | + { |
|
| 1677 | + return $this->get_many_related('Registration_Payment', $query_params); |
|
| 1678 | + } |
|
| 1679 | + |
|
| 1680 | + |
|
| 1681 | + /** |
|
| 1682 | + * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
| 1683 | + * Note: if there are no payments on the registration there will be no payment method returned. |
|
| 1684 | + * |
|
| 1685 | + * @return EE_Payment_Method|null |
|
| 1686 | + */ |
|
| 1687 | + public function payment_method() |
|
| 1688 | + { |
|
| 1689 | + return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
| 1690 | + } |
|
| 1691 | + |
|
| 1692 | + |
|
| 1693 | + /** |
|
| 1694 | + * @return \EE_Line_Item |
|
| 1695 | + * @throws EntityNotFoundException |
|
| 1696 | + * @throws \EE_Error |
|
| 1697 | + */ |
|
| 1698 | + public function ticket_line_item() |
|
| 1699 | + { |
|
| 1700 | + $ticket = $this->ticket(); |
|
| 1701 | + $transaction = $this->transaction(); |
|
| 1702 | + $line_item = null; |
|
| 1703 | + $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 1704 | + $transaction->total_line_item(), |
|
| 1705 | + 'Ticket', |
|
| 1706 | + array($ticket->ID()) |
|
| 1707 | + ); |
|
| 1708 | + foreach ($ticket_line_items as $ticket_line_item) { |
|
| 1709 | + if ( |
|
| 1710 | + $ticket_line_item instanceof \EE_Line_Item |
|
| 1711 | + && $ticket_line_item->OBJ_type() === 'Ticket' |
|
| 1712 | + && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
| 1713 | + ) { |
|
| 1714 | + $line_item = $ticket_line_item; |
|
| 1715 | + break; |
|
| 1716 | + } |
|
| 1717 | + } |
|
| 1718 | + if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1719 | + throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
| 1720 | + } |
|
| 1721 | + return $line_item; |
|
| 1722 | + } |
|
| 1723 | + |
|
| 1724 | + |
|
| 1725 | + /** |
|
| 1726 | + * Soft Deletes this model object. |
|
| 1727 | + * |
|
| 1728 | + * @return boolean | int |
|
| 1729 | + * @throws \RuntimeException |
|
| 1730 | + * @throws \EE_Error |
|
| 1731 | + */ |
|
| 1732 | + public function delete() |
|
| 1733 | + { |
|
| 1734 | + if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
| 1735 | + $this->set_status(EEM_Registration::status_id_cancelled); |
|
| 1736 | + } |
|
| 1737 | + return parent::delete(); |
|
| 1738 | + } |
|
| 1739 | + |
|
| 1740 | + |
|
| 1741 | + /** |
|
| 1742 | + * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
| 1743 | + * |
|
| 1744 | + * @throws \EE_Error |
|
| 1745 | + * @throws \RuntimeException |
|
| 1746 | + */ |
|
| 1747 | + public function restore() |
|
| 1748 | + { |
|
| 1749 | + $previous_status = $this->get_extra_meta( |
|
| 1750 | + EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
| 1751 | + true, |
|
| 1752 | + EEM_Registration::status_id_cancelled |
|
| 1753 | + ); |
|
| 1754 | + if ($previous_status) { |
|
| 1755 | + $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
| 1756 | + $this->set_status($previous_status); |
|
| 1757 | + } |
|
| 1758 | + return parent::restore(); |
|
| 1759 | + } |
|
| 1760 | + |
|
| 1761 | + |
|
| 1762 | + |
|
| 1763 | + /*************************** DEPRECATED ***************************/ |
|
| 1764 | + |
|
| 1765 | + |
|
| 1766 | + /** |
|
| 1767 | + * @deprecated |
|
| 1768 | + * @since 4.7.0 |
|
| 1769 | + * @access public |
|
| 1770 | + */ |
|
| 1771 | + public function price_paid() |
|
| 1772 | + { |
|
| 1773 | + EE_Error::doing_it_wrong('EE_Registration::price_paid()', |
|
| 1774 | + esc_html__('This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso'), |
|
| 1775 | + '4.7.0'); |
|
| 1776 | + return $this->final_price(); |
|
| 1777 | + } |
|
| 1778 | + |
|
| 1779 | + |
|
| 1780 | + /** |
|
| 1781 | + * @deprecated |
|
| 1782 | + * @since 4.7.0 |
|
| 1783 | + * @access public |
|
| 1784 | + * @param float $REG_final_price |
|
| 1785 | + * @throws EE_Error |
|
| 1786 | + * @throws RuntimeException |
|
| 1787 | + */ |
|
| 1788 | + public function set_price_paid($REG_final_price = 0.00) |
|
| 1789 | + { |
|
| 1790 | + EE_Error::doing_it_wrong('EE_Registration::set_price_paid()', |
|
| 1791 | + esc_html__('This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso'), |
|
| 1792 | + '4.7.0'); |
|
| 1793 | + $this->set_final_price($REG_final_price); |
|
| 1794 | + } |
|
| 1795 | + |
|
| 1796 | + |
|
| 1797 | + /** |
|
| 1798 | + * @deprecated |
|
| 1799 | + * @since 4.7.0 |
|
| 1800 | + * @return string |
|
| 1801 | + * @throws EE_Error |
|
| 1802 | + */ |
|
| 1803 | + public function pretty_price_paid() |
|
| 1804 | + { |
|
| 1805 | + EE_Error::doing_it_wrong('EE_Registration::pretty_price_paid()', |
|
| 1806 | + esc_html__('This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
| 1807 | + 'event_espresso'), '4.7.0'); |
|
| 1808 | + return $this->pretty_final_price(); |
|
| 1809 | + } |
|
| 1810 | + |
|
| 1811 | + |
|
| 1812 | + /** |
|
| 1813 | + * Gets the primary datetime related to this registration via the related Event to this registration |
|
| 1814 | + * |
|
| 1815 | + * @deprecated 4.9.17 |
|
| 1816 | + * @return EE_Datetime |
|
| 1817 | + * @throws EE_Error |
|
| 1818 | + * @throws EntityNotFoundException |
|
| 1819 | + */ |
|
| 1820 | + public function get_related_primary_datetime() |
|
| 1821 | + { |
|
| 1822 | + EE_Error::doing_it_wrong( |
|
| 1823 | + __METHOD__, |
|
| 1824 | + esc_html__( |
|
| 1825 | + 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
| 1826 | + 'event_espresso' |
|
| 1827 | + ), |
|
| 1828 | + '4.9.17', |
|
| 1829 | + '5.0.0' |
|
| 1830 | + ); |
|
| 1831 | + return $this->event()->primary_datetime(); |
|
| 1832 | + } |
|
| 1833 | 1833 | |
| 1834 | 1834 | |
| 1835 | 1835 | } |
@@ -18,1496 +18,1496 @@ |
||
| 18 | 18 | class EE_Line_Item extends EE_Base_Class implements EEI_Line_Item |
| 19 | 19 | { |
| 20 | 20 | |
| 21 | - /** |
|
| 22 | - * for children line items (currently not a normal relation) |
|
| 23 | - * |
|
| 24 | - * @type EE_Line_Item[] |
|
| 25 | - */ |
|
| 26 | - protected $_children = array(); |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * for the parent line item |
|
| 30 | - * |
|
| 31 | - * @var EE_Line_Item |
|
| 32 | - */ |
|
| 33 | - protected $_parent; |
|
| 34 | - |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * |
|
| 39 | - * @param array $props_n_values incoming values |
|
| 40 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 41 | - * used.) |
|
| 42 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 43 | - * date_format and the second value is the time format |
|
| 44 | - * @return EE_Line_Item |
|
| 45 | - * @throws EE_Error |
|
| 46 | - */ |
|
| 47 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 48 | - { |
|
| 49 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 50 | - return $has_object |
|
| 51 | - ? $has_object |
|
| 52 | - : new self($props_n_values, false, $timezone); |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - |
|
| 56 | - |
|
| 57 | - /** |
|
| 58 | - * @param array $props_n_values incoming values from the database |
|
| 59 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 60 | - * the website will be used. |
|
| 61 | - * @return EE_Line_Item |
|
| 62 | - * @throws EE_Error |
|
| 63 | - */ |
|
| 64 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 65 | - { |
|
| 66 | - return new self($props_n_values, true, $timezone); |
|
| 67 | - } |
|
| 68 | - |
|
| 69 | - |
|
| 70 | - |
|
| 71 | - /** |
|
| 72 | - * Adds some defaults if they're not specified |
|
| 73 | - * |
|
| 74 | - * @param array $fieldValues |
|
| 75 | - * @param bool $bydb |
|
| 76 | - * @param string $timezone |
|
| 77 | - * @throws EE_Error |
|
| 78 | - */ |
|
| 79 | - protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') |
|
| 80 | - { |
|
| 81 | - parent::__construct($fieldValues, $bydb, $timezone); |
|
| 82 | - if (! $this->get('LIN_code')) { |
|
| 83 | - $this->set_code($this->generate_code()); |
|
| 84 | - } |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - |
|
| 88 | - |
|
| 89 | - /** |
|
| 90 | - * Gets ID |
|
| 91 | - * |
|
| 92 | - * @return int |
|
| 93 | - * @throws EE_Error |
|
| 94 | - */ |
|
| 95 | - public function ID() |
|
| 96 | - { |
|
| 97 | - return $this->get('LIN_ID'); |
|
| 98 | - } |
|
| 99 | - |
|
| 100 | - |
|
| 101 | - |
|
| 102 | - /** |
|
| 103 | - * Gets TXN_ID |
|
| 104 | - * |
|
| 105 | - * @return int |
|
| 106 | - * @throws EE_Error |
|
| 107 | - */ |
|
| 108 | - public function TXN_ID() |
|
| 109 | - { |
|
| 110 | - return $this->get('TXN_ID'); |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - |
|
| 114 | - |
|
| 115 | - /** |
|
| 116 | - * Sets TXN_ID |
|
| 117 | - * |
|
| 118 | - * @param int $TXN_ID |
|
| 119 | - * @throws EE_Error |
|
| 120 | - */ |
|
| 121 | - public function set_TXN_ID($TXN_ID) |
|
| 122 | - { |
|
| 123 | - $this->set('TXN_ID', $TXN_ID); |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - |
|
| 127 | - |
|
| 128 | - /** |
|
| 129 | - * Gets name |
|
| 130 | - * |
|
| 131 | - * @return string |
|
| 132 | - * @throws EE_Error |
|
| 133 | - */ |
|
| 134 | - public function name() |
|
| 135 | - { |
|
| 136 | - $name = $this->get('LIN_name'); |
|
| 137 | - if (! $name) { |
|
| 138 | - $name = ucwords(str_replace('-', ' ', $this->type())); |
|
| 139 | - } |
|
| 140 | - return $name; |
|
| 141 | - } |
|
| 142 | - |
|
| 143 | - |
|
| 144 | - |
|
| 145 | - /** |
|
| 146 | - * Sets name |
|
| 147 | - * |
|
| 148 | - * @param string $name |
|
| 149 | - * @throws EE_Error |
|
| 150 | - */ |
|
| 151 | - public function set_name($name) |
|
| 152 | - { |
|
| 153 | - $this->set('LIN_name', $name); |
|
| 154 | - } |
|
| 155 | - |
|
| 156 | - |
|
| 157 | - |
|
| 158 | - /** |
|
| 159 | - * Gets desc |
|
| 160 | - * |
|
| 161 | - * @return string |
|
| 162 | - * @throws EE_Error |
|
| 163 | - */ |
|
| 164 | - public function desc() |
|
| 165 | - { |
|
| 166 | - return $this->get('LIN_desc'); |
|
| 167 | - } |
|
| 168 | - |
|
| 169 | - |
|
| 170 | - |
|
| 171 | - /** |
|
| 172 | - * Sets desc |
|
| 173 | - * |
|
| 174 | - * @param string $desc |
|
| 175 | - * @throws EE_Error |
|
| 176 | - */ |
|
| 177 | - public function set_desc($desc) |
|
| 178 | - { |
|
| 179 | - $this->set('LIN_desc', $desc); |
|
| 180 | - } |
|
| 181 | - |
|
| 182 | - |
|
| 183 | - |
|
| 184 | - /** |
|
| 185 | - * Gets quantity |
|
| 186 | - * |
|
| 187 | - * @return int |
|
| 188 | - * @throws EE_Error |
|
| 189 | - */ |
|
| 190 | - public function quantity() |
|
| 191 | - { |
|
| 192 | - return $this->get('LIN_quantity'); |
|
| 193 | - } |
|
| 194 | - |
|
| 195 | - |
|
| 196 | - |
|
| 197 | - /** |
|
| 198 | - * Sets quantity |
|
| 199 | - * |
|
| 200 | - * @param int $quantity |
|
| 201 | - * @throws EE_Error |
|
| 202 | - */ |
|
| 203 | - public function set_quantity($quantity) |
|
| 204 | - { |
|
| 205 | - $this->set('LIN_quantity', max($quantity, 0)); |
|
| 206 | - } |
|
| 207 | - |
|
| 208 | - |
|
| 209 | - |
|
| 210 | - /** |
|
| 211 | - * Gets item_id |
|
| 212 | - * |
|
| 213 | - * @return string |
|
| 214 | - * @throws EE_Error |
|
| 215 | - */ |
|
| 216 | - public function OBJ_ID() |
|
| 217 | - { |
|
| 218 | - return $this->get('OBJ_ID'); |
|
| 219 | - } |
|
| 220 | - |
|
| 221 | - |
|
| 222 | - |
|
| 223 | - /** |
|
| 224 | - * Sets item_id |
|
| 225 | - * |
|
| 226 | - * @param string $item_id |
|
| 227 | - * @throws EE_Error |
|
| 228 | - */ |
|
| 229 | - public function set_OBJ_ID($item_id) |
|
| 230 | - { |
|
| 231 | - $this->set('OBJ_ID', $item_id); |
|
| 232 | - } |
|
| 233 | - |
|
| 234 | - |
|
| 235 | - |
|
| 236 | - /** |
|
| 237 | - * Gets item_type |
|
| 238 | - * |
|
| 239 | - * @return string |
|
| 240 | - * @throws EE_Error |
|
| 241 | - */ |
|
| 242 | - public function OBJ_type() |
|
| 243 | - { |
|
| 244 | - return $this->get('OBJ_type'); |
|
| 245 | - } |
|
| 246 | - |
|
| 247 | - |
|
| 248 | - |
|
| 249 | - /** |
|
| 250 | - * Gets item_type |
|
| 251 | - * |
|
| 252 | - * @return string |
|
| 253 | - * @throws EE_Error |
|
| 254 | - */ |
|
| 255 | - public function OBJ_type_i18n() |
|
| 256 | - { |
|
| 257 | - $obj_type = $this->OBJ_type(); |
|
| 258 | - switch ($obj_type) { |
|
| 259 | - case 'Event': |
|
| 260 | - $obj_type = __('Event', 'event_espresso'); |
|
| 261 | - break; |
|
| 262 | - case 'Price': |
|
| 263 | - $obj_type = __('Price', 'event_espresso'); |
|
| 264 | - break; |
|
| 265 | - case 'Promotion': |
|
| 266 | - $obj_type = __('Promotion', 'event_espresso'); |
|
| 267 | - break; |
|
| 268 | - case 'Ticket': |
|
| 269 | - $obj_type = __('Ticket', 'event_espresso'); |
|
| 270 | - break; |
|
| 271 | - case 'Transaction': |
|
| 272 | - $obj_type = __('Transaction', 'event_espresso'); |
|
| 273 | - break; |
|
| 274 | - } |
|
| 275 | - return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this); |
|
| 276 | - } |
|
| 277 | - |
|
| 278 | - |
|
| 279 | - |
|
| 280 | - /** |
|
| 281 | - * Sets item_type |
|
| 282 | - * |
|
| 283 | - * @param string $OBJ_type |
|
| 284 | - * @throws EE_Error |
|
| 285 | - */ |
|
| 286 | - public function set_OBJ_type($OBJ_type) |
|
| 287 | - { |
|
| 288 | - $this->set('OBJ_type', $OBJ_type); |
|
| 289 | - } |
|
| 290 | - |
|
| 291 | - |
|
| 292 | - |
|
| 293 | - /** |
|
| 294 | - * Gets unit_price |
|
| 295 | - * |
|
| 296 | - * @return float |
|
| 297 | - * @throws EE_Error |
|
| 298 | - */ |
|
| 299 | - public function unit_price() |
|
| 300 | - { |
|
| 301 | - return $this->get('LIN_unit_price'); |
|
| 302 | - } |
|
| 303 | - |
|
| 304 | - |
|
| 305 | - |
|
| 306 | - /** |
|
| 307 | - * Sets unit_price |
|
| 308 | - * |
|
| 309 | - * @param float $unit_price |
|
| 310 | - * @throws EE_Error |
|
| 311 | - */ |
|
| 312 | - public function set_unit_price($unit_price) |
|
| 313 | - { |
|
| 314 | - $this->set('LIN_unit_price', $unit_price); |
|
| 315 | - } |
|
| 316 | - |
|
| 317 | - |
|
| 318 | - |
|
| 319 | - /** |
|
| 320 | - * Checks if this item is a percentage modifier or not |
|
| 321 | - * |
|
| 322 | - * @return boolean |
|
| 323 | - * @throws EE_Error |
|
| 324 | - */ |
|
| 325 | - public function is_percent() |
|
| 326 | - { |
|
| 327 | - if ($this->is_tax_sub_total()) { |
|
| 328 | - //tax subtotals HAVE a percent on them, that percentage only applies |
|
| 329 | - //to taxable items, so its' an exception. Treat it like a flat line item |
|
| 330 | - return false; |
|
| 331 | - } |
|
| 332 | - $unit_price = abs($this->get('LIN_unit_price')); |
|
| 333 | - $percent = abs($this->get('LIN_percent')); |
|
| 334 | - if ($unit_price < .001 && $percent) { |
|
| 335 | - return true; |
|
| 336 | - } |
|
| 337 | - if ($unit_price >= .001 && ! $percent) { |
|
| 338 | - return false; |
|
| 339 | - } |
|
| 340 | - if ($unit_price >= .001 && $percent) { |
|
| 341 | - throw new EE_Error( |
|
| 342 | - sprintf( |
|
| 343 | - esc_html__('A Line Item can not have a unit price of (%s) AND a percent (%s)!', 'event_espresso'), |
|
| 344 | - $unit_price, $percent |
|
| 345 | - ) |
|
| 346 | - ); |
|
| 347 | - } |
|
| 348 | - // if they're both 0, assume its not a percent item |
|
| 349 | - return false; |
|
| 350 | - } |
|
| 351 | - |
|
| 352 | - |
|
| 353 | - |
|
| 354 | - /** |
|
| 355 | - * Gets percent (between 100-.001) |
|
| 356 | - * |
|
| 357 | - * @return float |
|
| 358 | - * @throws EE_Error |
|
| 359 | - */ |
|
| 360 | - public function percent() |
|
| 361 | - { |
|
| 362 | - return $this->get('LIN_percent'); |
|
| 363 | - } |
|
| 364 | - |
|
| 365 | - |
|
| 366 | - |
|
| 367 | - /** |
|
| 368 | - * Sets percent (between 100-0.01) |
|
| 369 | - * |
|
| 370 | - * @param float $percent |
|
| 371 | - * @throws EE_Error |
|
| 372 | - */ |
|
| 373 | - public function set_percent($percent) |
|
| 374 | - { |
|
| 375 | - $this->set('LIN_percent', $percent); |
|
| 376 | - } |
|
| 377 | - |
|
| 378 | - |
|
| 379 | - |
|
| 380 | - /** |
|
| 381 | - * Gets total |
|
| 382 | - * |
|
| 383 | - * @return float |
|
| 384 | - * @throws EE_Error |
|
| 385 | - */ |
|
| 386 | - public function total() |
|
| 387 | - { |
|
| 388 | - return $this->get('LIN_total'); |
|
| 389 | - } |
|
| 390 | - |
|
| 391 | - |
|
| 392 | - |
|
| 393 | - /** |
|
| 394 | - * Sets total |
|
| 395 | - * |
|
| 396 | - * @param float $total |
|
| 397 | - * @throws EE_Error |
|
| 398 | - */ |
|
| 399 | - public function set_total($total) |
|
| 400 | - { |
|
| 401 | - $this->set('LIN_total', $total); |
|
| 402 | - } |
|
| 403 | - |
|
| 404 | - |
|
| 405 | - |
|
| 406 | - /** |
|
| 407 | - * Gets order |
|
| 408 | - * |
|
| 409 | - * @return int |
|
| 410 | - * @throws EE_Error |
|
| 411 | - */ |
|
| 412 | - public function order() |
|
| 413 | - { |
|
| 414 | - return $this->get('LIN_order'); |
|
| 415 | - } |
|
| 416 | - |
|
| 417 | - |
|
| 418 | - |
|
| 419 | - /** |
|
| 420 | - * Sets order |
|
| 421 | - * |
|
| 422 | - * @param int $order |
|
| 423 | - * @throws EE_Error |
|
| 424 | - */ |
|
| 425 | - public function set_order($order) |
|
| 426 | - { |
|
| 427 | - $this->set('LIN_order', $order); |
|
| 428 | - } |
|
| 429 | - |
|
| 430 | - |
|
| 431 | - |
|
| 432 | - /** |
|
| 433 | - * Gets parent |
|
| 434 | - * |
|
| 435 | - * @return int |
|
| 436 | - * @throws EE_Error |
|
| 437 | - */ |
|
| 438 | - public function parent_ID() |
|
| 439 | - { |
|
| 440 | - return $this->get('LIN_parent'); |
|
| 441 | - } |
|
| 442 | - |
|
| 443 | - |
|
| 444 | - |
|
| 445 | - /** |
|
| 446 | - * Sets parent |
|
| 447 | - * |
|
| 448 | - * @param int $parent |
|
| 449 | - * @throws EE_Error |
|
| 450 | - */ |
|
| 451 | - public function set_parent_ID($parent) |
|
| 452 | - { |
|
| 453 | - $this->set('LIN_parent', $parent); |
|
| 454 | - } |
|
| 455 | - |
|
| 456 | - |
|
| 457 | - |
|
| 458 | - /** |
|
| 459 | - * Gets type |
|
| 460 | - * |
|
| 461 | - * @return string |
|
| 462 | - * @throws EE_Error |
|
| 463 | - */ |
|
| 464 | - public function type() |
|
| 465 | - { |
|
| 466 | - return $this->get('LIN_type'); |
|
| 467 | - } |
|
| 468 | - |
|
| 469 | - |
|
| 470 | - |
|
| 471 | - /** |
|
| 472 | - * Sets type |
|
| 473 | - * |
|
| 474 | - * @param string $type |
|
| 475 | - * @throws EE_Error |
|
| 476 | - */ |
|
| 477 | - public function set_type($type) |
|
| 478 | - { |
|
| 479 | - $this->set('LIN_type', $type); |
|
| 480 | - } |
|
| 481 | - |
|
| 482 | - |
|
| 483 | - |
|
| 484 | - /** |
|
| 485 | - * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\ |
|
| 486 | - * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB |
|
| 487 | - * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()` |
|
| 488 | - * or indirectly by `EE_Line_item::add_child_line_item()`) |
|
| 489 | - * |
|
| 490 | - * @return EE_Base_Class|EE_Line_Item |
|
| 491 | - * @throws EE_Error |
|
| 492 | - */ |
|
| 493 | - public function parent() |
|
| 494 | - { |
|
| 495 | - return $this->ID() |
|
| 496 | - ? $this->get_model()->get_one_by_ID($this->parent_ID()) |
|
| 497 | - : $this->_parent; |
|
| 498 | - } |
|
| 499 | - |
|
| 500 | - |
|
| 501 | - |
|
| 502 | - /** |
|
| 503 | - * Gets ALL the children of this line item (ie, all the parts that contribute towards this total). |
|
| 504 | - * |
|
| 505 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 506 | - * @throws EE_Error |
|
| 507 | - */ |
|
| 508 | - public function children() |
|
| 509 | - { |
|
| 510 | - if ($this->ID()) { |
|
| 511 | - return $this->get_model()->get_all( |
|
| 512 | - array( |
|
| 513 | - array('LIN_parent' => $this->ID()), |
|
| 514 | - 'order_by' => array('LIN_order' => 'ASC'), |
|
| 515 | - ) |
|
| 516 | - ); |
|
| 517 | - } |
|
| 518 | - if (! is_array($this->_children)) { |
|
| 519 | - $this->_children = array(); |
|
| 520 | - } |
|
| 521 | - return $this->_children; |
|
| 522 | - } |
|
| 523 | - |
|
| 524 | - |
|
| 525 | - |
|
| 526 | - /** |
|
| 527 | - * Gets code |
|
| 528 | - * |
|
| 529 | - * @return string |
|
| 530 | - * @throws EE_Error |
|
| 531 | - */ |
|
| 532 | - public function code() |
|
| 533 | - { |
|
| 534 | - return $this->get('LIN_code'); |
|
| 535 | - } |
|
| 536 | - |
|
| 537 | - |
|
| 538 | - |
|
| 539 | - /** |
|
| 540 | - * Sets code |
|
| 541 | - * |
|
| 542 | - * @param string $code |
|
| 543 | - * @throws EE_Error |
|
| 544 | - */ |
|
| 545 | - public function set_code($code) |
|
| 546 | - { |
|
| 547 | - $this->set('LIN_code', $code); |
|
| 548 | - } |
|
| 549 | - |
|
| 550 | - |
|
| 551 | - |
|
| 552 | - /** |
|
| 553 | - * Gets is_taxable |
|
| 554 | - * |
|
| 555 | - * @return boolean |
|
| 556 | - * @throws EE_Error |
|
| 557 | - */ |
|
| 558 | - public function is_taxable() |
|
| 559 | - { |
|
| 560 | - return $this->get('LIN_is_taxable'); |
|
| 561 | - } |
|
| 562 | - |
|
| 563 | - |
|
| 564 | - |
|
| 565 | - /** |
|
| 566 | - * Sets is_taxable |
|
| 567 | - * |
|
| 568 | - * @param boolean $is_taxable |
|
| 569 | - * @throws EE_Error |
|
| 570 | - */ |
|
| 571 | - public function set_is_taxable($is_taxable) |
|
| 572 | - { |
|
| 573 | - $this->set('LIN_is_taxable', $is_taxable); |
|
| 574 | - } |
|
| 575 | - |
|
| 576 | - |
|
| 577 | - |
|
| 578 | - /** |
|
| 579 | - * Gets the object that this model-joins-to. |
|
| 580 | - * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on |
|
| 581 | - * EEM_Promotion_Object |
|
| 582 | - * |
|
| 583 | - * Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object |
|
| 584 | - * |
|
| 585 | - * @return EE_Base_Class | NULL |
|
| 586 | - * @throws EE_Error |
|
| 587 | - */ |
|
| 588 | - public function get_object() |
|
| 589 | - { |
|
| 590 | - $model_name_of_related_obj = $this->OBJ_type(); |
|
| 591 | - return $this->get_model()->has_relation($model_name_of_related_obj) |
|
| 592 | - ? $this->get_first_related($model_name_of_related_obj) |
|
| 593 | - : null; |
|
| 594 | - } |
|
| 595 | - |
|
| 596 | - |
|
| 597 | - |
|
| 598 | - /** |
|
| 599 | - * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket. |
|
| 600 | - * (IE, if this line item is for a price or something else, will return NULL) |
|
| 601 | - * |
|
| 602 | - * @param array $query_params |
|
| 603 | - * @return EE_Base_Class|EE_Ticket |
|
| 604 | - * @throws EE_Error |
|
| 605 | - */ |
|
| 606 | - public function ticket($query_params = array()) |
|
| 607 | - { |
|
| 608 | - //we're going to assume that when this method is called we always want to receive the attached ticket EVEN if that ticket is archived. This can be overridden via the incoming $query_params argument |
|
| 609 | - $remove_defaults = array('default_where_conditions' => 'none'); |
|
| 610 | - $query_params = array_merge($remove_defaults, $query_params); |
|
| 611 | - return $this->get_first_related('Ticket', $query_params); |
|
| 612 | - } |
|
| 613 | - |
|
| 614 | - |
|
| 615 | - |
|
| 616 | - /** |
|
| 617 | - * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket |
|
| 618 | - * |
|
| 619 | - * @return EE_Datetime | NULL |
|
| 620 | - * @throws EE_Error |
|
| 621 | - */ |
|
| 622 | - public function get_ticket_datetime() |
|
| 623 | - { |
|
| 624 | - if ($this->OBJ_type() === 'Ticket') { |
|
| 625 | - $ticket = $this->ticket(); |
|
| 626 | - if ($ticket instanceof EE_Ticket) { |
|
| 627 | - $datetime = $ticket->first_datetime(); |
|
| 628 | - if ($datetime instanceof EE_Datetime) { |
|
| 629 | - return $datetime; |
|
| 630 | - } |
|
| 631 | - } |
|
| 632 | - } |
|
| 633 | - return null; |
|
| 634 | - } |
|
| 635 | - |
|
| 636 | - |
|
| 637 | - |
|
| 638 | - /** |
|
| 639 | - * Gets the event's name that's related to the ticket, if this is for |
|
| 640 | - * a ticket |
|
| 641 | - * |
|
| 642 | - * @return string |
|
| 643 | - * @throws EE_Error |
|
| 644 | - */ |
|
| 645 | - public function ticket_event_name() |
|
| 646 | - { |
|
| 647 | - $event_name = esc_html__('Unknown', 'event_espresso'); |
|
| 648 | - $event = $this->ticket_event(); |
|
| 649 | - if ($event instanceof EE_Event) { |
|
| 650 | - $event_name = $event->name(); |
|
| 651 | - } |
|
| 652 | - return $event_name; |
|
| 653 | - } |
|
| 654 | - |
|
| 655 | - |
|
| 656 | - /** |
|
| 657 | - * Gets the event that's related to the ticket, if this line item represents a ticket. |
|
| 658 | - * |
|
| 659 | - * @return EE_Event|null |
|
| 660 | - * @throws EE_Error |
|
| 661 | - */ |
|
| 662 | - public function ticket_event() |
|
| 663 | - { |
|
| 664 | - $event = null; |
|
| 665 | - $ticket = $this->ticket(); |
|
| 666 | - if ($ticket instanceof EE_Ticket) { |
|
| 667 | - $datetime = $ticket->first_datetime(); |
|
| 668 | - if ($datetime instanceof EE_Datetime) { |
|
| 669 | - $event = $datetime->event(); |
|
| 670 | - } |
|
| 671 | - } |
|
| 672 | - return $event; |
|
| 673 | - } |
|
| 674 | - |
|
| 675 | - |
|
| 676 | - |
|
| 677 | - /** |
|
| 678 | - * Gets the first datetime for this lien item, assuming it's for a ticket |
|
| 679 | - * |
|
| 680 | - * @param string $date_format |
|
| 681 | - * @param string $time_format |
|
| 682 | - * @return string |
|
| 683 | - * @throws EE_Error |
|
| 684 | - */ |
|
| 685 | - public function ticket_datetime_start($date_format = '', $time_format = '') |
|
| 686 | - { |
|
| 687 | - $first_datetime_string = esc_html__('Unknown', 'event_espresso'); |
|
| 688 | - $datetime = $this->get_ticket_datetime(); |
|
| 689 | - if ($datetime) { |
|
| 690 | - $first_datetime_string = $datetime->start_date_and_time($date_format, $time_format); |
|
| 691 | - } |
|
| 692 | - return $first_datetime_string; |
|
| 693 | - } |
|
| 694 | - |
|
| 695 | - |
|
| 696 | - |
|
| 697 | - /** |
|
| 698 | - * Adds the line item as a child to this line item. If there is another child line |
|
| 699 | - * item with the same LIN_code, it is overwritten by this new one |
|
| 700 | - * |
|
| 701 | - * @param EEI_Line_Item $line_item |
|
| 702 | - * @param bool $set_order |
|
| 703 | - * @return bool success |
|
| 704 | - * @throws EE_Error |
|
| 705 | - */ |
|
| 706 | - public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true) |
|
| 707 | - { |
|
| 708 | - // should we calculate the LIN_order for this line item ? |
|
| 709 | - if ($set_order || $line_item->order() === null) { |
|
| 710 | - $line_item->set_order(count($this->children())); |
|
| 711 | - } |
|
| 712 | - if ($this->ID()) { |
|
| 713 | - //check for any duplicate line items (with the same code), if so, this replaces it |
|
| 714 | - $line_item_with_same_code = $this->get_child_line_item($line_item->code()); |
|
| 715 | - if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) { |
|
| 716 | - $this->delete_child_line_item($line_item_with_same_code->code()); |
|
| 717 | - } |
|
| 718 | - $line_item->set_parent_ID($this->ID()); |
|
| 719 | - if ($this->TXN_ID()) { |
|
| 720 | - $line_item->set_TXN_ID($this->TXN_ID()); |
|
| 721 | - } |
|
| 722 | - return $line_item->save(); |
|
| 723 | - } |
|
| 724 | - $this->_children[$line_item->code()] = $line_item; |
|
| 725 | - if ($line_item->parent() !== $this) { |
|
| 726 | - $line_item->set_parent($this); |
|
| 727 | - } |
|
| 728 | - return true; |
|
| 729 | - } |
|
| 730 | - |
|
| 731 | - |
|
| 732 | - /** |
|
| 733 | - * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation. |
|
| 734 | - * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save() |
|
| 735 | - * However, if this line item is NOT saved to the DB, this just caches the parent on |
|
| 736 | - * the EE_Line_Item::_parent property. |
|
| 737 | - * |
|
| 738 | - * @param EE_Line_Item $line_item |
|
| 739 | - * @throws EE_Error |
|
| 740 | - */ |
|
| 741 | - public function set_parent($line_item) |
|
| 742 | - { |
|
| 743 | - if ($this->ID()) { |
|
| 744 | - if (! $line_item->ID()) { |
|
| 745 | - $line_item->save(); |
|
| 746 | - } |
|
| 747 | - $this->set_parent_ID($line_item->ID()); |
|
| 748 | - $this->save(); |
|
| 749 | - } else { |
|
| 750 | - $this->_parent = $line_item; |
|
| 751 | - $this->set_parent_ID($line_item->ID()); |
|
| 752 | - } |
|
| 753 | - } |
|
| 754 | - |
|
| 755 | - |
|
| 756 | - |
|
| 757 | - /** |
|
| 758 | - * Gets the child line item as specified by its code. Because this returns an object (by reference) |
|
| 759 | - * you can modify this child line item and the parent (this object) can know about them |
|
| 760 | - * because it also has a reference to that line item |
|
| 761 | - * |
|
| 762 | - * @param string $code |
|
| 763 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 764 | - * @throws EE_Error |
|
| 765 | - */ |
|
| 766 | - public function get_child_line_item($code) |
|
| 767 | - { |
|
| 768 | - if ($this->ID()) { |
|
| 769 | - return $this->get_model()->get_one( |
|
| 770 | - array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code)) |
|
| 771 | - ); |
|
| 772 | - } |
|
| 773 | - return isset($this->_children[$code]) |
|
| 774 | - ? $this->_children[$code] |
|
| 775 | - : null; |
|
| 776 | - } |
|
| 777 | - |
|
| 778 | - |
|
| 779 | - |
|
| 780 | - /** |
|
| 781 | - * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD |
|
| 782 | - * cached on it) |
|
| 783 | - * |
|
| 784 | - * @return int |
|
| 785 | - * @throws EE_Error |
|
| 786 | - */ |
|
| 787 | - public function delete_children_line_items() |
|
| 788 | - { |
|
| 789 | - if ($this->ID()) { |
|
| 790 | - return $this->get_model()->delete(array(array('LIN_parent' => $this->ID()))); |
|
| 791 | - } |
|
| 792 | - $count = count($this->_children); |
|
| 793 | - $this->_children = array(); |
|
| 794 | - return $count; |
|
| 795 | - } |
|
| 796 | - |
|
| 797 | - |
|
| 798 | - |
|
| 799 | - /** |
|
| 800 | - * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line |
|
| 801 | - * HAS NOT been saved to the DB, removes the child line item with index $code. |
|
| 802 | - * Also searches through the child's children for a matching line item. However, once a line item has been found |
|
| 803 | - * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be |
|
| 804 | - * deleted) |
|
| 805 | - * |
|
| 806 | - * @param string $code |
|
| 807 | - * @param bool $stop_search_once_found |
|
| 808 | - * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to |
|
| 809 | - * the DB yet) |
|
| 810 | - * @throws EE_Error |
|
| 811 | - */ |
|
| 812 | - public function delete_child_line_item($code, $stop_search_once_found = true) |
|
| 813 | - { |
|
| 814 | - if ($this->ID()) { |
|
| 815 | - $items_deleted = 0; |
|
| 816 | - if ($this->code() === $code) { |
|
| 817 | - $items_deleted += EEH_Line_Item::delete_all_child_items($this); |
|
| 818 | - $items_deleted += (int)$this->delete(); |
|
| 819 | - if ($stop_search_once_found) { |
|
| 820 | - return $items_deleted; |
|
| 821 | - } |
|
| 822 | - } |
|
| 823 | - foreach ($this->children() as $child_line_item) { |
|
| 824 | - $items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found); |
|
| 825 | - } |
|
| 826 | - return $items_deleted; |
|
| 827 | - } |
|
| 828 | - if (isset($this->_children[$code])) { |
|
| 829 | - unset($this->_children[$code]); |
|
| 830 | - return 1; |
|
| 831 | - } |
|
| 832 | - return 0; |
|
| 833 | - } |
|
| 834 | - |
|
| 835 | - |
|
| 836 | - /** |
|
| 837 | - * If this line item is in the database, is of the type subtotal, and |
|
| 838 | - * has no children, why do we have it? It should be deleted so this function |
|
| 839 | - * does that |
|
| 840 | - * |
|
| 841 | - * @return boolean |
|
| 842 | - * @throws EE_Error |
|
| 843 | - */ |
|
| 844 | - public function delete_if_childless_subtotal() |
|
| 845 | - { |
|
| 846 | - if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) { |
|
| 847 | - return $this->delete(); |
|
| 848 | - } |
|
| 849 | - return false; |
|
| 850 | - } |
|
| 851 | - |
|
| 852 | - |
|
| 853 | - |
|
| 854 | - /** |
|
| 855 | - * Creates a code and returns a string. doesn't assign the code to this model object |
|
| 856 | - * |
|
| 857 | - * @return string |
|
| 858 | - * @throws EE_Error |
|
| 859 | - */ |
|
| 860 | - public function generate_code() |
|
| 861 | - { |
|
| 862 | - // each line item in the cart requires a unique identifier |
|
| 863 | - return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime()); |
|
| 864 | - } |
|
| 865 | - |
|
| 866 | - |
|
| 867 | - |
|
| 868 | - /** |
|
| 869 | - * @return bool |
|
| 870 | - * @throws EE_Error |
|
| 871 | - */ |
|
| 872 | - public function is_tax() |
|
| 873 | - { |
|
| 874 | - return $this->type() === EEM_Line_Item::type_tax; |
|
| 875 | - } |
|
| 876 | - |
|
| 877 | - |
|
| 878 | - |
|
| 879 | - /** |
|
| 880 | - * @return bool |
|
| 881 | - * @throws EE_Error |
|
| 882 | - */ |
|
| 883 | - public function is_tax_sub_total() |
|
| 884 | - { |
|
| 885 | - return $this->type() === EEM_Line_Item::type_tax_sub_total; |
|
| 886 | - } |
|
| 887 | - |
|
| 888 | - |
|
| 889 | - |
|
| 890 | - /** |
|
| 891 | - * @return bool |
|
| 892 | - * @throws EE_Error |
|
| 893 | - */ |
|
| 894 | - public function is_line_item() |
|
| 895 | - { |
|
| 896 | - return $this->type() === EEM_Line_Item::type_line_item; |
|
| 897 | - } |
|
| 898 | - |
|
| 899 | - |
|
| 900 | - |
|
| 901 | - /** |
|
| 902 | - * @return bool |
|
| 903 | - * @throws EE_Error |
|
| 904 | - */ |
|
| 905 | - public function is_sub_line_item() |
|
| 906 | - { |
|
| 907 | - return $this->type() === EEM_Line_Item::type_sub_line_item; |
|
| 908 | - } |
|
| 909 | - |
|
| 910 | - |
|
| 911 | - |
|
| 912 | - /** |
|
| 913 | - * @return bool |
|
| 914 | - * @throws EE_Error |
|
| 915 | - */ |
|
| 916 | - public function is_sub_total() |
|
| 917 | - { |
|
| 918 | - return $this->type() === EEM_Line_Item::type_sub_total; |
|
| 919 | - } |
|
| 920 | - |
|
| 921 | - |
|
| 922 | - |
|
| 923 | - /** |
|
| 924 | - * Whether or not this line item is a cancellation line item |
|
| 925 | - * |
|
| 926 | - * @return boolean |
|
| 927 | - * @throws EE_Error |
|
| 928 | - */ |
|
| 929 | - public function is_cancellation() |
|
| 930 | - { |
|
| 931 | - return EEM_Line_Item::type_cancellation === $this->type(); |
|
| 932 | - } |
|
| 933 | - |
|
| 934 | - |
|
| 935 | - |
|
| 936 | - /** |
|
| 937 | - * @return bool |
|
| 938 | - * @throws EE_Error |
|
| 939 | - */ |
|
| 940 | - public function is_total() |
|
| 941 | - { |
|
| 942 | - return $this->type() === EEM_Line_Item::type_total; |
|
| 943 | - } |
|
| 944 | - |
|
| 945 | - |
|
| 946 | - |
|
| 947 | - /** |
|
| 948 | - * @return bool |
|
| 949 | - * @throws EE_Error |
|
| 950 | - */ |
|
| 951 | - public function is_cancelled() |
|
| 952 | - { |
|
| 953 | - return $this->type() === EEM_Line_Item::type_cancellation; |
|
| 954 | - } |
|
| 955 | - |
|
| 956 | - |
|
| 957 | - |
|
| 958 | - /** |
|
| 959 | - * @return string like '2, 004.00', formatted according to the localized currency |
|
| 960 | - * @throws EE_Error |
|
| 961 | - */ |
|
| 962 | - public function unit_price_no_code() |
|
| 963 | - { |
|
| 964 | - return $this->get_pretty('LIN_unit_price', 'no_currency_code'); |
|
| 965 | - } |
|
| 966 | - |
|
| 967 | - |
|
| 968 | - |
|
| 969 | - /** |
|
| 970 | - * @return string like '2, 004.00', formatted according to the localized currency |
|
| 971 | - * @throws EE_Error |
|
| 972 | - */ |
|
| 973 | - public function total_no_code() |
|
| 974 | - { |
|
| 975 | - return $this->get_pretty('LIN_total', 'no_currency_code'); |
|
| 976 | - } |
|
| 977 | - |
|
| 978 | - |
|
| 979 | - |
|
| 980 | - /** |
|
| 981 | - * Gets the final total on this item, taking taxes into account. |
|
| 982 | - * Has the side-effect of setting the sub-total as it was just calculated. |
|
| 983 | - * If this is used on a grand-total line item, also updates the transaction's |
|
| 984 | - * TXN_total (provided this line item is allowed to persist, otherwise we don't |
|
| 985 | - * want to change a persistable transaction with info from a non-persistent line item) |
|
| 986 | - * |
|
| 987 | - * @return float |
|
| 988 | - * @throws EE_Error |
|
| 989 | - * @throws InvalidArgumentException |
|
| 990 | - * @throws InvalidInterfaceException |
|
| 991 | - * @throws InvalidDataTypeException |
|
| 992 | - */ |
|
| 993 | - public function recalculate_total_including_taxes() |
|
| 994 | - { |
|
| 995 | - $pre_tax_total = $this->recalculate_pre_tax_total(); |
|
| 996 | - $tax_total = $this->recalculate_taxes_and_tax_total(); |
|
| 997 | - $total = $pre_tax_total + $tax_total; |
|
| 998 | - // no negative totals plz |
|
| 999 | - $total = max($total, 0); |
|
| 1000 | - $this->set_total($total); |
|
| 1001 | - //only update the related transaction's total |
|
| 1002 | - //if we intend to save this line item and its a grand total |
|
| 1003 | - if ( |
|
| 1004 | - $this->allow_persist() && $this->type() === EEM_Line_Item::type_total |
|
| 1005 | - && $this->transaction() |
|
| 1006 | - instanceof |
|
| 1007 | - EE_Transaction |
|
| 1008 | - ) { |
|
| 1009 | - $this->transaction()->set_total($total); |
|
| 1010 | - if ($this->transaction()->ID()) { |
|
| 1011 | - $this->transaction()->save(); |
|
| 1012 | - } |
|
| 1013 | - } |
|
| 1014 | - $this->maybe_save(); |
|
| 1015 | - return $total; |
|
| 1016 | - } |
|
| 1017 | - |
|
| 1018 | - |
|
| 1019 | - /** |
|
| 1020 | - * Recursively goes through all the children and recalculates sub-totals EXCEPT for |
|
| 1021 | - * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its |
|
| 1022 | - * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and |
|
| 1023 | - * when this is called on the grand total |
|
| 1024 | - * |
|
| 1025 | - * @return float |
|
| 1026 | - * @throws InvalidArgumentException |
|
| 1027 | - * @throws InvalidInterfaceException |
|
| 1028 | - * @throws InvalidDataTypeException |
|
| 1029 | - * @throws EE_Error |
|
| 1030 | - */ |
|
| 1031 | - public function recalculate_pre_tax_total() |
|
| 1032 | - { |
|
| 1033 | - $total = 0; |
|
| 1034 | - $my_children = $this->children(); |
|
| 1035 | - $has_children = ! empty($my_children); |
|
| 1036 | - if ($has_children && $this->is_line_item()) { |
|
| 1037 | - $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children); |
|
| 1038 | - } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
| 1039 | - $total = $this->unit_price() * $this->quantity(); |
|
| 1040 | - } elseif ($this->is_sub_total() || $this->is_total()) { |
|
| 1041 | - $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children); |
|
| 1042 | - } elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) { |
|
| 1043 | - // completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total |
|
| 1044 | - return 0; |
|
| 1045 | - } |
|
| 1046 | - // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events) |
|
| 1047 | - if ( |
|
| 1048 | - ! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation() |
|
| 1049 | - ) { |
|
| 1050 | - if ($this->OBJ_type() !== 'Event') { |
|
| 1051 | - $this->set_quantity(1); |
|
| 1052 | - } |
|
| 1053 | - if (! $this->is_percent()) { |
|
| 1054 | - $this->set_unit_price($total); |
|
| 1055 | - } |
|
| 1056 | - } |
|
| 1057 | - //we don't want to bother saving grand totals, because that needs to factor in taxes anyways |
|
| 1058 | - //so it ought to be |
|
| 1059 | - if (! $this->is_total()) { |
|
| 1060 | - $this->set_total($total); |
|
| 1061 | - //if not a percent line item, make sure we keep the unit price in sync |
|
| 1062 | - if ( |
|
| 1063 | - $has_children |
|
| 1064 | - && $this->is_line_item() |
|
| 1065 | - && ! $this->is_percent() |
|
| 1066 | - ) { |
|
| 1067 | - if ($this->quantity() === 0) { |
|
| 1068 | - $new_unit_price = 0; |
|
| 1069 | - } else { |
|
| 1070 | - $new_unit_price = $this->total() / $this->quantity(); |
|
| 1071 | - } |
|
| 1072 | - $this->set_unit_price($new_unit_price); |
|
| 1073 | - } |
|
| 1074 | - $this->maybe_save(); |
|
| 1075 | - } |
|
| 1076 | - return $total; |
|
| 1077 | - } |
|
| 1078 | - |
|
| 1079 | - |
|
| 1080 | - |
|
| 1081 | - /** |
|
| 1082 | - * Calculates the pretax total when this line item is a subtotal or total line item. |
|
| 1083 | - * Basically does a sum-then-round approach (ie, any percent line item that are children |
|
| 1084 | - * will calculate their total based on the un-rounded total we're working with so far, and |
|
| 1085 | - * THEN round the result; instead of rounding as we go like with sub-line-items) |
|
| 1086 | - * |
|
| 1087 | - * @param float $calculated_total_so_far |
|
| 1088 | - * @param EE_Line_Item[] $my_children |
|
| 1089 | - * @return float |
|
| 1090 | - * @throws InvalidArgumentException |
|
| 1091 | - * @throws InvalidInterfaceException |
|
| 1092 | - * @throws InvalidDataTypeException |
|
| 1093 | - * @throws EE_Error |
|
| 1094 | - */ |
|
| 1095 | - protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null) |
|
| 1096 | - { |
|
| 1097 | - if ($my_children === null) { |
|
| 1098 | - $my_children = $this->children(); |
|
| 1099 | - } |
|
| 1100 | - //get the total of all its children |
|
| 1101 | - foreach ($my_children as $child_line_item) { |
|
| 1102 | - if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) { |
|
| 1103 | - // percentage line items are based on total so far |
|
| 1104 | - if ($child_line_item->is_percent()) { |
|
| 1105 | - //round as we go so that the line items add up ok |
|
| 1106 | - $percent_total = round( |
|
| 1107 | - $calculated_total_so_far * $child_line_item->percent() / 100, |
|
| 1108 | - EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1109 | - ); |
|
| 1110 | - $child_line_item->set_total($percent_total); |
|
| 1111 | - //so far all percent line items should have a quantity of 1 |
|
| 1112 | - //(ie, no double percent discounts. Although that might be requested someday) |
|
| 1113 | - $child_line_item->set_quantity(1); |
|
| 1114 | - $child_line_item->maybe_save(); |
|
| 1115 | - $calculated_total_so_far += $percent_total; |
|
| 1116 | - } else { |
|
| 1117 | - //verify flat sub-line-item quantities match their parent |
|
| 1118 | - if ($child_line_item->is_sub_line_item()) { |
|
| 1119 | - $child_line_item->set_quantity($this->quantity()); |
|
| 1120 | - } |
|
| 1121 | - $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1122 | - } |
|
| 1123 | - } |
|
| 1124 | - } |
|
| 1125 | - if ($this->is_sub_total()) { |
|
| 1126 | - // no negative totals plz |
|
| 1127 | - $calculated_total_so_far = max($calculated_total_so_far, 0); |
|
| 1128 | - } |
|
| 1129 | - return $calculated_total_so_far; |
|
| 1130 | - } |
|
| 1131 | - |
|
| 1132 | - |
|
| 1133 | - |
|
| 1134 | - /** |
|
| 1135 | - * Calculates the pretax total for a normal line item, in a round-then-sum approach |
|
| 1136 | - * (where each sub-line-item is applied to the base price for the line item |
|
| 1137 | - * and the result is immediately rounded, rather than summing all the sub-line-items |
|
| 1138 | - * then rounding, like we do when recalculating pretax totals on totals and subtotals). |
|
| 1139 | - * |
|
| 1140 | - * @param float $calculated_total_so_far |
|
| 1141 | - * @param EE_Line_Item[] $my_children |
|
| 1142 | - * @return float |
|
| 1143 | - * @throws InvalidArgumentException |
|
| 1144 | - * @throws InvalidInterfaceException |
|
| 1145 | - * @throws InvalidDataTypeException |
|
| 1146 | - * @throws EE_Error |
|
| 1147 | - */ |
|
| 1148 | - protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null) |
|
| 1149 | - { |
|
| 1150 | - if ($my_children === null) { |
|
| 1151 | - $my_children = $this->children(); |
|
| 1152 | - } |
|
| 1153 | - //we need to keep track of the running total for a single item, |
|
| 1154 | - //because we need to round as we go |
|
| 1155 | - $unit_price_for_total = 0; |
|
| 1156 | - $quantity_for_total = 1; |
|
| 1157 | - //get the total of all its children |
|
| 1158 | - foreach ($my_children as $child_line_item) { |
|
| 1159 | - if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) { |
|
| 1160 | - if ($child_line_item->is_percent()) { |
|
| 1161 | - //it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity |
|
| 1162 | - //not total multiplied by percent, because that ignores rounding along-the-way |
|
| 1163 | - $percent_unit_price = round( |
|
| 1164 | - $unit_price_for_total * $child_line_item->percent() / 100, |
|
| 1165 | - EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1166 | - ); |
|
| 1167 | - $percent_total = $percent_unit_price * $quantity_for_total; |
|
| 1168 | - $child_line_item->set_total($percent_total); |
|
| 1169 | - //so far all percent line items should have a quantity of 1 |
|
| 1170 | - //(ie, no double percent discounts. Although that might be requested someday) |
|
| 1171 | - $child_line_item->set_quantity(1); |
|
| 1172 | - $child_line_item->maybe_save(); |
|
| 1173 | - $calculated_total_so_far += $percent_total; |
|
| 1174 | - $unit_price_for_total += $percent_unit_price; |
|
| 1175 | - } else { |
|
| 1176 | - //verify flat sub-line-item quantities match their parent |
|
| 1177 | - if ($child_line_item->is_sub_line_item()) { |
|
| 1178 | - $child_line_item->set_quantity($this->quantity()); |
|
| 1179 | - } |
|
| 1180 | - $quantity_for_total = $child_line_item->quantity(); |
|
| 1181 | - $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1182 | - $unit_price_for_total += $child_line_item->unit_price(); |
|
| 1183 | - } |
|
| 1184 | - } |
|
| 1185 | - } |
|
| 1186 | - return $calculated_total_so_far; |
|
| 1187 | - } |
|
| 1188 | - |
|
| 1189 | - |
|
| 1190 | - |
|
| 1191 | - /** |
|
| 1192 | - * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets |
|
| 1193 | - * the totals on each tax calculated, and returns the final tax total |
|
| 1194 | - * |
|
| 1195 | - * @return float |
|
| 1196 | - * @throws EE_Error |
|
| 1197 | - */ |
|
| 1198 | - public function recalculate_taxes_and_tax_total() |
|
| 1199 | - { |
|
| 1200 | - //get all taxes |
|
| 1201 | - $taxes = $this->tax_descendants(); |
|
| 1202 | - //calculate the pretax total |
|
| 1203 | - $taxable_total = $this->taxable_total(); |
|
| 1204 | - $tax_total = 0; |
|
| 1205 | - foreach ($taxes as $tax) { |
|
| 1206 | - $total_on_this_tax = $taxable_total * $tax->percent() / 100; |
|
| 1207 | - //remember the total on this line item |
|
| 1208 | - $tax->set_total($total_on_this_tax); |
|
| 1209 | - $tax_total += $tax->total(); |
|
| 1210 | - } |
|
| 1211 | - $this->_recalculate_tax_sub_total(); |
|
| 1212 | - return $tax_total; |
|
| 1213 | - } |
|
| 1214 | - |
|
| 1215 | - |
|
| 1216 | - |
|
| 1217 | - /** |
|
| 1218 | - * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated |
|
| 1219 | - * |
|
| 1220 | - * @return void |
|
| 1221 | - * @throws EE_Error |
|
| 1222 | - */ |
|
| 1223 | - private function _recalculate_tax_sub_total() |
|
| 1224 | - { |
|
| 1225 | - if ($this->is_tax_sub_total()) { |
|
| 1226 | - $total = 0; |
|
| 1227 | - $total_percent = 0; |
|
| 1228 | - //simply loop through all its children (which should be taxes) and sum their total |
|
| 1229 | - foreach ($this->children() as $child_tax) { |
|
| 1230 | - if ($child_tax instanceof EE_Line_Item) { |
|
| 1231 | - $total += $child_tax->total(); |
|
| 1232 | - $total_percent += $child_tax->percent(); |
|
| 1233 | - } |
|
| 1234 | - } |
|
| 1235 | - $this->set_total($total); |
|
| 1236 | - $this->set_percent($total_percent); |
|
| 1237 | - } elseif ($this->is_total()) { |
|
| 1238 | - foreach ($this->children() as $maybe_tax_subtotal) { |
|
| 1239 | - if ($maybe_tax_subtotal instanceof EE_Line_Item) { |
|
| 1240 | - $maybe_tax_subtotal->_recalculate_tax_sub_total(); |
|
| 1241 | - } |
|
| 1242 | - } |
|
| 1243 | - } |
|
| 1244 | - } |
|
| 1245 | - |
|
| 1246 | - |
|
| 1247 | - |
|
| 1248 | - /** |
|
| 1249 | - * Gets the total tax on this line item. Assumes taxes have already been calculated using |
|
| 1250 | - * recalculate_taxes_and_total |
|
| 1251 | - * |
|
| 1252 | - * @return float |
|
| 1253 | - * @throws EE_Error |
|
| 1254 | - */ |
|
| 1255 | - public function get_total_tax() |
|
| 1256 | - { |
|
| 1257 | - $this->_recalculate_tax_sub_total(); |
|
| 1258 | - $total = 0; |
|
| 1259 | - foreach ($this->tax_descendants() as $tax_line_item) { |
|
| 1260 | - if ($tax_line_item instanceof EE_Line_Item) { |
|
| 1261 | - $total += $tax_line_item->total(); |
|
| 1262 | - } |
|
| 1263 | - } |
|
| 1264 | - return $total; |
|
| 1265 | - } |
|
| 1266 | - |
|
| 1267 | - |
|
| 1268 | - /** |
|
| 1269 | - * Gets the total for all the items purchased only |
|
| 1270 | - * |
|
| 1271 | - * @return float |
|
| 1272 | - * @throws EE_Error |
|
| 1273 | - */ |
|
| 1274 | - public function get_items_total() |
|
| 1275 | - { |
|
| 1276 | - //by default, let's make sure we're consistent with the existing line item |
|
| 1277 | - if ($this->is_total()) { |
|
| 1278 | - $pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this); |
|
| 1279 | - if ($pretax_subtotal_li instanceof EE_Line_Item) { |
|
| 1280 | - return $pretax_subtotal_li->total(); |
|
| 1281 | - } |
|
| 1282 | - } |
|
| 1283 | - $total = 0; |
|
| 1284 | - foreach ($this->get_items() as $item) { |
|
| 1285 | - if ($item instanceof EE_Line_Item) { |
|
| 1286 | - $total += $item->total(); |
|
| 1287 | - } |
|
| 1288 | - } |
|
| 1289 | - return $total; |
|
| 1290 | - } |
|
| 1291 | - |
|
| 1292 | - |
|
| 1293 | - |
|
| 1294 | - /** |
|
| 1295 | - * Gets all the descendants (ie, children or children of children etc) that |
|
| 1296 | - * are of the type 'tax' |
|
| 1297 | - * |
|
| 1298 | - * @return EE_Line_Item[] |
|
| 1299 | - */ |
|
| 1300 | - public function tax_descendants() |
|
| 1301 | - { |
|
| 1302 | - return EEH_Line_Item::get_tax_descendants($this); |
|
| 1303 | - } |
|
| 1304 | - |
|
| 1305 | - |
|
| 1306 | - |
|
| 1307 | - /** |
|
| 1308 | - * Gets all the real items purchased which are children of this item |
|
| 1309 | - * |
|
| 1310 | - * @return EE_Line_Item[] |
|
| 1311 | - */ |
|
| 1312 | - public function get_items() |
|
| 1313 | - { |
|
| 1314 | - return EEH_Line_Item::get_line_item_descendants($this); |
|
| 1315 | - } |
|
| 1316 | - |
|
| 1317 | - |
|
| 1318 | - |
|
| 1319 | - /** |
|
| 1320 | - * Returns the amount taxable among this line item's children (or if it has no children, |
|
| 1321 | - * how much of it is taxable). Does not recalculate totals or subtotals. |
|
| 1322 | - * If the taxable total is negative, (eg, if none of the tickets were taxable, |
|
| 1323 | - * but there is a "Taxable" discount), returns 0. |
|
| 1324 | - * |
|
| 1325 | - * @return float |
|
| 1326 | - * @throws EE_Error |
|
| 1327 | - */ |
|
| 1328 | - public function taxable_total() |
|
| 1329 | - { |
|
| 1330 | - $total = 0; |
|
| 1331 | - if ($this->children()) { |
|
| 1332 | - foreach ($this->children() as $child_line_item) { |
|
| 1333 | - if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) { |
|
| 1334 | - //if it's a percent item, only take into account the percent |
|
| 1335 | - //that's taxable too (the taxable total so far) |
|
| 1336 | - if ($child_line_item->is_percent()) { |
|
| 1337 | - $total += ($total * $child_line_item->percent() / 100); |
|
| 1338 | - } else { |
|
| 1339 | - $total += $child_line_item->total(); |
|
| 1340 | - } |
|
| 1341 | - } elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) { |
|
| 1342 | - $total += $child_line_item->taxable_total(); |
|
| 1343 | - } |
|
| 1344 | - } |
|
| 1345 | - } |
|
| 1346 | - return max($total, 0); |
|
| 1347 | - } |
|
| 1348 | - |
|
| 1349 | - |
|
| 1350 | - |
|
| 1351 | - /** |
|
| 1352 | - * Gets the transaction for this line item |
|
| 1353 | - * |
|
| 1354 | - * @return EE_Base_Class|EE_Transaction |
|
| 1355 | - * @throws EE_Error |
|
| 1356 | - */ |
|
| 1357 | - public function transaction() |
|
| 1358 | - { |
|
| 1359 | - return $this->get_first_related('Transaction'); |
|
| 1360 | - } |
|
| 1361 | - |
|
| 1362 | - |
|
| 1363 | - |
|
| 1364 | - /** |
|
| 1365 | - * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1366 | - * Because there currently is no proper parent-child relation on the model, |
|
| 1367 | - * save_this_and_cached() will NOT save the descendants. |
|
| 1368 | - * Also sets the transaction on this line item and all its descendants before saving |
|
| 1369 | - * |
|
| 1370 | - * @param int $txn_id if none is provided, assumes $this->TXN_ID() |
|
| 1371 | - * @return int count of items saved |
|
| 1372 | - * @throws EE_Error |
|
| 1373 | - */ |
|
| 1374 | - public function save_this_and_descendants_to_txn($txn_id = null) |
|
| 1375 | - { |
|
| 1376 | - $count = 0; |
|
| 1377 | - if (! $txn_id) { |
|
| 1378 | - $txn_id = $this->TXN_ID(); |
|
| 1379 | - } |
|
| 1380 | - $this->set_TXN_ID($txn_id); |
|
| 1381 | - $children = $this->children(); |
|
| 1382 | - $count += $this->save() |
|
| 1383 | - ? 1 |
|
| 1384 | - : 0; |
|
| 1385 | - foreach ($children as $child_line_item) { |
|
| 1386 | - if ($child_line_item instanceof EE_Line_Item) { |
|
| 1387 | - $child_line_item->set_parent_ID($this->ID()); |
|
| 1388 | - $count += $child_line_item->save_this_and_descendants_to_txn($txn_id); |
|
| 1389 | - } |
|
| 1390 | - } |
|
| 1391 | - return $count; |
|
| 1392 | - } |
|
| 1393 | - |
|
| 1394 | - |
|
| 1395 | - |
|
| 1396 | - /** |
|
| 1397 | - * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1398 | - * |
|
| 1399 | - * @return int count of items saved |
|
| 1400 | - * @throws EE_Error |
|
| 1401 | - */ |
|
| 1402 | - public function save_this_and_descendants() |
|
| 1403 | - { |
|
| 1404 | - $count = 0; |
|
| 1405 | - $children = $this->children(); |
|
| 1406 | - $count += $this->save() |
|
| 1407 | - ? 1 |
|
| 1408 | - : 0; |
|
| 1409 | - foreach ($children as $child_line_item) { |
|
| 1410 | - if ($child_line_item instanceof EE_Line_Item) { |
|
| 1411 | - $child_line_item->set_parent_ID($this->ID()); |
|
| 1412 | - $count += $child_line_item->save_this_and_descendants(); |
|
| 1413 | - } |
|
| 1414 | - } |
|
| 1415 | - return $count; |
|
| 1416 | - } |
|
| 1417 | - |
|
| 1418 | - |
|
| 1419 | - |
|
| 1420 | - /** |
|
| 1421 | - * returns the cancellation line item if this item was cancelled |
|
| 1422 | - * |
|
| 1423 | - * @return EE_Line_Item[] |
|
| 1424 | - * @throws InvalidArgumentException |
|
| 1425 | - * @throws InvalidInterfaceException |
|
| 1426 | - * @throws InvalidDataTypeException |
|
| 1427 | - * @throws ReflectionException |
|
| 1428 | - * @throws EE_Error |
|
| 1429 | - */ |
|
| 1430 | - public function get_cancellations() |
|
| 1431 | - { |
|
| 1432 | - EE_Registry::instance()->load_helper('Line_Item'); |
|
| 1433 | - return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation); |
|
| 1434 | - } |
|
| 1435 | - |
|
| 1436 | - |
|
| 1437 | - |
|
| 1438 | - /** |
|
| 1439 | - * If this item has an ID, then this saves it again to update the db |
|
| 1440 | - * |
|
| 1441 | - * @return int count of items saved |
|
| 1442 | - * @throws EE_Error |
|
| 1443 | - */ |
|
| 1444 | - public function maybe_save() |
|
| 1445 | - { |
|
| 1446 | - if ($this->ID()) { |
|
| 1447 | - return $this->save(); |
|
| 1448 | - } |
|
| 1449 | - return false; |
|
| 1450 | - } |
|
| 1451 | - |
|
| 1452 | - |
|
| 1453 | - /** |
|
| 1454 | - * clears the cached children and parent from the line item |
|
| 1455 | - * |
|
| 1456 | - * @return void |
|
| 1457 | - */ |
|
| 1458 | - public function clear_related_line_item_cache() |
|
| 1459 | - { |
|
| 1460 | - $this->_children = array(); |
|
| 1461 | - $this->_parent = null; |
|
| 1462 | - } |
|
| 1463 | - |
|
| 1464 | - |
|
| 1465 | - |
|
| 1466 | - /** |
|
| 1467 | - * @param bool $raw |
|
| 1468 | - * @return int |
|
| 1469 | - * @throws EE_Error |
|
| 1470 | - */ |
|
| 1471 | - public function timestamp($raw = false) |
|
| 1472 | - { |
|
| 1473 | - return $raw |
|
| 1474 | - ? $this->get_raw('LIN_timestamp') |
|
| 1475 | - : $this->get('LIN_timestamp'); |
|
| 1476 | - } |
|
| 1477 | - |
|
| 1478 | - |
|
| 1479 | - |
|
| 1480 | - |
|
| 1481 | - /************************* DEPRECATED *************************/ |
|
| 1482 | - /** |
|
| 1483 | - * @deprecated 4.6.0 |
|
| 1484 | - * @param string $type one of the constants on EEM_Line_Item |
|
| 1485 | - * @return EE_Line_Item[] |
|
| 1486 | - */ |
|
| 1487 | - protected function _get_descendants_of_type($type) |
|
| 1488 | - { |
|
| 1489 | - EE_Error::doing_it_wrong( |
|
| 1490 | - 'EE_Line_Item::_get_descendants_of_type()', |
|
| 1491 | - __('Method replaced with EEH_Line_Item::get_descendants_of_type()', 'event_espresso'), '4.6.0' |
|
| 1492 | - ); |
|
| 1493 | - return EEH_Line_Item::get_descendants_of_type($this, $type); |
|
| 1494 | - } |
|
| 1495 | - |
|
| 1496 | - |
|
| 1497 | - |
|
| 1498 | - /** |
|
| 1499 | - * @deprecated 4.6.0 |
|
| 1500 | - * @param string $type like one of the EEM_Line_Item::type_* |
|
| 1501 | - * @return EE_Line_Item |
|
| 1502 | - */ |
|
| 1503 | - public function get_nearest_descendant_of_type($type) |
|
| 1504 | - { |
|
| 1505 | - EE_Error::doing_it_wrong( |
|
| 1506 | - 'EE_Line_Item::get_nearest_descendant_of_type()', |
|
| 1507 | - __('Method replaced with EEH_Line_Item::get_nearest_descendant_of_type()', 'event_espresso'), '4.6.0' |
|
| 1508 | - ); |
|
| 1509 | - return EEH_Line_Item::get_nearest_descendant_of_type($this, $type); |
|
| 1510 | - } |
|
| 21 | + /** |
|
| 22 | + * for children line items (currently not a normal relation) |
|
| 23 | + * |
|
| 24 | + * @type EE_Line_Item[] |
|
| 25 | + */ |
|
| 26 | + protected $_children = array(); |
|
| 27 | + |
|
| 28 | + /** |
|
| 29 | + * for the parent line item |
|
| 30 | + * |
|
| 31 | + * @var EE_Line_Item |
|
| 32 | + */ |
|
| 33 | + protected $_parent; |
|
| 34 | + |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * |
|
| 39 | + * @param array $props_n_values incoming values |
|
| 40 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 41 | + * used.) |
|
| 42 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 43 | + * date_format and the second value is the time format |
|
| 44 | + * @return EE_Line_Item |
|
| 45 | + * @throws EE_Error |
|
| 46 | + */ |
|
| 47 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 48 | + { |
|
| 49 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 50 | + return $has_object |
|
| 51 | + ? $has_object |
|
| 52 | + : new self($props_n_values, false, $timezone); |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + |
|
| 56 | + |
|
| 57 | + /** |
|
| 58 | + * @param array $props_n_values incoming values from the database |
|
| 59 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 60 | + * the website will be used. |
|
| 61 | + * @return EE_Line_Item |
|
| 62 | + * @throws EE_Error |
|
| 63 | + */ |
|
| 64 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 65 | + { |
|
| 66 | + return new self($props_n_values, true, $timezone); |
|
| 67 | + } |
|
| 68 | + |
|
| 69 | + |
|
| 70 | + |
|
| 71 | + /** |
|
| 72 | + * Adds some defaults if they're not specified |
|
| 73 | + * |
|
| 74 | + * @param array $fieldValues |
|
| 75 | + * @param bool $bydb |
|
| 76 | + * @param string $timezone |
|
| 77 | + * @throws EE_Error |
|
| 78 | + */ |
|
| 79 | + protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') |
|
| 80 | + { |
|
| 81 | + parent::__construct($fieldValues, $bydb, $timezone); |
|
| 82 | + if (! $this->get('LIN_code')) { |
|
| 83 | + $this->set_code($this->generate_code()); |
|
| 84 | + } |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + |
|
| 88 | + |
|
| 89 | + /** |
|
| 90 | + * Gets ID |
|
| 91 | + * |
|
| 92 | + * @return int |
|
| 93 | + * @throws EE_Error |
|
| 94 | + */ |
|
| 95 | + public function ID() |
|
| 96 | + { |
|
| 97 | + return $this->get('LIN_ID'); |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + |
|
| 101 | + |
|
| 102 | + /** |
|
| 103 | + * Gets TXN_ID |
|
| 104 | + * |
|
| 105 | + * @return int |
|
| 106 | + * @throws EE_Error |
|
| 107 | + */ |
|
| 108 | + public function TXN_ID() |
|
| 109 | + { |
|
| 110 | + return $this->get('TXN_ID'); |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + |
|
| 114 | + |
|
| 115 | + /** |
|
| 116 | + * Sets TXN_ID |
|
| 117 | + * |
|
| 118 | + * @param int $TXN_ID |
|
| 119 | + * @throws EE_Error |
|
| 120 | + */ |
|
| 121 | + public function set_TXN_ID($TXN_ID) |
|
| 122 | + { |
|
| 123 | + $this->set('TXN_ID', $TXN_ID); |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + |
|
| 127 | + |
|
| 128 | + /** |
|
| 129 | + * Gets name |
|
| 130 | + * |
|
| 131 | + * @return string |
|
| 132 | + * @throws EE_Error |
|
| 133 | + */ |
|
| 134 | + public function name() |
|
| 135 | + { |
|
| 136 | + $name = $this->get('LIN_name'); |
|
| 137 | + if (! $name) { |
|
| 138 | + $name = ucwords(str_replace('-', ' ', $this->type())); |
|
| 139 | + } |
|
| 140 | + return $name; |
|
| 141 | + } |
|
| 142 | + |
|
| 143 | + |
|
| 144 | + |
|
| 145 | + /** |
|
| 146 | + * Sets name |
|
| 147 | + * |
|
| 148 | + * @param string $name |
|
| 149 | + * @throws EE_Error |
|
| 150 | + */ |
|
| 151 | + public function set_name($name) |
|
| 152 | + { |
|
| 153 | + $this->set('LIN_name', $name); |
|
| 154 | + } |
|
| 155 | + |
|
| 156 | + |
|
| 157 | + |
|
| 158 | + /** |
|
| 159 | + * Gets desc |
|
| 160 | + * |
|
| 161 | + * @return string |
|
| 162 | + * @throws EE_Error |
|
| 163 | + */ |
|
| 164 | + public function desc() |
|
| 165 | + { |
|
| 166 | + return $this->get('LIN_desc'); |
|
| 167 | + } |
|
| 168 | + |
|
| 169 | + |
|
| 170 | + |
|
| 171 | + /** |
|
| 172 | + * Sets desc |
|
| 173 | + * |
|
| 174 | + * @param string $desc |
|
| 175 | + * @throws EE_Error |
|
| 176 | + */ |
|
| 177 | + public function set_desc($desc) |
|
| 178 | + { |
|
| 179 | + $this->set('LIN_desc', $desc); |
|
| 180 | + } |
|
| 181 | + |
|
| 182 | + |
|
| 183 | + |
|
| 184 | + /** |
|
| 185 | + * Gets quantity |
|
| 186 | + * |
|
| 187 | + * @return int |
|
| 188 | + * @throws EE_Error |
|
| 189 | + */ |
|
| 190 | + public function quantity() |
|
| 191 | + { |
|
| 192 | + return $this->get('LIN_quantity'); |
|
| 193 | + } |
|
| 194 | + |
|
| 195 | + |
|
| 196 | + |
|
| 197 | + /** |
|
| 198 | + * Sets quantity |
|
| 199 | + * |
|
| 200 | + * @param int $quantity |
|
| 201 | + * @throws EE_Error |
|
| 202 | + */ |
|
| 203 | + public function set_quantity($quantity) |
|
| 204 | + { |
|
| 205 | + $this->set('LIN_quantity', max($quantity, 0)); |
|
| 206 | + } |
|
| 207 | + |
|
| 208 | + |
|
| 209 | + |
|
| 210 | + /** |
|
| 211 | + * Gets item_id |
|
| 212 | + * |
|
| 213 | + * @return string |
|
| 214 | + * @throws EE_Error |
|
| 215 | + */ |
|
| 216 | + public function OBJ_ID() |
|
| 217 | + { |
|
| 218 | + return $this->get('OBJ_ID'); |
|
| 219 | + } |
|
| 220 | + |
|
| 221 | + |
|
| 222 | + |
|
| 223 | + /** |
|
| 224 | + * Sets item_id |
|
| 225 | + * |
|
| 226 | + * @param string $item_id |
|
| 227 | + * @throws EE_Error |
|
| 228 | + */ |
|
| 229 | + public function set_OBJ_ID($item_id) |
|
| 230 | + { |
|
| 231 | + $this->set('OBJ_ID', $item_id); |
|
| 232 | + } |
|
| 233 | + |
|
| 234 | + |
|
| 235 | + |
|
| 236 | + /** |
|
| 237 | + * Gets item_type |
|
| 238 | + * |
|
| 239 | + * @return string |
|
| 240 | + * @throws EE_Error |
|
| 241 | + */ |
|
| 242 | + public function OBJ_type() |
|
| 243 | + { |
|
| 244 | + return $this->get('OBJ_type'); |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + |
|
| 248 | + |
|
| 249 | + /** |
|
| 250 | + * Gets item_type |
|
| 251 | + * |
|
| 252 | + * @return string |
|
| 253 | + * @throws EE_Error |
|
| 254 | + */ |
|
| 255 | + public function OBJ_type_i18n() |
|
| 256 | + { |
|
| 257 | + $obj_type = $this->OBJ_type(); |
|
| 258 | + switch ($obj_type) { |
|
| 259 | + case 'Event': |
|
| 260 | + $obj_type = __('Event', 'event_espresso'); |
|
| 261 | + break; |
|
| 262 | + case 'Price': |
|
| 263 | + $obj_type = __('Price', 'event_espresso'); |
|
| 264 | + break; |
|
| 265 | + case 'Promotion': |
|
| 266 | + $obj_type = __('Promotion', 'event_espresso'); |
|
| 267 | + break; |
|
| 268 | + case 'Ticket': |
|
| 269 | + $obj_type = __('Ticket', 'event_espresso'); |
|
| 270 | + break; |
|
| 271 | + case 'Transaction': |
|
| 272 | + $obj_type = __('Transaction', 'event_espresso'); |
|
| 273 | + break; |
|
| 274 | + } |
|
| 275 | + return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this); |
|
| 276 | + } |
|
| 277 | + |
|
| 278 | + |
|
| 279 | + |
|
| 280 | + /** |
|
| 281 | + * Sets item_type |
|
| 282 | + * |
|
| 283 | + * @param string $OBJ_type |
|
| 284 | + * @throws EE_Error |
|
| 285 | + */ |
|
| 286 | + public function set_OBJ_type($OBJ_type) |
|
| 287 | + { |
|
| 288 | + $this->set('OBJ_type', $OBJ_type); |
|
| 289 | + } |
|
| 290 | + |
|
| 291 | + |
|
| 292 | + |
|
| 293 | + /** |
|
| 294 | + * Gets unit_price |
|
| 295 | + * |
|
| 296 | + * @return float |
|
| 297 | + * @throws EE_Error |
|
| 298 | + */ |
|
| 299 | + public function unit_price() |
|
| 300 | + { |
|
| 301 | + return $this->get('LIN_unit_price'); |
|
| 302 | + } |
|
| 303 | + |
|
| 304 | + |
|
| 305 | + |
|
| 306 | + /** |
|
| 307 | + * Sets unit_price |
|
| 308 | + * |
|
| 309 | + * @param float $unit_price |
|
| 310 | + * @throws EE_Error |
|
| 311 | + */ |
|
| 312 | + public function set_unit_price($unit_price) |
|
| 313 | + { |
|
| 314 | + $this->set('LIN_unit_price', $unit_price); |
|
| 315 | + } |
|
| 316 | + |
|
| 317 | + |
|
| 318 | + |
|
| 319 | + /** |
|
| 320 | + * Checks if this item is a percentage modifier or not |
|
| 321 | + * |
|
| 322 | + * @return boolean |
|
| 323 | + * @throws EE_Error |
|
| 324 | + */ |
|
| 325 | + public function is_percent() |
|
| 326 | + { |
|
| 327 | + if ($this->is_tax_sub_total()) { |
|
| 328 | + //tax subtotals HAVE a percent on them, that percentage only applies |
|
| 329 | + //to taxable items, so its' an exception. Treat it like a flat line item |
|
| 330 | + return false; |
|
| 331 | + } |
|
| 332 | + $unit_price = abs($this->get('LIN_unit_price')); |
|
| 333 | + $percent = abs($this->get('LIN_percent')); |
|
| 334 | + if ($unit_price < .001 && $percent) { |
|
| 335 | + return true; |
|
| 336 | + } |
|
| 337 | + if ($unit_price >= .001 && ! $percent) { |
|
| 338 | + return false; |
|
| 339 | + } |
|
| 340 | + if ($unit_price >= .001 && $percent) { |
|
| 341 | + throw new EE_Error( |
|
| 342 | + sprintf( |
|
| 343 | + esc_html__('A Line Item can not have a unit price of (%s) AND a percent (%s)!', 'event_espresso'), |
|
| 344 | + $unit_price, $percent |
|
| 345 | + ) |
|
| 346 | + ); |
|
| 347 | + } |
|
| 348 | + // if they're both 0, assume its not a percent item |
|
| 349 | + return false; |
|
| 350 | + } |
|
| 351 | + |
|
| 352 | + |
|
| 353 | + |
|
| 354 | + /** |
|
| 355 | + * Gets percent (between 100-.001) |
|
| 356 | + * |
|
| 357 | + * @return float |
|
| 358 | + * @throws EE_Error |
|
| 359 | + */ |
|
| 360 | + public function percent() |
|
| 361 | + { |
|
| 362 | + return $this->get('LIN_percent'); |
|
| 363 | + } |
|
| 364 | + |
|
| 365 | + |
|
| 366 | + |
|
| 367 | + /** |
|
| 368 | + * Sets percent (between 100-0.01) |
|
| 369 | + * |
|
| 370 | + * @param float $percent |
|
| 371 | + * @throws EE_Error |
|
| 372 | + */ |
|
| 373 | + public function set_percent($percent) |
|
| 374 | + { |
|
| 375 | + $this->set('LIN_percent', $percent); |
|
| 376 | + } |
|
| 377 | + |
|
| 378 | + |
|
| 379 | + |
|
| 380 | + /** |
|
| 381 | + * Gets total |
|
| 382 | + * |
|
| 383 | + * @return float |
|
| 384 | + * @throws EE_Error |
|
| 385 | + */ |
|
| 386 | + public function total() |
|
| 387 | + { |
|
| 388 | + return $this->get('LIN_total'); |
|
| 389 | + } |
|
| 390 | + |
|
| 391 | + |
|
| 392 | + |
|
| 393 | + /** |
|
| 394 | + * Sets total |
|
| 395 | + * |
|
| 396 | + * @param float $total |
|
| 397 | + * @throws EE_Error |
|
| 398 | + */ |
|
| 399 | + public function set_total($total) |
|
| 400 | + { |
|
| 401 | + $this->set('LIN_total', $total); |
|
| 402 | + } |
|
| 403 | + |
|
| 404 | + |
|
| 405 | + |
|
| 406 | + /** |
|
| 407 | + * Gets order |
|
| 408 | + * |
|
| 409 | + * @return int |
|
| 410 | + * @throws EE_Error |
|
| 411 | + */ |
|
| 412 | + public function order() |
|
| 413 | + { |
|
| 414 | + return $this->get('LIN_order'); |
|
| 415 | + } |
|
| 416 | + |
|
| 417 | + |
|
| 418 | + |
|
| 419 | + /** |
|
| 420 | + * Sets order |
|
| 421 | + * |
|
| 422 | + * @param int $order |
|
| 423 | + * @throws EE_Error |
|
| 424 | + */ |
|
| 425 | + public function set_order($order) |
|
| 426 | + { |
|
| 427 | + $this->set('LIN_order', $order); |
|
| 428 | + } |
|
| 429 | + |
|
| 430 | + |
|
| 431 | + |
|
| 432 | + /** |
|
| 433 | + * Gets parent |
|
| 434 | + * |
|
| 435 | + * @return int |
|
| 436 | + * @throws EE_Error |
|
| 437 | + */ |
|
| 438 | + public function parent_ID() |
|
| 439 | + { |
|
| 440 | + return $this->get('LIN_parent'); |
|
| 441 | + } |
|
| 442 | + |
|
| 443 | + |
|
| 444 | + |
|
| 445 | + /** |
|
| 446 | + * Sets parent |
|
| 447 | + * |
|
| 448 | + * @param int $parent |
|
| 449 | + * @throws EE_Error |
|
| 450 | + */ |
|
| 451 | + public function set_parent_ID($parent) |
|
| 452 | + { |
|
| 453 | + $this->set('LIN_parent', $parent); |
|
| 454 | + } |
|
| 455 | + |
|
| 456 | + |
|
| 457 | + |
|
| 458 | + /** |
|
| 459 | + * Gets type |
|
| 460 | + * |
|
| 461 | + * @return string |
|
| 462 | + * @throws EE_Error |
|
| 463 | + */ |
|
| 464 | + public function type() |
|
| 465 | + { |
|
| 466 | + return $this->get('LIN_type'); |
|
| 467 | + } |
|
| 468 | + |
|
| 469 | + |
|
| 470 | + |
|
| 471 | + /** |
|
| 472 | + * Sets type |
|
| 473 | + * |
|
| 474 | + * @param string $type |
|
| 475 | + * @throws EE_Error |
|
| 476 | + */ |
|
| 477 | + public function set_type($type) |
|
| 478 | + { |
|
| 479 | + $this->set('LIN_type', $type); |
|
| 480 | + } |
|
| 481 | + |
|
| 482 | + |
|
| 483 | + |
|
| 484 | + /** |
|
| 485 | + * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\ |
|
| 486 | + * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB |
|
| 487 | + * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()` |
|
| 488 | + * or indirectly by `EE_Line_item::add_child_line_item()`) |
|
| 489 | + * |
|
| 490 | + * @return EE_Base_Class|EE_Line_Item |
|
| 491 | + * @throws EE_Error |
|
| 492 | + */ |
|
| 493 | + public function parent() |
|
| 494 | + { |
|
| 495 | + return $this->ID() |
|
| 496 | + ? $this->get_model()->get_one_by_ID($this->parent_ID()) |
|
| 497 | + : $this->_parent; |
|
| 498 | + } |
|
| 499 | + |
|
| 500 | + |
|
| 501 | + |
|
| 502 | + /** |
|
| 503 | + * Gets ALL the children of this line item (ie, all the parts that contribute towards this total). |
|
| 504 | + * |
|
| 505 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 506 | + * @throws EE_Error |
|
| 507 | + */ |
|
| 508 | + public function children() |
|
| 509 | + { |
|
| 510 | + if ($this->ID()) { |
|
| 511 | + return $this->get_model()->get_all( |
|
| 512 | + array( |
|
| 513 | + array('LIN_parent' => $this->ID()), |
|
| 514 | + 'order_by' => array('LIN_order' => 'ASC'), |
|
| 515 | + ) |
|
| 516 | + ); |
|
| 517 | + } |
|
| 518 | + if (! is_array($this->_children)) { |
|
| 519 | + $this->_children = array(); |
|
| 520 | + } |
|
| 521 | + return $this->_children; |
|
| 522 | + } |
|
| 523 | + |
|
| 524 | + |
|
| 525 | + |
|
| 526 | + /** |
|
| 527 | + * Gets code |
|
| 528 | + * |
|
| 529 | + * @return string |
|
| 530 | + * @throws EE_Error |
|
| 531 | + */ |
|
| 532 | + public function code() |
|
| 533 | + { |
|
| 534 | + return $this->get('LIN_code'); |
|
| 535 | + } |
|
| 536 | + |
|
| 537 | + |
|
| 538 | + |
|
| 539 | + /** |
|
| 540 | + * Sets code |
|
| 541 | + * |
|
| 542 | + * @param string $code |
|
| 543 | + * @throws EE_Error |
|
| 544 | + */ |
|
| 545 | + public function set_code($code) |
|
| 546 | + { |
|
| 547 | + $this->set('LIN_code', $code); |
|
| 548 | + } |
|
| 549 | + |
|
| 550 | + |
|
| 551 | + |
|
| 552 | + /** |
|
| 553 | + * Gets is_taxable |
|
| 554 | + * |
|
| 555 | + * @return boolean |
|
| 556 | + * @throws EE_Error |
|
| 557 | + */ |
|
| 558 | + public function is_taxable() |
|
| 559 | + { |
|
| 560 | + return $this->get('LIN_is_taxable'); |
|
| 561 | + } |
|
| 562 | + |
|
| 563 | + |
|
| 564 | + |
|
| 565 | + /** |
|
| 566 | + * Sets is_taxable |
|
| 567 | + * |
|
| 568 | + * @param boolean $is_taxable |
|
| 569 | + * @throws EE_Error |
|
| 570 | + */ |
|
| 571 | + public function set_is_taxable($is_taxable) |
|
| 572 | + { |
|
| 573 | + $this->set('LIN_is_taxable', $is_taxable); |
|
| 574 | + } |
|
| 575 | + |
|
| 576 | + |
|
| 577 | + |
|
| 578 | + /** |
|
| 579 | + * Gets the object that this model-joins-to. |
|
| 580 | + * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on |
|
| 581 | + * EEM_Promotion_Object |
|
| 582 | + * |
|
| 583 | + * Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object |
|
| 584 | + * |
|
| 585 | + * @return EE_Base_Class | NULL |
|
| 586 | + * @throws EE_Error |
|
| 587 | + */ |
|
| 588 | + public function get_object() |
|
| 589 | + { |
|
| 590 | + $model_name_of_related_obj = $this->OBJ_type(); |
|
| 591 | + return $this->get_model()->has_relation($model_name_of_related_obj) |
|
| 592 | + ? $this->get_first_related($model_name_of_related_obj) |
|
| 593 | + : null; |
|
| 594 | + } |
|
| 595 | + |
|
| 596 | + |
|
| 597 | + |
|
| 598 | + /** |
|
| 599 | + * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket. |
|
| 600 | + * (IE, if this line item is for a price or something else, will return NULL) |
|
| 601 | + * |
|
| 602 | + * @param array $query_params |
|
| 603 | + * @return EE_Base_Class|EE_Ticket |
|
| 604 | + * @throws EE_Error |
|
| 605 | + */ |
|
| 606 | + public function ticket($query_params = array()) |
|
| 607 | + { |
|
| 608 | + //we're going to assume that when this method is called we always want to receive the attached ticket EVEN if that ticket is archived. This can be overridden via the incoming $query_params argument |
|
| 609 | + $remove_defaults = array('default_where_conditions' => 'none'); |
|
| 610 | + $query_params = array_merge($remove_defaults, $query_params); |
|
| 611 | + return $this->get_first_related('Ticket', $query_params); |
|
| 612 | + } |
|
| 613 | + |
|
| 614 | + |
|
| 615 | + |
|
| 616 | + /** |
|
| 617 | + * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket |
|
| 618 | + * |
|
| 619 | + * @return EE_Datetime | NULL |
|
| 620 | + * @throws EE_Error |
|
| 621 | + */ |
|
| 622 | + public function get_ticket_datetime() |
|
| 623 | + { |
|
| 624 | + if ($this->OBJ_type() === 'Ticket') { |
|
| 625 | + $ticket = $this->ticket(); |
|
| 626 | + if ($ticket instanceof EE_Ticket) { |
|
| 627 | + $datetime = $ticket->first_datetime(); |
|
| 628 | + if ($datetime instanceof EE_Datetime) { |
|
| 629 | + return $datetime; |
|
| 630 | + } |
|
| 631 | + } |
|
| 632 | + } |
|
| 633 | + return null; |
|
| 634 | + } |
|
| 635 | + |
|
| 636 | + |
|
| 637 | + |
|
| 638 | + /** |
|
| 639 | + * Gets the event's name that's related to the ticket, if this is for |
|
| 640 | + * a ticket |
|
| 641 | + * |
|
| 642 | + * @return string |
|
| 643 | + * @throws EE_Error |
|
| 644 | + */ |
|
| 645 | + public function ticket_event_name() |
|
| 646 | + { |
|
| 647 | + $event_name = esc_html__('Unknown', 'event_espresso'); |
|
| 648 | + $event = $this->ticket_event(); |
|
| 649 | + if ($event instanceof EE_Event) { |
|
| 650 | + $event_name = $event->name(); |
|
| 651 | + } |
|
| 652 | + return $event_name; |
|
| 653 | + } |
|
| 654 | + |
|
| 655 | + |
|
| 656 | + /** |
|
| 657 | + * Gets the event that's related to the ticket, if this line item represents a ticket. |
|
| 658 | + * |
|
| 659 | + * @return EE_Event|null |
|
| 660 | + * @throws EE_Error |
|
| 661 | + */ |
|
| 662 | + public function ticket_event() |
|
| 663 | + { |
|
| 664 | + $event = null; |
|
| 665 | + $ticket = $this->ticket(); |
|
| 666 | + if ($ticket instanceof EE_Ticket) { |
|
| 667 | + $datetime = $ticket->first_datetime(); |
|
| 668 | + if ($datetime instanceof EE_Datetime) { |
|
| 669 | + $event = $datetime->event(); |
|
| 670 | + } |
|
| 671 | + } |
|
| 672 | + return $event; |
|
| 673 | + } |
|
| 674 | + |
|
| 675 | + |
|
| 676 | + |
|
| 677 | + /** |
|
| 678 | + * Gets the first datetime for this lien item, assuming it's for a ticket |
|
| 679 | + * |
|
| 680 | + * @param string $date_format |
|
| 681 | + * @param string $time_format |
|
| 682 | + * @return string |
|
| 683 | + * @throws EE_Error |
|
| 684 | + */ |
|
| 685 | + public function ticket_datetime_start($date_format = '', $time_format = '') |
|
| 686 | + { |
|
| 687 | + $first_datetime_string = esc_html__('Unknown', 'event_espresso'); |
|
| 688 | + $datetime = $this->get_ticket_datetime(); |
|
| 689 | + if ($datetime) { |
|
| 690 | + $first_datetime_string = $datetime->start_date_and_time($date_format, $time_format); |
|
| 691 | + } |
|
| 692 | + return $first_datetime_string; |
|
| 693 | + } |
|
| 694 | + |
|
| 695 | + |
|
| 696 | + |
|
| 697 | + /** |
|
| 698 | + * Adds the line item as a child to this line item. If there is another child line |
|
| 699 | + * item with the same LIN_code, it is overwritten by this new one |
|
| 700 | + * |
|
| 701 | + * @param EEI_Line_Item $line_item |
|
| 702 | + * @param bool $set_order |
|
| 703 | + * @return bool success |
|
| 704 | + * @throws EE_Error |
|
| 705 | + */ |
|
| 706 | + public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true) |
|
| 707 | + { |
|
| 708 | + // should we calculate the LIN_order for this line item ? |
|
| 709 | + if ($set_order || $line_item->order() === null) { |
|
| 710 | + $line_item->set_order(count($this->children())); |
|
| 711 | + } |
|
| 712 | + if ($this->ID()) { |
|
| 713 | + //check for any duplicate line items (with the same code), if so, this replaces it |
|
| 714 | + $line_item_with_same_code = $this->get_child_line_item($line_item->code()); |
|
| 715 | + if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) { |
|
| 716 | + $this->delete_child_line_item($line_item_with_same_code->code()); |
|
| 717 | + } |
|
| 718 | + $line_item->set_parent_ID($this->ID()); |
|
| 719 | + if ($this->TXN_ID()) { |
|
| 720 | + $line_item->set_TXN_ID($this->TXN_ID()); |
|
| 721 | + } |
|
| 722 | + return $line_item->save(); |
|
| 723 | + } |
|
| 724 | + $this->_children[$line_item->code()] = $line_item; |
|
| 725 | + if ($line_item->parent() !== $this) { |
|
| 726 | + $line_item->set_parent($this); |
|
| 727 | + } |
|
| 728 | + return true; |
|
| 729 | + } |
|
| 730 | + |
|
| 731 | + |
|
| 732 | + /** |
|
| 733 | + * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation. |
|
| 734 | + * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save() |
|
| 735 | + * However, if this line item is NOT saved to the DB, this just caches the parent on |
|
| 736 | + * the EE_Line_Item::_parent property. |
|
| 737 | + * |
|
| 738 | + * @param EE_Line_Item $line_item |
|
| 739 | + * @throws EE_Error |
|
| 740 | + */ |
|
| 741 | + public function set_parent($line_item) |
|
| 742 | + { |
|
| 743 | + if ($this->ID()) { |
|
| 744 | + if (! $line_item->ID()) { |
|
| 745 | + $line_item->save(); |
|
| 746 | + } |
|
| 747 | + $this->set_parent_ID($line_item->ID()); |
|
| 748 | + $this->save(); |
|
| 749 | + } else { |
|
| 750 | + $this->_parent = $line_item; |
|
| 751 | + $this->set_parent_ID($line_item->ID()); |
|
| 752 | + } |
|
| 753 | + } |
|
| 754 | + |
|
| 755 | + |
|
| 756 | + |
|
| 757 | + /** |
|
| 758 | + * Gets the child line item as specified by its code. Because this returns an object (by reference) |
|
| 759 | + * you can modify this child line item and the parent (this object) can know about them |
|
| 760 | + * because it also has a reference to that line item |
|
| 761 | + * |
|
| 762 | + * @param string $code |
|
| 763 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 764 | + * @throws EE_Error |
|
| 765 | + */ |
|
| 766 | + public function get_child_line_item($code) |
|
| 767 | + { |
|
| 768 | + if ($this->ID()) { |
|
| 769 | + return $this->get_model()->get_one( |
|
| 770 | + array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code)) |
|
| 771 | + ); |
|
| 772 | + } |
|
| 773 | + return isset($this->_children[$code]) |
|
| 774 | + ? $this->_children[$code] |
|
| 775 | + : null; |
|
| 776 | + } |
|
| 777 | + |
|
| 778 | + |
|
| 779 | + |
|
| 780 | + /** |
|
| 781 | + * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD |
|
| 782 | + * cached on it) |
|
| 783 | + * |
|
| 784 | + * @return int |
|
| 785 | + * @throws EE_Error |
|
| 786 | + */ |
|
| 787 | + public function delete_children_line_items() |
|
| 788 | + { |
|
| 789 | + if ($this->ID()) { |
|
| 790 | + return $this->get_model()->delete(array(array('LIN_parent' => $this->ID()))); |
|
| 791 | + } |
|
| 792 | + $count = count($this->_children); |
|
| 793 | + $this->_children = array(); |
|
| 794 | + return $count; |
|
| 795 | + } |
|
| 796 | + |
|
| 797 | + |
|
| 798 | + |
|
| 799 | + /** |
|
| 800 | + * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line |
|
| 801 | + * HAS NOT been saved to the DB, removes the child line item with index $code. |
|
| 802 | + * Also searches through the child's children for a matching line item. However, once a line item has been found |
|
| 803 | + * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be |
|
| 804 | + * deleted) |
|
| 805 | + * |
|
| 806 | + * @param string $code |
|
| 807 | + * @param bool $stop_search_once_found |
|
| 808 | + * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to |
|
| 809 | + * the DB yet) |
|
| 810 | + * @throws EE_Error |
|
| 811 | + */ |
|
| 812 | + public function delete_child_line_item($code, $stop_search_once_found = true) |
|
| 813 | + { |
|
| 814 | + if ($this->ID()) { |
|
| 815 | + $items_deleted = 0; |
|
| 816 | + if ($this->code() === $code) { |
|
| 817 | + $items_deleted += EEH_Line_Item::delete_all_child_items($this); |
|
| 818 | + $items_deleted += (int)$this->delete(); |
|
| 819 | + if ($stop_search_once_found) { |
|
| 820 | + return $items_deleted; |
|
| 821 | + } |
|
| 822 | + } |
|
| 823 | + foreach ($this->children() as $child_line_item) { |
|
| 824 | + $items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found); |
|
| 825 | + } |
|
| 826 | + return $items_deleted; |
|
| 827 | + } |
|
| 828 | + if (isset($this->_children[$code])) { |
|
| 829 | + unset($this->_children[$code]); |
|
| 830 | + return 1; |
|
| 831 | + } |
|
| 832 | + return 0; |
|
| 833 | + } |
|
| 834 | + |
|
| 835 | + |
|
| 836 | + /** |
|
| 837 | + * If this line item is in the database, is of the type subtotal, and |
|
| 838 | + * has no children, why do we have it? It should be deleted so this function |
|
| 839 | + * does that |
|
| 840 | + * |
|
| 841 | + * @return boolean |
|
| 842 | + * @throws EE_Error |
|
| 843 | + */ |
|
| 844 | + public function delete_if_childless_subtotal() |
|
| 845 | + { |
|
| 846 | + if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) { |
|
| 847 | + return $this->delete(); |
|
| 848 | + } |
|
| 849 | + return false; |
|
| 850 | + } |
|
| 851 | + |
|
| 852 | + |
|
| 853 | + |
|
| 854 | + /** |
|
| 855 | + * Creates a code and returns a string. doesn't assign the code to this model object |
|
| 856 | + * |
|
| 857 | + * @return string |
|
| 858 | + * @throws EE_Error |
|
| 859 | + */ |
|
| 860 | + public function generate_code() |
|
| 861 | + { |
|
| 862 | + // each line item in the cart requires a unique identifier |
|
| 863 | + return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime()); |
|
| 864 | + } |
|
| 865 | + |
|
| 866 | + |
|
| 867 | + |
|
| 868 | + /** |
|
| 869 | + * @return bool |
|
| 870 | + * @throws EE_Error |
|
| 871 | + */ |
|
| 872 | + public function is_tax() |
|
| 873 | + { |
|
| 874 | + return $this->type() === EEM_Line_Item::type_tax; |
|
| 875 | + } |
|
| 876 | + |
|
| 877 | + |
|
| 878 | + |
|
| 879 | + /** |
|
| 880 | + * @return bool |
|
| 881 | + * @throws EE_Error |
|
| 882 | + */ |
|
| 883 | + public function is_tax_sub_total() |
|
| 884 | + { |
|
| 885 | + return $this->type() === EEM_Line_Item::type_tax_sub_total; |
|
| 886 | + } |
|
| 887 | + |
|
| 888 | + |
|
| 889 | + |
|
| 890 | + /** |
|
| 891 | + * @return bool |
|
| 892 | + * @throws EE_Error |
|
| 893 | + */ |
|
| 894 | + public function is_line_item() |
|
| 895 | + { |
|
| 896 | + return $this->type() === EEM_Line_Item::type_line_item; |
|
| 897 | + } |
|
| 898 | + |
|
| 899 | + |
|
| 900 | + |
|
| 901 | + /** |
|
| 902 | + * @return bool |
|
| 903 | + * @throws EE_Error |
|
| 904 | + */ |
|
| 905 | + public function is_sub_line_item() |
|
| 906 | + { |
|
| 907 | + return $this->type() === EEM_Line_Item::type_sub_line_item; |
|
| 908 | + } |
|
| 909 | + |
|
| 910 | + |
|
| 911 | + |
|
| 912 | + /** |
|
| 913 | + * @return bool |
|
| 914 | + * @throws EE_Error |
|
| 915 | + */ |
|
| 916 | + public function is_sub_total() |
|
| 917 | + { |
|
| 918 | + return $this->type() === EEM_Line_Item::type_sub_total; |
|
| 919 | + } |
|
| 920 | + |
|
| 921 | + |
|
| 922 | + |
|
| 923 | + /** |
|
| 924 | + * Whether or not this line item is a cancellation line item |
|
| 925 | + * |
|
| 926 | + * @return boolean |
|
| 927 | + * @throws EE_Error |
|
| 928 | + */ |
|
| 929 | + public function is_cancellation() |
|
| 930 | + { |
|
| 931 | + return EEM_Line_Item::type_cancellation === $this->type(); |
|
| 932 | + } |
|
| 933 | + |
|
| 934 | + |
|
| 935 | + |
|
| 936 | + /** |
|
| 937 | + * @return bool |
|
| 938 | + * @throws EE_Error |
|
| 939 | + */ |
|
| 940 | + public function is_total() |
|
| 941 | + { |
|
| 942 | + return $this->type() === EEM_Line_Item::type_total; |
|
| 943 | + } |
|
| 944 | + |
|
| 945 | + |
|
| 946 | + |
|
| 947 | + /** |
|
| 948 | + * @return bool |
|
| 949 | + * @throws EE_Error |
|
| 950 | + */ |
|
| 951 | + public function is_cancelled() |
|
| 952 | + { |
|
| 953 | + return $this->type() === EEM_Line_Item::type_cancellation; |
|
| 954 | + } |
|
| 955 | + |
|
| 956 | + |
|
| 957 | + |
|
| 958 | + /** |
|
| 959 | + * @return string like '2, 004.00', formatted according to the localized currency |
|
| 960 | + * @throws EE_Error |
|
| 961 | + */ |
|
| 962 | + public function unit_price_no_code() |
|
| 963 | + { |
|
| 964 | + return $this->get_pretty('LIN_unit_price', 'no_currency_code'); |
|
| 965 | + } |
|
| 966 | + |
|
| 967 | + |
|
| 968 | + |
|
| 969 | + /** |
|
| 970 | + * @return string like '2, 004.00', formatted according to the localized currency |
|
| 971 | + * @throws EE_Error |
|
| 972 | + */ |
|
| 973 | + public function total_no_code() |
|
| 974 | + { |
|
| 975 | + return $this->get_pretty('LIN_total', 'no_currency_code'); |
|
| 976 | + } |
|
| 977 | + |
|
| 978 | + |
|
| 979 | + |
|
| 980 | + /** |
|
| 981 | + * Gets the final total on this item, taking taxes into account. |
|
| 982 | + * Has the side-effect of setting the sub-total as it was just calculated. |
|
| 983 | + * If this is used on a grand-total line item, also updates the transaction's |
|
| 984 | + * TXN_total (provided this line item is allowed to persist, otherwise we don't |
|
| 985 | + * want to change a persistable transaction with info from a non-persistent line item) |
|
| 986 | + * |
|
| 987 | + * @return float |
|
| 988 | + * @throws EE_Error |
|
| 989 | + * @throws InvalidArgumentException |
|
| 990 | + * @throws InvalidInterfaceException |
|
| 991 | + * @throws InvalidDataTypeException |
|
| 992 | + */ |
|
| 993 | + public function recalculate_total_including_taxes() |
|
| 994 | + { |
|
| 995 | + $pre_tax_total = $this->recalculate_pre_tax_total(); |
|
| 996 | + $tax_total = $this->recalculate_taxes_and_tax_total(); |
|
| 997 | + $total = $pre_tax_total + $tax_total; |
|
| 998 | + // no negative totals plz |
|
| 999 | + $total = max($total, 0); |
|
| 1000 | + $this->set_total($total); |
|
| 1001 | + //only update the related transaction's total |
|
| 1002 | + //if we intend to save this line item and its a grand total |
|
| 1003 | + if ( |
|
| 1004 | + $this->allow_persist() && $this->type() === EEM_Line_Item::type_total |
|
| 1005 | + && $this->transaction() |
|
| 1006 | + instanceof |
|
| 1007 | + EE_Transaction |
|
| 1008 | + ) { |
|
| 1009 | + $this->transaction()->set_total($total); |
|
| 1010 | + if ($this->transaction()->ID()) { |
|
| 1011 | + $this->transaction()->save(); |
|
| 1012 | + } |
|
| 1013 | + } |
|
| 1014 | + $this->maybe_save(); |
|
| 1015 | + return $total; |
|
| 1016 | + } |
|
| 1017 | + |
|
| 1018 | + |
|
| 1019 | + /** |
|
| 1020 | + * Recursively goes through all the children and recalculates sub-totals EXCEPT for |
|
| 1021 | + * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its |
|
| 1022 | + * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and |
|
| 1023 | + * when this is called on the grand total |
|
| 1024 | + * |
|
| 1025 | + * @return float |
|
| 1026 | + * @throws InvalidArgumentException |
|
| 1027 | + * @throws InvalidInterfaceException |
|
| 1028 | + * @throws InvalidDataTypeException |
|
| 1029 | + * @throws EE_Error |
|
| 1030 | + */ |
|
| 1031 | + public function recalculate_pre_tax_total() |
|
| 1032 | + { |
|
| 1033 | + $total = 0; |
|
| 1034 | + $my_children = $this->children(); |
|
| 1035 | + $has_children = ! empty($my_children); |
|
| 1036 | + if ($has_children && $this->is_line_item()) { |
|
| 1037 | + $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children); |
|
| 1038 | + } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
| 1039 | + $total = $this->unit_price() * $this->quantity(); |
|
| 1040 | + } elseif ($this->is_sub_total() || $this->is_total()) { |
|
| 1041 | + $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children); |
|
| 1042 | + } elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) { |
|
| 1043 | + // completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total |
|
| 1044 | + return 0; |
|
| 1045 | + } |
|
| 1046 | + // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events) |
|
| 1047 | + if ( |
|
| 1048 | + ! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation() |
|
| 1049 | + ) { |
|
| 1050 | + if ($this->OBJ_type() !== 'Event') { |
|
| 1051 | + $this->set_quantity(1); |
|
| 1052 | + } |
|
| 1053 | + if (! $this->is_percent()) { |
|
| 1054 | + $this->set_unit_price($total); |
|
| 1055 | + } |
|
| 1056 | + } |
|
| 1057 | + //we don't want to bother saving grand totals, because that needs to factor in taxes anyways |
|
| 1058 | + //so it ought to be |
|
| 1059 | + if (! $this->is_total()) { |
|
| 1060 | + $this->set_total($total); |
|
| 1061 | + //if not a percent line item, make sure we keep the unit price in sync |
|
| 1062 | + if ( |
|
| 1063 | + $has_children |
|
| 1064 | + && $this->is_line_item() |
|
| 1065 | + && ! $this->is_percent() |
|
| 1066 | + ) { |
|
| 1067 | + if ($this->quantity() === 0) { |
|
| 1068 | + $new_unit_price = 0; |
|
| 1069 | + } else { |
|
| 1070 | + $new_unit_price = $this->total() / $this->quantity(); |
|
| 1071 | + } |
|
| 1072 | + $this->set_unit_price($new_unit_price); |
|
| 1073 | + } |
|
| 1074 | + $this->maybe_save(); |
|
| 1075 | + } |
|
| 1076 | + return $total; |
|
| 1077 | + } |
|
| 1078 | + |
|
| 1079 | + |
|
| 1080 | + |
|
| 1081 | + /** |
|
| 1082 | + * Calculates the pretax total when this line item is a subtotal or total line item. |
|
| 1083 | + * Basically does a sum-then-round approach (ie, any percent line item that are children |
|
| 1084 | + * will calculate their total based on the un-rounded total we're working with so far, and |
|
| 1085 | + * THEN round the result; instead of rounding as we go like with sub-line-items) |
|
| 1086 | + * |
|
| 1087 | + * @param float $calculated_total_so_far |
|
| 1088 | + * @param EE_Line_Item[] $my_children |
|
| 1089 | + * @return float |
|
| 1090 | + * @throws InvalidArgumentException |
|
| 1091 | + * @throws InvalidInterfaceException |
|
| 1092 | + * @throws InvalidDataTypeException |
|
| 1093 | + * @throws EE_Error |
|
| 1094 | + */ |
|
| 1095 | + protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null) |
|
| 1096 | + { |
|
| 1097 | + if ($my_children === null) { |
|
| 1098 | + $my_children = $this->children(); |
|
| 1099 | + } |
|
| 1100 | + //get the total of all its children |
|
| 1101 | + foreach ($my_children as $child_line_item) { |
|
| 1102 | + if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) { |
|
| 1103 | + // percentage line items are based on total so far |
|
| 1104 | + if ($child_line_item->is_percent()) { |
|
| 1105 | + //round as we go so that the line items add up ok |
|
| 1106 | + $percent_total = round( |
|
| 1107 | + $calculated_total_so_far * $child_line_item->percent() / 100, |
|
| 1108 | + EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1109 | + ); |
|
| 1110 | + $child_line_item->set_total($percent_total); |
|
| 1111 | + //so far all percent line items should have a quantity of 1 |
|
| 1112 | + //(ie, no double percent discounts. Although that might be requested someday) |
|
| 1113 | + $child_line_item->set_quantity(1); |
|
| 1114 | + $child_line_item->maybe_save(); |
|
| 1115 | + $calculated_total_so_far += $percent_total; |
|
| 1116 | + } else { |
|
| 1117 | + //verify flat sub-line-item quantities match their parent |
|
| 1118 | + if ($child_line_item->is_sub_line_item()) { |
|
| 1119 | + $child_line_item->set_quantity($this->quantity()); |
|
| 1120 | + } |
|
| 1121 | + $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1122 | + } |
|
| 1123 | + } |
|
| 1124 | + } |
|
| 1125 | + if ($this->is_sub_total()) { |
|
| 1126 | + // no negative totals plz |
|
| 1127 | + $calculated_total_so_far = max($calculated_total_so_far, 0); |
|
| 1128 | + } |
|
| 1129 | + return $calculated_total_so_far; |
|
| 1130 | + } |
|
| 1131 | + |
|
| 1132 | + |
|
| 1133 | + |
|
| 1134 | + /** |
|
| 1135 | + * Calculates the pretax total for a normal line item, in a round-then-sum approach |
|
| 1136 | + * (where each sub-line-item is applied to the base price for the line item |
|
| 1137 | + * and the result is immediately rounded, rather than summing all the sub-line-items |
|
| 1138 | + * then rounding, like we do when recalculating pretax totals on totals and subtotals). |
|
| 1139 | + * |
|
| 1140 | + * @param float $calculated_total_so_far |
|
| 1141 | + * @param EE_Line_Item[] $my_children |
|
| 1142 | + * @return float |
|
| 1143 | + * @throws InvalidArgumentException |
|
| 1144 | + * @throws InvalidInterfaceException |
|
| 1145 | + * @throws InvalidDataTypeException |
|
| 1146 | + * @throws EE_Error |
|
| 1147 | + */ |
|
| 1148 | + protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null) |
|
| 1149 | + { |
|
| 1150 | + if ($my_children === null) { |
|
| 1151 | + $my_children = $this->children(); |
|
| 1152 | + } |
|
| 1153 | + //we need to keep track of the running total for a single item, |
|
| 1154 | + //because we need to round as we go |
|
| 1155 | + $unit_price_for_total = 0; |
|
| 1156 | + $quantity_for_total = 1; |
|
| 1157 | + //get the total of all its children |
|
| 1158 | + foreach ($my_children as $child_line_item) { |
|
| 1159 | + if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) { |
|
| 1160 | + if ($child_line_item->is_percent()) { |
|
| 1161 | + //it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity |
|
| 1162 | + //not total multiplied by percent, because that ignores rounding along-the-way |
|
| 1163 | + $percent_unit_price = round( |
|
| 1164 | + $unit_price_for_total * $child_line_item->percent() / 100, |
|
| 1165 | + EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1166 | + ); |
|
| 1167 | + $percent_total = $percent_unit_price * $quantity_for_total; |
|
| 1168 | + $child_line_item->set_total($percent_total); |
|
| 1169 | + //so far all percent line items should have a quantity of 1 |
|
| 1170 | + //(ie, no double percent discounts. Although that might be requested someday) |
|
| 1171 | + $child_line_item->set_quantity(1); |
|
| 1172 | + $child_line_item->maybe_save(); |
|
| 1173 | + $calculated_total_so_far += $percent_total; |
|
| 1174 | + $unit_price_for_total += $percent_unit_price; |
|
| 1175 | + } else { |
|
| 1176 | + //verify flat sub-line-item quantities match their parent |
|
| 1177 | + if ($child_line_item->is_sub_line_item()) { |
|
| 1178 | + $child_line_item->set_quantity($this->quantity()); |
|
| 1179 | + } |
|
| 1180 | + $quantity_for_total = $child_line_item->quantity(); |
|
| 1181 | + $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1182 | + $unit_price_for_total += $child_line_item->unit_price(); |
|
| 1183 | + } |
|
| 1184 | + } |
|
| 1185 | + } |
|
| 1186 | + return $calculated_total_so_far; |
|
| 1187 | + } |
|
| 1188 | + |
|
| 1189 | + |
|
| 1190 | + |
|
| 1191 | + /** |
|
| 1192 | + * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets |
|
| 1193 | + * the totals on each tax calculated, and returns the final tax total |
|
| 1194 | + * |
|
| 1195 | + * @return float |
|
| 1196 | + * @throws EE_Error |
|
| 1197 | + */ |
|
| 1198 | + public function recalculate_taxes_and_tax_total() |
|
| 1199 | + { |
|
| 1200 | + //get all taxes |
|
| 1201 | + $taxes = $this->tax_descendants(); |
|
| 1202 | + //calculate the pretax total |
|
| 1203 | + $taxable_total = $this->taxable_total(); |
|
| 1204 | + $tax_total = 0; |
|
| 1205 | + foreach ($taxes as $tax) { |
|
| 1206 | + $total_on_this_tax = $taxable_total * $tax->percent() / 100; |
|
| 1207 | + //remember the total on this line item |
|
| 1208 | + $tax->set_total($total_on_this_tax); |
|
| 1209 | + $tax_total += $tax->total(); |
|
| 1210 | + } |
|
| 1211 | + $this->_recalculate_tax_sub_total(); |
|
| 1212 | + return $tax_total; |
|
| 1213 | + } |
|
| 1214 | + |
|
| 1215 | + |
|
| 1216 | + |
|
| 1217 | + /** |
|
| 1218 | + * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated |
|
| 1219 | + * |
|
| 1220 | + * @return void |
|
| 1221 | + * @throws EE_Error |
|
| 1222 | + */ |
|
| 1223 | + private function _recalculate_tax_sub_total() |
|
| 1224 | + { |
|
| 1225 | + if ($this->is_tax_sub_total()) { |
|
| 1226 | + $total = 0; |
|
| 1227 | + $total_percent = 0; |
|
| 1228 | + //simply loop through all its children (which should be taxes) and sum their total |
|
| 1229 | + foreach ($this->children() as $child_tax) { |
|
| 1230 | + if ($child_tax instanceof EE_Line_Item) { |
|
| 1231 | + $total += $child_tax->total(); |
|
| 1232 | + $total_percent += $child_tax->percent(); |
|
| 1233 | + } |
|
| 1234 | + } |
|
| 1235 | + $this->set_total($total); |
|
| 1236 | + $this->set_percent($total_percent); |
|
| 1237 | + } elseif ($this->is_total()) { |
|
| 1238 | + foreach ($this->children() as $maybe_tax_subtotal) { |
|
| 1239 | + if ($maybe_tax_subtotal instanceof EE_Line_Item) { |
|
| 1240 | + $maybe_tax_subtotal->_recalculate_tax_sub_total(); |
|
| 1241 | + } |
|
| 1242 | + } |
|
| 1243 | + } |
|
| 1244 | + } |
|
| 1245 | + |
|
| 1246 | + |
|
| 1247 | + |
|
| 1248 | + /** |
|
| 1249 | + * Gets the total tax on this line item. Assumes taxes have already been calculated using |
|
| 1250 | + * recalculate_taxes_and_total |
|
| 1251 | + * |
|
| 1252 | + * @return float |
|
| 1253 | + * @throws EE_Error |
|
| 1254 | + */ |
|
| 1255 | + public function get_total_tax() |
|
| 1256 | + { |
|
| 1257 | + $this->_recalculate_tax_sub_total(); |
|
| 1258 | + $total = 0; |
|
| 1259 | + foreach ($this->tax_descendants() as $tax_line_item) { |
|
| 1260 | + if ($tax_line_item instanceof EE_Line_Item) { |
|
| 1261 | + $total += $tax_line_item->total(); |
|
| 1262 | + } |
|
| 1263 | + } |
|
| 1264 | + return $total; |
|
| 1265 | + } |
|
| 1266 | + |
|
| 1267 | + |
|
| 1268 | + /** |
|
| 1269 | + * Gets the total for all the items purchased only |
|
| 1270 | + * |
|
| 1271 | + * @return float |
|
| 1272 | + * @throws EE_Error |
|
| 1273 | + */ |
|
| 1274 | + public function get_items_total() |
|
| 1275 | + { |
|
| 1276 | + //by default, let's make sure we're consistent with the existing line item |
|
| 1277 | + if ($this->is_total()) { |
|
| 1278 | + $pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this); |
|
| 1279 | + if ($pretax_subtotal_li instanceof EE_Line_Item) { |
|
| 1280 | + return $pretax_subtotal_li->total(); |
|
| 1281 | + } |
|
| 1282 | + } |
|
| 1283 | + $total = 0; |
|
| 1284 | + foreach ($this->get_items() as $item) { |
|
| 1285 | + if ($item instanceof EE_Line_Item) { |
|
| 1286 | + $total += $item->total(); |
|
| 1287 | + } |
|
| 1288 | + } |
|
| 1289 | + return $total; |
|
| 1290 | + } |
|
| 1291 | + |
|
| 1292 | + |
|
| 1293 | + |
|
| 1294 | + /** |
|
| 1295 | + * Gets all the descendants (ie, children or children of children etc) that |
|
| 1296 | + * are of the type 'tax' |
|
| 1297 | + * |
|
| 1298 | + * @return EE_Line_Item[] |
|
| 1299 | + */ |
|
| 1300 | + public function tax_descendants() |
|
| 1301 | + { |
|
| 1302 | + return EEH_Line_Item::get_tax_descendants($this); |
|
| 1303 | + } |
|
| 1304 | + |
|
| 1305 | + |
|
| 1306 | + |
|
| 1307 | + /** |
|
| 1308 | + * Gets all the real items purchased which are children of this item |
|
| 1309 | + * |
|
| 1310 | + * @return EE_Line_Item[] |
|
| 1311 | + */ |
|
| 1312 | + public function get_items() |
|
| 1313 | + { |
|
| 1314 | + return EEH_Line_Item::get_line_item_descendants($this); |
|
| 1315 | + } |
|
| 1316 | + |
|
| 1317 | + |
|
| 1318 | + |
|
| 1319 | + /** |
|
| 1320 | + * Returns the amount taxable among this line item's children (or if it has no children, |
|
| 1321 | + * how much of it is taxable). Does not recalculate totals or subtotals. |
|
| 1322 | + * If the taxable total is negative, (eg, if none of the tickets were taxable, |
|
| 1323 | + * but there is a "Taxable" discount), returns 0. |
|
| 1324 | + * |
|
| 1325 | + * @return float |
|
| 1326 | + * @throws EE_Error |
|
| 1327 | + */ |
|
| 1328 | + public function taxable_total() |
|
| 1329 | + { |
|
| 1330 | + $total = 0; |
|
| 1331 | + if ($this->children()) { |
|
| 1332 | + foreach ($this->children() as $child_line_item) { |
|
| 1333 | + if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) { |
|
| 1334 | + //if it's a percent item, only take into account the percent |
|
| 1335 | + //that's taxable too (the taxable total so far) |
|
| 1336 | + if ($child_line_item->is_percent()) { |
|
| 1337 | + $total += ($total * $child_line_item->percent() / 100); |
|
| 1338 | + } else { |
|
| 1339 | + $total += $child_line_item->total(); |
|
| 1340 | + } |
|
| 1341 | + } elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) { |
|
| 1342 | + $total += $child_line_item->taxable_total(); |
|
| 1343 | + } |
|
| 1344 | + } |
|
| 1345 | + } |
|
| 1346 | + return max($total, 0); |
|
| 1347 | + } |
|
| 1348 | + |
|
| 1349 | + |
|
| 1350 | + |
|
| 1351 | + /** |
|
| 1352 | + * Gets the transaction for this line item |
|
| 1353 | + * |
|
| 1354 | + * @return EE_Base_Class|EE_Transaction |
|
| 1355 | + * @throws EE_Error |
|
| 1356 | + */ |
|
| 1357 | + public function transaction() |
|
| 1358 | + { |
|
| 1359 | + return $this->get_first_related('Transaction'); |
|
| 1360 | + } |
|
| 1361 | + |
|
| 1362 | + |
|
| 1363 | + |
|
| 1364 | + /** |
|
| 1365 | + * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1366 | + * Because there currently is no proper parent-child relation on the model, |
|
| 1367 | + * save_this_and_cached() will NOT save the descendants. |
|
| 1368 | + * Also sets the transaction on this line item and all its descendants before saving |
|
| 1369 | + * |
|
| 1370 | + * @param int $txn_id if none is provided, assumes $this->TXN_ID() |
|
| 1371 | + * @return int count of items saved |
|
| 1372 | + * @throws EE_Error |
|
| 1373 | + */ |
|
| 1374 | + public function save_this_and_descendants_to_txn($txn_id = null) |
|
| 1375 | + { |
|
| 1376 | + $count = 0; |
|
| 1377 | + if (! $txn_id) { |
|
| 1378 | + $txn_id = $this->TXN_ID(); |
|
| 1379 | + } |
|
| 1380 | + $this->set_TXN_ID($txn_id); |
|
| 1381 | + $children = $this->children(); |
|
| 1382 | + $count += $this->save() |
|
| 1383 | + ? 1 |
|
| 1384 | + : 0; |
|
| 1385 | + foreach ($children as $child_line_item) { |
|
| 1386 | + if ($child_line_item instanceof EE_Line_Item) { |
|
| 1387 | + $child_line_item->set_parent_ID($this->ID()); |
|
| 1388 | + $count += $child_line_item->save_this_and_descendants_to_txn($txn_id); |
|
| 1389 | + } |
|
| 1390 | + } |
|
| 1391 | + return $count; |
|
| 1392 | + } |
|
| 1393 | + |
|
| 1394 | + |
|
| 1395 | + |
|
| 1396 | + /** |
|
| 1397 | + * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1398 | + * |
|
| 1399 | + * @return int count of items saved |
|
| 1400 | + * @throws EE_Error |
|
| 1401 | + */ |
|
| 1402 | + public function save_this_and_descendants() |
|
| 1403 | + { |
|
| 1404 | + $count = 0; |
|
| 1405 | + $children = $this->children(); |
|
| 1406 | + $count += $this->save() |
|
| 1407 | + ? 1 |
|
| 1408 | + : 0; |
|
| 1409 | + foreach ($children as $child_line_item) { |
|
| 1410 | + if ($child_line_item instanceof EE_Line_Item) { |
|
| 1411 | + $child_line_item->set_parent_ID($this->ID()); |
|
| 1412 | + $count += $child_line_item->save_this_and_descendants(); |
|
| 1413 | + } |
|
| 1414 | + } |
|
| 1415 | + return $count; |
|
| 1416 | + } |
|
| 1417 | + |
|
| 1418 | + |
|
| 1419 | + |
|
| 1420 | + /** |
|
| 1421 | + * returns the cancellation line item if this item was cancelled |
|
| 1422 | + * |
|
| 1423 | + * @return EE_Line_Item[] |
|
| 1424 | + * @throws InvalidArgumentException |
|
| 1425 | + * @throws InvalidInterfaceException |
|
| 1426 | + * @throws InvalidDataTypeException |
|
| 1427 | + * @throws ReflectionException |
|
| 1428 | + * @throws EE_Error |
|
| 1429 | + */ |
|
| 1430 | + public function get_cancellations() |
|
| 1431 | + { |
|
| 1432 | + EE_Registry::instance()->load_helper('Line_Item'); |
|
| 1433 | + return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation); |
|
| 1434 | + } |
|
| 1435 | + |
|
| 1436 | + |
|
| 1437 | + |
|
| 1438 | + /** |
|
| 1439 | + * If this item has an ID, then this saves it again to update the db |
|
| 1440 | + * |
|
| 1441 | + * @return int count of items saved |
|
| 1442 | + * @throws EE_Error |
|
| 1443 | + */ |
|
| 1444 | + public function maybe_save() |
|
| 1445 | + { |
|
| 1446 | + if ($this->ID()) { |
|
| 1447 | + return $this->save(); |
|
| 1448 | + } |
|
| 1449 | + return false; |
|
| 1450 | + } |
|
| 1451 | + |
|
| 1452 | + |
|
| 1453 | + /** |
|
| 1454 | + * clears the cached children and parent from the line item |
|
| 1455 | + * |
|
| 1456 | + * @return void |
|
| 1457 | + */ |
|
| 1458 | + public function clear_related_line_item_cache() |
|
| 1459 | + { |
|
| 1460 | + $this->_children = array(); |
|
| 1461 | + $this->_parent = null; |
|
| 1462 | + } |
|
| 1463 | + |
|
| 1464 | + |
|
| 1465 | + |
|
| 1466 | + /** |
|
| 1467 | + * @param bool $raw |
|
| 1468 | + * @return int |
|
| 1469 | + * @throws EE_Error |
|
| 1470 | + */ |
|
| 1471 | + public function timestamp($raw = false) |
|
| 1472 | + { |
|
| 1473 | + return $raw |
|
| 1474 | + ? $this->get_raw('LIN_timestamp') |
|
| 1475 | + : $this->get('LIN_timestamp'); |
|
| 1476 | + } |
|
| 1477 | + |
|
| 1478 | + |
|
| 1479 | + |
|
| 1480 | + |
|
| 1481 | + /************************* DEPRECATED *************************/ |
|
| 1482 | + /** |
|
| 1483 | + * @deprecated 4.6.0 |
|
| 1484 | + * @param string $type one of the constants on EEM_Line_Item |
|
| 1485 | + * @return EE_Line_Item[] |
|
| 1486 | + */ |
|
| 1487 | + protected function _get_descendants_of_type($type) |
|
| 1488 | + { |
|
| 1489 | + EE_Error::doing_it_wrong( |
|
| 1490 | + 'EE_Line_Item::_get_descendants_of_type()', |
|
| 1491 | + __('Method replaced with EEH_Line_Item::get_descendants_of_type()', 'event_espresso'), '4.6.0' |
|
| 1492 | + ); |
|
| 1493 | + return EEH_Line_Item::get_descendants_of_type($this, $type); |
|
| 1494 | + } |
|
| 1495 | + |
|
| 1496 | + |
|
| 1497 | + |
|
| 1498 | + /** |
|
| 1499 | + * @deprecated 4.6.0 |
|
| 1500 | + * @param string $type like one of the EEM_Line_Item::type_* |
|
| 1501 | + * @return EE_Line_Item |
|
| 1502 | + */ |
|
| 1503 | + public function get_nearest_descendant_of_type($type) |
|
| 1504 | + { |
|
| 1505 | + EE_Error::doing_it_wrong( |
|
| 1506 | + 'EE_Line_Item::get_nearest_descendant_of_type()', |
|
| 1507 | + __('Method replaced with EEH_Line_Item::get_nearest_descendant_of_type()', 'event_espresso'), '4.6.0' |
|
| 1508 | + ); |
|
| 1509 | + return EEH_Line_Item::get_nearest_descendant_of_type($this, $type); |
|
| 1510 | + } |
|
| 1511 | 1511 | |
| 1512 | 1512 | |
| 1513 | 1513 | |
@@ -79,7 +79,7 @@ discard block |
||
| 79 | 79 | protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') |
| 80 | 80 | { |
| 81 | 81 | parent::__construct($fieldValues, $bydb, $timezone); |
| 82 | - if (! $this->get('LIN_code')) { |
|
| 82 | + if ( ! $this->get('LIN_code')) { |
|
| 83 | 83 | $this->set_code($this->generate_code()); |
| 84 | 84 | } |
| 85 | 85 | } |
@@ -134,7 +134,7 @@ discard block |
||
| 134 | 134 | public function name() |
| 135 | 135 | { |
| 136 | 136 | $name = $this->get('LIN_name'); |
| 137 | - if (! $name) { |
|
| 137 | + if ( ! $name) { |
|
| 138 | 138 | $name = ucwords(str_replace('-', ' ', $this->type())); |
| 139 | 139 | } |
| 140 | 140 | return $name; |
@@ -515,7 +515,7 @@ discard block |
||
| 515 | 515 | ) |
| 516 | 516 | ); |
| 517 | 517 | } |
| 518 | - if (! is_array($this->_children)) { |
|
| 518 | + if ( ! is_array($this->_children)) { |
|
| 519 | 519 | $this->_children = array(); |
| 520 | 520 | } |
| 521 | 521 | return $this->_children; |
@@ -741,7 +741,7 @@ discard block |
||
| 741 | 741 | public function set_parent($line_item) |
| 742 | 742 | { |
| 743 | 743 | if ($this->ID()) { |
| 744 | - if (! $line_item->ID()) { |
|
| 744 | + if ( ! $line_item->ID()) { |
|
| 745 | 745 | $line_item->save(); |
| 746 | 746 | } |
| 747 | 747 | $this->set_parent_ID($line_item->ID()); |
@@ -815,7 +815,7 @@ discard block |
||
| 815 | 815 | $items_deleted = 0; |
| 816 | 816 | if ($this->code() === $code) { |
| 817 | 817 | $items_deleted += EEH_Line_Item::delete_all_child_items($this); |
| 818 | - $items_deleted += (int)$this->delete(); |
|
| 818 | + $items_deleted += (int) $this->delete(); |
|
| 819 | 819 | if ($stop_search_once_found) { |
| 820 | 820 | return $items_deleted; |
| 821 | 821 | } |
@@ -860,7 +860,7 @@ discard block |
||
| 860 | 860 | public function generate_code() |
| 861 | 861 | { |
| 862 | 862 | // each line item in the cart requires a unique identifier |
| 863 | - return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime()); |
|
| 863 | + return md5($this->get('OBJ_type').$this->get('OBJ_ID').microtime()); |
|
| 864 | 864 | } |
| 865 | 865 | |
| 866 | 866 | |
@@ -1035,7 +1035,7 @@ discard block |
||
| 1035 | 1035 | $has_children = ! empty($my_children); |
| 1036 | 1036 | if ($has_children && $this->is_line_item()) { |
| 1037 | 1037 | $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children); |
| 1038 | - } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
| 1038 | + } elseif ( ! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
| 1039 | 1039 | $total = $this->unit_price() * $this->quantity(); |
| 1040 | 1040 | } elseif ($this->is_sub_total() || $this->is_total()) { |
| 1041 | 1041 | $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children); |
@@ -1050,13 +1050,13 @@ discard block |
||
| 1050 | 1050 | if ($this->OBJ_type() !== 'Event') { |
| 1051 | 1051 | $this->set_quantity(1); |
| 1052 | 1052 | } |
| 1053 | - if (! $this->is_percent()) { |
|
| 1053 | + if ( ! $this->is_percent()) { |
|
| 1054 | 1054 | $this->set_unit_price($total); |
| 1055 | 1055 | } |
| 1056 | 1056 | } |
| 1057 | 1057 | //we don't want to bother saving grand totals, because that needs to factor in taxes anyways |
| 1058 | 1058 | //so it ought to be |
| 1059 | - if (! $this->is_total()) { |
|
| 1059 | + if ( ! $this->is_total()) { |
|
| 1060 | 1060 | $this->set_total($total); |
| 1061 | 1061 | //if not a percent line item, make sure we keep the unit price in sync |
| 1062 | 1062 | if ( |
@@ -1374,7 +1374,7 @@ discard block |
||
| 1374 | 1374 | public function save_this_and_descendants_to_txn($txn_id = null) |
| 1375 | 1375 | { |
| 1376 | 1376 | $count = 0; |
| 1377 | - if (! $txn_id) { |
|
| 1377 | + if ( ! $txn_id) { |
|
| 1378 | 1378 | $txn_id = $this->TXN_ID(); |
| 1379 | 1379 | } |
| 1380 | 1380 | $this->set_TXN_ID($txn_id); |
@@ -863,7 +863,7 @@ |
||
| 863 | 863 | * handles toggling the checkin status for the registration, |
| 864 | 864 | * |
| 865 | 865 | * @access protected |
| 866 | - * @return int|void |
|
| 866 | + * @return integer |
|
| 867 | 867 | */ |
| 868 | 868 | protected function _toggle_checkin_status() |
| 869 | 869 | { |
@@ -38,9 +38,9 @@ discard block |
||
| 38 | 38 | { |
| 39 | 39 | parent::__construct($routing); |
| 40 | 40 | if ( ! defined('REG_CAF_TEMPLATE_PATH')) { |
| 41 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 42 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 43 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 41 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'registrations/templates/'); |
|
| 42 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'registrations/assets/'); |
|
| 43 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registrations/assets/'); |
|
| 44 | 44 | } |
| 45 | 45 | } |
| 46 | 46 | |
@@ -48,7 +48,7 @@ discard block |
||
| 48 | 48 | |
| 49 | 49 | protected function _extend_page_config() |
| 50 | 50 | { |
| 51 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 51 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'registrations'; |
|
| 52 | 52 | $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
| 53 | 53 | ? $this->_req_data['_REG_ID'] |
| 54 | 54 | : 0; |
@@ -181,14 +181,14 @@ discard block |
||
| 181 | 181 | //enqueue newsletter js |
| 182 | 182 | wp_enqueue_script( |
| 183 | 183 | 'ee-newsletter-trigger', |
| 184 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 184 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.js', |
|
| 185 | 185 | array('ee-dialog'), |
| 186 | 186 | EVENT_ESPRESSO_VERSION, |
| 187 | 187 | true |
| 188 | 188 | ); |
| 189 | 189 | wp_enqueue_style( |
| 190 | 190 | 'ee-newsletter-trigger-css', |
| 191 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 191 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.css', |
|
| 192 | 192 | array(), |
| 193 | 193 | EVENT_ESPRESSO_VERSION |
| 194 | 194 | ); |
@@ -207,7 +207,7 @@ discard block |
||
| 207 | 207 | { |
| 208 | 208 | wp_register_script( |
| 209 | 209 | 'ee-reg-reports-js', |
| 210 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 210 | + REG_CAF_ASSETS_URL.'ee-registration-admin-reports.js', |
|
| 211 | 211 | array('google-charts'), |
| 212 | 212 | EVENT_ESPRESSO_VERSION, |
| 213 | 213 | true |
@@ -412,7 +412,7 @@ discard block |
||
| 412 | 412 | $codes[$field] = implode(', ', array_keys($shortcode_array)); |
| 413 | 413 | } |
| 414 | 414 | $shortcodes = $codes; |
| 415 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 415 | + $form_template = REG_CAF_TEMPLATE_PATH.'newsletter-send-form.template.php'; |
|
| 416 | 416 | $form_template_args = array( |
| 417 | 417 | 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
| 418 | 418 | 'form_route' => 'newsletter_selected_send', |
@@ -573,7 +573,7 @@ discard block |
||
| 573 | 573 | */ |
| 574 | 574 | protected function _registration_reports() |
| 575 | 575 | { |
| 576 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 576 | + $template_path = EE_ADMIN_TEMPLATE.'admin_reports.template.php'; |
|
| 577 | 577 | $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
| 578 | 578 | $template_path, |
| 579 | 579 | $this->_reports_template_data, |
@@ -595,7 +595,7 @@ discard block |
||
| 595 | 595 | { |
| 596 | 596 | $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
| 597 | 597 | $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
| 598 | - $results = (array)$results; |
|
| 598 | + $results = (array) $results; |
|
| 599 | 599 | $regs = array(); |
| 600 | 600 | $subtitle = ''; |
| 601 | 601 | if ($results) { |
@@ -605,7 +605,7 @@ discard block |
||
| 605 | 605 | $report_column_values = array(); |
| 606 | 606 | foreach ($result as $property_name => $property_value) { |
| 607 | 607 | $property_value = $property_name === 'Registration_REG_date' ? $property_value |
| 608 | - : (int)$property_value; |
|
| 608 | + : (int) $property_value; |
|
| 609 | 609 | $report_column_values[] = $property_value; |
| 610 | 610 | if ($tracker === 0) { |
| 611 | 611 | if ($property_name === 'Registration_REG_date') { |
@@ -622,7 +622,7 @@ discard block |
||
| 622 | 622 | array_unshift($regs, $column_titles); |
| 623 | 623 | //setup the date range. |
| 624 | 624 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
| 625 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 625 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
| 626 | 626 | $ending_date = new DateTime("now", $DateTimeZone); |
| 627 | 627 | $subtitle = sprintf( |
| 628 | 628 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -642,7 +642,7 @@ discard block |
||
| 642 | 642 | '%sThere are currently no registration records in the last month for this report.%s', |
| 643 | 643 | 'event_espresso' |
| 644 | 644 | ), |
| 645 | - '<h2>' . $report_title . '</h2><p>', |
|
| 645 | + '<h2>'.$report_title.'</h2><p>', |
|
| 646 | 646 | '</p>' |
| 647 | 647 | ), |
| 648 | 648 | ); |
@@ -662,7 +662,7 @@ discard block |
||
| 662 | 662 | { |
| 663 | 663 | $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
| 664 | 664 | $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
| 665 | - $results = (array)$results; |
|
| 665 | + $results = (array) $results; |
|
| 666 | 666 | $regs = array(); |
| 667 | 667 | $subtitle = ''; |
| 668 | 668 | if ($results) { |
@@ -675,7 +675,7 @@ discard block |
||
| 675 | 675 | $property_value, |
| 676 | 676 | 4, |
| 677 | 677 | '...' |
| 678 | - ) : (int)$property_value; |
|
| 678 | + ) : (int) $property_value; |
|
| 679 | 679 | $report_column_values[] = $property_value; |
| 680 | 680 | if ($tracker === 0) { |
| 681 | 681 | if ($property_name === 'Registration_Event') { |
@@ -692,7 +692,7 @@ discard block |
||
| 692 | 692 | array_unshift($regs, $column_titles); |
| 693 | 693 | //setup the date range. |
| 694 | 694 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
| 695 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 695 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
| 696 | 696 | $ending_date = new DateTime("now", $DateTimeZone); |
| 697 | 697 | $subtitle = sprintf( |
| 698 | 698 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -712,7 +712,7 @@ discard block |
||
| 712 | 712 | '%sThere are currently no registration records in the last month for this report.%s', |
| 713 | 713 | 'event_espresso' |
| 714 | 714 | ), |
| 715 | - '<h2>' . $report_title . '</h2><p>', |
|
| 715 | + '<h2>'.$report_title.'</h2><p>', |
|
| 716 | 716 | '</p>' |
| 717 | 717 | ), |
| 718 | 718 | ); |
@@ -762,7 +762,7 @@ discard block |
||
| 762 | 762 | if ($datetime instanceof EE_Datetime) { |
| 763 | 763 | $datetime_label = $datetime->get_dtt_display_name(true); |
| 764 | 764 | $datetime_label .= ! empty($datetime_label) |
| 765 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 765 | + ? ' ('.$datetime->get_dtt_display_name().')' |
|
| 766 | 766 | : $datetime->get_dtt_display_name(); |
| 767 | 767 | } |
| 768 | 768 | $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
@@ -776,7 +776,7 @@ discard block |
||
| 776 | 776 | ) |
| 777 | 777 | : ''; |
| 778 | 778 | $datetime_link = ! empty($datetime_link) |
| 779 | - ? '<a href="' . $datetime_link . '">' |
|
| 779 | + ? '<a href="'.$datetime_link.'">' |
|
| 780 | 780 | . '<span id="checkin-dtt">' |
| 781 | 781 | . $datetime_label |
| 782 | 782 | . '</span></a>' |
@@ -788,8 +788,8 @@ discard block |
||
| 788 | 788 | ? $attendee->get_admin_details_link() |
| 789 | 789 | : ''; |
| 790 | 790 | $attendee_link = ! empty($attendee_link) |
| 791 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 792 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 791 | + ? '<a href="'.$attendee->get_admin_details_link().'"' |
|
| 792 | + . ' title="'.esc_html__('Click for attendee details', 'event_espresso').'">' |
|
| 793 | 793 | . '<span id="checkin-attendee-name">' |
| 794 | 794 | . $attendee_name |
| 795 | 795 | . '</span></a>' |
@@ -798,25 +798,25 @@ discard block |
||
| 798 | 798 | ? $registration->event()->get_admin_details_link() |
| 799 | 799 | : ''; |
| 800 | 800 | $event_link = ! empty($event_link) |
| 801 | - ? '<a href="' . $event_link . '"' |
|
| 802 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 801 | + ? '<a href="'.$event_link.'"' |
|
| 802 | + . ' title="'.esc_html__('Click here to edit event.', 'event_espresso').'">' |
|
| 803 | 803 | . '<span id="checkin-event-name">' |
| 804 | 804 | . $registration->event_name() |
| 805 | 805 | . '</span>' |
| 806 | 806 | . '</a>' |
| 807 | 807 | : ''; |
| 808 | 808 | $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
| 809 | - ? '<h2>' . sprintf( |
|
| 809 | + ? '<h2>'.sprintf( |
|
| 810 | 810 | esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
| 811 | 811 | $attendee_link, |
| 812 | 812 | $datetime_link, |
| 813 | 813 | $event_link |
| 814 | - ) . '</h2>' |
|
| 814 | + ).'</h2>' |
|
| 815 | 815 | : ''; |
| 816 | 816 | $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
| 817 | - ? '<input type="hidden" name="_REGID" value="' . $reg_id . '">' : ''; |
|
| 817 | + ? '<input type="hidden" name="_REGID" value="'.$reg_id.'">' : ''; |
|
| 818 | 818 | $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
| 819 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 819 | + ? '<input type="hidden" name="DTT_ID" value="'.$dtt_id.'">' : ''; |
|
| 820 | 820 | $this->display_admin_list_table_page_with_no_sidebar(); |
| 821 | 821 | } |
| 822 | 822 | |
@@ -852,7 +852,7 @@ discard block |
||
| 852 | 852 | //beautiful! Made it this far so let's get the status. |
| 853 | 853 | $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
| 854 | 854 | //setup new class to return via ajax |
| 855 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 855 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin '.$new_status->cssClasses(); |
|
| 856 | 856 | $this->_template_args['success'] = true; |
| 857 | 857 | $this->_return_json(); |
| 858 | 858 | } |
@@ -1059,37 +1059,37 @@ discard block |
||
| 1059 | 1059 | 'desc' => __('View All Check-in Records for this Registrant', 'event_espresso'), |
| 1060 | 1060 | ), |
| 1061 | 1061 | 'approved_status' => array( |
| 1062 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1062 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_approved, |
|
| 1063 | 1063 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
| 1064 | 1064 | ), |
| 1065 | 1065 | 'cancelled_status' => array( |
| 1066 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1066 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_cancelled, |
|
| 1067 | 1067 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
| 1068 | 1068 | ), |
| 1069 | 1069 | 'declined_status' => array( |
| 1070 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1070 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_declined, |
|
| 1071 | 1071 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
| 1072 | 1072 | ), |
| 1073 | 1073 | 'not_approved' => array( |
| 1074 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1074 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_not_approved, |
|
| 1075 | 1075 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
| 1076 | 1076 | ), |
| 1077 | 1077 | 'pending_status' => array( |
| 1078 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1078 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_pending_payment, |
|
| 1079 | 1079 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
| 1080 | 1080 | ), |
| 1081 | 1081 | 'wait_list' => array( |
| 1082 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1082 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_wait_list, |
|
| 1083 | 1083 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
| 1084 | 1084 | ), |
| 1085 | 1085 | ); |
| 1086 | 1086 | $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
| 1087 | 1087 | $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
| 1088 | 1088 | $this->_template_args['before_list_table'] = ! empty($event_id) |
| 1089 | - ? '<h2>' . sprintf( |
|
| 1089 | + ? '<h2>'.sprintf( |
|
| 1090 | 1090 | __('Viewing Registrations for Event: %s', 'event_espresso'), |
| 1091 | 1091 | EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
| 1092 | - ) . '</h2>' |
|
| 1092 | + ).'</h2>' |
|
| 1093 | 1093 | : ''; |
| 1094 | 1094 | //need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on the event. |
| 1095 | 1095 | /** @var EE_Event $event */ |
@@ -1108,7 +1108,7 @@ discard block |
||
| 1108 | 1108 | $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
| 1109 | 1109 | $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
| 1110 | 1110 | $this->_template_args['before_list_table'] .= $datetime->name(); |
| 1111 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1111 | + $this->_template_args['before_list_table'] .= ' ( '.$datetime->date_and_time_range().' )'; |
|
| 1112 | 1112 | $this->_template_args['before_list_table'] .= '</span></h2>'; |
| 1113 | 1113 | } |
| 1114 | 1114 | //if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status column |
@@ -1175,11 +1175,11 @@ discard block |
||
| 1175 | 1175 | //normalize some request params that get setup by the parent `get_registrations` method. |
| 1176 | 1176 | $request = $this->_req_data; |
| 1177 | 1177 | $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
| 1178 | - $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1179 | - if($trash){ |
|
| 1178 | + $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1179 | + if ($trash) { |
|
| 1180 | 1180 | $request['status'] = 'trash'; |
| 1181 | 1181 | } |
| 1182 | - $query_params = $this->_get_checkin_query_params_from_request( $request, $per_page, $count ); |
|
| 1182 | + $query_params = $this->_get_checkin_query_params_from_request($request, $per_page, $count); |
|
| 1183 | 1183 | /** |
| 1184 | 1184 | * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
| 1185 | 1185 | * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
@@ -3,7 +3,7 @@ discard block |
||
| 3 | 3 | use EventEspresso\ui\browser\checkins\entities\CheckinStatusDashicon; |
| 4 | 4 | |
| 5 | 5 | if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
| 6 | - exit('NO direct script access allowed'); |
|
| 6 | + exit('NO direct script access allowed'); |
|
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | |
@@ -20,1182 +20,1182 @@ discard block |
||
| 20 | 20 | { |
| 21 | 21 | |
| 22 | 22 | |
| 23 | - /** |
|
| 24 | - * This is used to hold the reports template data which is setup early in the request. |
|
| 25 | - * |
|
| 26 | - * @type array |
|
| 27 | - */ |
|
| 28 | - protected $_reports_template_data = array(); |
|
| 29 | - |
|
| 30 | - |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * Extend_Registrations_Admin_Page constructor. |
|
| 34 | - * |
|
| 35 | - * @param bool $routing |
|
| 36 | - */ |
|
| 37 | - public function __construct($routing = true) |
|
| 38 | - { |
|
| 39 | - parent::__construct($routing); |
|
| 40 | - if ( ! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 41 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 42 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 43 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 44 | - } |
|
| 45 | - } |
|
| 46 | - |
|
| 47 | - |
|
| 48 | - |
|
| 49 | - protected function _extend_page_config() |
|
| 50 | - { |
|
| 51 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 52 | - $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
| 53 | - ? $this->_req_data['_REG_ID'] |
|
| 54 | - : 0; |
|
| 55 | - // $att_id = ! empty( $this->_req_data['ATT_ID'] ) ? ! is_array( $this->_req_data['ATT_ID'] ) : 0; |
|
| 56 | - // $att_id = ! empty( $this->_req_data['post'] ) && ! is_array( $this->_req_data['post'] ) |
|
| 57 | - // ? $this->_req_data['post'] : $att_id; |
|
| 58 | - $new_page_routes = array( |
|
| 59 | - 'reports' => array( |
|
| 60 | - 'func' => '_registration_reports', |
|
| 61 | - 'capability' => 'ee_read_registrations', |
|
| 62 | - ), |
|
| 63 | - 'registration_checkins' => array( |
|
| 64 | - 'func' => '_registration_checkin_list_table', |
|
| 65 | - 'capability' => 'ee_read_checkins', |
|
| 66 | - ), |
|
| 67 | - 'newsletter_selected_send' => array( |
|
| 68 | - 'func' => '_newsletter_selected_send', |
|
| 69 | - 'noheader' => true, |
|
| 70 | - 'capability' => 'ee_send_message', |
|
| 71 | - ), |
|
| 72 | - 'delete_checkin_rows' => array( |
|
| 73 | - 'func' => '_delete_checkin_rows', |
|
| 74 | - 'noheader' => true, |
|
| 75 | - 'capability' => 'ee_delete_checkins', |
|
| 76 | - ), |
|
| 77 | - 'delete_checkin_row' => array( |
|
| 78 | - 'func' => '_delete_checkin_row', |
|
| 79 | - 'noheader' => true, |
|
| 80 | - 'capability' => 'ee_delete_checkin', |
|
| 81 | - 'obj_id' => $reg_id, |
|
| 82 | - ), |
|
| 83 | - 'toggle_checkin_status' => array( |
|
| 84 | - 'func' => '_toggle_checkin_status', |
|
| 85 | - 'noheader' => true, |
|
| 86 | - 'capability' => 'ee_edit_checkin', |
|
| 87 | - 'obj_id' => $reg_id, |
|
| 88 | - ), |
|
| 89 | - 'toggle_checkin_status_bulk' => array( |
|
| 90 | - 'func' => '_toggle_checkin_status', |
|
| 91 | - 'noheader' => true, |
|
| 92 | - 'capability' => 'ee_edit_checkins' |
|
| 93 | - ), |
|
| 94 | - 'event_registrations' => array( |
|
| 95 | - 'func' => '_event_registrations_list_table', |
|
| 96 | - 'capability' => 'ee_read_checkins', |
|
| 97 | - ), |
|
| 98 | - 'registrations_checkin_report' => array( |
|
| 99 | - 'func' => '_registrations_checkin_report', |
|
| 100 | - 'noheader' => true, |
|
| 101 | - 'capability' => 'ee_read_registrations', |
|
| 102 | - ), |
|
| 103 | - ); |
|
| 104 | - $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
| 105 | - $new_page_config = array( |
|
| 106 | - 'reports' => array( |
|
| 107 | - 'nav' => array( |
|
| 108 | - 'label' => __('Reports', 'event_espresso'), |
|
| 109 | - 'order' => 30, |
|
| 110 | - ), |
|
| 111 | - 'help_tabs' => array( |
|
| 112 | - 'registrations_reports_help_tab' => array( |
|
| 113 | - 'title' => __('Registration Reports', 'event_espresso'), |
|
| 114 | - 'filename' => 'registrations_reports', |
|
| 115 | - ), |
|
| 116 | - ), |
|
| 117 | - /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
| 118 | - 'require_nonce' => false, |
|
| 119 | - ), |
|
| 120 | - 'event_registrations' => array( |
|
| 121 | - 'nav' => array( |
|
| 122 | - 'label' => __('Event Check-In', 'event_espresso'), |
|
| 123 | - 'order' => 10, |
|
| 124 | - 'persistent' => true, |
|
| 125 | - ), |
|
| 126 | - 'help_tabs' => array( |
|
| 127 | - 'registrations_event_checkin_help_tab' => array( |
|
| 128 | - 'title' => __('Registrations Event Check-In', 'event_espresso'), |
|
| 129 | - 'filename' => 'registrations_event_checkin', |
|
| 130 | - ), |
|
| 131 | - 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
| 132 | - 'title' => __('Event Check-In Table Column Headings', 'event_espresso'), |
|
| 133 | - 'filename' => 'registrations_event_checkin_table_column_headings', |
|
| 134 | - ), |
|
| 135 | - 'registrations_event_checkin_filters_help_tab' => array( |
|
| 136 | - 'title' => __('Event Check-In Filters', 'event_espresso'), |
|
| 137 | - 'filename' => 'registrations_event_checkin_filters', |
|
| 138 | - ), |
|
| 139 | - 'registrations_event_checkin_views_help_tab' => array( |
|
| 140 | - 'title' => __('Event Check-In Views', 'event_espresso'), |
|
| 141 | - 'filename' => 'registrations_event_checkin_views', |
|
| 142 | - ), |
|
| 143 | - 'registrations_event_checkin_other_help_tab' => array( |
|
| 144 | - 'title' => __('Event Check-In Other', 'event_espresso'), |
|
| 145 | - 'filename' => 'registrations_event_checkin_other', |
|
| 146 | - ), |
|
| 147 | - ), |
|
| 148 | - 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
| 149 | - 'qtips' => array('Registration_List_Table_Tips'), |
|
| 150 | - 'list_table' => 'EE_Event_Registrations_List_Table', |
|
| 151 | - 'metaboxes' => array(), |
|
| 152 | - 'require_nonce' => false, |
|
| 153 | - ), |
|
| 154 | - 'registration_checkins' => array( |
|
| 155 | - 'nav' => array( |
|
| 156 | - 'label' => __('Check-In Records', 'event_espresso'), |
|
| 157 | - 'order' => 15, |
|
| 158 | - 'persistent' => false, |
|
| 159 | - ), |
|
| 160 | - 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
| 161 | - //'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
| 162 | - 'metaboxes' => array(), |
|
| 163 | - 'require_nonce' => false, |
|
| 164 | - ), |
|
| 165 | - ); |
|
| 166 | - $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
| 167 | - $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
| 168 | - $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
| 169 | - } |
|
| 170 | - |
|
| 171 | - |
|
| 172 | - |
|
| 173 | - protected function _ajax_hooks() |
|
| 174 | - { |
|
| 175 | - parent::_ajax_hooks(); |
|
| 176 | - add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
| 177 | - } |
|
| 178 | - |
|
| 179 | - |
|
| 180 | - |
|
| 181 | - public function load_scripts_styles() |
|
| 182 | - { |
|
| 183 | - parent::load_scripts_styles(); |
|
| 184 | - //if newsletter message type is active then let's add filter and load js for it. |
|
| 185 | - if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
| 186 | - //enqueue newsletter js |
|
| 187 | - wp_enqueue_script( |
|
| 188 | - 'ee-newsletter-trigger', |
|
| 189 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 190 | - array('ee-dialog'), |
|
| 191 | - EVENT_ESPRESSO_VERSION, |
|
| 192 | - true |
|
| 193 | - ); |
|
| 194 | - wp_enqueue_style( |
|
| 195 | - 'ee-newsletter-trigger-css', |
|
| 196 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 197 | - array(), |
|
| 198 | - EVENT_ESPRESSO_VERSION |
|
| 199 | - ); |
|
| 200 | - //hook in buttons for newsletter message type trigger. |
|
| 201 | - add_action( |
|
| 202 | - 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
| 203 | - array($this, 'add_newsletter_action_buttons'), |
|
| 204 | - 10 |
|
| 205 | - ); |
|
| 206 | - } |
|
| 207 | - } |
|
| 208 | - |
|
| 209 | - |
|
| 210 | - |
|
| 211 | - public function load_scripts_styles_reports() |
|
| 212 | - { |
|
| 213 | - wp_register_script( |
|
| 214 | - 'ee-reg-reports-js', |
|
| 215 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 216 | - array('google-charts'), |
|
| 217 | - EVENT_ESPRESSO_VERSION, |
|
| 218 | - true |
|
| 219 | - ); |
|
| 220 | - wp_enqueue_script('ee-reg-reports-js'); |
|
| 221 | - $this->_registration_reports_js_setup(); |
|
| 222 | - } |
|
| 223 | - |
|
| 224 | - |
|
| 225 | - |
|
| 226 | - protected function _add_screen_options_event_registrations() |
|
| 227 | - { |
|
| 228 | - $this->_per_page_screen_option(); |
|
| 229 | - } |
|
| 230 | - |
|
| 231 | - |
|
| 232 | - |
|
| 233 | - protected function _add_screen_options_registration_checkins() |
|
| 234 | - { |
|
| 235 | - $page_title = $this->_admin_page_title; |
|
| 236 | - $this->_admin_page_title = __('Check-In Records', 'event_espresso'); |
|
| 237 | - $this->_per_page_screen_option(); |
|
| 238 | - $this->_admin_page_title = $page_title; |
|
| 239 | - } |
|
| 240 | - |
|
| 241 | - |
|
| 242 | - |
|
| 243 | - protected function _set_list_table_views_event_registrations() |
|
| 244 | - { |
|
| 245 | - $this->_views = array( |
|
| 246 | - 'all' => array( |
|
| 247 | - 'slug' => 'all', |
|
| 248 | - 'label' => __('All', 'event_espresso'), |
|
| 249 | - 'count' => 0, |
|
| 250 | - 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
| 251 | - ? array() |
|
| 252 | - : array( |
|
| 253 | - 'toggle_checkin_status_bulk' => __('Toggle Check-In', 'event_espresso'), |
|
| 254 | - ), |
|
| 255 | - ), |
|
| 256 | - ); |
|
| 257 | - } |
|
| 258 | - |
|
| 259 | - |
|
| 260 | - |
|
| 261 | - protected function _set_list_table_views_registration_checkins() |
|
| 262 | - { |
|
| 263 | - $this->_views = array( |
|
| 264 | - 'all' => array( |
|
| 265 | - 'slug' => 'all', |
|
| 266 | - 'label' => __('All', 'event_espresso'), |
|
| 267 | - 'count' => 0, |
|
| 268 | - 'bulk_action' => array('delete_checkin_rows' => __('Delete Check-In Rows', 'event_espresso')), |
|
| 269 | - ), |
|
| 270 | - ); |
|
| 271 | - } |
|
| 272 | - |
|
| 273 | - |
|
| 274 | - |
|
| 275 | - /** |
|
| 276 | - * callback for ajax action. |
|
| 277 | - * |
|
| 278 | - * @since 4.3.0 |
|
| 279 | - * @return void (JSON) |
|
| 280 | - * @throws \EE_Error |
|
| 281 | - */ |
|
| 282 | - public function get_newsletter_form_content() |
|
| 283 | - { |
|
| 284 | - //do a nonce check cause we're not coming in from an normal route here. |
|
| 285 | - $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
| 286 | - $this->_req_data['get_newsletter_form_content_nonce'] |
|
| 287 | - ) : ''; |
|
| 288 | - $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
| 289 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
| 290 | - //let's get the mtp for the incoming MTP_ ID |
|
| 291 | - if ( ! isset($this->_req_data['GRP_ID'])) { |
|
| 292 | - EE_Error::add_error( |
|
| 293 | - __( |
|
| 294 | - '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).', |
|
| 295 | - 'event_espresso' |
|
| 296 | - ), |
|
| 297 | - __FILE__, |
|
| 298 | - __FUNCTION__, |
|
| 299 | - __LINE__ |
|
| 300 | - ); |
|
| 301 | - $this->_template_args['success'] = false; |
|
| 302 | - $this->_template_args['error'] = true; |
|
| 303 | - $this->_return_json(); |
|
| 304 | - } |
|
| 305 | - $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
| 306 | - if ( ! $MTPG instanceof EE_Message_Template_Group) { |
|
| 307 | - EE_Error::add_error( |
|
| 308 | - sprintf( |
|
| 309 | - __( |
|
| 310 | - 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
| 311 | - 'event_espresso' |
|
| 312 | - ), |
|
| 313 | - $this->_req_data['GRP_ID'] |
|
| 314 | - ), |
|
| 315 | - __FILE__, |
|
| 316 | - __FUNCTION__, |
|
| 317 | - __LINE__ |
|
| 318 | - ); |
|
| 319 | - $this->_template_args['success'] = false; |
|
| 320 | - $this->_template_args['error'] = true; |
|
| 321 | - $this->_return_json(); |
|
| 322 | - } |
|
| 323 | - $MTPs = $MTPG->context_templates(); |
|
| 324 | - $MTPs = $MTPs['attendee']; |
|
| 325 | - $template_fields = array(); |
|
| 326 | - /** @var EE_Message_Template $MTP */ |
|
| 327 | - foreach ($MTPs as $MTP) { |
|
| 328 | - $field = $MTP->get('MTP_template_field'); |
|
| 329 | - if ($field === 'content') { |
|
| 330 | - $content = $MTP->get('MTP_content'); |
|
| 331 | - if ( ! empty($content['newsletter_content'])) { |
|
| 332 | - $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
| 333 | - } |
|
| 334 | - continue; |
|
| 335 | - } |
|
| 336 | - $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content'); |
|
| 337 | - } |
|
| 338 | - $this->_template_args['success'] = true; |
|
| 339 | - $this->_template_args['error'] = false; |
|
| 340 | - $this->_template_args['data'] = array( |
|
| 341 | - 'batch_message_from' => isset($template_fields['from']) |
|
| 342 | - ? $template_fields['from'] |
|
| 343 | - : '', |
|
| 344 | - 'batch_message_subject' => isset($template_fields['subject']) |
|
| 345 | - ? $template_fields['subject'] |
|
| 346 | - : '', |
|
| 347 | - 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
| 348 | - ? $template_fields['newsletter_content'] |
|
| 349 | - : '', |
|
| 350 | - ); |
|
| 351 | - $this->_return_json(); |
|
| 352 | - } |
|
| 353 | - |
|
| 354 | - |
|
| 355 | - |
|
| 356 | - /** |
|
| 357 | - * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
| 358 | - * |
|
| 359 | - * @since 4.3.0 |
|
| 360 | - * @param EE_Admin_List_Table $list_table |
|
| 361 | - * @return void |
|
| 362 | - */ |
|
| 363 | - public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
| 364 | - { |
|
| 365 | - if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
| 366 | - 'ee_send_message', |
|
| 367 | - 'espresso_registrations_newsletter_selected_send' |
|
| 368 | - ) |
|
| 369 | - ) { |
|
| 370 | - return; |
|
| 371 | - } |
|
| 372 | - $routes_to_add_to = array( |
|
| 373 | - 'contact_list', |
|
| 374 | - 'event_registrations', |
|
| 375 | - 'default', |
|
| 376 | - ); |
|
| 377 | - if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
| 378 | - if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
| 379 | - || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
| 380 | - ) { |
|
| 381 | - echo ''; |
|
| 382 | - } else { |
|
| 383 | - $button_text = sprintf( |
|
| 384 | - __('Send Batch Message (%s selected)', 'event_espresso'), |
|
| 385 | - '<span class="send-selected-newsletter-count">0</span>' |
|
| 386 | - ); |
|
| 387 | - echo '<button id="selected-batch-send-trigger" class="button secondary-button"><span class="dashicons dashicons-email "></span>' |
|
| 388 | - . $button_text |
|
| 389 | - . '</button>'; |
|
| 390 | - add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
| 391 | - } |
|
| 392 | - } |
|
| 393 | - } |
|
| 394 | - |
|
| 395 | - |
|
| 396 | - |
|
| 397 | - public function newsletter_send_form_skeleton() |
|
| 398 | - { |
|
| 399 | - $list_table = $this->_list_table_object; |
|
| 400 | - $codes = array(); |
|
| 401 | - //need to templates for the newsletter message type for the template selector. |
|
| 402 | - $values[] = array('text' => __('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
| 403 | - $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
| 404 | - array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
| 405 | - ); |
|
| 406 | - foreach ($mtps as $mtp) { |
|
| 407 | - $name = $mtp->name(); |
|
| 408 | - $values[] = array( |
|
| 409 | - 'text' => empty($name) ? __('Global', 'event_espresso') : $name, |
|
| 410 | - 'id' => $mtp->ID(), |
|
| 411 | - ); |
|
| 412 | - } |
|
| 413 | - //need to get a list of shortcodes that are available for the newsletter message type. |
|
| 414 | - $shortcodes = EEH_MSG_Template::get_shortcodes('newsletter', 'email', array(), 'attendee', false); |
|
| 415 | - foreach ($shortcodes as $field => $shortcode_array) { |
|
| 416 | - $codes[$field] = implode(', ', array_keys($shortcode_array)); |
|
| 417 | - } |
|
| 418 | - $shortcodes = $codes; |
|
| 419 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 420 | - $form_template_args = array( |
|
| 421 | - 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
| 422 | - 'form_route' => 'newsletter_selected_send', |
|
| 423 | - 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
| 424 | - 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
| 425 | - 'redirect_back_to' => $this->_req_action, |
|
| 426 | - 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
| 427 | - 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
| 428 | - 'shortcodes' => $shortcodes, |
|
| 429 | - 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
| 430 | - ); |
|
| 431 | - EEH_Template::display_template($form_template, $form_template_args); |
|
| 432 | - } |
|
| 433 | - |
|
| 434 | - |
|
| 435 | - |
|
| 436 | - /** |
|
| 437 | - * Handles sending selected registrations/contacts a newsletter. |
|
| 438 | - * |
|
| 439 | - * @since 4.3.0 |
|
| 440 | - * @return void |
|
| 441 | - * @throws \EE_Error |
|
| 442 | - */ |
|
| 443 | - protected function _newsletter_selected_send() |
|
| 444 | - { |
|
| 445 | - $success = true; |
|
| 446 | - //first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
| 447 | - if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
| 448 | - EE_Error::add_error( |
|
| 449 | - __( |
|
| 450 | - 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
| 451 | - 'event_espresso' |
|
| 452 | - ), |
|
| 453 | - __FILE__, |
|
| 454 | - __FUNCTION__, |
|
| 455 | - __LINE__ |
|
| 456 | - ); |
|
| 457 | - $success = false; |
|
| 458 | - } |
|
| 459 | - if ($success) { |
|
| 460 | - //update Message template in case there are any changes |
|
| 461 | - $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
| 462 | - $this->_req_data['newsletter_mtp_selected'] |
|
| 463 | - ); |
|
| 464 | - $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
| 465 | - ? $Message_Template_Group->context_templates() |
|
| 466 | - : array(); |
|
| 467 | - if (empty($Message_Templates)) { |
|
| 468 | - EE_Error::add_error( |
|
| 469 | - __( |
|
| 470 | - 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
| 471 | - 'event_espresso' |
|
| 472 | - ), |
|
| 473 | - __FILE__, |
|
| 474 | - __FUNCTION__, |
|
| 475 | - __LINE__ |
|
| 476 | - ); |
|
| 477 | - } |
|
| 478 | - //let's just update the specific fields |
|
| 479 | - foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
| 480 | - if ($Message_Template instanceof EE_Message_Template) { |
|
| 481 | - $field = $Message_Template->get('MTP_template_field'); |
|
| 482 | - $content = $Message_Template->get('MTP_content'); |
|
| 483 | - $new_content = $content; |
|
| 484 | - switch ($field) { |
|
| 485 | - case 'from' : |
|
| 486 | - $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
| 487 | - ? $this->_req_data['batch_message']['from'] |
|
| 488 | - : $content; |
|
| 489 | - break; |
|
| 490 | - case 'subject' : |
|
| 491 | - $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
| 492 | - ? $this->_req_data['batch_message']['subject'] |
|
| 493 | - : $content; |
|
| 494 | - break; |
|
| 495 | - case 'content' : |
|
| 496 | - $new_content = $content; |
|
| 497 | - $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
| 498 | - ? $this->_req_data['batch_message']['content'] |
|
| 499 | - : $content['newsletter_content']; |
|
| 500 | - break; |
|
| 501 | - default : |
|
| 502 | - //continue the foreach loop, we don't want to set $new_content nor save. |
|
| 503 | - continue 2; |
|
| 504 | - } |
|
| 505 | - $Message_Template->set('MTP_content', $new_content); |
|
| 506 | - $Message_Template->save(); |
|
| 507 | - } |
|
| 508 | - } |
|
| 509 | - //great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
| 510 | - $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
| 511 | - ? $this->_req_data['batch_message']['id_type'] |
|
| 512 | - : 'registration'; |
|
| 513 | - //id_type will affect how we assemble the ids. |
|
| 514 | - $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
| 515 | - ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
| 516 | - : array(); |
|
| 517 | - $registrations_used_for_contact_data = array(); |
|
| 518 | - //using switch because eventually we'll have other contexts that will be used for generating messages. |
|
| 519 | - switch ($id_type) { |
|
| 520 | - case 'registration' : |
|
| 521 | - $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
| 522 | - array( |
|
| 523 | - array( |
|
| 524 | - 'REG_ID' => array('IN', $ids), |
|
| 525 | - ), |
|
| 526 | - ) |
|
| 527 | - ); |
|
| 528 | - break; |
|
| 529 | - case 'contact' : |
|
| 530 | - $registrations_used_for_contact_data = EEM_Registration::instance() |
|
| 531 | - ->get_latest_registration_for_each_of_given_contacts($ids); |
|
| 532 | - break; |
|
| 533 | - } |
|
| 534 | - do_action( |
|
| 535 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
| 536 | - $registrations_used_for_contact_data, |
|
| 537 | - $Message_Template_Group->ID() |
|
| 538 | - ); |
|
| 539 | - //kept for backward compat, internally we no longer use this action. |
|
| 540 | - //@deprecated 4.8.36.rc.002 |
|
| 541 | - $contacts = $id_type === 'registration' |
|
| 542 | - ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
| 543 | - : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
| 544 | - do_action( |
|
| 545 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
| 546 | - $contacts, |
|
| 547 | - $Message_Template_Group->ID() |
|
| 548 | - ); |
|
| 549 | - } |
|
| 550 | - $query_args = array( |
|
| 551 | - 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
| 552 | - ? $this->_req_data['redirect_back_to'] |
|
| 553 | - : 'default', |
|
| 554 | - ); |
|
| 555 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 556 | - } |
|
| 557 | - |
|
| 558 | - |
|
| 559 | - |
|
| 560 | - /** |
|
| 561 | - * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
| 562 | - * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
| 563 | - */ |
|
| 564 | - protected function _registration_reports_js_setup() |
|
| 565 | - { |
|
| 566 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
| 567 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
| 568 | - } |
|
| 569 | - |
|
| 570 | - |
|
| 571 | - |
|
| 572 | - /** |
|
| 573 | - * generates Business Reports regarding Registrations |
|
| 574 | - * |
|
| 575 | - * @access protected |
|
| 576 | - * @return void |
|
| 577 | - */ |
|
| 578 | - protected function _registration_reports() |
|
| 579 | - { |
|
| 580 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 581 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 582 | - $template_path, |
|
| 583 | - $this->_reports_template_data, |
|
| 584 | - true |
|
| 585 | - ); |
|
| 586 | - // the final template wrapper |
|
| 587 | - $this->display_admin_page_with_no_sidebar(); |
|
| 588 | - } |
|
| 589 | - |
|
| 590 | - |
|
| 591 | - |
|
| 592 | - /** |
|
| 593 | - * Generates Business Report showing total registrations per day. |
|
| 594 | - * |
|
| 595 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 596 | - * @return string |
|
| 597 | - */ |
|
| 598 | - private function _registrations_per_day_report($period = '-1 month') |
|
| 599 | - { |
|
| 600 | - $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
| 601 | - $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
| 602 | - $results = (array)$results; |
|
| 603 | - $regs = array(); |
|
| 604 | - $subtitle = ''; |
|
| 605 | - if ($results) { |
|
| 606 | - $column_titles = array(); |
|
| 607 | - $tracker = 0; |
|
| 608 | - foreach ($results as $result) { |
|
| 609 | - $report_column_values = array(); |
|
| 610 | - foreach ($result as $property_name => $property_value) { |
|
| 611 | - $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
| 612 | - : (int)$property_value; |
|
| 613 | - $report_column_values[] = $property_value; |
|
| 614 | - if ($tracker === 0) { |
|
| 615 | - if ($property_name === 'Registration_REG_date') { |
|
| 616 | - $column_titles[] = __('Date (only days with registrations are shown)', 'event_espresso'); |
|
| 617 | - } else { |
|
| 618 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 619 | - } |
|
| 620 | - } |
|
| 621 | - } |
|
| 622 | - $tracker++; |
|
| 623 | - $regs[] = $report_column_values; |
|
| 624 | - } |
|
| 625 | - //make sure the column_titles is pushed to the beginning of the array |
|
| 626 | - array_unshift($regs, $column_titles); |
|
| 627 | - //setup the date range. |
|
| 628 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 629 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 630 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
| 631 | - $subtitle = sprintf( |
|
| 632 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 633 | - $beginning_date->format('Y-m-d'), |
|
| 634 | - $ending_date->format('Y-m-d') |
|
| 635 | - ); |
|
| 636 | - } |
|
| 637 | - $report_title = __('Total Registrations per Day', 'event_espresso'); |
|
| 638 | - $report_params = array( |
|
| 639 | - 'title' => $report_title, |
|
| 640 | - 'subtitle' => $subtitle, |
|
| 641 | - 'id' => $report_ID, |
|
| 642 | - 'regs' => $regs, |
|
| 643 | - 'noResults' => empty($regs), |
|
| 644 | - 'noRegsMsg' => sprintf( |
|
| 645 | - __( |
|
| 646 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
| 647 | - 'event_espresso' |
|
| 648 | - ), |
|
| 649 | - '<h2>' . $report_title . '</h2><p>', |
|
| 650 | - '</p>' |
|
| 651 | - ), |
|
| 652 | - ); |
|
| 653 | - wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
| 654 | - return $report_ID; |
|
| 655 | - } |
|
| 656 | - |
|
| 657 | - |
|
| 658 | - |
|
| 659 | - /** |
|
| 660 | - * Generates Business Report showing total registrations per event. |
|
| 661 | - * |
|
| 662 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 663 | - * @return string |
|
| 664 | - */ |
|
| 665 | - private function _registrations_per_event_report($period = '-1 month') |
|
| 666 | - { |
|
| 667 | - $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
| 668 | - $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
| 669 | - $results = (array)$results; |
|
| 670 | - $regs = array(); |
|
| 671 | - $subtitle = ''; |
|
| 672 | - if ($results) { |
|
| 673 | - $column_titles = array(); |
|
| 674 | - $tracker = 0; |
|
| 675 | - foreach ($results as $result) { |
|
| 676 | - $report_column_values = array(); |
|
| 677 | - foreach ($result as $property_name => $property_value) { |
|
| 678 | - $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
| 679 | - $property_value, |
|
| 680 | - 4, |
|
| 681 | - '...' |
|
| 682 | - ) : (int)$property_value; |
|
| 683 | - $report_column_values[] = $property_value; |
|
| 684 | - if ($tracker === 0) { |
|
| 685 | - if ($property_name === 'Registration_Event') { |
|
| 686 | - $column_titles[] = __('Event', 'event_espresso'); |
|
| 687 | - } else { |
|
| 688 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 689 | - } |
|
| 690 | - } |
|
| 691 | - } |
|
| 692 | - $tracker++; |
|
| 693 | - $regs[] = $report_column_values; |
|
| 694 | - } |
|
| 695 | - //make sure the column_titles is pushed to the beginning of the array |
|
| 696 | - array_unshift($regs, $column_titles); |
|
| 697 | - //setup the date range. |
|
| 698 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 699 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 700 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
| 701 | - $subtitle = sprintf( |
|
| 702 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 703 | - $beginning_date->format('Y-m-d'), |
|
| 704 | - $ending_date->format('Y-m-d') |
|
| 705 | - ); |
|
| 706 | - } |
|
| 707 | - $report_title = __('Total Registrations per Event', 'event_espresso'); |
|
| 708 | - $report_params = array( |
|
| 709 | - 'title' => $report_title, |
|
| 710 | - 'subtitle' => $subtitle, |
|
| 711 | - 'id' => $report_ID, |
|
| 712 | - 'regs' => $regs, |
|
| 713 | - 'noResults' => empty($regs), |
|
| 714 | - 'noRegsMsg' => sprintf( |
|
| 715 | - __( |
|
| 716 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
| 717 | - 'event_espresso' |
|
| 718 | - ), |
|
| 719 | - '<h2>' . $report_title . '</h2><p>', |
|
| 720 | - '</p>' |
|
| 721 | - ), |
|
| 722 | - ); |
|
| 723 | - wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
| 724 | - return $report_ID; |
|
| 725 | - } |
|
| 726 | - |
|
| 727 | - |
|
| 728 | - |
|
| 729 | - /** |
|
| 730 | - * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
| 731 | - * |
|
| 732 | - * @access protected |
|
| 733 | - * @return void |
|
| 734 | - * @throws \EE_Error |
|
| 735 | - */ |
|
| 736 | - protected function _registration_checkin_list_table() |
|
| 737 | - { |
|
| 738 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 739 | - $reg_id = isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : null; |
|
| 740 | - /** @var EE_Registration $registration */ |
|
| 741 | - $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
| 742 | - $attendee = $registration->attendee(); |
|
| 743 | - $this->_admin_page_title .= $this->get_action_link_or_button( |
|
| 744 | - 'new_registration', |
|
| 745 | - 'add-registrant', |
|
| 746 | - array('event_id' => $registration->event_ID()), |
|
| 747 | - 'add-new-h2' |
|
| 748 | - ); |
|
| 749 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 750 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 751 | - $legend_items = array( |
|
| 752 | - 'checkin' => array( |
|
| 753 | - 'class' => $checked_in->cssClasses(), |
|
| 754 | - 'desc' => $checked_in->legendLabel(), |
|
| 755 | - ), |
|
| 756 | - 'checkout' => array( |
|
| 757 | - 'class' => $checked_out->cssClasses(), |
|
| 758 | - 'desc' => $checked_out->legendLabel(), |
|
| 759 | - ), |
|
| 760 | - ); |
|
| 761 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 762 | - $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 763 | - /** @var EE_Datetime $datetime */ |
|
| 764 | - $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
| 765 | - $datetime_label = ''; |
|
| 766 | - if ($datetime instanceof EE_Datetime) { |
|
| 767 | - $datetime_label = $datetime->get_dtt_display_name(true); |
|
| 768 | - $datetime_label .= ! empty($datetime_label) |
|
| 769 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 770 | - : $datetime->get_dtt_display_name(); |
|
| 771 | - } |
|
| 772 | - $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
| 773 | - ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 774 | - array( |
|
| 775 | - 'action' => 'event_registrations', |
|
| 776 | - 'event_id' => $registration->event_ID(), |
|
| 777 | - 'DTT_ID' => $dtt_id, |
|
| 778 | - ), |
|
| 779 | - $this->_admin_base_url |
|
| 780 | - ) |
|
| 781 | - : ''; |
|
| 782 | - $datetime_link = ! empty($datetime_link) |
|
| 783 | - ? '<a href="' . $datetime_link . '">' |
|
| 784 | - . '<span id="checkin-dtt">' |
|
| 785 | - . $datetime_label |
|
| 786 | - . '</span></a>' |
|
| 787 | - : $datetime_label; |
|
| 788 | - $attendee_name = $attendee instanceof EE_Attendee |
|
| 789 | - ? $attendee->full_name() |
|
| 790 | - : ''; |
|
| 791 | - $attendee_link = $attendee instanceof EE_Attendee |
|
| 792 | - ? $attendee->get_admin_details_link() |
|
| 793 | - : ''; |
|
| 794 | - $attendee_link = ! empty($attendee_link) |
|
| 795 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 796 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 797 | - . '<span id="checkin-attendee-name">' |
|
| 798 | - . $attendee_name |
|
| 799 | - . '</span></a>' |
|
| 800 | - : ''; |
|
| 801 | - $event_link = $registration->event() instanceof EE_Event |
|
| 802 | - ? $registration->event()->get_admin_details_link() |
|
| 803 | - : ''; |
|
| 804 | - $event_link = ! empty($event_link) |
|
| 805 | - ? '<a href="' . $event_link . '"' |
|
| 806 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 807 | - . '<span id="checkin-event-name">' |
|
| 808 | - . $registration->event_name() |
|
| 809 | - . '</span>' |
|
| 810 | - . '</a>' |
|
| 811 | - : ''; |
|
| 812 | - $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
| 813 | - ? '<h2>' . sprintf( |
|
| 814 | - esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
| 815 | - $attendee_link, |
|
| 816 | - $datetime_link, |
|
| 817 | - $event_link |
|
| 818 | - ) . '</h2>' |
|
| 819 | - : ''; |
|
| 820 | - $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
| 821 | - ? '<input type="hidden" name="_REGID" value="' . $reg_id . '">' : ''; |
|
| 822 | - $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
| 823 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 824 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 825 | - } |
|
| 826 | - |
|
| 827 | - |
|
| 828 | - |
|
| 829 | - /** |
|
| 830 | - * toggle the Check-in status for the given registration (coming from ajax) |
|
| 831 | - * |
|
| 832 | - * @return void (JSON) |
|
| 833 | - */ |
|
| 834 | - public function toggle_checkin_status() |
|
| 835 | - { |
|
| 836 | - //first make sure we have the necessary data |
|
| 837 | - if ( ! isset($this->_req_data['_regid'])) { |
|
| 838 | - EE_Error::add_error( |
|
| 839 | - __( |
|
| 840 | - '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', |
|
| 841 | - 'event_espresso' |
|
| 842 | - ), |
|
| 843 | - __FILE__, |
|
| 844 | - __FUNCTION__, |
|
| 845 | - __LINE__ |
|
| 846 | - ); |
|
| 847 | - $this->_template_args['success'] = false; |
|
| 848 | - $this->_template_args['error'] = true; |
|
| 849 | - $this->_return_json(); |
|
| 850 | - }; |
|
| 851 | - //do a nonce check cause we're not coming in from an normal route here. |
|
| 852 | - $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
| 853 | - : ''; |
|
| 854 | - $nonce_ref = 'checkin_nonce'; |
|
| 855 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
| 856 | - //beautiful! Made it this far so let's get the status. |
|
| 857 | - $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
| 858 | - //setup new class to return via ajax |
|
| 859 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 860 | - $this->_template_args['success'] = true; |
|
| 861 | - $this->_return_json(); |
|
| 862 | - } |
|
| 863 | - |
|
| 864 | - |
|
| 865 | - |
|
| 866 | - /** |
|
| 867 | - * handles toggling the checkin status for the registration, |
|
| 868 | - * |
|
| 869 | - * @access protected |
|
| 870 | - * @return int|void |
|
| 871 | - */ |
|
| 872 | - protected function _toggle_checkin_status() |
|
| 873 | - { |
|
| 874 | - //first let's get the query args out of the way for the redirect |
|
| 875 | - $query_args = array( |
|
| 876 | - 'action' => 'event_registrations', |
|
| 877 | - 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 878 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
| 879 | - ); |
|
| 880 | - $new_status = false; |
|
| 881 | - // bulk action check in toggle |
|
| 882 | - if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 883 | - // cycle thru checkboxes |
|
| 884 | - while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 885 | - $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 886 | - $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
| 887 | - } |
|
| 888 | - } elseif (isset($this->_req_data['_regid'])) { |
|
| 889 | - //coming from ajax request |
|
| 890 | - $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
| 891 | - $query_args['DTT_ID'] = $DTT_ID; |
|
| 892 | - $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
| 893 | - } else { |
|
| 894 | - EE_Error::add_error( |
|
| 895 | - __('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
| 896 | - __FILE__, |
|
| 897 | - __FUNCTION__, |
|
| 898 | - __LINE__ |
|
| 899 | - ); |
|
| 900 | - } |
|
| 901 | - if (defined('DOING_AJAX')) { |
|
| 902 | - return $new_status; |
|
| 903 | - } |
|
| 904 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 905 | - } |
|
| 906 | - |
|
| 907 | - |
|
| 908 | - |
|
| 909 | - /** |
|
| 910 | - * This is toggles a single Check-in for the given registration and datetime. |
|
| 911 | - * |
|
| 912 | - * @param int $REG_ID The registration we're toggling |
|
| 913 | - * @param int $DTT_ID The datetime we're toggling |
|
| 914 | - * @return int The new status toggled to. |
|
| 915 | - * @throws \EE_Error |
|
| 916 | - */ |
|
| 917 | - private function _toggle_checkin($REG_ID, $DTT_ID) |
|
| 918 | - { |
|
| 919 | - /** @var EE_Registration $REG */ |
|
| 920 | - $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
| 921 | - $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
| 922 | - if ($new_status !== false) { |
|
| 923 | - EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
| 924 | - } else { |
|
| 925 | - EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
| 926 | - $new_status = false; |
|
| 927 | - } |
|
| 928 | - return $new_status; |
|
| 929 | - } |
|
| 930 | - |
|
| 931 | - |
|
| 932 | - |
|
| 933 | - /** |
|
| 934 | - * Takes care of deleting multiple EE_Checkin table rows |
|
| 935 | - * |
|
| 936 | - * @access protected |
|
| 937 | - * @return void |
|
| 938 | - * @throws \EE_Error |
|
| 939 | - */ |
|
| 940 | - protected function _delete_checkin_rows() |
|
| 941 | - { |
|
| 942 | - $query_args = array( |
|
| 943 | - 'action' => 'registration_checkins', |
|
| 944 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 945 | - '_REGID' => isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : 0, |
|
| 946 | - ); |
|
| 947 | - $errors = 0; |
|
| 948 | - if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 949 | - while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 950 | - if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 951 | - $errors++; |
|
| 952 | - } |
|
| 953 | - } |
|
| 954 | - } else { |
|
| 955 | - EE_Error::add_error( |
|
| 956 | - __( |
|
| 957 | - 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
| 958 | - 'event_espresso' |
|
| 959 | - ), |
|
| 960 | - __FILE__, |
|
| 961 | - __FUNCTION__, |
|
| 962 | - __LINE__ |
|
| 963 | - ); |
|
| 964 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 965 | - } |
|
| 966 | - if ($errors > 0) { |
|
| 967 | - EE_Error::add_error( |
|
| 968 | - sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
| 969 | - __FILE__, |
|
| 970 | - __FUNCTION__, |
|
| 971 | - __LINE__ |
|
| 972 | - ); |
|
| 973 | - } else { |
|
| 974 | - EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
| 975 | - } |
|
| 976 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 977 | - } |
|
| 978 | - |
|
| 979 | - |
|
| 980 | - |
|
| 981 | - /** |
|
| 982 | - * Deletes a single EE_Checkin row |
|
| 983 | - * |
|
| 984 | - * @return void |
|
| 985 | - * @throws \EE_Error |
|
| 986 | - */ |
|
| 987 | - protected function _delete_checkin_row() |
|
| 988 | - { |
|
| 989 | - $query_args = array( |
|
| 990 | - 'action' => 'registration_checkins', |
|
| 991 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 992 | - '_REGID' => isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : 0, |
|
| 993 | - ); |
|
| 994 | - if ( ! empty($this->_req_data['CHK_ID'])) { |
|
| 995 | - if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 996 | - EE_Error::add_error( |
|
| 997 | - __('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
| 998 | - __FILE__, |
|
| 999 | - __FUNCTION__, |
|
| 1000 | - __LINE__ |
|
| 1001 | - ); |
|
| 1002 | - } else { |
|
| 1003 | - EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
| 1004 | - } |
|
| 1005 | - } else { |
|
| 1006 | - EE_Error::add_error( |
|
| 1007 | - __( |
|
| 1008 | - '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', |
|
| 1009 | - 'event_espresso' |
|
| 1010 | - ), |
|
| 1011 | - __FILE__, |
|
| 1012 | - __FUNCTION__, |
|
| 1013 | - __LINE__ |
|
| 1014 | - ); |
|
| 1015 | - } |
|
| 1016 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1017 | - } |
|
| 1018 | - |
|
| 1019 | - |
|
| 1020 | - |
|
| 1021 | - /** |
|
| 1022 | - * generates HTML for the Event Registrations List Table |
|
| 1023 | - * |
|
| 1024 | - * @access protected |
|
| 1025 | - * @return void |
|
| 1026 | - * @throws \EE_Error |
|
| 1027 | - */ |
|
| 1028 | - protected function _event_registrations_list_table() |
|
| 1029 | - { |
|
| 1030 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1031 | - $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
| 1032 | - ? $this->get_action_link_or_button( |
|
| 1033 | - 'new_registration', |
|
| 1034 | - 'add-registrant', |
|
| 1035 | - array('event_id' => $this->_req_data['event_id']), |
|
| 1036 | - 'add-new-h2', |
|
| 1037 | - '', |
|
| 1038 | - false |
|
| 1039 | - ) |
|
| 1040 | - : ''; |
|
| 1041 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 1042 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 1043 | - $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
| 1044 | - $legend_items = array( |
|
| 1045 | - 'star-icon' => array( |
|
| 1046 | - 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
| 1047 | - 'desc' => __('This Registrant is the Primary Registrant', 'event_espresso'), |
|
| 1048 | - ), |
|
| 1049 | - 'checkin' => array( |
|
| 1050 | - 'class' => $checked_in->cssClasses(), |
|
| 1051 | - 'desc' => $checked_in->legendLabel(), |
|
| 1052 | - ), |
|
| 1053 | - 'checkout' => array( |
|
| 1054 | - 'class' => $checked_out->cssClasses(), |
|
| 1055 | - 'desc' => $checked_out->legendLabel(), |
|
| 1056 | - ), |
|
| 1057 | - 'nocheckinrecord' => array( |
|
| 1058 | - 'class' => $checked_never->cssClasses(), |
|
| 1059 | - 'desc' => $checked_never->legendLabel(), |
|
| 1060 | - ), |
|
| 1061 | - 'view_details' => array( |
|
| 1062 | - 'class' => 'dashicons dashicons-search', |
|
| 1063 | - 'desc' => __('View All Check-in Records for this Registrant', 'event_espresso'), |
|
| 1064 | - ), |
|
| 1065 | - 'approved_status' => array( |
|
| 1066 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1067 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
| 1068 | - ), |
|
| 1069 | - 'cancelled_status' => array( |
|
| 1070 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1071 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
| 1072 | - ), |
|
| 1073 | - 'declined_status' => array( |
|
| 1074 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1075 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
| 1076 | - ), |
|
| 1077 | - 'not_approved' => array( |
|
| 1078 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1079 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
| 1080 | - ), |
|
| 1081 | - 'pending_status' => array( |
|
| 1082 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1083 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
| 1084 | - ), |
|
| 1085 | - 'wait_list' => array( |
|
| 1086 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1087 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
| 1088 | - ), |
|
| 1089 | - ); |
|
| 1090 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 1091 | - $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
| 1092 | - $this->_template_args['before_list_table'] = ! empty($event_id) |
|
| 1093 | - ? '<h2>' . sprintf( |
|
| 1094 | - __('Viewing Registrations for Event: %s', 'event_espresso'), |
|
| 1095 | - EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
| 1096 | - ) . '</h2>' |
|
| 1097 | - : ''; |
|
| 1098 | - //need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on the event. |
|
| 1099 | - /** @var EE_Event $event */ |
|
| 1100 | - $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 1101 | - $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
| 1102 | - $datetime = null; |
|
| 1103 | - if ($event instanceof EE_Event) { |
|
| 1104 | - $datetimes_on_event = $event->datetimes(); |
|
| 1105 | - if (count($datetimes_on_event) === 1) { |
|
| 1106 | - $datetime = reset($datetimes_on_event); |
|
| 1107 | - } |
|
| 1108 | - } |
|
| 1109 | - $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
| 1110 | - if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
| 1111 | - $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
| 1112 | - $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
| 1113 | - $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
| 1114 | - $this->_template_args['before_list_table'] .= $datetime->name(); |
|
| 1115 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1116 | - $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
| 1117 | - } |
|
| 1118 | - //if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status column |
|
| 1119 | - //represents |
|
| 1120 | - if ( ! $datetime instanceof EE_Datetime) { |
|
| 1121 | - $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
| 1122 | - . __('In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
| 1123 | - 'event_espresso') |
|
| 1124 | - . '</p>'; |
|
| 1125 | - } |
|
| 1126 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 1127 | - } |
|
| 1128 | - |
|
| 1129 | - /** |
|
| 1130 | - * Download the registrations check-in report (same as the normal registration report, but with different where |
|
| 1131 | - * conditions) |
|
| 1132 | - * |
|
| 1133 | - * @return void ends the request by a redirect or download |
|
| 1134 | - */ |
|
| 1135 | - public function _registrations_checkin_report() |
|
| 1136 | - { |
|
| 1137 | - $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
| 1138 | - } |
|
| 1139 | - |
|
| 1140 | - /** |
|
| 1141 | - * Gets the query params from the request, plus adds a where condition for the registration status, |
|
| 1142 | - * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
| 1143 | - * |
|
| 1144 | - * @param array $request |
|
| 1145 | - * @param int $per_page |
|
| 1146 | - * @param bool $count |
|
| 1147 | - * @return array |
|
| 1148 | - */ |
|
| 1149 | - protected function _get_checkin_query_params_from_request( |
|
| 1150 | - $request, |
|
| 1151 | - $per_page = 10, |
|
| 1152 | - $count = false |
|
| 1153 | - ) { |
|
| 1154 | - $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
| 1155 | - //unlike the regular registrations list table, |
|
| 1156 | - $status_ids_array = apply_filters( |
|
| 1157 | - 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
| 1158 | - array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
| 1159 | - ); |
|
| 1160 | - $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
| 1161 | - return $query_params; |
|
| 1162 | - } |
|
| 1163 | - |
|
| 1164 | - |
|
| 1165 | - |
|
| 1166 | - |
|
| 1167 | - /** |
|
| 1168 | - * Gets registrations for an event |
|
| 1169 | - * |
|
| 1170 | - * @param int $per_page |
|
| 1171 | - * @param bool $count whether to return count or data. |
|
| 1172 | - * @param bool $trash |
|
| 1173 | - * @param string $orderby |
|
| 1174 | - * @return EE_Registration[]|int |
|
| 1175 | - * @throws \EE_Error |
|
| 1176 | - */ |
|
| 1177 | - public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
| 1178 | - { |
|
| 1179 | - //normalize some request params that get setup by the parent `get_registrations` method. |
|
| 1180 | - $request = $this->_req_data; |
|
| 1181 | - $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
| 1182 | - $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1183 | - if($trash){ |
|
| 1184 | - $request['status'] = 'trash'; |
|
| 1185 | - } |
|
| 1186 | - $query_params = $this->_get_checkin_query_params_from_request( $request, $per_page, $count ); |
|
| 1187 | - /** |
|
| 1188 | - * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
| 1189 | - * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
| 1190 | - * @see EEM_Base::get_all() |
|
| 1191 | - */ |
|
| 1192 | - $query_params['group_by'] = ''; |
|
| 1193 | - |
|
| 1194 | - return $count |
|
| 1195 | - ? EEM_Registration::instance()->count($query_params) |
|
| 1196 | - /** @type EE_Registration[] */ |
|
| 1197 | - : EEM_Registration::instance()->get_all($query_params); |
|
| 1198 | - } |
|
| 23 | + /** |
|
| 24 | + * This is used to hold the reports template data which is setup early in the request. |
|
| 25 | + * |
|
| 26 | + * @type array |
|
| 27 | + */ |
|
| 28 | + protected $_reports_template_data = array(); |
|
| 29 | + |
|
| 30 | + |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * Extend_Registrations_Admin_Page constructor. |
|
| 34 | + * |
|
| 35 | + * @param bool $routing |
|
| 36 | + */ |
|
| 37 | + public function __construct($routing = true) |
|
| 38 | + { |
|
| 39 | + parent::__construct($routing); |
|
| 40 | + if ( ! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 41 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 42 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 43 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 44 | + } |
|
| 45 | + } |
|
| 46 | + |
|
| 47 | + |
|
| 48 | + |
|
| 49 | + protected function _extend_page_config() |
|
| 50 | + { |
|
| 51 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 52 | + $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
| 53 | + ? $this->_req_data['_REG_ID'] |
|
| 54 | + : 0; |
|
| 55 | + // $att_id = ! empty( $this->_req_data['ATT_ID'] ) ? ! is_array( $this->_req_data['ATT_ID'] ) : 0; |
|
| 56 | + // $att_id = ! empty( $this->_req_data['post'] ) && ! is_array( $this->_req_data['post'] ) |
|
| 57 | + // ? $this->_req_data['post'] : $att_id; |
|
| 58 | + $new_page_routes = array( |
|
| 59 | + 'reports' => array( |
|
| 60 | + 'func' => '_registration_reports', |
|
| 61 | + 'capability' => 'ee_read_registrations', |
|
| 62 | + ), |
|
| 63 | + 'registration_checkins' => array( |
|
| 64 | + 'func' => '_registration_checkin_list_table', |
|
| 65 | + 'capability' => 'ee_read_checkins', |
|
| 66 | + ), |
|
| 67 | + 'newsletter_selected_send' => array( |
|
| 68 | + 'func' => '_newsletter_selected_send', |
|
| 69 | + 'noheader' => true, |
|
| 70 | + 'capability' => 'ee_send_message', |
|
| 71 | + ), |
|
| 72 | + 'delete_checkin_rows' => array( |
|
| 73 | + 'func' => '_delete_checkin_rows', |
|
| 74 | + 'noheader' => true, |
|
| 75 | + 'capability' => 'ee_delete_checkins', |
|
| 76 | + ), |
|
| 77 | + 'delete_checkin_row' => array( |
|
| 78 | + 'func' => '_delete_checkin_row', |
|
| 79 | + 'noheader' => true, |
|
| 80 | + 'capability' => 'ee_delete_checkin', |
|
| 81 | + 'obj_id' => $reg_id, |
|
| 82 | + ), |
|
| 83 | + 'toggle_checkin_status' => array( |
|
| 84 | + 'func' => '_toggle_checkin_status', |
|
| 85 | + 'noheader' => true, |
|
| 86 | + 'capability' => 'ee_edit_checkin', |
|
| 87 | + 'obj_id' => $reg_id, |
|
| 88 | + ), |
|
| 89 | + 'toggle_checkin_status_bulk' => array( |
|
| 90 | + 'func' => '_toggle_checkin_status', |
|
| 91 | + 'noheader' => true, |
|
| 92 | + 'capability' => 'ee_edit_checkins' |
|
| 93 | + ), |
|
| 94 | + 'event_registrations' => array( |
|
| 95 | + 'func' => '_event_registrations_list_table', |
|
| 96 | + 'capability' => 'ee_read_checkins', |
|
| 97 | + ), |
|
| 98 | + 'registrations_checkin_report' => array( |
|
| 99 | + 'func' => '_registrations_checkin_report', |
|
| 100 | + 'noheader' => true, |
|
| 101 | + 'capability' => 'ee_read_registrations', |
|
| 102 | + ), |
|
| 103 | + ); |
|
| 104 | + $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
| 105 | + $new_page_config = array( |
|
| 106 | + 'reports' => array( |
|
| 107 | + 'nav' => array( |
|
| 108 | + 'label' => __('Reports', 'event_espresso'), |
|
| 109 | + 'order' => 30, |
|
| 110 | + ), |
|
| 111 | + 'help_tabs' => array( |
|
| 112 | + 'registrations_reports_help_tab' => array( |
|
| 113 | + 'title' => __('Registration Reports', 'event_espresso'), |
|
| 114 | + 'filename' => 'registrations_reports', |
|
| 115 | + ), |
|
| 116 | + ), |
|
| 117 | + /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
| 118 | + 'require_nonce' => false, |
|
| 119 | + ), |
|
| 120 | + 'event_registrations' => array( |
|
| 121 | + 'nav' => array( |
|
| 122 | + 'label' => __('Event Check-In', 'event_espresso'), |
|
| 123 | + 'order' => 10, |
|
| 124 | + 'persistent' => true, |
|
| 125 | + ), |
|
| 126 | + 'help_tabs' => array( |
|
| 127 | + 'registrations_event_checkin_help_tab' => array( |
|
| 128 | + 'title' => __('Registrations Event Check-In', 'event_espresso'), |
|
| 129 | + 'filename' => 'registrations_event_checkin', |
|
| 130 | + ), |
|
| 131 | + 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
| 132 | + 'title' => __('Event Check-In Table Column Headings', 'event_espresso'), |
|
| 133 | + 'filename' => 'registrations_event_checkin_table_column_headings', |
|
| 134 | + ), |
|
| 135 | + 'registrations_event_checkin_filters_help_tab' => array( |
|
| 136 | + 'title' => __('Event Check-In Filters', 'event_espresso'), |
|
| 137 | + 'filename' => 'registrations_event_checkin_filters', |
|
| 138 | + ), |
|
| 139 | + 'registrations_event_checkin_views_help_tab' => array( |
|
| 140 | + 'title' => __('Event Check-In Views', 'event_espresso'), |
|
| 141 | + 'filename' => 'registrations_event_checkin_views', |
|
| 142 | + ), |
|
| 143 | + 'registrations_event_checkin_other_help_tab' => array( |
|
| 144 | + 'title' => __('Event Check-In Other', 'event_espresso'), |
|
| 145 | + 'filename' => 'registrations_event_checkin_other', |
|
| 146 | + ), |
|
| 147 | + ), |
|
| 148 | + 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
| 149 | + 'qtips' => array('Registration_List_Table_Tips'), |
|
| 150 | + 'list_table' => 'EE_Event_Registrations_List_Table', |
|
| 151 | + 'metaboxes' => array(), |
|
| 152 | + 'require_nonce' => false, |
|
| 153 | + ), |
|
| 154 | + 'registration_checkins' => array( |
|
| 155 | + 'nav' => array( |
|
| 156 | + 'label' => __('Check-In Records', 'event_espresso'), |
|
| 157 | + 'order' => 15, |
|
| 158 | + 'persistent' => false, |
|
| 159 | + ), |
|
| 160 | + 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
| 161 | + //'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
| 162 | + 'metaboxes' => array(), |
|
| 163 | + 'require_nonce' => false, |
|
| 164 | + ), |
|
| 165 | + ); |
|
| 166 | + $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
| 167 | + $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
| 168 | + $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
| 169 | + } |
|
| 170 | + |
|
| 171 | + |
|
| 172 | + |
|
| 173 | + protected function _ajax_hooks() |
|
| 174 | + { |
|
| 175 | + parent::_ajax_hooks(); |
|
| 176 | + add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
| 177 | + } |
|
| 178 | + |
|
| 179 | + |
|
| 180 | + |
|
| 181 | + public function load_scripts_styles() |
|
| 182 | + { |
|
| 183 | + parent::load_scripts_styles(); |
|
| 184 | + //if newsletter message type is active then let's add filter and load js for it. |
|
| 185 | + if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
| 186 | + //enqueue newsletter js |
|
| 187 | + wp_enqueue_script( |
|
| 188 | + 'ee-newsletter-trigger', |
|
| 189 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 190 | + array('ee-dialog'), |
|
| 191 | + EVENT_ESPRESSO_VERSION, |
|
| 192 | + true |
|
| 193 | + ); |
|
| 194 | + wp_enqueue_style( |
|
| 195 | + 'ee-newsletter-trigger-css', |
|
| 196 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 197 | + array(), |
|
| 198 | + EVENT_ESPRESSO_VERSION |
|
| 199 | + ); |
|
| 200 | + //hook in buttons for newsletter message type trigger. |
|
| 201 | + add_action( |
|
| 202 | + 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
| 203 | + array($this, 'add_newsletter_action_buttons'), |
|
| 204 | + 10 |
|
| 205 | + ); |
|
| 206 | + } |
|
| 207 | + } |
|
| 208 | + |
|
| 209 | + |
|
| 210 | + |
|
| 211 | + public function load_scripts_styles_reports() |
|
| 212 | + { |
|
| 213 | + wp_register_script( |
|
| 214 | + 'ee-reg-reports-js', |
|
| 215 | + REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 216 | + array('google-charts'), |
|
| 217 | + EVENT_ESPRESSO_VERSION, |
|
| 218 | + true |
|
| 219 | + ); |
|
| 220 | + wp_enqueue_script('ee-reg-reports-js'); |
|
| 221 | + $this->_registration_reports_js_setup(); |
|
| 222 | + } |
|
| 223 | + |
|
| 224 | + |
|
| 225 | + |
|
| 226 | + protected function _add_screen_options_event_registrations() |
|
| 227 | + { |
|
| 228 | + $this->_per_page_screen_option(); |
|
| 229 | + } |
|
| 230 | + |
|
| 231 | + |
|
| 232 | + |
|
| 233 | + protected function _add_screen_options_registration_checkins() |
|
| 234 | + { |
|
| 235 | + $page_title = $this->_admin_page_title; |
|
| 236 | + $this->_admin_page_title = __('Check-In Records', 'event_espresso'); |
|
| 237 | + $this->_per_page_screen_option(); |
|
| 238 | + $this->_admin_page_title = $page_title; |
|
| 239 | + } |
|
| 240 | + |
|
| 241 | + |
|
| 242 | + |
|
| 243 | + protected function _set_list_table_views_event_registrations() |
|
| 244 | + { |
|
| 245 | + $this->_views = array( |
|
| 246 | + 'all' => array( |
|
| 247 | + 'slug' => 'all', |
|
| 248 | + 'label' => __('All', 'event_espresso'), |
|
| 249 | + 'count' => 0, |
|
| 250 | + 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
| 251 | + ? array() |
|
| 252 | + : array( |
|
| 253 | + 'toggle_checkin_status_bulk' => __('Toggle Check-In', 'event_espresso'), |
|
| 254 | + ), |
|
| 255 | + ), |
|
| 256 | + ); |
|
| 257 | + } |
|
| 258 | + |
|
| 259 | + |
|
| 260 | + |
|
| 261 | + protected function _set_list_table_views_registration_checkins() |
|
| 262 | + { |
|
| 263 | + $this->_views = array( |
|
| 264 | + 'all' => array( |
|
| 265 | + 'slug' => 'all', |
|
| 266 | + 'label' => __('All', 'event_espresso'), |
|
| 267 | + 'count' => 0, |
|
| 268 | + 'bulk_action' => array('delete_checkin_rows' => __('Delete Check-In Rows', 'event_espresso')), |
|
| 269 | + ), |
|
| 270 | + ); |
|
| 271 | + } |
|
| 272 | + |
|
| 273 | + |
|
| 274 | + |
|
| 275 | + /** |
|
| 276 | + * callback for ajax action. |
|
| 277 | + * |
|
| 278 | + * @since 4.3.0 |
|
| 279 | + * @return void (JSON) |
|
| 280 | + * @throws \EE_Error |
|
| 281 | + */ |
|
| 282 | + public function get_newsletter_form_content() |
|
| 283 | + { |
|
| 284 | + //do a nonce check cause we're not coming in from an normal route here. |
|
| 285 | + $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
| 286 | + $this->_req_data['get_newsletter_form_content_nonce'] |
|
| 287 | + ) : ''; |
|
| 288 | + $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
| 289 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
| 290 | + //let's get the mtp for the incoming MTP_ ID |
|
| 291 | + if ( ! isset($this->_req_data['GRP_ID'])) { |
|
| 292 | + EE_Error::add_error( |
|
| 293 | + __( |
|
| 294 | + '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).', |
|
| 295 | + 'event_espresso' |
|
| 296 | + ), |
|
| 297 | + __FILE__, |
|
| 298 | + __FUNCTION__, |
|
| 299 | + __LINE__ |
|
| 300 | + ); |
|
| 301 | + $this->_template_args['success'] = false; |
|
| 302 | + $this->_template_args['error'] = true; |
|
| 303 | + $this->_return_json(); |
|
| 304 | + } |
|
| 305 | + $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
| 306 | + if ( ! $MTPG instanceof EE_Message_Template_Group) { |
|
| 307 | + EE_Error::add_error( |
|
| 308 | + sprintf( |
|
| 309 | + __( |
|
| 310 | + 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
| 311 | + 'event_espresso' |
|
| 312 | + ), |
|
| 313 | + $this->_req_data['GRP_ID'] |
|
| 314 | + ), |
|
| 315 | + __FILE__, |
|
| 316 | + __FUNCTION__, |
|
| 317 | + __LINE__ |
|
| 318 | + ); |
|
| 319 | + $this->_template_args['success'] = false; |
|
| 320 | + $this->_template_args['error'] = true; |
|
| 321 | + $this->_return_json(); |
|
| 322 | + } |
|
| 323 | + $MTPs = $MTPG->context_templates(); |
|
| 324 | + $MTPs = $MTPs['attendee']; |
|
| 325 | + $template_fields = array(); |
|
| 326 | + /** @var EE_Message_Template $MTP */ |
|
| 327 | + foreach ($MTPs as $MTP) { |
|
| 328 | + $field = $MTP->get('MTP_template_field'); |
|
| 329 | + if ($field === 'content') { |
|
| 330 | + $content = $MTP->get('MTP_content'); |
|
| 331 | + if ( ! empty($content['newsletter_content'])) { |
|
| 332 | + $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
| 333 | + } |
|
| 334 | + continue; |
|
| 335 | + } |
|
| 336 | + $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content'); |
|
| 337 | + } |
|
| 338 | + $this->_template_args['success'] = true; |
|
| 339 | + $this->_template_args['error'] = false; |
|
| 340 | + $this->_template_args['data'] = array( |
|
| 341 | + 'batch_message_from' => isset($template_fields['from']) |
|
| 342 | + ? $template_fields['from'] |
|
| 343 | + : '', |
|
| 344 | + 'batch_message_subject' => isset($template_fields['subject']) |
|
| 345 | + ? $template_fields['subject'] |
|
| 346 | + : '', |
|
| 347 | + 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
| 348 | + ? $template_fields['newsletter_content'] |
|
| 349 | + : '', |
|
| 350 | + ); |
|
| 351 | + $this->_return_json(); |
|
| 352 | + } |
|
| 353 | + |
|
| 354 | + |
|
| 355 | + |
|
| 356 | + /** |
|
| 357 | + * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
| 358 | + * |
|
| 359 | + * @since 4.3.0 |
|
| 360 | + * @param EE_Admin_List_Table $list_table |
|
| 361 | + * @return void |
|
| 362 | + */ |
|
| 363 | + public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
| 364 | + { |
|
| 365 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
| 366 | + 'ee_send_message', |
|
| 367 | + 'espresso_registrations_newsletter_selected_send' |
|
| 368 | + ) |
|
| 369 | + ) { |
|
| 370 | + return; |
|
| 371 | + } |
|
| 372 | + $routes_to_add_to = array( |
|
| 373 | + 'contact_list', |
|
| 374 | + 'event_registrations', |
|
| 375 | + 'default', |
|
| 376 | + ); |
|
| 377 | + if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
| 378 | + if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
| 379 | + || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
| 380 | + ) { |
|
| 381 | + echo ''; |
|
| 382 | + } else { |
|
| 383 | + $button_text = sprintf( |
|
| 384 | + __('Send Batch Message (%s selected)', 'event_espresso'), |
|
| 385 | + '<span class="send-selected-newsletter-count">0</span>' |
|
| 386 | + ); |
|
| 387 | + echo '<button id="selected-batch-send-trigger" class="button secondary-button"><span class="dashicons dashicons-email "></span>' |
|
| 388 | + . $button_text |
|
| 389 | + . '</button>'; |
|
| 390 | + add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
| 391 | + } |
|
| 392 | + } |
|
| 393 | + } |
|
| 394 | + |
|
| 395 | + |
|
| 396 | + |
|
| 397 | + public function newsletter_send_form_skeleton() |
|
| 398 | + { |
|
| 399 | + $list_table = $this->_list_table_object; |
|
| 400 | + $codes = array(); |
|
| 401 | + //need to templates for the newsletter message type for the template selector. |
|
| 402 | + $values[] = array('text' => __('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
| 403 | + $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
| 404 | + array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
| 405 | + ); |
|
| 406 | + foreach ($mtps as $mtp) { |
|
| 407 | + $name = $mtp->name(); |
|
| 408 | + $values[] = array( |
|
| 409 | + 'text' => empty($name) ? __('Global', 'event_espresso') : $name, |
|
| 410 | + 'id' => $mtp->ID(), |
|
| 411 | + ); |
|
| 412 | + } |
|
| 413 | + //need to get a list of shortcodes that are available for the newsletter message type. |
|
| 414 | + $shortcodes = EEH_MSG_Template::get_shortcodes('newsletter', 'email', array(), 'attendee', false); |
|
| 415 | + foreach ($shortcodes as $field => $shortcode_array) { |
|
| 416 | + $codes[$field] = implode(', ', array_keys($shortcode_array)); |
|
| 417 | + } |
|
| 418 | + $shortcodes = $codes; |
|
| 419 | + $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 420 | + $form_template_args = array( |
|
| 421 | + 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
| 422 | + 'form_route' => 'newsletter_selected_send', |
|
| 423 | + 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
| 424 | + 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
| 425 | + 'redirect_back_to' => $this->_req_action, |
|
| 426 | + 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
| 427 | + 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
| 428 | + 'shortcodes' => $shortcodes, |
|
| 429 | + 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
| 430 | + ); |
|
| 431 | + EEH_Template::display_template($form_template, $form_template_args); |
|
| 432 | + } |
|
| 433 | + |
|
| 434 | + |
|
| 435 | + |
|
| 436 | + /** |
|
| 437 | + * Handles sending selected registrations/contacts a newsletter. |
|
| 438 | + * |
|
| 439 | + * @since 4.3.0 |
|
| 440 | + * @return void |
|
| 441 | + * @throws \EE_Error |
|
| 442 | + */ |
|
| 443 | + protected function _newsletter_selected_send() |
|
| 444 | + { |
|
| 445 | + $success = true; |
|
| 446 | + //first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
| 447 | + if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
| 448 | + EE_Error::add_error( |
|
| 449 | + __( |
|
| 450 | + 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
| 451 | + 'event_espresso' |
|
| 452 | + ), |
|
| 453 | + __FILE__, |
|
| 454 | + __FUNCTION__, |
|
| 455 | + __LINE__ |
|
| 456 | + ); |
|
| 457 | + $success = false; |
|
| 458 | + } |
|
| 459 | + if ($success) { |
|
| 460 | + //update Message template in case there are any changes |
|
| 461 | + $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
| 462 | + $this->_req_data['newsletter_mtp_selected'] |
|
| 463 | + ); |
|
| 464 | + $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
| 465 | + ? $Message_Template_Group->context_templates() |
|
| 466 | + : array(); |
|
| 467 | + if (empty($Message_Templates)) { |
|
| 468 | + EE_Error::add_error( |
|
| 469 | + __( |
|
| 470 | + 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
| 471 | + 'event_espresso' |
|
| 472 | + ), |
|
| 473 | + __FILE__, |
|
| 474 | + __FUNCTION__, |
|
| 475 | + __LINE__ |
|
| 476 | + ); |
|
| 477 | + } |
|
| 478 | + //let's just update the specific fields |
|
| 479 | + foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
| 480 | + if ($Message_Template instanceof EE_Message_Template) { |
|
| 481 | + $field = $Message_Template->get('MTP_template_field'); |
|
| 482 | + $content = $Message_Template->get('MTP_content'); |
|
| 483 | + $new_content = $content; |
|
| 484 | + switch ($field) { |
|
| 485 | + case 'from' : |
|
| 486 | + $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
| 487 | + ? $this->_req_data['batch_message']['from'] |
|
| 488 | + : $content; |
|
| 489 | + break; |
|
| 490 | + case 'subject' : |
|
| 491 | + $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
| 492 | + ? $this->_req_data['batch_message']['subject'] |
|
| 493 | + : $content; |
|
| 494 | + break; |
|
| 495 | + case 'content' : |
|
| 496 | + $new_content = $content; |
|
| 497 | + $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
| 498 | + ? $this->_req_data['batch_message']['content'] |
|
| 499 | + : $content['newsletter_content']; |
|
| 500 | + break; |
|
| 501 | + default : |
|
| 502 | + //continue the foreach loop, we don't want to set $new_content nor save. |
|
| 503 | + continue 2; |
|
| 504 | + } |
|
| 505 | + $Message_Template->set('MTP_content', $new_content); |
|
| 506 | + $Message_Template->save(); |
|
| 507 | + } |
|
| 508 | + } |
|
| 509 | + //great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
| 510 | + $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
| 511 | + ? $this->_req_data['batch_message']['id_type'] |
|
| 512 | + : 'registration'; |
|
| 513 | + //id_type will affect how we assemble the ids. |
|
| 514 | + $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
| 515 | + ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
| 516 | + : array(); |
|
| 517 | + $registrations_used_for_contact_data = array(); |
|
| 518 | + //using switch because eventually we'll have other contexts that will be used for generating messages. |
|
| 519 | + switch ($id_type) { |
|
| 520 | + case 'registration' : |
|
| 521 | + $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
| 522 | + array( |
|
| 523 | + array( |
|
| 524 | + 'REG_ID' => array('IN', $ids), |
|
| 525 | + ), |
|
| 526 | + ) |
|
| 527 | + ); |
|
| 528 | + break; |
|
| 529 | + case 'contact' : |
|
| 530 | + $registrations_used_for_contact_data = EEM_Registration::instance() |
|
| 531 | + ->get_latest_registration_for_each_of_given_contacts($ids); |
|
| 532 | + break; |
|
| 533 | + } |
|
| 534 | + do_action( |
|
| 535 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
| 536 | + $registrations_used_for_contact_data, |
|
| 537 | + $Message_Template_Group->ID() |
|
| 538 | + ); |
|
| 539 | + //kept for backward compat, internally we no longer use this action. |
|
| 540 | + //@deprecated 4.8.36.rc.002 |
|
| 541 | + $contacts = $id_type === 'registration' |
|
| 542 | + ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
| 543 | + : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
| 544 | + do_action( |
|
| 545 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
| 546 | + $contacts, |
|
| 547 | + $Message_Template_Group->ID() |
|
| 548 | + ); |
|
| 549 | + } |
|
| 550 | + $query_args = array( |
|
| 551 | + 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
| 552 | + ? $this->_req_data['redirect_back_to'] |
|
| 553 | + : 'default', |
|
| 554 | + ); |
|
| 555 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 556 | + } |
|
| 557 | + |
|
| 558 | + |
|
| 559 | + |
|
| 560 | + /** |
|
| 561 | + * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
| 562 | + * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
| 563 | + */ |
|
| 564 | + protected function _registration_reports_js_setup() |
|
| 565 | + { |
|
| 566 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
| 567 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
| 568 | + } |
|
| 569 | + |
|
| 570 | + |
|
| 571 | + |
|
| 572 | + /** |
|
| 573 | + * generates Business Reports regarding Registrations |
|
| 574 | + * |
|
| 575 | + * @access protected |
|
| 576 | + * @return void |
|
| 577 | + */ |
|
| 578 | + protected function _registration_reports() |
|
| 579 | + { |
|
| 580 | + $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 581 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 582 | + $template_path, |
|
| 583 | + $this->_reports_template_data, |
|
| 584 | + true |
|
| 585 | + ); |
|
| 586 | + // the final template wrapper |
|
| 587 | + $this->display_admin_page_with_no_sidebar(); |
|
| 588 | + } |
|
| 589 | + |
|
| 590 | + |
|
| 591 | + |
|
| 592 | + /** |
|
| 593 | + * Generates Business Report showing total registrations per day. |
|
| 594 | + * |
|
| 595 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 596 | + * @return string |
|
| 597 | + */ |
|
| 598 | + private function _registrations_per_day_report($period = '-1 month') |
|
| 599 | + { |
|
| 600 | + $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
| 601 | + $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
| 602 | + $results = (array)$results; |
|
| 603 | + $regs = array(); |
|
| 604 | + $subtitle = ''; |
|
| 605 | + if ($results) { |
|
| 606 | + $column_titles = array(); |
|
| 607 | + $tracker = 0; |
|
| 608 | + foreach ($results as $result) { |
|
| 609 | + $report_column_values = array(); |
|
| 610 | + foreach ($result as $property_name => $property_value) { |
|
| 611 | + $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
| 612 | + : (int)$property_value; |
|
| 613 | + $report_column_values[] = $property_value; |
|
| 614 | + if ($tracker === 0) { |
|
| 615 | + if ($property_name === 'Registration_REG_date') { |
|
| 616 | + $column_titles[] = __('Date (only days with registrations are shown)', 'event_espresso'); |
|
| 617 | + } else { |
|
| 618 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 619 | + } |
|
| 620 | + } |
|
| 621 | + } |
|
| 622 | + $tracker++; |
|
| 623 | + $regs[] = $report_column_values; |
|
| 624 | + } |
|
| 625 | + //make sure the column_titles is pushed to the beginning of the array |
|
| 626 | + array_unshift($regs, $column_titles); |
|
| 627 | + //setup the date range. |
|
| 628 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 629 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 630 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
| 631 | + $subtitle = sprintf( |
|
| 632 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 633 | + $beginning_date->format('Y-m-d'), |
|
| 634 | + $ending_date->format('Y-m-d') |
|
| 635 | + ); |
|
| 636 | + } |
|
| 637 | + $report_title = __('Total Registrations per Day', 'event_espresso'); |
|
| 638 | + $report_params = array( |
|
| 639 | + 'title' => $report_title, |
|
| 640 | + 'subtitle' => $subtitle, |
|
| 641 | + 'id' => $report_ID, |
|
| 642 | + 'regs' => $regs, |
|
| 643 | + 'noResults' => empty($regs), |
|
| 644 | + 'noRegsMsg' => sprintf( |
|
| 645 | + __( |
|
| 646 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
| 647 | + 'event_espresso' |
|
| 648 | + ), |
|
| 649 | + '<h2>' . $report_title . '</h2><p>', |
|
| 650 | + '</p>' |
|
| 651 | + ), |
|
| 652 | + ); |
|
| 653 | + wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
| 654 | + return $report_ID; |
|
| 655 | + } |
|
| 656 | + |
|
| 657 | + |
|
| 658 | + |
|
| 659 | + /** |
|
| 660 | + * Generates Business Report showing total registrations per event. |
|
| 661 | + * |
|
| 662 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 663 | + * @return string |
|
| 664 | + */ |
|
| 665 | + private function _registrations_per_event_report($period = '-1 month') |
|
| 666 | + { |
|
| 667 | + $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
| 668 | + $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
| 669 | + $results = (array)$results; |
|
| 670 | + $regs = array(); |
|
| 671 | + $subtitle = ''; |
|
| 672 | + if ($results) { |
|
| 673 | + $column_titles = array(); |
|
| 674 | + $tracker = 0; |
|
| 675 | + foreach ($results as $result) { |
|
| 676 | + $report_column_values = array(); |
|
| 677 | + foreach ($result as $property_name => $property_value) { |
|
| 678 | + $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
| 679 | + $property_value, |
|
| 680 | + 4, |
|
| 681 | + '...' |
|
| 682 | + ) : (int)$property_value; |
|
| 683 | + $report_column_values[] = $property_value; |
|
| 684 | + if ($tracker === 0) { |
|
| 685 | + if ($property_name === 'Registration_Event') { |
|
| 686 | + $column_titles[] = __('Event', 'event_espresso'); |
|
| 687 | + } else { |
|
| 688 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 689 | + } |
|
| 690 | + } |
|
| 691 | + } |
|
| 692 | + $tracker++; |
|
| 693 | + $regs[] = $report_column_values; |
|
| 694 | + } |
|
| 695 | + //make sure the column_titles is pushed to the beginning of the array |
|
| 696 | + array_unshift($regs, $column_titles); |
|
| 697 | + //setup the date range. |
|
| 698 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 699 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 700 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
| 701 | + $subtitle = sprintf( |
|
| 702 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 703 | + $beginning_date->format('Y-m-d'), |
|
| 704 | + $ending_date->format('Y-m-d') |
|
| 705 | + ); |
|
| 706 | + } |
|
| 707 | + $report_title = __('Total Registrations per Event', 'event_espresso'); |
|
| 708 | + $report_params = array( |
|
| 709 | + 'title' => $report_title, |
|
| 710 | + 'subtitle' => $subtitle, |
|
| 711 | + 'id' => $report_ID, |
|
| 712 | + 'regs' => $regs, |
|
| 713 | + 'noResults' => empty($regs), |
|
| 714 | + 'noRegsMsg' => sprintf( |
|
| 715 | + __( |
|
| 716 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
| 717 | + 'event_espresso' |
|
| 718 | + ), |
|
| 719 | + '<h2>' . $report_title . '</h2><p>', |
|
| 720 | + '</p>' |
|
| 721 | + ), |
|
| 722 | + ); |
|
| 723 | + wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
| 724 | + return $report_ID; |
|
| 725 | + } |
|
| 726 | + |
|
| 727 | + |
|
| 728 | + |
|
| 729 | + /** |
|
| 730 | + * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
| 731 | + * |
|
| 732 | + * @access protected |
|
| 733 | + * @return void |
|
| 734 | + * @throws \EE_Error |
|
| 735 | + */ |
|
| 736 | + protected function _registration_checkin_list_table() |
|
| 737 | + { |
|
| 738 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 739 | + $reg_id = isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : null; |
|
| 740 | + /** @var EE_Registration $registration */ |
|
| 741 | + $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
| 742 | + $attendee = $registration->attendee(); |
|
| 743 | + $this->_admin_page_title .= $this->get_action_link_or_button( |
|
| 744 | + 'new_registration', |
|
| 745 | + 'add-registrant', |
|
| 746 | + array('event_id' => $registration->event_ID()), |
|
| 747 | + 'add-new-h2' |
|
| 748 | + ); |
|
| 749 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 750 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 751 | + $legend_items = array( |
|
| 752 | + 'checkin' => array( |
|
| 753 | + 'class' => $checked_in->cssClasses(), |
|
| 754 | + 'desc' => $checked_in->legendLabel(), |
|
| 755 | + ), |
|
| 756 | + 'checkout' => array( |
|
| 757 | + 'class' => $checked_out->cssClasses(), |
|
| 758 | + 'desc' => $checked_out->legendLabel(), |
|
| 759 | + ), |
|
| 760 | + ); |
|
| 761 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 762 | + $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 763 | + /** @var EE_Datetime $datetime */ |
|
| 764 | + $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
| 765 | + $datetime_label = ''; |
|
| 766 | + if ($datetime instanceof EE_Datetime) { |
|
| 767 | + $datetime_label = $datetime->get_dtt_display_name(true); |
|
| 768 | + $datetime_label .= ! empty($datetime_label) |
|
| 769 | + ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 770 | + : $datetime->get_dtt_display_name(); |
|
| 771 | + } |
|
| 772 | + $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
| 773 | + ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 774 | + array( |
|
| 775 | + 'action' => 'event_registrations', |
|
| 776 | + 'event_id' => $registration->event_ID(), |
|
| 777 | + 'DTT_ID' => $dtt_id, |
|
| 778 | + ), |
|
| 779 | + $this->_admin_base_url |
|
| 780 | + ) |
|
| 781 | + : ''; |
|
| 782 | + $datetime_link = ! empty($datetime_link) |
|
| 783 | + ? '<a href="' . $datetime_link . '">' |
|
| 784 | + . '<span id="checkin-dtt">' |
|
| 785 | + . $datetime_label |
|
| 786 | + . '</span></a>' |
|
| 787 | + : $datetime_label; |
|
| 788 | + $attendee_name = $attendee instanceof EE_Attendee |
|
| 789 | + ? $attendee->full_name() |
|
| 790 | + : ''; |
|
| 791 | + $attendee_link = $attendee instanceof EE_Attendee |
|
| 792 | + ? $attendee->get_admin_details_link() |
|
| 793 | + : ''; |
|
| 794 | + $attendee_link = ! empty($attendee_link) |
|
| 795 | + ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 796 | + . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 797 | + . '<span id="checkin-attendee-name">' |
|
| 798 | + . $attendee_name |
|
| 799 | + . '</span></a>' |
|
| 800 | + : ''; |
|
| 801 | + $event_link = $registration->event() instanceof EE_Event |
|
| 802 | + ? $registration->event()->get_admin_details_link() |
|
| 803 | + : ''; |
|
| 804 | + $event_link = ! empty($event_link) |
|
| 805 | + ? '<a href="' . $event_link . '"' |
|
| 806 | + . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 807 | + . '<span id="checkin-event-name">' |
|
| 808 | + . $registration->event_name() |
|
| 809 | + . '</span>' |
|
| 810 | + . '</a>' |
|
| 811 | + : ''; |
|
| 812 | + $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
| 813 | + ? '<h2>' . sprintf( |
|
| 814 | + esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
| 815 | + $attendee_link, |
|
| 816 | + $datetime_link, |
|
| 817 | + $event_link |
|
| 818 | + ) . '</h2>' |
|
| 819 | + : ''; |
|
| 820 | + $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
| 821 | + ? '<input type="hidden" name="_REGID" value="' . $reg_id . '">' : ''; |
|
| 822 | + $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
| 823 | + ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 824 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 825 | + } |
|
| 826 | + |
|
| 827 | + |
|
| 828 | + |
|
| 829 | + /** |
|
| 830 | + * toggle the Check-in status for the given registration (coming from ajax) |
|
| 831 | + * |
|
| 832 | + * @return void (JSON) |
|
| 833 | + */ |
|
| 834 | + public function toggle_checkin_status() |
|
| 835 | + { |
|
| 836 | + //first make sure we have the necessary data |
|
| 837 | + if ( ! isset($this->_req_data['_regid'])) { |
|
| 838 | + EE_Error::add_error( |
|
| 839 | + __( |
|
| 840 | + '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', |
|
| 841 | + 'event_espresso' |
|
| 842 | + ), |
|
| 843 | + __FILE__, |
|
| 844 | + __FUNCTION__, |
|
| 845 | + __LINE__ |
|
| 846 | + ); |
|
| 847 | + $this->_template_args['success'] = false; |
|
| 848 | + $this->_template_args['error'] = true; |
|
| 849 | + $this->_return_json(); |
|
| 850 | + }; |
|
| 851 | + //do a nonce check cause we're not coming in from an normal route here. |
|
| 852 | + $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
| 853 | + : ''; |
|
| 854 | + $nonce_ref = 'checkin_nonce'; |
|
| 855 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
| 856 | + //beautiful! Made it this far so let's get the status. |
|
| 857 | + $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
| 858 | + //setup new class to return via ajax |
|
| 859 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 860 | + $this->_template_args['success'] = true; |
|
| 861 | + $this->_return_json(); |
|
| 862 | + } |
|
| 863 | + |
|
| 864 | + |
|
| 865 | + |
|
| 866 | + /** |
|
| 867 | + * handles toggling the checkin status for the registration, |
|
| 868 | + * |
|
| 869 | + * @access protected |
|
| 870 | + * @return int|void |
|
| 871 | + */ |
|
| 872 | + protected function _toggle_checkin_status() |
|
| 873 | + { |
|
| 874 | + //first let's get the query args out of the way for the redirect |
|
| 875 | + $query_args = array( |
|
| 876 | + 'action' => 'event_registrations', |
|
| 877 | + 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 878 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
| 879 | + ); |
|
| 880 | + $new_status = false; |
|
| 881 | + // bulk action check in toggle |
|
| 882 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 883 | + // cycle thru checkboxes |
|
| 884 | + while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 885 | + $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 886 | + $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
| 887 | + } |
|
| 888 | + } elseif (isset($this->_req_data['_regid'])) { |
|
| 889 | + //coming from ajax request |
|
| 890 | + $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
| 891 | + $query_args['DTT_ID'] = $DTT_ID; |
|
| 892 | + $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
| 893 | + } else { |
|
| 894 | + EE_Error::add_error( |
|
| 895 | + __('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
| 896 | + __FILE__, |
|
| 897 | + __FUNCTION__, |
|
| 898 | + __LINE__ |
|
| 899 | + ); |
|
| 900 | + } |
|
| 901 | + if (defined('DOING_AJAX')) { |
|
| 902 | + return $new_status; |
|
| 903 | + } |
|
| 904 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 905 | + } |
|
| 906 | + |
|
| 907 | + |
|
| 908 | + |
|
| 909 | + /** |
|
| 910 | + * This is toggles a single Check-in for the given registration and datetime. |
|
| 911 | + * |
|
| 912 | + * @param int $REG_ID The registration we're toggling |
|
| 913 | + * @param int $DTT_ID The datetime we're toggling |
|
| 914 | + * @return int The new status toggled to. |
|
| 915 | + * @throws \EE_Error |
|
| 916 | + */ |
|
| 917 | + private function _toggle_checkin($REG_ID, $DTT_ID) |
|
| 918 | + { |
|
| 919 | + /** @var EE_Registration $REG */ |
|
| 920 | + $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
| 921 | + $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
| 922 | + if ($new_status !== false) { |
|
| 923 | + EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
| 924 | + } else { |
|
| 925 | + EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
| 926 | + $new_status = false; |
|
| 927 | + } |
|
| 928 | + return $new_status; |
|
| 929 | + } |
|
| 930 | + |
|
| 931 | + |
|
| 932 | + |
|
| 933 | + /** |
|
| 934 | + * Takes care of deleting multiple EE_Checkin table rows |
|
| 935 | + * |
|
| 936 | + * @access protected |
|
| 937 | + * @return void |
|
| 938 | + * @throws \EE_Error |
|
| 939 | + */ |
|
| 940 | + protected function _delete_checkin_rows() |
|
| 941 | + { |
|
| 942 | + $query_args = array( |
|
| 943 | + 'action' => 'registration_checkins', |
|
| 944 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 945 | + '_REGID' => isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : 0, |
|
| 946 | + ); |
|
| 947 | + $errors = 0; |
|
| 948 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 949 | + while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 950 | + if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 951 | + $errors++; |
|
| 952 | + } |
|
| 953 | + } |
|
| 954 | + } else { |
|
| 955 | + EE_Error::add_error( |
|
| 956 | + __( |
|
| 957 | + 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
| 958 | + 'event_espresso' |
|
| 959 | + ), |
|
| 960 | + __FILE__, |
|
| 961 | + __FUNCTION__, |
|
| 962 | + __LINE__ |
|
| 963 | + ); |
|
| 964 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 965 | + } |
|
| 966 | + if ($errors > 0) { |
|
| 967 | + EE_Error::add_error( |
|
| 968 | + sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
| 969 | + __FILE__, |
|
| 970 | + __FUNCTION__, |
|
| 971 | + __LINE__ |
|
| 972 | + ); |
|
| 973 | + } else { |
|
| 974 | + EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
| 975 | + } |
|
| 976 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 977 | + } |
|
| 978 | + |
|
| 979 | + |
|
| 980 | + |
|
| 981 | + /** |
|
| 982 | + * Deletes a single EE_Checkin row |
|
| 983 | + * |
|
| 984 | + * @return void |
|
| 985 | + * @throws \EE_Error |
|
| 986 | + */ |
|
| 987 | + protected function _delete_checkin_row() |
|
| 988 | + { |
|
| 989 | + $query_args = array( |
|
| 990 | + 'action' => 'registration_checkins', |
|
| 991 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 992 | + '_REGID' => isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : 0, |
|
| 993 | + ); |
|
| 994 | + if ( ! empty($this->_req_data['CHK_ID'])) { |
|
| 995 | + if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 996 | + EE_Error::add_error( |
|
| 997 | + __('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
| 998 | + __FILE__, |
|
| 999 | + __FUNCTION__, |
|
| 1000 | + __LINE__ |
|
| 1001 | + ); |
|
| 1002 | + } else { |
|
| 1003 | + EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
| 1004 | + } |
|
| 1005 | + } else { |
|
| 1006 | + EE_Error::add_error( |
|
| 1007 | + __( |
|
| 1008 | + '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', |
|
| 1009 | + 'event_espresso' |
|
| 1010 | + ), |
|
| 1011 | + __FILE__, |
|
| 1012 | + __FUNCTION__, |
|
| 1013 | + __LINE__ |
|
| 1014 | + ); |
|
| 1015 | + } |
|
| 1016 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1017 | + } |
|
| 1018 | + |
|
| 1019 | + |
|
| 1020 | + |
|
| 1021 | + /** |
|
| 1022 | + * generates HTML for the Event Registrations List Table |
|
| 1023 | + * |
|
| 1024 | + * @access protected |
|
| 1025 | + * @return void |
|
| 1026 | + * @throws \EE_Error |
|
| 1027 | + */ |
|
| 1028 | + protected function _event_registrations_list_table() |
|
| 1029 | + { |
|
| 1030 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1031 | + $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
| 1032 | + ? $this->get_action_link_or_button( |
|
| 1033 | + 'new_registration', |
|
| 1034 | + 'add-registrant', |
|
| 1035 | + array('event_id' => $this->_req_data['event_id']), |
|
| 1036 | + 'add-new-h2', |
|
| 1037 | + '', |
|
| 1038 | + false |
|
| 1039 | + ) |
|
| 1040 | + : ''; |
|
| 1041 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 1042 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 1043 | + $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
| 1044 | + $legend_items = array( |
|
| 1045 | + 'star-icon' => array( |
|
| 1046 | + 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
| 1047 | + 'desc' => __('This Registrant is the Primary Registrant', 'event_espresso'), |
|
| 1048 | + ), |
|
| 1049 | + 'checkin' => array( |
|
| 1050 | + 'class' => $checked_in->cssClasses(), |
|
| 1051 | + 'desc' => $checked_in->legendLabel(), |
|
| 1052 | + ), |
|
| 1053 | + 'checkout' => array( |
|
| 1054 | + 'class' => $checked_out->cssClasses(), |
|
| 1055 | + 'desc' => $checked_out->legendLabel(), |
|
| 1056 | + ), |
|
| 1057 | + 'nocheckinrecord' => array( |
|
| 1058 | + 'class' => $checked_never->cssClasses(), |
|
| 1059 | + 'desc' => $checked_never->legendLabel(), |
|
| 1060 | + ), |
|
| 1061 | + 'view_details' => array( |
|
| 1062 | + 'class' => 'dashicons dashicons-search', |
|
| 1063 | + 'desc' => __('View All Check-in Records for this Registrant', 'event_espresso'), |
|
| 1064 | + ), |
|
| 1065 | + 'approved_status' => array( |
|
| 1066 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1067 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
| 1068 | + ), |
|
| 1069 | + 'cancelled_status' => array( |
|
| 1070 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1071 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
| 1072 | + ), |
|
| 1073 | + 'declined_status' => array( |
|
| 1074 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1075 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
| 1076 | + ), |
|
| 1077 | + 'not_approved' => array( |
|
| 1078 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1079 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
| 1080 | + ), |
|
| 1081 | + 'pending_status' => array( |
|
| 1082 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1083 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
| 1084 | + ), |
|
| 1085 | + 'wait_list' => array( |
|
| 1086 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1087 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
| 1088 | + ), |
|
| 1089 | + ); |
|
| 1090 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 1091 | + $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
| 1092 | + $this->_template_args['before_list_table'] = ! empty($event_id) |
|
| 1093 | + ? '<h2>' . sprintf( |
|
| 1094 | + __('Viewing Registrations for Event: %s', 'event_espresso'), |
|
| 1095 | + EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
| 1096 | + ) . '</h2>' |
|
| 1097 | + : ''; |
|
| 1098 | + //need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on the event. |
|
| 1099 | + /** @var EE_Event $event */ |
|
| 1100 | + $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 1101 | + $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
| 1102 | + $datetime = null; |
|
| 1103 | + if ($event instanceof EE_Event) { |
|
| 1104 | + $datetimes_on_event = $event->datetimes(); |
|
| 1105 | + if (count($datetimes_on_event) === 1) { |
|
| 1106 | + $datetime = reset($datetimes_on_event); |
|
| 1107 | + } |
|
| 1108 | + } |
|
| 1109 | + $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
| 1110 | + if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
| 1111 | + $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
| 1112 | + $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
| 1113 | + $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
| 1114 | + $this->_template_args['before_list_table'] .= $datetime->name(); |
|
| 1115 | + $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1116 | + $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
| 1117 | + } |
|
| 1118 | + //if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status column |
|
| 1119 | + //represents |
|
| 1120 | + if ( ! $datetime instanceof EE_Datetime) { |
|
| 1121 | + $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
| 1122 | + . __('In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
| 1123 | + 'event_espresso') |
|
| 1124 | + . '</p>'; |
|
| 1125 | + } |
|
| 1126 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 1127 | + } |
|
| 1128 | + |
|
| 1129 | + /** |
|
| 1130 | + * Download the registrations check-in report (same as the normal registration report, but with different where |
|
| 1131 | + * conditions) |
|
| 1132 | + * |
|
| 1133 | + * @return void ends the request by a redirect or download |
|
| 1134 | + */ |
|
| 1135 | + public function _registrations_checkin_report() |
|
| 1136 | + { |
|
| 1137 | + $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
| 1138 | + } |
|
| 1139 | + |
|
| 1140 | + /** |
|
| 1141 | + * Gets the query params from the request, plus adds a where condition for the registration status, |
|
| 1142 | + * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
| 1143 | + * |
|
| 1144 | + * @param array $request |
|
| 1145 | + * @param int $per_page |
|
| 1146 | + * @param bool $count |
|
| 1147 | + * @return array |
|
| 1148 | + */ |
|
| 1149 | + protected function _get_checkin_query_params_from_request( |
|
| 1150 | + $request, |
|
| 1151 | + $per_page = 10, |
|
| 1152 | + $count = false |
|
| 1153 | + ) { |
|
| 1154 | + $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
| 1155 | + //unlike the regular registrations list table, |
|
| 1156 | + $status_ids_array = apply_filters( |
|
| 1157 | + 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
| 1158 | + array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
| 1159 | + ); |
|
| 1160 | + $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
| 1161 | + return $query_params; |
|
| 1162 | + } |
|
| 1163 | + |
|
| 1164 | + |
|
| 1165 | + |
|
| 1166 | + |
|
| 1167 | + /** |
|
| 1168 | + * Gets registrations for an event |
|
| 1169 | + * |
|
| 1170 | + * @param int $per_page |
|
| 1171 | + * @param bool $count whether to return count or data. |
|
| 1172 | + * @param bool $trash |
|
| 1173 | + * @param string $orderby |
|
| 1174 | + * @return EE_Registration[]|int |
|
| 1175 | + * @throws \EE_Error |
|
| 1176 | + */ |
|
| 1177 | + public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
| 1178 | + { |
|
| 1179 | + //normalize some request params that get setup by the parent `get_registrations` method. |
|
| 1180 | + $request = $this->_req_data; |
|
| 1181 | + $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
| 1182 | + $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1183 | + if($trash){ |
|
| 1184 | + $request['status'] = 'trash'; |
|
| 1185 | + } |
|
| 1186 | + $query_params = $this->_get_checkin_query_params_from_request( $request, $per_page, $count ); |
|
| 1187 | + /** |
|
| 1188 | + * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
| 1189 | + * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
| 1190 | + * @see EEM_Base::get_all() |
|
| 1191 | + */ |
|
| 1192 | + $query_params['group_by'] = ''; |
|
| 1193 | + |
|
| 1194 | + return $count |
|
| 1195 | + ? EEM_Registration::instance()->count($query_params) |
|
| 1196 | + /** @type EE_Registration[] */ |
|
| 1197 | + : EEM_Registration::instance()->get_all($query_params); |
|
| 1198 | + } |
|
| 1199 | 1199 | |
| 1200 | 1200 | |
| 1201 | 1201 | } //end class Registrations Admin Page |
@@ -21,100 +21,100 @@ |
||
| 21 | 21 | class CheckinStatusDashicon |
| 22 | 22 | { |
| 23 | 23 | |
| 24 | - /** |
|
| 25 | - * @var int $checkin_status |
|
| 26 | - */ |
|
| 27 | - private $checkin_status; |
|
| 28 | - |
|
| 29 | - |
|
| 30 | - /** |
|
| 31 | - * CheckinStatusDashicon constructor. |
|
| 32 | - * |
|
| 33 | - * @param int $checkin_status |
|
| 34 | - */ |
|
| 35 | - public function __construct($checkin_status = EE_Checkin::status_checked_never) |
|
| 36 | - { |
|
| 37 | - $this->checkin_status = $checkin_status; |
|
| 38 | - } |
|
| 39 | - |
|
| 40 | - |
|
| 41 | - /** |
|
| 42 | - * @param EE_Checkin $checkin |
|
| 43 | - * @return CheckinStatusDashicon |
|
| 44 | - * @throws EE_Error |
|
| 45 | - */ |
|
| 46 | - public static function fromCheckin(EE_Checkin $checkin) |
|
| 47 | - { |
|
| 48 | - return new CheckinStatusDashicon( |
|
| 49 | - $checkin->status() |
|
| 50 | - ? EE_Checkin::status_checked_in |
|
| 51 | - : EE_Checkin::status_checked_out |
|
| 52 | - ); |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * @param EE_Registration $registration |
|
| 58 | - * @param EE_Datetime $datetime |
|
| 59 | - * @return CheckinStatusDashicon |
|
| 60 | - * @throws EE_Error |
|
| 61 | - */ |
|
| 62 | - public static function fromRegistrationAndDatetime(EE_Registration $registration, EE_Datetime $datetime) |
|
| 63 | - { |
|
| 64 | - return new CheckinStatusDashicon( |
|
| 65 | - $registration->check_in_status_for_datetime( |
|
| 66 | - $datetime->ID() |
|
| 67 | - ) |
|
| 68 | - ); |
|
| 69 | - } |
|
| 70 | - |
|
| 71 | - |
|
| 72 | - /** |
|
| 73 | - * @param EE_Registration $registration |
|
| 74 | - * @param int $DTT_ID |
|
| 75 | - * @return CheckinStatusDashicon |
|
| 76 | - * @throws EE_Error |
|
| 77 | - */ |
|
| 78 | - public static function fromRegistrationAndDatetimeId(EE_Registration $registration, $DTT_ID = 0) |
|
| 79 | - { |
|
| 80 | - return new CheckinStatusDashicon( |
|
| 81 | - $registration->check_in_status_for_datetime( |
|
| 82 | - absint($DTT_ID) |
|
| 83 | - ) |
|
| 84 | - ); |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - /** |
|
| 88 | - * Will return the correct set of dashicon css classes for the set checkin status |
|
| 89 | - * |
|
| 90 | - * @return string |
|
| 91 | - */ |
|
| 92 | - public function cssClasses() |
|
| 93 | - { |
|
| 94 | - if ($this->checkin_status === EE_Checkin::status_checked_in) { |
|
| 95 | - return "ee-dashicons ee-icon-check-in checkin-icons checkedin-status-{$this->checkin_status}"; |
|
| 96 | - } |
|
| 97 | - if ($this->checkin_status === EE_Checkin::status_checked_out) { |
|
| 98 | - return "ee-dashicons ee-icon-check-out checkin-icons checkedin-status-{$this->checkin_status}"; |
|
| 99 | - } |
|
| 100 | - return "dashicons dashicons-no checkin-icons checkedin-status-{$this->checkin_status}"; |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - /** |
|
| 104 | - * returns a description for the Checkin Status Dashicon that can be used in List Table Legends |
|
| 105 | - * |
|
| 106 | - * @return string |
|
| 107 | - */ |
|
| 108 | - public function legendLabel() |
|
| 109 | - { |
|
| 110 | - if ($this->checkin_status === EE_Checkin::status_checked_in) { |
|
| 111 | - return esc_html__('This Registrant has been Checked In', 'event_espresso'); |
|
| 112 | - } |
|
| 113 | - if ($this->checkin_status === EE_Checkin::status_checked_out) { |
|
| 114 | - return esc_html__('This Registrant has been Checked Out', 'event_espresso'); |
|
| 115 | - } |
|
| 116 | - return esc_html__('No Check-in Record has been Created for this Registrant', 'event_espresso'); |
|
| 117 | - } |
|
| 24 | + /** |
|
| 25 | + * @var int $checkin_status |
|
| 26 | + */ |
|
| 27 | + private $checkin_status; |
|
| 28 | + |
|
| 29 | + |
|
| 30 | + /** |
|
| 31 | + * CheckinStatusDashicon constructor. |
|
| 32 | + * |
|
| 33 | + * @param int $checkin_status |
|
| 34 | + */ |
|
| 35 | + public function __construct($checkin_status = EE_Checkin::status_checked_never) |
|
| 36 | + { |
|
| 37 | + $this->checkin_status = $checkin_status; |
|
| 38 | + } |
|
| 39 | + |
|
| 40 | + |
|
| 41 | + /** |
|
| 42 | + * @param EE_Checkin $checkin |
|
| 43 | + * @return CheckinStatusDashicon |
|
| 44 | + * @throws EE_Error |
|
| 45 | + */ |
|
| 46 | + public static function fromCheckin(EE_Checkin $checkin) |
|
| 47 | + { |
|
| 48 | + return new CheckinStatusDashicon( |
|
| 49 | + $checkin->status() |
|
| 50 | + ? EE_Checkin::status_checked_in |
|
| 51 | + : EE_Checkin::status_checked_out |
|
| 52 | + ); |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * @param EE_Registration $registration |
|
| 58 | + * @param EE_Datetime $datetime |
|
| 59 | + * @return CheckinStatusDashicon |
|
| 60 | + * @throws EE_Error |
|
| 61 | + */ |
|
| 62 | + public static function fromRegistrationAndDatetime(EE_Registration $registration, EE_Datetime $datetime) |
|
| 63 | + { |
|
| 64 | + return new CheckinStatusDashicon( |
|
| 65 | + $registration->check_in_status_for_datetime( |
|
| 66 | + $datetime->ID() |
|
| 67 | + ) |
|
| 68 | + ); |
|
| 69 | + } |
|
| 70 | + |
|
| 71 | + |
|
| 72 | + /** |
|
| 73 | + * @param EE_Registration $registration |
|
| 74 | + * @param int $DTT_ID |
|
| 75 | + * @return CheckinStatusDashicon |
|
| 76 | + * @throws EE_Error |
|
| 77 | + */ |
|
| 78 | + public static function fromRegistrationAndDatetimeId(EE_Registration $registration, $DTT_ID = 0) |
|
| 79 | + { |
|
| 80 | + return new CheckinStatusDashicon( |
|
| 81 | + $registration->check_in_status_for_datetime( |
|
| 82 | + absint($DTT_ID) |
|
| 83 | + ) |
|
| 84 | + ); |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + /** |
|
| 88 | + * Will return the correct set of dashicon css classes for the set checkin status |
|
| 89 | + * |
|
| 90 | + * @return string |
|
| 91 | + */ |
|
| 92 | + public function cssClasses() |
|
| 93 | + { |
|
| 94 | + if ($this->checkin_status === EE_Checkin::status_checked_in) { |
|
| 95 | + return "ee-dashicons ee-icon-check-in checkin-icons checkedin-status-{$this->checkin_status}"; |
|
| 96 | + } |
|
| 97 | + if ($this->checkin_status === EE_Checkin::status_checked_out) { |
|
| 98 | + return "ee-dashicons ee-icon-check-out checkin-icons checkedin-status-{$this->checkin_status}"; |
|
| 99 | + } |
|
| 100 | + return "dashicons dashicons-no checkin-icons checkedin-status-{$this->checkin_status}"; |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + /** |
|
| 104 | + * returns a description for the Checkin Status Dashicon that can be used in List Table Legends |
|
| 105 | + * |
|
| 106 | + * @return string |
|
| 107 | + */ |
|
| 108 | + public function legendLabel() |
|
| 109 | + { |
|
| 110 | + if ($this->checkin_status === EE_Checkin::status_checked_in) { |
|
| 111 | + return esc_html__('This Registrant has been Checked In', 'event_espresso'); |
|
| 112 | + } |
|
| 113 | + if ($this->checkin_status === EE_Checkin::status_checked_out) { |
|
| 114 | + return esc_html__('This Registrant has been Checked Out', 'event_espresso'); |
|
| 115 | + } |
|
| 116 | + return esc_html__('No Check-in Record has been Created for this Registrant', 'event_espresso'); |
|
| 117 | + } |
|
| 118 | 118 | |
| 119 | 119 | |
| 120 | 120 | } |
@@ -8,645 +8,645 @@ |
||
| 8 | 8 | class EE_Email_messenger extends EE_messenger |
| 9 | 9 | { |
| 10 | 10 | |
| 11 | - /** |
|
| 12 | - * To field for email |
|
| 13 | - * @var string |
|
| 14 | - */ |
|
| 15 | - protected $_to = ''; |
|
| 16 | - |
|
| 17 | - |
|
| 18 | - /** |
|
| 19 | - * CC field for email. |
|
| 20 | - * @var string |
|
| 21 | - */ |
|
| 22 | - protected $_cc = ''; |
|
| 23 | - |
|
| 24 | - /** |
|
| 25 | - * From field for email |
|
| 26 | - * @var string |
|
| 27 | - */ |
|
| 28 | - protected $_from = ''; |
|
| 29 | - |
|
| 30 | - |
|
| 31 | - /** |
|
| 32 | - * Subject field for email |
|
| 33 | - * @var string |
|
| 34 | - */ |
|
| 35 | - protected $_subject = ''; |
|
| 36 | - |
|
| 37 | - |
|
| 38 | - /** |
|
| 39 | - * Content field for email |
|
| 40 | - * @var string |
|
| 41 | - */ |
|
| 42 | - protected $_content = ''; |
|
| 43 | - |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * constructor |
|
| 47 | - * |
|
| 48 | - * @access public |
|
| 49 | - */ |
|
| 50 | - public function __construct() |
|
| 51 | - { |
|
| 52 | - //set name and description properties |
|
| 53 | - $this->name = 'email'; |
|
| 54 | - $this->description = sprintf( |
|
| 55 | - esc_html__( |
|
| 56 | - 'This messenger delivers messages via email using the built-in %s function included with WordPress', |
|
| 57 | - 'event_espresso' |
|
| 58 | - ), |
|
| 59 | - '<code>wp_mail</code>' |
|
| 60 | - ); |
|
| 61 | - $this->label = array( |
|
| 62 | - 'singular' => esc_html__('email', 'event_espresso'), |
|
| 63 | - 'plural' => esc_html__('emails', 'event_espresso'), |
|
| 64 | - ); |
|
| 65 | - $this->activate_on_install = true; |
|
| 66 | - |
|
| 67 | - //we're using defaults so let's call parent constructor that will take care of setting up all the other |
|
| 68 | - // properties |
|
| 69 | - parent::__construct(); |
|
| 70 | - } |
|
| 71 | - |
|
| 72 | - |
|
| 73 | - /** |
|
| 74 | - * see abstract declaration in parent class for details. |
|
| 75 | - */ |
|
| 76 | - protected function _set_admin_pages() |
|
| 77 | - { |
|
| 78 | - $this->admin_registered_pages = array( |
|
| 79 | - 'events_edit' => true, |
|
| 80 | - ); |
|
| 81 | - } |
|
| 82 | - |
|
| 83 | - |
|
| 84 | - /** |
|
| 85 | - * see abstract declaration in parent class for details |
|
| 86 | - */ |
|
| 87 | - protected function _set_valid_shortcodes() |
|
| 88 | - { |
|
| 89 | - //remember by leaving the other fields not set, those fields will inherit the valid shortcodes from the |
|
| 90 | - // message type. |
|
| 91 | - $this->_valid_shortcodes = array( |
|
| 92 | - 'to' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'), |
|
| 93 | - 'cc' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'), |
|
| 94 | - 'from' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'), |
|
| 95 | - ); |
|
| 96 | - } |
|
| 97 | - |
|
| 98 | - |
|
| 99 | - /** |
|
| 100 | - * see abstract declaration in parent class for details |
|
| 101 | - * |
|
| 102 | - * @access protected |
|
| 103 | - * @return void |
|
| 104 | - */ |
|
| 105 | - protected function _set_validator_config() |
|
| 106 | - { |
|
| 107 | - $valid_shortcodes = $this->get_valid_shortcodes(); |
|
| 108 | - |
|
| 109 | - $this->_validator_config = array( |
|
| 110 | - 'to' => array( |
|
| 111 | - 'shortcodes' => $valid_shortcodes['to'], |
|
| 112 | - 'type' => 'email', |
|
| 113 | - ), |
|
| 114 | - 'cc' => array( |
|
| 115 | - 'shortcodes' => $valid_shortcodes['to'], |
|
| 116 | - 'type' => 'email', |
|
| 117 | - ), |
|
| 118 | - 'from' => array( |
|
| 119 | - 'shortcodes' => $valid_shortcodes['from'], |
|
| 120 | - 'type' => 'email', |
|
| 121 | - ), |
|
| 122 | - 'subject' => array( |
|
| 123 | - 'shortcodes' => array( |
|
| 124 | - 'organization', |
|
| 125 | - 'primary_registration_details', |
|
| 126 | - 'event_author', |
|
| 127 | - 'primary_registration_details', |
|
| 128 | - 'recipient_details', |
|
| 129 | - ), |
|
| 130 | - ), |
|
| 131 | - 'content' => array( |
|
| 132 | - 'shortcodes' => array( |
|
| 133 | - 'event_list', |
|
| 134 | - 'attendee_list', |
|
| 135 | - 'ticket_list', |
|
| 136 | - 'organization', |
|
| 137 | - 'primary_registration_details', |
|
| 138 | - 'primary_registration_list', |
|
| 139 | - 'event_author', |
|
| 140 | - 'recipient_details', |
|
| 141 | - 'recipient_list', |
|
| 142 | - 'transaction', |
|
| 143 | - 'messenger', |
|
| 144 | - ), |
|
| 145 | - ), |
|
| 146 | - 'attendee_list' => array( |
|
| 147 | - 'shortcodes' => array('attendee', 'event_list', 'ticket_list'), |
|
| 148 | - 'required' => array('[ATTENDEE_LIST]'), |
|
| 149 | - ), |
|
| 150 | - 'event_list' => array( |
|
| 151 | - 'shortcodes' => array( |
|
| 152 | - 'event', |
|
| 153 | - 'attendee_list', |
|
| 154 | - 'ticket_list', |
|
| 155 | - 'venue', |
|
| 156 | - 'datetime_list', |
|
| 157 | - 'attendee', |
|
| 158 | - 'primary_registration_details', |
|
| 159 | - 'primary_registration_list', |
|
| 160 | - 'event_author', |
|
| 161 | - 'recipient_details', |
|
| 162 | - 'recipient_list', |
|
| 163 | - ), |
|
| 164 | - 'required' => array('[EVENT_LIST]'), |
|
| 165 | - ), |
|
| 166 | - 'ticket_list' => array( |
|
| 167 | - 'shortcodes' => array( |
|
| 168 | - 'event_list', |
|
| 169 | - 'attendee_list', |
|
| 170 | - 'ticket', |
|
| 171 | - 'datetime_list', |
|
| 172 | - 'primary_registration_details', |
|
| 173 | - 'recipient_details', |
|
| 174 | - ), |
|
| 175 | - 'required' => array('[TICKET_LIST]'), |
|
| 176 | - ), |
|
| 177 | - 'datetime_list' => array( |
|
| 178 | - 'shortcodes' => array('datetime'), |
|
| 179 | - 'required' => array('[DATETIME_LIST]'), |
|
| 180 | - ), |
|
| 181 | - ); |
|
| 182 | - } |
|
| 183 | - |
|
| 184 | - |
|
| 185 | - /** |
|
| 186 | - * @see parent EE_messenger class for docs |
|
| 187 | - * @since 4.5.0 |
|
| 188 | - */ |
|
| 189 | - public function do_secondary_messenger_hooks($sending_messenger_name) |
|
| 190 | - { |
|
| 191 | - if ($sending_messenger_name = 'html') { |
|
| 192 | - add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8); |
|
| 193 | - } |
|
| 194 | - } |
|
| 195 | - |
|
| 196 | - |
|
| 197 | - public function add_email_css( |
|
| 198 | - $variation_path, |
|
| 199 | - $messenger, |
|
| 200 | - $message_type, |
|
| 201 | - $type, |
|
| 202 | - $variation, |
|
| 203 | - $file_extension, |
|
| 204 | - $url, |
|
| 205 | - EE_Messages_Template_Pack $template_pack |
|
| 206 | - ) { |
|
| 207 | - //prevent recursion on this callback. |
|
| 208 | - remove_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10); |
|
| 209 | - $variation = $this->get_variation($template_pack, $message_type, $url, 'main', $variation, false); |
|
| 210 | - |
|
| 211 | - add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8); |
|
| 212 | - return $variation; |
|
| 213 | - } |
|
| 214 | - |
|
| 215 | - |
|
| 216 | - /** |
|
| 217 | - * See parent for details |
|
| 218 | - * |
|
| 219 | - * @access protected |
|
| 220 | - * @return void |
|
| 221 | - */ |
|
| 222 | - protected function _set_test_settings_fields() |
|
| 223 | - { |
|
| 224 | - $this->_test_settings_fields = array( |
|
| 225 | - 'to' => array( |
|
| 226 | - 'input' => 'text', |
|
| 227 | - 'label' => esc_html__('Send a test email to', 'event_espresso'), |
|
| 228 | - 'type' => 'email', |
|
| 229 | - 'required' => true, |
|
| 230 | - 'validation' => true, |
|
| 231 | - 'css_class' => 'large-text', |
|
| 232 | - 'format' => '%s', |
|
| 233 | - 'default' => get_bloginfo('admin_email'), |
|
| 234 | - ), |
|
| 235 | - 'subject' => array( |
|
| 236 | - 'input' => 'hidden', |
|
| 237 | - 'label' => '', |
|
| 238 | - 'type' => 'string', |
|
| 239 | - 'required' => false, |
|
| 240 | - 'validation' => false, |
|
| 241 | - 'format' => '%s', |
|
| 242 | - 'value' => sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')), |
|
| 243 | - 'default' => '', |
|
| 244 | - 'css_class' => '', |
|
| 245 | - ), |
|
| 246 | - ); |
|
| 247 | - } |
|
| 248 | - |
|
| 249 | - |
|
| 250 | - /** |
|
| 251 | - * _set_template_fields |
|
| 252 | - * This sets up the fields that a messenger requires for the message to go out. |
|
| 253 | - * |
|
| 254 | - * @access protected |
|
| 255 | - * @return void |
|
| 256 | - */ |
|
| 257 | - protected function _set_template_fields() |
|
| 258 | - { |
|
| 259 | - // any extra template fields that are NOT used by the messenger but will get used by a messenger field for |
|
| 260 | - // shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field |
|
| 261 | - // they relate to. This is important for the Messages_admin to know what fields to display to the user. |
|
| 262 | - // Also, notice that the "values" are equal to the field type that messages admin will use to know what |
|
| 263 | - // kind of field to display. The values ALSO have one index labeled "shortcode". the values in that array |
|
| 264 | - // indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be |
|
| 265 | - // displayed. If the required shortcode isn't part of the shortcodes array then the field is not needed and |
|
| 266 | - // will not be displayed/parsed. |
|
| 267 | - $this->_template_fields = array( |
|
| 268 | - 'to' => array( |
|
| 269 | - 'input' => 'text', |
|
| 270 | - 'label' => esc_html_x( |
|
| 271 | - 'To', |
|
| 272 | - 'Label for the "To" field for email addresses', |
|
| 273 | - 'event_espresso' |
|
| 274 | - ), |
|
| 275 | - 'type' => 'string', |
|
| 276 | - 'required' => true, |
|
| 277 | - 'validation' => true, |
|
| 278 | - 'css_class' => 'large-text', |
|
| 279 | - 'format' => '%s', |
|
| 280 | - ), |
|
| 281 | - 'cc' => array( |
|
| 282 | - 'input' => 'text', |
|
| 283 | - 'label' => esc_html_x( |
|
| 284 | - 'CC', |
|
| 285 | - 'Label for the "Carbon Copy" field used for additional email addresses', |
|
| 286 | - 'event_espresso' |
|
| 287 | - ), |
|
| 288 | - 'type' => 'string', |
|
| 289 | - 'required' => false, |
|
| 290 | - 'validation' => true, |
|
| 291 | - 'css_class' => 'large-text', |
|
| 292 | - 'format' => '%s', |
|
| 293 | - ), |
|
| 294 | - 'from' => array( |
|
| 295 | - 'input' => 'text', |
|
| 296 | - 'label' => esc_html_x( |
|
| 297 | - 'From', |
|
| 298 | - 'Label for the "From" field for email addresses.', |
|
| 299 | - 'event_espresso' |
|
| 300 | - ), |
|
| 301 | - 'type' => 'string', |
|
| 302 | - 'required' => true, |
|
| 303 | - 'validation' => true, |
|
| 304 | - 'css_class' => 'large-text', |
|
| 305 | - 'format' => '%s', |
|
| 306 | - ), |
|
| 307 | - 'subject' => array( |
|
| 308 | - 'input' => 'text', |
|
| 309 | - 'label' => esc_html_x( |
|
| 310 | - 'Subject', |
|
| 311 | - 'Label for the "Subject" field (short description of contents) for emails.', |
|
| 312 | - 'event_espresso' |
|
| 313 | - ), |
|
| 314 | - 'type' => 'string', |
|
| 315 | - 'required' => true, |
|
| 316 | - 'validation' => true, |
|
| 317 | - 'css_class' => 'large-text', |
|
| 318 | - 'format' => '%s', |
|
| 319 | - ), |
|
| 320 | - 'content' => '', |
|
| 321 | - //left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field. |
|
| 322 | - 'extra' => array( |
|
| 323 | - 'content' => array( |
|
| 324 | - 'main' => array( |
|
| 325 | - 'input' => 'wp_editor', |
|
| 326 | - 'label' => esc_html__('Main Content', 'event_espresso'), |
|
| 327 | - 'type' => 'string', |
|
| 328 | - 'required' => true, |
|
| 329 | - 'validation' => true, |
|
| 330 | - 'format' => '%s', |
|
| 331 | - 'rows' => '15', |
|
| 332 | - ), |
|
| 333 | - 'event_list' => array( |
|
| 334 | - 'input' => 'wp_editor', |
|
| 335 | - 'label' => '[EVENT_LIST]', |
|
| 336 | - 'type' => 'string', |
|
| 337 | - 'required' => true, |
|
| 338 | - 'validation' => true, |
|
| 339 | - 'format' => '%s', |
|
| 340 | - 'rows' => '15', |
|
| 341 | - 'shortcodes_required' => array('[EVENT_LIST]'), |
|
| 342 | - ), |
|
| 343 | - 'attendee_list' => array( |
|
| 344 | - 'input' => 'textarea', |
|
| 345 | - 'label' => '[ATTENDEE_LIST]', |
|
| 346 | - 'type' => 'string', |
|
| 347 | - 'required' => true, |
|
| 348 | - 'validation' => true, |
|
| 349 | - 'format' => '%s', |
|
| 350 | - 'css_class' => 'large-text', |
|
| 351 | - 'rows' => '5', |
|
| 352 | - 'shortcodes_required' => array('[ATTENDEE_LIST]'), |
|
| 353 | - ), |
|
| 354 | - 'ticket_list' => array( |
|
| 355 | - 'input' => 'textarea', |
|
| 356 | - 'label' => '[TICKET_LIST]', |
|
| 357 | - 'type' => 'string', |
|
| 358 | - 'required' => true, |
|
| 359 | - 'validation' => true, |
|
| 360 | - 'format' => '%s', |
|
| 361 | - 'css_class' => 'large-text', |
|
| 362 | - 'rows' => '10', |
|
| 363 | - 'shortcodes_required' => array('[TICKET_LIST]'), |
|
| 364 | - ), |
|
| 365 | - 'datetime_list' => array( |
|
| 366 | - 'input' => 'textarea', |
|
| 367 | - 'label' => '[DATETIME_LIST]', |
|
| 368 | - 'type' => 'string', |
|
| 369 | - 'required' => true, |
|
| 370 | - 'validation' => true, |
|
| 371 | - 'format' => '%s', |
|
| 372 | - 'css_class' => 'large-text', |
|
| 373 | - 'rows' => '10', |
|
| 374 | - 'shortcodes_required' => array('[DATETIME_LIST]'), |
|
| 375 | - ), |
|
| 376 | - ), |
|
| 377 | - ), |
|
| 378 | - ); |
|
| 379 | - } |
|
| 380 | - |
|
| 381 | - |
|
| 382 | - /** |
|
| 383 | - * See definition of this class in parent |
|
| 384 | - */ |
|
| 385 | - protected function _set_default_message_types() |
|
| 386 | - { |
|
| 387 | - $this->_default_message_types = array( |
|
| 388 | - 'payment', |
|
| 389 | - 'payment_refund', |
|
| 390 | - 'registration', |
|
| 391 | - 'not_approved_registration', |
|
| 392 | - 'pending_approval', |
|
| 393 | - ); |
|
| 394 | - } |
|
| 395 | - |
|
| 396 | - |
|
| 397 | - /** |
|
| 398 | - * @see definition of this class in parent |
|
| 399 | - * @since 4.5.0 |
|
| 400 | - */ |
|
| 401 | - protected function _set_valid_message_types() |
|
| 402 | - { |
|
| 403 | - $this->_valid_message_types = array( |
|
| 404 | - 'payment', |
|
| 405 | - 'registration', |
|
| 406 | - 'not_approved_registration', |
|
| 407 | - 'declined_registration', |
|
| 408 | - 'cancelled_registration', |
|
| 409 | - 'pending_approval', |
|
| 410 | - 'registration_summary', |
|
| 411 | - 'payment_reminder', |
|
| 412 | - 'payment_declined', |
|
| 413 | - 'payment_refund', |
|
| 414 | - ); |
|
| 415 | - } |
|
| 416 | - |
|
| 417 | - |
|
| 418 | - /** |
|
| 419 | - * setting up admin_settings_fields for messenger. |
|
| 420 | - */ |
|
| 421 | - protected function _set_admin_settings_fields() |
|
| 422 | - { |
|
| 423 | - } |
|
| 424 | - |
|
| 425 | - /** |
|
| 426 | - * We just deliver the messages don't kill us!! |
|
| 427 | - * |
|
| 428 | - * @return bool|WP_Error true if message delivered, false if it didn't deliver OR bubble up any error object if |
|
| 429 | - * present. |
|
| 430 | - * @throws EE_Error |
|
| 431 | - * @throws \TijsVerkoyen\CssToInlineStyles\Exception |
|
| 432 | - */ |
|
| 433 | - protected function _send_message() |
|
| 434 | - { |
|
| 435 | - $success = wp_mail( |
|
| 436 | - html_entity_decode($this->_to, ENT_QUOTES, "UTF-8"), |
|
| 437 | - stripslashes(html_entity_decode($this->_subject, ENT_QUOTES, "UTF-8")), |
|
| 438 | - $this->_body(), |
|
| 439 | - $this->_headers() |
|
| 440 | - ); |
|
| 441 | - if (! $success) { |
|
| 442 | - EE_Error::add_error( |
|
| 443 | - sprintf( |
|
| 444 | - esc_html__( |
|
| 445 | - 'The email did not send successfully.%3$sThe WordPress wp_mail function is used for sending mails but does not give any useful information when an email fails to send.%3$sIt is possible the "to" address (%1$s) or "from" address (%2$s) is invalid.%3$s', |
|
| 446 | - 'event_espresso' |
|
| 447 | - ), |
|
| 448 | - $this->_to, |
|
| 449 | - $this->_from, |
|
| 450 | - '<br />' |
|
| 451 | - ), |
|
| 452 | - __FILE__, |
|
| 453 | - __FUNCTION__, |
|
| 454 | - __LINE__ |
|
| 455 | - ); |
|
| 456 | - } |
|
| 457 | - return $success; |
|
| 458 | - } |
|
| 459 | - |
|
| 460 | - |
|
| 461 | - /** |
|
| 462 | - * see parent for definition |
|
| 463 | - * |
|
| 464 | - * @return string html body of the message content and the related css. |
|
| 465 | - * @throws EE_Error |
|
| 466 | - * @throws \TijsVerkoyen\CssToInlineStyles\Exception |
|
| 467 | - */ |
|
| 468 | - protected function _preview() |
|
| 469 | - { |
|
| 470 | - return $this->_body(true); |
|
| 471 | - } |
|
| 472 | - |
|
| 473 | - |
|
| 474 | - /** |
|
| 475 | - * Setup headers for email |
|
| 476 | - * |
|
| 477 | - * @access protected |
|
| 478 | - * @return string formatted header for email |
|
| 479 | - */ |
|
| 480 | - protected function _headers() |
|
| 481 | - { |
|
| 482 | - $this->_ensure_has_from_email_address(); |
|
| 483 | - $from = stripslashes_deep(html_entity_decode($this->_from, ENT_QUOTES, "UTF-8")); |
|
| 484 | - $headers = array( |
|
| 485 | - 'From:' . $from, |
|
| 486 | - 'Reply-To:' . $from, |
|
| 487 | - 'Content-Type:text/html; charset=utf-8', |
|
| 488 | - ); |
|
| 489 | - |
|
| 490 | - if (! empty($this->_cc)) { |
|
| 491 | - $headers[] = 'cc: ' . $this->_cc; |
|
| 492 | - } |
|
| 493 | - |
|
| 494 | - //but wait! Header's for the from is NOT reliable because some plugins don't respect From: as set in the |
|
| 495 | - // header. |
|
| 496 | - add_filter('wp_mail_from', array($this, 'set_from_address'), 100); |
|
| 497 | - add_filter('wp_mail_from_name', array($this, 'set_from_name'), 100); |
|
| 498 | - return apply_filters('FHEE__EE_Email_messenger___headers', $headers, $this->_incoming_message_type, $this); |
|
| 499 | - } |
|
| 500 | - |
|
| 501 | - |
|
| 502 | - /** |
|
| 503 | - * This simply ensures that the from address is not empty. If it is, then we use whatever is set as the site email |
|
| 504 | - * address for the from address to avoid problems with sending emails. |
|
| 505 | - */ |
|
| 506 | - protected function _ensure_has_from_email_address() |
|
| 507 | - { |
|
| 508 | - if (empty($this->_from)) { |
|
| 509 | - $this->_from = get_bloginfo('admin_email'); |
|
| 510 | - } |
|
| 511 | - } |
|
| 512 | - |
|
| 513 | - |
|
| 514 | - /** |
|
| 515 | - * This simply parses whatever is set as the $_from address and determines if it is in the format {name} <{email}> |
|
| 516 | - * or just {email} and returns an array with the "from_name" and "from_email" as the values. Note from_name *MAY* |
|
| 517 | - * be empty |
|
| 518 | - * |
|
| 519 | - * @since 4.3.1 |
|
| 520 | - * @return array |
|
| 521 | - */ |
|
| 522 | - private function _parse_from() |
|
| 523 | - { |
|
| 524 | - if (strpos($this->_from, '<') !== false) { |
|
| 525 | - $from_name = substr($this->_from, 0, strpos($this->_from, '<') - 1); |
|
| 526 | - $from_name = str_replace('"', '', $from_name); |
|
| 527 | - $from_name = trim($from_name); |
|
| 528 | - |
|
| 529 | - $from_email = substr($this->_from, strpos($this->_from, '<') + 1); |
|
| 530 | - $from_email = str_replace('>', '', $from_email); |
|
| 531 | - $from_email = trim($from_email); |
|
| 532 | - } elseif (trim($this->_from) !== '') { |
|
| 533 | - $from_name = ''; |
|
| 534 | - $from_email = trim($this->_from); |
|
| 535 | - } else { |
|
| 536 | - $from_name = $from_email = ''; |
|
| 537 | - } |
|
| 538 | - return array($from_name, $from_email); |
|
| 539 | - } |
|
| 540 | - |
|
| 541 | - |
|
| 542 | - /** |
|
| 543 | - * Callback for the wp_mail_from filter. |
|
| 544 | - * |
|
| 545 | - * @since 4.3.1 |
|
| 546 | - * @param string $from_email What the original from_email is. |
|
| 547 | - * @return string |
|
| 548 | - */ |
|
| 549 | - public function set_from_address($from_email) |
|
| 550 | - { |
|
| 551 | - $parsed_from = $this->_parse_from(); |
|
| 552 | - //includes fallback if the parsing failed. |
|
| 553 | - $from_email = is_array($parsed_from) && ! empty($parsed_from[1]) |
|
| 554 | - ? $parsed_from[1] |
|
| 555 | - : get_bloginfo('admin_email'); |
|
| 556 | - return $from_email; |
|
| 557 | - } |
|
| 558 | - |
|
| 559 | - |
|
| 560 | - /** |
|
| 561 | - * Callback fro the wp_mail_from_name filter. |
|
| 562 | - * |
|
| 563 | - * @since 4.3.1 |
|
| 564 | - * @param string $from_name The original from_name. |
|
| 565 | - * @return string |
|
| 566 | - */ |
|
| 567 | - public function set_from_name($from_name) |
|
| 568 | - { |
|
| 569 | - $parsed_from = $this->_parse_from(); |
|
| 570 | - if (is_array($parsed_from) && ! empty($parsed_from[0])) { |
|
| 571 | - $from_name = $parsed_from[0]; |
|
| 572 | - } |
|
| 573 | - |
|
| 574 | - //if from name is "WordPress" let's sub in the site name instead (more friendly!) |
|
| 575 | - $from_name = $from_name == 'WordPress' ? get_bloginfo() : $from_name; |
|
| 576 | - |
|
| 577 | - return stripslashes_deep(html_entity_decode($from_name, ENT_QUOTES, "UTF-8")); |
|
| 578 | - } |
|
| 579 | - |
|
| 580 | - |
|
| 581 | - /** |
|
| 582 | - * setup body for email |
|
| 583 | - * |
|
| 584 | - * @param bool $preview will determine whether this is preview template or not. |
|
| 585 | - * @return string formatted body for email. |
|
| 586 | - * @throws EE_Error |
|
| 587 | - * @throws \TijsVerkoyen\CssToInlineStyles\Exception |
|
| 588 | - */ |
|
| 589 | - protected function _body($preview = false) |
|
| 590 | - { |
|
| 591 | - //setup template args! |
|
| 592 | - $this->_template_args = array( |
|
| 593 | - 'subject' => $this->_subject, |
|
| 594 | - 'from' => $this->_from, |
|
| 595 | - 'main_body' => wpautop( |
|
| 596 | - stripslashes_deep( |
|
| 597 | - html_entity_decode($this->_content, ENT_QUOTES, "UTF-8") |
|
| 598 | - ) |
|
| 599 | - ), |
|
| 600 | - ); |
|
| 601 | - $body = $this->_get_main_template($preview); |
|
| 602 | - |
|
| 603 | - /** |
|
| 604 | - * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched. |
|
| 605 | - * |
|
| 606 | - * @type bool $preview Indicates whether a preview is being generated or not. |
|
| 607 | - * @return bool true indicates to use the inliner, false bypasses it. |
|
| 608 | - */ |
|
| 609 | - if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) { |
|
| 610 | - //require CssToInlineStyles library and its dependencies via composer autoloader |
|
| 611 | - require_once EE_THIRD_PARTY . 'cssinliner/vendor/autoload.php'; |
|
| 612 | - |
|
| 613 | - //now if this isn't a preview, let's setup the body so it has inline styles |
|
| 614 | - if (! $preview || ($preview && defined('DOING_AJAX'))) { |
|
| 615 | - $style = file_get_contents( |
|
| 616 | - $this->get_variation( |
|
| 617 | - $this->_tmp_pack, |
|
| 618 | - $this->_incoming_message_type->name, |
|
| 619 | - false, |
|
| 620 | - 'main', |
|
| 621 | - $this->_variation |
|
| 622 | - ), |
|
| 623 | - true |
|
| 624 | - ); |
|
| 625 | - $CSS = new TijsVerkoyen\CssToInlineStyles\CssToInlineStyles($body, $style); |
|
| 626 | - //for some reason the library has a bracket and new line at the beginning. This takes care of that. |
|
| 627 | - $body = ltrim($CSS->convert(true), ">\n"); |
|
| 628 | - //see https://events.codebasehq.com/projects/event-espresso/tickets/8609 |
|
| 629 | - $body = ltrim($body, "<?"); |
|
| 630 | - } |
|
| 631 | - |
|
| 632 | - } |
|
| 633 | - return $body; |
|
| 634 | - } |
|
| 635 | - |
|
| 636 | - |
|
| 637 | - /** |
|
| 638 | - * This just returns any existing test settings that might be saved in the database |
|
| 639 | - * |
|
| 640 | - * @access public |
|
| 641 | - * @return array |
|
| 642 | - */ |
|
| 643 | - public function get_existing_test_settings() |
|
| 644 | - { |
|
| 645 | - $settings = parent::get_existing_test_settings(); |
|
| 646 | - //override subject if present because we always want it to be fresh. |
|
| 647 | - if (is_array($settings) && ! empty($settings['subject'])) { |
|
| 648 | - $settings['subject'] = sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')); |
|
| 649 | - } |
|
| 650 | - return $settings; |
|
| 651 | - } |
|
| 11 | + /** |
|
| 12 | + * To field for email |
|
| 13 | + * @var string |
|
| 14 | + */ |
|
| 15 | + protected $_to = ''; |
|
| 16 | + |
|
| 17 | + |
|
| 18 | + /** |
|
| 19 | + * CC field for email. |
|
| 20 | + * @var string |
|
| 21 | + */ |
|
| 22 | + protected $_cc = ''; |
|
| 23 | + |
|
| 24 | + /** |
|
| 25 | + * From field for email |
|
| 26 | + * @var string |
|
| 27 | + */ |
|
| 28 | + protected $_from = ''; |
|
| 29 | + |
|
| 30 | + |
|
| 31 | + /** |
|
| 32 | + * Subject field for email |
|
| 33 | + * @var string |
|
| 34 | + */ |
|
| 35 | + protected $_subject = ''; |
|
| 36 | + |
|
| 37 | + |
|
| 38 | + /** |
|
| 39 | + * Content field for email |
|
| 40 | + * @var string |
|
| 41 | + */ |
|
| 42 | + protected $_content = ''; |
|
| 43 | + |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * constructor |
|
| 47 | + * |
|
| 48 | + * @access public |
|
| 49 | + */ |
|
| 50 | + public function __construct() |
|
| 51 | + { |
|
| 52 | + //set name and description properties |
|
| 53 | + $this->name = 'email'; |
|
| 54 | + $this->description = sprintf( |
|
| 55 | + esc_html__( |
|
| 56 | + 'This messenger delivers messages via email using the built-in %s function included with WordPress', |
|
| 57 | + 'event_espresso' |
|
| 58 | + ), |
|
| 59 | + '<code>wp_mail</code>' |
|
| 60 | + ); |
|
| 61 | + $this->label = array( |
|
| 62 | + 'singular' => esc_html__('email', 'event_espresso'), |
|
| 63 | + 'plural' => esc_html__('emails', 'event_espresso'), |
|
| 64 | + ); |
|
| 65 | + $this->activate_on_install = true; |
|
| 66 | + |
|
| 67 | + //we're using defaults so let's call parent constructor that will take care of setting up all the other |
|
| 68 | + // properties |
|
| 69 | + parent::__construct(); |
|
| 70 | + } |
|
| 71 | + |
|
| 72 | + |
|
| 73 | + /** |
|
| 74 | + * see abstract declaration in parent class for details. |
|
| 75 | + */ |
|
| 76 | + protected function _set_admin_pages() |
|
| 77 | + { |
|
| 78 | + $this->admin_registered_pages = array( |
|
| 79 | + 'events_edit' => true, |
|
| 80 | + ); |
|
| 81 | + } |
|
| 82 | + |
|
| 83 | + |
|
| 84 | + /** |
|
| 85 | + * see abstract declaration in parent class for details |
|
| 86 | + */ |
|
| 87 | + protected function _set_valid_shortcodes() |
|
| 88 | + { |
|
| 89 | + //remember by leaving the other fields not set, those fields will inherit the valid shortcodes from the |
|
| 90 | + // message type. |
|
| 91 | + $this->_valid_shortcodes = array( |
|
| 92 | + 'to' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'), |
|
| 93 | + 'cc' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'), |
|
| 94 | + 'from' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'), |
|
| 95 | + ); |
|
| 96 | + } |
|
| 97 | + |
|
| 98 | + |
|
| 99 | + /** |
|
| 100 | + * see abstract declaration in parent class for details |
|
| 101 | + * |
|
| 102 | + * @access protected |
|
| 103 | + * @return void |
|
| 104 | + */ |
|
| 105 | + protected function _set_validator_config() |
|
| 106 | + { |
|
| 107 | + $valid_shortcodes = $this->get_valid_shortcodes(); |
|
| 108 | + |
|
| 109 | + $this->_validator_config = array( |
|
| 110 | + 'to' => array( |
|
| 111 | + 'shortcodes' => $valid_shortcodes['to'], |
|
| 112 | + 'type' => 'email', |
|
| 113 | + ), |
|
| 114 | + 'cc' => array( |
|
| 115 | + 'shortcodes' => $valid_shortcodes['to'], |
|
| 116 | + 'type' => 'email', |
|
| 117 | + ), |
|
| 118 | + 'from' => array( |
|
| 119 | + 'shortcodes' => $valid_shortcodes['from'], |
|
| 120 | + 'type' => 'email', |
|
| 121 | + ), |
|
| 122 | + 'subject' => array( |
|
| 123 | + 'shortcodes' => array( |
|
| 124 | + 'organization', |
|
| 125 | + 'primary_registration_details', |
|
| 126 | + 'event_author', |
|
| 127 | + 'primary_registration_details', |
|
| 128 | + 'recipient_details', |
|
| 129 | + ), |
|
| 130 | + ), |
|
| 131 | + 'content' => array( |
|
| 132 | + 'shortcodes' => array( |
|
| 133 | + 'event_list', |
|
| 134 | + 'attendee_list', |
|
| 135 | + 'ticket_list', |
|
| 136 | + 'organization', |
|
| 137 | + 'primary_registration_details', |
|
| 138 | + 'primary_registration_list', |
|
| 139 | + 'event_author', |
|
| 140 | + 'recipient_details', |
|
| 141 | + 'recipient_list', |
|
| 142 | + 'transaction', |
|
| 143 | + 'messenger', |
|
| 144 | + ), |
|
| 145 | + ), |
|
| 146 | + 'attendee_list' => array( |
|
| 147 | + 'shortcodes' => array('attendee', 'event_list', 'ticket_list'), |
|
| 148 | + 'required' => array('[ATTENDEE_LIST]'), |
|
| 149 | + ), |
|
| 150 | + 'event_list' => array( |
|
| 151 | + 'shortcodes' => array( |
|
| 152 | + 'event', |
|
| 153 | + 'attendee_list', |
|
| 154 | + 'ticket_list', |
|
| 155 | + 'venue', |
|
| 156 | + 'datetime_list', |
|
| 157 | + 'attendee', |
|
| 158 | + 'primary_registration_details', |
|
| 159 | + 'primary_registration_list', |
|
| 160 | + 'event_author', |
|
| 161 | + 'recipient_details', |
|
| 162 | + 'recipient_list', |
|
| 163 | + ), |
|
| 164 | + 'required' => array('[EVENT_LIST]'), |
|
| 165 | + ), |
|
| 166 | + 'ticket_list' => array( |
|
| 167 | + 'shortcodes' => array( |
|
| 168 | + 'event_list', |
|
| 169 | + 'attendee_list', |
|
| 170 | + 'ticket', |
|
| 171 | + 'datetime_list', |
|
| 172 | + 'primary_registration_details', |
|
| 173 | + 'recipient_details', |
|
| 174 | + ), |
|
| 175 | + 'required' => array('[TICKET_LIST]'), |
|
| 176 | + ), |
|
| 177 | + 'datetime_list' => array( |
|
| 178 | + 'shortcodes' => array('datetime'), |
|
| 179 | + 'required' => array('[DATETIME_LIST]'), |
|
| 180 | + ), |
|
| 181 | + ); |
|
| 182 | + } |
|
| 183 | + |
|
| 184 | + |
|
| 185 | + /** |
|
| 186 | + * @see parent EE_messenger class for docs |
|
| 187 | + * @since 4.5.0 |
|
| 188 | + */ |
|
| 189 | + public function do_secondary_messenger_hooks($sending_messenger_name) |
|
| 190 | + { |
|
| 191 | + if ($sending_messenger_name = 'html') { |
|
| 192 | + add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8); |
|
| 193 | + } |
|
| 194 | + } |
|
| 195 | + |
|
| 196 | + |
|
| 197 | + public function add_email_css( |
|
| 198 | + $variation_path, |
|
| 199 | + $messenger, |
|
| 200 | + $message_type, |
|
| 201 | + $type, |
|
| 202 | + $variation, |
|
| 203 | + $file_extension, |
|
| 204 | + $url, |
|
| 205 | + EE_Messages_Template_Pack $template_pack |
|
| 206 | + ) { |
|
| 207 | + //prevent recursion on this callback. |
|
| 208 | + remove_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10); |
|
| 209 | + $variation = $this->get_variation($template_pack, $message_type, $url, 'main', $variation, false); |
|
| 210 | + |
|
| 211 | + add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8); |
|
| 212 | + return $variation; |
|
| 213 | + } |
|
| 214 | + |
|
| 215 | + |
|
| 216 | + /** |
|
| 217 | + * See parent for details |
|
| 218 | + * |
|
| 219 | + * @access protected |
|
| 220 | + * @return void |
|
| 221 | + */ |
|
| 222 | + protected function _set_test_settings_fields() |
|
| 223 | + { |
|
| 224 | + $this->_test_settings_fields = array( |
|
| 225 | + 'to' => array( |
|
| 226 | + 'input' => 'text', |
|
| 227 | + 'label' => esc_html__('Send a test email to', 'event_espresso'), |
|
| 228 | + 'type' => 'email', |
|
| 229 | + 'required' => true, |
|
| 230 | + 'validation' => true, |
|
| 231 | + 'css_class' => 'large-text', |
|
| 232 | + 'format' => '%s', |
|
| 233 | + 'default' => get_bloginfo('admin_email'), |
|
| 234 | + ), |
|
| 235 | + 'subject' => array( |
|
| 236 | + 'input' => 'hidden', |
|
| 237 | + 'label' => '', |
|
| 238 | + 'type' => 'string', |
|
| 239 | + 'required' => false, |
|
| 240 | + 'validation' => false, |
|
| 241 | + 'format' => '%s', |
|
| 242 | + 'value' => sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')), |
|
| 243 | + 'default' => '', |
|
| 244 | + 'css_class' => '', |
|
| 245 | + ), |
|
| 246 | + ); |
|
| 247 | + } |
|
| 248 | + |
|
| 249 | + |
|
| 250 | + /** |
|
| 251 | + * _set_template_fields |
|
| 252 | + * This sets up the fields that a messenger requires for the message to go out. |
|
| 253 | + * |
|
| 254 | + * @access protected |
|
| 255 | + * @return void |
|
| 256 | + */ |
|
| 257 | + protected function _set_template_fields() |
|
| 258 | + { |
|
| 259 | + // any extra template fields that are NOT used by the messenger but will get used by a messenger field for |
|
| 260 | + // shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field |
|
| 261 | + // they relate to. This is important for the Messages_admin to know what fields to display to the user. |
|
| 262 | + // Also, notice that the "values" are equal to the field type that messages admin will use to know what |
|
| 263 | + // kind of field to display. The values ALSO have one index labeled "shortcode". the values in that array |
|
| 264 | + // indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be |
|
| 265 | + // displayed. If the required shortcode isn't part of the shortcodes array then the field is not needed and |
|
| 266 | + // will not be displayed/parsed. |
|
| 267 | + $this->_template_fields = array( |
|
| 268 | + 'to' => array( |
|
| 269 | + 'input' => 'text', |
|
| 270 | + 'label' => esc_html_x( |
|
| 271 | + 'To', |
|
| 272 | + 'Label for the "To" field for email addresses', |
|
| 273 | + 'event_espresso' |
|
| 274 | + ), |
|
| 275 | + 'type' => 'string', |
|
| 276 | + 'required' => true, |
|
| 277 | + 'validation' => true, |
|
| 278 | + 'css_class' => 'large-text', |
|
| 279 | + 'format' => '%s', |
|
| 280 | + ), |
|
| 281 | + 'cc' => array( |
|
| 282 | + 'input' => 'text', |
|
| 283 | + 'label' => esc_html_x( |
|
| 284 | + 'CC', |
|
| 285 | + 'Label for the "Carbon Copy" field used for additional email addresses', |
|
| 286 | + 'event_espresso' |
|
| 287 | + ), |
|
| 288 | + 'type' => 'string', |
|
| 289 | + 'required' => false, |
|
| 290 | + 'validation' => true, |
|
| 291 | + 'css_class' => 'large-text', |
|
| 292 | + 'format' => '%s', |
|
| 293 | + ), |
|
| 294 | + 'from' => array( |
|
| 295 | + 'input' => 'text', |
|
| 296 | + 'label' => esc_html_x( |
|
| 297 | + 'From', |
|
| 298 | + 'Label for the "From" field for email addresses.', |
|
| 299 | + 'event_espresso' |
|
| 300 | + ), |
|
| 301 | + 'type' => 'string', |
|
| 302 | + 'required' => true, |
|
| 303 | + 'validation' => true, |
|
| 304 | + 'css_class' => 'large-text', |
|
| 305 | + 'format' => '%s', |
|
| 306 | + ), |
|
| 307 | + 'subject' => array( |
|
| 308 | + 'input' => 'text', |
|
| 309 | + 'label' => esc_html_x( |
|
| 310 | + 'Subject', |
|
| 311 | + 'Label for the "Subject" field (short description of contents) for emails.', |
|
| 312 | + 'event_espresso' |
|
| 313 | + ), |
|
| 314 | + 'type' => 'string', |
|
| 315 | + 'required' => true, |
|
| 316 | + 'validation' => true, |
|
| 317 | + 'css_class' => 'large-text', |
|
| 318 | + 'format' => '%s', |
|
| 319 | + ), |
|
| 320 | + 'content' => '', |
|
| 321 | + //left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field. |
|
| 322 | + 'extra' => array( |
|
| 323 | + 'content' => array( |
|
| 324 | + 'main' => array( |
|
| 325 | + 'input' => 'wp_editor', |
|
| 326 | + 'label' => esc_html__('Main Content', 'event_espresso'), |
|
| 327 | + 'type' => 'string', |
|
| 328 | + 'required' => true, |
|
| 329 | + 'validation' => true, |
|
| 330 | + 'format' => '%s', |
|
| 331 | + 'rows' => '15', |
|
| 332 | + ), |
|
| 333 | + 'event_list' => array( |
|
| 334 | + 'input' => 'wp_editor', |
|
| 335 | + 'label' => '[EVENT_LIST]', |
|
| 336 | + 'type' => 'string', |
|
| 337 | + 'required' => true, |
|
| 338 | + 'validation' => true, |
|
| 339 | + 'format' => '%s', |
|
| 340 | + 'rows' => '15', |
|
| 341 | + 'shortcodes_required' => array('[EVENT_LIST]'), |
|
| 342 | + ), |
|
| 343 | + 'attendee_list' => array( |
|
| 344 | + 'input' => 'textarea', |
|
| 345 | + 'label' => '[ATTENDEE_LIST]', |
|
| 346 | + 'type' => 'string', |
|
| 347 | + 'required' => true, |
|
| 348 | + 'validation' => true, |
|
| 349 | + 'format' => '%s', |
|
| 350 | + 'css_class' => 'large-text', |
|
| 351 | + 'rows' => '5', |
|
| 352 | + 'shortcodes_required' => array('[ATTENDEE_LIST]'), |
|
| 353 | + ), |
|
| 354 | + 'ticket_list' => array( |
|
| 355 | + 'input' => 'textarea', |
|
| 356 | + 'label' => '[TICKET_LIST]', |
|
| 357 | + 'type' => 'string', |
|
| 358 | + 'required' => true, |
|
| 359 | + 'validation' => true, |
|
| 360 | + 'format' => '%s', |
|
| 361 | + 'css_class' => 'large-text', |
|
| 362 | + 'rows' => '10', |
|
| 363 | + 'shortcodes_required' => array('[TICKET_LIST]'), |
|
| 364 | + ), |
|
| 365 | + 'datetime_list' => array( |
|
| 366 | + 'input' => 'textarea', |
|
| 367 | + 'label' => '[DATETIME_LIST]', |
|
| 368 | + 'type' => 'string', |
|
| 369 | + 'required' => true, |
|
| 370 | + 'validation' => true, |
|
| 371 | + 'format' => '%s', |
|
| 372 | + 'css_class' => 'large-text', |
|
| 373 | + 'rows' => '10', |
|
| 374 | + 'shortcodes_required' => array('[DATETIME_LIST]'), |
|
| 375 | + ), |
|
| 376 | + ), |
|
| 377 | + ), |
|
| 378 | + ); |
|
| 379 | + } |
|
| 380 | + |
|
| 381 | + |
|
| 382 | + /** |
|
| 383 | + * See definition of this class in parent |
|
| 384 | + */ |
|
| 385 | + protected function _set_default_message_types() |
|
| 386 | + { |
|
| 387 | + $this->_default_message_types = array( |
|
| 388 | + 'payment', |
|
| 389 | + 'payment_refund', |
|
| 390 | + 'registration', |
|
| 391 | + 'not_approved_registration', |
|
| 392 | + 'pending_approval', |
|
| 393 | + ); |
|
| 394 | + } |
|
| 395 | + |
|
| 396 | + |
|
| 397 | + /** |
|
| 398 | + * @see definition of this class in parent |
|
| 399 | + * @since 4.5.0 |
|
| 400 | + */ |
|
| 401 | + protected function _set_valid_message_types() |
|
| 402 | + { |
|
| 403 | + $this->_valid_message_types = array( |
|
| 404 | + 'payment', |
|
| 405 | + 'registration', |
|
| 406 | + 'not_approved_registration', |
|
| 407 | + 'declined_registration', |
|
| 408 | + 'cancelled_registration', |
|
| 409 | + 'pending_approval', |
|
| 410 | + 'registration_summary', |
|
| 411 | + 'payment_reminder', |
|
| 412 | + 'payment_declined', |
|
| 413 | + 'payment_refund', |
|
| 414 | + ); |
|
| 415 | + } |
|
| 416 | + |
|
| 417 | + |
|
| 418 | + /** |
|
| 419 | + * setting up admin_settings_fields for messenger. |
|
| 420 | + */ |
|
| 421 | + protected function _set_admin_settings_fields() |
|
| 422 | + { |
|
| 423 | + } |
|
| 424 | + |
|
| 425 | + /** |
|
| 426 | + * We just deliver the messages don't kill us!! |
|
| 427 | + * |
|
| 428 | + * @return bool|WP_Error true if message delivered, false if it didn't deliver OR bubble up any error object if |
|
| 429 | + * present. |
|
| 430 | + * @throws EE_Error |
|
| 431 | + * @throws \TijsVerkoyen\CssToInlineStyles\Exception |
|
| 432 | + */ |
|
| 433 | + protected function _send_message() |
|
| 434 | + { |
|
| 435 | + $success = wp_mail( |
|
| 436 | + html_entity_decode($this->_to, ENT_QUOTES, "UTF-8"), |
|
| 437 | + stripslashes(html_entity_decode($this->_subject, ENT_QUOTES, "UTF-8")), |
|
| 438 | + $this->_body(), |
|
| 439 | + $this->_headers() |
|
| 440 | + ); |
|
| 441 | + if (! $success) { |
|
| 442 | + EE_Error::add_error( |
|
| 443 | + sprintf( |
|
| 444 | + esc_html__( |
|
| 445 | + 'The email did not send successfully.%3$sThe WordPress wp_mail function is used for sending mails but does not give any useful information when an email fails to send.%3$sIt is possible the "to" address (%1$s) or "from" address (%2$s) is invalid.%3$s', |
|
| 446 | + 'event_espresso' |
|
| 447 | + ), |
|
| 448 | + $this->_to, |
|
| 449 | + $this->_from, |
|
| 450 | + '<br />' |
|
| 451 | + ), |
|
| 452 | + __FILE__, |
|
| 453 | + __FUNCTION__, |
|
| 454 | + __LINE__ |
|
| 455 | + ); |
|
| 456 | + } |
|
| 457 | + return $success; |
|
| 458 | + } |
|
| 459 | + |
|
| 460 | + |
|
| 461 | + /** |
|
| 462 | + * see parent for definition |
|
| 463 | + * |
|
| 464 | + * @return string html body of the message content and the related css. |
|
| 465 | + * @throws EE_Error |
|
| 466 | + * @throws \TijsVerkoyen\CssToInlineStyles\Exception |
|
| 467 | + */ |
|
| 468 | + protected function _preview() |
|
| 469 | + { |
|
| 470 | + return $this->_body(true); |
|
| 471 | + } |
|
| 472 | + |
|
| 473 | + |
|
| 474 | + /** |
|
| 475 | + * Setup headers for email |
|
| 476 | + * |
|
| 477 | + * @access protected |
|
| 478 | + * @return string formatted header for email |
|
| 479 | + */ |
|
| 480 | + protected function _headers() |
|
| 481 | + { |
|
| 482 | + $this->_ensure_has_from_email_address(); |
|
| 483 | + $from = stripslashes_deep(html_entity_decode($this->_from, ENT_QUOTES, "UTF-8")); |
|
| 484 | + $headers = array( |
|
| 485 | + 'From:' . $from, |
|
| 486 | + 'Reply-To:' . $from, |
|
| 487 | + 'Content-Type:text/html; charset=utf-8', |
|
| 488 | + ); |
|
| 489 | + |
|
| 490 | + if (! empty($this->_cc)) { |
|
| 491 | + $headers[] = 'cc: ' . $this->_cc; |
|
| 492 | + } |
|
| 493 | + |
|
| 494 | + //but wait! Header's for the from is NOT reliable because some plugins don't respect From: as set in the |
|
| 495 | + // header. |
|
| 496 | + add_filter('wp_mail_from', array($this, 'set_from_address'), 100); |
|
| 497 | + add_filter('wp_mail_from_name', array($this, 'set_from_name'), 100); |
|
| 498 | + return apply_filters('FHEE__EE_Email_messenger___headers', $headers, $this->_incoming_message_type, $this); |
|
| 499 | + } |
|
| 500 | + |
|
| 501 | + |
|
| 502 | + /** |
|
| 503 | + * This simply ensures that the from address is not empty. If it is, then we use whatever is set as the site email |
|
| 504 | + * address for the from address to avoid problems with sending emails. |
|
| 505 | + */ |
|
| 506 | + protected function _ensure_has_from_email_address() |
|
| 507 | + { |
|
| 508 | + if (empty($this->_from)) { |
|
| 509 | + $this->_from = get_bloginfo('admin_email'); |
|
| 510 | + } |
|
| 511 | + } |
|
| 512 | + |
|
| 513 | + |
|
| 514 | + /** |
|
| 515 | + * This simply parses whatever is set as the $_from address and determines if it is in the format {name} <{email}> |
|
| 516 | + * or just {email} and returns an array with the "from_name" and "from_email" as the values. Note from_name *MAY* |
|
| 517 | + * be empty |
|
| 518 | + * |
|
| 519 | + * @since 4.3.1 |
|
| 520 | + * @return array |
|
| 521 | + */ |
|
| 522 | + private function _parse_from() |
|
| 523 | + { |
|
| 524 | + if (strpos($this->_from, '<') !== false) { |
|
| 525 | + $from_name = substr($this->_from, 0, strpos($this->_from, '<') - 1); |
|
| 526 | + $from_name = str_replace('"', '', $from_name); |
|
| 527 | + $from_name = trim($from_name); |
|
| 528 | + |
|
| 529 | + $from_email = substr($this->_from, strpos($this->_from, '<') + 1); |
|
| 530 | + $from_email = str_replace('>', '', $from_email); |
|
| 531 | + $from_email = trim($from_email); |
|
| 532 | + } elseif (trim($this->_from) !== '') { |
|
| 533 | + $from_name = ''; |
|
| 534 | + $from_email = trim($this->_from); |
|
| 535 | + } else { |
|
| 536 | + $from_name = $from_email = ''; |
|
| 537 | + } |
|
| 538 | + return array($from_name, $from_email); |
|
| 539 | + } |
|
| 540 | + |
|
| 541 | + |
|
| 542 | + /** |
|
| 543 | + * Callback for the wp_mail_from filter. |
|
| 544 | + * |
|
| 545 | + * @since 4.3.1 |
|
| 546 | + * @param string $from_email What the original from_email is. |
|
| 547 | + * @return string |
|
| 548 | + */ |
|
| 549 | + public function set_from_address($from_email) |
|
| 550 | + { |
|
| 551 | + $parsed_from = $this->_parse_from(); |
|
| 552 | + //includes fallback if the parsing failed. |
|
| 553 | + $from_email = is_array($parsed_from) && ! empty($parsed_from[1]) |
|
| 554 | + ? $parsed_from[1] |
|
| 555 | + : get_bloginfo('admin_email'); |
|
| 556 | + return $from_email; |
|
| 557 | + } |
|
| 558 | + |
|
| 559 | + |
|
| 560 | + /** |
|
| 561 | + * Callback fro the wp_mail_from_name filter. |
|
| 562 | + * |
|
| 563 | + * @since 4.3.1 |
|
| 564 | + * @param string $from_name The original from_name. |
|
| 565 | + * @return string |
|
| 566 | + */ |
|
| 567 | + public function set_from_name($from_name) |
|
| 568 | + { |
|
| 569 | + $parsed_from = $this->_parse_from(); |
|
| 570 | + if (is_array($parsed_from) && ! empty($parsed_from[0])) { |
|
| 571 | + $from_name = $parsed_from[0]; |
|
| 572 | + } |
|
| 573 | + |
|
| 574 | + //if from name is "WordPress" let's sub in the site name instead (more friendly!) |
|
| 575 | + $from_name = $from_name == 'WordPress' ? get_bloginfo() : $from_name; |
|
| 576 | + |
|
| 577 | + return stripslashes_deep(html_entity_decode($from_name, ENT_QUOTES, "UTF-8")); |
|
| 578 | + } |
|
| 579 | + |
|
| 580 | + |
|
| 581 | + /** |
|
| 582 | + * setup body for email |
|
| 583 | + * |
|
| 584 | + * @param bool $preview will determine whether this is preview template or not. |
|
| 585 | + * @return string formatted body for email. |
|
| 586 | + * @throws EE_Error |
|
| 587 | + * @throws \TijsVerkoyen\CssToInlineStyles\Exception |
|
| 588 | + */ |
|
| 589 | + protected function _body($preview = false) |
|
| 590 | + { |
|
| 591 | + //setup template args! |
|
| 592 | + $this->_template_args = array( |
|
| 593 | + 'subject' => $this->_subject, |
|
| 594 | + 'from' => $this->_from, |
|
| 595 | + 'main_body' => wpautop( |
|
| 596 | + stripslashes_deep( |
|
| 597 | + html_entity_decode($this->_content, ENT_QUOTES, "UTF-8") |
|
| 598 | + ) |
|
| 599 | + ), |
|
| 600 | + ); |
|
| 601 | + $body = $this->_get_main_template($preview); |
|
| 602 | + |
|
| 603 | + /** |
|
| 604 | + * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched. |
|
| 605 | + * |
|
| 606 | + * @type bool $preview Indicates whether a preview is being generated or not. |
|
| 607 | + * @return bool true indicates to use the inliner, false bypasses it. |
|
| 608 | + */ |
|
| 609 | + if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) { |
|
| 610 | + //require CssToInlineStyles library and its dependencies via composer autoloader |
|
| 611 | + require_once EE_THIRD_PARTY . 'cssinliner/vendor/autoload.php'; |
|
| 612 | + |
|
| 613 | + //now if this isn't a preview, let's setup the body so it has inline styles |
|
| 614 | + if (! $preview || ($preview && defined('DOING_AJAX'))) { |
|
| 615 | + $style = file_get_contents( |
|
| 616 | + $this->get_variation( |
|
| 617 | + $this->_tmp_pack, |
|
| 618 | + $this->_incoming_message_type->name, |
|
| 619 | + false, |
|
| 620 | + 'main', |
|
| 621 | + $this->_variation |
|
| 622 | + ), |
|
| 623 | + true |
|
| 624 | + ); |
|
| 625 | + $CSS = new TijsVerkoyen\CssToInlineStyles\CssToInlineStyles($body, $style); |
|
| 626 | + //for some reason the library has a bracket and new line at the beginning. This takes care of that. |
|
| 627 | + $body = ltrim($CSS->convert(true), ">\n"); |
|
| 628 | + //see https://events.codebasehq.com/projects/event-espresso/tickets/8609 |
|
| 629 | + $body = ltrim($body, "<?"); |
|
| 630 | + } |
|
| 631 | + |
|
| 632 | + } |
|
| 633 | + return $body; |
|
| 634 | + } |
|
| 635 | + |
|
| 636 | + |
|
| 637 | + /** |
|
| 638 | + * This just returns any existing test settings that might be saved in the database |
|
| 639 | + * |
|
| 640 | + * @access public |
|
| 641 | + * @return array |
|
| 642 | + */ |
|
| 643 | + public function get_existing_test_settings() |
|
| 644 | + { |
|
| 645 | + $settings = parent::get_existing_test_settings(); |
|
| 646 | + //override subject if present because we always want it to be fresh. |
|
| 647 | + if (is_array($settings) && ! empty($settings['subject'])) { |
|
| 648 | + $settings['subject'] = sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')); |
|
| 649 | + } |
|
| 650 | + return $settings; |
|
| 651 | + } |
|
| 652 | 652 | } |
@@ -58,7 +58,7 @@ discard block |
||
| 58 | 58 | ), |
| 59 | 59 | '<code>wp_mail</code>' |
| 60 | 60 | ); |
| 61 | - $this->label = array( |
|
| 61 | + $this->label = array( |
|
| 62 | 62 | 'singular' => esc_html__('email', 'event_espresso'), |
| 63 | 63 | 'plural' => esc_html__('emails', 'event_espresso'), |
| 64 | 64 | ); |
@@ -438,7 +438,7 @@ discard block |
||
| 438 | 438 | $this->_body(), |
| 439 | 439 | $this->_headers() |
| 440 | 440 | ); |
| 441 | - if (! $success) { |
|
| 441 | + if ( ! $success) { |
|
| 442 | 442 | EE_Error::add_error( |
| 443 | 443 | sprintf( |
| 444 | 444 | esc_html__( |
@@ -482,13 +482,13 @@ discard block |
||
| 482 | 482 | $this->_ensure_has_from_email_address(); |
| 483 | 483 | $from = stripslashes_deep(html_entity_decode($this->_from, ENT_QUOTES, "UTF-8")); |
| 484 | 484 | $headers = array( |
| 485 | - 'From:' . $from, |
|
| 486 | - 'Reply-To:' . $from, |
|
| 485 | + 'From:'.$from, |
|
| 486 | + 'Reply-To:'.$from, |
|
| 487 | 487 | 'Content-Type:text/html; charset=utf-8', |
| 488 | 488 | ); |
| 489 | 489 | |
| 490 | - if (! empty($this->_cc)) { |
|
| 491 | - $headers[] = 'cc: ' . $this->_cc; |
|
| 490 | + if ( ! empty($this->_cc)) { |
|
| 491 | + $headers[] = 'cc: '.$this->_cc; |
|
| 492 | 492 | } |
| 493 | 493 | |
| 494 | 494 | //but wait! Header's for the from is NOT reliable because some plugins don't respect From: as set in the |
@@ -598,7 +598,7 @@ discard block |
||
| 598 | 598 | ) |
| 599 | 599 | ), |
| 600 | 600 | ); |
| 601 | - $body = $this->_get_main_template($preview); |
|
| 601 | + $body = $this->_get_main_template($preview); |
|
| 602 | 602 | |
| 603 | 603 | /** |
| 604 | 604 | * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched. |
@@ -608,10 +608,10 @@ discard block |
||
| 608 | 608 | */ |
| 609 | 609 | if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) { |
| 610 | 610 | //require CssToInlineStyles library and its dependencies via composer autoloader |
| 611 | - require_once EE_THIRD_PARTY . 'cssinliner/vendor/autoload.php'; |
|
| 611 | + require_once EE_THIRD_PARTY.'cssinliner/vendor/autoload.php'; |
|
| 612 | 612 | |
| 613 | 613 | //now if this isn't a preview, let's setup the body so it has inline styles |
| 614 | - if (! $preview || ($preview && defined('DOING_AJAX'))) { |
|
| 614 | + if ( ! $preview || ($preview && defined('DOING_AJAX'))) { |
|
| 615 | 615 | $style = file_get_contents( |
| 616 | 616 | $this->get_variation( |
| 617 | 617 | $this->_tmp_pack, |
@@ -8,7 +8,7 @@ discard block |
||
| 8 | 8 | use ReflectionMethod; |
| 9 | 9 | |
| 10 | 10 | if (! defined('EVENT_ESPRESSO_VERSION')) { |
| 11 | - exit('No direct script access allowed'); |
|
| 11 | + exit('No direct script access allowed'); |
|
| 12 | 12 | } |
| 13 | 13 | |
| 14 | 14 | |
@@ -26,53 +26,53 @@ discard block |
||
| 26 | 26 | |
| 27 | 27 | |
| 28 | 28 | |
| 29 | - /** |
|
| 30 | - * @param Exception $exception |
|
| 31 | - * @throws Exception |
|
| 32 | - */ |
|
| 33 | - public function __construct(Exception $exception) |
|
| 34 | - { |
|
| 35 | - if (WP_DEBUG && ! defined('EE_TESTS_DIR')) { |
|
| 36 | - $this->displayException($exception); |
|
| 37 | - } else { |
|
| 38 | - throw $exception; |
|
| 39 | - } |
|
| 40 | - } |
|
| 29 | + /** |
|
| 30 | + * @param Exception $exception |
|
| 31 | + * @throws Exception |
|
| 32 | + */ |
|
| 33 | + public function __construct(Exception $exception) |
|
| 34 | + { |
|
| 35 | + if (WP_DEBUG && ! defined('EE_TESTS_DIR')) { |
|
| 36 | + $this->displayException($exception); |
|
| 37 | + } else { |
|
| 38 | + throw $exception; |
|
| 39 | + } |
|
| 40 | + } |
|
| 41 | 41 | |
| 42 | 42 | |
| 43 | 43 | |
| 44 | - /** |
|
| 45 | - * @access protected |
|
| 46 | - * @param Exception $exception |
|
| 47 | - * @throws ReflectionException |
|
| 48 | - */ |
|
| 49 | - protected function displayException(Exception $exception) |
|
| 50 | - { |
|
| 51 | - $error_code = ''; |
|
| 52 | - $trace_details = ''; |
|
| 53 | - $time = time(); |
|
| 54 | - $trace = $exception->getTrace(); |
|
| 55 | - // get separate user and developer messages if they exist |
|
| 56 | - $msg = explode('||', $exception->getMessage()); |
|
| 57 | - $user_msg = $msg[0]; |
|
| 58 | - $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0]; |
|
| 59 | - $msg = WP_DEBUG ? $dev_msg : $user_msg; |
|
| 60 | - // start gathering output |
|
| 61 | - $output = $this->exceptionStyles(); |
|
| 62 | - $output .= ' |
|
| 44 | + /** |
|
| 45 | + * @access protected |
|
| 46 | + * @param Exception $exception |
|
| 47 | + * @throws ReflectionException |
|
| 48 | + */ |
|
| 49 | + protected function displayException(Exception $exception) |
|
| 50 | + { |
|
| 51 | + $error_code = ''; |
|
| 52 | + $trace_details = ''; |
|
| 53 | + $time = time(); |
|
| 54 | + $trace = $exception->getTrace(); |
|
| 55 | + // get separate user and developer messages if they exist |
|
| 56 | + $msg = explode('||', $exception->getMessage()); |
|
| 57 | + $user_msg = $msg[0]; |
|
| 58 | + $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0]; |
|
| 59 | + $msg = WP_DEBUG ? $dev_msg : $user_msg; |
|
| 60 | + // start gathering output |
|
| 61 | + $output = $this->exceptionStyles(); |
|
| 62 | + $output .= ' |
|
| 63 | 63 | <div id="ee-error-message" class="error">'; |
| 64 | - if (! WP_DEBUG) { |
|
| 65 | - $output .= ' |
|
| 64 | + if (! WP_DEBUG) { |
|
| 65 | + $output .= ' |
|
| 66 | 66 | <p>'; |
| 67 | - } |
|
| 68 | - // process trace info |
|
| 69 | - if (empty($trace)) { |
|
| 70 | - $trace_details .= __( |
|
| 71 | - 'Sorry, but no trace information was available for this exception.', |
|
| 72 | - 'event_espresso' |
|
| 73 | - ); |
|
| 74 | - } else { |
|
| 75 | - $trace_details .= ' |
|
| 67 | + } |
|
| 68 | + // process trace info |
|
| 69 | + if (empty($trace)) { |
|
| 70 | + $trace_details .= __( |
|
| 71 | + 'Sorry, but no trace information was available for this exception.', |
|
| 72 | + 'event_espresso' |
|
| 73 | + ); |
|
| 74 | + } else { |
|
| 75 | + $trace_details .= ' |
|
| 76 | 76 | <div id="ee-trace-details"> |
| 77 | 77 | <table width="100%" border="0" cellpadding="5" cellspacing="0"> |
| 78 | 78 | <tr> |
@@ -80,260 +80,260 @@ discard block |
||
| 80 | 80 | <th scope="col" align="right" style="width:3.5%;">Line</th> |
| 81 | 81 | <th scope="col" align="left" style="width:40%;">File</th> |
| 82 | 82 | <th scope="col" align="left">' . __('Class', 'event_espresso') . '->' . __('Method( arguments )', |
| 83 | - 'event_espresso') . '</th> |
|
| 83 | + 'event_espresso') . '</th> |
|
| 84 | 84 | </tr>'; |
| 85 | - $last_on_stack = count($trace) - 1; |
|
| 86 | - // reverse array so that stack is in proper chronological order |
|
| 87 | - $sorted_trace = array_reverse($trace); |
|
| 88 | - foreach ($sorted_trace as $nmbr => $trace) { |
|
| 89 | - $file = isset($trace['file']) ? $trace['file'] : ''; |
|
| 90 | - $class = isset($trace['class']) ? $trace['class'] : ''; |
|
| 91 | - $type = isset($trace['type']) ? $trace['type'] : ''; |
|
| 92 | - $function = isset($trace['function']) ? $trace['function'] : ''; |
|
| 93 | - $args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : ''; |
|
| 94 | - $args = isset($trace['args']) && count($trace['args']) > 4 ? ' <br />' . $args . '<br />' : $args; |
|
| 95 | - $line = isset($trace['line']) ? $trace['line'] : ''; |
|
| 96 | - $zebra = $nmbr % 2 !== 0 ? ' odd' : ''; |
|
| 97 | - if (empty($file) && ! empty($class)) { |
|
| 98 | - $a = new ReflectionClass($class); |
|
| 99 | - $file = $a->getFileName(); |
|
| 100 | - if (empty($line) && ! empty($function)) { |
|
| 101 | - try { |
|
| 102 | - //if $function is a closure, this throws an exception |
|
| 103 | - $b = new ReflectionMethod($class, $function); |
|
| 104 | - $line = $b->getStartLine(); |
|
| 105 | - } catch (Exception $closure_exception) { |
|
| 106 | - $line = 'unknown'; |
|
| 107 | - } |
|
| 108 | - } |
|
| 109 | - } |
|
| 110 | - if ($nmbr === $last_on_stack) { |
|
| 111 | - $file = $exception->getFile() !== '' ? $exception->getFile() : $file; |
|
| 112 | - $line = $exception->getLine() !== '' ? $exception->getLine() : $line; |
|
| 113 | - $error_code = $this->generate_error_code($file, $trace['function'], $line); |
|
| 114 | - } |
|
| 115 | - $file = \EEH_File::standardise_directory_separators($file); |
|
| 116 | - $nmbr = ! empty($nmbr) ? $nmbr : ' '; |
|
| 117 | - $line = ! empty($line) ? $line : ' '; |
|
| 118 | - $file = ! empty($file) ? $file : ' '; |
|
| 119 | - $class_display = ! empty($class) ? $class : ''; |
|
| 120 | - $type = ! empty($type) ? $type : ''; |
|
| 121 | - $function = ! empty($function) ? $function : ''; |
|
| 122 | - $args = ! empty($args) ? '( ' . $args . ' )' : '()'; |
|
| 123 | - $trace_details .= ' |
|
| 85 | + $last_on_stack = count($trace) - 1; |
|
| 86 | + // reverse array so that stack is in proper chronological order |
|
| 87 | + $sorted_trace = array_reverse($trace); |
|
| 88 | + foreach ($sorted_trace as $nmbr => $trace) { |
|
| 89 | + $file = isset($trace['file']) ? $trace['file'] : ''; |
|
| 90 | + $class = isset($trace['class']) ? $trace['class'] : ''; |
|
| 91 | + $type = isset($trace['type']) ? $trace['type'] : ''; |
|
| 92 | + $function = isset($trace['function']) ? $trace['function'] : ''; |
|
| 93 | + $args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : ''; |
|
| 94 | + $args = isset($trace['args']) && count($trace['args']) > 4 ? ' <br />' . $args . '<br />' : $args; |
|
| 95 | + $line = isset($trace['line']) ? $trace['line'] : ''; |
|
| 96 | + $zebra = $nmbr % 2 !== 0 ? ' odd' : ''; |
|
| 97 | + if (empty($file) && ! empty($class)) { |
|
| 98 | + $a = new ReflectionClass($class); |
|
| 99 | + $file = $a->getFileName(); |
|
| 100 | + if (empty($line) && ! empty($function)) { |
|
| 101 | + try { |
|
| 102 | + //if $function is a closure, this throws an exception |
|
| 103 | + $b = new ReflectionMethod($class, $function); |
|
| 104 | + $line = $b->getStartLine(); |
|
| 105 | + } catch (Exception $closure_exception) { |
|
| 106 | + $line = 'unknown'; |
|
| 107 | + } |
|
| 108 | + } |
|
| 109 | + } |
|
| 110 | + if ($nmbr === $last_on_stack) { |
|
| 111 | + $file = $exception->getFile() !== '' ? $exception->getFile() : $file; |
|
| 112 | + $line = $exception->getLine() !== '' ? $exception->getLine() : $line; |
|
| 113 | + $error_code = $this->generate_error_code($file, $trace['function'], $line); |
|
| 114 | + } |
|
| 115 | + $file = \EEH_File::standardise_directory_separators($file); |
|
| 116 | + $nmbr = ! empty($nmbr) ? $nmbr : ' '; |
|
| 117 | + $line = ! empty($line) ? $line : ' '; |
|
| 118 | + $file = ! empty($file) ? $file : ' '; |
|
| 119 | + $class_display = ! empty($class) ? $class : ''; |
|
| 120 | + $type = ! empty($type) ? $type : ''; |
|
| 121 | + $function = ! empty($function) ? $function : ''; |
|
| 122 | + $args = ! empty($args) ? '( ' . $args . ' )' : '()'; |
|
| 123 | + $trace_details .= ' |
|
| 124 | 124 | <tr> |
| 125 | 125 | <td align="right" valign="top" class="' |
| 126 | - . $zebra |
|
| 127 | - . '">' |
|
| 128 | - . $nmbr |
|
| 129 | - . '</td> |
|
| 126 | + . $zebra |
|
| 127 | + . '">' |
|
| 128 | + . $nmbr |
|
| 129 | + . '</td> |
|
| 130 | 130 | <td align="right" valign="top" class="' |
| 131 | - . $zebra |
|
| 132 | - . '">' |
|
| 133 | - . $line |
|
| 134 | - . '</td> |
|
| 131 | + . $zebra |
|
| 132 | + . '">' |
|
| 133 | + . $line |
|
| 134 | + . '</td> |
|
| 135 | 135 | <td align="left" valign="top" class="' |
| 136 | - . $zebra |
|
| 137 | - . '">' |
|
| 138 | - . $file |
|
| 139 | - . '</td> |
|
| 136 | + . $zebra |
|
| 137 | + . '">' |
|
| 138 | + . $file |
|
| 139 | + . '</td> |
|
| 140 | 140 | <td align="left" valign="top" class="' |
| 141 | - . $zebra |
|
| 142 | - . '">' |
|
| 143 | - . $class_display |
|
| 144 | - . $type |
|
| 145 | - . $function |
|
| 146 | - . $args |
|
| 147 | - . '</td> |
|
| 141 | + . $zebra |
|
| 142 | + . '">' |
|
| 143 | + . $class_display |
|
| 144 | + . $type |
|
| 145 | + . $function |
|
| 146 | + . $args |
|
| 147 | + . '</td> |
|
| 148 | 148 | </tr>'; |
| 149 | - } |
|
| 150 | - $trace_details .= ' |
|
| 149 | + } |
|
| 150 | + $trace_details .= ' |
|
| 151 | 151 | </table> |
| 152 | 152 | </div>'; |
| 153 | - } |
|
| 154 | - $code = $exception->getCode() ? $exception->getCode() : $error_code; |
|
| 155 | - // add generic non-identifying messages for non-privileged users |
|
| 156 | - if (! WP_DEBUG) { |
|
| 157 | - $output .= '<span class="ee-error-user-msg-spn">' |
|
| 158 | - . trim($msg) |
|
| 159 | - . '</span> <sup>' |
|
| 160 | - . $code |
|
| 161 | - . '</sup><br />'; |
|
| 162 | - } else { |
|
| 163 | - // or helpful developer messages if debugging is on |
|
| 164 | - $output .= ' |
|
| 153 | + } |
|
| 154 | + $code = $exception->getCode() ? $exception->getCode() : $error_code; |
|
| 155 | + // add generic non-identifying messages for non-privileged users |
|
| 156 | + if (! WP_DEBUG) { |
|
| 157 | + $output .= '<span class="ee-error-user-msg-spn">' |
|
| 158 | + . trim($msg) |
|
| 159 | + . '</span> <sup>' |
|
| 160 | + . $code |
|
| 161 | + . '</sup><br />'; |
|
| 162 | + } else { |
|
| 163 | + // or helpful developer messages if debugging is on |
|
| 164 | + $output .= ' |
|
| 165 | 165 | <div class="ee-error-dev-msg-dv"> |
| 166 | 166 | <p class="ee-error-dev-msg-pg"> |
| 167 | 167 | ' |
| 168 | - . sprintf( |
|
| 169 | - __('%1$sAn %2$s was thrown!%3$s code: %4$s', 'event_espresso'), |
|
| 170 | - '<strong class="ee-error-dev-msg-str">', |
|
| 171 | - get_class($exception), |
|
| 172 | - '</strong> <span>', |
|
| 173 | - $code . '</span>' |
|
| 174 | - ) |
|
| 175 | - . '<br /> |
|
| 168 | + . sprintf( |
|
| 169 | + __('%1$sAn %2$s was thrown!%3$s code: %4$s', 'event_espresso'), |
|
| 170 | + '<strong class="ee-error-dev-msg-str">', |
|
| 171 | + get_class($exception), |
|
| 172 | + '</strong> <span>', |
|
| 173 | + $code . '</span>' |
|
| 174 | + ) |
|
| 175 | + . '<br /> |
|
| 176 | 176 | <span class="big-text">"' |
| 177 | - . trim($msg) |
|
| 178 | - . '"</span><br/> |
|
| 177 | + . trim($msg) |
|
| 178 | + . '"</span><br/> |
|
| 179 | 179 | <a id="display-ee-error-trace-1' |
| 180 | - . $time |
|
| 181 | - . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-1' |
|
| 182 | - . $time |
|
| 183 | - . '"> |
|
| 180 | + . $time |
|
| 181 | + . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-1' |
|
| 182 | + . $time |
|
| 183 | + . '"> |
|
| 184 | 184 | ' |
| 185 | - . __('click to view backtrace and class/method details', 'event_espresso') |
|
| 186 | - . ' |
|
| 185 | + . __('click to view backtrace and class/method details', 'event_espresso') |
|
| 186 | + . ' |
|
| 187 | 187 | </a><br /> |
| 188 | 188 | ' |
| 189 | - . $exception->getFile() |
|
| 190 | - . sprintf( |
|
| 191 | - __('%1$s( line no: %2$s )%3$s', 'event_espresso'), |
|
| 192 | - ' <span class="small-text lt-grey-text">', |
|
| 193 | - $exception->getLine(), |
|
| 194 | - '</span>' |
|
| 195 | - ) |
|
| 196 | - . ' |
|
| 189 | + . $exception->getFile() |
|
| 190 | + . sprintf( |
|
| 191 | + __('%1$s( line no: %2$s )%3$s', 'event_espresso'), |
|
| 192 | + ' <span class="small-text lt-grey-text">', |
|
| 193 | + $exception->getLine(), |
|
| 194 | + '</span>' |
|
| 195 | + ) |
|
| 196 | + . ' |
|
| 197 | 197 | </p> |
| 198 | 198 | <div id="ee-error-trace-1' |
| 199 | - . $time |
|
| 200 | - . '-dv" class="ee-error-trace-dv" style="display: none;"> |
|
| 199 | + . $time |
|
| 200 | + . '-dv" class="ee-error-trace-dv" style="display: none;"> |
|
| 201 | 201 | ' |
| 202 | - . $trace_details; |
|
| 203 | - if (! empty($class)) { |
|
| 204 | - $output .= ' |
|
| 202 | + . $trace_details; |
|
| 203 | + if (! empty($class)) { |
|
| 204 | + $output .= ' |
|
| 205 | 205 | <div style="padding:3px; margin:0 0 1em; border:1px solid #999; background:#fff; border-radius:3px;"> |
| 206 | 206 | <div style="padding:1em 2em; border:1px solid #999; background:#fcfcfc;"> |
| 207 | 207 | <h3>' . __('Class Details', 'event_espresso') . '</h3>'; |
| 208 | - $a = new ReflectionClass($class); |
|
| 209 | - $output .= ' |
|
| 208 | + $a = new ReflectionClass($class); |
|
| 209 | + $output .= ' |
|
| 210 | 210 | <pre>' . $a . '</pre> |
| 211 | 211 | </div> |
| 212 | 212 | </div>'; |
| 213 | - } |
|
| 214 | - $output .= ' |
|
| 213 | + } |
|
| 214 | + $output .= ' |
|
| 215 | 215 | </div> |
| 216 | 216 | </div> |
| 217 | 217 | <br />'; |
| 218 | - } |
|
| 219 | - // remove last linebreak |
|
| 220 | - $output = substr($output, 0, -6); |
|
| 221 | - if (! WP_DEBUG) { |
|
| 222 | - $output .= ' |
|
| 218 | + } |
|
| 219 | + // remove last linebreak |
|
| 220 | + $output = substr($output, 0, -6); |
|
| 221 | + if (! WP_DEBUG) { |
|
| 222 | + $output .= ' |
|
| 223 | 223 | </p>'; |
| 224 | - } |
|
| 225 | - $output .= ' |
|
| 224 | + } |
|
| 225 | + $output .= ' |
|
| 226 | 226 | </div>'; |
| 227 | - $output .= $this->printScripts(true); |
|
| 228 | - if (defined('DOING_AJAX')) { |
|
| 229 | - echo wp_json_encode(array('error' => $output)); |
|
| 230 | - exit(); |
|
| 231 | - } |
|
| 232 | - echo $output; |
|
| 233 | - } |
|
| 227 | + $output .= $this->printScripts(true); |
|
| 228 | + if (defined('DOING_AJAX')) { |
|
| 229 | + echo wp_json_encode(array('error' => $output)); |
|
| 230 | + exit(); |
|
| 231 | + } |
|
| 232 | + echo $output; |
|
| 233 | + } |
|
| 234 | 234 | |
| 235 | 235 | |
| 236 | 236 | |
| 237 | - /** |
|
| 238 | - * generate string from exception trace args |
|
| 239 | - * |
|
| 240 | - * @param array $arguments |
|
| 241 | - * @param int $indent |
|
| 242 | - * @param bool $array |
|
| 243 | - * @return string |
|
| 244 | - */ |
|
| 245 | - private function _convert_args_to_string($arguments = array(), $indent = 0, $array = false) |
|
| 246 | - { |
|
| 247 | - $args = array(); |
|
| 248 | - $args_count = count($arguments); |
|
| 249 | - if ($args_count > 2) { |
|
| 250 | - $indent++; |
|
| 251 | - $args[] = '<br />'; |
|
| 252 | - } |
|
| 253 | - $x = 0; |
|
| 254 | - foreach ($arguments as $arg) { |
|
| 255 | - $x++; |
|
| 256 | - for ($i = 0; $i < $indent; $i++) { |
|
| 257 | - $args[] = ' '; |
|
| 258 | - } |
|
| 259 | - if (is_string($arg)) { |
|
| 260 | - if (! $array && strlen($arg) > 75) { |
|
| 261 | - $args[] = '<br />'; |
|
| 262 | - for ($i = 0; $i <= $indent; $i++) { |
|
| 263 | - $args[] = ' '; |
|
| 264 | - } |
|
| 265 | - $args[] = "'" . $arg . "'<br />"; |
|
| 266 | - } else { |
|
| 267 | - $args[] = " '" . $arg . "'"; |
|
| 268 | - } |
|
| 269 | - } elseif (is_array($arg)) { |
|
| 270 | - $arg_count = count($arg); |
|
| 271 | - if ($arg_count > 2) { |
|
| 272 | - $indent++; |
|
| 273 | - $args[] = ' array(' . $this->_convert_args_to_string($arg, $indent, true) . ')'; |
|
| 274 | - $indent--; |
|
| 275 | - } else if ($arg_count === 0) { |
|
| 276 | - $args[] = ' array()'; |
|
| 277 | - } else { |
|
| 278 | - $args[] = ' array( ' . $this->_convert_args_to_string($arg) . ' )'; |
|
| 279 | - } |
|
| 280 | - } elseif ($arg === null) { |
|
| 281 | - $args[] = ' null'; |
|
| 282 | - } elseif (is_bool($arg)) { |
|
| 283 | - $args[] = $arg ? ' true' : ' false'; |
|
| 284 | - } elseif (is_object($arg)) { |
|
| 285 | - $args[] = get_class($arg); |
|
| 286 | - } elseif (is_resource($arg)) { |
|
| 287 | - $args[] = get_resource_type($arg); |
|
| 288 | - } else { |
|
| 289 | - $args[] = $arg; |
|
| 290 | - } |
|
| 291 | - if ($x === $args_count) { |
|
| 292 | - if ($args_count > 2) { |
|
| 293 | - $args[] = '<br />'; |
|
| 294 | - $indent--; |
|
| 295 | - for ($i = 1; $i < $indent; $i++) { |
|
| 296 | - $args[] = ' '; |
|
| 297 | - } |
|
| 298 | - } |
|
| 299 | - } else { |
|
| 300 | - $args[] = $args_count > 2 ? ',<br />' : ', '; |
|
| 301 | - } |
|
| 302 | - } |
|
| 303 | - return implode('', $args); |
|
| 304 | - } |
|
| 237 | + /** |
|
| 238 | + * generate string from exception trace args |
|
| 239 | + * |
|
| 240 | + * @param array $arguments |
|
| 241 | + * @param int $indent |
|
| 242 | + * @param bool $array |
|
| 243 | + * @return string |
|
| 244 | + */ |
|
| 245 | + private function _convert_args_to_string($arguments = array(), $indent = 0, $array = false) |
|
| 246 | + { |
|
| 247 | + $args = array(); |
|
| 248 | + $args_count = count($arguments); |
|
| 249 | + if ($args_count > 2) { |
|
| 250 | + $indent++; |
|
| 251 | + $args[] = '<br />'; |
|
| 252 | + } |
|
| 253 | + $x = 0; |
|
| 254 | + foreach ($arguments as $arg) { |
|
| 255 | + $x++; |
|
| 256 | + for ($i = 0; $i < $indent; $i++) { |
|
| 257 | + $args[] = ' '; |
|
| 258 | + } |
|
| 259 | + if (is_string($arg)) { |
|
| 260 | + if (! $array && strlen($arg) > 75) { |
|
| 261 | + $args[] = '<br />'; |
|
| 262 | + for ($i = 0; $i <= $indent; $i++) { |
|
| 263 | + $args[] = ' '; |
|
| 264 | + } |
|
| 265 | + $args[] = "'" . $arg . "'<br />"; |
|
| 266 | + } else { |
|
| 267 | + $args[] = " '" . $arg . "'"; |
|
| 268 | + } |
|
| 269 | + } elseif (is_array($arg)) { |
|
| 270 | + $arg_count = count($arg); |
|
| 271 | + if ($arg_count > 2) { |
|
| 272 | + $indent++; |
|
| 273 | + $args[] = ' array(' . $this->_convert_args_to_string($arg, $indent, true) . ')'; |
|
| 274 | + $indent--; |
|
| 275 | + } else if ($arg_count === 0) { |
|
| 276 | + $args[] = ' array()'; |
|
| 277 | + } else { |
|
| 278 | + $args[] = ' array( ' . $this->_convert_args_to_string($arg) . ' )'; |
|
| 279 | + } |
|
| 280 | + } elseif ($arg === null) { |
|
| 281 | + $args[] = ' null'; |
|
| 282 | + } elseif (is_bool($arg)) { |
|
| 283 | + $args[] = $arg ? ' true' : ' false'; |
|
| 284 | + } elseif (is_object($arg)) { |
|
| 285 | + $args[] = get_class($arg); |
|
| 286 | + } elseif (is_resource($arg)) { |
|
| 287 | + $args[] = get_resource_type($arg); |
|
| 288 | + } else { |
|
| 289 | + $args[] = $arg; |
|
| 290 | + } |
|
| 291 | + if ($x === $args_count) { |
|
| 292 | + if ($args_count > 2) { |
|
| 293 | + $args[] = '<br />'; |
|
| 294 | + $indent--; |
|
| 295 | + for ($i = 1; $i < $indent; $i++) { |
|
| 296 | + $args[] = ' '; |
|
| 297 | + } |
|
| 298 | + } |
|
| 299 | + } else { |
|
| 300 | + $args[] = $args_count > 2 ? ',<br />' : ', '; |
|
| 301 | + } |
|
| 302 | + } |
|
| 303 | + return implode('', $args); |
|
| 304 | + } |
|
| 305 | 305 | |
| 306 | 306 | |
| 307 | 307 | |
| 308 | - /** |
|
| 309 | - * create error code from filepath, function name, |
|
| 310 | - * and line number where exception or error was thrown |
|
| 311 | - * |
|
| 312 | - * @access protected |
|
| 313 | - * @param string $file |
|
| 314 | - * @param string $func |
|
| 315 | - * @param string $line |
|
| 316 | - * @return string |
|
| 317 | - */ |
|
| 318 | - protected function generate_error_code($file = '', $func = '', $line = '') |
|
| 319 | - { |
|
| 320 | - $file_bits = explode('.', basename($file)); |
|
| 321 | - $error_code = ! empty($file_bits[0]) ? $file_bits[0] : ''; |
|
| 322 | - $error_code .= ! empty($func) ? ' - ' . $func : ''; |
|
| 323 | - $error_code .= ! empty($line) ? ' - ' . $line : ''; |
|
| 324 | - return $error_code; |
|
| 325 | - } |
|
| 308 | + /** |
|
| 309 | + * create error code from filepath, function name, |
|
| 310 | + * and line number where exception or error was thrown |
|
| 311 | + * |
|
| 312 | + * @access protected |
|
| 313 | + * @param string $file |
|
| 314 | + * @param string $func |
|
| 315 | + * @param string $line |
|
| 316 | + * @return string |
|
| 317 | + */ |
|
| 318 | + protected function generate_error_code($file = '', $func = '', $line = '') |
|
| 319 | + { |
|
| 320 | + $file_bits = explode('.', basename($file)); |
|
| 321 | + $error_code = ! empty($file_bits[0]) ? $file_bits[0] : ''; |
|
| 322 | + $error_code .= ! empty($func) ? ' - ' . $func : ''; |
|
| 323 | + $error_code .= ! empty($line) ? ' - ' . $line : ''; |
|
| 324 | + return $error_code; |
|
| 325 | + } |
|
| 326 | 326 | |
| 327 | 327 | |
| 328 | 328 | |
| 329 | - /** |
|
| 330 | - * _exception_styles |
|
| 331 | - * |
|
| 332 | - * @return string |
|
| 333 | - */ |
|
| 334 | - private function exceptionStyles() |
|
| 335 | - { |
|
| 336 | - return ' |
|
| 329 | + /** |
|
| 330 | + * _exception_styles |
|
| 331 | + * |
|
| 332 | + * @return string |
|
| 333 | + */ |
|
| 334 | + private function exceptionStyles() |
|
| 335 | + { |
|
| 336 | + return ' |
|
| 337 | 337 | <style type="text/css"> |
| 338 | 338 | #ee-error-message { |
| 339 | 339 | max-width:90% !important; |
@@ -390,30 +390,30 @@ discard block |
||
| 390 | 390 | color: #999; |
| 391 | 391 | } |
| 392 | 392 | </style>'; |
| 393 | - } |
|
| 393 | + } |
|
| 394 | 394 | |
| 395 | 395 | |
| 396 | 396 | |
| 397 | - /** |
|
| 398 | - * _print_scripts |
|
| 399 | - * |
|
| 400 | - * @param bool $force_print |
|
| 401 | - * @return string |
|
| 402 | - */ |
|
| 403 | - private function printScripts($force_print = false) |
|
| 404 | - { |
|
| 405 | - if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) { |
|
| 406 | - if (wp_script_is('ee_error_js', 'enqueued')) { |
|
| 407 | - return ''; |
|
| 408 | - } |
|
| 409 | - if (wp_script_is('ee_error_js', 'registered')) { |
|
| 410 | - wp_enqueue_style('espresso_default'); |
|
| 411 | - wp_enqueue_style('espresso_custom_css'); |
|
| 412 | - wp_enqueue_script( 'ee_error_js' ); |
|
| 397 | + /** |
|
| 398 | + * _print_scripts |
|
| 399 | + * |
|
| 400 | + * @param bool $force_print |
|
| 401 | + * @return string |
|
| 402 | + */ |
|
| 403 | + private function printScripts($force_print = false) |
|
| 404 | + { |
|
| 405 | + if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) { |
|
| 406 | + if (wp_script_is('ee_error_js', 'enqueued')) { |
|
| 407 | + return ''; |
|
| 408 | + } |
|
| 409 | + if (wp_script_is('ee_error_js', 'registered')) { |
|
| 410 | + wp_enqueue_style('espresso_default'); |
|
| 411 | + wp_enqueue_style('espresso_custom_css'); |
|
| 412 | + wp_enqueue_script( 'ee_error_js' ); |
|
| 413 | 413 | wp_localize_script( 'ee_error_js', 'ee_settings', array( 'wp_debug' => WP_DEBUG ) ); |
| 414 | - } |
|
| 415 | - } else { |
|
| 416 | - return ' |
|
| 414 | + } |
|
| 415 | + } else { |
|
| 416 | + return ' |
|
| 417 | 417 | <script> |
| 418 | 418 | /* <![CDATA[ */ |
| 419 | 419 | var ee_settings = {"wp_debug":"' . WP_DEBUG . '"}; |
@@ -423,9 +423,9 @@ discard block |
||
| 423 | 423 | <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script> |
| 424 | 424 | <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script> |
| 425 | 425 | '; |
| 426 | - } |
|
| 427 | - return ''; |
|
| 428 | - } |
|
| 426 | + } |
|
| 427 | + return ''; |
|
| 428 | + } |
|
| 429 | 429 | |
| 430 | 430 | |
| 431 | 431 | |
@@ -7,7 +7,7 @@ discard block |
||
| 7 | 7 | use ReflectionException; |
| 8 | 8 | use ReflectionMethod; |
| 9 | 9 | |
| 10 | -if (! defined('EVENT_ESPRESSO_VERSION')) { |
|
| 10 | +if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
|
| 11 | 11 | exit('No direct script access allowed'); |
| 12 | 12 | } |
| 13 | 13 | |
@@ -61,7 +61,7 @@ discard block |
||
| 61 | 61 | $output = $this->exceptionStyles(); |
| 62 | 62 | $output .= ' |
| 63 | 63 | <div id="ee-error-message" class="error">'; |
| 64 | - if (! WP_DEBUG) { |
|
| 64 | + if ( ! WP_DEBUG) { |
|
| 65 | 65 | $output .= ' |
| 66 | 66 | <p>'; |
| 67 | 67 | } |
@@ -79,8 +79,8 @@ discard block |
||
| 79 | 79 | <th scope="col" align="right" style="width:2.5%;">#</th> |
| 80 | 80 | <th scope="col" align="right" style="width:3.5%;">Line</th> |
| 81 | 81 | <th scope="col" align="left" style="width:40%;">File</th> |
| 82 | - <th scope="col" align="left">' . __('Class', 'event_espresso') . '->' . __('Method( arguments )', |
|
| 83 | - 'event_espresso') . '</th> |
|
| 82 | + <th scope="col" align="left">' . __('Class', 'event_espresso').'->'.__('Method( arguments )', |
|
| 83 | + 'event_espresso').'</th> |
|
| 84 | 84 | </tr>'; |
| 85 | 85 | $last_on_stack = count($trace) - 1; |
| 86 | 86 | // reverse array so that stack is in proper chronological order |
@@ -91,7 +91,7 @@ discard block |
||
| 91 | 91 | $type = isset($trace['type']) ? $trace['type'] : ''; |
| 92 | 92 | $function = isset($trace['function']) ? $trace['function'] : ''; |
| 93 | 93 | $args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : ''; |
| 94 | - $args = isset($trace['args']) && count($trace['args']) > 4 ? ' <br />' . $args . '<br />' : $args; |
|
| 94 | + $args = isset($trace['args']) && count($trace['args']) > 4 ? ' <br />'.$args.'<br />' : $args; |
|
| 95 | 95 | $line = isset($trace['line']) ? $trace['line'] : ''; |
| 96 | 96 | $zebra = $nmbr % 2 !== 0 ? ' odd' : ''; |
| 97 | 97 | if (empty($file) && ! empty($class)) { |
@@ -119,7 +119,7 @@ discard block |
||
| 119 | 119 | $class_display = ! empty($class) ? $class : ''; |
| 120 | 120 | $type = ! empty($type) ? $type : ''; |
| 121 | 121 | $function = ! empty($function) ? $function : ''; |
| 122 | - $args = ! empty($args) ? '( ' . $args . ' )' : '()'; |
|
| 122 | + $args = ! empty($args) ? '( '.$args.' )' : '()'; |
|
| 123 | 123 | $trace_details .= ' |
| 124 | 124 | <tr> |
| 125 | 125 | <td align="right" valign="top" class="' |
@@ -153,7 +153,7 @@ discard block |
||
| 153 | 153 | } |
| 154 | 154 | $code = $exception->getCode() ? $exception->getCode() : $error_code; |
| 155 | 155 | // add generic non-identifying messages for non-privileged users |
| 156 | - if (! WP_DEBUG) { |
|
| 156 | + if ( ! WP_DEBUG) { |
|
| 157 | 157 | $output .= '<span class="ee-error-user-msg-spn">' |
| 158 | 158 | . trim($msg) |
| 159 | 159 | . '</span> <sup>' |
@@ -170,7 +170,7 @@ discard block |
||
| 170 | 170 | '<strong class="ee-error-dev-msg-str">', |
| 171 | 171 | get_class($exception), |
| 172 | 172 | '</strong> <span>', |
| 173 | - $code . '</span>' |
|
| 173 | + $code.'</span>' |
|
| 174 | 174 | ) |
| 175 | 175 | . '<br /> |
| 176 | 176 | <span class="big-text">"' |
@@ -200,14 +200,14 @@ discard block |
||
| 200 | 200 | . '-dv" class="ee-error-trace-dv" style="display: none;"> |
| 201 | 201 | ' |
| 202 | 202 | . $trace_details; |
| 203 | - if (! empty($class)) { |
|
| 203 | + if ( ! empty($class)) { |
|
| 204 | 204 | $output .= ' |
| 205 | 205 | <div style="padding:3px; margin:0 0 1em; border:1px solid #999; background:#fff; border-radius:3px;"> |
| 206 | 206 | <div style="padding:1em 2em; border:1px solid #999; background:#fcfcfc;"> |
| 207 | - <h3>' . __('Class Details', 'event_espresso') . '</h3>'; |
|
| 207 | + <h3>' . __('Class Details', 'event_espresso').'</h3>'; |
|
| 208 | 208 | $a = new ReflectionClass($class); |
| 209 | 209 | $output .= ' |
| 210 | - <pre>' . $a . '</pre> |
|
| 210 | + <pre>' . $a.'</pre> |
|
| 211 | 211 | </div> |
| 212 | 212 | </div>'; |
| 213 | 213 | } |
@@ -218,7 +218,7 @@ discard block |
||
| 218 | 218 | } |
| 219 | 219 | // remove last linebreak |
| 220 | 220 | $output = substr($output, 0, -6); |
| 221 | - if (! WP_DEBUG) { |
|
| 221 | + if ( ! WP_DEBUG) { |
|
| 222 | 222 | $output .= ' |
| 223 | 223 | </p>'; |
| 224 | 224 | } |
@@ -257,25 +257,25 @@ discard block |
||
| 257 | 257 | $args[] = ' '; |
| 258 | 258 | } |
| 259 | 259 | if (is_string($arg)) { |
| 260 | - if (! $array && strlen($arg) > 75) { |
|
| 260 | + if ( ! $array && strlen($arg) > 75) { |
|
| 261 | 261 | $args[] = '<br />'; |
| 262 | 262 | for ($i = 0; $i <= $indent; $i++) { |
| 263 | 263 | $args[] = ' '; |
| 264 | 264 | } |
| 265 | - $args[] = "'" . $arg . "'<br />"; |
|
| 265 | + $args[] = "'".$arg."'<br />"; |
|
| 266 | 266 | } else { |
| 267 | - $args[] = " '" . $arg . "'"; |
|
| 267 | + $args[] = " '".$arg."'"; |
|
| 268 | 268 | } |
| 269 | 269 | } elseif (is_array($arg)) { |
| 270 | 270 | $arg_count = count($arg); |
| 271 | 271 | if ($arg_count > 2) { |
| 272 | 272 | $indent++; |
| 273 | - $args[] = ' array(' . $this->_convert_args_to_string($arg, $indent, true) . ')'; |
|
| 273 | + $args[] = ' array('.$this->_convert_args_to_string($arg, $indent, true).')'; |
|
| 274 | 274 | $indent--; |
| 275 | 275 | } else if ($arg_count === 0) { |
| 276 | 276 | $args[] = ' array()'; |
| 277 | 277 | } else { |
| 278 | - $args[] = ' array( ' . $this->_convert_args_to_string($arg) . ' )'; |
|
| 278 | + $args[] = ' array( '.$this->_convert_args_to_string($arg).' )'; |
|
| 279 | 279 | } |
| 280 | 280 | } elseif ($arg === null) { |
| 281 | 281 | $args[] = ' null'; |
@@ -319,8 +319,8 @@ discard block |
||
| 319 | 319 | { |
| 320 | 320 | $file_bits = explode('.', basename($file)); |
| 321 | 321 | $error_code = ! empty($file_bits[0]) ? $file_bits[0] : ''; |
| 322 | - $error_code .= ! empty($func) ? ' - ' . $func : ''; |
|
| 323 | - $error_code .= ! empty($line) ? ' - ' . $line : ''; |
|
| 322 | + $error_code .= ! empty($func) ? ' - '.$func : ''; |
|
| 323 | + $error_code .= ! empty($line) ? ' - '.$line : ''; |
|
| 324 | 324 | return $error_code; |
| 325 | 325 | } |
| 326 | 326 | |
@@ -402,26 +402,26 @@ discard block |
||
| 402 | 402 | */ |
| 403 | 403 | private function printScripts($force_print = false) |
| 404 | 404 | { |
| 405 | - if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) { |
|
| 405 | + if ( ! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) { |
|
| 406 | 406 | if (wp_script_is('ee_error_js', 'enqueued')) { |
| 407 | 407 | return ''; |
| 408 | 408 | } |
| 409 | 409 | if (wp_script_is('ee_error_js', 'registered')) { |
| 410 | 410 | wp_enqueue_style('espresso_default'); |
| 411 | 411 | wp_enqueue_style('espresso_custom_css'); |
| 412 | - wp_enqueue_script( 'ee_error_js' ); |
|
| 413 | - wp_localize_script( 'ee_error_js', 'ee_settings', array( 'wp_debug' => WP_DEBUG ) ); |
|
| 412 | + wp_enqueue_script('ee_error_js'); |
|
| 413 | + wp_localize_script('ee_error_js', 'ee_settings', array('wp_debug' => WP_DEBUG)); |
|
| 414 | 414 | } |
| 415 | 415 | } else { |
| 416 | 416 | return ' |
| 417 | 417 | <script> |
| 418 | 418 | /* <![CDATA[ */ |
| 419 | -var ee_settings = {"wp_debug":"' . WP_DEBUG . '"}; |
|
| 419 | +var ee_settings = {"wp_debug":"' . WP_DEBUG.'"}; |
|
| 420 | 420 | /* ]]> */ |
| 421 | 421 | </script> |
| 422 | -<script src="' . includes_url() . 'js/jquery/jquery.js" type="text/javascript"></script> |
|
| 423 | -<script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script> |
|
| 424 | -<script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script> |
|
| 422 | +<script src="' . includes_url().'js/jquery/jquery.js" type="text/javascript"></script> |
|
| 423 | +<script src="' . EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js'.'?ver='.espresso_version().'" type="text/javascript"></script> |
|
| 424 | +<script src="' . EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js'.'?ver='.espresso_version().'" type="text/javascript"></script> |
|
| 425 | 425 | '; |
| 426 | 426 | } |
| 427 | 427 | return ''; |
@@ -5,8 +5,8 @@ discard block |
||
| 5 | 5 | // if you're a dev and want to receive all errors via email |
| 6 | 6 | // add this to your wp-config.php: define( 'EE_ERROR_EMAILS', TRUE ); |
| 7 | 7 | if (defined('WP_DEBUG') && WP_DEBUG === true && defined('EE_ERROR_EMAILS') && EE_ERROR_EMAILS === true) { |
| 8 | - set_error_handler(array('EE_Error', 'error_handler')); |
|
| 9 | - register_shutdown_function(array('EE_Error', 'fatal_error_handler')); |
|
| 8 | + set_error_handler(array('EE_Error', 'error_handler')); |
|
| 9 | + register_shutdown_function(array('EE_Error', 'fatal_error_handler')); |
|
| 10 | 10 | } |
| 11 | 11 | |
| 12 | 12 | |
@@ -23,259 +23,259 @@ discard block |
||
| 23 | 23 | { |
| 24 | 24 | |
| 25 | 25 | |
| 26 | - /** |
|
| 27 | - * name of the file to log exceptions to |
|
| 28 | - * |
|
| 29 | - * @var string |
|
| 30 | - */ |
|
| 31 | - private static $_exception_log_file = 'espresso_error_log.txt'; |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * stores details for all exception |
|
| 35 | - * |
|
| 36 | - * @var array |
|
| 37 | - */ |
|
| 38 | - private static $_all_exceptions = array(); |
|
| 39 | - |
|
| 40 | - /** |
|
| 41 | - * tracks number of errors |
|
| 42 | - * |
|
| 43 | - * @var int |
|
| 44 | - */ |
|
| 45 | - private static $_error_count = 0; |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * has shutdown action been added ? |
|
| 49 | - * |
|
| 50 | - * @var array $_espresso_notices |
|
| 51 | - */ |
|
| 52 | - private static $_espresso_notices = array('success' => false, 'errors' => false, 'attention' => false); |
|
| 53 | - |
|
| 54 | - |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * @override default exception handling |
|
| 58 | - * @param string $message |
|
| 59 | - * @param int $code |
|
| 60 | - * @param Exception|null $previous |
|
| 61 | - */ |
|
| 62 | - public function __construct($message, $code = 0, Exception $previous = null) |
|
| 63 | - { |
|
| 64 | - if (version_compare(PHP_VERSION, '5.3.0', '<')) { |
|
| 65 | - parent::__construct($message, $code); |
|
| 66 | - } else { |
|
| 67 | - parent::__construct($message, $code, $previous); |
|
| 68 | - } |
|
| 69 | - } |
|
| 70 | - |
|
| 71 | - |
|
| 72 | - |
|
| 73 | - /** |
|
| 74 | - * error_handler |
|
| 75 | - * |
|
| 76 | - * @param $code |
|
| 77 | - * @param $message |
|
| 78 | - * @param $file |
|
| 79 | - * @param $line |
|
| 80 | - * @return void |
|
| 81 | - */ |
|
| 82 | - public static function error_handler($code, $message, $file, $line) |
|
| 83 | - { |
|
| 84 | - $type = EE_Error::error_type($code); |
|
| 85 | - $site = site_url(); |
|
| 86 | - switch ($site) { |
|
| 87 | - case 'http://ee4.eventespresso.com/' : |
|
| 88 | - case 'http://ee4decaf.eventespresso.com/' : |
|
| 89 | - case 'http://ee4hf.eventespresso.com/' : |
|
| 90 | - case 'http://ee4a.eventespresso.com/' : |
|
| 91 | - case 'http://ee4ad.eventespresso.com/' : |
|
| 92 | - case 'http://ee4b.eventespresso.com/' : |
|
| 93 | - case 'http://ee4bd.eventespresso.com/' : |
|
| 94 | - case 'http://ee4d.eventespresso.com/' : |
|
| 95 | - case 'http://ee4dd.eventespresso.com/' : |
|
| 96 | - $to = '[email protected]'; |
|
| 97 | - break; |
|
| 98 | - default : |
|
| 99 | - $to = get_option('admin_email'); |
|
| 100 | - } |
|
| 101 | - $subject = $type . ' ' . $message . ' in ' . EVENT_ESPRESSO_VERSION . ' on ' . site_url(); |
|
| 102 | - $msg = EE_Error::_format_error($type, $message, $file, $line); |
|
| 103 | - if (function_exists('wp_mail')) { |
|
| 104 | - add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type')); |
|
| 105 | - wp_mail($to, $subject, $msg); |
|
| 106 | - } |
|
| 107 | - echo '<div id="message" class="espresso-notices error"><p>'; |
|
| 108 | - echo $type . ': ' . $message . '<br />' . $file . ' line ' . $line; |
|
| 109 | - echo '<br /></p></div>'; |
|
| 110 | - } |
|
| 111 | - |
|
| 112 | - |
|
| 113 | - |
|
| 114 | - /** |
|
| 115 | - * error_type |
|
| 116 | - * http://www.php.net/manual/en/errorfunc.constants.php#109430 |
|
| 117 | - * |
|
| 118 | - * @param $code |
|
| 119 | - * @return string |
|
| 120 | - */ |
|
| 121 | - public static function error_type($code) |
|
| 122 | - { |
|
| 123 | - switch ($code) { |
|
| 124 | - case E_ERROR: // 1 // |
|
| 125 | - return 'E_ERROR'; |
|
| 126 | - case E_WARNING: // 2 // |
|
| 127 | - return 'E_WARNING'; |
|
| 128 | - case E_PARSE: // 4 // |
|
| 129 | - return 'E_PARSE'; |
|
| 130 | - case E_NOTICE: // 8 // |
|
| 131 | - return 'E_NOTICE'; |
|
| 132 | - case E_CORE_ERROR: // 16 // |
|
| 133 | - return 'E_CORE_ERROR'; |
|
| 134 | - case E_CORE_WARNING: // 32 // |
|
| 135 | - return 'E_CORE_WARNING'; |
|
| 136 | - case E_COMPILE_ERROR: // 64 // |
|
| 137 | - return 'E_COMPILE_ERROR'; |
|
| 138 | - case E_COMPILE_WARNING: // 128 // |
|
| 139 | - return 'E_COMPILE_WARNING'; |
|
| 140 | - case E_USER_ERROR: // 256 // |
|
| 141 | - return 'E_USER_ERROR'; |
|
| 142 | - case E_USER_WARNING: // 512 // |
|
| 143 | - return 'E_USER_WARNING'; |
|
| 144 | - case E_USER_NOTICE: // 1024 // |
|
| 145 | - return 'E_USER_NOTICE'; |
|
| 146 | - case E_STRICT: // 2048 // |
|
| 147 | - return 'E_STRICT'; |
|
| 148 | - case E_RECOVERABLE_ERROR: // 4096 // |
|
| 149 | - return 'E_RECOVERABLE_ERROR'; |
|
| 150 | - case E_DEPRECATED: // 8192 // |
|
| 151 | - return 'E_DEPRECATED'; |
|
| 152 | - case E_USER_DEPRECATED: // 16384 // |
|
| 153 | - return 'E_USER_DEPRECATED'; |
|
| 154 | - case E_ALL: // 16384 // |
|
| 155 | - return 'E_ALL'; |
|
| 156 | - } |
|
| 157 | - return ''; |
|
| 158 | - } |
|
| 159 | - |
|
| 160 | - |
|
| 161 | - |
|
| 162 | - /** |
|
| 163 | - * fatal_error_handler |
|
| 164 | - * |
|
| 165 | - * @return void |
|
| 166 | - */ |
|
| 167 | - public static function fatal_error_handler() |
|
| 168 | - { |
|
| 169 | - $last_error = error_get_last(); |
|
| 170 | - if ($last_error['type'] === E_ERROR) { |
|
| 171 | - EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']); |
|
| 172 | - } |
|
| 173 | - } |
|
| 174 | - |
|
| 175 | - |
|
| 176 | - |
|
| 177 | - /** |
|
| 178 | - * _format_error |
|
| 179 | - * |
|
| 180 | - * @param $code |
|
| 181 | - * @param $message |
|
| 182 | - * @param $file |
|
| 183 | - * @param $line |
|
| 184 | - * @return string |
|
| 185 | - */ |
|
| 186 | - private static function _format_error($code, $message, $file, $line) |
|
| 187 | - { |
|
| 188 | - $html = "<table cellpadding='5'><thead bgcolor='#f8f8f8'><th>Item</th><th align='left'>Details</th></thead><tbody>"; |
|
| 189 | - $html .= "<tr valign='top'><td><b>Code</b></td><td>$code</td></tr>"; |
|
| 190 | - $html .= "<tr valign='top'><td><b>Error</b></td><td>$message</td></tr>"; |
|
| 191 | - $html .= "<tr valign='top'><td><b>File</b></td><td>$file</td></tr>"; |
|
| 192 | - $html .= "<tr valign='top'><td><b>Line</b></td><td>$line</td></tr>"; |
|
| 193 | - $html .= '</tbody></table>'; |
|
| 194 | - return $html; |
|
| 195 | - } |
|
| 196 | - |
|
| 197 | - |
|
| 198 | - |
|
| 199 | - /** |
|
| 200 | - * set_content_type |
|
| 201 | - * |
|
| 202 | - * @param $content_type |
|
| 203 | - * @return string |
|
| 204 | - */ |
|
| 205 | - public static function set_content_type($content_type) |
|
| 206 | - { |
|
| 207 | - return 'text/html'; |
|
| 208 | - } |
|
| 209 | - |
|
| 210 | - |
|
| 211 | - |
|
| 212 | - /** |
|
| 213 | - * @return void |
|
| 214 | - * @throws EE_Error |
|
| 215 | - * @throws ReflectionException |
|
| 216 | - */ |
|
| 217 | - public function get_error() |
|
| 218 | - { |
|
| 219 | - if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) { |
|
| 220 | - throw $this; |
|
| 221 | - } |
|
| 222 | - // get separate user and developer messages if they exist |
|
| 223 | - $msg = explode('||', $this->getMessage()); |
|
| 224 | - $user_msg = $msg[0]; |
|
| 225 | - $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0]; |
|
| 226 | - $msg = WP_DEBUG ? $dev_msg : $user_msg; |
|
| 227 | - // add details to _all_exceptions array |
|
| 228 | - $x_time = time(); |
|
| 229 | - self::$_all_exceptions[$x_time]['name'] = get_class($this); |
|
| 230 | - self::$_all_exceptions[$x_time]['file'] = $this->getFile(); |
|
| 231 | - self::$_all_exceptions[$x_time]['line'] = $this->getLine(); |
|
| 232 | - self::$_all_exceptions[$x_time]['msg'] = $msg; |
|
| 233 | - self::$_all_exceptions[$x_time]['code'] = $this->getCode(); |
|
| 234 | - self::$_all_exceptions[$x_time]['trace'] = $this->getTrace(); |
|
| 235 | - self::$_all_exceptions[$x_time]['string'] = $this->getTraceAsString(); |
|
| 236 | - self::$_error_count++; |
|
| 237 | - //add_action( 'shutdown', array( $this, 'display_errors' )); |
|
| 238 | - $this->display_errors(); |
|
| 239 | - } |
|
| 240 | - |
|
| 241 | - |
|
| 242 | - |
|
| 243 | - /** |
|
| 244 | - * has_error |
|
| 245 | - * |
|
| 246 | - * @param bool $check_stored |
|
| 247 | - * @param string $type_to_check |
|
| 248 | - * @return bool |
|
| 249 | - */ |
|
| 250 | - public static function has_error($check_stored = false, $type_to_check = 'errors') |
|
| 251 | - { |
|
| 252 | - $has_error = isset(self::$_espresso_notices[$type_to_check]) |
|
| 253 | - && ! empty(self::$_espresso_notices[$type_to_check]) |
|
| 254 | - ? true |
|
| 255 | - : false; |
|
| 256 | - if ($check_stored && ! $has_error) { |
|
| 257 | - $notices = (array)get_option('ee_notices', array()); |
|
| 258 | - foreach ($notices as $type => $notice) { |
|
| 259 | - if ($type === $type_to_check && $notice) { |
|
| 260 | - return true; |
|
| 261 | - } |
|
| 262 | - } |
|
| 263 | - } |
|
| 264 | - return $has_error; |
|
| 265 | - } |
|
| 266 | - |
|
| 267 | - |
|
| 268 | - |
|
| 269 | - /** |
|
| 270 | - * display_errors |
|
| 271 | - * |
|
| 272 | - * @echo string |
|
| 273 | - * @throws \ReflectionException |
|
| 274 | - */ |
|
| 275 | - public function display_errors() |
|
| 276 | - { |
|
| 277 | - $trace_details = ''; |
|
| 278 | - $output = ' |
|
| 26 | + /** |
|
| 27 | + * name of the file to log exceptions to |
|
| 28 | + * |
|
| 29 | + * @var string |
|
| 30 | + */ |
|
| 31 | + private static $_exception_log_file = 'espresso_error_log.txt'; |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * stores details for all exception |
|
| 35 | + * |
|
| 36 | + * @var array |
|
| 37 | + */ |
|
| 38 | + private static $_all_exceptions = array(); |
|
| 39 | + |
|
| 40 | + /** |
|
| 41 | + * tracks number of errors |
|
| 42 | + * |
|
| 43 | + * @var int |
|
| 44 | + */ |
|
| 45 | + private static $_error_count = 0; |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * has shutdown action been added ? |
|
| 49 | + * |
|
| 50 | + * @var array $_espresso_notices |
|
| 51 | + */ |
|
| 52 | + private static $_espresso_notices = array('success' => false, 'errors' => false, 'attention' => false); |
|
| 53 | + |
|
| 54 | + |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * @override default exception handling |
|
| 58 | + * @param string $message |
|
| 59 | + * @param int $code |
|
| 60 | + * @param Exception|null $previous |
|
| 61 | + */ |
|
| 62 | + public function __construct($message, $code = 0, Exception $previous = null) |
|
| 63 | + { |
|
| 64 | + if (version_compare(PHP_VERSION, '5.3.0', '<')) { |
|
| 65 | + parent::__construct($message, $code); |
|
| 66 | + } else { |
|
| 67 | + parent::__construct($message, $code, $previous); |
|
| 68 | + } |
|
| 69 | + } |
|
| 70 | + |
|
| 71 | + |
|
| 72 | + |
|
| 73 | + /** |
|
| 74 | + * error_handler |
|
| 75 | + * |
|
| 76 | + * @param $code |
|
| 77 | + * @param $message |
|
| 78 | + * @param $file |
|
| 79 | + * @param $line |
|
| 80 | + * @return void |
|
| 81 | + */ |
|
| 82 | + public static function error_handler($code, $message, $file, $line) |
|
| 83 | + { |
|
| 84 | + $type = EE_Error::error_type($code); |
|
| 85 | + $site = site_url(); |
|
| 86 | + switch ($site) { |
|
| 87 | + case 'http://ee4.eventespresso.com/' : |
|
| 88 | + case 'http://ee4decaf.eventespresso.com/' : |
|
| 89 | + case 'http://ee4hf.eventespresso.com/' : |
|
| 90 | + case 'http://ee4a.eventespresso.com/' : |
|
| 91 | + case 'http://ee4ad.eventespresso.com/' : |
|
| 92 | + case 'http://ee4b.eventespresso.com/' : |
|
| 93 | + case 'http://ee4bd.eventespresso.com/' : |
|
| 94 | + case 'http://ee4d.eventespresso.com/' : |
|
| 95 | + case 'http://ee4dd.eventespresso.com/' : |
|
| 96 | + $to = '[email protected]'; |
|
| 97 | + break; |
|
| 98 | + default : |
|
| 99 | + $to = get_option('admin_email'); |
|
| 100 | + } |
|
| 101 | + $subject = $type . ' ' . $message . ' in ' . EVENT_ESPRESSO_VERSION . ' on ' . site_url(); |
|
| 102 | + $msg = EE_Error::_format_error($type, $message, $file, $line); |
|
| 103 | + if (function_exists('wp_mail')) { |
|
| 104 | + add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type')); |
|
| 105 | + wp_mail($to, $subject, $msg); |
|
| 106 | + } |
|
| 107 | + echo '<div id="message" class="espresso-notices error"><p>'; |
|
| 108 | + echo $type . ': ' . $message . '<br />' . $file . ' line ' . $line; |
|
| 109 | + echo '<br /></p></div>'; |
|
| 110 | + } |
|
| 111 | + |
|
| 112 | + |
|
| 113 | + |
|
| 114 | + /** |
|
| 115 | + * error_type |
|
| 116 | + * http://www.php.net/manual/en/errorfunc.constants.php#109430 |
|
| 117 | + * |
|
| 118 | + * @param $code |
|
| 119 | + * @return string |
|
| 120 | + */ |
|
| 121 | + public static function error_type($code) |
|
| 122 | + { |
|
| 123 | + switch ($code) { |
|
| 124 | + case E_ERROR: // 1 // |
|
| 125 | + return 'E_ERROR'; |
|
| 126 | + case E_WARNING: // 2 // |
|
| 127 | + return 'E_WARNING'; |
|
| 128 | + case E_PARSE: // 4 // |
|
| 129 | + return 'E_PARSE'; |
|
| 130 | + case E_NOTICE: // 8 // |
|
| 131 | + return 'E_NOTICE'; |
|
| 132 | + case E_CORE_ERROR: // 16 // |
|
| 133 | + return 'E_CORE_ERROR'; |
|
| 134 | + case E_CORE_WARNING: // 32 // |
|
| 135 | + return 'E_CORE_WARNING'; |
|
| 136 | + case E_COMPILE_ERROR: // 64 // |
|
| 137 | + return 'E_COMPILE_ERROR'; |
|
| 138 | + case E_COMPILE_WARNING: // 128 // |
|
| 139 | + return 'E_COMPILE_WARNING'; |
|
| 140 | + case E_USER_ERROR: // 256 // |
|
| 141 | + return 'E_USER_ERROR'; |
|
| 142 | + case E_USER_WARNING: // 512 // |
|
| 143 | + return 'E_USER_WARNING'; |
|
| 144 | + case E_USER_NOTICE: // 1024 // |
|
| 145 | + return 'E_USER_NOTICE'; |
|
| 146 | + case E_STRICT: // 2048 // |
|
| 147 | + return 'E_STRICT'; |
|
| 148 | + case E_RECOVERABLE_ERROR: // 4096 // |
|
| 149 | + return 'E_RECOVERABLE_ERROR'; |
|
| 150 | + case E_DEPRECATED: // 8192 // |
|
| 151 | + return 'E_DEPRECATED'; |
|
| 152 | + case E_USER_DEPRECATED: // 16384 // |
|
| 153 | + return 'E_USER_DEPRECATED'; |
|
| 154 | + case E_ALL: // 16384 // |
|
| 155 | + return 'E_ALL'; |
|
| 156 | + } |
|
| 157 | + return ''; |
|
| 158 | + } |
|
| 159 | + |
|
| 160 | + |
|
| 161 | + |
|
| 162 | + /** |
|
| 163 | + * fatal_error_handler |
|
| 164 | + * |
|
| 165 | + * @return void |
|
| 166 | + */ |
|
| 167 | + public static function fatal_error_handler() |
|
| 168 | + { |
|
| 169 | + $last_error = error_get_last(); |
|
| 170 | + if ($last_error['type'] === E_ERROR) { |
|
| 171 | + EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']); |
|
| 172 | + } |
|
| 173 | + } |
|
| 174 | + |
|
| 175 | + |
|
| 176 | + |
|
| 177 | + /** |
|
| 178 | + * _format_error |
|
| 179 | + * |
|
| 180 | + * @param $code |
|
| 181 | + * @param $message |
|
| 182 | + * @param $file |
|
| 183 | + * @param $line |
|
| 184 | + * @return string |
|
| 185 | + */ |
|
| 186 | + private static function _format_error($code, $message, $file, $line) |
|
| 187 | + { |
|
| 188 | + $html = "<table cellpadding='5'><thead bgcolor='#f8f8f8'><th>Item</th><th align='left'>Details</th></thead><tbody>"; |
|
| 189 | + $html .= "<tr valign='top'><td><b>Code</b></td><td>$code</td></tr>"; |
|
| 190 | + $html .= "<tr valign='top'><td><b>Error</b></td><td>$message</td></tr>"; |
|
| 191 | + $html .= "<tr valign='top'><td><b>File</b></td><td>$file</td></tr>"; |
|
| 192 | + $html .= "<tr valign='top'><td><b>Line</b></td><td>$line</td></tr>"; |
|
| 193 | + $html .= '</tbody></table>'; |
|
| 194 | + return $html; |
|
| 195 | + } |
|
| 196 | + |
|
| 197 | + |
|
| 198 | + |
|
| 199 | + /** |
|
| 200 | + * set_content_type |
|
| 201 | + * |
|
| 202 | + * @param $content_type |
|
| 203 | + * @return string |
|
| 204 | + */ |
|
| 205 | + public static function set_content_type($content_type) |
|
| 206 | + { |
|
| 207 | + return 'text/html'; |
|
| 208 | + } |
|
| 209 | + |
|
| 210 | + |
|
| 211 | + |
|
| 212 | + /** |
|
| 213 | + * @return void |
|
| 214 | + * @throws EE_Error |
|
| 215 | + * @throws ReflectionException |
|
| 216 | + */ |
|
| 217 | + public function get_error() |
|
| 218 | + { |
|
| 219 | + if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) { |
|
| 220 | + throw $this; |
|
| 221 | + } |
|
| 222 | + // get separate user and developer messages if they exist |
|
| 223 | + $msg = explode('||', $this->getMessage()); |
|
| 224 | + $user_msg = $msg[0]; |
|
| 225 | + $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0]; |
|
| 226 | + $msg = WP_DEBUG ? $dev_msg : $user_msg; |
|
| 227 | + // add details to _all_exceptions array |
|
| 228 | + $x_time = time(); |
|
| 229 | + self::$_all_exceptions[$x_time]['name'] = get_class($this); |
|
| 230 | + self::$_all_exceptions[$x_time]['file'] = $this->getFile(); |
|
| 231 | + self::$_all_exceptions[$x_time]['line'] = $this->getLine(); |
|
| 232 | + self::$_all_exceptions[$x_time]['msg'] = $msg; |
|
| 233 | + self::$_all_exceptions[$x_time]['code'] = $this->getCode(); |
|
| 234 | + self::$_all_exceptions[$x_time]['trace'] = $this->getTrace(); |
|
| 235 | + self::$_all_exceptions[$x_time]['string'] = $this->getTraceAsString(); |
|
| 236 | + self::$_error_count++; |
|
| 237 | + //add_action( 'shutdown', array( $this, 'display_errors' )); |
|
| 238 | + $this->display_errors(); |
|
| 239 | + } |
|
| 240 | + |
|
| 241 | + |
|
| 242 | + |
|
| 243 | + /** |
|
| 244 | + * has_error |
|
| 245 | + * |
|
| 246 | + * @param bool $check_stored |
|
| 247 | + * @param string $type_to_check |
|
| 248 | + * @return bool |
|
| 249 | + */ |
|
| 250 | + public static function has_error($check_stored = false, $type_to_check = 'errors') |
|
| 251 | + { |
|
| 252 | + $has_error = isset(self::$_espresso_notices[$type_to_check]) |
|
| 253 | + && ! empty(self::$_espresso_notices[$type_to_check]) |
|
| 254 | + ? true |
|
| 255 | + : false; |
|
| 256 | + if ($check_stored && ! $has_error) { |
|
| 257 | + $notices = (array)get_option('ee_notices', array()); |
|
| 258 | + foreach ($notices as $type => $notice) { |
|
| 259 | + if ($type === $type_to_check && $notice) { |
|
| 260 | + return true; |
|
| 261 | + } |
|
| 262 | + } |
|
| 263 | + } |
|
| 264 | + return $has_error; |
|
| 265 | + } |
|
| 266 | + |
|
| 267 | + |
|
| 268 | + |
|
| 269 | + /** |
|
| 270 | + * display_errors |
|
| 271 | + * |
|
| 272 | + * @echo string |
|
| 273 | + * @throws \ReflectionException |
|
| 274 | + */ |
|
| 275 | + public function display_errors() |
|
| 276 | + { |
|
| 277 | + $trace_details = ''; |
|
| 278 | + $output = ' |
|
| 279 | 279 | <style type="text/css"> |
| 280 | 280 | #ee-error-message { |
| 281 | 281 | max-width:90% !important; |
@@ -331,19 +331,19 @@ discard block |
||
| 331 | 331 | } |
| 332 | 332 | </style> |
| 333 | 333 | <div id="ee-error-message" class="error">'; |
| 334 | - if (! WP_DEBUG) { |
|
| 335 | - $output .= ' |
|
| 334 | + if (! WP_DEBUG) { |
|
| 335 | + $output .= ' |
|
| 336 | 336 | <p>'; |
| 337 | - } |
|
| 338 | - // cycle thru errors |
|
| 339 | - foreach (self::$_all_exceptions as $time => $ex) { |
|
| 340 | - $error_code = ''; |
|
| 341 | - // process trace info |
|
| 342 | - if (empty($ex['trace'])) { |
|
| 343 | - $trace_details .= __('Sorry, but no trace information was available for this exception.', |
|
| 344 | - 'event_espresso'); |
|
| 345 | - } else { |
|
| 346 | - $trace_details .= ' |
|
| 337 | + } |
|
| 338 | + // cycle thru errors |
|
| 339 | + foreach (self::$_all_exceptions as $time => $ex) { |
|
| 340 | + $error_code = ''; |
|
| 341 | + // process trace info |
|
| 342 | + if (empty($ex['trace'])) { |
|
| 343 | + $trace_details .= __('Sorry, but no trace information was available for this exception.', |
|
| 344 | + 'event_espresso'); |
|
| 345 | + } else { |
|
| 346 | + $trace_details .= ' |
|
| 347 | 347 | <div id="ee-trace-details"> |
| 348 | 348 | <table width="100%" border="0" cellpadding="5" cellspacing="0"> |
| 349 | 349 | <tr> |
@@ -353,43 +353,43 @@ discard block |
||
| 353 | 353 | <th scope="col" align="left">Class</th> |
| 354 | 354 | <th scope="col" align="left">Method( arguments )</th> |
| 355 | 355 | </tr>'; |
| 356 | - $last_on_stack = count($ex['trace']) - 1; |
|
| 357 | - // reverse array so that stack is in proper chronological order |
|
| 358 | - $sorted_trace = array_reverse($ex['trace']); |
|
| 359 | - foreach ($sorted_trace as $nmbr => $trace) { |
|
| 360 | - $file = isset($trace['file']) ? $trace['file'] : ''; |
|
| 361 | - $class = isset($trace['class']) ? $trace['class'] : ''; |
|
| 362 | - $type = isset($trace['type']) ? $trace['type'] : ''; |
|
| 363 | - $function = isset($trace['function']) ? $trace['function'] : ''; |
|
| 364 | - $args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : ''; |
|
| 365 | - $line = isset($trace['line']) ? $trace['line'] : ''; |
|
| 366 | - $zebra = ($nmbr % 2) ? ' odd' : ''; |
|
| 367 | - if (empty($file) && ! empty($class)) { |
|
| 368 | - $a = new ReflectionClass($class); |
|
| 369 | - $file = $a->getFileName(); |
|
| 370 | - if (empty($line) && ! empty($function)) { |
|
| 371 | - try { |
|
| 372 | - //if $function is a closure, this throws an exception |
|
| 373 | - $b = new ReflectionMethod($class, $function); |
|
| 374 | - $line = $b->getStartLine(); |
|
| 375 | - } catch (Exception $closure_exception) { |
|
| 376 | - $line = 'unknown'; |
|
| 377 | - } |
|
| 378 | - } |
|
| 379 | - } |
|
| 380 | - if ($nmbr === $last_on_stack) { |
|
| 381 | - $file = $ex['file'] !== '' ? $ex['file'] : $file; |
|
| 382 | - $line = $ex['line'] !== '' ? $ex['line'] : $line; |
|
| 383 | - $error_code = self::generate_error_code($file, $trace['function'], $line); |
|
| 384 | - } |
|
| 385 | - $nmbr_dsply = ! empty($nmbr) ? $nmbr : ' '; |
|
| 386 | - $line_dsply = ! empty($line) ? $line : ' '; |
|
| 387 | - $file_dsply = ! empty($file) ? $file : ' '; |
|
| 388 | - $class_dsply = ! empty($class) ? $class : ' '; |
|
| 389 | - $type_dsply = ! empty($type) ? $type : ' '; |
|
| 390 | - $function_dsply = ! empty($function) ? $function : ' '; |
|
| 391 | - $args_dsply = ! empty($args) ? '( ' . $args . ' )' : ''; |
|
| 392 | - $trace_details .= ' |
|
| 356 | + $last_on_stack = count($ex['trace']) - 1; |
|
| 357 | + // reverse array so that stack is in proper chronological order |
|
| 358 | + $sorted_trace = array_reverse($ex['trace']); |
|
| 359 | + foreach ($sorted_trace as $nmbr => $trace) { |
|
| 360 | + $file = isset($trace['file']) ? $trace['file'] : ''; |
|
| 361 | + $class = isset($trace['class']) ? $trace['class'] : ''; |
|
| 362 | + $type = isset($trace['type']) ? $trace['type'] : ''; |
|
| 363 | + $function = isset($trace['function']) ? $trace['function'] : ''; |
|
| 364 | + $args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : ''; |
|
| 365 | + $line = isset($trace['line']) ? $trace['line'] : ''; |
|
| 366 | + $zebra = ($nmbr % 2) ? ' odd' : ''; |
|
| 367 | + if (empty($file) && ! empty($class)) { |
|
| 368 | + $a = new ReflectionClass($class); |
|
| 369 | + $file = $a->getFileName(); |
|
| 370 | + if (empty($line) && ! empty($function)) { |
|
| 371 | + try { |
|
| 372 | + //if $function is a closure, this throws an exception |
|
| 373 | + $b = new ReflectionMethod($class, $function); |
|
| 374 | + $line = $b->getStartLine(); |
|
| 375 | + } catch (Exception $closure_exception) { |
|
| 376 | + $line = 'unknown'; |
|
| 377 | + } |
|
| 378 | + } |
|
| 379 | + } |
|
| 380 | + if ($nmbr === $last_on_stack) { |
|
| 381 | + $file = $ex['file'] !== '' ? $ex['file'] : $file; |
|
| 382 | + $line = $ex['line'] !== '' ? $ex['line'] : $line; |
|
| 383 | + $error_code = self::generate_error_code($file, $trace['function'], $line); |
|
| 384 | + } |
|
| 385 | + $nmbr_dsply = ! empty($nmbr) ? $nmbr : ' '; |
|
| 386 | + $line_dsply = ! empty($line) ? $line : ' '; |
|
| 387 | + $file_dsply = ! empty($file) ? $file : ' '; |
|
| 388 | + $class_dsply = ! empty($class) ? $class : ' '; |
|
| 389 | + $type_dsply = ! empty($type) ? $type : ' '; |
|
| 390 | + $function_dsply = ! empty($function) ? $function : ' '; |
|
| 391 | + $args_dsply = ! empty($args) ? '( ' . $args . ' )' : ''; |
|
| 392 | + $trace_details .= ' |
|
| 393 | 393 | <tr> |
| 394 | 394 | <td align="right" class="' . $zebra . '">' . $nmbr_dsply . '</td> |
| 395 | 395 | <td align="right" class="' . $zebra . '">' . $line_dsply . '</td> |
@@ -397,674 +397,674 @@ discard block |
||
| 397 | 397 | <td align="left" class="' . $zebra . '">' . $class_dsply . '</td> |
| 398 | 398 | <td align="left" class="' . $zebra . '">' . $type_dsply . $function_dsply . $args_dsply . '</td> |
| 399 | 399 | </tr>'; |
| 400 | - } |
|
| 401 | - $trace_details .= ' |
|
| 400 | + } |
|
| 401 | + $trace_details .= ' |
|
| 402 | 402 | </table> |
| 403 | 403 | </div>'; |
| 404 | - } |
|
| 405 | - $ex['code'] = $ex['code'] ? $ex['code'] : $error_code; |
|
| 406 | - // add generic non-identifying messages for non-privileged users |
|
| 407 | - if (! WP_DEBUG) { |
|
| 408 | - $output .= '<span class="ee-error-user-msg-spn">' |
|
| 409 | - . trim($ex['msg']) |
|
| 410 | - . '</span> <sup>' |
|
| 411 | - . $ex['code'] |
|
| 412 | - . '</sup><br />'; |
|
| 413 | - } else { |
|
| 414 | - // or helpful developer messages if debugging is on |
|
| 415 | - $output .= ' |
|
| 404 | + } |
|
| 405 | + $ex['code'] = $ex['code'] ? $ex['code'] : $error_code; |
|
| 406 | + // add generic non-identifying messages for non-privileged users |
|
| 407 | + if (! WP_DEBUG) { |
|
| 408 | + $output .= '<span class="ee-error-user-msg-spn">' |
|
| 409 | + . trim($ex['msg']) |
|
| 410 | + . '</span> <sup>' |
|
| 411 | + . $ex['code'] |
|
| 412 | + . '</sup><br />'; |
|
| 413 | + } else { |
|
| 414 | + // or helpful developer messages if debugging is on |
|
| 415 | + $output .= ' |
|
| 416 | 416 | <div class="ee-error-dev-msg-dv"> |
| 417 | 417 | <p class="ee-error-dev-msg-pg"> |
| 418 | 418 | <strong class="ee-error-dev-msg-str">An ' |
| 419 | - . $ex['name'] |
|
| 420 | - . ' exception was thrown!</strong> <span>code: ' |
|
| 421 | - . $ex['code'] |
|
| 422 | - . '</span><br /> |
|
| 419 | + . $ex['name'] |
|
| 420 | + . ' exception was thrown!</strong> <span>code: ' |
|
| 421 | + . $ex['code'] |
|
| 422 | + . '</span><br /> |
|
| 423 | 423 | <span class="big-text">"' |
| 424 | - . trim($ex['msg']) |
|
| 425 | - . '"</span><br/> |
|
| 424 | + . trim($ex['msg']) |
|
| 425 | + . '"</span><br/> |
|
| 426 | 426 | <a id="display-ee-error-trace-' |
| 427 | - . self::$_error_count |
|
| 428 | - . $time |
|
| 429 | - . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-' |
|
| 430 | - . self::$_error_count |
|
| 431 | - . $time |
|
| 432 | - . '"> |
|
| 427 | + . self::$_error_count |
|
| 428 | + . $time |
|
| 429 | + . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-' |
|
| 430 | + . self::$_error_count |
|
| 431 | + . $time |
|
| 432 | + . '"> |
|
| 433 | 433 | ' |
| 434 | - . __('click to view backtrace and class/method details', 'event_espresso') |
|
| 435 | - . ' |
|
| 434 | + . __('click to view backtrace and class/method details', 'event_espresso') |
|
| 435 | + . ' |
|
| 436 | 436 | </a><br /> |
| 437 | 437 | <span class="small-text lt-grey-text">' |
| 438 | - . $ex['file'] |
|
| 439 | - . ' ( line no: ' |
|
| 440 | - . $ex['line'] |
|
| 441 | - . ' )</span> |
|
| 438 | + . $ex['file'] |
|
| 439 | + . ' ( line no: ' |
|
| 440 | + . $ex['line'] |
|
| 441 | + . ' )</span> |
|
| 442 | 442 | </p> |
| 443 | 443 | <div id="ee-error-trace-' |
| 444 | - . self::$_error_count |
|
| 445 | - . $time |
|
| 446 | - . '-dv" class="ee-error-trace-dv" style="display: none;"> |
|
| 444 | + . self::$_error_count |
|
| 445 | + . $time |
|
| 446 | + . '-dv" class="ee-error-trace-dv" style="display: none;"> |
|
| 447 | 447 | ' |
| 448 | - . $trace_details; |
|
| 449 | - if (! empty($class)) { |
|
| 450 | - $output .= ' |
|
| 448 | + . $trace_details; |
|
| 449 | + if (! empty($class)) { |
|
| 450 | + $output .= ' |
|
| 451 | 451 | <div style="padding:3px; margin:0 0 1em; border:1px solid #666; background:#fff; border-radius:3px;"> |
| 452 | 452 | <div style="padding:1em 2em; border:1px solid #666; background:#f9f9f9;"> |
| 453 | 453 | <h3>Class Details</h3>'; |
| 454 | - $a = new ReflectionClass($class); |
|
| 455 | - $output .= ' |
|
| 454 | + $a = new ReflectionClass($class); |
|
| 455 | + $output .= ' |
|
| 456 | 456 | <pre>' . $a . '</pre> |
| 457 | 457 | </div> |
| 458 | 458 | </div>'; |
| 459 | - } |
|
| 460 | - $output .= ' |
|
| 459 | + } |
|
| 460 | + $output .= ' |
|
| 461 | 461 | </div> |
| 462 | 462 | </div> |
| 463 | 463 | <br />'; |
| 464 | - } |
|
| 465 | - $this->write_to_error_log($time, $ex); |
|
| 466 | - } |
|
| 467 | - // remove last linebreak |
|
| 468 | - $output = substr($output, 0, -6); |
|
| 469 | - if (! WP_DEBUG) { |
|
| 470 | - $output .= ' |
|
| 464 | + } |
|
| 465 | + $this->write_to_error_log($time, $ex); |
|
| 466 | + } |
|
| 467 | + // remove last linebreak |
|
| 468 | + $output = substr($output, 0, -6); |
|
| 469 | + if (! WP_DEBUG) { |
|
| 470 | + $output .= ' |
|
| 471 | 471 | </p>'; |
| 472 | - } |
|
| 473 | - $output .= ' |
|
| 472 | + } |
|
| 473 | + $output .= ' |
|
| 474 | 474 | </div>'; |
| 475 | - $output .= self::_print_scripts(true); |
|
| 476 | - if (defined('DOING_AJAX')) { |
|
| 477 | - echo wp_json_encode(array('error' => $output)); |
|
| 478 | - exit(); |
|
| 479 | - } |
|
| 480 | - echo $output; |
|
| 481 | - die(); |
|
| 482 | - } |
|
| 483 | - |
|
| 484 | - |
|
| 485 | - |
|
| 486 | - /** |
|
| 487 | - * generate string from exception trace args |
|
| 488 | - * |
|
| 489 | - * @param array $arguments |
|
| 490 | - * @param bool $array |
|
| 491 | - * @return string |
|
| 492 | - */ |
|
| 493 | - private function _convert_args_to_string($arguments = array(), $array = false) |
|
| 494 | - { |
|
| 495 | - $arg_string = ''; |
|
| 496 | - if (! empty($arguments)) { |
|
| 497 | - $args = array(); |
|
| 498 | - foreach ($arguments as $arg) { |
|
| 499 | - if (! empty($arg)) { |
|
| 500 | - if (is_string($arg)) { |
|
| 501 | - $args[] = " '" . $arg . "'"; |
|
| 502 | - } elseif (is_array($arg)) { |
|
| 503 | - $args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true); |
|
| 504 | - } elseif ($arg === null) { |
|
| 505 | - $args[] = ' NULL'; |
|
| 506 | - } elseif (is_bool($arg)) { |
|
| 507 | - $args[] = ($arg) ? ' TRUE' : ' FALSE'; |
|
| 508 | - } elseif (is_object($arg)) { |
|
| 509 | - $args[] = ' OBJECT ' . get_class($arg); |
|
| 510 | - } elseif (is_resource($arg)) { |
|
| 511 | - $args[] = get_resource_type($arg); |
|
| 512 | - } else { |
|
| 513 | - $args[] = $arg; |
|
| 514 | - } |
|
| 515 | - } |
|
| 516 | - } |
|
| 517 | - $arg_string = implode(', ', $args); |
|
| 518 | - } |
|
| 519 | - if ($array) { |
|
| 520 | - $arg_string .= ' )'; |
|
| 521 | - } |
|
| 522 | - return $arg_string; |
|
| 523 | - } |
|
| 524 | - |
|
| 525 | - |
|
| 526 | - |
|
| 527 | - /** |
|
| 528 | - * add error message |
|
| 529 | - * |
|
| 530 | - * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 531 | - * separate messages for user || dev |
|
| 532 | - * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 533 | - * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 534 | - * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 535 | - * @return void |
|
| 536 | - */ |
|
| 537 | - public static function add_error($msg = null, $file = null, $func = null, $line = null) |
|
| 538 | - { |
|
| 539 | - self::_add_notice('errors', $msg, $file, $func, $line); |
|
| 540 | - self::$_error_count++; |
|
| 541 | - } |
|
| 542 | - |
|
| 543 | - |
|
| 544 | - |
|
| 545 | - /** |
|
| 546 | - * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just |
|
| 547 | - * adds an error |
|
| 548 | - * |
|
| 549 | - * @param string $msg |
|
| 550 | - * @param string $file |
|
| 551 | - * @param string $func |
|
| 552 | - * @param string $line |
|
| 553 | - * @throws EE_Error |
|
| 554 | - */ |
|
| 555 | - public static function throw_exception_if_debugging($msg = null, $file = null, $func = null, $line = null) |
|
| 556 | - { |
|
| 557 | - if (WP_DEBUG) { |
|
| 558 | - throw new EE_Error($msg); |
|
| 559 | - } |
|
| 560 | - EE_Error::add_error($msg, $file, $func, $line); |
|
| 561 | - } |
|
| 562 | - |
|
| 563 | - |
|
| 564 | - |
|
| 565 | - /** |
|
| 566 | - * add success message |
|
| 567 | - * |
|
| 568 | - * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 569 | - * separate messages for user || dev |
|
| 570 | - * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 571 | - * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 572 | - * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 573 | - * @return void |
|
| 574 | - */ |
|
| 575 | - public static function add_success($msg = null, $file = null, $func = null, $line = null) |
|
| 576 | - { |
|
| 577 | - self::_add_notice('success', $msg, $file, $func, $line); |
|
| 578 | - } |
|
| 579 | - |
|
| 580 | - |
|
| 581 | - |
|
| 582 | - /** |
|
| 583 | - * add attention message |
|
| 584 | - * |
|
| 585 | - * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 586 | - * separate messages for user || dev |
|
| 587 | - * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 588 | - * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 589 | - * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 590 | - * @return void |
|
| 591 | - */ |
|
| 592 | - public static function add_attention($msg = null, $file = null, $func = null, $line = null) |
|
| 593 | - { |
|
| 594 | - self::_add_notice('attention', $msg, $file, $func, $line); |
|
| 595 | - } |
|
| 596 | - |
|
| 597 | - |
|
| 598 | - |
|
| 599 | - /** |
|
| 600 | - * add success message |
|
| 601 | - * |
|
| 602 | - * @param string $type whether the message is for a success or error notification |
|
| 603 | - * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 604 | - * separate messages for user || dev |
|
| 605 | - * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 606 | - * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 607 | - * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 608 | - * @return void |
|
| 609 | - */ |
|
| 610 | - private static function _add_notice($type = 'success', $msg = null, $file = null, $func = null, $line = null) |
|
| 611 | - { |
|
| 612 | - if (empty($msg)) { |
|
| 613 | - EE_Error::doing_it_wrong( |
|
| 614 | - 'EE_Error::add_' . $type . '()', |
|
| 615 | - sprintf( |
|
| 616 | - __('Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d', |
|
| 617 | - 'event_espresso'), |
|
| 618 | - $type, |
|
| 619 | - $file, |
|
| 620 | - $line |
|
| 621 | - ), |
|
| 622 | - EVENT_ESPRESSO_VERSION |
|
| 623 | - ); |
|
| 624 | - } |
|
| 625 | - if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) { |
|
| 626 | - EE_Error::doing_it_wrong( |
|
| 627 | - 'EE_Error::add_error()', |
|
| 628 | - __('You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.', |
|
| 629 | - 'event_espresso'), |
|
| 630 | - EVENT_ESPRESSO_VERSION |
|
| 631 | - ); |
|
| 632 | - } |
|
| 633 | - // get separate user and developer messages if they exist |
|
| 634 | - $msg = explode('||', $msg); |
|
| 635 | - $user_msg = $msg[0]; |
|
| 636 | - $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0]; |
|
| 637 | - /** |
|
| 638 | - * Do an action so other code can be triggered when a notice is created |
|
| 639 | - * |
|
| 640 | - * @param string $type can be 'errors', 'attention', or 'success' |
|
| 641 | - * @param string $user_msg message displayed to user when WP_DEBUG is off |
|
| 642 | - * @param string $user_msg message displayed to user when WP_DEBUG is on |
|
| 643 | - * @param string $file file where error was generated |
|
| 644 | - * @param string $func function where error was generated |
|
| 645 | - * @param string $line line where error was generated |
|
| 646 | - */ |
|
| 647 | - do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line); |
|
| 648 | - $msg = WP_DEBUG ? $dev_msg : $user_msg; |
|
| 649 | - // add notice if message exists |
|
| 650 | - if (! empty($msg)) { |
|
| 651 | - // get error code |
|
| 652 | - $notice_code = EE_Error::generate_error_code($file, $func, $line); |
|
| 653 | - if (WP_DEBUG && $type === 'errors') { |
|
| 654 | - $msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>'; |
|
| 655 | - } |
|
| 656 | - // add notice. Index by code if it's not blank |
|
| 657 | - if ($notice_code) { |
|
| 658 | - self::$_espresso_notices[$type][$notice_code] = $msg; |
|
| 659 | - } else { |
|
| 660 | - self::$_espresso_notices[$type][] = $msg; |
|
| 661 | - } |
|
| 662 | - add_action('wp_footer', array('EE_Error', 'enqueue_error_scripts'), 1); |
|
| 663 | - } |
|
| 664 | - } |
|
| 665 | - |
|
| 666 | - |
|
| 667 | - |
|
| 668 | - /** |
|
| 669 | - * in some case it may be necessary to overwrite the existing success messages |
|
| 670 | - * |
|
| 671 | - * @return void |
|
| 672 | - */ |
|
| 673 | - public static function overwrite_success() |
|
| 674 | - { |
|
| 675 | - self::$_espresso_notices['success'] = false; |
|
| 676 | - } |
|
| 677 | - |
|
| 678 | - |
|
| 679 | - |
|
| 680 | - /** |
|
| 681 | - * in some case it may be necessary to overwrite the existing attention messages |
|
| 682 | - * |
|
| 683 | - * @return void |
|
| 684 | - */ |
|
| 685 | - public static function overwrite_attention() |
|
| 686 | - { |
|
| 687 | - self::$_espresso_notices['attention'] = false; |
|
| 688 | - } |
|
| 689 | - |
|
| 690 | - |
|
| 691 | - |
|
| 692 | - /** |
|
| 693 | - * in some case it may be necessary to overwrite the existing error messages |
|
| 694 | - * |
|
| 695 | - * @return void |
|
| 696 | - */ |
|
| 697 | - public static function overwrite_errors() |
|
| 698 | - { |
|
| 699 | - self::$_espresso_notices['errors'] = false; |
|
| 700 | - } |
|
| 701 | - |
|
| 702 | - |
|
| 703 | - |
|
| 704 | - /** |
|
| 705 | - * reset_notices |
|
| 706 | - * |
|
| 707 | - * @return void |
|
| 708 | - */ |
|
| 709 | - public static function reset_notices() |
|
| 710 | - { |
|
| 711 | - self::$_espresso_notices['success'] = false; |
|
| 712 | - self::$_espresso_notices['attention'] = false; |
|
| 713 | - self::$_espresso_notices['errors'] = false; |
|
| 714 | - } |
|
| 715 | - |
|
| 716 | - |
|
| 717 | - |
|
| 718 | - /** |
|
| 719 | - * has_errors |
|
| 720 | - * |
|
| 721 | - * @return int |
|
| 722 | - */ |
|
| 723 | - public static function has_notices() |
|
| 724 | - { |
|
| 725 | - $has_notices = 0; |
|
| 726 | - // check for success messages |
|
| 727 | - $has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success']) ? 3 |
|
| 728 | - : $has_notices; |
|
| 729 | - // check for attention messages |
|
| 730 | - $has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention']) ? 2 |
|
| 731 | - : $has_notices; |
|
| 732 | - // check for error messages |
|
| 733 | - $has_notices = self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors']) ? 1 |
|
| 734 | - : $has_notices; |
|
| 735 | - return $has_notices; |
|
| 736 | - } |
|
| 737 | - |
|
| 738 | - |
|
| 739 | - |
|
| 740 | - /** |
|
| 741 | - * This simply returns non formatted error notices as they were sent into the EE_Error object. |
|
| 742 | - * |
|
| 743 | - * @since 4.9.0 |
|
| 744 | - * @return array |
|
| 745 | - */ |
|
| 746 | - public static function get_vanilla_notices() |
|
| 747 | - { |
|
| 748 | - return array( |
|
| 749 | - 'success' => isset(self::$_espresso_notices['success']) ? self::$_espresso_notices['success'] : array(), |
|
| 750 | - 'attention' => isset(self::$_espresso_notices['attention']) ? self::$_espresso_notices['attention'] |
|
| 751 | - : array(), |
|
| 752 | - 'errors' => isset(self::$_espresso_notices['errors']) ? self::$_espresso_notices['errors'] : array(), |
|
| 753 | - ); |
|
| 754 | - } |
|
| 755 | - |
|
| 756 | - |
|
| 757 | - |
|
| 758 | - /** |
|
| 759 | - * compile all error or success messages into one string |
|
| 760 | - * |
|
| 761 | - * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them |
|
| 762 | - * @param boolean $format_output whether or not to format the messages for display in the WP admin |
|
| 763 | - * @param boolean $save_to_transient whether or not to save notices to the db for retrieval on next request |
|
| 764 | - * - ONLY do this just before redirecting |
|
| 765 | - * @param boolean $remove_empty whether or not to unset empty messages |
|
| 766 | - * @return array |
|
| 767 | - */ |
|
| 768 | - public static function get_notices($format_output = true, $save_to_transient = false, $remove_empty = true) |
|
| 769 | - { |
|
| 770 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 771 | - $success_messages = ''; |
|
| 772 | - $attention_messages = ''; |
|
| 773 | - $error_messages = ''; |
|
| 774 | - $print_scripts = false; |
|
| 775 | - // either save notices to the db |
|
| 776 | - if ($save_to_transient) { |
|
| 777 | - update_option('ee_notices', self::$_espresso_notices); |
|
| 778 | - return array(); |
|
| 779 | - } |
|
| 780 | - // grab any notices that have been previously saved |
|
| 781 | - if ($notices = get_option('ee_notices', false)) { |
|
| 782 | - foreach ($notices as $type => $notice) { |
|
| 783 | - if (is_array($notice) && ! empty($notice)) { |
|
| 784 | - // make sure that existing notice type is an array |
|
| 785 | - self::$_espresso_notices[$type] = is_array(self::$_espresso_notices[$type]) |
|
| 786 | - && ! empty(self::$_espresso_notices[$type]) |
|
| 787 | - ? self::$_espresso_notices[$type] : array(); |
|
| 788 | - // merge stored notices with any newly created ones |
|
| 789 | - self::$_espresso_notices[$type] = array_merge(self::$_espresso_notices[$type], $notice); |
|
| 790 | - $print_scripts = true; |
|
| 791 | - } |
|
| 792 | - } |
|
| 793 | - // now clear any stored notices |
|
| 794 | - update_option('ee_notices', false); |
|
| 795 | - } |
|
| 796 | - // check for success messages |
|
| 797 | - if (self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])) { |
|
| 798 | - // combine messages |
|
| 799 | - $success_messages .= implode(self::$_espresso_notices['success'], '<br /><br />'); |
|
| 800 | - $print_scripts = true; |
|
| 801 | - } |
|
| 802 | - // check for attention messages |
|
| 803 | - if (self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])) { |
|
| 804 | - // combine messages |
|
| 805 | - $attention_messages .= implode(self::$_espresso_notices['attention'], '<br /><br />'); |
|
| 806 | - $print_scripts = true; |
|
| 807 | - } |
|
| 808 | - // check for error messages |
|
| 809 | - if (self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])) { |
|
| 810 | - $error_messages .= count(self::$_espresso_notices['errors']) > 1 |
|
| 811 | - ? __('The following errors have occurred:<br />', 'event_espresso') |
|
| 812 | - : __('An error has occurred:<br />', 'event_espresso'); |
|
| 813 | - // combine messages |
|
| 814 | - $error_messages .= implode(self::$_espresso_notices['errors'], '<br /><br />'); |
|
| 815 | - $print_scripts = true; |
|
| 816 | - } |
|
| 817 | - if ($format_output) { |
|
| 818 | - $notices = '<div id="espresso-notices">'; |
|
| 819 | - $close = is_admin() ? '' |
|
| 820 | - : '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"></span></a>'; |
|
| 821 | - if ($success_messages !== '') { |
|
| 822 | - $css_id = is_admin() ? 'message' : 'espresso-notices-success'; |
|
| 823 | - $css_class = is_admin() ? 'updated fade' : 'success fade-away'; |
|
| 824 | - //showMessage( $success_messages ); |
|
| 825 | - $notices .= '<div id="' |
|
| 826 | - . $css_id |
|
| 827 | - . '" class="espresso-notices ' |
|
| 828 | - . $css_class |
|
| 829 | - . '" style="display:none;"><p>' |
|
| 830 | - . $success_messages |
|
| 831 | - . '</p>' |
|
| 832 | - . $close |
|
| 833 | - . '</div>'; |
|
| 834 | - } |
|
| 835 | - if ($attention_messages !== '') { |
|
| 836 | - $css_id = is_admin() ? 'message' : 'espresso-notices-attention'; |
|
| 837 | - $css_class = is_admin() ? 'updated ee-notices-attention' : 'attention fade-away'; |
|
| 838 | - //showMessage( $error_messages, TRUE ); |
|
| 839 | - $notices .= '<div id="' |
|
| 840 | - . $css_id |
|
| 841 | - . '" class="espresso-notices ' |
|
| 842 | - . $css_class |
|
| 843 | - . '" style="display:none;"><p>' |
|
| 844 | - . $attention_messages |
|
| 845 | - . '</p>' |
|
| 846 | - . $close |
|
| 847 | - . '</div>'; |
|
| 848 | - } |
|
| 849 | - if ($error_messages !== '') { |
|
| 850 | - $css_id = is_admin() ? 'message' : 'espresso-notices-error'; |
|
| 851 | - $css_class = is_admin() ? 'error' : 'error fade-away'; |
|
| 852 | - //showMessage( $error_messages, TRUE ); |
|
| 853 | - $notices .= '<div id="' |
|
| 854 | - . $css_id |
|
| 855 | - . '" class="espresso-notices ' |
|
| 856 | - . $css_class |
|
| 857 | - . '" style="display:none;"><p>' |
|
| 858 | - . $error_messages |
|
| 859 | - . '</p>' |
|
| 860 | - . $close |
|
| 861 | - . '</div>'; |
|
| 862 | - } |
|
| 863 | - $notices .= '</div>'; |
|
| 864 | - } else { |
|
| 865 | - $notices = array( |
|
| 866 | - 'success' => $success_messages, |
|
| 867 | - 'attention' => $attention_messages, |
|
| 868 | - 'errors' => $error_messages, |
|
| 869 | - ); |
|
| 870 | - if ($remove_empty) { |
|
| 871 | - // remove empty notices |
|
| 872 | - foreach ($notices as $type => $notice) { |
|
| 873 | - if (empty($notice)) { |
|
| 874 | - unset($notices[$type]); |
|
| 875 | - } |
|
| 876 | - } |
|
| 877 | - } |
|
| 878 | - } |
|
| 879 | - if ($print_scripts) { |
|
| 880 | - self::_print_scripts(); |
|
| 881 | - } |
|
| 882 | - return $notices; |
|
| 883 | - } |
|
| 884 | - |
|
| 885 | - |
|
| 886 | - |
|
| 887 | - /** |
|
| 888 | - * add_persistent_admin_notice |
|
| 889 | - * |
|
| 890 | - * @param string $pan_name the name, or key of the Persistent Admin Notice to be stored |
|
| 891 | - * @param string $pan_message the message to be stored persistently until dismissed |
|
| 892 | - * @param bool $force_update allows one to enforce the reappearance of a persistent message. |
|
| 893 | - * @return void |
|
| 894 | - */ |
|
| 895 | - public static function add_persistent_admin_notice($pan_name = '', $pan_message, $force_update = false) |
|
| 896 | - { |
|
| 897 | - if (! empty($pan_name) && ! empty($pan_message)) { |
|
| 898 | - $persistent_admin_notices = get_option('ee_pers_admin_notices', array()); |
|
| 899 | - //maybe initialize persistent_admin_notices |
|
| 900 | - if (empty($persistent_admin_notices)) { |
|
| 901 | - add_option('ee_pers_admin_notices', array(), '', 'no'); |
|
| 902 | - } |
|
| 903 | - $pan_name = sanitize_key($pan_name); |
|
| 904 | - if (! array_key_exists($pan_name, $persistent_admin_notices) || $force_update) { |
|
| 905 | - $persistent_admin_notices[$pan_name] = $pan_message; |
|
| 906 | - update_option('ee_pers_admin_notices', $persistent_admin_notices); |
|
| 907 | - } |
|
| 908 | - } |
|
| 909 | - } |
|
| 910 | - |
|
| 911 | - |
|
| 912 | - |
|
| 913 | - /** |
|
| 914 | - * dismiss_persistent_admin_notice |
|
| 915 | - * |
|
| 916 | - * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed |
|
| 917 | - * @param bool $purge |
|
| 918 | - * @param bool $return_immediately |
|
| 919 | - * @return void |
|
| 920 | - */ |
|
| 921 | - public static function dismiss_persistent_admin_notice($pan_name = '', $purge = false, $return_immediately = false) |
|
| 922 | - { |
|
| 923 | - $pan_name = EE_Registry::instance()->REQ->is_set('ee_nag_notice') |
|
| 924 | - ? EE_Registry::instance()->REQ->get('ee_nag_notice') : $pan_name; |
|
| 925 | - if (! empty($pan_name)) { |
|
| 926 | - $persistent_admin_notices = get_option('ee_pers_admin_notices', array()); |
|
| 927 | - // check if notice we wish to dismiss is actually in the $persistent_admin_notices array |
|
| 928 | - if (is_array($persistent_admin_notices) && isset($persistent_admin_notices[$pan_name])) { |
|
| 929 | - // completely delete nag notice, or just NULL message so that it can NOT be added again ? |
|
| 930 | - if ($purge) { |
|
| 931 | - unset($persistent_admin_notices[$pan_name]); |
|
| 932 | - } else { |
|
| 933 | - $persistent_admin_notices[$pan_name] = null; |
|
| 934 | - } |
|
| 935 | - if (update_option('ee_pers_admin_notices', $persistent_admin_notices) === false) { |
|
| 936 | - EE_Error::add_error(sprintf(__('The persistent admin notice for "%s" could not be deleted.', |
|
| 937 | - 'event_espresso'), $pan_name), __FILE__, __FUNCTION__, __LINE__); |
|
| 938 | - } |
|
| 939 | - } |
|
| 940 | - } |
|
| 941 | - if ($return_immediately) { |
|
| 942 | - return; |
|
| 943 | - } |
|
| 944 | - if (EE_Registry::instance()->REQ->ajax) { |
|
| 945 | - // grab any notices and concatenate into string |
|
| 946 | - echo wp_json_encode(array('errors' => implode('<br />', EE_Error::get_notices(false)))); |
|
| 947 | - exit(); |
|
| 948 | - } |
|
| 949 | - // save errors to a transient to be displayed on next request (after redirect) |
|
| 950 | - EE_Error::get_notices(false, true); |
|
| 951 | - $return_url = EE_Registry::instance()->REQ->is_set('return_url') |
|
| 952 | - ? EE_Registry::instance()->REQ->get('return_url') : ''; |
|
| 953 | - wp_safe_redirect(urldecode($return_url)); |
|
| 954 | - } |
|
| 955 | - |
|
| 956 | - |
|
| 957 | - |
|
| 958 | - /** |
|
| 959 | - * display_persistent_admin_notices |
|
| 960 | - * |
|
| 961 | - * @param string $pan_name the name, or key of the Persistent Admin Notice to be stored |
|
| 962 | - * @param string $pan_message the message to be stored persistently until dismissed |
|
| 963 | - * @param string $return_url URL to go back to after nag notice is dismissed |
|
| 964 | - * @return string |
|
| 965 | - */ |
|
| 966 | - public static function display_persistent_admin_notices($pan_name = '', $pan_message = '', $return_url = '') |
|
| 967 | - { |
|
| 968 | - if (! empty($pan_name) && ! empty($pan_message)) { |
|
| 969 | - $args = array( |
|
| 970 | - 'nag_notice' => $pan_name, |
|
| 971 | - 'return_url' => urlencode($return_url), |
|
| 972 | - 'ajax_url' => WP_AJAX_URL, |
|
| 973 | - 'unknown_error' => esc_html__( |
|
| 974 | - 'An unknown error has occurred on the server while attempting to dismiss this notice.', |
|
| 975 | - 'event_espresso' |
|
| 976 | - ), |
|
| 977 | - ); |
|
| 978 | - EE_Registry::$i18n_js_strings = array_merge( |
|
| 979 | - EE_Registry::$i18n_js_strings, |
|
| 980 | - array('ee_dismiss' => $args) |
|
| 981 | - ); |
|
| 982 | - return ' |
|
| 475 | + $output .= self::_print_scripts(true); |
|
| 476 | + if (defined('DOING_AJAX')) { |
|
| 477 | + echo wp_json_encode(array('error' => $output)); |
|
| 478 | + exit(); |
|
| 479 | + } |
|
| 480 | + echo $output; |
|
| 481 | + die(); |
|
| 482 | + } |
|
| 483 | + |
|
| 484 | + |
|
| 485 | + |
|
| 486 | + /** |
|
| 487 | + * generate string from exception trace args |
|
| 488 | + * |
|
| 489 | + * @param array $arguments |
|
| 490 | + * @param bool $array |
|
| 491 | + * @return string |
|
| 492 | + */ |
|
| 493 | + private function _convert_args_to_string($arguments = array(), $array = false) |
|
| 494 | + { |
|
| 495 | + $arg_string = ''; |
|
| 496 | + if (! empty($arguments)) { |
|
| 497 | + $args = array(); |
|
| 498 | + foreach ($arguments as $arg) { |
|
| 499 | + if (! empty($arg)) { |
|
| 500 | + if (is_string($arg)) { |
|
| 501 | + $args[] = " '" . $arg . "'"; |
|
| 502 | + } elseif (is_array($arg)) { |
|
| 503 | + $args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true); |
|
| 504 | + } elseif ($arg === null) { |
|
| 505 | + $args[] = ' NULL'; |
|
| 506 | + } elseif (is_bool($arg)) { |
|
| 507 | + $args[] = ($arg) ? ' TRUE' : ' FALSE'; |
|
| 508 | + } elseif (is_object($arg)) { |
|
| 509 | + $args[] = ' OBJECT ' . get_class($arg); |
|
| 510 | + } elseif (is_resource($arg)) { |
|
| 511 | + $args[] = get_resource_type($arg); |
|
| 512 | + } else { |
|
| 513 | + $args[] = $arg; |
|
| 514 | + } |
|
| 515 | + } |
|
| 516 | + } |
|
| 517 | + $arg_string = implode(', ', $args); |
|
| 518 | + } |
|
| 519 | + if ($array) { |
|
| 520 | + $arg_string .= ' )'; |
|
| 521 | + } |
|
| 522 | + return $arg_string; |
|
| 523 | + } |
|
| 524 | + |
|
| 525 | + |
|
| 526 | + |
|
| 527 | + /** |
|
| 528 | + * add error message |
|
| 529 | + * |
|
| 530 | + * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 531 | + * separate messages for user || dev |
|
| 532 | + * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 533 | + * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 534 | + * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 535 | + * @return void |
|
| 536 | + */ |
|
| 537 | + public static function add_error($msg = null, $file = null, $func = null, $line = null) |
|
| 538 | + { |
|
| 539 | + self::_add_notice('errors', $msg, $file, $func, $line); |
|
| 540 | + self::$_error_count++; |
|
| 541 | + } |
|
| 542 | + |
|
| 543 | + |
|
| 544 | + |
|
| 545 | + /** |
|
| 546 | + * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just |
|
| 547 | + * adds an error |
|
| 548 | + * |
|
| 549 | + * @param string $msg |
|
| 550 | + * @param string $file |
|
| 551 | + * @param string $func |
|
| 552 | + * @param string $line |
|
| 553 | + * @throws EE_Error |
|
| 554 | + */ |
|
| 555 | + public static function throw_exception_if_debugging($msg = null, $file = null, $func = null, $line = null) |
|
| 556 | + { |
|
| 557 | + if (WP_DEBUG) { |
|
| 558 | + throw new EE_Error($msg); |
|
| 559 | + } |
|
| 560 | + EE_Error::add_error($msg, $file, $func, $line); |
|
| 561 | + } |
|
| 562 | + |
|
| 563 | + |
|
| 564 | + |
|
| 565 | + /** |
|
| 566 | + * add success message |
|
| 567 | + * |
|
| 568 | + * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 569 | + * separate messages for user || dev |
|
| 570 | + * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 571 | + * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 572 | + * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 573 | + * @return void |
|
| 574 | + */ |
|
| 575 | + public static function add_success($msg = null, $file = null, $func = null, $line = null) |
|
| 576 | + { |
|
| 577 | + self::_add_notice('success', $msg, $file, $func, $line); |
|
| 578 | + } |
|
| 579 | + |
|
| 580 | + |
|
| 581 | + |
|
| 582 | + /** |
|
| 583 | + * add attention message |
|
| 584 | + * |
|
| 585 | + * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 586 | + * separate messages for user || dev |
|
| 587 | + * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 588 | + * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 589 | + * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 590 | + * @return void |
|
| 591 | + */ |
|
| 592 | + public static function add_attention($msg = null, $file = null, $func = null, $line = null) |
|
| 593 | + { |
|
| 594 | + self::_add_notice('attention', $msg, $file, $func, $line); |
|
| 595 | + } |
|
| 596 | + |
|
| 597 | + |
|
| 598 | + |
|
| 599 | + /** |
|
| 600 | + * add success message |
|
| 601 | + * |
|
| 602 | + * @param string $type whether the message is for a success or error notification |
|
| 603 | + * @param string $msg the message to display to users or developers - adding a double pipe || (OR) creates |
|
| 604 | + * separate messages for user || dev |
|
| 605 | + * @param string $file the file that the error occurred in - just use __FILE__ |
|
| 606 | + * @param string $func the function/method that the error occurred in - just use __FUNCTION__ |
|
| 607 | + * @param string $line the line number where the error occurred - just use __LINE__ |
|
| 608 | + * @return void |
|
| 609 | + */ |
|
| 610 | + private static function _add_notice($type = 'success', $msg = null, $file = null, $func = null, $line = null) |
|
| 611 | + { |
|
| 612 | + if (empty($msg)) { |
|
| 613 | + EE_Error::doing_it_wrong( |
|
| 614 | + 'EE_Error::add_' . $type . '()', |
|
| 615 | + sprintf( |
|
| 616 | + __('Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d', |
|
| 617 | + 'event_espresso'), |
|
| 618 | + $type, |
|
| 619 | + $file, |
|
| 620 | + $line |
|
| 621 | + ), |
|
| 622 | + EVENT_ESPRESSO_VERSION |
|
| 623 | + ); |
|
| 624 | + } |
|
| 625 | + if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) { |
|
| 626 | + EE_Error::doing_it_wrong( |
|
| 627 | + 'EE_Error::add_error()', |
|
| 628 | + __('You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.', |
|
| 629 | + 'event_espresso'), |
|
| 630 | + EVENT_ESPRESSO_VERSION |
|
| 631 | + ); |
|
| 632 | + } |
|
| 633 | + // get separate user and developer messages if they exist |
|
| 634 | + $msg = explode('||', $msg); |
|
| 635 | + $user_msg = $msg[0]; |
|
| 636 | + $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0]; |
|
| 637 | + /** |
|
| 638 | + * Do an action so other code can be triggered when a notice is created |
|
| 639 | + * |
|
| 640 | + * @param string $type can be 'errors', 'attention', or 'success' |
|
| 641 | + * @param string $user_msg message displayed to user when WP_DEBUG is off |
|
| 642 | + * @param string $user_msg message displayed to user when WP_DEBUG is on |
|
| 643 | + * @param string $file file where error was generated |
|
| 644 | + * @param string $func function where error was generated |
|
| 645 | + * @param string $line line where error was generated |
|
| 646 | + */ |
|
| 647 | + do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line); |
|
| 648 | + $msg = WP_DEBUG ? $dev_msg : $user_msg; |
|
| 649 | + // add notice if message exists |
|
| 650 | + if (! empty($msg)) { |
|
| 651 | + // get error code |
|
| 652 | + $notice_code = EE_Error::generate_error_code($file, $func, $line); |
|
| 653 | + if (WP_DEBUG && $type === 'errors') { |
|
| 654 | + $msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>'; |
|
| 655 | + } |
|
| 656 | + // add notice. Index by code if it's not blank |
|
| 657 | + if ($notice_code) { |
|
| 658 | + self::$_espresso_notices[$type][$notice_code] = $msg; |
|
| 659 | + } else { |
|
| 660 | + self::$_espresso_notices[$type][] = $msg; |
|
| 661 | + } |
|
| 662 | + add_action('wp_footer', array('EE_Error', 'enqueue_error_scripts'), 1); |
|
| 663 | + } |
|
| 664 | + } |
|
| 665 | + |
|
| 666 | + |
|
| 667 | + |
|
| 668 | + /** |
|
| 669 | + * in some case it may be necessary to overwrite the existing success messages |
|
| 670 | + * |
|
| 671 | + * @return void |
|
| 672 | + */ |
|
| 673 | + public static function overwrite_success() |
|
| 674 | + { |
|
| 675 | + self::$_espresso_notices['success'] = false; |
|
| 676 | + } |
|
| 677 | + |
|
| 678 | + |
|
| 679 | + |
|
| 680 | + /** |
|
| 681 | + * in some case it may be necessary to overwrite the existing attention messages |
|
| 682 | + * |
|
| 683 | + * @return void |
|
| 684 | + */ |
|
| 685 | + public static function overwrite_attention() |
|
| 686 | + { |
|
| 687 | + self::$_espresso_notices['attention'] = false; |
|
| 688 | + } |
|
| 689 | + |
|
| 690 | + |
|
| 691 | + |
|
| 692 | + /** |
|
| 693 | + * in some case it may be necessary to overwrite the existing error messages |
|
| 694 | + * |
|
| 695 | + * @return void |
|
| 696 | + */ |
|
| 697 | + public static function overwrite_errors() |
|
| 698 | + { |
|
| 699 | + self::$_espresso_notices['errors'] = false; |
|
| 700 | + } |
|
| 701 | + |
|
| 702 | + |
|
| 703 | + |
|
| 704 | + /** |
|
| 705 | + * reset_notices |
|
| 706 | + * |
|
| 707 | + * @return void |
|
| 708 | + */ |
|
| 709 | + public static function reset_notices() |
|
| 710 | + { |
|
| 711 | + self::$_espresso_notices['success'] = false; |
|
| 712 | + self::$_espresso_notices['attention'] = false; |
|
| 713 | + self::$_espresso_notices['errors'] = false; |
|
| 714 | + } |
|
| 715 | + |
|
| 716 | + |
|
| 717 | + |
|
| 718 | + /** |
|
| 719 | + * has_errors |
|
| 720 | + * |
|
| 721 | + * @return int |
|
| 722 | + */ |
|
| 723 | + public static function has_notices() |
|
| 724 | + { |
|
| 725 | + $has_notices = 0; |
|
| 726 | + // check for success messages |
|
| 727 | + $has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success']) ? 3 |
|
| 728 | + : $has_notices; |
|
| 729 | + // check for attention messages |
|
| 730 | + $has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention']) ? 2 |
|
| 731 | + : $has_notices; |
|
| 732 | + // check for error messages |
|
| 733 | + $has_notices = self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors']) ? 1 |
|
| 734 | + : $has_notices; |
|
| 735 | + return $has_notices; |
|
| 736 | + } |
|
| 737 | + |
|
| 738 | + |
|
| 739 | + |
|
| 740 | + /** |
|
| 741 | + * This simply returns non formatted error notices as they were sent into the EE_Error object. |
|
| 742 | + * |
|
| 743 | + * @since 4.9.0 |
|
| 744 | + * @return array |
|
| 745 | + */ |
|
| 746 | + public static function get_vanilla_notices() |
|
| 747 | + { |
|
| 748 | + return array( |
|
| 749 | + 'success' => isset(self::$_espresso_notices['success']) ? self::$_espresso_notices['success'] : array(), |
|
| 750 | + 'attention' => isset(self::$_espresso_notices['attention']) ? self::$_espresso_notices['attention'] |
|
| 751 | + : array(), |
|
| 752 | + 'errors' => isset(self::$_espresso_notices['errors']) ? self::$_espresso_notices['errors'] : array(), |
|
| 753 | + ); |
|
| 754 | + } |
|
| 755 | + |
|
| 756 | + |
|
| 757 | + |
|
| 758 | + /** |
|
| 759 | + * compile all error or success messages into one string |
|
| 760 | + * |
|
| 761 | + * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them |
|
| 762 | + * @param boolean $format_output whether or not to format the messages for display in the WP admin |
|
| 763 | + * @param boolean $save_to_transient whether or not to save notices to the db for retrieval on next request |
|
| 764 | + * - ONLY do this just before redirecting |
|
| 765 | + * @param boolean $remove_empty whether or not to unset empty messages |
|
| 766 | + * @return array |
|
| 767 | + */ |
|
| 768 | + public static function get_notices($format_output = true, $save_to_transient = false, $remove_empty = true) |
|
| 769 | + { |
|
| 770 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 771 | + $success_messages = ''; |
|
| 772 | + $attention_messages = ''; |
|
| 773 | + $error_messages = ''; |
|
| 774 | + $print_scripts = false; |
|
| 775 | + // either save notices to the db |
|
| 776 | + if ($save_to_transient) { |
|
| 777 | + update_option('ee_notices', self::$_espresso_notices); |
|
| 778 | + return array(); |
|
| 779 | + } |
|
| 780 | + // grab any notices that have been previously saved |
|
| 781 | + if ($notices = get_option('ee_notices', false)) { |
|
| 782 | + foreach ($notices as $type => $notice) { |
|
| 783 | + if (is_array($notice) && ! empty($notice)) { |
|
| 784 | + // make sure that existing notice type is an array |
|
| 785 | + self::$_espresso_notices[$type] = is_array(self::$_espresso_notices[$type]) |
|
| 786 | + && ! empty(self::$_espresso_notices[$type]) |
|
| 787 | + ? self::$_espresso_notices[$type] : array(); |
|
| 788 | + // merge stored notices with any newly created ones |
|
| 789 | + self::$_espresso_notices[$type] = array_merge(self::$_espresso_notices[$type], $notice); |
|
| 790 | + $print_scripts = true; |
|
| 791 | + } |
|
| 792 | + } |
|
| 793 | + // now clear any stored notices |
|
| 794 | + update_option('ee_notices', false); |
|
| 795 | + } |
|
| 796 | + // check for success messages |
|
| 797 | + if (self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])) { |
|
| 798 | + // combine messages |
|
| 799 | + $success_messages .= implode(self::$_espresso_notices['success'], '<br /><br />'); |
|
| 800 | + $print_scripts = true; |
|
| 801 | + } |
|
| 802 | + // check for attention messages |
|
| 803 | + if (self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])) { |
|
| 804 | + // combine messages |
|
| 805 | + $attention_messages .= implode(self::$_espresso_notices['attention'], '<br /><br />'); |
|
| 806 | + $print_scripts = true; |
|
| 807 | + } |
|
| 808 | + // check for error messages |
|
| 809 | + if (self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])) { |
|
| 810 | + $error_messages .= count(self::$_espresso_notices['errors']) > 1 |
|
| 811 | + ? __('The following errors have occurred:<br />', 'event_espresso') |
|
| 812 | + : __('An error has occurred:<br />', 'event_espresso'); |
|
| 813 | + // combine messages |
|
| 814 | + $error_messages .= implode(self::$_espresso_notices['errors'], '<br /><br />'); |
|
| 815 | + $print_scripts = true; |
|
| 816 | + } |
|
| 817 | + if ($format_output) { |
|
| 818 | + $notices = '<div id="espresso-notices">'; |
|
| 819 | + $close = is_admin() ? '' |
|
| 820 | + : '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"></span></a>'; |
|
| 821 | + if ($success_messages !== '') { |
|
| 822 | + $css_id = is_admin() ? 'message' : 'espresso-notices-success'; |
|
| 823 | + $css_class = is_admin() ? 'updated fade' : 'success fade-away'; |
|
| 824 | + //showMessage( $success_messages ); |
|
| 825 | + $notices .= '<div id="' |
|
| 826 | + . $css_id |
|
| 827 | + . '" class="espresso-notices ' |
|
| 828 | + . $css_class |
|
| 829 | + . '" style="display:none;"><p>' |
|
| 830 | + . $success_messages |
|
| 831 | + . '</p>' |
|
| 832 | + . $close |
|
| 833 | + . '</div>'; |
|
| 834 | + } |
|
| 835 | + if ($attention_messages !== '') { |
|
| 836 | + $css_id = is_admin() ? 'message' : 'espresso-notices-attention'; |
|
| 837 | + $css_class = is_admin() ? 'updated ee-notices-attention' : 'attention fade-away'; |
|
| 838 | + //showMessage( $error_messages, TRUE ); |
|
| 839 | + $notices .= '<div id="' |
|
| 840 | + . $css_id |
|
| 841 | + . '" class="espresso-notices ' |
|
| 842 | + . $css_class |
|
| 843 | + . '" style="display:none;"><p>' |
|
| 844 | + . $attention_messages |
|
| 845 | + . '</p>' |
|
| 846 | + . $close |
|
| 847 | + . '</div>'; |
|
| 848 | + } |
|
| 849 | + if ($error_messages !== '') { |
|
| 850 | + $css_id = is_admin() ? 'message' : 'espresso-notices-error'; |
|
| 851 | + $css_class = is_admin() ? 'error' : 'error fade-away'; |
|
| 852 | + //showMessage( $error_messages, TRUE ); |
|
| 853 | + $notices .= '<div id="' |
|
| 854 | + . $css_id |
|
| 855 | + . '" class="espresso-notices ' |
|
| 856 | + . $css_class |
|
| 857 | + . '" style="display:none;"><p>' |
|
| 858 | + . $error_messages |
|
| 859 | + . '</p>' |
|
| 860 | + . $close |
|
| 861 | + . '</div>'; |
|
| 862 | + } |
|
| 863 | + $notices .= '</div>'; |
|
| 864 | + } else { |
|
| 865 | + $notices = array( |
|
| 866 | + 'success' => $success_messages, |
|
| 867 | + 'attention' => $attention_messages, |
|
| 868 | + 'errors' => $error_messages, |
|
| 869 | + ); |
|
| 870 | + if ($remove_empty) { |
|
| 871 | + // remove empty notices |
|
| 872 | + foreach ($notices as $type => $notice) { |
|
| 873 | + if (empty($notice)) { |
|
| 874 | + unset($notices[$type]); |
|
| 875 | + } |
|
| 876 | + } |
|
| 877 | + } |
|
| 878 | + } |
|
| 879 | + if ($print_scripts) { |
|
| 880 | + self::_print_scripts(); |
|
| 881 | + } |
|
| 882 | + return $notices; |
|
| 883 | + } |
|
| 884 | + |
|
| 885 | + |
|
| 886 | + |
|
| 887 | + /** |
|
| 888 | + * add_persistent_admin_notice |
|
| 889 | + * |
|
| 890 | + * @param string $pan_name the name, or key of the Persistent Admin Notice to be stored |
|
| 891 | + * @param string $pan_message the message to be stored persistently until dismissed |
|
| 892 | + * @param bool $force_update allows one to enforce the reappearance of a persistent message. |
|
| 893 | + * @return void |
|
| 894 | + */ |
|
| 895 | + public static function add_persistent_admin_notice($pan_name = '', $pan_message, $force_update = false) |
|
| 896 | + { |
|
| 897 | + if (! empty($pan_name) && ! empty($pan_message)) { |
|
| 898 | + $persistent_admin_notices = get_option('ee_pers_admin_notices', array()); |
|
| 899 | + //maybe initialize persistent_admin_notices |
|
| 900 | + if (empty($persistent_admin_notices)) { |
|
| 901 | + add_option('ee_pers_admin_notices', array(), '', 'no'); |
|
| 902 | + } |
|
| 903 | + $pan_name = sanitize_key($pan_name); |
|
| 904 | + if (! array_key_exists($pan_name, $persistent_admin_notices) || $force_update) { |
|
| 905 | + $persistent_admin_notices[$pan_name] = $pan_message; |
|
| 906 | + update_option('ee_pers_admin_notices', $persistent_admin_notices); |
|
| 907 | + } |
|
| 908 | + } |
|
| 909 | + } |
|
| 910 | + |
|
| 911 | + |
|
| 912 | + |
|
| 913 | + /** |
|
| 914 | + * dismiss_persistent_admin_notice |
|
| 915 | + * |
|
| 916 | + * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed |
|
| 917 | + * @param bool $purge |
|
| 918 | + * @param bool $return_immediately |
|
| 919 | + * @return void |
|
| 920 | + */ |
|
| 921 | + public static function dismiss_persistent_admin_notice($pan_name = '', $purge = false, $return_immediately = false) |
|
| 922 | + { |
|
| 923 | + $pan_name = EE_Registry::instance()->REQ->is_set('ee_nag_notice') |
|
| 924 | + ? EE_Registry::instance()->REQ->get('ee_nag_notice') : $pan_name; |
|
| 925 | + if (! empty($pan_name)) { |
|
| 926 | + $persistent_admin_notices = get_option('ee_pers_admin_notices', array()); |
|
| 927 | + // check if notice we wish to dismiss is actually in the $persistent_admin_notices array |
|
| 928 | + if (is_array($persistent_admin_notices) && isset($persistent_admin_notices[$pan_name])) { |
|
| 929 | + // completely delete nag notice, or just NULL message so that it can NOT be added again ? |
|
| 930 | + if ($purge) { |
|
| 931 | + unset($persistent_admin_notices[$pan_name]); |
|
| 932 | + } else { |
|
| 933 | + $persistent_admin_notices[$pan_name] = null; |
|
| 934 | + } |
|
| 935 | + if (update_option('ee_pers_admin_notices', $persistent_admin_notices) === false) { |
|
| 936 | + EE_Error::add_error(sprintf(__('The persistent admin notice for "%s" could not be deleted.', |
|
| 937 | + 'event_espresso'), $pan_name), __FILE__, __FUNCTION__, __LINE__); |
|
| 938 | + } |
|
| 939 | + } |
|
| 940 | + } |
|
| 941 | + if ($return_immediately) { |
|
| 942 | + return; |
|
| 943 | + } |
|
| 944 | + if (EE_Registry::instance()->REQ->ajax) { |
|
| 945 | + // grab any notices and concatenate into string |
|
| 946 | + echo wp_json_encode(array('errors' => implode('<br />', EE_Error::get_notices(false)))); |
|
| 947 | + exit(); |
|
| 948 | + } |
|
| 949 | + // save errors to a transient to be displayed on next request (after redirect) |
|
| 950 | + EE_Error::get_notices(false, true); |
|
| 951 | + $return_url = EE_Registry::instance()->REQ->is_set('return_url') |
|
| 952 | + ? EE_Registry::instance()->REQ->get('return_url') : ''; |
|
| 953 | + wp_safe_redirect(urldecode($return_url)); |
|
| 954 | + } |
|
| 955 | + |
|
| 956 | + |
|
| 957 | + |
|
| 958 | + /** |
|
| 959 | + * display_persistent_admin_notices |
|
| 960 | + * |
|
| 961 | + * @param string $pan_name the name, or key of the Persistent Admin Notice to be stored |
|
| 962 | + * @param string $pan_message the message to be stored persistently until dismissed |
|
| 963 | + * @param string $return_url URL to go back to after nag notice is dismissed |
|
| 964 | + * @return string |
|
| 965 | + */ |
|
| 966 | + public static function display_persistent_admin_notices($pan_name = '', $pan_message = '', $return_url = '') |
|
| 967 | + { |
|
| 968 | + if (! empty($pan_name) && ! empty($pan_message)) { |
|
| 969 | + $args = array( |
|
| 970 | + 'nag_notice' => $pan_name, |
|
| 971 | + 'return_url' => urlencode($return_url), |
|
| 972 | + 'ajax_url' => WP_AJAX_URL, |
|
| 973 | + 'unknown_error' => esc_html__( |
|
| 974 | + 'An unknown error has occurred on the server while attempting to dismiss this notice.', |
|
| 975 | + 'event_espresso' |
|
| 976 | + ), |
|
| 977 | + ); |
|
| 978 | + EE_Registry::$i18n_js_strings = array_merge( |
|
| 979 | + EE_Registry::$i18n_js_strings, |
|
| 980 | + array('ee_dismiss' => $args) |
|
| 981 | + ); |
|
| 982 | + return ' |
|
| 983 | 983 | <div id="' |
| 984 | - . $pan_name |
|
| 985 | - . '" class="espresso-notices updated ee-nag-notice clearfix" style="border-left: 4px solid #fcb93c;"> |
|
| 984 | + . $pan_name |
|
| 985 | + . '" class="espresso-notices updated ee-nag-notice clearfix" style="border-left: 4px solid #fcb93c;"> |
|
| 986 | 986 | <p>' |
| 987 | - . $pan_message |
|
| 988 | - . '</p> |
|
| 987 | + . $pan_message |
|
| 988 | + . '</p> |
|
| 989 | 989 | <a class="dismiss-ee-nag-notice hide-if-no-js" style="float: right; cursor: pointer; text-decoration:none;" rel="' |
| 990 | - . $pan_name |
|
| 991 | - . '"> |
|
| 990 | + . $pan_name |
|
| 991 | + . '"> |
|
| 992 | 992 | <span class="dashicons dashicons-dismiss" style="position:relative; top:-1px; margin-right:.25em;"></span>' |
| 993 | - . __('Dismiss', 'event_espresso') |
|
| 994 | - . ' |
|
| 993 | + . __('Dismiss', 'event_espresso') |
|
| 994 | + . ' |
|
| 995 | 995 | </a> |
| 996 | 996 | <div style="clear:both;"></div> |
| 997 | 997 | </div>'; |
| 998 | - } |
|
| 999 | - return ''; |
|
| 1000 | - } |
|
| 1001 | - |
|
| 1002 | - |
|
| 1003 | - |
|
| 1004 | - /** |
|
| 1005 | - * get_persistent_admin_notices |
|
| 1006 | - * |
|
| 1007 | - * @param string $return_url |
|
| 1008 | - * @return string |
|
| 1009 | - */ |
|
| 1010 | - public static function get_persistent_admin_notices($return_url = '') |
|
| 1011 | - { |
|
| 1012 | - $notices = ''; |
|
| 1013 | - // check for persistent admin notices |
|
| 1014 | - //filter the list though so plugins can notify the admin in a different way if they want |
|
| 1015 | - $persistent_admin_notices = apply_filters( |
|
| 1016 | - 'FHEE__EE_Error__get_persistent_admin_notices', |
|
| 1017 | - get_option('ee_pers_admin_notices', false), |
|
| 1018 | - 'ee_pers_admin_notices', |
|
| 1019 | - $return_url |
|
| 1020 | - ); |
|
| 1021 | - if ($persistent_admin_notices) { |
|
| 1022 | - // load scripts |
|
| 1023 | - wp_register_script( |
|
| 1024 | - 'espresso_core', |
|
| 1025 | - EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js', |
|
| 1026 | - array('jquery'), |
|
| 1027 | - EVENT_ESPRESSO_VERSION, |
|
| 1028 | - true |
|
| 1029 | - ); |
|
| 1030 | - wp_register_script( |
|
| 1031 | - 'ee_error_js', |
|
| 1032 | - EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js', |
|
| 1033 | - array('espresso_core'), |
|
| 1034 | - EVENT_ESPRESSO_VERSION, |
|
| 1035 | - true |
|
| 1036 | - ); |
|
| 1037 | - wp_enqueue_script('ee_error_js'); |
|
| 1038 | - // and display notices |
|
| 1039 | - foreach ($persistent_admin_notices as $pan_name => $pan_message) { |
|
| 1040 | - $notices .= self::display_persistent_admin_notices($pan_name, $pan_message, $return_url); |
|
| 1041 | - } |
|
| 1042 | - } |
|
| 1043 | - return $notices; |
|
| 1044 | - } |
|
| 1045 | - |
|
| 1046 | - |
|
| 1047 | - |
|
| 1048 | - /** |
|
| 1049 | - * _print_scripts |
|
| 1050 | - * |
|
| 1051 | - * @param bool $force_print |
|
| 1052 | - * @return string |
|
| 1053 | - */ |
|
| 1054 | - private static function _print_scripts($force_print = false) |
|
| 1055 | - { |
|
| 1056 | - if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) { |
|
| 1057 | - if (wp_script_is('ee_error_js', 'enqueued')) { |
|
| 1058 | - return ''; |
|
| 1059 | - } |
|
| 1060 | - if (wp_script_is('ee_error_js', 'registered')) { |
|
| 1061 | - wp_enqueue_style('espresso_default'); |
|
| 1062 | - wp_enqueue_style('espresso_custom_css'); |
|
| 1063 | - wp_enqueue_script('ee_error_js'); |
|
| 1064 | - wp_localize_script('ee_error_js', 'ee_settings', array('wp_debug' => WP_DEBUG)); |
|
| 1065 | - } |
|
| 1066 | - } else { |
|
| 1067 | - return ' |
|
| 998 | + } |
|
| 999 | + return ''; |
|
| 1000 | + } |
|
| 1001 | + |
|
| 1002 | + |
|
| 1003 | + |
|
| 1004 | + /** |
|
| 1005 | + * get_persistent_admin_notices |
|
| 1006 | + * |
|
| 1007 | + * @param string $return_url |
|
| 1008 | + * @return string |
|
| 1009 | + */ |
|
| 1010 | + public static function get_persistent_admin_notices($return_url = '') |
|
| 1011 | + { |
|
| 1012 | + $notices = ''; |
|
| 1013 | + // check for persistent admin notices |
|
| 1014 | + //filter the list though so plugins can notify the admin in a different way if they want |
|
| 1015 | + $persistent_admin_notices = apply_filters( |
|
| 1016 | + 'FHEE__EE_Error__get_persistent_admin_notices', |
|
| 1017 | + get_option('ee_pers_admin_notices', false), |
|
| 1018 | + 'ee_pers_admin_notices', |
|
| 1019 | + $return_url |
|
| 1020 | + ); |
|
| 1021 | + if ($persistent_admin_notices) { |
|
| 1022 | + // load scripts |
|
| 1023 | + wp_register_script( |
|
| 1024 | + 'espresso_core', |
|
| 1025 | + EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js', |
|
| 1026 | + array('jquery'), |
|
| 1027 | + EVENT_ESPRESSO_VERSION, |
|
| 1028 | + true |
|
| 1029 | + ); |
|
| 1030 | + wp_register_script( |
|
| 1031 | + 'ee_error_js', |
|
| 1032 | + EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js', |
|
| 1033 | + array('espresso_core'), |
|
| 1034 | + EVENT_ESPRESSO_VERSION, |
|
| 1035 | + true |
|
| 1036 | + ); |
|
| 1037 | + wp_enqueue_script('ee_error_js'); |
|
| 1038 | + // and display notices |
|
| 1039 | + foreach ($persistent_admin_notices as $pan_name => $pan_message) { |
|
| 1040 | + $notices .= self::display_persistent_admin_notices($pan_name, $pan_message, $return_url); |
|
| 1041 | + } |
|
| 1042 | + } |
|
| 1043 | + return $notices; |
|
| 1044 | + } |
|
| 1045 | + |
|
| 1046 | + |
|
| 1047 | + |
|
| 1048 | + /** |
|
| 1049 | + * _print_scripts |
|
| 1050 | + * |
|
| 1051 | + * @param bool $force_print |
|
| 1052 | + * @return string |
|
| 1053 | + */ |
|
| 1054 | + private static function _print_scripts($force_print = false) |
|
| 1055 | + { |
|
| 1056 | + if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) { |
|
| 1057 | + if (wp_script_is('ee_error_js', 'enqueued')) { |
|
| 1058 | + return ''; |
|
| 1059 | + } |
|
| 1060 | + if (wp_script_is('ee_error_js', 'registered')) { |
|
| 1061 | + wp_enqueue_style('espresso_default'); |
|
| 1062 | + wp_enqueue_style('espresso_custom_css'); |
|
| 1063 | + wp_enqueue_script('ee_error_js'); |
|
| 1064 | + wp_localize_script('ee_error_js', 'ee_settings', array('wp_debug' => WP_DEBUG)); |
|
| 1065 | + } |
|
| 1066 | + } else { |
|
| 1067 | + return ' |
|
| 1068 | 1068 | <script> |
| 1069 | 1069 | /* <![CDATA[ */ |
| 1070 | 1070 | var ee_settings = {"wp_debug":"' . WP_DEBUG . '"}; |
@@ -1074,143 +1074,143 @@ discard block |
||
| 1074 | 1074 | <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script> |
| 1075 | 1075 | <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script> |
| 1076 | 1076 | '; |
| 1077 | - } |
|
| 1078 | - return ''; |
|
| 1079 | - } |
|
| 1080 | - |
|
| 1081 | - |
|
| 1082 | - |
|
| 1083 | - /** |
|
| 1084 | - * enqueue_error_scripts |
|
| 1085 | - * |
|
| 1086 | - * @return void |
|
| 1087 | - */ |
|
| 1088 | - public static function enqueue_error_scripts() |
|
| 1089 | - { |
|
| 1090 | - self::_print_scripts(); |
|
| 1091 | - } |
|
| 1092 | - |
|
| 1093 | - |
|
| 1094 | - |
|
| 1095 | - /** |
|
| 1096 | - * create error code from filepath, function name, |
|
| 1097 | - * and line number where exception or error was thrown |
|
| 1098 | - * |
|
| 1099 | - * @param string $file |
|
| 1100 | - * @param string $func |
|
| 1101 | - * @param string $line |
|
| 1102 | - * @return string |
|
| 1103 | - */ |
|
| 1104 | - public static function generate_error_code($file = '', $func = '', $line = '') |
|
| 1105 | - { |
|
| 1106 | - $file = explode('.', basename($file)); |
|
| 1107 | - $error_code = ! empty($file[0]) ? $file[0] : ''; |
|
| 1108 | - $error_code .= ! empty($func) ? ' - ' . $func : ''; |
|
| 1109 | - $error_code .= ! empty($line) ? ' - ' . $line : ''; |
|
| 1110 | - return $error_code; |
|
| 1111 | - } |
|
| 1112 | - |
|
| 1113 | - |
|
| 1114 | - |
|
| 1115 | - /** |
|
| 1116 | - * write exception details to log file |
|
| 1117 | - * |
|
| 1118 | - * @param int $time |
|
| 1119 | - * @param array $ex |
|
| 1120 | - * @param bool $clear |
|
| 1121 | - * @return void |
|
| 1122 | - */ |
|
| 1123 | - public function write_to_error_log($time = 0, $ex = array(), $clear = false) |
|
| 1124 | - { |
|
| 1125 | - if (empty($ex)) { |
|
| 1126 | - return; |
|
| 1127 | - } |
|
| 1128 | - if (! $time) { |
|
| 1129 | - $time = time(); |
|
| 1130 | - } |
|
| 1131 | - $exception_log = '----------------------------------------------------------------------------------------' |
|
| 1132 | - . PHP_EOL; |
|
| 1133 | - $exception_log .= '[' . date('Y-m-d H:i:s', $time) . '] Exception Details' . PHP_EOL; |
|
| 1134 | - $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL; |
|
| 1135 | - $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL; |
|
| 1136 | - $exception_log .= 'File: ' . $ex['file'] . PHP_EOL; |
|
| 1137 | - $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL; |
|
| 1138 | - $exception_log .= 'Stack trace: ' . PHP_EOL; |
|
| 1139 | - $exception_log .= $ex['string'] . PHP_EOL; |
|
| 1140 | - $exception_log .= '----------------------------------------------------------------------------------------' |
|
| 1141 | - . PHP_EOL; |
|
| 1142 | - try { |
|
| 1143 | - EEH_File::ensure_file_exists_and_is_writable( |
|
| 1144 | - EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file |
|
| 1145 | - ); |
|
| 1146 | - EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs'); |
|
| 1147 | - if (! $clear) { |
|
| 1148 | - //get existing log file and append new log info |
|
| 1149 | - $exception_log = EEH_File::get_file_contents( |
|
| 1150 | - EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file |
|
| 1151 | - ) . $exception_log; |
|
| 1152 | - } |
|
| 1153 | - EEH_File::write_to_file( |
|
| 1154 | - EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file, |
|
| 1155 | - $exception_log |
|
| 1156 | - ); |
|
| 1157 | - } catch (EE_Error $e) { |
|
| 1158 | - EE_Error::add_error(sprintf(__('Event Espresso error logging could not be setup because: %s', |
|
| 1159 | - 'event_espresso'), $e->getMessage())); |
|
| 1160 | - return; |
|
| 1161 | - } |
|
| 1162 | - } |
|
| 1163 | - |
|
| 1164 | - |
|
| 1165 | - |
|
| 1166 | - /** |
|
| 1167 | - * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method. |
|
| 1168 | - * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown, |
|
| 1169 | - * but the code execution is done in a manner that could lead to unexpected results |
|
| 1170 | - * (i.e. running to early, or too late in WP or EE loading process). |
|
| 1171 | - * A good test for knowing whether to use this method is: |
|
| 1172 | - * 1. Is there going to be a PHP error if something isn't setup/used correctly? |
|
| 1173 | - * Yes -> use EE_Error::add_error() or throw new EE_Error() |
|
| 1174 | - * 2. If this is loaded before something else, it won't break anything, |
|
| 1175 | - * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong() |
|
| 1176 | - * |
|
| 1177 | - * @uses constant WP_DEBUG test if wp_debug is on or not |
|
| 1178 | - * @param string $function The function that was called |
|
| 1179 | - * @param string $message A message explaining what has been done incorrectly |
|
| 1180 | - * @param string $version The version of Event Espresso where the error was added |
|
| 1181 | - * @param string $applies_when a version string for when you want the doing_it_wrong notice to begin appearing |
|
| 1182 | - * for a deprecated function. This allows deprecation to occur during one version, |
|
| 1183 | - * but not have any notices appear until a later version. This allows developers |
|
| 1184 | - * extra time to update their code before notices appear. |
|
| 1185 | - * @param int $error_type |
|
| 1186 | - */ |
|
| 1187 | - public static function doing_it_wrong( |
|
| 1188 | - $function, |
|
| 1189 | - $message, |
|
| 1190 | - $version, |
|
| 1191 | - $applies_when = '', |
|
| 1192 | - $error_type = null |
|
| 1193 | - ) { |
|
| 1194 | - if (defined('WP_DEBUG') && WP_DEBUG) { |
|
| 1195 | - EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type); |
|
| 1196 | - } |
|
| 1197 | - } |
|
| 1198 | - |
|
| 1199 | - |
|
| 1200 | - |
|
| 1201 | - /** |
|
| 1202 | - * Like get_notices, but returns an array of all the notices of the given type. |
|
| 1203 | - * |
|
| 1204 | - * @return array { |
|
| 1205 | - * @type array $success all the success messages |
|
| 1206 | - * @type array $errors all the error messages |
|
| 1207 | - * @type array $attention all the attention messages |
|
| 1208 | - * } |
|
| 1209 | - */ |
|
| 1210 | - public static function get_raw_notices() |
|
| 1211 | - { |
|
| 1212 | - return self::$_espresso_notices; |
|
| 1213 | - } |
|
| 1077 | + } |
|
| 1078 | + return ''; |
|
| 1079 | + } |
|
| 1080 | + |
|
| 1081 | + |
|
| 1082 | + |
|
| 1083 | + /** |
|
| 1084 | + * enqueue_error_scripts |
|
| 1085 | + * |
|
| 1086 | + * @return void |
|
| 1087 | + */ |
|
| 1088 | + public static function enqueue_error_scripts() |
|
| 1089 | + { |
|
| 1090 | + self::_print_scripts(); |
|
| 1091 | + } |
|
| 1092 | + |
|
| 1093 | + |
|
| 1094 | + |
|
| 1095 | + /** |
|
| 1096 | + * create error code from filepath, function name, |
|
| 1097 | + * and line number where exception or error was thrown |
|
| 1098 | + * |
|
| 1099 | + * @param string $file |
|
| 1100 | + * @param string $func |
|
| 1101 | + * @param string $line |
|
| 1102 | + * @return string |
|
| 1103 | + */ |
|
| 1104 | + public static function generate_error_code($file = '', $func = '', $line = '') |
|
| 1105 | + { |
|
| 1106 | + $file = explode('.', basename($file)); |
|
| 1107 | + $error_code = ! empty($file[0]) ? $file[0] : ''; |
|
| 1108 | + $error_code .= ! empty($func) ? ' - ' . $func : ''; |
|
| 1109 | + $error_code .= ! empty($line) ? ' - ' . $line : ''; |
|
| 1110 | + return $error_code; |
|
| 1111 | + } |
|
| 1112 | + |
|
| 1113 | + |
|
| 1114 | + |
|
| 1115 | + /** |
|
| 1116 | + * write exception details to log file |
|
| 1117 | + * |
|
| 1118 | + * @param int $time |
|
| 1119 | + * @param array $ex |
|
| 1120 | + * @param bool $clear |
|
| 1121 | + * @return void |
|
| 1122 | + */ |
|
| 1123 | + public function write_to_error_log($time = 0, $ex = array(), $clear = false) |
|
| 1124 | + { |
|
| 1125 | + if (empty($ex)) { |
|
| 1126 | + return; |
|
| 1127 | + } |
|
| 1128 | + if (! $time) { |
|
| 1129 | + $time = time(); |
|
| 1130 | + } |
|
| 1131 | + $exception_log = '----------------------------------------------------------------------------------------' |
|
| 1132 | + . PHP_EOL; |
|
| 1133 | + $exception_log .= '[' . date('Y-m-d H:i:s', $time) . '] Exception Details' . PHP_EOL; |
|
| 1134 | + $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL; |
|
| 1135 | + $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL; |
|
| 1136 | + $exception_log .= 'File: ' . $ex['file'] . PHP_EOL; |
|
| 1137 | + $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL; |
|
| 1138 | + $exception_log .= 'Stack trace: ' . PHP_EOL; |
|
| 1139 | + $exception_log .= $ex['string'] . PHP_EOL; |
|
| 1140 | + $exception_log .= '----------------------------------------------------------------------------------------' |
|
| 1141 | + . PHP_EOL; |
|
| 1142 | + try { |
|
| 1143 | + EEH_File::ensure_file_exists_and_is_writable( |
|
| 1144 | + EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file |
|
| 1145 | + ); |
|
| 1146 | + EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs'); |
|
| 1147 | + if (! $clear) { |
|
| 1148 | + //get existing log file and append new log info |
|
| 1149 | + $exception_log = EEH_File::get_file_contents( |
|
| 1150 | + EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file |
|
| 1151 | + ) . $exception_log; |
|
| 1152 | + } |
|
| 1153 | + EEH_File::write_to_file( |
|
| 1154 | + EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file, |
|
| 1155 | + $exception_log |
|
| 1156 | + ); |
|
| 1157 | + } catch (EE_Error $e) { |
|
| 1158 | + EE_Error::add_error(sprintf(__('Event Espresso error logging could not be setup because: %s', |
|
| 1159 | + 'event_espresso'), $e->getMessage())); |
|
| 1160 | + return; |
|
| 1161 | + } |
|
| 1162 | + } |
|
| 1163 | + |
|
| 1164 | + |
|
| 1165 | + |
|
| 1166 | + /** |
|
| 1167 | + * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method. |
|
| 1168 | + * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown, |
|
| 1169 | + * but the code execution is done in a manner that could lead to unexpected results |
|
| 1170 | + * (i.e. running to early, or too late in WP or EE loading process). |
|
| 1171 | + * A good test for knowing whether to use this method is: |
|
| 1172 | + * 1. Is there going to be a PHP error if something isn't setup/used correctly? |
|
| 1173 | + * Yes -> use EE_Error::add_error() or throw new EE_Error() |
|
| 1174 | + * 2. If this is loaded before something else, it won't break anything, |
|
| 1175 | + * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong() |
|
| 1176 | + * |
|
| 1177 | + * @uses constant WP_DEBUG test if wp_debug is on or not |
|
| 1178 | + * @param string $function The function that was called |
|
| 1179 | + * @param string $message A message explaining what has been done incorrectly |
|
| 1180 | + * @param string $version The version of Event Espresso where the error was added |
|
| 1181 | + * @param string $applies_when a version string for when you want the doing_it_wrong notice to begin appearing |
|
| 1182 | + * for a deprecated function. This allows deprecation to occur during one version, |
|
| 1183 | + * but not have any notices appear until a later version. This allows developers |
|
| 1184 | + * extra time to update their code before notices appear. |
|
| 1185 | + * @param int $error_type |
|
| 1186 | + */ |
|
| 1187 | + public static function doing_it_wrong( |
|
| 1188 | + $function, |
|
| 1189 | + $message, |
|
| 1190 | + $version, |
|
| 1191 | + $applies_when = '', |
|
| 1192 | + $error_type = null |
|
| 1193 | + ) { |
|
| 1194 | + if (defined('WP_DEBUG') && WP_DEBUG) { |
|
| 1195 | + EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type); |
|
| 1196 | + } |
|
| 1197 | + } |
|
| 1198 | + |
|
| 1199 | + |
|
| 1200 | + |
|
| 1201 | + /** |
|
| 1202 | + * Like get_notices, but returns an array of all the notices of the given type. |
|
| 1203 | + * |
|
| 1204 | + * @return array { |
|
| 1205 | + * @type array $success all the success messages |
|
| 1206 | + * @type array $errors all the error messages |
|
| 1207 | + * @type array $attention all the attention messages |
|
| 1208 | + * } |
|
| 1209 | + */ |
|
| 1210 | + public static function get_raw_notices() |
|
| 1211 | + { |
|
| 1212 | + return self::$_espresso_notices; |
|
| 1213 | + } |
|
| 1214 | 1214 | |
| 1215 | 1215 | |
| 1216 | 1216 | |
@@ -1226,27 +1226,27 @@ discard block |
||
| 1226 | 1226 | */ |
| 1227 | 1227 | function espresso_error_enqueue_scripts() |
| 1228 | 1228 | { |
| 1229 | - // js for error handling |
|
| 1230 | - wp_register_script( |
|
| 1231 | - 'espresso_core', |
|
| 1232 | - EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js', |
|
| 1233 | - array('jquery'), |
|
| 1234 | - EVENT_ESPRESSO_VERSION, |
|
| 1235 | - false |
|
| 1236 | - ); |
|
| 1237 | - wp_register_script( |
|
| 1238 | - 'ee_error_js', |
|
| 1239 | - EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js', |
|
| 1240 | - array('espresso_core'), |
|
| 1241 | - EVENT_ESPRESSO_VERSION, |
|
| 1242 | - false |
|
| 1243 | - ); |
|
| 1229 | + // js for error handling |
|
| 1230 | + wp_register_script( |
|
| 1231 | + 'espresso_core', |
|
| 1232 | + EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js', |
|
| 1233 | + array('jquery'), |
|
| 1234 | + EVENT_ESPRESSO_VERSION, |
|
| 1235 | + false |
|
| 1236 | + ); |
|
| 1237 | + wp_register_script( |
|
| 1238 | + 'ee_error_js', |
|
| 1239 | + EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js', |
|
| 1240 | + array('espresso_core'), |
|
| 1241 | + EVENT_ESPRESSO_VERSION, |
|
| 1242 | + false |
|
| 1243 | + ); |
|
| 1244 | 1244 | } |
| 1245 | 1245 | |
| 1246 | 1246 | if (is_admin()) { |
| 1247 | - add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 2); |
|
| 1247 | + add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 2); |
|
| 1248 | 1248 | } else { |
| 1249 | - add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 2); |
|
| 1249 | + add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 2); |
|
| 1250 | 1250 | } |
| 1251 | 1251 | |
| 1252 | 1252 | |
@@ -569,6 +569,7 @@ |
||
| 569 | 569 | * @param EE_Registration $registration |
| 570 | 570 | * @param EE_Question $question |
| 571 | 571 | * @param mixed EE_Answer|NULL $answer |
| 572 | + * @param EE_Answer $answer |
|
| 572 | 573 | * @return EE_Form_Input_Base |
| 573 | 574 | * @throws \EE_Error |
| 574 | 575 | */ |
@@ -47,7 +47,7 @@ discard block |
||
| 47 | 47 | { |
| 48 | 48 | $this->_slug = 'attendee_information'; |
| 49 | 49 | $this->_name = esc_html__('Attendee Information', 'event_espresso'); |
| 50 | - $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php'; |
|
| 50 | + $this->_template = SPCO_REG_STEPS_PATH.$this->_slug.DS.'attendee_info_main.template.php'; |
|
| 51 | 51 | $this->checkout = $checkout; |
| 52 | 52 | $this->_reset_success_message(); |
| 53 | 53 | $this->set_instructions( |
@@ -58,11 +58,11 @@ discard block |
||
| 58 | 58 | |
| 59 | 59 | public function translate_js_strings() |
| 60 | 60 | { |
| 61 | - EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
| 61 | + EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
| 62 | 62 | ' is a required question.', |
| 63 | 63 | 'event_espresso' |
| 64 | 64 | ); |
| 65 | - EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
| 65 | + EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
| 66 | 66 | ' is a required question. Please enter a value for at least one of the options.', |
| 67 | 67 | 'event_espresso' |
| 68 | 68 | ); |
@@ -70,18 +70,18 @@ discard block |
||
| 70 | 70 | 'Please answer all required questions correctly before proceeding.', |
| 71 | 71 | 'event_espresso' |
| 72 | 72 | ); |
| 73 | - EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
| 73 | + EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
| 74 | 74 | esc_html__( |
| 75 | 75 | 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.', |
| 76 | 76 | 'event_espresso' |
| 77 | 77 | ), |
| 78 | 78 | '<br/>' |
| 79 | 79 | ); |
| 80 | - EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
| 80 | + EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
| 81 | 81 | 'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.', |
| 82 | 82 | 'event_espresso' |
| 83 | 83 | ); |
| 84 | - EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
| 84 | + EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
| 85 | 85 | 'You must enter a valid email address.', |
| 86 | 86 | 'event_espresso' |
| 87 | 87 | ); |
@@ -144,7 +144,7 @@ discard block |
||
| 144 | 144 | && $this->checkout->visit_allows_processing_of_this_registration($registration) |
| 145 | 145 | ) { |
| 146 | 146 | $subsections[$registration->reg_url_link()] = $this->_registrations_reg_form($registration); |
| 147 | - if (! $this->checkout->admin_request) { |
|
| 147 | + if ( ! $this->checkout->admin_request) { |
|
| 148 | 148 | $template_args['registrations'][$registration->reg_url_link()] = $registration; |
| 149 | 149 | $template_args['ticket_count'][$registration->ticket()->ID()] = isset( |
| 150 | 150 | $template_args['ticket_count'][$registration->ticket()->ID()] |
@@ -193,8 +193,7 @@ discard block |
||
| 193 | 193 | 'html_id' => $this->reg_form_name(), |
| 194 | 194 | 'subsections' => $subsections, |
| 195 | 195 | 'layout_strategy' => $this->checkout->admin_request ? |
| 196 | - new EE_Div_Per_Section_Layout() : |
|
| 197 | - new EE_Template_Layout( |
|
| 196 | + new EE_Div_Per_Section_Layout() : new EE_Template_Layout( |
|
| 198 | 197 | array( |
| 199 | 198 | 'layout_template_file' => $this->_template, // layout_template |
| 200 | 199 | 'template_args' => $template_args, |
@@ -232,7 +231,7 @@ discard block |
||
| 232 | 231 | if ($question_groups) { |
| 233 | 232 | // array of params to pass to parent constructor |
| 234 | 233 | $form_args = array( |
| 235 | - 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
| 234 | + 'html_id' => 'ee-registration-'.$registration->reg_url_link(), |
|
| 236 | 235 | 'html_class' => 'ee-reg-form-attendee-dv', |
| 237 | 236 | 'html_style' => $this->checkout->admin_request |
| 238 | 237 | ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
@@ -288,7 +287,7 @@ discard block |
||
| 288 | 287 | // generate hidden input |
| 289 | 288 | return new EE_Hidden_Input( |
| 290 | 289 | array( |
| 291 | - 'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(), |
|
| 290 | + 'html_id' => 'additional-attendee-reg-info-'.$registration->reg_url_link(), |
|
| 292 | 291 | 'default' => $additional_attendee_reg_info, |
| 293 | 292 | ) |
| 294 | 293 | ); |
@@ -308,11 +307,11 @@ discard block |
||
| 308 | 307 | { |
| 309 | 308 | // array of params to pass to parent constructor |
| 310 | 309 | $form_args = array( |
| 311 | - 'html_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier(), |
|
| 310 | + 'html_id' => 'ee-reg-form-qstn-grp-'.$question_group->identifier(), |
|
| 312 | 311 | 'html_class' => $this->checkout->admin_request |
| 313 | 312 | ? 'form-table ee-reg-form-qstn-grp-dv' |
| 314 | 313 | : 'ee-reg-form-qstn-grp-dv', |
| 315 | - 'html_label_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-lbl', |
|
| 314 | + 'html_label_id' => 'ee-reg-form-qstn-grp-'.$question_group->identifier().'-lbl', |
|
| 316 | 315 | 'subsections' => array( |
| 317 | 316 | 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group), |
| 318 | 317 | ), |
@@ -323,7 +322,7 @@ discard block |
||
| 323 | 322 | // where params |
| 324 | 323 | $query_params = array('QST_deleted' => 0); |
| 325 | 324 | // don't load admin only questions on the frontend |
| 326 | - if (! $this->checkout->admin_request) { |
|
| 325 | + if ( ! $this->checkout->admin_request) { |
|
| 327 | 326 | $query_params['QST_admin_only'] = array('!=', true); |
| 328 | 327 | } |
| 329 | 328 | $questions = $question_group->get_many_related( |
@@ -467,7 +466,7 @@ discard block |
||
| 467 | 466 | { |
| 468 | 467 | return new EE_Form_Section_HTML( |
| 469 | 468 | EEH_Template::locate_template( |
| 470 | - SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php', |
|
| 469 | + SPCO_REG_STEPS_PATH.$this->_slug.DS.'_auto_copy_attendee_info.template.php', |
|
| 471 | 470 | apply_filters( |
| 472 | 471 | 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
| 473 | 472 | array() |
@@ -499,16 +498,16 @@ discard block |
||
| 499 | 498 | if ($registration->ticket()->ID() !== $prev_ticket) { |
| 500 | 499 | $item_name = $registration->ticket()->name(); |
| 501 | 500 | $item_name .= $registration->ticket()->description() !== '' |
| 502 | - ? ' - ' . $registration->ticket()->description() |
|
| 501 | + ? ' - '.$registration->ticket()->description() |
|
| 503 | 502 | : ''; |
| 504 | - $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']'] = |
|
| 503 | + $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-'.$registration->ticket()->ID().']'] = |
|
| 505 | 504 | new EE_Form_Section_HTML( |
| 506 | - '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>' |
|
| 505 | + '<h6 class="spco-copy-attendee-event-hdr">'.$item_name.'</h6>' |
|
| 507 | 506 | ); |
| 508 | 507 | $prev_ticket = $registration->ticket()->ID(); |
| 509 | 508 | } |
| 510 | 509 | |
| 511 | - $copy_attendee_info_inputs['spco_copy_attendee_chk[' . $registration->ID() . ']'] = |
|
| 510 | + $copy_attendee_info_inputs['spco_copy_attendee_chk['.$registration->ID().']'] = |
|
| 512 | 511 | new EE_Checkbox_Multi_Input( |
| 513 | 512 | array( |
| 514 | 513 | $registration->ID() => sprintf( |
@@ -517,7 +516,7 @@ discard block |
||
| 517 | 516 | ), |
| 518 | 517 | ), |
| 519 | 518 | array( |
| 520 | - 'html_id' => 'spco-copy-attendee-chk-' . $registration->reg_url_link(), |
|
| 519 | + 'html_id' => 'spco-copy-attendee-chk-'.$registration->reg_url_link(), |
|
| 521 | 520 | 'html_class' => 'spco-copy-attendee-chk ee-do-not-validate', |
| 522 | 521 | 'display_html_label_text' => false, |
| 523 | 522 | ) |
@@ -566,7 +565,7 @@ discard block |
||
| 566 | 565 | $registration, |
| 567 | 566 | $question->system_ID() |
| 568 | 567 | ); |
| 569 | - $answer = $answer_value === null |
|
| 568 | + $answer = $answer_value === null |
|
| 570 | 569 | ? EEM_Answer::instance()->get_one( |
| 571 | 570 | array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
| 572 | 571 | ) |
@@ -583,14 +582,14 @@ discard block |
||
| 583 | 582 | } |
| 584 | 583 | // verify instance |
| 585 | 584 | if ($answer instanceof EE_Answer) { |
| 586 | - if (! empty($answer_value)) { |
|
| 585 | + if ( ! empty($answer_value)) { |
|
| 587 | 586 | $answer->set('ANS_value', $answer_value); |
| 588 | 587 | } |
| 589 | 588 | $answer->cache('Question', $question); |
| 590 | 589 | //remember system ID had a bug where sometimes it could be null |
| 591 | 590 | $answer_cache_id = $question->is_system_question() |
| 592 | - ? $question->system_ID() . '-' . $registration->reg_url_link() |
|
| 593 | - : $question->ID() . '-' . $registration->reg_url_link(); |
|
| 591 | + ? $question->system_ID().'-'.$registration->reg_url_link() |
|
| 592 | + : $question->ID().'-'.$registration->reg_url_link(); |
|
| 594 | 593 | $registration->cache('Answer', $answer, $answer_cache_id); |
| 595 | 594 | } |
| 596 | 595 | return $this->_generate_question_input($registration, $question, $answer); |
@@ -622,18 +621,18 @@ discard block |
||
| 622 | 621 | 10, |
| 623 | 622 | 4 |
| 624 | 623 | ); |
| 625 | - $input_constructor_args = array( |
|
| 626 | - 'html_name' => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']', |
|
| 627 | - 'html_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
| 628 | - 'html_class' => 'ee-reg-qstn ee-reg-qstn-' . $identifier, |
|
| 629 | - 'html_label_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
| 624 | + $input_constructor_args = array( |
|
| 625 | + 'html_name' => 'ee_reg_qstn['.$registration->ID().']['.$identifier.']', |
|
| 626 | + 'html_id' => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier, |
|
| 627 | + 'html_class' => 'ee-reg-qstn ee-reg-qstn-'.$identifier, |
|
| 628 | + 'html_label_id' => 'ee_reg_qstn-'.$registration->ID().'-'.$identifier, |
|
| 630 | 629 | 'html_label_class' => 'ee-reg-qstn', |
| 631 | 630 | ); |
| 632 | 631 | $input_constructor_args['html_label_id'] .= '-lbl'; |
| 633 | 632 | if ($answer instanceof EE_Answer && $answer->ID()) { |
| 634 | - $input_constructor_args['html_name'] .= '[' . $answer->ID() . ']'; |
|
| 635 | - $input_constructor_args['html_id'] .= '-' . $answer->ID(); |
|
| 636 | - $input_constructor_args['html_label_id'] .= '-' . $answer->ID(); |
|
| 633 | + $input_constructor_args['html_name'] .= '['.$answer->ID().']'; |
|
| 634 | + $input_constructor_args['html_id'] .= '-'.$answer->ID(); |
|
| 635 | + $input_constructor_args['html_label_id'] .= '-'.$answer->ID(); |
|
| 637 | 636 | } |
| 638 | 637 | $form_input = $question->generate_form_input( |
| 639 | 638 | $registration, |
@@ -676,7 +675,7 @@ discard block |
||
| 676 | 675 | $countries = $this->checkout->action === 'process_reg_step' |
| 677 | 676 | ? EEM_Country::instance()->get_all_countries() |
| 678 | 677 | : EEM_Country::instance()->get_all_active_countries(); |
| 679 | - if (! empty($countries)) { |
|
| 678 | + if ( ! empty($countries)) { |
|
| 680 | 679 | foreach ($countries as $country) { |
| 681 | 680 | if ($country instanceof EE_Country) { |
| 682 | 681 | $country_options[$country->ID()] = $country->name(); |
@@ -726,7 +725,7 @@ discard block |
||
| 726 | 725 | $states = $this->checkout->action === 'process_reg_step' |
| 727 | 726 | ? EEM_State::instance()->get_all_states() |
| 728 | 727 | : EEM_State::instance()->get_all_active_states(); |
| 729 | - if (! empty($states)) { |
|
| 728 | + if ( ! empty($states)) { |
|
| 730 | 729 | foreach ($states as $state) { |
| 731 | 730 | if ($state instanceof EE_State) { |
| 732 | 731 | $state_options[$state->country()->name()][$state->ID()] = $state->name(); |
@@ -778,7 +777,7 @@ discard block |
||
| 778 | 777 | ); |
| 779 | 778 | return false; |
| 780 | 779 | } |
| 781 | - if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
| 780 | + if ( ! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
| 782 | 781 | EE_Error::add_error( |
| 783 | 782 | esc_html__( |
| 784 | 783 | 'A valid transaction could not be initiated for processing your registrations.', |
@@ -809,7 +808,7 @@ discard block |
||
| 809 | 808 | if ($registrations_processed === false) { |
| 810 | 809 | // but return immediately if the previous step exited early due to errors |
| 811 | 810 | return false; |
| 812 | - } elseif (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
| 811 | + } elseif ( ! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
| 813 | 812 | // generate a correctly translated string for all possible singular/plural combinations |
| 814 | 813 | if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
| 815 | 814 | $error_msg = sprintf( |
@@ -889,7 +888,7 @@ discard block |
||
| 889 | 888 | // grab the saved registrations from the transaction |
| 890 | 889 | foreach ($registrations as $registration) { |
| 891 | 890 | // verify EE_Registration object |
| 892 | - if (! $registration instanceof EE_Registration) { |
|
| 891 | + if ( ! $registration instanceof EE_Registration) { |
|
| 893 | 892 | EE_Error::add_error( |
| 894 | 893 | esc_html__( |
| 895 | 894 | 'An invalid Registration object was discovered when attempting to process your registration information.', |
@@ -904,12 +903,12 @@ discard block |
||
| 904 | 903 | /** @var string $reg_url_link */ |
| 905 | 904 | $reg_url_link = $registration->reg_url_link(); |
| 906 | 905 | // reg_url_link exists ? |
| 907 | - if (! empty($reg_url_link)) { |
|
| 906 | + if ( ! empty($reg_url_link)) { |
|
| 908 | 907 | // should this registration be processed during this visit ? |
| 909 | 908 | if ($this->checkout->visit_allows_processing_of_this_registration($registration)) { |
| 910 | 909 | // if NOT revisiting, then let's save the registration now, |
| 911 | 910 | // so that we have a REG_ID to use when generating other objects |
| 912 | - if (! $this->checkout->revisit) { |
|
| 911 | + if ( ! $this->checkout->revisit) { |
|
| 913 | 912 | $registration->save(); |
| 914 | 913 | } |
| 915 | 914 | /** |
@@ -944,7 +943,7 @@ discard block |
||
| 944 | 943 | ? true |
| 945 | 944 | : false; |
| 946 | 945 | // filter form input data for this registration |
| 947 | - $valid_data[$reg_url_link] = (array)apply_filters( |
|
| 946 | + $valid_data[$reg_url_link] = (array) apply_filters( |
|
| 948 | 947 | 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
| 949 | 948 | $valid_data[$reg_url_link] |
| 950 | 949 | ); |
@@ -956,11 +955,11 @@ discard block |
||
| 956 | 955 | } |
| 957 | 956 | // now loop through our array of valid post data && process attendee reg forms |
| 958 | 957 | foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) { |
| 959 | - if (! in_array($form_section, $non_input_form_sections)) { |
|
| 958 | + if ( ! in_array($form_section, $non_input_form_sections)) { |
|
| 960 | 959 | foreach ($form_inputs as $form_input => $input_value) { |
| 961 | 960 | // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ ); |
| 962 | 961 | // check for critical inputs |
| 963 | - if (! $this->_verify_critical_attendee_details_are_set_and_validate_email( |
|
| 962 | + if ( ! $this->_verify_critical_attendee_details_are_set_and_validate_email( |
|
| 964 | 963 | $form_input, |
| 965 | 964 | $input_value |
| 966 | 965 | ) |
@@ -980,7 +979,7 @@ discard block |
||
| 980 | 979 | $input_value = $primary_registrant[$form_input]; |
| 981 | 980 | } |
| 982 | 981 | // now attempt to save the input data |
| 983 | - if (! $this->_save_registration_form_input( |
|
| 982 | + if ( ! $this->_save_registration_form_input( |
|
| 984 | 983 | $registration, |
| 985 | 984 | $form_input, |
| 986 | 985 | $input_value |
@@ -1036,7 +1035,7 @@ discard block |
||
| 1036 | 1035 | // add relation to registration, set attendee ID, and cache attendee |
| 1037 | 1036 | $this->_associate_attendee_with_registration($registration, $attendee); |
| 1038 | 1037 | // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ ); |
| 1039 | - if (! $registration->attendee() instanceof EE_Attendee) { |
|
| 1038 | + if ( ! $registration->attendee() instanceof EE_Attendee) { |
|
| 1040 | 1039 | EE_Error::add_error( |
| 1041 | 1040 | sprintf( |
| 1042 | 1041 | esc_html__( |
@@ -1121,7 +1120,7 @@ discard block |
||
| 1121 | 1120 | * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477 |
| 1122 | 1121 | */ |
| 1123 | 1122 | $answer_cache_id = $this->checkout->reg_url_link |
| 1124 | - ? $form_input . '-' . $registration->reg_url_link() |
|
| 1123 | + ? $form_input.'-'.$registration->reg_url_link() |
|
| 1125 | 1124 | : $form_input; |
| 1126 | 1125 | $answer_is_obj = isset($this->_registration_answers[$answer_cache_id]) |
| 1127 | 1126 | && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer |
@@ -1142,10 +1141,10 @@ discard block |
||
| 1142 | 1141 | break; |
| 1143 | 1142 | |
| 1144 | 1143 | default: |
| 1145 | - $ATT_input = 'ATT_' . $form_input; |
|
| 1144 | + $ATT_input = 'ATT_'.$form_input; |
|
| 1146 | 1145 | //EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ ); |
| 1147 | 1146 | $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false; |
| 1148 | - $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input; |
|
| 1147 | + $form_input = $attendee_property ? 'ATT_'.$form_input : $form_input; |
|
| 1149 | 1148 | } |
| 1150 | 1149 | // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ ); |
| 1151 | 1150 | // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ ); |
@@ -1190,7 +1189,7 @@ discard block |
||
| 1190 | 1189 | ) { |
| 1191 | 1190 | if (empty($input_value)) { |
| 1192 | 1191 | // if the form input isn't marked as being required, then just return |
| 1193 | - if (! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) { |
|
| 1192 | + if ( ! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) { |
|
| 1194 | 1193 | return true; |
| 1195 | 1194 | } |
| 1196 | 1195 | switch ($form_input) { |
@@ -1277,7 +1276,7 @@ discard block |
||
| 1277 | 1276 | 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
| 1278 | 1277 | false |
| 1279 | 1278 | )) { |
| 1280 | - $address_details = array( |
|
| 1279 | + $address_details = array( |
|
| 1281 | 1280 | 'ATT_address', |
| 1282 | 1281 | 'ATT_address2', |
| 1283 | 1282 | 'ATT_city', |
@@ -1289,7 +1288,7 @@ discard block |
||
| 1289 | 1288 | $critical_attendee_details = array_merge($critical_attendee_details, $address_details); |
| 1290 | 1289 | } |
| 1291 | 1290 | foreach ($critical_attendee_details as $critical_attendee_detail) { |
| 1292 | - if (! isset($attendee_data[$critical_attendee_detail]) |
|
| 1291 | + if ( ! isset($attendee_data[$critical_attendee_detail]) |
|
| 1293 | 1292 | || empty($attendee_data[$critical_attendee_detail]) |
| 1294 | 1293 | ) { |
| 1295 | 1294 | $attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get( |
@@ -16,1324 +16,1324 @@ |
||
| 16 | 16 | class EE_SPCO_Reg_Step_Attendee_Information extends EE_SPCO_Reg_Step |
| 17 | 17 | { |
| 18 | 18 | |
| 19 | - /** |
|
| 20 | - * @type bool $_print_copy_info |
|
| 21 | - */ |
|
| 22 | - private $_print_copy_info = false; |
|
| 23 | - |
|
| 24 | - /** |
|
| 25 | - * @type array $_attendee_data |
|
| 26 | - */ |
|
| 27 | - private $_attendee_data = array(); |
|
| 28 | - |
|
| 29 | - /** |
|
| 30 | - * @type array $_required_questions |
|
| 31 | - */ |
|
| 32 | - private $_required_questions = array(); |
|
| 33 | - |
|
| 34 | - /** |
|
| 35 | - * @type array $_registration_answers |
|
| 36 | - */ |
|
| 37 | - private $_registration_answers = array(); |
|
| 38 | - |
|
| 39 | - |
|
| 40 | - /** |
|
| 41 | - * class constructor |
|
| 42 | - * |
|
| 43 | - * @access public |
|
| 44 | - * @param EE_Checkout $checkout |
|
| 45 | - */ |
|
| 46 | - public function __construct(EE_Checkout $checkout) |
|
| 47 | - { |
|
| 48 | - $this->_slug = 'attendee_information'; |
|
| 49 | - $this->_name = esc_html__('Attendee Information', 'event_espresso'); |
|
| 50 | - $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php'; |
|
| 51 | - $this->checkout = $checkout; |
|
| 52 | - $this->_reset_success_message(); |
|
| 53 | - $this->set_instructions( |
|
| 54 | - esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso') |
|
| 55 | - ); |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - |
|
| 59 | - public function translate_js_strings() |
|
| 60 | - { |
|
| 61 | - EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
| 62 | - ' is a required question.', |
|
| 63 | - 'event_espresso' |
|
| 64 | - ); |
|
| 65 | - EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
| 66 | - ' is a required question. Please enter a value for at least one of the options.', |
|
| 67 | - 'event_espresso' |
|
| 68 | - ); |
|
| 69 | - EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__( |
|
| 70 | - 'Please answer all required questions correctly before proceeding.', |
|
| 71 | - 'event_espresso' |
|
| 72 | - ); |
|
| 73 | - EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
| 74 | - esc_html__( |
|
| 75 | - 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.', |
|
| 76 | - 'event_espresso' |
|
| 77 | - ), |
|
| 78 | - '<br/>' |
|
| 79 | - ); |
|
| 80 | - EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
| 81 | - 'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.', |
|
| 82 | - 'event_espresso' |
|
| 83 | - ); |
|
| 84 | - EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
| 85 | - 'You must enter a valid email address.', |
|
| 86 | - 'event_espresso' |
|
| 87 | - ); |
|
| 88 | - EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__( |
|
| 89 | - 'You must enter a valid email address and answer all other required questions before you can proceed.', |
|
| 90 | - 'event_espresso' |
|
| 91 | - ); |
|
| 92 | - } |
|
| 93 | - |
|
| 94 | - |
|
| 95 | - public function enqueue_styles_and_scripts() |
|
| 96 | - { |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - |
|
| 100 | - /** |
|
| 101 | - * @return boolean |
|
| 102 | - */ |
|
| 103 | - public function initialize_reg_step() |
|
| 104 | - { |
|
| 105 | - return true; |
|
| 106 | - } |
|
| 107 | - |
|
| 108 | - |
|
| 109 | - /** |
|
| 110 | - * @return EE_Form_Section_Proper |
|
| 111 | - * @throws EE_Error |
|
| 112 | - * @throws InvalidArgumentException |
|
| 113 | - * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 114 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 115 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 116 | - */ |
|
| 117 | - public function generate_reg_form() |
|
| 118 | - { |
|
| 119 | - $this->_print_copy_info = false; |
|
| 120 | - $primary_registrant = null; |
|
| 121 | - // autoload Line_Item_Display classes |
|
| 122 | - EEH_Autoloader::register_line_item_display_autoloaders(); |
|
| 123 | - $Line_Item_Display = new EE_Line_Item_Display(); |
|
| 124 | - // calculate taxes |
|
| 125 | - $Line_Item_Display->display_line_item( |
|
| 126 | - $this->checkout->cart->get_grand_total(), |
|
| 127 | - array('set_tax_rate' => true) |
|
| 128 | - ); |
|
| 129 | - /** @var $subsections EE_Form_Section_Proper[] */ |
|
| 130 | - $subsections = array( |
|
| 131 | - 'default_hidden_inputs' => $this->reg_step_hidden_inputs(), |
|
| 132 | - ); |
|
| 133 | - $template_args = array( |
|
| 134 | - 'revisit' => $this->checkout->revisit, |
|
| 135 | - 'registrations' => array(), |
|
| 136 | - 'ticket_count' => array(), |
|
| 137 | - ); |
|
| 138 | - // grab the saved registrations from the transaction |
|
| 139 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
| 140 | - if ($registrations) { |
|
| 141 | - foreach ($registrations as $registration) { |
|
| 142 | - // can this registration be processed during this visit ? |
|
| 143 | - if ($registration instanceof EE_Registration |
|
| 144 | - && $this->checkout->visit_allows_processing_of_this_registration($registration) |
|
| 145 | - ) { |
|
| 146 | - $subsections[$registration->reg_url_link()] = $this->_registrations_reg_form($registration); |
|
| 147 | - if (! $this->checkout->admin_request) { |
|
| 148 | - $template_args['registrations'][$registration->reg_url_link()] = $registration; |
|
| 149 | - $template_args['ticket_count'][$registration->ticket()->ID()] = isset( |
|
| 150 | - $template_args['ticket_count'][$registration->ticket()->ID()] |
|
| 151 | - ) |
|
| 152 | - ? $template_args['ticket_count'][$registration->ticket()->ID()] + 1 |
|
| 153 | - : 1; |
|
| 154 | - $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 155 | - $this->checkout->cart->get_grand_total(), |
|
| 156 | - 'Ticket', |
|
| 157 | - array($registration->ticket()->ID()) |
|
| 158 | - ); |
|
| 159 | - $ticket_line_item = is_array($ticket_line_item) |
|
| 160 | - ? reset($ticket_line_item) |
|
| 161 | - : $ticket_line_item; |
|
| 162 | - $template_args['ticket_line_item'][$registration->ticket()->ID()] = |
|
| 163 | - $Line_Item_Display->display_line_item($ticket_line_item); |
|
| 164 | - } |
|
| 165 | - if ($registration->is_primary_registrant()) { |
|
| 166 | - $primary_registrant = $registration->reg_url_link(); |
|
| 167 | - } |
|
| 168 | - } |
|
| 169 | - } |
|
| 170 | - // print_copy_info ? |
|
| 171 | - if ($primary_registrant && ! $this->checkout->admin_request && count($registrations) > 1) { |
|
| 172 | - // TODO: add admin option for toggling copy attendee info, |
|
| 173 | - // then use that value to change $this->_print_copy_info |
|
| 174 | - $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info |
|
| 175 | - ? $this->_copy_attendee_info_form() |
|
| 176 | - : $this->_auto_copy_attendee_info(); |
|
| 177 | - // generate hidden input |
|
| 178 | - if (isset($subsections[$primary_registrant]) |
|
| 179 | - && $subsections[$primary_registrant] instanceof EE_Form_Section_Proper |
|
| 180 | - ) { |
|
| 181 | - $subsections[$primary_registrant]->add_subsections( |
|
| 182 | - $copy_options, |
|
| 183 | - 'primary_registrant', |
|
| 184 | - false |
|
| 185 | - ); |
|
| 186 | - } |
|
| 187 | - } |
|
| 188 | - } |
|
| 189 | - |
|
| 190 | - return new EE_Form_Section_Proper( |
|
| 191 | - array( |
|
| 192 | - 'name' => $this->reg_form_name(), |
|
| 193 | - 'html_id' => $this->reg_form_name(), |
|
| 194 | - 'subsections' => $subsections, |
|
| 195 | - 'layout_strategy' => $this->checkout->admin_request ? |
|
| 196 | - new EE_Div_Per_Section_Layout() : |
|
| 197 | - new EE_Template_Layout( |
|
| 198 | - array( |
|
| 199 | - 'layout_template_file' => $this->_template, // layout_template |
|
| 200 | - 'template_args' => $template_args, |
|
| 201 | - ) |
|
| 202 | - ), |
|
| 203 | - ) |
|
| 204 | - ); |
|
| 205 | - } |
|
| 206 | - |
|
| 207 | - |
|
| 208 | - /** |
|
| 209 | - * @param EE_Registration $registration |
|
| 210 | - * @return EE_Form_Section_Base |
|
| 211 | - * @throws EE_Error |
|
| 212 | - * @throws InvalidArgumentException |
|
| 213 | - * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 214 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 215 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 216 | - */ |
|
| 217 | - private function _registrations_reg_form(EE_Registration $registration) |
|
| 218 | - { |
|
| 219 | - static $attendee_nmbr = 1; |
|
| 220 | - $form_args = array(); |
|
| 221 | - // verify that registration has valid event |
|
| 222 | - if ($registration->event() instanceof EE_Event) { |
|
| 223 | - $question_groups = $registration->event()->question_groups( |
|
| 224 | - apply_filters( |
|
| 225 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters', |
|
| 226 | - array( |
|
| 227 | - array( |
|
| 228 | - 'Event.EVT_ID' => $registration->event()->ID(), |
|
| 229 | - 'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false, |
|
| 230 | - ), |
|
| 231 | - 'order_by' => array('QSG_order' => 'ASC'), |
|
| 232 | - ), |
|
| 233 | - $registration, |
|
| 234 | - $this |
|
| 235 | - ) |
|
| 236 | - ); |
|
| 237 | - if ($question_groups) { |
|
| 238 | - // array of params to pass to parent constructor |
|
| 239 | - $form_args = array( |
|
| 240 | - 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
| 241 | - 'html_class' => 'ee-reg-form-attendee-dv', |
|
| 242 | - 'html_style' => $this->checkout->admin_request |
|
| 243 | - ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
|
| 244 | - : '', |
|
| 245 | - 'subsections' => array(), |
|
| 246 | - 'layout_strategy' => new EE_Fieldset_Section_Layout( |
|
| 247 | - array( |
|
| 248 | - 'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text', |
|
| 249 | - 'legend_text' => sprintf(__('Attendee %d', 'event_espresso'), $attendee_nmbr), |
|
| 250 | - ) |
|
| 251 | - ), |
|
| 252 | - ); |
|
| 253 | - foreach ($question_groups as $question_group) { |
|
| 254 | - if ($question_group instanceof EE_Question_Group) { |
|
| 255 | - $form_args['subsections'][$question_group->identifier()] = $this->_question_group_reg_form( |
|
| 256 | - $registration, |
|
| 257 | - $question_group |
|
| 258 | - ); |
|
| 259 | - } |
|
| 260 | - } |
|
| 261 | - // add hidden input |
|
| 262 | - $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input( |
|
| 263 | - $registration |
|
| 264 | - ); |
|
| 265 | - // if we have question groups for additional attendees, then display the copy options |
|
| 266 | - $this->_print_copy_info = $attendee_nmbr > 1 ? true : $this->_print_copy_info; |
|
| 267 | - if ($registration->is_primary_registrant()) { |
|
| 268 | - // generate hidden input |
|
| 269 | - $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs( |
|
| 270 | - $registration |
|
| 271 | - ); |
|
| 272 | - } |
|
| 273 | - } |
|
| 274 | - } |
|
| 275 | - $attendee_nmbr++; |
|
| 276 | - return ! empty($form_args) ? new EE_Form_Section_Proper($form_args) : new EE_Form_Section_HTML(); |
|
| 277 | - } |
|
| 278 | - |
|
| 279 | - |
|
| 280 | - /** |
|
| 281 | - * _additional_attendee_reg_info_input |
|
| 282 | - * |
|
| 283 | - * @access public |
|
| 284 | - * @param EE_Registration $registration |
|
| 285 | - * @param bool $additional_attendee_reg_info |
|
| 286 | - * @return EE_Form_Input_Base |
|
| 287 | - * @throws \EE_Error |
|
| 288 | - */ |
|
| 289 | - private function _additional_attendee_reg_info_input( |
|
| 290 | - EE_Registration $registration, |
|
| 291 | - $additional_attendee_reg_info = true |
|
| 292 | - ) { |
|
| 293 | - // generate hidden input |
|
| 294 | - return new EE_Hidden_Input( |
|
| 295 | - array( |
|
| 296 | - 'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(), |
|
| 297 | - 'default' => $additional_attendee_reg_info, |
|
| 298 | - ) |
|
| 299 | - ); |
|
| 300 | - } |
|
| 301 | - |
|
| 302 | - |
|
| 303 | - /** |
|
| 304 | - * @param EE_Registration $registration |
|
| 305 | - * @param EE_Question_Group $question_group |
|
| 306 | - * @return EE_Form_Section_Proper |
|
| 307 | - * @throws EE_Error |
|
| 308 | - * @throws InvalidArgumentException |
|
| 309 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 310 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 311 | - */ |
|
| 312 | - private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group) |
|
| 313 | - { |
|
| 314 | - // array of params to pass to parent constructor |
|
| 315 | - $form_args = array( |
|
| 316 | - 'html_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier(), |
|
| 317 | - 'html_class' => $this->checkout->admin_request |
|
| 318 | - ? 'form-table ee-reg-form-qstn-grp-dv' |
|
| 319 | - : 'ee-reg-form-qstn-grp-dv', |
|
| 320 | - 'html_label_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-lbl', |
|
| 321 | - 'subsections' => array( |
|
| 322 | - 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group), |
|
| 323 | - ), |
|
| 324 | - 'layout_strategy' => $this->checkout->admin_request |
|
| 325 | - ? new EE_Admin_Two_Column_Layout() |
|
| 326 | - : new EE_Div_Per_Section_Layout(), |
|
| 327 | - ); |
|
| 328 | - // where params |
|
| 329 | - $query_params = array('QST_deleted' => 0); |
|
| 330 | - // don't load admin only questions on the frontend |
|
| 331 | - if (! $this->checkout->admin_request) { |
|
| 332 | - $query_params['QST_admin_only'] = array('!=', true); |
|
| 333 | - } |
|
| 334 | - $questions = $question_group->get_many_related( |
|
| 335 | - 'Question', |
|
| 336 | - apply_filters( |
|
| 337 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params', |
|
| 338 | - array( |
|
| 339 | - $query_params, |
|
| 340 | - 'order_by' => array( |
|
| 341 | - 'Question_Group_Question.QGQ_order' => 'ASC', |
|
| 342 | - ), |
|
| 343 | - ), |
|
| 344 | - $question_group, |
|
| 345 | - $registration, |
|
| 346 | - $this |
|
| 347 | - ) |
|
| 348 | - ); |
|
| 349 | - // filter for additional content before questions |
|
| 350 | - $form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML( |
|
| 351 | - apply_filters( |
|
| 352 | - 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', |
|
| 353 | - '', |
|
| 354 | - $registration, |
|
| 355 | - $question_group, |
|
| 356 | - $this |
|
| 357 | - ) |
|
| 358 | - ); |
|
| 359 | - // loop thru questions |
|
| 360 | - foreach ($questions as $question) { |
|
| 361 | - if ($question instanceof EE_Question) { |
|
| 362 | - $identifier = $question->is_system_question() |
|
| 363 | - ? $question->system_ID() |
|
| 364 | - : $question->ID(); |
|
| 365 | - $form_args['subsections'][$identifier] = $this->reg_form_question($registration, $question); |
|
| 366 | - } |
|
| 367 | - } |
|
| 368 | - $form_args['subsections'] = apply_filters( |
|
| 369 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array', |
|
| 370 | - $form_args['subsections'], |
|
| 371 | - $registration, |
|
| 372 | - $question_group, |
|
| 373 | - $this |
|
| 374 | - ); |
|
| 375 | - // filter for additional content after questions |
|
| 376 | - $form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML( |
|
| 377 | - apply_filters( |
|
| 378 | - 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', |
|
| 379 | - '', |
|
| 380 | - $registration, |
|
| 381 | - $question_group, |
|
| 382 | - $this |
|
| 383 | - ) |
|
| 384 | - ); |
|
| 19 | + /** |
|
| 20 | + * @type bool $_print_copy_info |
|
| 21 | + */ |
|
| 22 | + private $_print_copy_info = false; |
|
| 23 | + |
|
| 24 | + /** |
|
| 25 | + * @type array $_attendee_data |
|
| 26 | + */ |
|
| 27 | + private $_attendee_data = array(); |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * @type array $_required_questions |
|
| 31 | + */ |
|
| 32 | + private $_required_questions = array(); |
|
| 33 | + |
|
| 34 | + /** |
|
| 35 | + * @type array $_registration_answers |
|
| 36 | + */ |
|
| 37 | + private $_registration_answers = array(); |
|
| 38 | + |
|
| 39 | + |
|
| 40 | + /** |
|
| 41 | + * class constructor |
|
| 42 | + * |
|
| 43 | + * @access public |
|
| 44 | + * @param EE_Checkout $checkout |
|
| 45 | + */ |
|
| 46 | + public function __construct(EE_Checkout $checkout) |
|
| 47 | + { |
|
| 48 | + $this->_slug = 'attendee_information'; |
|
| 49 | + $this->_name = esc_html__('Attendee Information', 'event_espresso'); |
|
| 50 | + $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php'; |
|
| 51 | + $this->checkout = $checkout; |
|
| 52 | + $this->_reset_success_message(); |
|
| 53 | + $this->set_instructions( |
|
| 54 | + esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso') |
|
| 55 | + ); |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + |
|
| 59 | + public function translate_js_strings() |
|
| 60 | + { |
|
| 61 | + EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
| 62 | + ' is a required question.', |
|
| 63 | + 'event_espresso' |
|
| 64 | + ); |
|
| 65 | + EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
| 66 | + ' is a required question. Please enter a value for at least one of the options.', |
|
| 67 | + 'event_espresso' |
|
| 68 | + ); |
|
| 69 | + EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__( |
|
| 70 | + 'Please answer all required questions correctly before proceeding.', |
|
| 71 | + 'event_espresso' |
|
| 72 | + ); |
|
| 73 | + EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
| 74 | + esc_html__( |
|
| 75 | + 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.', |
|
| 76 | + 'event_espresso' |
|
| 77 | + ), |
|
| 78 | + '<br/>' |
|
| 79 | + ); |
|
| 80 | + EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
| 81 | + 'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.', |
|
| 82 | + 'event_espresso' |
|
| 83 | + ); |
|
| 84 | + EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
| 85 | + 'You must enter a valid email address.', |
|
| 86 | + 'event_espresso' |
|
| 87 | + ); |
|
| 88 | + EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__( |
|
| 89 | + 'You must enter a valid email address and answer all other required questions before you can proceed.', |
|
| 90 | + 'event_espresso' |
|
| 91 | + ); |
|
| 92 | + } |
|
| 93 | + |
|
| 94 | + |
|
| 95 | + public function enqueue_styles_and_scripts() |
|
| 96 | + { |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + |
|
| 100 | + /** |
|
| 101 | + * @return boolean |
|
| 102 | + */ |
|
| 103 | + public function initialize_reg_step() |
|
| 104 | + { |
|
| 105 | + return true; |
|
| 106 | + } |
|
| 107 | + |
|
| 108 | + |
|
| 109 | + /** |
|
| 110 | + * @return EE_Form_Section_Proper |
|
| 111 | + * @throws EE_Error |
|
| 112 | + * @throws InvalidArgumentException |
|
| 113 | + * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 114 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 115 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 116 | + */ |
|
| 117 | + public function generate_reg_form() |
|
| 118 | + { |
|
| 119 | + $this->_print_copy_info = false; |
|
| 120 | + $primary_registrant = null; |
|
| 121 | + // autoload Line_Item_Display classes |
|
| 122 | + EEH_Autoloader::register_line_item_display_autoloaders(); |
|
| 123 | + $Line_Item_Display = new EE_Line_Item_Display(); |
|
| 124 | + // calculate taxes |
|
| 125 | + $Line_Item_Display->display_line_item( |
|
| 126 | + $this->checkout->cart->get_grand_total(), |
|
| 127 | + array('set_tax_rate' => true) |
|
| 128 | + ); |
|
| 129 | + /** @var $subsections EE_Form_Section_Proper[] */ |
|
| 130 | + $subsections = array( |
|
| 131 | + 'default_hidden_inputs' => $this->reg_step_hidden_inputs(), |
|
| 132 | + ); |
|
| 133 | + $template_args = array( |
|
| 134 | + 'revisit' => $this->checkout->revisit, |
|
| 135 | + 'registrations' => array(), |
|
| 136 | + 'ticket_count' => array(), |
|
| 137 | + ); |
|
| 138 | + // grab the saved registrations from the transaction |
|
| 139 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
| 140 | + if ($registrations) { |
|
| 141 | + foreach ($registrations as $registration) { |
|
| 142 | + // can this registration be processed during this visit ? |
|
| 143 | + if ($registration instanceof EE_Registration |
|
| 144 | + && $this->checkout->visit_allows_processing_of_this_registration($registration) |
|
| 145 | + ) { |
|
| 146 | + $subsections[$registration->reg_url_link()] = $this->_registrations_reg_form($registration); |
|
| 147 | + if (! $this->checkout->admin_request) { |
|
| 148 | + $template_args['registrations'][$registration->reg_url_link()] = $registration; |
|
| 149 | + $template_args['ticket_count'][$registration->ticket()->ID()] = isset( |
|
| 150 | + $template_args['ticket_count'][$registration->ticket()->ID()] |
|
| 151 | + ) |
|
| 152 | + ? $template_args['ticket_count'][$registration->ticket()->ID()] + 1 |
|
| 153 | + : 1; |
|
| 154 | + $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 155 | + $this->checkout->cart->get_grand_total(), |
|
| 156 | + 'Ticket', |
|
| 157 | + array($registration->ticket()->ID()) |
|
| 158 | + ); |
|
| 159 | + $ticket_line_item = is_array($ticket_line_item) |
|
| 160 | + ? reset($ticket_line_item) |
|
| 161 | + : $ticket_line_item; |
|
| 162 | + $template_args['ticket_line_item'][$registration->ticket()->ID()] = |
|
| 163 | + $Line_Item_Display->display_line_item($ticket_line_item); |
|
| 164 | + } |
|
| 165 | + if ($registration->is_primary_registrant()) { |
|
| 166 | + $primary_registrant = $registration->reg_url_link(); |
|
| 167 | + } |
|
| 168 | + } |
|
| 169 | + } |
|
| 170 | + // print_copy_info ? |
|
| 171 | + if ($primary_registrant && ! $this->checkout->admin_request && count($registrations) > 1) { |
|
| 172 | + // TODO: add admin option for toggling copy attendee info, |
|
| 173 | + // then use that value to change $this->_print_copy_info |
|
| 174 | + $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info |
|
| 175 | + ? $this->_copy_attendee_info_form() |
|
| 176 | + : $this->_auto_copy_attendee_info(); |
|
| 177 | + // generate hidden input |
|
| 178 | + if (isset($subsections[$primary_registrant]) |
|
| 179 | + && $subsections[$primary_registrant] instanceof EE_Form_Section_Proper |
|
| 180 | + ) { |
|
| 181 | + $subsections[$primary_registrant]->add_subsections( |
|
| 182 | + $copy_options, |
|
| 183 | + 'primary_registrant', |
|
| 184 | + false |
|
| 185 | + ); |
|
| 186 | + } |
|
| 187 | + } |
|
| 188 | + } |
|
| 189 | + |
|
| 190 | + return new EE_Form_Section_Proper( |
|
| 191 | + array( |
|
| 192 | + 'name' => $this->reg_form_name(), |
|
| 193 | + 'html_id' => $this->reg_form_name(), |
|
| 194 | + 'subsections' => $subsections, |
|
| 195 | + 'layout_strategy' => $this->checkout->admin_request ? |
|
| 196 | + new EE_Div_Per_Section_Layout() : |
|
| 197 | + new EE_Template_Layout( |
|
| 198 | + array( |
|
| 199 | + 'layout_template_file' => $this->_template, // layout_template |
|
| 200 | + 'template_args' => $template_args, |
|
| 201 | + ) |
|
| 202 | + ), |
|
| 203 | + ) |
|
| 204 | + ); |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + |
|
| 208 | + /** |
|
| 209 | + * @param EE_Registration $registration |
|
| 210 | + * @return EE_Form_Section_Base |
|
| 211 | + * @throws EE_Error |
|
| 212 | + * @throws InvalidArgumentException |
|
| 213 | + * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 214 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 215 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 216 | + */ |
|
| 217 | + private function _registrations_reg_form(EE_Registration $registration) |
|
| 218 | + { |
|
| 219 | + static $attendee_nmbr = 1; |
|
| 220 | + $form_args = array(); |
|
| 221 | + // verify that registration has valid event |
|
| 222 | + if ($registration->event() instanceof EE_Event) { |
|
| 223 | + $question_groups = $registration->event()->question_groups( |
|
| 224 | + apply_filters( |
|
| 225 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters', |
|
| 226 | + array( |
|
| 227 | + array( |
|
| 228 | + 'Event.EVT_ID' => $registration->event()->ID(), |
|
| 229 | + 'Event_Question_Group.EQG_primary' => $registration->count() === 1 ? true : false, |
|
| 230 | + ), |
|
| 231 | + 'order_by' => array('QSG_order' => 'ASC'), |
|
| 232 | + ), |
|
| 233 | + $registration, |
|
| 234 | + $this |
|
| 235 | + ) |
|
| 236 | + ); |
|
| 237 | + if ($question_groups) { |
|
| 238 | + // array of params to pass to parent constructor |
|
| 239 | + $form_args = array( |
|
| 240 | + 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
| 241 | + 'html_class' => 'ee-reg-form-attendee-dv', |
|
| 242 | + 'html_style' => $this->checkout->admin_request |
|
| 243 | + ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
|
| 244 | + : '', |
|
| 245 | + 'subsections' => array(), |
|
| 246 | + 'layout_strategy' => new EE_Fieldset_Section_Layout( |
|
| 247 | + array( |
|
| 248 | + 'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text', |
|
| 249 | + 'legend_text' => sprintf(__('Attendee %d', 'event_espresso'), $attendee_nmbr), |
|
| 250 | + ) |
|
| 251 | + ), |
|
| 252 | + ); |
|
| 253 | + foreach ($question_groups as $question_group) { |
|
| 254 | + if ($question_group instanceof EE_Question_Group) { |
|
| 255 | + $form_args['subsections'][$question_group->identifier()] = $this->_question_group_reg_form( |
|
| 256 | + $registration, |
|
| 257 | + $question_group |
|
| 258 | + ); |
|
| 259 | + } |
|
| 260 | + } |
|
| 261 | + // add hidden input |
|
| 262 | + $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input( |
|
| 263 | + $registration |
|
| 264 | + ); |
|
| 265 | + // if we have question groups for additional attendees, then display the copy options |
|
| 266 | + $this->_print_copy_info = $attendee_nmbr > 1 ? true : $this->_print_copy_info; |
|
| 267 | + if ($registration->is_primary_registrant()) { |
|
| 268 | + // generate hidden input |
|
| 269 | + $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs( |
|
| 270 | + $registration |
|
| 271 | + ); |
|
| 272 | + } |
|
| 273 | + } |
|
| 274 | + } |
|
| 275 | + $attendee_nmbr++; |
|
| 276 | + return ! empty($form_args) ? new EE_Form_Section_Proper($form_args) : new EE_Form_Section_HTML(); |
|
| 277 | + } |
|
| 278 | + |
|
| 279 | + |
|
| 280 | + /** |
|
| 281 | + * _additional_attendee_reg_info_input |
|
| 282 | + * |
|
| 283 | + * @access public |
|
| 284 | + * @param EE_Registration $registration |
|
| 285 | + * @param bool $additional_attendee_reg_info |
|
| 286 | + * @return EE_Form_Input_Base |
|
| 287 | + * @throws \EE_Error |
|
| 288 | + */ |
|
| 289 | + private function _additional_attendee_reg_info_input( |
|
| 290 | + EE_Registration $registration, |
|
| 291 | + $additional_attendee_reg_info = true |
|
| 292 | + ) { |
|
| 293 | + // generate hidden input |
|
| 294 | + return new EE_Hidden_Input( |
|
| 295 | + array( |
|
| 296 | + 'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(), |
|
| 297 | + 'default' => $additional_attendee_reg_info, |
|
| 298 | + ) |
|
| 299 | + ); |
|
| 300 | + } |
|
| 301 | + |
|
| 302 | + |
|
| 303 | + /** |
|
| 304 | + * @param EE_Registration $registration |
|
| 305 | + * @param EE_Question_Group $question_group |
|
| 306 | + * @return EE_Form_Section_Proper |
|
| 307 | + * @throws EE_Error |
|
| 308 | + * @throws InvalidArgumentException |
|
| 309 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 310 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 311 | + */ |
|
| 312 | + private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group) |
|
| 313 | + { |
|
| 314 | + // array of params to pass to parent constructor |
|
| 315 | + $form_args = array( |
|
| 316 | + 'html_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier(), |
|
| 317 | + 'html_class' => $this->checkout->admin_request |
|
| 318 | + ? 'form-table ee-reg-form-qstn-grp-dv' |
|
| 319 | + : 'ee-reg-form-qstn-grp-dv', |
|
| 320 | + 'html_label_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-lbl', |
|
| 321 | + 'subsections' => array( |
|
| 322 | + 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group), |
|
| 323 | + ), |
|
| 324 | + 'layout_strategy' => $this->checkout->admin_request |
|
| 325 | + ? new EE_Admin_Two_Column_Layout() |
|
| 326 | + : new EE_Div_Per_Section_Layout(), |
|
| 327 | + ); |
|
| 328 | + // where params |
|
| 329 | + $query_params = array('QST_deleted' => 0); |
|
| 330 | + // don't load admin only questions on the frontend |
|
| 331 | + if (! $this->checkout->admin_request) { |
|
| 332 | + $query_params['QST_admin_only'] = array('!=', true); |
|
| 333 | + } |
|
| 334 | + $questions = $question_group->get_many_related( |
|
| 335 | + 'Question', |
|
| 336 | + apply_filters( |
|
| 337 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params', |
|
| 338 | + array( |
|
| 339 | + $query_params, |
|
| 340 | + 'order_by' => array( |
|
| 341 | + 'Question_Group_Question.QGQ_order' => 'ASC', |
|
| 342 | + ), |
|
| 343 | + ), |
|
| 344 | + $question_group, |
|
| 345 | + $registration, |
|
| 346 | + $this |
|
| 347 | + ) |
|
| 348 | + ); |
|
| 349 | + // filter for additional content before questions |
|
| 350 | + $form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML( |
|
| 351 | + apply_filters( |
|
| 352 | + 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', |
|
| 353 | + '', |
|
| 354 | + $registration, |
|
| 355 | + $question_group, |
|
| 356 | + $this |
|
| 357 | + ) |
|
| 358 | + ); |
|
| 359 | + // loop thru questions |
|
| 360 | + foreach ($questions as $question) { |
|
| 361 | + if ($question instanceof EE_Question) { |
|
| 362 | + $identifier = $question->is_system_question() |
|
| 363 | + ? $question->system_ID() |
|
| 364 | + : $question->ID(); |
|
| 365 | + $form_args['subsections'][$identifier] = $this->reg_form_question($registration, $question); |
|
| 366 | + } |
|
| 367 | + } |
|
| 368 | + $form_args['subsections'] = apply_filters( |
|
| 369 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array', |
|
| 370 | + $form_args['subsections'], |
|
| 371 | + $registration, |
|
| 372 | + $question_group, |
|
| 373 | + $this |
|
| 374 | + ); |
|
| 375 | + // filter for additional content after questions |
|
| 376 | + $form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML( |
|
| 377 | + apply_filters( |
|
| 378 | + 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', |
|
| 379 | + '', |
|
| 380 | + $registration, |
|
| 381 | + $question_group, |
|
| 382 | + $this |
|
| 383 | + ) |
|
| 384 | + ); |
|
| 385 | 385 | // d( $form_args ); |
| 386 | - $question_group_reg_form = new EE_Form_Section_Proper($form_args); |
|
| 387 | - return apply_filters( |
|
| 388 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form', |
|
| 389 | - $question_group_reg_form, |
|
| 390 | - $registration, |
|
| 391 | - $question_group, |
|
| 392 | - $this |
|
| 393 | - ); |
|
| 394 | - } |
|
| 395 | - |
|
| 396 | - |
|
| 397 | - /** |
|
| 398 | - * @access public |
|
| 399 | - * @param EE_Question_Group $question_group |
|
| 400 | - * @return EE_Form_Section_HTML |
|
| 401 | - */ |
|
| 402 | - private function _question_group_header(EE_Question_Group $question_group) |
|
| 403 | - { |
|
| 404 | - $html = ''; |
|
| 405 | - // group_name |
|
| 406 | - if ($question_group->show_group_name() && $question_group->name() !== '') { |
|
| 407 | - if ($this->checkout->admin_request) { |
|
| 408 | - $html .= EEH_HTML::br(); |
|
| 409 | - $html .= EEH_HTML::h3( |
|
| 410 | - $question_group->name(), |
|
| 411 | - '', |
|
| 412 | - 'ee-reg-form-qstn-grp-title title', |
|
| 413 | - 'font-size: 1.3em; padding-left:0;' |
|
| 414 | - ); |
|
| 415 | - } else { |
|
| 416 | - $html .= EEH_HTML::h4( |
|
| 417 | - $question_group->name(), |
|
| 418 | - '', |
|
| 419 | - 'ee-reg-form-qstn-grp-title section-title' |
|
| 420 | - ); |
|
| 421 | - } |
|
| 422 | - } |
|
| 423 | - // group_desc |
|
| 424 | - if ($question_group->show_group_desc() && $question_group->desc() !== '') { |
|
| 425 | - $html .= EEH_HTML::p( |
|
| 426 | - $question_group->desc(), |
|
| 427 | - '', |
|
| 428 | - $this->checkout->admin_request |
|
| 429 | - ? 'ee-reg-form-qstn-grp-desc-pg' |
|
| 430 | - : 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text' |
|
| 431 | - ); |
|
| 432 | - } |
|
| 433 | - return new EE_Form_Section_HTML($html); |
|
| 434 | - } |
|
| 435 | - |
|
| 436 | - |
|
| 437 | - /** |
|
| 438 | - * @access public |
|
| 439 | - * @return EE_Form_Section_Proper |
|
| 440 | - * @throws \EE_Error |
|
| 441 | - */ |
|
| 442 | - private function _copy_attendee_info_form() |
|
| 443 | - { |
|
| 444 | - // array of params to pass to parent constructor |
|
| 445 | - return new EE_Form_Section_Proper( |
|
| 446 | - array( |
|
| 447 | - 'subsections' => $this->_copy_attendee_info_inputs(), |
|
| 448 | - 'layout_strategy' => new EE_Template_Layout( |
|
| 449 | - array( |
|
| 450 | - 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
| 451 | - . $this->_slug |
|
| 452 | - . DS |
|
| 453 | - . 'copy_attendee_info.template.php', |
|
| 454 | - 'begin_template_file' => null, |
|
| 455 | - 'input_template_file' => null, |
|
| 456 | - 'subsection_template_file' => null, |
|
| 457 | - 'end_template_file' => null, |
|
| 458 | - ) |
|
| 459 | - ), |
|
| 460 | - ) |
|
| 461 | - ); |
|
| 462 | - } |
|
| 463 | - |
|
| 464 | - |
|
| 465 | - /** |
|
| 466 | - * _auto_copy_attendee_info |
|
| 467 | - * |
|
| 468 | - * @access public |
|
| 469 | - * @return EE_Form_Section_HTML |
|
| 470 | - */ |
|
| 471 | - private function _auto_copy_attendee_info() |
|
| 472 | - { |
|
| 473 | - return new EE_Form_Section_HTML( |
|
| 474 | - EEH_Template::locate_template( |
|
| 475 | - SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php', |
|
| 476 | - apply_filters( |
|
| 477 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
|
| 478 | - array() |
|
| 479 | - ), |
|
| 480 | - true, |
|
| 481 | - true |
|
| 482 | - ) |
|
| 483 | - ); |
|
| 484 | - } |
|
| 485 | - |
|
| 486 | - |
|
| 487 | - /** |
|
| 488 | - * _copy_attendee_info_inputs |
|
| 489 | - * |
|
| 490 | - * @access public |
|
| 491 | - * @return array |
|
| 492 | - * @throws \EE_Error |
|
| 493 | - */ |
|
| 494 | - private function _copy_attendee_info_inputs() |
|
| 495 | - { |
|
| 496 | - $copy_attendee_info_inputs = array(); |
|
| 497 | - $prev_ticket = null; |
|
| 498 | - // grab the saved registrations from the transaction |
|
| 499 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
| 500 | - foreach ($registrations as $registration) { |
|
| 501 | - // for all attendees other than the primary attendee |
|
| 502 | - if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) { |
|
| 503 | - // if this is a new ticket OR if this is the very first additional attendee after the primary attendee |
|
| 504 | - if ($registration->ticket()->ID() !== $prev_ticket) { |
|
| 505 | - $item_name = $registration->ticket()->name(); |
|
| 506 | - $item_name .= $registration->ticket()->description() !== '' |
|
| 507 | - ? ' - ' . $registration->ticket()->description() |
|
| 508 | - : ''; |
|
| 509 | - $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']'] = |
|
| 510 | - new EE_Form_Section_HTML( |
|
| 511 | - '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>' |
|
| 512 | - ); |
|
| 513 | - $prev_ticket = $registration->ticket()->ID(); |
|
| 514 | - } |
|
| 515 | - |
|
| 516 | - $copy_attendee_info_inputs['spco_copy_attendee_chk[' . $registration->ID() . ']'] = |
|
| 517 | - new EE_Checkbox_Multi_Input( |
|
| 518 | - array( |
|
| 519 | - $registration->ID() => sprintf( |
|
| 520 | - esc_html__('Attendee #%s', 'event_espresso'), |
|
| 521 | - $registration->count() |
|
| 522 | - ), |
|
| 523 | - ), |
|
| 524 | - array( |
|
| 525 | - 'html_id' => 'spco-copy-attendee-chk-' . $registration->reg_url_link(), |
|
| 526 | - 'html_class' => 'spco-copy-attendee-chk ee-do-not-validate', |
|
| 527 | - 'display_html_label_text' => false, |
|
| 528 | - ) |
|
| 529 | - ); |
|
| 530 | - } |
|
| 531 | - } |
|
| 532 | - return $copy_attendee_info_inputs; |
|
| 533 | - } |
|
| 534 | - |
|
| 535 | - |
|
| 536 | - /** |
|
| 537 | - * _additional_primary_registrant_inputs |
|
| 538 | - * |
|
| 539 | - * @access public |
|
| 540 | - * @param EE_Registration $registration |
|
| 541 | - * @return EE_Form_Input_Base |
|
| 542 | - * @throws \EE_Error |
|
| 543 | - */ |
|
| 544 | - private function _additional_primary_registrant_inputs(EE_Registration $registration) |
|
| 545 | - { |
|
| 546 | - // generate hidden input |
|
| 547 | - return new EE_Hidden_Input( |
|
| 548 | - array( |
|
| 549 | - 'html_id' => 'primary_registrant', |
|
| 550 | - 'default' => $registration->reg_url_link(), |
|
| 551 | - ) |
|
| 552 | - ); |
|
| 553 | - } |
|
| 554 | - |
|
| 555 | - |
|
| 556 | - /** |
|
| 557 | - * @access public |
|
| 558 | - * @param EE_Registration $registration |
|
| 559 | - * @param EE_Question $question |
|
| 560 | - * @return EE_Form_Input_Base |
|
| 561 | - * @throws EE_Error |
|
| 562 | - * @throws InvalidArgumentException |
|
| 563 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 564 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 565 | - */ |
|
| 566 | - public function reg_form_question(EE_Registration $registration, EE_Question $question) |
|
| 567 | - { |
|
| 568 | - |
|
| 569 | - // if this question was for an attendee detail, then check for that answer |
|
| 570 | - $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value( |
|
| 571 | - $registration, |
|
| 572 | - $question->system_ID() |
|
| 573 | - ); |
|
| 574 | - $answer = $answer_value === null |
|
| 575 | - ? EEM_Answer::instance()->get_one( |
|
| 576 | - array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
| 577 | - ) |
|
| 578 | - : null; |
|
| 579 | - // if NOT returning to edit an existing registration |
|
| 580 | - // OR if this question is for an attendee property |
|
| 581 | - // OR we still don't have an EE_Answer object |
|
| 582 | - if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) { |
|
| 583 | - // create an EE_Answer object for storing everything in |
|
| 584 | - $answer = EE_Answer::new_instance(array( |
|
| 585 | - 'QST_ID' => $question->ID(), |
|
| 586 | - 'REG_ID' => $registration->ID(), |
|
| 587 | - )); |
|
| 588 | - } |
|
| 589 | - // verify instance |
|
| 590 | - if ($answer instanceof EE_Answer) { |
|
| 591 | - if (! empty($answer_value)) { |
|
| 592 | - $answer->set('ANS_value', $answer_value); |
|
| 593 | - } |
|
| 594 | - $answer->cache('Question', $question); |
|
| 595 | - //remember system ID had a bug where sometimes it could be null |
|
| 596 | - $answer_cache_id = $question->is_system_question() |
|
| 597 | - ? $question->system_ID() . '-' . $registration->reg_url_link() |
|
| 598 | - : $question->ID() . '-' . $registration->reg_url_link(); |
|
| 599 | - $registration->cache('Answer', $answer, $answer_cache_id); |
|
| 600 | - } |
|
| 601 | - return $this->_generate_question_input($registration, $question, $answer); |
|
| 602 | - } |
|
| 603 | - |
|
| 604 | - |
|
| 605 | - /** |
|
| 606 | - * @param EE_Registration $registration |
|
| 607 | - * @param EE_Question $question |
|
| 608 | - * @param mixed EE_Answer|NULL $answer |
|
| 609 | - * @return EE_Form_Input_Base |
|
| 610 | - * @throws \EE_Error |
|
| 611 | - */ |
|
| 612 | - private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer) |
|
| 613 | - { |
|
| 614 | - $identifier = $question->is_system_question() |
|
| 615 | - ? $question->system_ID() |
|
| 616 | - : $question->ID(); |
|
| 617 | - $this->_required_questions[$identifier] = $question->required() ? true : false; |
|
| 618 | - add_filter( |
|
| 619 | - 'FHEE__EE_Question__generate_form_input__country_options', |
|
| 620 | - array($this, 'use_cached_countries_for_form_input'), |
|
| 621 | - 10, |
|
| 622 | - 4 |
|
| 623 | - ); |
|
| 624 | - add_filter( |
|
| 625 | - 'FHEE__EE_Question__generate_form_input__state_options', |
|
| 626 | - array($this, 'use_cached_states_for_form_input'), |
|
| 627 | - 10, |
|
| 628 | - 4 |
|
| 629 | - ); |
|
| 630 | - $input_constructor_args = array( |
|
| 631 | - 'html_name' => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']', |
|
| 632 | - 'html_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
| 633 | - 'html_class' => 'ee-reg-qstn ee-reg-qstn-' . $identifier, |
|
| 634 | - 'html_label_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
| 635 | - 'html_label_class' => 'ee-reg-qstn', |
|
| 636 | - ); |
|
| 637 | - $input_constructor_args['html_label_id'] .= '-lbl'; |
|
| 638 | - if ($answer instanceof EE_Answer && $answer->ID()) { |
|
| 639 | - $input_constructor_args['html_name'] .= '[' . $answer->ID() . ']'; |
|
| 640 | - $input_constructor_args['html_id'] .= '-' . $answer->ID(); |
|
| 641 | - $input_constructor_args['html_label_id'] .= '-' . $answer->ID(); |
|
| 642 | - } |
|
| 643 | - $form_input = $question->generate_form_input( |
|
| 644 | - $registration, |
|
| 645 | - $answer, |
|
| 646 | - $input_constructor_args |
|
| 647 | - ); |
|
| 648 | - remove_filter( |
|
| 649 | - 'FHEE__EE_Question__generate_form_input__country_options', |
|
| 650 | - array($this, 'use_cached_countries_for_form_input') |
|
| 651 | - ); |
|
| 652 | - remove_filter( |
|
| 653 | - 'FHEE__EE_Question__generate_form_input__state_options', |
|
| 654 | - array($this, 'use_cached_states_for_form_input') |
|
| 655 | - ); |
|
| 656 | - return $form_input; |
|
| 657 | - } |
|
| 658 | - |
|
| 659 | - |
|
| 660 | - /** |
|
| 661 | - * Gets the list of countries for the form input |
|
| 662 | - * |
|
| 663 | - * @param array|null $countries_list |
|
| 664 | - * @param \EE_Question $question |
|
| 665 | - * @param \EE_Registration $registration |
|
| 666 | - * @param \EE_Answer $answer |
|
| 667 | - * @return array 2d keys are country IDs, values are their names |
|
| 668 | - * @throws EE_Error |
|
| 669 | - * @throws InvalidArgumentException |
|
| 670 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 671 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 672 | - */ |
|
| 673 | - public function use_cached_countries_for_form_input( |
|
| 674 | - $countries_list, |
|
| 675 | - \EE_Question $question = null, |
|
| 676 | - \EE_Registration $registration = null, |
|
| 677 | - \EE_Answer $answer = null |
|
| 678 | - ) { |
|
| 679 | - $country_options = array('' => ''); |
|
| 680 | - // get possibly cached list of countries |
|
| 681 | - $countries = $this->checkout->action === 'process_reg_step' |
|
| 682 | - ? EEM_Country::instance()->get_all_countries() |
|
| 683 | - : EEM_Country::instance()->get_all_active_countries(); |
|
| 684 | - if (! empty($countries)) { |
|
| 685 | - foreach ($countries as $country) { |
|
| 686 | - if ($country instanceof EE_Country) { |
|
| 687 | - $country_options[$country->ID()] = $country->name(); |
|
| 688 | - } |
|
| 689 | - } |
|
| 690 | - } |
|
| 691 | - if ($question instanceof EE_Question |
|
| 692 | - && $registration instanceof EE_Registration) { |
|
| 693 | - $answer = EEM_Answer::instance()->get_one( |
|
| 694 | - array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
| 695 | - ); |
|
| 696 | - } else { |
|
| 697 | - $answer = EE_Answer::new_instance(); |
|
| 698 | - } |
|
| 699 | - $country_options = apply_filters( |
|
| 700 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options', |
|
| 701 | - $country_options, |
|
| 702 | - $this, |
|
| 703 | - $registration, |
|
| 704 | - $question, |
|
| 705 | - $answer |
|
| 706 | - ); |
|
| 707 | - return $country_options; |
|
| 708 | - } |
|
| 709 | - |
|
| 710 | - |
|
| 711 | - /** |
|
| 712 | - * Gets the list of states for the form input |
|
| 713 | - * |
|
| 714 | - * @param array|null $states_list |
|
| 715 | - * @param \EE_Question $question |
|
| 716 | - * @param \EE_Registration $registration |
|
| 717 | - * @param \EE_Answer $answer |
|
| 718 | - * @return array 2d keys are state IDs, values are their names |
|
| 719 | - * @throws EE_Error |
|
| 720 | - * @throws InvalidArgumentException |
|
| 721 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 722 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 723 | - */ |
|
| 724 | - public function use_cached_states_for_form_input( |
|
| 725 | - $states_list, |
|
| 726 | - \EE_Question $question = null, |
|
| 727 | - \EE_Registration $registration = null, |
|
| 728 | - \EE_Answer $answer = null |
|
| 729 | - ) { |
|
| 730 | - $state_options = array('' => array('' => '')); |
|
| 731 | - $states = $this->checkout->action === 'process_reg_step' |
|
| 732 | - ? EEM_State::instance()->get_all_states() |
|
| 733 | - : EEM_State::instance()->get_all_active_states(); |
|
| 734 | - if (! empty($states)) { |
|
| 735 | - foreach ($states as $state) { |
|
| 736 | - if ($state instanceof EE_State) { |
|
| 737 | - $state_options[$state->country()->name()][$state->ID()] = $state->name(); |
|
| 738 | - } |
|
| 739 | - } |
|
| 740 | - } |
|
| 741 | - $state_options = apply_filters( |
|
| 742 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options', |
|
| 743 | - $state_options, |
|
| 744 | - $this, |
|
| 745 | - $registration, |
|
| 746 | - $question, |
|
| 747 | - $answer |
|
| 748 | - ); |
|
| 749 | - return $state_options; |
|
| 750 | - } |
|
| 751 | - |
|
| 752 | - |
|
| 753 | - |
|
| 754 | - |
|
| 755 | - |
|
| 756 | - |
|
| 757 | - /********************************************************************************************************/ |
|
| 758 | - /**************************************** PROCESS REG STEP ****************************************/ |
|
| 759 | - /********************************************************************************************************/ |
|
| 760 | - /** |
|
| 761 | - * @return bool |
|
| 762 | - * @throws EE_Error |
|
| 763 | - * @throws InvalidArgumentException |
|
| 764 | - * @throws ReflectionException |
|
| 765 | - * @throws RuntimeException |
|
| 766 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 767 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 768 | - */ |
|
| 769 | - public function process_reg_step() |
|
| 770 | - { |
|
| 771 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 772 | - // grab validated data from form |
|
| 773 | - $valid_data = $this->checkout->current_step->valid_data(); |
|
| 774 | - // EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
| 775 | - // EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ ); |
|
| 776 | - // if we don't have any $valid_data then something went TERRIBLY WRONG !!! |
|
| 777 | - if (empty($valid_data)) { |
|
| 778 | - EE_Error::add_error( |
|
| 779 | - esc_html__('No valid question responses were received.', 'event_espresso'), |
|
| 780 | - __FILE__, |
|
| 781 | - __FUNCTION__, |
|
| 782 | - __LINE__ |
|
| 783 | - ); |
|
| 784 | - return false; |
|
| 785 | - } |
|
| 786 | - if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
| 787 | - EE_Error::add_error( |
|
| 788 | - esc_html__( |
|
| 789 | - 'A valid transaction could not be initiated for processing your registrations.', |
|
| 790 | - 'event_espresso' |
|
| 791 | - ), |
|
| 792 | - __FILE__, |
|
| 793 | - __FUNCTION__, |
|
| 794 | - __LINE__ |
|
| 795 | - ); |
|
| 796 | - return false; |
|
| 797 | - } |
|
| 798 | - // get cached registrations |
|
| 799 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
| 800 | - // verify we got the goods |
|
| 801 | - if (empty($registrations)) { |
|
| 802 | - EE_Error::add_error( |
|
| 803 | - esc_html__('Your form data could not be applied to any valid registrations.', 'event_espresso'), |
|
| 804 | - __FILE__, |
|
| 805 | - __FUNCTION__, |
|
| 806 | - __LINE__ |
|
| 807 | - ); |
|
| 808 | - return false; |
|
| 809 | - } |
|
| 810 | - // extract attendee info from form data and save to model objects |
|
| 811 | - $registrations_processed = $this->_process_registrations($registrations, $valid_data); |
|
| 812 | - // if first pass thru SPCO, |
|
| 813 | - // then let's check processed registrations against the total number of tickets in the cart |
|
| 814 | - if ($registrations_processed === false) { |
|
| 815 | - // but return immediately if the previous step exited early due to errors |
|
| 816 | - return false; |
|
| 817 | - } elseif (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
| 818 | - // generate a correctly translated string for all possible singular/plural combinations |
|
| 819 | - if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
|
| 820 | - $error_msg = sprintf( |
|
| 821 | - esc_html__( |
|
| 822 | - 'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed', |
|
| 823 | - 'event_espresso' |
|
| 824 | - ), |
|
| 825 | - $this->checkout->total_ticket_count, |
|
| 826 | - $registrations_processed |
|
| 827 | - ); |
|
| 828 | - } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) { |
|
| 829 | - $error_msg = sprintf( |
|
| 830 | - esc_html__( |
|
| 831 | - 'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed', |
|
| 832 | - 'event_espresso' |
|
| 833 | - ), |
|
| 834 | - $this->checkout->total_ticket_count, |
|
| 835 | - $registrations_processed |
|
| 836 | - ); |
|
| 837 | - } else { |
|
| 838 | - $error_msg = sprintf( |
|
| 839 | - esc_html__( |
|
| 840 | - 'There was a total of %1$d tickets in the Event Queue, but %2$ds registrations were processed', |
|
| 841 | - 'event_espresso' |
|
| 842 | - ), |
|
| 843 | - $this->checkout->total_ticket_count, |
|
| 844 | - $registrations_processed |
|
| 845 | - ); |
|
| 846 | - } |
|
| 847 | - EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 848 | - return false; |
|
| 849 | - } |
|
| 850 | - // mark this reg step as completed |
|
| 851 | - $this->set_completed(); |
|
| 852 | - $this->_set_success_message( |
|
| 853 | - esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso') |
|
| 854 | - ); |
|
| 855 | - //do action in case a plugin wants to do something with the data submitted in step 1. |
|
| 856 | - //passes EE_Single_Page_Checkout, and it's posted data |
|
| 857 | - do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data); |
|
| 858 | - return true; |
|
| 859 | - } |
|
| 860 | - |
|
| 861 | - |
|
| 862 | - /** |
|
| 863 | - * _process_registrations |
|
| 864 | - * |
|
| 865 | - * @param EE_Registration[] $registrations |
|
| 866 | - * @param array $valid_data |
|
| 867 | - * @return bool|int |
|
| 868 | - * @throws EE_Error |
|
| 869 | - * @throws InvalidArgumentException |
|
| 870 | - * @throws ReflectionException |
|
| 871 | - * @throws RuntimeException |
|
| 872 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 873 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 874 | - */ |
|
| 875 | - private function _process_registrations($registrations = array(), $valid_data = array()) |
|
| 876 | - { |
|
| 877 | - // load resources and set some defaults |
|
| 878 | - EE_Registry::instance()->load_model('Attendee'); |
|
| 879 | - // holder for primary registrant attendee object |
|
| 880 | - $this->checkout->primary_attendee_obj = null; |
|
| 881 | - // array for tracking reg form data for the primary registrant |
|
| 882 | - $primary_registrant = array( |
|
| 883 | - 'line_item_id' => null, |
|
| 884 | - ); |
|
| 885 | - $copy_primary = false; |
|
| 886 | - // reg form sections that do not contain inputs |
|
| 887 | - $non_input_form_sections = array( |
|
| 888 | - 'primary_registrant', |
|
| 889 | - 'additional_attendee_reg_info', |
|
| 890 | - 'spco_copy_attendee_chk', |
|
| 891 | - ); |
|
| 892 | - // attendee counter |
|
| 893 | - $att_nmbr = 0; |
|
| 894 | - // grab the saved registrations from the transaction |
|
| 895 | - foreach ($registrations as $registration) { |
|
| 896 | - // verify EE_Registration object |
|
| 897 | - if (! $registration instanceof EE_Registration) { |
|
| 898 | - EE_Error::add_error( |
|
| 899 | - esc_html__( |
|
| 900 | - 'An invalid Registration object was discovered when attempting to process your registration information.', |
|
| 901 | - 'event_espresso' |
|
| 902 | - ), |
|
| 903 | - __FILE__, |
|
| 904 | - __FUNCTION__, |
|
| 905 | - __LINE__ |
|
| 906 | - ); |
|
| 907 | - return false; |
|
| 908 | - } |
|
| 909 | - /** @var string $reg_url_link */ |
|
| 910 | - $reg_url_link = $registration->reg_url_link(); |
|
| 911 | - // reg_url_link exists ? |
|
| 912 | - if (! empty($reg_url_link)) { |
|
| 913 | - // should this registration be processed during this visit ? |
|
| 914 | - if ($this->checkout->visit_allows_processing_of_this_registration($registration)) { |
|
| 915 | - // if NOT revisiting, then let's save the registration now, |
|
| 916 | - // so that we have a REG_ID to use when generating other objects |
|
| 917 | - if (! $this->checkout->revisit) { |
|
| 918 | - $registration->save(); |
|
| 919 | - } |
|
| 920 | - /** |
|
| 921 | - * This allows plugins to trigger a fail on processing of a |
|
| 922 | - * registration for any conditions they may have for it to pass. |
|
| 923 | - * |
|
| 924 | - * @var bool if true is returned by the plugin then the |
|
| 925 | - * registration processing is halted. |
|
| 926 | - */ |
|
| 927 | - if (apply_filters( |
|
| 928 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process', |
|
| 929 | - false, |
|
| 930 | - $att_nmbr, |
|
| 931 | - $registration, |
|
| 932 | - $registrations, |
|
| 933 | - $valid_data, |
|
| 934 | - $this |
|
| 935 | - )) { |
|
| 936 | - return false; |
|
| 937 | - } |
|
| 938 | - |
|
| 939 | - // Houston, we have a registration! |
|
| 940 | - $att_nmbr++; |
|
| 941 | - $this->_attendee_data[$reg_url_link] = array(); |
|
| 942 | - // grab any existing related answer objects |
|
| 943 | - $this->_registration_answers = $registration->answers(); |
|
| 944 | - // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ); |
|
| 945 | - if (isset($valid_data[$reg_url_link])) { |
|
| 946 | - // do we need to copy basic info from primary attendee ? |
|
| 947 | - $copy_primary = isset($valid_data[$reg_url_link]['additional_attendee_reg_info']) |
|
| 948 | - && absint($valid_data[$reg_url_link]['additional_attendee_reg_info']) === 0 |
|
| 949 | - ? true |
|
| 950 | - : false; |
|
| 951 | - // filter form input data for this registration |
|
| 952 | - $valid_data[$reg_url_link] = (array)apply_filters( |
|
| 953 | - 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
|
| 954 | - $valid_data[$reg_url_link] |
|
| 955 | - ); |
|
| 956 | - if (isset($valid_data['primary_attendee'])) { |
|
| 957 | - $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee']) |
|
| 958 | - ? $valid_data['primary_attendee'] |
|
| 959 | - : false; |
|
| 960 | - unset($valid_data['primary_attendee']); |
|
| 961 | - } |
|
| 962 | - // now loop through our array of valid post data && process attendee reg forms |
|
| 963 | - foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) { |
|
| 964 | - if (! in_array($form_section, $non_input_form_sections)) { |
|
| 965 | - foreach ($form_inputs as $form_input => $input_value) { |
|
| 966 | - // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ ); |
|
| 967 | - // check for critical inputs |
|
| 968 | - if (! $this->_verify_critical_attendee_details_are_set_and_validate_email( |
|
| 969 | - $form_input, |
|
| 970 | - $input_value |
|
| 971 | - ) |
|
| 972 | - ) { |
|
| 973 | - return false; |
|
| 974 | - } |
|
| 975 | - // store a bit of data about the primary attendee |
|
| 976 | - if ($att_nmbr === 1 |
|
| 977 | - && ! empty($input_value) |
|
| 978 | - && $reg_url_link === $primary_registrant['line_item_id'] |
|
| 979 | - ) { |
|
| 980 | - $primary_registrant[$form_input] = $input_value; |
|
| 981 | - } elseif ($copy_primary |
|
| 982 | - && $input_value === null |
|
| 983 | - && isset($primary_registrant[$form_input]) |
|
| 984 | - ) { |
|
| 985 | - $input_value = $primary_registrant[$form_input]; |
|
| 986 | - } |
|
| 987 | - // now attempt to save the input data |
|
| 988 | - if (! $this->_save_registration_form_input( |
|
| 989 | - $registration, |
|
| 990 | - $form_input, |
|
| 991 | - $input_value |
|
| 992 | - ) |
|
| 993 | - ) { |
|
| 994 | - EE_Error::add_error( |
|
| 995 | - sprintf( |
|
| 996 | - esc_html__( |
|
| 997 | - 'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"', |
|
| 998 | - 'event_espresso' |
|
| 999 | - ), |
|
| 1000 | - $form_input, |
|
| 1001 | - $input_value |
|
| 1002 | - ), |
|
| 1003 | - __FILE__, |
|
| 1004 | - __FUNCTION__, |
|
| 1005 | - __LINE__ |
|
| 1006 | - ); |
|
| 1007 | - return false; |
|
| 1008 | - } |
|
| 1009 | - } |
|
| 1010 | - } |
|
| 1011 | - } // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs ) |
|
| 1012 | - } |
|
| 1013 | - //EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ ); |
|
| 1014 | - // this registration does not require additional attendee information ? |
|
| 1015 | - if ($copy_primary |
|
| 1016 | - && $att_nmbr > 1 |
|
| 1017 | - && $this->checkout->primary_attendee_obj instanceof EE_Attendee |
|
| 1018 | - ) { |
|
| 1019 | - // just copy the primary registrant |
|
| 1020 | - $attendee = $this->checkout->primary_attendee_obj; |
|
| 1021 | - } else { |
|
| 1022 | - // ensure critical details are set for additional attendees |
|
| 1023 | - $this->_attendee_data[$reg_url_link] = $att_nmbr > 1 |
|
| 1024 | - ? $this->_copy_critical_attendee_details_from_primary_registrant( |
|
| 1025 | - $this->_attendee_data[$reg_url_link] |
|
| 1026 | - ) |
|
| 1027 | - : $this->_attendee_data[$reg_url_link]; |
|
| 1028 | - // execute create attendee command (which may return an existing attendee) |
|
| 1029 | - $attendee = EE_Registry::instance()->BUS->execute( |
|
| 1030 | - new CreateAttendeeCommand( |
|
| 1031 | - $this->_attendee_data[$reg_url_link], |
|
| 1032 | - $registration |
|
| 1033 | - ) |
|
| 1034 | - ); |
|
| 1035 | - // who's #1 ? |
|
| 1036 | - if ($att_nmbr === 1) { |
|
| 1037 | - $this->checkout->primary_attendee_obj = $attendee; |
|
| 1038 | - } |
|
| 1039 | - } |
|
| 1040 | - // EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ ); |
|
| 1041 | - // add relation to registration, set attendee ID, and cache attendee |
|
| 1042 | - $this->_associate_attendee_with_registration($registration, $attendee); |
|
| 1043 | - // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ ); |
|
| 1044 | - if (! $registration->attendee() instanceof EE_Attendee) { |
|
| 1045 | - EE_Error::add_error( |
|
| 1046 | - sprintf( |
|
| 1047 | - esc_html__( |
|
| 1048 | - 'Registration %s has an invalid or missing Attendee object.', |
|
| 1049 | - 'event_espresso' |
|
| 1050 | - ), |
|
| 1051 | - $reg_url_link |
|
| 1052 | - ), |
|
| 1053 | - __FILE__, |
|
| 1054 | - __FUNCTION__, |
|
| 1055 | - __LINE__ |
|
| 1056 | - ); |
|
| 1057 | - return false; |
|
| 1058 | - } |
|
| 1059 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 1060 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 1061 | - // at this point, we should have enough details about the registrant to consider the registration |
|
| 1062 | - // NOT incomplete |
|
| 1063 | - $registration_processor->toggle_incomplete_registration_status_to_default($registration, false); |
|
| 1064 | - // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to |
|
| 1065 | - // abandoned |
|
| 1066 | - $this->checkout->transaction->toggle_failed_transaction_status(); |
|
| 1067 | - // if we've gotten this far, then let's save what we have |
|
| 1068 | - $registration->save(); |
|
| 1069 | - // add relation between TXN and registration |
|
| 1070 | - $this->_associate_registration_with_transaction($registration); |
|
| 1071 | - } |
|
| 1072 | - } else { |
|
| 1073 | - EE_Error::add_error( |
|
| 1074 | - esc_html__( |
|
| 1075 | - 'An invalid or missing line item ID was encountered while attempting to process the registration form.', |
|
| 1076 | - 'event_espresso' |
|
| 1077 | - ), |
|
| 1078 | - __FILE__, |
|
| 1079 | - __FUNCTION__, |
|
| 1080 | - __LINE__ |
|
| 1081 | - ); |
|
| 1082 | - // remove malformed data |
|
| 1083 | - unset($valid_data[$reg_url_link]); |
|
| 1084 | - return false; |
|
| 1085 | - } |
|
| 1086 | - |
|
| 1087 | - } // end of foreach ( $this->checkout->transaction->registrations() as $registration ) |
|
| 1088 | - return $att_nmbr; |
|
| 1089 | - } |
|
| 1090 | - |
|
| 1091 | - |
|
| 1092 | - /** |
|
| 1093 | - * _save_registration_form_input |
|
| 1094 | - * |
|
| 1095 | - * @param EE_Registration $registration |
|
| 1096 | - * @param string $form_input |
|
| 1097 | - * @param string $input_value |
|
| 1098 | - * @return bool |
|
| 1099 | - * @throws EE_Error |
|
| 1100 | - * @throws InvalidArgumentException |
|
| 1101 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 1102 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 1103 | - */ |
|
| 1104 | - private function _save_registration_form_input( |
|
| 1105 | - EE_Registration $registration, |
|
| 1106 | - $form_input = '', |
|
| 1107 | - $input_value = '' |
|
| 1108 | - ) { |
|
| 1109 | - // \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 ); |
|
| 1110 | - // \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ ); |
|
| 1111 | - // \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ ); |
|
| 1112 | - // allow for plugins to hook in and do their own processing of the form input. |
|
| 1113 | - // For plugins to bypass normal processing here, they just need to return a boolean value. |
|
| 1114 | - if (apply_filters( |
|
| 1115 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input', |
|
| 1116 | - false, |
|
| 1117 | - $registration, |
|
| 1118 | - $form_input, |
|
| 1119 | - $input_value, |
|
| 1120 | - $this |
|
| 1121 | - )) { |
|
| 1122 | - return true; |
|
| 1123 | - } |
|
| 1124 | - /* |
|
| 386 | + $question_group_reg_form = new EE_Form_Section_Proper($form_args); |
|
| 387 | + return apply_filters( |
|
| 388 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form', |
|
| 389 | + $question_group_reg_form, |
|
| 390 | + $registration, |
|
| 391 | + $question_group, |
|
| 392 | + $this |
|
| 393 | + ); |
|
| 394 | + } |
|
| 395 | + |
|
| 396 | + |
|
| 397 | + /** |
|
| 398 | + * @access public |
|
| 399 | + * @param EE_Question_Group $question_group |
|
| 400 | + * @return EE_Form_Section_HTML |
|
| 401 | + */ |
|
| 402 | + private function _question_group_header(EE_Question_Group $question_group) |
|
| 403 | + { |
|
| 404 | + $html = ''; |
|
| 405 | + // group_name |
|
| 406 | + if ($question_group->show_group_name() && $question_group->name() !== '') { |
|
| 407 | + if ($this->checkout->admin_request) { |
|
| 408 | + $html .= EEH_HTML::br(); |
|
| 409 | + $html .= EEH_HTML::h3( |
|
| 410 | + $question_group->name(), |
|
| 411 | + '', |
|
| 412 | + 'ee-reg-form-qstn-grp-title title', |
|
| 413 | + 'font-size: 1.3em; padding-left:0;' |
|
| 414 | + ); |
|
| 415 | + } else { |
|
| 416 | + $html .= EEH_HTML::h4( |
|
| 417 | + $question_group->name(), |
|
| 418 | + '', |
|
| 419 | + 'ee-reg-form-qstn-grp-title section-title' |
|
| 420 | + ); |
|
| 421 | + } |
|
| 422 | + } |
|
| 423 | + // group_desc |
|
| 424 | + if ($question_group->show_group_desc() && $question_group->desc() !== '') { |
|
| 425 | + $html .= EEH_HTML::p( |
|
| 426 | + $question_group->desc(), |
|
| 427 | + '', |
|
| 428 | + $this->checkout->admin_request |
|
| 429 | + ? 'ee-reg-form-qstn-grp-desc-pg' |
|
| 430 | + : 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text' |
|
| 431 | + ); |
|
| 432 | + } |
|
| 433 | + return new EE_Form_Section_HTML($html); |
|
| 434 | + } |
|
| 435 | + |
|
| 436 | + |
|
| 437 | + /** |
|
| 438 | + * @access public |
|
| 439 | + * @return EE_Form_Section_Proper |
|
| 440 | + * @throws \EE_Error |
|
| 441 | + */ |
|
| 442 | + private function _copy_attendee_info_form() |
|
| 443 | + { |
|
| 444 | + // array of params to pass to parent constructor |
|
| 445 | + return new EE_Form_Section_Proper( |
|
| 446 | + array( |
|
| 447 | + 'subsections' => $this->_copy_attendee_info_inputs(), |
|
| 448 | + 'layout_strategy' => new EE_Template_Layout( |
|
| 449 | + array( |
|
| 450 | + 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
| 451 | + . $this->_slug |
|
| 452 | + . DS |
|
| 453 | + . 'copy_attendee_info.template.php', |
|
| 454 | + 'begin_template_file' => null, |
|
| 455 | + 'input_template_file' => null, |
|
| 456 | + 'subsection_template_file' => null, |
|
| 457 | + 'end_template_file' => null, |
|
| 458 | + ) |
|
| 459 | + ), |
|
| 460 | + ) |
|
| 461 | + ); |
|
| 462 | + } |
|
| 463 | + |
|
| 464 | + |
|
| 465 | + /** |
|
| 466 | + * _auto_copy_attendee_info |
|
| 467 | + * |
|
| 468 | + * @access public |
|
| 469 | + * @return EE_Form_Section_HTML |
|
| 470 | + */ |
|
| 471 | + private function _auto_copy_attendee_info() |
|
| 472 | + { |
|
| 473 | + return new EE_Form_Section_HTML( |
|
| 474 | + EEH_Template::locate_template( |
|
| 475 | + SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php', |
|
| 476 | + apply_filters( |
|
| 477 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
|
| 478 | + array() |
|
| 479 | + ), |
|
| 480 | + true, |
|
| 481 | + true |
|
| 482 | + ) |
|
| 483 | + ); |
|
| 484 | + } |
|
| 485 | + |
|
| 486 | + |
|
| 487 | + /** |
|
| 488 | + * _copy_attendee_info_inputs |
|
| 489 | + * |
|
| 490 | + * @access public |
|
| 491 | + * @return array |
|
| 492 | + * @throws \EE_Error |
|
| 493 | + */ |
|
| 494 | + private function _copy_attendee_info_inputs() |
|
| 495 | + { |
|
| 496 | + $copy_attendee_info_inputs = array(); |
|
| 497 | + $prev_ticket = null; |
|
| 498 | + // grab the saved registrations from the transaction |
|
| 499 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
| 500 | + foreach ($registrations as $registration) { |
|
| 501 | + // for all attendees other than the primary attendee |
|
| 502 | + if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) { |
|
| 503 | + // if this is a new ticket OR if this is the very first additional attendee after the primary attendee |
|
| 504 | + if ($registration->ticket()->ID() !== $prev_ticket) { |
|
| 505 | + $item_name = $registration->ticket()->name(); |
|
| 506 | + $item_name .= $registration->ticket()->description() !== '' |
|
| 507 | + ? ' - ' . $registration->ticket()->description() |
|
| 508 | + : ''; |
|
| 509 | + $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']'] = |
|
| 510 | + new EE_Form_Section_HTML( |
|
| 511 | + '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>' |
|
| 512 | + ); |
|
| 513 | + $prev_ticket = $registration->ticket()->ID(); |
|
| 514 | + } |
|
| 515 | + |
|
| 516 | + $copy_attendee_info_inputs['spco_copy_attendee_chk[' . $registration->ID() . ']'] = |
|
| 517 | + new EE_Checkbox_Multi_Input( |
|
| 518 | + array( |
|
| 519 | + $registration->ID() => sprintf( |
|
| 520 | + esc_html__('Attendee #%s', 'event_espresso'), |
|
| 521 | + $registration->count() |
|
| 522 | + ), |
|
| 523 | + ), |
|
| 524 | + array( |
|
| 525 | + 'html_id' => 'spco-copy-attendee-chk-' . $registration->reg_url_link(), |
|
| 526 | + 'html_class' => 'spco-copy-attendee-chk ee-do-not-validate', |
|
| 527 | + 'display_html_label_text' => false, |
|
| 528 | + ) |
|
| 529 | + ); |
|
| 530 | + } |
|
| 531 | + } |
|
| 532 | + return $copy_attendee_info_inputs; |
|
| 533 | + } |
|
| 534 | + |
|
| 535 | + |
|
| 536 | + /** |
|
| 537 | + * _additional_primary_registrant_inputs |
|
| 538 | + * |
|
| 539 | + * @access public |
|
| 540 | + * @param EE_Registration $registration |
|
| 541 | + * @return EE_Form_Input_Base |
|
| 542 | + * @throws \EE_Error |
|
| 543 | + */ |
|
| 544 | + private function _additional_primary_registrant_inputs(EE_Registration $registration) |
|
| 545 | + { |
|
| 546 | + // generate hidden input |
|
| 547 | + return new EE_Hidden_Input( |
|
| 548 | + array( |
|
| 549 | + 'html_id' => 'primary_registrant', |
|
| 550 | + 'default' => $registration->reg_url_link(), |
|
| 551 | + ) |
|
| 552 | + ); |
|
| 553 | + } |
|
| 554 | + |
|
| 555 | + |
|
| 556 | + /** |
|
| 557 | + * @access public |
|
| 558 | + * @param EE_Registration $registration |
|
| 559 | + * @param EE_Question $question |
|
| 560 | + * @return EE_Form_Input_Base |
|
| 561 | + * @throws EE_Error |
|
| 562 | + * @throws InvalidArgumentException |
|
| 563 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 564 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 565 | + */ |
|
| 566 | + public function reg_form_question(EE_Registration $registration, EE_Question $question) |
|
| 567 | + { |
|
| 568 | + |
|
| 569 | + // if this question was for an attendee detail, then check for that answer |
|
| 570 | + $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value( |
|
| 571 | + $registration, |
|
| 572 | + $question->system_ID() |
|
| 573 | + ); |
|
| 574 | + $answer = $answer_value === null |
|
| 575 | + ? EEM_Answer::instance()->get_one( |
|
| 576 | + array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
| 577 | + ) |
|
| 578 | + : null; |
|
| 579 | + // if NOT returning to edit an existing registration |
|
| 580 | + // OR if this question is for an attendee property |
|
| 581 | + // OR we still don't have an EE_Answer object |
|
| 582 | + if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) { |
|
| 583 | + // create an EE_Answer object for storing everything in |
|
| 584 | + $answer = EE_Answer::new_instance(array( |
|
| 585 | + 'QST_ID' => $question->ID(), |
|
| 586 | + 'REG_ID' => $registration->ID(), |
|
| 587 | + )); |
|
| 588 | + } |
|
| 589 | + // verify instance |
|
| 590 | + if ($answer instanceof EE_Answer) { |
|
| 591 | + if (! empty($answer_value)) { |
|
| 592 | + $answer->set('ANS_value', $answer_value); |
|
| 593 | + } |
|
| 594 | + $answer->cache('Question', $question); |
|
| 595 | + //remember system ID had a bug where sometimes it could be null |
|
| 596 | + $answer_cache_id = $question->is_system_question() |
|
| 597 | + ? $question->system_ID() . '-' . $registration->reg_url_link() |
|
| 598 | + : $question->ID() . '-' . $registration->reg_url_link(); |
|
| 599 | + $registration->cache('Answer', $answer, $answer_cache_id); |
|
| 600 | + } |
|
| 601 | + return $this->_generate_question_input($registration, $question, $answer); |
|
| 602 | + } |
|
| 603 | + |
|
| 604 | + |
|
| 605 | + /** |
|
| 606 | + * @param EE_Registration $registration |
|
| 607 | + * @param EE_Question $question |
|
| 608 | + * @param mixed EE_Answer|NULL $answer |
|
| 609 | + * @return EE_Form_Input_Base |
|
| 610 | + * @throws \EE_Error |
|
| 611 | + */ |
|
| 612 | + private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer) |
|
| 613 | + { |
|
| 614 | + $identifier = $question->is_system_question() |
|
| 615 | + ? $question->system_ID() |
|
| 616 | + : $question->ID(); |
|
| 617 | + $this->_required_questions[$identifier] = $question->required() ? true : false; |
|
| 618 | + add_filter( |
|
| 619 | + 'FHEE__EE_Question__generate_form_input__country_options', |
|
| 620 | + array($this, 'use_cached_countries_for_form_input'), |
|
| 621 | + 10, |
|
| 622 | + 4 |
|
| 623 | + ); |
|
| 624 | + add_filter( |
|
| 625 | + 'FHEE__EE_Question__generate_form_input__state_options', |
|
| 626 | + array($this, 'use_cached_states_for_form_input'), |
|
| 627 | + 10, |
|
| 628 | + 4 |
|
| 629 | + ); |
|
| 630 | + $input_constructor_args = array( |
|
| 631 | + 'html_name' => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']', |
|
| 632 | + 'html_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
| 633 | + 'html_class' => 'ee-reg-qstn ee-reg-qstn-' . $identifier, |
|
| 634 | + 'html_label_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
| 635 | + 'html_label_class' => 'ee-reg-qstn', |
|
| 636 | + ); |
|
| 637 | + $input_constructor_args['html_label_id'] .= '-lbl'; |
|
| 638 | + if ($answer instanceof EE_Answer && $answer->ID()) { |
|
| 639 | + $input_constructor_args['html_name'] .= '[' . $answer->ID() . ']'; |
|
| 640 | + $input_constructor_args['html_id'] .= '-' . $answer->ID(); |
|
| 641 | + $input_constructor_args['html_label_id'] .= '-' . $answer->ID(); |
|
| 642 | + } |
|
| 643 | + $form_input = $question->generate_form_input( |
|
| 644 | + $registration, |
|
| 645 | + $answer, |
|
| 646 | + $input_constructor_args |
|
| 647 | + ); |
|
| 648 | + remove_filter( |
|
| 649 | + 'FHEE__EE_Question__generate_form_input__country_options', |
|
| 650 | + array($this, 'use_cached_countries_for_form_input') |
|
| 651 | + ); |
|
| 652 | + remove_filter( |
|
| 653 | + 'FHEE__EE_Question__generate_form_input__state_options', |
|
| 654 | + array($this, 'use_cached_states_for_form_input') |
|
| 655 | + ); |
|
| 656 | + return $form_input; |
|
| 657 | + } |
|
| 658 | + |
|
| 659 | + |
|
| 660 | + /** |
|
| 661 | + * Gets the list of countries for the form input |
|
| 662 | + * |
|
| 663 | + * @param array|null $countries_list |
|
| 664 | + * @param \EE_Question $question |
|
| 665 | + * @param \EE_Registration $registration |
|
| 666 | + * @param \EE_Answer $answer |
|
| 667 | + * @return array 2d keys are country IDs, values are their names |
|
| 668 | + * @throws EE_Error |
|
| 669 | + * @throws InvalidArgumentException |
|
| 670 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 671 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 672 | + */ |
|
| 673 | + public function use_cached_countries_for_form_input( |
|
| 674 | + $countries_list, |
|
| 675 | + \EE_Question $question = null, |
|
| 676 | + \EE_Registration $registration = null, |
|
| 677 | + \EE_Answer $answer = null |
|
| 678 | + ) { |
|
| 679 | + $country_options = array('' => ''); |
|
| 680 | + // get possibly cached list of countries |
|
| 681 | + $countries = $this->checkout->action === 'process_reg_step' |
|
| 682 | + ? EEM_Country::instance()->get_all_countries() |
|
| 683 | + : EEM_Country::instance()->get_all_active_countries(); |
|
| 684 | + if (! empty($countries)) { |
|
| 685 | + foreach ($countries as $country) { |
|
| 686 | + if ($country instanceof EE_Country) { |
|
| 687 | + $country_options[$country->ID()] = $country->name(); |
|
| 688 | + } |
|
| 689 | + } |
|
| 690 | + } |
|
| 691 | + if ($question instanceof EE_Question |
|
| 692 | + && $registration instanceof EE_Registration) { |
|
| 693 | + $answer = EEM_Answer::instance()->get_one( |
|
| 694 | + array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
| 695 | + ); |
|
| 696 | + } else { |
|
| 697 | + $answer = EE_Answer::new_instance(); |
|
| 698 | + } |
|
| 699 | + $country_options = apply_filters( |
|
| 700 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options', |
|
| 701 | + $country_options, |
|
| 702 | + $this, |
|
| 703 | + $registration, |
|
| 704 | + $question, |
|
| 705 | + $answer |
|
| 706 | + ); |
|
| 707 | + return $country_options; |
|
| 708 | + } |
|
| 709 | + |
|
| 710 | + |
|
| 711 | + /** |
|
| 712 | + * Gets the list of states for the form input |
|
| 713 | + * |
|
| 714 | + * @param array|null $states_list |
|
| 715 | + * @param \EE_Question $question |
|
| 716 | + * @param \EE_Registration $registration |
|
| 717 | + * @param \EE_Answer $answer |
|
| 718 | + * @return array 2d keys are state IDs, values are their names |
|
| 719 | + * @throws EE_Error |
|
| 720 | + * @throws InvalidArgumentException |
|
| 721 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 722 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 723 | + */ |
|
| 724 | + public function use_cached_states_for_form_input( |
|
| 725 | + $states_list, |
|
| 726 | + \EE_Question $question = null, |
|
| 727 | + \EE_Registration $registration = null, |
|
| 728 | + \EE_Answer $answer = null |
|
| 729 | + ) { |
|
| 730 | + $state_options = array('' => array('' => '')); |
|
| 731 | + $states = $this->checkout->action === 'process_reg_step' |
|
| 732 | + ? EEM_State::instance()->get_all_states() |
|
| 733 | + : EEM_State::instance()->get_all_active_states(); |
|
| 734 | + if (! empty($states)) { |
|
| 735 | + foreach ($states as $state) { |
|
| 736 | + if ($state instanceof EE_State) { |
|
| 737 | + $state_options[$state->country()->name()][$state->ID()] = $state->name(); |
|
| 738 | + } |
|
| 739 | + } |
|
| 740 | + } |
|
| 741 | + $state_options = apply_filters( |
|
| 742 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options', |
|
| 743 | + $state_options, |
|
| 744 | + $this, |
|
| 745 | + $registration, |
|
| 746 | + $question, |
|
| 747 | + $answer |
|
| 748 | + ); |
|
| 749 | + return $state_options; |
|
| 750 | + } |
|
| 751 | + |
|
| 752 | + |
|
| 753 | + |
|
| 754 | + |
|
| 755 | + |
|
| 756 | + |
|
| 757 | + /********************************************************************************************************/ |
|
| 758 | + /**************************************** PROCESS REG STEP ****************************************/ |
|
| 759 | + /********************************************************************************************************/ |
|
| 760 | + /** |
|
| 761 | + * @return bool |
|
| 762 | + * @throws EE_Error |
|
| 763 | + * @throws InvalidArgumentException |
|
| 764 | + * @throws ReflectionException |
|
| 765 | + * @throws RuntimeException |
|
| 766 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 767 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 768 | + */ |
|
| 769 | + public function process_reg_step() |
|
| 770 | + { |
|
| 771 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 772 | + // grab validated data from form |
|
| 773 | + $valid_data = $this->checkout->current_step->valid_data(); |
|
| 774 | + // EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
| 775 | + // EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ ); |
|
| 776 | + // if we don't have any $valid_data then something went TERRIBLY WRONG !!! |
|
| 777 | + if (empty($valid_data)) { |
|
| 778 | + EE_Error::add_error( |
|
| 779 | + esc_html__('No valid question responses were received.', 'event_espresso'), |
|
| 780 | + __FILE__, |
|
| 781 | + __FUNCTION__, |
|
| 782 | + __LINE__ |
|
| 783 | + ); |
|
| 784 | + return false; |
|
| 785 | + } |
|
| 786 | + if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
| 787 | + EE_Error::add_error( |
|
| 788 | + esc_html__( |
|
| 789 | + 'A valid transaction could not be initiated for processing your registrations.', |
|
| 790 | + 'event_espresso' |
|
| 791 | + ), |
|
| 792 | + __FILE__, |
|
| 793 | + __FUNCTION__, |
|
| 794 | + __LINE__ |
|
| 795 | + ); |
|
| 796 | + return false; |
|
| 797 | + } |
|
| 798 | + // get cached registrations |
|
| 799 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
| 800 | + // verify we got the goods |
|
| 801 | + if (empty($registrations)) { |
|
| 802 | + EE_Error::add_error( |
|
| 803 | + esc_html__('Your form data could not be applied to any valid registrations.', 'event_espresso'), |
|
| 804 | + __FILE__, |
|
| 805 | + __FUNCTION__, |
|
| 806 | + __LINE__ |
|
| 807 | + ); |
|
| 808 | + return false; |
|
| 809 | + } |
|
| 810 | + // extract attendee info from form data and save to model objects |
|
| 811 | + $registrations_processed = $this->_process_registrations($registrations, $valid_data); |
|
| 812 | + // if first pass thru SPCO, |
|
| 813 | + // then let's check processed registrations against the total number of tickets in the cart |
|
| 814 | + if ($registrations_processed === false) { |
|
| 815 | + // but return immediately if the previous step exited early due to errors |
|
| 816 | + return false; |
|
| 817 | + } elseif (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
| 818 | + // generate a correctly translated string for all possible singular/plural combinations |
|
| 819 | + if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
|
| 820 | + $error_msg = sprintf( |
|
| 821 | + esc_html__( |
|
| 822 | + 'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed', |
|
| 823 | + 'event_espresso' |
|
| 824 | + ), |
|
| 825 | + $this->checkout->total_ticket_count, |
|
| 826 | + $registrations_processed |
|
| 827 | + ); |
|
| 828 | + } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) { |
|
| 829 | + $error_msg = sprintf( |
|
| 830 | + esc_html__( |
|
| 831 | + 'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed', |
|
| 832 | + 'event_espresso' |
|
| 833 | + ), |
|
| 834 | + $this->checkout->total_ticket_count, |
|
| 835 | + $registrations_processed |
|
| 836 | + ); |
|
| 837 | + } else { |
|
| 838 | + $error_msg = sprintf( |
|
| 839 | + esc_html__( |
|
| 840 | + 'There was a total of %1$d tickets in the Event Queue, but %2$ds registrations were processed', |
|
| 841 | + 'event_espresso' |
|
| 842 | + ), |
|
| 843 | + $this->checkout->total_ticket_count, |
|
| 844 | + $registrations_processed |
|
| 845 | + ); |
|
| 846 | + } |
|
| 847 | + EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 848 | + return false; |
|
| 849 | + } |
|
| 850 | + // mark this reg step as completed |
|
| 851 | + $this->set_completed(); |
|
| 852 | + $this->_set_success_message( |
|
| 853 | + esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso') |
|
| 854 | + ); |
|
| 855 | + //do action in case a plugin wants to do something with the data submitted in step 1. |
|
| 856 | + //passes EE_Single_Page_Checkout, and it's posted data |
|
| 857 | + do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data); |
|
| 858 | + return true; |
|
| 859 | + } |
|
| 860 | + |
|
| 861 | + |
|
| 862 | + /** |
|
| 863 | + * _process_registrations |
|
| 864 | + * |
|
| 865 | + * @param EE_Registration[] $registrations |
|
| 866 | + * @param array $valid_data |
|
| 867 | + * @return bool|int |
|
| 868 | + * @throws EE_Error |
|
| 869 | + * @throws InvalidArgumentException |
|
| 870 | + * @throws ReflectionException |
|
| 871 | + * @throws RuntimeException |
|
| 872 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 873 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 874 | + */ |
|
| 875 | + private function _process_registrations($registrations = array(), $valid_data = array()) |
|
| 876 | + { |
|
| 877 | + // load resources and set some defaults |
|
| 878 | + EE_Registry::instance()->load_model('Attendee'); |
|
| 879 | + // holder for primary registrant attendee object |
|
| 880 | + $this->checkout->primary_attendee_obj = null; |
|
| 881 | + // array for tracking reg form data for the primary registrant |
|
| 882 | + $primary_registrant = array( |
|
| 883 | + 'line_item_id' => null, |
|
| 884 | + ); |
|
| 885 | + $copy_primary = false; |
|
| 886 | + // reg form sections that do not contain inputs |
|
| 887 | + $non_input_form_sections = array( |
|
| 888 | + 'primary_registrant', |
|
| 889 | + 'additional_attendee_reg_info', |
|
| 890 | + 'spco_copy_attendee_chk', |
|
| 891 | + ); |
|
| 892 | + // attendee counter |
|
| 893 | + $att_nmbr = 0; |
|
| 894 | + // grab the saved registrations from the transaction |
|
| 895 | + foreach ($registrations as $registration) { |
|
| 896 | + // verify EE_Registration object |
|
| 897 | + if (! $registration instanceof EE_Registration) { |
|
| 898 | + EE_Error::add_error( |
|
| 899 | + esc_html__( |
|
| 900 | + 'An invalid Registration object was discovered when attempting to process your registration information.', |
|
| 901 | + 'event_espresso' |
|
| 902 | + ), |
|
| 903 | + __FILE__, |
|
| 904 | + __FUNCTION__, |
|
| 905 | + __LINE__ |
|
| 906 | + ); |
|
| 907 | + return false; |
|
| 908 | + } |
|
| 909 | + /** @var string $reg_url_link */ |
|
| 910 | + $reg_url_link = $registration->reg_url_link(); |
|
| 911 | + // reg_url_link exists ? |
|
| 912 | + if (! empty($reg_url_link)) { |
|
| 913 | + // should this registration be processed during this visit ? |
|
| 914 | + if ($this->checkout->visit_allows_processing_of_this_registration($registration)) { |
|
| 915 | + // if NOT revisiting, then let's save the registration now, |
|
| 916 | + // so that we have a REG_ID to use when generating other objects |
|
| 917 | + if (! $this->checkout->revisit) { |
|
| 918 | + $registration->save(); |
|
| 919 | + } |
|
| 920 | + /** |
|
| 921 | + * This allows plugins to trigger a fail on processing of a |
|
| 922 | + * registration for any conditions they may have for it to pass. |
|
| 923 | + * |
|
| 924 | + * @var bool if true is returned by the plugin then the |
|
| 925 | + * registration processing is halted. |
|
| 926 | + */ |
|
| 927 | + if (apply_filters( |
|
| 928 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process', |
|
| 929 | + false, |
|
| 930 | + $att_nmbr, |
|
| 931 | + $registration, |
|
| 932 | + $registrations, |
|
| 933 | + $valid_data, |
|
| 934 | + $this |
|
| 935 | + )) { |
|
| 936 | + return false; |
|
| 937 | + } |
|
| 938 | + |
|
| 939 | + // Houston, we have a registration! |
|
| 940 | + $att_nmbr++; |
|
| 941 | + $this->_attendee_data[$reg_url_link] = array(); |
|
| 942 | + // grab any existing related answer objects |
|
| 943 | + $this->_registration_answers = $registration->answers(); |
|
| 944 | + // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ); |
|
| 945 | + if (isset($valid_data[$reg_url_link])) { |
|
| 946 | + // do we need to copy basic info from primary attendee ? |
|
| 947 | + $copy_primary = isset($valid_data[$reg_url_link]['additional_attendee_reg_info']) |
|
| 948 | + && absint($valid_data[$reg_url_link]['additional_attendee_reg_info']) === 0 |
|
| 949 | + ? true |
|
| 950 | + : false; |
|
| 951 | + // filter form input data for this registration |
|
| 952 | + $valid_data[$reg_url_link] = (array)apply_filters( |
|
| 953 | + 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
|
| 954 | + $valid_data[$reg_url_link] |
|
| 955 | + ); |
|
| 956 | + if (isset($valid_data['primary_attendee'])) { |
|
| 957 | + $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee']) |
|
| 958 | + ? $valid_data['primary_attendee'] |
|
| 959 | + : false; |
|
| 960 | + unset($valid_data['primary_attendee']); |
|
| 961 | + } |
|
| 962 | + // now loop through our array of valid post data && process attendee reg forms |
|
| 963 | + foreach ($valid_data[$reg_url_link] as $form_section => $form_inputs) { |
|
| 964 | + if (! in_array($form_section, $non_input_form_sections)) { |
|
| 965 | + foreach ($form_inputs as $form_input => $input_value) { |
|
| 966 | + // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ ); |
|
| 967 | + // check for critical inputs |
|
| 968 | + if (! $this->_verify_critical_attendee_details_are_set_and_validate_email( |
|
| 969 | + $form_input, |
|
| 970 | + $input_value |
|
| 971 | + ) |
|
| 972 | + ) { |
|
| 973 | + return false; |
|
| 974 | + } |
|
| 975 | + // store a bit of data about the primary attendee |
|
| 976 | + if ($att_nmbr === 1 |
|
| 977 | + && ! empty($input_value) |
|
| 978 | + && $reg_url_link === $primary_registrant['line_item_id'] |
|
| 979 | + ) { |
|
| 980 | + $primary_registrant[$form_input] = $input_value; |
|
| 981 | + } elseif ($copy_primary |
|
| 982 | + && $input_value === null |
|
| 983 | + && isset($primary_registrant[$form_input]) |
|
| 984 | + ) { |
|
| 985 | + $input_value = $primary_registrant[$form_input]; |
|
| 986 | + } |
|
| 987 | + // now attempt to save the input data |
|
| 988 | + if (! $this->_save_registration_form_input( |
|
| 989 | + $registration, |
|
| 990 | + $form_input, |
|
| 991 | + $input_value |
|
| 992 | + ) |
|
| 993 | + ) { |
|
| 994 | + EE_Error::add_error( |
|
| 995 | + sprintf( |
|
| 996 | + esc_html__( |
|
| 997 | + 'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"', |
|
| 998 | + 'event_espresso' |
|
| 999 | + ), |
|
| 1000 | + $form_input, |
|
| 1001 | + $input_value |
|
| 1002 | + ), |
|
| 1003 | + __FILE__, |
|
| 1004 | + __FUNCTION__, |
|
| 1005 | + __LINE__ |
|
| 1006 | + ); |
|
| 1007 | + return false; |
|
| 1008 | + } |
|
| 1009 | + } |
|
| 1010 | + } |
|
| 1011 | + } // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs ) |
|
| 1012 | + } |
|
| 1013 | + //EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ ); |
|
| 1014 | + // this registration does not require additional attendee information ? |
|
| 1015 | + if ($copy_primary |
|
| 1016 | + && $att_nmbr > 1 |
|
| 1017 | + && $this->checkout->primary_attendee_obj instanceof EE_Attendee |
|
| 1018 | + ) { |
|
| 1019 | + // just copy the primary registrant |
|
| 1020 | + $attendee = $this->checkout->primary_attendee_obj; |
|
| 1021 | + } else { |
|
| 1022 | + // ensure critical details are set for additional attendees |
|
| 1023 | + $this->_attendee_data[$reg_url_link] = $att_nmbr > 1 |
|
| 1024 | + ? $this->_copy_critical_attendee_details_from_primary_registrant( |
|
| 1025 | + $this->_attendee_data[$reg_url_link] |
|
| 1026 | + ) |
|
| 1027 | + : $this->_attendee_data[$reg_url_link]; |
|
| 1028 | + // execute create attendee command (which may return an existing attendee) |
|
| 1029 | + $attendee = EE_Registry::instance()->BUS->execute( |
|
| 1030 | + new CreateAttendeeCommand( |
|
| 1031 | + $this->_attendee_data[$reg_url_link], |
|
| 1032 | + $registration |
|
| 1033 | + ) |
|
| 1034 | + ); |
|
| 1035 | + // who's #1 ? |
|
| 1036 | + if ($att_nmbr === 1) { |
|
| 1037 | + $this->checkout->primary_attendee_obj = $attendee; |
|
| 1038 | + } |
|
| 1039 | + } |
|
| 1040 | + // EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ ); |
|
| 1041 | + // add relation to registration, set attendee ID, and cache attendee |
|
| 1042 | + $this->_associate_attendee_with_registration($registration, $attendee); |
|
| 1043 | + // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ ); |
|
| 1044 | + if (! $registration->attendee() instanceof EE_Attendee) { |
|
| 1045 | + EE_Error::add_error( |
|
| 1046 | + sprintf( |
|
| 1047 | + esc_html__( |
|
| 1048 | + 'Registration %s has an invalid or missing Attendee object.', |
|
| 1049 | + 'event_espresso' |
|
| 1050 | + ), |
|
| 1051 | + $reg_url_link |
|
| 1052 | + ), |
|
| 1053 | + __FILE__, |
|
| 1054 | + __FUNCTION__, |
|
| 1055 | + __LINE__ |
|
| 1056 | + ); |
|
| 1057 | + return false; |
|
| 1058 | + } |
|
| 1059 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 1060 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 1061 | + // at this point, we should have enough details about the registrant to consider the registration |
|
| 1062 | + // NOT incomplete |
|
| 1063 | + $registration_processor->toggle_incomplete_registration_status_to_default($registration, false); |
|
| 1064 | + // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to |
|
| 1065 | + // abandoned |
|
| 1066 | + $this->checkout->transaction->toggle_failed_transaction_status(); |
|
| 1067 | + // if we've gotten this far, then let's save what we have |
|
| 1068 | + $registration->save(); |
|
| 1069 | + // add relation between TXN and registration |
|
| 1070 | + $this->_associate_registration_with_transaction($registration); |
|
| 1071 | + } |
|
| 1072 | + } else { |
|
| 1073 | + EE_Error::add_error( |
|
| 1074 | + esc_html__( |
|
| 1075 | + 'An invalid or missing line item ID was encountered while attempting to process the registration form.', |
|
| 1076 | + 'event_espresso' |
|
| 1077 | + ), |
|
| 1078 | + __FILE__, |
|
| 1079 | + __FUNCTION__, |
|
| 1080 | + __LINE__ |
|
| 1081 | + ); |
|
| 1082 | + // remove malformed data |
|
| 1083 | + unset($valid_data[$reg_url_link]); |
|
| 1084 | + return false; |
|
| 1085 | + } |
|
| 1086 | + |
|
| 1087 | + } // end of foreach ( $this->checkout->transaction->registrations() as $registration ) |
|
| 1088 | + return $att_nmbr; |
|
| 1089 | + } |
|
| 1090 | + |
|
| 1091 | + |
|
| 1092 | + /** |
|
| 1093 | + * _save_registration_form_input |
|
| 1094 | + * |
|
| 1095 | + * @param EE_Registration $registration |
|
| 1096 | + * @param string $form_input |
|
| 1097 | + * @param string $input_value |
|
| 1098 | + * @return bool |
|
| 1099 | + * @throws EE_Error |
|
| 1100 | + * @throws InvalidArgumentException |
|
| 1101 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 1102 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 1103 | + */ |
|
| 1104 | + private function _save_registration_form_input( |
|
| 1105 | + EE_Registration $registration, |
|
| 1106 | + $form_input = '', |
|
| 1107 | + $input_value = '' |
|
| 1108 | + ) { |
|
| 1109 | + // \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 ); |
|
| 1110 | + // \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ ); |
|
| 1111 | + // \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ ); |
|
| 1112 | + // allow for plugins to hook in and do their own processing of the form input. |
|
| 1113 | + // For plugins to bypass normal processing here, they just need to return a boolean value. |
|
| 1114 | + if (apply_filters( |
|
| 1115 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input', |
|
| 1116 | + false, |
|
| 1117 | + $registration, |
|
| 1118 | + $form_input, |
|
| 1119 | + $input_value, |
|
| 1120 | + $this |
|
| 1121 | + )) { |
|
| 1122 | + return true; |
|
| 1123 | + } |
|
| 1124 | + /* |
|
| 1125 | 1125 | * $answer_cache_id is the key used to find the EE_Answer we want |
| 1126 | 1126 | * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477 |
| 1127 | 1127 | */ |
| 1128 | - $answer_cache_id = $this->checkout->reg_url_link |
|
| 1129 | - ? $form_input . '-' . $registration->reg_url_link() |
|
| 1130 | - : $form_input; |
|
| 1131 | - $answer_is_obj = isset($this->_registration_answers[$answer_cache_id]) |
|
| 1132 | - && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer |
|
| 1133 | - ? true |
|
| 1134 | - : false; |
|
| 1135 | - //rename form_inputs if they are EE_Attendee properties |
|
| 1136 | - switch ((string) $form_input) { |
|
| 1137 | - case 'state': |
|
| 1138 | - case 'STA_ID': |
|
| 1139 | - $attendee_property = true; |
|
| 1140 | - $form_input = 'STA_ID'; |
|
| 1141 | - break; |
|
| 1142 | - |
|
| 1143 | - case 'country': |
|
| 1144 | - case 'CNT_ISO': |
|
| 1145 | - $attendee_property = true; |
|
| 1146 | - $form_input = 'CNT_ISO'; |
|
| 1147 | - break; |
|
| 1148 | - |
|
| 1149 | - default: |
|
| 1150 | - $ATT_input = 'ATT_' . $form_input; |
|
| 1151 | - //EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ ); |
|
| 1152 | - $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false; |
|
| 1153 | - $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input; |
|
| 1154 | - } |
|
| 1155 | - // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ ); |
|
| 1156 | - // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ ); |
|
| 1157 | - // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ ); |
|
| 1158 | - // if this form input has a corresponding attendee property |
|
| 1159 | - if ($attendee_property) { |
|
| 1160 | - $this->_attendee_data[$registration->reg_url_link()][$form_input] = $input_value; |
|
| 1161 | - if ($answer_is_obj) { |
|
| 1162 | - // and delete the corresponding answer since we won't be storing this data in that object |
|
| 1163 | - $registration->_remove_relation_to($this->_registration_answers[$answer_cache_id], 'Answer'); |
|
| 1164 | - $this->_registration_answers[$answer_cache_id]->delete_permanently(); |
|
| 1165 | - } |
|
| 1166 | - return true; |
|
| 1167 | - } elseif ($answer_is_obj) { |
|
| 1168 | - // save this data to the answer object |
|
| 1169 | - $this->_registration_answers[$answer_cache_id]->set_value($input_value); |
|
| 1170 | - $result = $this->_registration_answers[$answer_cache_id]->save(); |
|
| 1171 | - return $result !== false ? true : false; |
|
| 1172 | - } else { |
|
| 1173 | - foreach ($this->_registration_answers as $answer) { |
|
| 1174 | - if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) { |
|
| 1175 | - $answer->set_value($input_value); |
|
| 1176 | - $result = $answer->save(); |
|
| 1177 | - return $result !== false ? true : false; |
|
| 1178 | - } |
|
| 1179 | - } |
|
| 1180 | - } |
|
| 1181 | - return false; |
|
| 1182 | - } |
|
| 1183 | - |
|
| 1184 | - |
|
| 1185 | - /** |
|
| 1186 | - * _verify_critical_attendee_details_are_set |
|
| 1187 | - * |
|
| 1188 | - * @param string $form_input |
|
| 1189 | - * @param string $input_value |
|
| 1190 | - * @return boolean |
|
| 1191 | - */ |
|
| 1192 | - private function _verify_critical_attendee_details_are_set_and_validate_email( |
|
| 1193 | - $form_input = '', |
|
| 1194 | - $input_value = '' |
|
| 1195 | - ) { |
|
| 1196 | - if (empty($input_value)) { |
|
| 1197 | - // if the form input isn't marked as being required, then just return |
|
| 1198 | - if (! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) { |
|
| 1199 | - return true; |
|
| 1200 | - } |
|
| 1201 | - switch ($form_input) { |
|
| 1202 | - case 'fname': |
|
| 1203 | - EE_Error::add_error( |
|
| 1204 | - esc_html__('First Name is a required value.', 'event_espresso'), |
|
| 1205 | - __FILE__, |
|
| 1206 | - __FUNCTION__, |
|
| 1207 | - __LINE__ |
|
| 1208 | - ); |
|
| 1209 | - return false; |
|
| 1210 | - break; |
|
| 1211 | - case 'lname': |
|
| 1212 | - EE_Error::add_error( |
|
| 1213 | - esc_html__('Last Name is a required value.', 'event_espresso'), |
|
| 1214 | - __FILE__, |
|
| 1215 | - __FUNCTION__, |
|
| 1216 | - __LINE__ |
|
| 1217 | - ); |
|
| 1218 | - return false; |
|
| 1219 | - break; |
|
| 1220 | - case 'email': |
|
| 1221 | - EE_Error::add_error( |
|
| 1222 | - esc_html__('Please enter a valid email address.', 'event_espresso'), |
|
| 1223 | - __FILE__, |
|
| 1224 | - __FUNCTION__, |
|
| 1225 | - __LINE__ |
|
| 1226 | - ); |
|
| 1227 | - return false; |
|
| 1228 | - break; |
|
| 1229 | - } |
|
| 1230 | - } |
|
| 1231 | - return true; |
|
| 1232 | - } |
|
| 1233 | - |
|
| 1234 | - |
|
| 1235 | - /** |
|
| 1236 | - * _associate_attendee_with_registration |
|
| 1237 | - * |
|
| 1238 | - * @param EE_Registration $registration |
|
| 1239 | - * @param EE_Attendee $attendee |
|
| 1240 | - * @return void |
|
| 1241 | - * @throws EE_Error |
|
| 1242 | - * @throws RuntimeException |
|
| 1243 | - */ |
|
| 1244 | - private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee) |
|
| 1245 | - { |
|
| 1246 | - // add relation to attendee |
|
| 1247 | - $registration->_add_relation_to($attendee, 'Attendee'); |
|
| 1248 | - $registration->set_attendee_id($attendee->ID()); |
|
| 1249 | - $registration->update_cache_after_object_save('Attendee', $attendee); |
|
| 1250 | - } |
|
| 1251 | - |
|
| 1252 | - |
|
| 1253 | - /** |
|
| 1254 | - * _associate_registration_with_transaction |
|
| 1255 | - * |
|
| 1256 | - * @param EE_Registration $registration |
|
| 1257 | - * @return void |
|
| 1258 | - * @throws \EE_Error |
|
| 1259 | - */ |
|
| 1260 | - private function _associate_registration_with_transaction(EE_Registration $registration) |
|
| 1261 | - { |
|
| 1262 | - // add relation to registration |
|
| 1263 | - $this->checkout->transaction->_add_relation_to($registration, 'Registration'); |
|
| 1264 | - $this->checkout->transaction->update_cache_after_object_save('Registration', $registration); |
|
| 1265 | - } |
|
| 1266 | - |
|
| 1267 | - |
|
| 1268 | - /** |
|
| 1269 | - * _copy_critical_attendee_details_from_primary_registrant |
|
| 1270 | - * ensures that all attendees at least have data for first name, last name, and email address |
|
| 1271 | - * |
|
| 1272 | - * @param array $attendee_data |
|
| 1273 | - * @return array |
|
| 1274 | - * @throws \EE_Error |
|
| 1275 | - */ |
|
| 1276 | - private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array()) |
|
| 1277 | - { |
|
| 1278 | - // bare minimum critical details include first name, last name, email address |
|
| 1279 | - $critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email'); |
|
| 1280 | - // add address info to critical details? |
|
| 1281 | - if (apply_filters( |
|
| 1282 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
|
| 1283 | - false |
|
| 1284 | - )) { |
|
| 1285 | - $address_details = array( |
|
| 1286 | - 'ATT_address', |
|
| 1287 | - 'ATT_address2', |
|
| 1288 | - 'ATT_city', |
|
| 1289 | - 'STA_ID', |
|
| 1290 | - 'CNT_ISO', |
|
| 1291 | - 'ATT_zip', |
|
| 1292 | - 'ATT_phone', |
|
| 1293 | - ); |
|
| 1294 | - $critical_attendee_details = array_merge($critical_attendee_details, $address_details); |
|
| 1295 | - } |
|
| 1296 | - foreach ($critical_attendee_details as $critical_attendee_detail) { |
|
| 1297 | - if (! isset($attendee_data[$critical_attendee_detail]) |
|
| 1298 | - || empty($attendee_data[$critical_attendee_detail]) |
|
| 1299 | - ) { |
|
| 1300 | - $attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get( |
|
| 1301 | - $critical_attendee_detail |
|
| 1302 | - ); |
|
| 1303 | - } |
|
| 1304 | - } |
|
| 1305 | - return $attendee_data; |
|
| 1306 | - } |
|
| 1307 | - |
|
| 1308 | - |
|
| 1309 | - /** |
|
| 1310 | - * update_reg_step |
|
| 1311 | - * this is the final step after a user revisits the site to edit their attendee information |
|
| 1312 | - * this gets called AFTER the process_reg_step() method above |
|
| 1313 | - * |
|
| 1314 | - * @return bool |
|
| 1315 | - * @throws EE_Error |
|
| 1316 | - * @throws InvalidArgumentException |
|
| 1317 | - * @throws ReflectionException |
|
| 1318 | - * @throws RuntimeException |
|
| 1319 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 1320 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 1321 | - */ |
|
| 1322 | - public function update_reg_step() |
|
| 1323 | - { |
|
| 1324 | - // save everything |
|
| 1325 | - if ($this->process_reg_step()) { |
|
| 1326 | - $this->checkout->redirect = true; |
|
| 1327 | - $this->checkout->redirect_url = add_query_arg( |
|
| 1328 | - array( |
|
| 1329 | - 'e_reg_url_link' => $this->checkout->reg_url_link, |
|
| 1330 | - 'revisit' => true, |
|
| 1331 | - ), |
|
| 1332 | - $this->checkout->thank_you_page_url |
|
| 1333 | - ); |
|
| 1334 | - $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
| 1335 | - return true; |
|
| 1336 | - } |
|
| 1337 | - return false; |
|
| 1338 | - } |
|
| 1128 | + $answer_cache_id = $this->checkout->reg_url_link |
|
| 1129 | + ? $form_input . '-' . $registration->reg_url_link() |
|
| 1130 | + : $form_input; |
|
| 1131 | + $answer_is_obj = isset($this->_registration_answers[$answer_cache_id]) |
|
| 1132 | + && $this->_registration_answers[$answer_cache_id] instanceof EE_Answer |
|
| 1133 | + ? true |
|
| 1134 | + : false; |
|
| 1135 | + //rename form_inputs if they are EE_Attendee properties |
|
| 1136 | + switch ((string) $form_input) { |
|
| 1137 | + case 'state': |
|
| 1138 | + case 'STA_ID': |
|
| 1139 | + $attendee_property = true; |
|
| 1140 | + $form_input = 'STA_ID'; |
|
| 1141 | + break; |
|
| 1142 | + |
|
| 1143 | + case 'country': |
|
| 1144 | + case 'CNT_ISO': |
|
| 1145 | + $attendee_property = true; |
|
| 1146 | + $form_input = 'CNT_ISO'; |
|
| 1147 | + break; |
|
| 1148 | + |
|
| 1149 | + default: |
|
| 1150 | + $ATT_input = 'ATT_' . $form_input; |
|
| 1151 | + //EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ ); |
|
| 1152 | + $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false; |
|
| 1153 | + $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input; |
|
| 1154 | + } |
|
| 1155 | + // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ ); |
|
| 1156 | + // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ ); |
|
| 1157 | + // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ ); |
|
| 1158 | + // if this form input has a corresponding attendee property |
|
| 1159 | + if ($attendee_property) { |
|
| 1160 | + $this->_attendee_data[$registration->reg_url_link()][$form_input] = $input_value; |
|
| 1161 | + if ($answer_is_obj) { |
|
| 1162 | + // and delete the corresponding answer since we won't be storing this data in that object |
|
| 1163 | + $registration->_remove_relation_to($this->_registration_answers[$answer_cache_id], 'Answer'); |
|
| 1164 | + $this->_registration_answers[$answer_cache_id]->delete_permanently(); |
|
| 1165 | + } |
|
| 1166 | + return true; |
|
| 1167 | + } elseif ($answer_is_obj) { |
|
| 1168 | + // save this data to the answer object |
|
| 1169 | + $this->_registration_answers[$answer_cache_id]->set_value($input_value); |
|
| 1170 | + $result = $this->_registration_answers[$answer_cache_id]->save(); |
|
| 1171 | + return $result !== false ? true : false; |
|
| 1172 | + } else { |
|
| 1173 | + foreach ($this->_registration_answers as $answer) { |
|
| 1174 | + if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) { |
|
| 1175 | + $answer->set_value($input_value); |
|
| 1176 | + $result = $answer->save(); |
|
| 1177 | + return $result !== false ? true : false; |
|
| 1178 | + } |
|
| 1179 | + } |
|
| 1180 | + } |
|
| 1181 | + return false; |
|
| 1182 | + } |
|
| 1183 | + |
|
| 1184 | + |
|
| 1185 | + /** |
|
| 1186 | + * _verify_critical_attendee_details_are_set |
|
| 1187 | + * |
|
| 1188 | + * @param string $form_input |
|
| 1189 | + * @param string $input_value |
|
| 1190 | + * @return boolean |
|
| 1191 | + */ |
|
| 1192 | + private function _verify_critical_attendee_details_are_set_and_validate_email( |
|
| 1193 | + $form_input = '', |
|
| 1194 | + $input_value = '' |
|
| 1195 | + ) { |
|
| 1196 | + if (empty($input_value)) { |
|
| 1197 | + // if the form input isn't marked as being required, then just return |
|
| 1198 | + if (! isset($this->_required_questions[$form_input]) || ! $this->_required_questions[$form_input]) { |
|
| 1199 | + return true; |
|
| 1200 | + } |
|
| 1201 | + switch ($form_input) { |
|
| 1202 | + case 'fname': |
|
| 1203 | + EE_Error::add_error( |
|
| 1204 | + esc_html__('First Name is a required value.', 'event_espresso'), |
|
| 1205 | + __FILE__, |
|
| 1206 | + __FUNCTION__, |
|
| 1207 | + __LINE__ |
|
| 1208 | + ); |
|
| 1209 | + return false; |
|
| 1210 | + break; |
|
| 1211 | + case 'lname': |
|
| 1212 | + EE_Error::add_error( |
|
| 1213 | + esc_html__('Last Name is a required value.', 'event_espresso'), |
|
| 1214 | + __FILE__, |
|
| 1215 | + __FUNCTION__, |
|
| 1216 | + __LINE__ |
|
| 1217 | + ); |
|
| 1218 | + return false; |
|
| 1219 | + break; |
|
| 1220 | + case 'email': |
|
| 1221 | + EE_Error::add_error( |
|
| 1222 | + esc_html__('Please enter a valid email address.', 'event_espresso'), |
|
| 1223 | + __FILE__, |
|
| 1224 | + __FUNCTION__, |
|
| 1225 | + __LINE__ |
|
| 1226 | + ); |
|
| 1227 | + return false; |
|
| 1228 | + break; |
|
| 1229 | + } |
|
| 1230 | + } |
|
| 1231 | + return true; |
|
| 1232 | + } |
|
| 1233 | + |
|
| 1234 | + |
|
| 1235 | + /** |
|
| 1236 | + * _associate_attendee_with_registration |
|
| 1237 | + * |
|
| 1238 | + * @param EE_Registration $registration |
|
| 1239 | + * @param EE_Attendee $attendee |
|
| 1240 | + * @return void |
|
| 1241 | + * @throws EE_Error |
|
| 1242 | + * @throws RuntimeException |
|
| 1243 | + */ |
|
| 1244 | + private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee) |
|
| 1245 | + { |
|
| 1246 | + // add relation to attendee |
|
| 1247 | + $registration->_add_relation_to($attendee, 'Attendee'); |
|
| 1248 | + $registration->set_attendee_id($attendee->ID()); |
|
| 1249 | + $registration->update_cache_after_object_save('Attendee', $attendee); |
|
| 1250 | + } |
|
| 1251 | + |
|
| 1252 | + |
|
| 1253 | + /** |
|
| 1254 | + * _associate_registration_with_transaction |
|
| 1255 | + * |
|
| 1256 | + * @param EE_Registration $registration |
|
| 1257 | + * @return void |
|
| 1258 | + * @throws \EE_Error |
|
| 1259 | + */ |
|
| 1260 | + private function _associate_registration_with_transaction(EE_Registration $registration) |
|
| 1261 | + { |
|
| 1262 | + // add relation to registration |
|
| 1263 | + $this->checkout->transaction->_add_relation_to($registration, 'Registration'); |
|
| 1264 | + $this->checkout->transaction->update_cache_after_object_save('Registration', $registration); |
|
| 1265 | + } |
|
| 1266 | + |
|
| 1267 | + |
|
| 1268 | + /** |
|
| 1269 | + * _copy_critical_attendee_details_from_primary_registrant |
|
| 1270 | + * ensures that all attendees at least have data for first name, last name, and email address |
|
| 1271 | + * |
|
| 1272 | + * @param array $attendee_data |
|
| 1273 | + * @return array |
|
| 1274 | + * @throws \EE_Error |
|
| 1275 | + */ |
|
| 1276 | + private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array()) |
|
| 1277 | + { |
|
| 1278 | + // bare minimum critical details include first name, last name, email address |
|
| 1279 | + $critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email'); |
|
| 1280 | + // add address info to critical details? |
|
| 1281 | + if (apply_filters( |
|
| 1282 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
|
| 1283 | + false |
|
| 1284 | + )) { |
|
| 1285 | + $address_details = array( |
|
| 1286 | + 'ATT_address', |
|
| 1287 | + 'ATT_address2', |
|
| 1288 | + 'ATT_city', |
|
| 1289 | + 'STA_ID', |
|
| 1290 | + 'CNT_ISO', |
|
| 1291 | + 'ATT_zip', |
|
| 1292 | + 'ATT_phone', |
|
| 1293 | + ); |
|
| 1294 | + $critical_attendee_details = array_merge($critical_attendee_details, $address_details); |
|
| 1295 | + } |
|
| 1296 | + foreach ($critical_attendee_details as $critical_attendee_detail) { |
|
| 1297 | + if (! isset($attendee_data[$critical_attendee_detail]) |
|
| 1298 | + || empty($attendee_data[$critical_attendee_detail]) |
|
| 1299 | + ) { |
|
| 1300 | + $attendee_data[$critical_attendee_detail] = $this->checkout->primary_attendee_obj->get( |
|
| 1301 | + $critical_attendee_detail |
|
| 1302 | + ); |
|
| 1303 | + } |
|
| 1304 | + } |
|
| 1305 | + return $attendee_data; |
|
| 1306 | + } |
|
| 1307 | + |
|
| 1308 | + |
|
| 1309 | + /** |
|
| 1310 | + * update_reg_step |
|
| 1311 | + * this is the final step after a user revisits the site to edit their attendee information |
|
| 1312 | + * this gets called AFTER the process_reg_step() method above |
|
| 1313 | + * |
|
| 1314 | + * @return bool |
|
| 1315 | + * @throws EE_Error |
|
| 1316 | + * @throws InvalidArgumentException |
|
| 1317 | + * @throws ReflectionException |
|
| 1318 | + * @throws RuntimeException |
|
| 1319 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
| 1320 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
| 1321 | + */ |
|
| 1322 | + public function update_reg_step() |
|
| 1323 | + { |
|
| 1324 | + // save everything |
|
| 1325 | + if ($this->process_reg_step()) { |
|
| 1326 | + $this->checkout->redirect = true; |
|
| 1327 | + $this->checkout->redirect_url = add_query_arg( |
|
| 1328 | + array( |
|
| 1329 | + 'e_reg_url_link' => $this->checkout->reg_url_link, |
|
| 1330 | + 'revisit' => true, |
|
| 1331 | + ), |
|
| 1332 | + $this->checkout->thank_you_page_url |
|
| 1333 | + ); |
|
| 1334 | + $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
| 1335 | + return true; |
|
| 1336 | + } |
|
| 1337 | + return false; |
|
| 1338 | + } |
|
| 1339 | 1339 | } |
@@ -17,7 +17,7 @@ discard block |
||
| 17 | 17 | use WP_Post; |
| 18 | 18 | |
| 19 | 19 | if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) { |
| 20 | - exit( 'No direct script access allowed' ); |
|
| 20 | + exit( 'No direct script access allowed' ); |
|
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | |
@@ -34,713 +34,713 @@ discard block |
||
| 34 | 34 | class DisplayTicketSelector |
| 35 | 35 | { |
| 36 | 36 | |
| 37 | - /** |
|
| 38 | - * event that ticket selector is being generated for |
|
| 39 | - * |
|
| 40 | - * @access protected |
|
| 41 | - * @var EE_Event $event |
|
| 42 | - */ |
|
| 43 | - protected $event; |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * Used to flag when the ticket selector is being called from an external iframe. |
|
| 47 | - * |
|
| 48 | - * @var bool $iframe |
|
| 49 | - */ |
|
| 50 | - protected $iframe = false; |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * max attendees that can register for event at one time |
|
| 54 | - * |
|
| 55 | - * @var int $max_attendees |
|
| 56 | - */ |
|
| 57 | - private $max_attendees = EE_INF; |
|
| 58 | - |
|
| 59 | - /** |
|
| 60 | - *@var string $date_format |
|
| 61 | - */ |
|
| 62 | - private $date_format; |
|
| 63 | - |
|
| 64 | - /** |
|
| 65 | - *@var string $time_format |
|
| 66 | - */ |
|
| 67 | - private $time_format; |
|
| 68 | - |
|
| 69 | - /** |
|
| 70 | - *@var boolean $display_full_ui |
|
| 71 | - */ |
|
| 72 | - private $display_full_ui; |
|
| 73 | - |
|
| 74 | - |
|
| 75 | - |
|
| 76 | - /** |
|
| 77 | - * DisplayTicketSelector constructor. |
|
| 78 | - */ |
|
| 79 | - public function __construct() |
|
| 80 | - { |
|
| 81 | - $this->date_format = apply_filters( |
|
| 82 | - 'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format', |
|
| 83 | - get_option('date_format') |
|
| 84 | - ); |
|
| 85 | - $this->time_format = apply_filters( |
|
| 86 | - 'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format', |
|
| 87 | - get_option('time_format') |
|
| 88 | - ); |
|
| 89 | - } |
|
| 90 | - |
|
| 91 | - |
|
| 92 | - |
|
| 93 | - /** |
|
| 94 | - * @param boolean $iframe |
|
| 95 | - */ |
|
| 96 | - public function setIframe( $iframe = true ) |
|
| 97 | - { |
|
| 98 | - $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN ); |
|
| 99 | - } |
|
| 100 | - |
|
| 101 | - |
|
| 102 | - /** |
|
| 103 | - * finds and sets the \EE_Event object for use throughout class |
|
| 104 | - * |
|
| 105 | - * @param mixed $event |
|
| 106 | - * @return bool |
|
| 107 | - * @throws EE_Error |
|
| 108 | - */ |
|
| 109 | - protected function setEvent( $event = null ) |
|
| 110 | - { |
|
| 111 | - if ( $event === null ) { |
|
| 112 | - global $post; |
|
| 113 | - $event = $post; |
|
| 114 | - } |
|
| 115 | - if ( $event instanceof EE_Event ) { |
|
| 116 | - $this->event = $event; |
|
| 117 | - } elseif ( $event instanceof WP_Post ) { |
|
| 118 | - if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) { |
|
| 119 | - $this->event = $event->EE_Event; |
|
| 120 | - } elseif ( $event->post_type === 'espresso_events' ) { |
|
| 121 | - $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event ); |
|
| 122 | - $this->event = $event->EE_Event; |
|
| 123 | - } |
|
| 124 | - } else { |
|
| 125 | - $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' ); |
|
| 126 | - $dev_msg = $user_msg . __( |
|
| 127 | - 'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.', |
|
| 128 | - 'event_espresso' |
|
| 129 | - ); |
|
| 130 | - EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ ); |
|
| 131 | - return false; |
|
| 132 | - } |
|
| 133 | - return true; |
|
| 134 | - } |
|
| 135 | - |
|
| 136 | - |
|
| 137 | - |
|
| 138 | - /** |
|
| 139 | - * @return int |
|
| 140 | - */ |
|
| 141 | - public function getMaxAttendees() |
|
| 142 | - { |
|
| 143 | - return $this->max_attendees; |
|
| 144 | - } |
|
| 145 | - |
|
| 146 | - |
|
| 147 | - |
|
| 148 | - /** |
|
| 149 | - * @param int $max_attendees |
|
| 150 | - */ |
|
| 151 | - public function setMaxAttendees($max_attendees) |
|
| 152 | - { |
|
| 153 | - $this->max_attendees = absint( |
|
| 154 | - apply_filters( |
|
| 155 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets', |
|
| 156 | - $max_attendees |
|
| 157 | - ) |
|
| 158 | - ); |
|
| 159 | - } |
|
| 160 | - |
|
| 161 | - |
|
| 162 | - |
|
| 163 | - /** |
|
| 164 | - * Returns whether or not the full ticket selector should be shown or not. |
|
| 165 | - * Currently, it displays on the frontend (including ajax requests) but not the backend |
|
| 166 | - * @return bool |
|
| 167 | - */ |
|
| 168 | - private function display_full_ui() |
|
| 169 | - { |
|
| 170 | - if ($this->display_full_ui === null) { |
|
| 171 | - $this->display_full_ui = ! is_admin() || (defined('DOING_AJAX') && DOING_AJAX); |
|
| 172 | - } |
|
| 173 | - return $this->display_full_ui; |
|
| 174 | - } |
|
| 175 | - |
|
| 176 | - |
|
| 177 | - /** |
|
| 178 | - * creates buttons for selecting number of attendees for an event |
|
| 179 | - * |
|
| 180 | - * @param WP_Post|int $event |
|
| 181 | - * @param bool $view_details |
|
| 182 | - * @return string |
|
| 183 | - * @throws EE_Error |
|
| 184 | - */ |
|
| 185 | - public function display( $event = null, $view_details = false ) |
|
| 186 | - { |
|
| 187 | - // reset filter for displaying submit button |
|
| 188 | - remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' ); |
|
| 189 | - // poke and prod incoming event till it tells us what it is |
|
| 190 | - if ( ! $this->setEvent( $event ) ) { |
|
| 191 | - return false; |
|
| 192 | - } |
|
| 193 | - // begin gathering template arguments by getting event status |
|
| 194 | - $template_args = array( 'event_status' => $this->event->get_active_status() ); |
|
| 195 | - if ( |
|
| 196 | - $this->activeEventAndShowTicketSelector( |
|
| 197 | - $event, |
|
| 198 | - $template_args['event_status'], |
|
| 199 | - $view_details |
|
| 200 | - ) |
|
| 201 | - ) { |
|
| 202 | - return ! is_single() ? $this->displayViewDetailsButton() : ''; |
|
| 203 | - } |
|
| 204 | - // filter the maximum qty that can appear in the Ticket Selector qty dropdowns |
|
| 205 | - $this->setMaxAttendees($this->event->additional_limit()); |
|
| 206 | - if ($this->getMaxAttendees() < 1) { |
|
| 207 | - return $this->ticketSalesClosedMessage(); |
|
| 208 | - } |
|
| 209 | - // is the event expired ? |
|
| 210 | - $template_args['event_is_expired'] = $this->event->is_expired(); |
|
| 211 | - if ( $template_args[ 'event_is_expired' ] ) { |
|
| 212 | - return $this->expiredEventMessage(); |
|
| 213 | - } |
|
| 214 | - // get all tickets for this event ordered by the datetime |
|
| 215 | - $tickets = $this->getTickets(); |
|
| 216 | - if (count($tickets) < 1) { |
|
| 217 | - return $this->noTicketAvailableMessage(); |
|
| 218 | - } |
|
| 219 | - if (EED_Events_Archive::is_iframe()){ |
|
| 220 | - $this->setIframe(); |
|
| 221 | - } |
|
| 222 | - // redirecting to another site for registration ?? |
|
| 223 | - $external_url = (string) $this->event->external_url(); |
|
| 224 | - // if redirecting to another site for registration, then we don't load the TS |
|
| 225 | - $ticket_selector = $external_url |
|
| 226 | - ? $this->externalEventRegistration() |
|
| 227 | - : $this->loadTicketSelector($tickets,$template_args); |
|
| 228 | - // now set up the form (but not for the admin) |
|
| 229 | - $ticket_selector = $this->display_full_ui() |
|
| 230 | - ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
| 231 | - : $ticket_selector; |
|
| 232 | - // submit button and form close tag |
|
| 233 | - $ticket_selector .= $this->display_full_ui() ? $this->displaySubmitButton($external_url) : ''; |
|
| 234 | - return $ticket_selector; |
|
| 235 | - } |
|
| 236 | - |
|
| 237 | - |
|
| 238 | - |
|
| 239 | - /** |
|
| 240 | - * displayTicketSelector |
|
| 241 | - * examines the event properties and determines whether a Ticket Selector should be displayed |
|
| 242 | - * |
|
| 243 | - * @param WP_Post|int $event |
|
| 244 | - * @param string $_event_active_status |
|
| 245 | - * @param bool $view_details |
|
| 246 | - * @return bool |
|
| 247 | - * @throws EE_Error |
|
| 248 | - */ |
|
| 249 | - protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details) |
|
| 250 | - { |
|
| 251 | - $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event; |
|
| 252 | - return $this->display_full_ui() |
|
| 253 | - && ( |
|
| 254 | - ! $this->event->display_ticket_selector() |
|
| 255 | - || $view_details |
|
| 256 | - || post_password_required($event_post) |
|
| 257 | - || ( |
|
| 258 | - $_event_active_status !== EE_Datetime::active |
|
| 259 | - && $_event_active_status !== EE_Datetime::upcoming |
|
| 260 | - && $_event_active_status !== EE_Datetime::sold_out |
|
| 261 | - && ! ( |
|
| 262 | - $_event_active_status === EE_Datetime::inactive |
|
| 263 | - && is_user_logged_in() |
|
| 264 | - ) |
|
| 265 | - ) |
|
| 266 | - ); |
|
| 267 | - } |
|
| 268 | - |
|
| 269 | - |
|
| 270 | - |
|
| 271 | - /** |
|
| 272 | - * noTicketAvailableMessage |
|
| 273 | - * notice displayed if event is expired |
|
| 274 | - * |
|
| 275 | - * @return string |
|
| 276 | - * @throws EE_Error |
|
| 277 | - */ |
|
| 278 | - protected function expiredEventMessage() |
|
| 279 | - { |
|
| 280 | - return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
| 281 | - 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
|
| 282 | - 'event_espresso' |
|
| 283 | - ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
| 284 | - } |
|
| 285 | - |
|
| 286 | - |
|
| 287 | - |
|
| 288 | - /** |
|
| 289 | - * noTicketAvailableMessage |
|
| 290 | - * notice displayed if event has no more tickets available |
|
| 291 | - * |
|
| 292 | - * @return string |
|
| 293 | - * @throws EE_Error |
|
| 294 | - */ |
|
| 295 | - protected function noTicketAvailableMessage() |
|
| 296 | - { |
|
| 297 | - $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' ); |
|
| 298 | - if (current_user_can('edit_post', $this->event->ID())) { |
|
| 299 | - $no_ticket_available_msg .= sprintf( |
|
| 300 | - esc_html__( |
|
| 301 | - '%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s', |
|
| 302 | - 'event_espresso' |
|
| 303 | - ), |
|
| 304 | - '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 305 | - '</b><br />', |
|
| 306 | - '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
| 307 | - '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->' |
|
| 308 | - ); |
|
| 309 | - } |
|
| 310 | - return ' |
|
| 37 | + /** |
|
| 38 | + * event that ticket selector is being generated for |
|
| 39 | + * |
|
| 40 | + * @access protected |
|
| 41 | + * @var EE_Event $event |
|
| 42 | + */ |
|
| 43 | + protected $event; |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * Used to flag when the ticket selector is being called from an external iframe. |
|
| 47 | + * |
|
| 48 | + * @var bool $iframe |
|
| 49 | + */ |
|
| 50 | + protected $iframe = false; |
|
| 51 | + |
|
| 52 | + /** |
|
| 53 | + * max attendees that can register for event at one time |
|
| 54 | + * |
|
| 55 | + * @var int $max_attendees |
|
| 56 | + */ |
|
| 57 | + private $max_attendees = EE_INF; |
|
| 58 | + |
|
| 59 | + /** |
|
| 60 | + *@var string $date_format |
|
| 61 | + */ |
|
| 62 | + private $date_format; |
|
| 63 | + |
|
| 64 | + /** |
|
| 65 | + *@var string $time_format |
|
| 66 | + */ |
|
| 67 | + private $time_format; |
|
| 68 | + |
|
| 69 | + /** |
|
| 70 | + *@var boolean $display_full_ui |
|
| 71 | + */ |
|
| 72 | + private $display_full_ui; |
|
| 73 | + |
|
| 74 | + |
|
| 75 | + |
|
| 76 | + /** |
|
| 77 | + * DisplayTicketSelector constructor. |
|
| 78 | + */ |
|
| 79 | + public function __construct() |
|
| 80 | + { |
|
| 81 | + $this->date_format = apply_filters( |
|
| 82 | + 'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format', |
|
| 83 | + get_option('date_format') |
|
| 84 | + ); |
|
| 85 | + $this->time_format = apply_filters( |
|
| 86 | + 'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format', |
|
| 87 | + get_option('time_format') |
|
| 88 | + ); |
|
| 89 | + } |
|
| 90 | + |
|
| 91 | + |
|
| 92 | + |
|
| 93 | + /** |
|
| 94 | + * @param boolean $iframe |
|
| 95 | + */ |
|
| 96 | + public function setIframe( $iframe = true ) |
|
| 97 | + { |
|
| 98 | + $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN ); |
|
| 99 | + } |
|
| 100 | + |
|
| 101 | + |
|
| 102 | + /** |
|
| 103 | + * finds and sets the \EE_Event object for use throughout class |
|
| 104 | + * |
|
| 105 | + * @param mixed $event |
|
| 106 | + * @return bool |
|
| 107 | + * @throws EE_Error |
|
| 108 | + */ |
|
| 109 | + protected function setEvent( $event = null ) |
|
| 110 | + { |
|
| 111 | + if ( $event === null ) { |
|
| 112 | + global $post; |
|
| 113 | + $event = $post; |
|
| 114 | + } |
|
| 115 | + if ( $event instanceof EE_Event ) { |
|
| 116 | + $this->event = $event; |
|
| 117 | + } elseif ( $event instanceof WP_Post ) { |
|
| 118 | + if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) { |
|
| 119 | + $this->event = $event->EE_Event; |
|
| 120 | + } elseif ( $event->post_type === 'espresso_events' ) { |
|
| 121 | + $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event ); |
|
| 122 | + $this->event = $event->EE_Event; |
|
| 123 | + } |
|
| 124 | + } else { |
|
| 125 | + $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' ); |
|
| 126 | + $dev_msg = $user_msg . __( |
|
| 127 | + 'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.', |
|
| 128 | + 'event_espresso' |
|
| 129 | + ); |
|
| 130 | + EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ ); |
|
| 131 | + return false; |
|
| 132 | + } |
|
| 133 | + return true; |
|
| 134 | + } |
|
| 135 | + |
|
| 136 | + |
|
| 137 | + |
|
| 138 | + /** |
|
| 139 | + * @return int |
|
| 140 | + */ |
|
| 141 | + public function getMaxAttendees() |
|
| 142 | + { |
|
| 143 | + return $this->max_attendees; |
|
| 144 | + } |
|
| 145 | + |
|
| 146 | + |
|
| 147 | + |
|
| 148 | + /** |
|
| 149 | + * @param int $max_attendees |
|
| 150 | + */ |
|
| 151 | + public function setMaxAttendees($max_attendees) |
|
| 152 | + { |
|
| 153 | + $this->max_attendees = absint( |
|
| 154 | + apply_filters( |
|
| 155 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets', |
|
| 156 | + $max_attendees |
|
| 157 | + ) |
|
| 158 | + ); |
|
| 159 | + } |
|
| 160 | + |
|
| 161 | + |
|
| 162 | + |
|
| 163 | + /** |
|
| 164 | + * Returns whether or not the full ticket selector should be shown or not. |
|
| 165 | + * Currently, it displays on the frontend (including ajax requests) but not the backend |
|
| 166 | + * @return bool |
|
| 167 | + */ |
|
| 168 | + private function display_full_ui() |
|
| 169 | + { |
|
| 170 | + if ($this->display_full_ui === null) { |
|
| 171 | + $this->display_full_ui = ! is_admin() || (defined('DOING_AJAX') && DOING_AJAX); |
|
| 172 | + } |
|
| 173 | + return $this->display_full_ui; |
|
| 174 | + } |
|
| 175 | + |
|
| 176 | + |
|
| 177 | + /** |
|
| 178 | + * creates buttons for selecting number of attendees for an event |
|
| 179 | + * |
|
| 180 | + * @param WP_Post|int $event |
|
| 181 | + * @param bool $view_details |
|
| 182 | + * @return string |
|
| 183 | + * @throws EE_Error |
|
| 184 | + */ |
|
| 185 | + public function display( $event = null, $view_details = false ) |
|
| 186 | + { |
|
| 187 | + // reset filter for displaying submit button |
|
| 188 | + remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' ); |
|
| 189 | + // poke and prod incoming event till it tells us what it is |
|
| 190 | + if ( ! $this->setEvent( $event ) ) { |
|
| 191 | + return false; |
|
| 192 | + } |
|
| 193 | + // begin gathering template arguments by getting event status |
|
| 194 | + $template_args = array( 'event_status' => $this->event->get_active_status() ); |
|
| 195 | + if ( |
|
| 196 | + $this->activeEventAndShowTicketSelector( |
|
| 197 | + $event, |
|
| 198 | + $template_args['event_status'], |
|
| 199 | + $view_details |
|
| 200 | + ) |
|
| 201 | + ) { |
|
| 202 | + return ! is_single() ? $this->displayViewDetailsButton() : ''; |
|
| 203 | + } |
|
| 204 | + // filter the maximum qty that can appear in the Ticket Selector qty dropdowns |
|
| 205 | + $this->setMaxAttendees($this->event->additional_limit()); |
|
| 206 | + if ($this->getMaxAttendees() < 1) { |
|
| 207 | + return $this->ticketSalesClosedMessage(); |
|
| 208 | + } |
|
| 209 | + // is the event expired ? |
|
| 210 | + $template_args['event_is_expired'] = $this->event->is_expired(); |
|
| 211 | + if ( $template_args[ 'event_is_expired' ] ) { |
|
| 212 | + return $this->expiredEventMessage(); |
|
| 213 | + } |
|
| 214 | + // get all tickets for this event ordered by the datetime |
|
| 215 | + $tickets = $this->getTickets(); |
|
| 216 | + if (count($tickets) < 1) { |
|
| 217 | + return $this->noTicketAvailableMessage(); |
|
| 218 | + } |
|
| 219 | + if (EED_Events_Archive::is_iframe()){ |
|
| 220 | + $this->setIframe(); |
|
| 221 | + } |
|
| 222 | + // redirecting to another site for registration ?? |
|
| 223 | + $external_url = (string) $this->event->external_url(); |
|
| 224 | + // if redirecting to another site for registration, then we don't load the TS |
|
| 225 | + $ticket_selector = $external_url |
|
| 226 | + ? $this->externalEventRegistration() |
|
| 227 | + : $this->loadTicketSelector($tickets,$template_args); |
|
| 228 | + // now set up the form (but not for the admin) |
|
| 229 | + $ticket_selector = $this->display_full_ui() |
|
| 230 | + ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
| 231 | + : $ticket_selector; |
|
| 232 | + // submit button and form close tag |
|
| 233 | + $ticket_selector .= $this->display_full_ui() ? $this->displaySubmitButton($external_url) : ''; |
|
| 234 | + return $ticket_selector; |
|
| 235 | + } |
|
| 236 | + |
|
| 237 | + |
|
| 238 | + |
|
| 239 | + /** |
|
| 240 | + * displayTicketSelector |
|
| 241 | + * examines the event properties and determines whether a Ticket Selector should be displayed |
|
| 242 | + * |
|
| 243 | + * @param WP_Post|int $event |
|
| 244 | + * @param string $_event_active_status |
|
| 245 | + * @param bool $view_details |
|
| 246 | + * @return bool |
|
| 247 | + * @throws EE_Error |
|
| 248 | + */ |
|
| 249 | + protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details) |
|
| 250 | + { |
|
| 251 | + $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event; |
|
| 252 | + return $this->display_full_ui() |
|
| 253 | + && ( |
|
| 254 | + ! $this->event->display_ticket_selector() |
|
| 255 | + || $view_details |
|
| 256 | + || post_password_required($event_post) |
|
| 257 | + || ( |
|
| 258 | + $_event_active_status !== EE_Datetime::active |
|
| 259 | + && $_event_active_status !== EE_Datetime::upcoming |
|
| 260 | + && $_event_active_status !== EE_Datetime::sold_out |
|
| 261 | + && ! ( |
|
| 262 | + $_event_active_status === EE_Datetime::inactive |
|
| 263 | + && is_user_logged_in() |
|
| 264 | + ) |
|
| 265 | + ) |
|
| 266 | + ); |
|
| 267 | + } |
|
| 268 | + |
|
| 269 | + |
|
| 270 | + |
|
| 271 | + /** |
|
| 272 | + * noTicketAvailableMessage |
|
| 273 | + * notice displayed if event is expired |
|
| 274 | + * |
|
| 275 | + * @return string |
|
| 276 | + * @throws EE_Error |
|
| 277 | + */ |
|
| 278 | + protected function expiredEventMessage() |
|
| 279 | + { |
|
| 280 | + return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
| 281 | + 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
|
| 282 | + 'event_espresso' |
|
| 283 | + ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
| 284 | + } |
|
| 285 | + |
|
| 286 | + |
|
| 287 | + |
|
| 288 | + /** |
|
| 289 | + * noTicketAvailableMessage |
|
| 290 | + * notice displayed if event has no more tickets available |
|
| 291 | + * |
|
| 292 | + * @return string |
|
| 293 | + * @throws EE_Error |
|
| 294 | + */ |
|
| 295 | + protected function noTicketAvailableMessage() |
|
| 296 | + { |
|
| 297 | + $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' ); |
|
| 298 | + if (current_user_can('edit_post', $this->event->ID())) { |
|
| 299 | + $no_ticket_available_msg .= sprintf( |
|
| 300 | + esc_html__( |
|
| 301 | + '%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s', |
|
| 302 | + 'event_espresso' |
|
| 303 | + ), |
|
| 304 | + '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 305 | + '</b><br />', |
|
| 306 | + '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
| 307 | + '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->' |
|
| 308 | + ); |
|
| 309 | + } |
|
| 310 | + return ' |
|
| 311 | 311 | <div class="ee-event-expired-notice"> |
| 312 | 312 | <span class="important-notice">' . $no_ticket_available_msg . '</span> |
| 313 | 313 | </div><!-- .ee-event-expired-notice -->'; |
| 314 | - } |
|
| 315 | - |
|
| 316 | - |
|
| 317 | - |
|
| 318 | - /** |
|
| 319 | - * ticketSalesClosed |
|
| 320 | - * notice displayed if event ticket sales are turned off |
|
| 321 | - * |
|
| 322 | - * @return string |
|
| 323 | - * @throws EE_Error |
|
| 324 | - */ |
|
| 325 | - protected function ticketSalesClosedMessage() |
|
| 326 | - { |
|
| 327 | - $sales_closed_msg = esc_html__( |
|
| 328 | - 'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.', |
|
| 329 | - 'event_espresso' |
|
| 330 | - ); |
|
| 331 | - if (current_user_can('edit_post', $this->event->ID())) { |
|
| 332 | - $sales_closed_msg .= sprintf( |
|
| 333 | - esc_html__( |
|
| 334 | - '%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s', |
|
| 335 | - 'event_espresso' |
|
| 336 | - ), |
|
| 337 | - '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 338 | - '</b><br />', |
|
| 339 | - '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
| 340 | - '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
|
| 341 | - ); |
|
| 342 | - } |
|
| 343 | - return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
| 344 | - } |
|
| 345 | - |
|
| 346 | - |
|
| 347 | - |
|
| 348 | - /** |
|
| 349 | - * getTickets |
|
| 350 | - * |
|
| 351 | - * @return \EE_Base_Class[]|\EE_Ticket[] |
|
| 352 | - * @throws EE_Error |
|
| 353 | - */ |
|
| 354 | - protected function getTickets() |
|
| 355 | - { |
|
| 356 | - $ticket_query_args = array( |
|
| 357 | - array('Datetime.EVT_ID' => $this->event->ID()), |
|
| 358 | - 'order_by' => array( |
|
| 359 | - 'TKT_order' => 'ASC', |
|
| 360 | - 'TKT_required' => 'DESC', |
|
| 361 | - 'TKT_start_date' => 'ASC', |
|
| 362 | - 'TKT_end_date' => 'ASC', |
|
| 363 | - 'Datetime.DTT_EVT_start' => 'DESC', |
|
| 364 | - ), |
|
| 365 | - ); |
|
| 366 | - if ( |
|
| 367 | - ! ( |
|
| 368 | - EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
| 369 | - && EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets |
|
| 370 | - ) |
|
| 371 | - ) { |
|
| 372 | - //use the correct applicable time query depending on what version of core is being run. |
|
| 373 | - $current_time = method_exists('EEM_Datetime', 'current_time_for_query') |
|
| 374 | - ? time() |
|
| 375 | - : current_time('timestamp'); |
|
| 376 | - $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time); |
|
| 377 | - } |
|
| 378 | - return EEM_Ticket::instance()->get_all($ticket_query_args); |
|
| 379 | - } |
|
| 380 | - |
|
| 381 | - |
|
| 382 | - |
|
| 383 | - /** |
|
| 384 | - * loadTicketSelector |
|
| 385 | - * begins to assemble template arguments |
|
| 386 | - * and decides whether to load a "simple" ticket selector, or the standard |
|
| 387 | - * |
|
| 388 | - * @param \EE_Ticket[] $tickets |
|
| 389 | - * @param array $template_args |
|
| 390 | - * @return string |
|
| 391 | - * @throws EE_Error |
|
| 392 | - */ |
|
| 393 | - protected function loadTicketSelector(array $tickets, array $template_args) |
|
| 394 | - { |
|
| 395 | - $template_args['event'] = $this->event; |
|
| 396 | - $template_args['EVT_ID'] = $this->event->ID(); |
|
| 397 | - $template_args['event_is_expired'] = $this->event->is_expired(); |
|
| 398 | - $template_args['max_atndz'] = $this->getMaxAttendees(); |
|
| 399 | - $template_args['date_format'] = $this->date_format; |
|
| 400 | - $template_args['time_format'] = $this->time_format; |
|
| 401 | - /** |
|
| 402 | - * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected |
|
| 403 | - * |
|
| 404 | - * @since 4.9.13 |
|
| 405 | - * @param string '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to |
|
| 406 | - * @param int $EVT_ID The Event ID |
|
| 407 | - */ |
|
| 408 | - $template_args['anchor_id'] = apply_filters( |
|
| 409 | - 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
|
| 410 | - '#tkt-slctr-tbl-' . $this->event->ID(), |
|
| 411 | - $this->event->ID() |
|
| 412 | - ); |
|
| 413 | - $template_args['tickets'] = $tickets; |
|
| 414 | - $template_args['ticket_count'] = count($tickets); |
|
| 415 | - $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args); |
|
| 416 | - return $ticket_selector instanceof TicketSelectorSimple |
|
| 417 | - ? $ticket_selector |
|
| 418 | - : new TicketSelectorStandard( |
|
| 419 | - $this->event, |
|
| 420 | - $tickets, |
|
| 421 | - $this->getMaxAttendees(), |
|
| 422 | - $template_args, |
|
| 423 | - $this->date_format, |
|
| 424 | - $this->time_format |
|
| 425 | - ); |
|
| 426 | - } |
|
| 427 | - |
|
| 428 | - |
|
| 429 | - |
|
| 430 | - /** |
|
| 431 | - * simpleTicketSelector |
|
| 432 | - * there's one ticket, and max attendees is set to one, |
|
| 433 | - * so if the event is free, then this is a "simple" ticket selector |
|
| 434 | - * a.k.a. "Dude Where's my Ticket Selector?" |
|
| 435 | - * |
|
| 436 | - * @param \EE_Ticket[] $tickets |
|
| 437 | - * @param array $template_args |
|
| 438 | - * @return string |
|
| 439 | - * @throws EE_Error |
|
| 440 | - */ |
|
| 441 | - protected function simpleTicketSelector($tickets, array $template_args) |
|
| 442 | - { |
|
| 443 | - // if there is only ONE ticket with a max qty of ONE |
|
| 444 | - if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) { |
|
| 445 | - return ''; |
|
| 446 | - } |
|
| 447 | - /** @var \EE_Ticket $ticket */ |
|
| 448 | - $ticket = reset($tickets); |
|
| 449 | - // if the ticket is free... then not much need for the ticket selector |
|
| 450 | - if ( |
|
| 451 | - apply_filters( |
|
| 452 | - 'FHEE__ticket_selector_chart_template__hide_ticket_selector', |
|
| 453 | - $ticket->is_free(), |
|
| 454 | - $this->event->ID() |
|
| 455 | - ) |
|
| 456 | - ) { |
|
| 457 | - return new TicketSelectorSimple( |
|
| 458 | - $this->event, |
|
| 459 | - $ticket, |
|
| 460 | - $this->getMaxAttendees(), |
|
| 461 | - $template_args |
|
| 462 | - ); |
|
| 463 | - } |
|
| 464 | - return ''; |
|
| 465 | - } |
|
| 466 | - |
|
| 467 | - |
|
| 468 | - |
|
| 469 | - /** |
|
| 470 | - * externalEventRegistration |
|
| 471 | - * |
|
| 472 | - * @return string |
|
| 473 | - */ |
|
| 474 | - public function externalEventRegistration() |
|
| 475 | - { |
|
| 476 | - // if not we still need to trigger the display of the submit button |
|
| 477 | - add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
| 478 | - //display notice to admin that registration is external |
|
| 479 | - return $this->display_full_ui() |
|
| 480 | - ? esc_html__( |
|
| 481 | - 'Registration is at an external URL for this event.', |
|
| 482 | - 'event_espresso' |
|
| 483 | - ) |
|
| 484 | - : ''; |
|
| 485 | - } |
|
| 486 | - |
|
| 487 | - |
|
| 488 | - |
|
| 489 | - /** |
|
| 490 | - * formOpen |
|
| 491 | - * |
|
| 492 | - * @param int $ID |
|
| 493 | - * @param string $external_url |
|
| 494 | - * @return string |
|
| 495 | - */ |
|
| 496 | - public function formOpen( $ID = 0, $external_url = '' ) |
|
| 497 | - { |
|
| 498 | - // if redirecting, we don't need any anything else |
|
| 499 | - if ( $external_url ) { |
|
| 500 | - $html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"'; |
|
| 501 | - // open link in new window ? |
|
| 502 | - $html .= apply_filters( |
|
| 503 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
|
| 504 | - EED_Events_Archive::is_iframe() |
|
| 505 | - ) |
|
| 506 | - ? ' target="_blank"' |
|
| 507 | - : ''; |
|
| 508 | - $html .= '>'; |
|
| 509 | - $query_args = EEH_URL::get_query_string( $external_url ); |
|
| 510 | - foreach ( (array)$query_args as $query_arg => $value ) { |
|
| 511 | - $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
| 512 | - } |
|
| 513 | - return $html; |
|
| 514 | - } |
|
| 515 | - // if there is no submit button, then don't start building a form |
|
| 516 | - // because the "View Details" button will build its own form |
|
| 517 | - if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) { |
|
| 518 | - return ''; |
|
| 519 | - } |
|
| 520 | - $checkout_url = EEH_Event_View::event_link_url( $ID ); |
|
| 521 | - if ( ! $checkout_url ) { |
|
| 522 | - EE_Error::add_error( |
|
| 523 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
| 524 | - __FILE__, |
|
| 525 | - __FUNCTION__, |
|
| 526 | - __LINE__ |
|
| 527 | - ); |
|
| 528 | - } |
|
| 529 | - // set no cache headers and constants |
|
| 530 | - EE_System::do_not_cache(); |
|
| 531 | - $extra_params = $this->iframe ? ' target="_blank"' : ''; |
|
| 532 | - $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>'; |
|
| 533 | - $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
|
| 534 | - $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event ); |
|
| 535 | - return $html; |
|
| 536 | - } |
|
| 537 | - |
|
| 538 | - |
|
| 539 | - |
|
| 540 | - /** |
|
| 541 | - * displaySubmitButton |
|
| 542 | - * |
|
| 543 | - * @param string $external_url |
|
| 544 | - * @return string |
|
| 545 | - * @throws EE_Error |
|
| 546 | - */ |
|
| 547 | - public function displaySubmitButton($external_url = '') |
|
| 548 | - { |
|
| 549 | - $html = ''; |
|
| 550 | - if ($this->display_full_ui()) { |
|
| 551 | - // standard TS displayed with submit button, ie: "Register Now" |
|
| 552 | - if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 553 | - $html .= $this->displayRegisterNowButton(); |
|
| 554 | - $html .= empty($external_url) |
|
| 555 | - ? $this->ticketSelectorEndDiv() |
|
| 556 | - : $this->clearTicketSelector(); |
|
| 557 | - $html .= '<br/>' . $this->formClose(); |
|
| 558 | - } elseif ($this->getMaxAttendees() === 1) { |
|
| 559 | - // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
|
| 560 | - if ($this->event->is_sold_out()) { |
|
| 561 | - // then instead of a View Details or Submit button, just display a "Sold Out" message |
|
| 562 | - $html .= apply_filters( |
|
| 563 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg', |
|
| 564 | - sprintf( |
|
| 565 | - __( |
|
| 566 | - '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s', |
|
| 567 | - 'event_espresso' |
|
| 568 | - ), |
|
| 569 | - '<p class="no-ticket-selector-msg clear-float">', |
|
| 570 | - $this->event->name(), |
|
| 571 | - '</p>', |
|
| 572 | - '<br />' |
|
| 573 | - ), |
|
| 574 | - $this->event |
|
| 575 | - ); |
|
| 576 | - if ( |
|
| 577 | - apply_filters( |
|
| 578 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 579 | - false, |
|
| 580 | - $this->event |
|
| 581 | - ) |
|
| 582 | - ) { |
|
| 583 | - $html .= $this->displayRegisterNowButton(); |
|
| 584 | - } |
|
| 585 | - // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
|
| 586 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 587 | - } elseif ( |
|
| 588 | - apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
|
| 589 | - && ! is_single() |
|
| 590 | - ) { |
|
| 591 | - // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event, |
|
| 592 | - // but no tickets are available, so display event's "View Details" button. |
|
| 593 | - // it is being viewed via somewhere other than a single post |
|
| 594 | - $html .= $this->displayViewDetailsButton(true); |
|
| 595 | - } else { |
|
| 596 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 597 | - } |
|
| 598 | - } elseif (is_archive()) { |
|
| 599 | - // event list, no tickets available so display event's "View Details" button |
|
| 600 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 601 | - $html .= $this->displayViewDetailsButton(); |
|
| 602 | - } else { |
|
| 603 | - if ( |
|
| 604 | - apply_filters( |
|
| 605 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 606 | - false, |
|
| 607 | - $this->event |
|
| 608 | - ) |
|
| 609 | - ) { |
|
| 610 | - $html .= $this->displayRegisterNowButton(); |
|
| 611 | - } |
|
| 612 | - // no submit or view details button, and no additional content |
|
| 613 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 614 | - } |
|
| 615 | - if ( ! $this->iframe && ! is_archive()) { |
|
| 616 | - $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector')); |
|
| 617 | - } |
|
| 618 | - } |
|
| 619 | - return apply_filters( |
|
| 620 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displaySubmitButton__html', |
|
| 621 | - $html, |
|
| 622 | - $this->event |
|
| 623 | - ); |
|
| 624 | - } |
|
| 625 | - |
|
| 626 | - |
|
| 627 | - |
|
| 628 | - /** |
|
| 629 | - * @return string |
|
| 630 | - * @throws EE_Error |
|
| 631 | - */ |
|
| 632 | - public function displayRegisterNowButton() |
|
| 633 | - { |
|
| 634 | - $btn_text = apply_filters( |
|
| 635 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text', |
|
| 636 | - __('Register Now', 'event_espresso'), |
|
| 637 | - $this->event |
|
| 638 | - ); |
|
| 639 | - $external_url = $this->event->external_url(); |
|
| 640 | - $html = EEH_HTML::div( |
|
| 641 | - '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
| 642 | - ); |
|
| 643 | - $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
| 644 | - $html .= ' class="ticket-selector-submit-btn '; |
|
| 645 | - $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
|
| 646 | - $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
| 647 | - $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 648 | - $html .= apply_filters( |
|
| 649 | - 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
|
| 650 | - '', |
|
| 651 | - $this->event |
|
| 652 | - ); |
|
| 653 | - return $html; |
|
| 654 | - } |
|
| 655 | - |
|
| 656 | - |
|
| 657 | - /** |
|
| 658 | - * displayViewDetailsButton |
|
| 659 | - * |
|
| 660 | - * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event |
|
| 661 | - * (ie: $_max_atndz === 1) where there are no available tickets, |
|
| 662 | - * either because they are sold out, expired, or not yet on sale. |
|
| 663 | - * In this case, we need to close the form BEFORE adding any closing divs |
|
| 664 | - * @return string |
|
| 665 | - * @throws EE_Error |
|
| 666 | - */ |
|
| 667 | - public function displayViewDetailsButton( $DWMTS = false ) |
|
| 668 | - { |
|
| 669 | - if ( ! $this->event->get_permalink() ) { |
|
| 670 | - EE_Error::add_error( |
|
| 671 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
| 672 | - __FILE__, __FUNCTION__, __LINE__ |
|
| 673 | - ); |
|
| 674 | - } |
|
| 675 | - $view_details_btn = '<form method="POST" action="'; |
|
| 676 | - $view_details_btn .= apply_filters( |
|
| 677 | - 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url', |
|
| 678 | - $this->event->get_permalink(), |
|
| 679 | - $this->event |
|
| 680 | - ); |
|
| 681 | - $view_details_btn .= '"'; |
|
| 682 | - // open link in new window ? |
|
| 683 | - $view_details_btn .= apply_filters( |
|
| 684 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank', |
|
| 685 | - EED_Events_Archive::is_iframe() |
|
| 686 | - ) |
|
| 687 | - ? ' target="_blank"' |
|
| 688 | - : ''; |
|
| 689 | - $view_details_btn .='>'; |
|
| 690 | - $btn_text = apply_filters( |
|
| 691 | - 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
|
| 692 | - esc_html__('View Details', 'event_espresso'), |
|
| 693 | - $this->event |
|
| 694 | - ); |
|
| 695 | - $view_details_btn .= '<input id="ticket-selector-submit-' |
|
| 696 | - . $this->event->ID() |
|
| 697 | - . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
|
| 698 | - . $btn_text |
|
| 699 | - . '" />'; |
|
| 700 | - $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event ); |
|
| 701 | - if ($DWMTS) { |
|
| 702 | - $view_details_btn .= $this->formClose(); |
|
| 703 | - $view_details_btn .= $this->ticketSelectorEndDiv(); |
|
| 704 | - $view_details_btn .= '<br/>'; |
|
| 705 | - } else { |
|
| 706 | - $view_details_btn .= $this->clearTicketSelector(); |
|
| 707 | - $view_details_btn .= '<br/>'; |
|
| 708 | - $view_details_btn .= $this->formClose(); |
|
| 709 | - } |
|
| 710 | - return $view_details_btn; |
|
| 711 | - } |
|
| 712 | - |
|
| 713 | - |
|
| 714 | - |
|
| 715 | - /** |
|
| 716 | - * @return string |
|
| 717 | - */ |
|
| 718 | - public function ticketSelectorEndDiv() |
|
| 719 | - { |
|
| 720 | - return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
| 721 | - } |
|
| 722 | - |
|
| 723 | - |
|
| 724 | - |
|
| 725 | - /** |
|
| 726 | - * @return string |
|
| 727 | - */ |
|
| 728 | - public function clearTicketSelector() |
|
| 729 | - { |
|
| 730 | - // standard TS displayed, appears after a "Register Now" or "view Details" button |
|
| 731 | - return '<div class="clear"></div><!-- clearTicketSelector -->'; |
|
| 732 | - } |
|
| 733 | - |
|
| 734 | - |
|
| 735 | - |
|
| 736 | - /** |
|
| 737 | - * @access public |
|
| 738 | - * @return string |
|
| 739 | - */ |
|
| 740 | - public function formClose() |
|
| 741 | - { |
|
| 742 | - return '</form>'; |
|
| 743 | - } |
|
| 314 | + } |
|
| 315 | + |
|
| 316 | + |
|
| 317 | + |
|
| 318 | + /** |
|
| 319 | + * ticketSalesClosed |
|
| 320 | + * notice displayed if event ticket sales are turned off |
|
| 321 | + * |
|
| 322 | + * @return string |
|
| 323 | + * @throws EE_Error |
|
| 324 | + */ |
|
| 325 | + protected function ticketSalesClosedMessage() |
|
| 326 | + { |
|
| 327 | + $sales_closed_msg = esc_html__( |
|
| 328 | + 'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.', |
|
| 329 | + 'event_espresso' |
|
| 330 | + ); |
|
| 331 | + if (current_user_can('edit_post', $this->event->ID())) { |
|
| 332 | + $sales_closed_msg .= sprintf( |
|
| 333 | + esc_html__( |
|
| 334 | + '%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s', |
|
| 335 | + 'event_espresso' |
|
| 336 | + ), |
|
| 337 | + '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 338 | + '</b><br />', |
|
| 339 | + '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
| 340 | + '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
|
| 341 | + ); |
|
| 342 | + } |
|
| 343 | + return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
| 344 | + } |
|
| 345 | + |
|
| 346 | + |
|
| 347 | + |
|
| 348 | + /** |
|
| 349 | + * getTickets |
|
| 350 | + * |
|
| 351 | + * @return \EE_Base_Class[]|\EE_Ticket[] |
|
| 352 | + * @throws EE_Error |
|
| 353 | + */ |
|
| 354 | + protected function getTickets() |
|
| 355 | + { |
|
| 356 | + $ticket_query_args = array( |
|
| 357 | + array('Datetime.EVT_ID' => $this->event->ID()), |
|
| 358 | + 'order_by' => array( |
|
| 359 | + 'TKT_order' => 'ASC', |
|
| 360 | + 'TKT_required' => 'DESC', |
|
| 361 | + 'TKT_start_date' => 'ASC', |
|
| 362 | + 'TKT_end_date' => 'ASC', |
|
| 363 | + 'Datetime.DTT_EVT_start' => 'DESC', |
|
| 364 | + ), |
|
| 365 | + ); |
|
| 366 | + if ( |
|
| 367 | + ! ( |
|
| 368 | + EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
| 369 | + && EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets |
|
| 370 | + ) |
|
| 371 | + ) { |
|
| 372 | + //use the correct applicable time query depending on what version of core is being run. |
|
| 373 | + $current_time = method_exists('EEM_Datetime', 'current_time_for_query') |
|
| 374 | + ? time() |
|
| 375 | + : current_time('timestamp'); |
|
| 376 | + $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time); |
|
| 377 | + } |
|
| 378 | + return EEM_Ticket::instance()->get_all($ticket_query_args); |
|
| 379 | + } |
|
| 380 | + |
|
| 381 | + |
|
| 382 | + |
|
| 383 | + /** |
|
| 384 | + * loadTicketSelector |
|
| 385 | + * begins to assemble template arguments |
|
| 386 | + * and decides whether to load a "simple" ticket selector, or the standard |
|
| 387 | + * |
|
| 388 | + * @param \EE_Ticket[] $tickets |
|
| 389 | + * @param array $template_args |
|
| 390 | + * @return string |
|
| 391 | + * @throws EE_Error |
|
| 392 | + */ |
|
| 393 | + protected function loadTicketSelector(array $tickets, array $template_args) |
|
| 394 | + { |
|
| 395 | + $template_args['event'] = $this->event; |
|
| 396 | + $template_args['EVT_ID'] = $this->event->ID(); |
|
| 397 | + $template_args['event_is_expired'] = $this->event->is_expired(); |
|
| 398 | + $template_args['max_atndz'] = $this->getMaxAttendees(); |
|
| 399 | + $template_args['date_format'] = $this->date_format; |
|
| 400 | + $template_args['time_format'] = $this->time_format; |
|
| 401 | + /** |
|
| 402 | + * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected |
|
| 403 | + * |
|
| 404 | + * @since 4.9.13 |
|
| 405 | + * @param string '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to |
|
| 406 | + * @param int $EVT_ID The Event ID |
|
| 407 | + */ |
|
| 408 | + $template_args['anchor_id'] = apply_filters( |
|
| 409 | + 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
|
| 410 | + '#tkt-slctr-tbl-' . $this->event->ID(), |
|
| 411 | + $this->event->ID() |
|
| 412 | + ); |
|
| 413 | + $template_args['tickets'] = $tickets; |
|
| 414 | + $template_args['ticket_count'] = count($tickets); |
|
| 415 | + $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args); |
|
| 416 | + return $ticket_selector instanceof TicketSelectorSimple |
|
| 417 | + ? $ticket_selector |
|
| 418 | + : new TicketSelectorStandard( |
|
| 419 | + $this->event, |
|
| 420 | + $tickets, |
|
| 421 | + $this->getMaxAttendees(), |
|
| 422 | + $template_args, |
|
| 423 | + $this->date_format, |
|
| 424 | + $this->time_format |
|
| 425 | + ); |
|
| 426 | + } |
|
| 427 | + |
|
| 428 | + |
|
| 429 | + |
|
| 430 | + /** |
|
| 431 | + * simpleTicketSelector |
|
| 432 | + * there's one ticket, and max attendees is set to one, |
|
| 433 | + * so if the event is free, then this is a "simple" ticket selector |
|
| 434 | + * a.k.a. "Dude Where's my Ticket Selector?" |
|
| 435 | + * |
|
| 436 | + * @param \EE_Ticket[] $tickets |
|
| 437 | + * @param array $template_args |
|
| 438 | + * @return string |
|
| 439 | + * @throws EE_Error |
|
| 440 | + */ |
|
| 441 | + protected function simpleTicketSelector($tickets, array $template_args) |
|
| 442 | + { |
|
| 443 | + // if there is only ONE ticket with a max qty of ONE |
|
| 444 | + if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) { |
|
| 445 | + return ''; |
|
| 446 | + } |
|
| 447 | + /** @var \EE_Ticket $ticket */ |
|
| 448 | + $ticket = reset($tickets); |
|
| 449 | + // if the ticket is free... then not much need for the ticket selector |
|
| 450 | + if ( |
|
| 451 | + apply_filters( |
|
| 452 | + 'FHEE__ticket_selector_chart_template__hide_ticket_selector', |
|
| 453 | + $ticket->is_free(), |
|
| 454 | + $this->event->ID() |
|
| 455 | + ) |
|
| 456 | + ) { |
|
| 457 | + return new TicketSelectorSimple( |
|
| 458 | + $this->event, |
|
| 459 | + $ticket, |
|
| 460 | + $this->getMaxAttendees(), |
|
| 461 | + $template_args |
|
| 462 | + ); |
|
| 463 | + } |
|
| 464 | + return ''; |
|
| 465 | + } |
|
| 466 | + |
|
| 467 | + |
|
| 468 | + |
|
| 469 | + /** |
|
| 470 | + * externalEventRegistration |
|
| 471 | + * |
|
| 472 | + * @return string |
|
| 473 | + */ |
|
| 474 | + public function externalEventRegistration() |
|
| 475 | + { |
|
| 476 | + // if not we still need to trigger the display of the submit button |
|
| 477 | + add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
| 478 | + //display notice to admin that registration is external |
|
| 479 | + return $this->display_full_ui() |
|
| 480 | + ? esc_html__( |
|
| 481 | + 'Registration is at an external URL for this event.', |
|
| 482 | + 'event_espresso' |
|
| 483 | + ) |
|
| 484 | + : ''; |
|
| 485 | + } |
|
| 486 | + |
|
| 487 | + |
|
| 488 | + |
|
| 489 | + /** |
|
| 490 | + * formOpen |
|
| 491 | + * |
|
| 492 | + * @param int $ID |
|
| 493 | + * @param string $external_url |
|
| 494 | + * @return string |
|
| 495 | + */ |
|
| 496 | + public function formOpen( $ID = 0, $external_url = '' ) |
|
| 497 | + { |
|
| 498 | + // if redirecting, we don't need any anything else |
|
| 499 | + if ( $external_url ) { |
|
| 500 | + $html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"'; |
|
| 501 | + // open link in new window ? |
|
| 502 | + $html .= apply_filters( |
|
| 503 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
|
| 504 | + EED_Events_Archive::is_iframe() |
|
| 505 | + ) |
|
| 506 | + ? ' target="_blank"' |
|
| 507 | + : ''; |
|
| 508 | + $html .= '>'; |
|
| 509 | + $query_args = EEH_URL::get_query_string( $external_url ); |
|
| 510 | + foreach ( (array)$query_args as $query_arg => $value ) { |
|
| 511 | + $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
| 512 | + } |
|
| 513 | + return $html; |
|
| 514 | + } |
|
| 515 | + // if there is no submit button, then don't start building a form |
|
| 516 | + // because the "View Details" button will build its own form |
|
| 517 | + if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) { |
|
| 518 | + return ''; |
|
| 519 | + } |
|
| 520 | + $checkout_url = EEH_Event_View::event_link_url( $ID ); |
|
| 521 | + if ( ! $checkout_url ) { |
|
| 522 | + EE_Error::add_error( |
|
| 523 | + esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
| 524 | + __FILE__, |
|
| 525 | + __FUNCTION__, |
|
| 526 | + __LINE__ |
|
| 527 | + ); |
|
| 528 | + } |
|
| 529 | + // set no cache headers and constants |
|
| 530 | + EE_System::do_not_cache(); |
|
| 531 | + $extra_params = $this->iframe ? ' target="_blank"' : ''; |
|
| 532 | + $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>'; |
|
| 533 | + $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
|
| 534 | + $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event ); |
|
| 535 | + return $html; |
|
| 536 | + } |
|
| 537 | + |
|
| 538 | + |
|
| 539 | + |
|
| 540 | + /** |
|
| 541 | + * displaySubmitButton |
|
| 542 | + * |
|
| 543 | + * @param string $external_url |
|
| 544 | + * @return string |
|
| 545 | + * @throws EE_Error |
|
| 546 | + */ |
|
| 547 | + public function displaySubmitButton($external_url = '') |
|
| 548 | + { |
|
| 549 | + $html = ''; |
|
| 550 | + if ($this->display_full_ui()) { |
|
| 551 | + // standard TS displayed with submit button, ie: "Register Now" |
|
| 552 | + if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 553 | + $html .= $this->displayRegisterNowButton(); |
|
| 554 | + $html .= empty($external_url) |
|
| 555 | + ? $this->ticketSelectorEndDiv() |
|
| 556 | + : $this->clearTicketSelector(); |
|
| 557 | + $html .= '<br/>' . $this->formClose(); |
|
| 558 | + } elseif ($this->getMaxAttendees() === 1) { |
|
| 559 | + // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
|
| 560 | + if ($this->event->is_sold_out()) { |
|
| 561 | + // then instead of a View Details or Submit button, just display a "Sold Out" message |
|
| 562 | + $html .= apply_filters( |
|
| 563 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg', |
|
| 564 | + sprintf( |
|
| 565 | + __( |
|
| 566 | + '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s', |
|
| 567 | + 'event_espresso' |
|
| 568 | + ), |
|
| 569 | + '<p class="no-ticket-selector-msg clear-float">', |
|
| 570 | + $this->event->name(), |
|
| 571 | + '</p>', |
|
| 572 | + '<br />' |
|
| 573 | + ), |
|
| 574 | + $this->event |
|
| 575 | + ); |
|
| 576 | + if ( |
|
| 577 | + apply_filters( |
|
| 578 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 579 | + false, |
|
| 580 | + $this->event |
|
| 581 | + ) |
|
| 582 | + ) { |
|
| 583 | + $html .= $this->displayRegisterNowButton(); |
|
| 584 | + } |
|
| 585 | + // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
|
| 586 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 587 | + } elseif ( |
|
| 588 | + apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
|
| 589 | + && ! is_single() |
|
| 590 | + ) { |
|
| 591 | + // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event, |
|
| 592 | + // but no tickets are available, so display event's "View Details" button. |
|
| 593 | + // it is being viewed via somewhere other than a single post |
|
| 594 | + $html .= $this->displayViewDetailsButton(true); |
|
| 595 | + } else { |
|
| 596 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 597 | + } |
|
| 598 | + } elseif (is_archive()) { |
|
| 599 | + // event list, no tickets available so display event's "View Details" button |
|
| 600 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 601 | + $html .= $this->displayViewDetailsButton(); |
|
| 602 | + } else { |
|
| 603 | + if ( |
|
| 604 | + apply_filters( |
|
| 605 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 606 | + false, |
|
| 607 | + $this->event |
|
| 608 | + ) |
|
| 609 | + ) { |
|
| 610 | + $html .= $this->displayRegisterNowButton(); |
|
| 611 | + } |
|
| 612 | + // no submit or view details button, and no additional content |
|
| 613 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 614 | + } |
|
| 615 | + if ( ! $this->iframe && ! is_archive()) { |
|
| 616 | + $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector')); |
|
| 617 | + } |
|
| 618 | + } |
|
| 619 | + return apply_filters( |
|
| 620 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displaySubmitButton__html', |
|
| 621 | + $html, |
|
| 622 | + $this->event |
|
| 623 | + ); |
|
| 624 | + } |
|
| 625 | + |
|
| 626 | + |
|
| 627 | + |
|
| 628 | + /** |
|
| 629 | + * @return string |
|
| 630 | + * @throws EE_Error |
|
| 631 | + */ |
|
| 632 | + public function displayRegisterNowButton() |
|
| 633 | + { |
|
| 634 | + $btn_text = apply_filters( |
|
| 635 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text', |
|
| 636 | + __('Register Now', 'event_espresso'), |
|
| 637 | + $this->event |
|
| 638 | + ); |
|
| 639 | + $external_url = $this->event->external_url(); |
|
| 640 | + $html = EEH_HTML::div( |
|
| 641 | + '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
| 642 | + ); |
|
| 643 | + $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
| 644 | + $html .= ' class="ticket-selector-submit-btn '; |
|
| 645 | + $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
|
| 646 | + $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
| 647 | + $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 648 | + $html .= apply_filters( |
|
| 649 | + 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
|
| 650 | + '', |
|
| 651 | + $this->event |
|
| 652 | + ); |
|
| 653 | + return $html; |
|
| 654 | + } |
|
| 655 | + |
|
| 656 | + |
|
| 657 | + /** |
|
| 658 | + * displayViewDetailsButton |
|
| 659 | + * |
|
| 660 | + * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event |
|
| 661 | + * (ie: $_max_atndz === 1) where there are no available tickets, |
|
| 662 | + * either because they are sold out, expired, or not yet on sale. |
|
| 663 | + * In this case, we need to close the form BEFORE adding any closing divs |
|
| 664 | + * @return string |
|
| 665 | + * @throws EE_Error |
|
| 666 | + */ |
|
| 667 | + public function displayViewDetailsButton( $DWMTS = false ) |
|
| 668 | + { |
|
| 669 | + if ( ! $this->event->get_permalink() ) { |
|
| 670 | + EE_Error::add_error( |
|
| 671 | + esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
| 672 | + __FILE__, __FUNCTION__, __LINE__ |
|
| 673 | + ); |
|
| 674 | + } |
|
| 675 | + $view_details_btn = '<form method="POST" action="'; |
|
| 676 | + $view_details_btn .= apply_filters( |
|
| 677 | + 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url', |
|
| 678 | + $this->event->get_permalink(), |
|
| 679 | + $this->event |
|
| 680 | + ); |
|
| 681 | + $view_details_btn .= '"'; |
|
| 682 | + // open link in new window ? |
|
| 683 | + $view_details_btn .= apply_filters( |
|
| 684 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank', |
|
| 685 | + EED_Events_Archive::is_iframe() |
|
| 686 | + ) |
|
| 687 | + ? ' target="_blank"' |
|
| 688 | + : ''; |
|
| 689 | + $view_details_btn .='>'; |
|
| 690 | + $btn_text = apply_filters( |
|
| 691 | + 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
|
| 692 | + esc_html__('View Details', 'event_espresso'), |
|
| 693 | + $this->event |
|
| 694 | + ); |
|
| 695 | + $view_details_btn .= '<input id="ticket-selector-submit-' |
|
| 696 | + . $this->event->ID() |
|
| 697 | + . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
|
| 698 | + . $btn_text |
|
| 699 | + . '" />'; |
|
| 700 | + $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event ); |
|
| 701 | + if ($DWMTS) { |
|
| 702 | + $view_details_btn .= $this->formClose(); |
|
| 703 | + $view_details_btn .= $this->ticketSelectorEndDiv(); |
|
| 704 | + $view_details_btn .= '<br/>'; |
|
| 705 | + } else { |
|
| 706 | + $view_details_btn .= $this->clearTicketSelector(); |
|
| 707 | + $view_details_btn .= '<br/>'; |
|
| 708 | + $view_details_btn .= $this->formClose(); |
|
| 709 | + } |
|
| 710 | + return $view_details_btn; |
|
| 711 | + } |
|
| 712 | + |
|
| 713 | + |
|
| 714 | + |
|
| 715 | + /** |
|
| 716 | + * @return string |
|
| 717 | + */ |
|
| 718 | + public function ticketSelectorEndDiv() |
|
| 719 | + { |
|
| 720 | + return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
| 721 | + } |
|
| 722 | + |
|
| 723 | + |
|
| 724 | + |
|
| 725 | + /** |
|
| 726 | + * @return string |
|
| 727 | + */ |
|
| 728 | + public function clearTicketSelector() |
|
| 729 | + { |
|
| 730 | + // standard TS displayed, appears after a "Register Now" or "view Details" button |
|
| 731 | + return '<div class="clear"></div><!-- clearTicketSelector -->'; |
|
| 732 | + } |
|
| 733 | + |
|
| 734 | + |
|
| 735 | + |
|
| 736 | + /** |
|
| 737 | + * @access public |
|
| 738 | + * @return string |
|
| 739 | + */ |
|
| 740 | + public function formClose() |
|
| 741 | + { |
|
| 742 | + return '</form>'; |
|
| 743 | + } |
|
| 744 | 744 | |
| 745 | 745 | |
| 746 | 746 | |
@@ -16,8 +16,8 @@ discard block |
||
| 16 | 16 | use EEM_Ticket; |
| 17 | 17 | use WP_Post; |
| 18 | 18 | |
| 19 | -if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) { |
|
| 20 | - exit( 'No direct script access allowed' ); |
|
| 19 | +if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
|
| 20 | + exit('No direct script access allowed'); |
|
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | |
@@ -93,9 +93,9 @@ discard block |
||
| 93 | 93 | /** |
| 94 | 94 | * @param boolean $iframe |
| 95 | 95 | */ |
| 96 | - public function setIframe( $iframe = true ) |
|
| 96 | + public function setIframe($iframe = true) |
|
| 97 | 97 | { |
| 98 | - $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN ); |
|
| 98 | + $this->iframe = filter_var($iframe, FILTER_VALIDATE_BOOLEAN); |
|
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 101 | |
@@ -106,28 +106,28 @@ discard block |
||
| 106 | 106 | * @return bool |
| 107 | 107 | * @throws EE_Error |
| 108 | 108 | */ |
| 109 | - protected function setEvent( $event = null ) |
|
| 109 | + protected function setEvent($event = null) |
|
| 110 | 110 | { |
| 111 | - if ( $event === null ) { |
|
| 111 | + if ($event === null) { |
|
| 112 | 112 | global $post; |
| 113 | 113 | $event = $post; |
| 114 | 114 | } |
| 115 | - if ( $event instanceof EE_Event ) { |
|
| 115 | + if ($event instanceof EE_Event) { |
|
| 116 | 116 | $this->event = $event; |
| 117 | - } elseif ( $event instanceof WP_Post ) { |
|
| 118 | - if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) { |
|
| 117 | + } elseif ($event instanceof WP_Post) { |
|
| 118 | + if (isset($event->EE_Event) && $event->EE_Event instanceof EE_Event) { |
|
| 119 | 119 | $this->event = $event->EE_Event; |
| 120 | - } elseif ( $event->post_type === 'espresso_events' ) { |
|
| 121 | - $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event ); |
|
| 120 | + } elseif ($event->post_type === 'espresso_events') { |
|
| 121 | + $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object($event); |
|
| 122 | 122 | $this->event = $event->EE_Event; |
| 123 | 123 | } |
| 124 | 124 | } else { |
| 125 | - $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' ); |
|
| 126 | - $dev_msg = $user_msg . __( |
|
| 125 | + $user_msg = __('No Event object or an invalid Event object was supplied.', 'event_espresso'); |
|
| 126 | + $dev_msg = $user_msg.__( |
|
| 127 | 127 | 'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.', |
| 128 | 128 | 'event_espresso' |
| 129 | 129 | ); |
| 130 | - EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ ); |
|
| 130 | + EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 131 | 131 | return false; |
| 132 | 132 | } |
| 133 | 133 | return true; |
@@ -182,16 +182,16 @@ discard block |
||
| 182 | 182 | * @return string |
| 183 | 183 | * @throws EE_Error |
| 184 | 184 | */ |
| 185 | - public function display( $event = null, $view_details = false ) |
|
| 185 | + public function display($event = null, $view_details = false) |
|
| 186 | 186 | { |
| 187 | 187 | // reset filter for displaying submit button |
| 188 | - remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' ); |
|
| 188 | + remove_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
| 189 | 189 | // poke and prod incoming event till it tells us what it is |
| 190 | - if ( ! $this->setEvent( $event ) ) { |
|
| 190 | + if ( ! $this->setEvent($event)) { |
|
| 191 | 191 | return false; |
| 192 | 192 | } |
| 193 | 193 | // begin gathering template arguments by getting event status |
| 194 | - $template_args = array( 'event_status' => $this->event->get_active_status() ); |
|
| 194 | + $template_args = array('event_status' => $this->event->get_active_status()); |
|
| 195 | 195 | if ( |
| 196 | 196 | $this->activeEventAndShowTicketSelector( |
| 197 | 197 | $event, |
@@ -208,7 +208,7 @@ discard block |
||
| 208 | 208 | } |
| 209 | 209 | // is the event expired ? |
| 210 | 210 | $template_args['event_is_expired'] = $this->event->is_expired(); |
| 211 | - if ( $template_args[ 'event_is_expired' ] ) { |
|
| 211 | + if ($template_args['event_is_expired']) { |
|
| 212 | 212 | return $this->expiredEventMessage(); |
| 213 | 213 | } |
| 214 | 214 | // get all tickets for this event ordered by the datetime |
@@ -216,7 +216,7 @@ discard block |
||
| 216 | 216 | if (count($tickets) < 1) { |
| 217 | 217 | return $this->noTicketAvailableMessage(); |
| 218 | 218 | } |
| 219 | - if (EED_Events_Archive::is_iframe()){ |
|
| 219 | + if (EED_Events_Archive::is_iframe()) { |
|
| 220 | 220 | $this->setIframe(); |
| 221 | 221 | } |
| 222 | 222 | // redirecting to another site for registration ?? |
@@ -224,10 +224,10 @@ discard block |
||
| 224 | 224 | // if redirecting to another site for registration, then we don't load the TS |
| 225 | 225 | $ticket_selector = $external_url |
| 226 | 226 | ? $this->externalEventRegistration() |
| 227 | - : $this->loadTicketSelector($tickets,$template_args); |
|
| 227 | + : $this->loadTicketSelector($tickets, $template_args); |
|
| 228 | 228 | // now set up the form (but not for the admin) |
| 229 | 229 | $ticket_selector = $this->display_full_ui() |
| 230 | - ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
| 230 | + ? $this->formOpen($this->event->ID(), $external_url).$ticket_selector |
|
| 231 | 231 | : $ticket_selector; |
| 232 | 232 | // submit button and form close tag |
| 233 | 233 | $ticket_selector .= $this->display_full_ui() ? $this->displaySubmitButton($external_url) : ''; |
@@ -277,10 +277,10 @@ discard block |
||
| 277 | 277 | */ |
| 278 | 278 | protected function expiredEventMessage() |
| 279 | 279 | { |
| 280 | - return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
| 280 | + return '<div class="ee-event-expired-notice"><span class="important-notice">'.esc_html__( |
|
| 281 | 281 | 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
| 282 | 282 | 'event_espresso' |
| 283 | - ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
| 283 | + ).'</span></div><!-- .ee-event-expired-notice -->'; |
|
| 284 | 284 | } |
| 285 | 285 | |
| 286 | 286 | |
@@ -294,7 +294,7 @@ discard block |
||
| 294 | 294 | */ |
| 295 | 295 | protected function noTicketAvailableMessage() |
| 296 | 296 | { |
| 297 | - $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' ); |
|
| 297 | + $no_ticket_available_msg = esc_html__('We\'re sorry, but all ticket sales have ended.', 'event_espresso'); |
|
| 298 | 298 | if (current_user_can('edit_post', $this->event->ID())) { |
| 299 | 299 | $no_ticket_available_msg .= sprintf( |
| 300 | 300 | esc_html__( |
@@ -309,7 +309,7 @@ discard block |
||
| 309 | 309 | } |
| 310 | 310 | return ' |
| 311 | 311 | <div class="ee-event-expired-notice"> |
| 312 | - <span class="important-notice">' . $no_ticket_available_msg . '</span> |
|
| 312 | + <span class="important-notice">' . $no_ticket_available_msg.'</span> |
|
| 313 | 313 | </div><!-- .ee-event-expired-notice -->'; |
| 314 | 314 | } |
| 315 | 315 | |
@@ -340,7 +340,7 @@ discard block |
||
| 340 | 340 | '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
| 341 | 341 | ); |
| 342 | 342 | } |
| 343 | - return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
| 343 | + return '<p><span class="important-notice">'.$sales_closed_msg.'</span></p>'; |
|
| 344 | 344 | } |
| 345 | 345 | |
| 346 | 346 | |
@@ -407,12 +407,12 @@ discard block |
||
| 407 | 407 | */ |
| 408 | 408 | $template_args['anchor_id'] = apply_filters( |
| 409 | 409 | 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
| 410 | - '#tkt-slctr-tbl-' . $this->event->ID(), |
|
| 410 | + '#tkt-slctr-tbl-'.$this->event->ID(), |
|
| 411 | 411 | $this->event->ID() |
| 412 | 412 | ); |
| 413 | 413 | $template_args['tickets'] = $tickets; |
| 414 | 414 | $template_args['ticket_count'] = count($tickets); |
| 415 | - $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args); |
|
| 415 | + $ticket_selector = $this->simpleTicketSelector($tickets, $template_args); |
|
| 416 | 416 | return $ticket_selector instanceof TicketSelectorSimple |
| 417 | 417 | ? $ticket_selector |
| 418 | 418 | : new TicketSelectorStandard( |
@@ -493,11 +493,11 @@ discard block |
||
| 493 | 493 | * @param string $external_url |
| 494 | 494 | * @return string |
| 495 | 495 | */ |
| 496 | - public function formOpen( $ID = 0, $external_url = '' ) |
|
| 496 | + public function formOpen($ID = 0, $external_url = '') |
|
| 497 | 497 | { |
| 498 | 498 | // if redirecting, we don't need any anything else |
| 499 | - if ( $external_url ) { |
|
| 500 | - $html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"'; |
|
| 499 | + if ($external_url) { |
|
| 500 | + $html = '<form method="GET" action="'.EEH_URL::refactor_url($external_url).'"'; |
|
| 501 | 501 | // open link in new window ? |
| 502 | 502 | $html .= apply_filters( |
| 503 | 503 | 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
@@ -506,21 +506,21 @@ discard block |
||
| 506 | 506 | ? ' target="_blank"' |
| 507 | 507 | : ''; |
| 508 | 508 | $html .= '>'; |
| 509 | - $query_args = EEH_URL::get_query_string( $external_url ); |
|
| 510 | - foreach ( (array)$query_args as $query_arg => $value ) { |
|
| 511 | - $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
| 509 | + $query_args = EEH_URL::get_query_string($external_url); |
|
| 510 | + foreach ((array) $query_args as $query_arg => $value) { |
|
| 511 | + $html .= '<input type="hidden" name="'.$query_arg.'" value="'.$value.'">'; |
|
| 512 | 512 | } |
| 513 | 513 | return $html; |
| 514 | 514 | } |
| 515 | 515 | // if there is no submit button, then don't start building a form |
| 516 | 516 | // because the "View Details" button will build its own form |
| 517 | - if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) { |
|
| 517 | + if ( ! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 518 | 518 | return ''; |
| 519 | 519 | } |
| 520 | - $checkout_url = EEH_Event_View::event_link_url( $ID ); |
|
| 521 | - if ( ! $checkout_url ) { |
|
| 520 | + $checkout_url = EEH_Event_View::event_link_url($ID); |
|
| 521 | + if ( ! $checkout_url) { |
|
| 522 | 522 | EE_Error::add_error( |
| 523 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
| 523 | + esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
| 524 | 524 | __FILE__, |
| 525 | 525 | __FUNCTION__, |
| 526 | 526 | __LINE__ |
@@ -529,9 +529,9 @@ discard block |
||
| 529 | 529 | // set no cache headers and constants |
| 530 | 530 | EE_System::do_not_cache(); |
| 531 | 531 | $extra_params = $this->iframe ? ' target="_blank"' : ''; |
| 532 | - $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>'; |
|
| 532 | + $html = '<form method="POST" action="'.$checkout_url.'"'.$extra_params.'>'; |
|
| 533 | 533 | $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
| 534 | - $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event ); |
|
| 534 | + $html = apply_filters('FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event); |
|
| 535 | 535 | return $html; |
| 536 | 536 | } |
| 537 | 537 | |
@@ -554,7 +554,7 @@ discard block |
||
| 554 | 554 | $html .= empty($external_url) |
| 555 | 555 | ? $this->ticketSelectorEndDiv() |
| 556 | 556 | : $this->clearTicketSelector(); |
| 557 | - $html .= '<br/>' . $this->formClose(); |
|
| 557 | + $html .= '<br/>'.$this->formClose(); |
|
| 558 | 558 | } elseif ($this->getMaxAttendees() === 1) { |
| 559 | 559 | // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
| 560 | 560 | if ($this->event->is_sold_out()) { |
@@ -583,7 +583,7 @@ discard block |
||
| 583 | 583 | $html .= $this->displayRegisterNowButton(); |
| 584 | 584 | } |
| 585 | 585 | // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
| 586 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 586 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 587 | 587 | } elseif ( |
| 588 | 588 | apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
| 589 | 589 | && ! is_single() |
@@ -638,13 +638,13 @@ discard block |
||
| 638 | 638 | ); |
| 639 | 639 | $external_url = $this->event->external_url(); |
| 640 | 640 | $html = EEH_HTML::div( |
| 641 | - '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
| 641 | + '', 'ticket-selector-submit-'.$this->event->ID().'-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
| 642 | 642 | ); |
| 643 | - $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
| 643 | + $html .= '<input id="ticket-selector-submit-'.$this->event->ID().'-btn"'; |
|
| 644 | 644 | $html .= ' class="ticket-selector-submit-btn '; |
| 645 | 645 | $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
| 646 | - $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
| 647 | - $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 646 | + $html .= ' type="submit" value="'.$btn_text.'" />'; |
|
| 647 | + $html .= EEH_HTML::divx().'<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 648 | 648 | $html .= apply_filters( |
| 649 | 649 | 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
| 650 | 650 | '', |
@@ -664,11 +664,11 @@ discard block |
||
| 664 | 664 | * @return string |
| 665 | 665 | * @throws EE_Error |
| 666 | 666 | */ |
| 667 | - public function displayViewDetailsButton( $DWMTS = false ) |
|
| 667 | + public function displayViewDetailsButton($DWMTS = false) |
|
| 668 | 668 | { |
| 669 | - if ( ! $this->event->get_permalink() ) { |
|
| 669 | + if ( ! $this->event->get_permalink()) { |
|
| 670 | 670 | EE_Error::add_error( |
| 671 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
| 671 | + esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
| 672 | 672 | __FILE__, __FUNCTION__, __LINE__ |
| 673 | 673 | ); |
| 674 | 674 | } |
@@ -686,7 +686,7 @@ discard block |
||
| 686 | 686 | ) |
| 687 | 687 | ? ' target="_blank"' |
| 688 | 688 | : ''; |
| 689 | - $view_details_btn .='>'; |
|
| 689 | + $view_details_btn .= '>'; |
|
| 690 | 690 | $btn_text = apply_filters( |
| 691 | 691 | 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
| 692 | 692 | esc_html__('View Details', 'event_espresso'), |
@@ -697,7 +697,7 @@ discard block |
||
| 697 | 697 | . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
| 698 | 698 | . $btn_text |
| 699 | 699 | . '" />'; |
| 700 | - $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event ); |
|
| 700 | + $view_details_btn .= apply_filters('FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event); |
|
| 701 | 701 | if ($DWMTS) { |
| 702 | 702 | $view_details_btn .= $this->formClose(); |
| 703 | 703 | $view_details_btn .= $this->ticketSelectorEndDiv(); |
@@ -717,7 +717,7 @@ discard block |
||
| 717 | 717 | */ |
| 718 | 718 | public function ticketSelectorEndDiv() |
| 719 | 719 | { |
| 720 | - return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
| 720 | + return $this->clearTicketSelector().'</div><!-- ticketSelectorEndDiv -->'; |
|
| 721 | 721 | } |
| 722 | 722 | |
| 723 | 723 | |