@@ -119,7 +119,7 @@ discard block |
||
| 119 | 119 | { |
| 120 | 120 | switch ($field_name) { |
| 121 | 121 | case 'REG_code': |
| 122 | - if (! empty($field_value) && $this->reg_code() === null) { |
|
| 122 | + if ( ! empty($field_value) && $this->reg_code() === null) { |
|
| 123 | 123 | $this->set_reg_code($field_value, $use_default); |
| 124 | 124 | } |
| 125 | 125 | break; |
@@ -400,7 +400,7 @@ discard block |
||
| 400 | 400 | public function event() |
| 401 | 401 | { |
| 402 | 402 | $event = $this->get_first_related('Event'); |
| 403 | - if (! $event instanceof \EE_Event) { |
|
| 403 | + if ( ! $event instanceof \EE_Event) { |
|
| 404 | 404 | throw new EntityNotFoundException('Event ID', $this->event_ID()); |
| 405 | 405 | } |
| 406 | 406 | return $event; |
@@ -443,7 +443,7 @@ discard block |
||
| 443 | 443 | { |
| 444 | 444 | // reserved ticket and datetime counts will be decremented as sold counts are incremented |
| 445 | 445 | // so stop tracking that this reg has a ticket reserved |
| 446 | - $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 446 | + $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:".__LINE__.')'); |
|
| 447 | 447 | $ticket = $this->ticket(); |
| 448 | 448 | $ticket->increaseSold(); |
| 449 | 449 | // possibly set event status to sold out |
@@ -497,7 +497,7 @@ discard block |
||
| 497 | 497 | && $update_ticket |
| 498 | 498 | ) { |
| 499 | 499 | $ticket = $this->ticket(); |
| 500 | - $ticket->increaseReserved(1, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 500 | + $ticket->increaseReserved(1, "REG: {$this->ID()} (ln:".__LINE__.')'); |
|
| 501 | 501 | $ticket->save(); |
| 502 | 502 | } |
| 503 | 503 | } |
@@ -528,7 +528,7 @@ discard block |
||
| 528 | 528 | && $update_ticket |
| 529 | 529 | ) { |
| 530 | 530 | $ticket = $this->ticket(); |
| 531 | - $ticket->decreaseReserved(1, true, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 531 | + $ticket->decreaseReserved(1, true, "REG: {$this->ID()} (ln:".__LINE__.')'); |
|
| 532 | 532 | } |
| 533 | 533 | } |
| 534 | 534 | } |
@@ -1202,7 +1202,7 @@ discard block |
||
| 1202 | 1202 | : ''; |
| 1203 | 1203 | break; |
| 1204 | 1204 | } |
| 1205 | - return $icon . $status[ $this->status_ID() ]; |
|
| 1205 | + return $icon.$status[$this->status_ID()]; |
|
| 1206 | 1206 | } |
| 1207 | 1207 | |
| 1208 | 1208 | |
@@ -1420,7 +1420,7 @@ discard block |
||
| 1420 | 1420 | return false; |
| 1421 | 1421 | } |
| 1422 | 1422 | // is there a datetime ticket that matches this dtt_ID? |
| 1423 | - if (! (EEM_Datetime_Ticket::instance()->exists( |
|
| 1423 | + if ( ! (EEM_Datetime_Ticket::instance()->exists( |
|
| 1424 | 1424 | array( |
| 1425 | 1425 | array( |
| 1426 | 1426 | 'TKT_ID' => $this->get('TKT_ID'), |
@@ -1451,7 +1451,7 @@ discard block |
||
| 1451 | 1451 | { |
| 1452 | 1452 | $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
| 1453 | 1453 | |
| 1454 | - if (! $DTT_ID) { |
|
| 1454 | + if ( ! $DTT_ID) { |
|
| 1455 | 1455 | return false; |
| 1456 | 1456 | } |
| 1457 | 1457 | |
@@ -1459,7 +1459,7 @@ discard block |
||
| 1459 | 1459 | |
| 1460 | 1460 | // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
| 1461 | 1461 | // check-in or not. |
| 1462 | - if (! $max_uses || $max_uses === EE_INF) { |
|
| 1462 | + if ( ! $max_uses || $max_uses === EE_INF) { |
|
| 1463 | 1463 | return true; |
| 1464 | 1464 | } |
| 1465 | 1465 | |
@@ -1519,7 +1519,7 @@ discard block |
||
| 1519 | 1519 | $datetime = $this->get_latest_related_datetime(); |
| 1520 | 1520 | $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
| 1521 | 1521 | // verify the registration can checkin for the given DTT_ID |
| 1522 | - } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1522 | + } elseif ( ! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1523 | 1523 | EE_Error::add_error( |
| 1524 | 1524 | sprintf( |
| 1525 | 1525 | esc_html__( |
@@ -1542,7 +1542,7 @@ discard block |
||
| 1542 | 1542 | ); |
| 1543 | 1543 | // start by getting the current status so we know what status we'll be changing to. |
| 1544 | 1544 | $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
| 1545 | - $status_to = $status_paths[ $cur_status ]; |
|
| 1545 | + $status_to = $status_paths[$cur_status]; |
|
| 1546 | 1546 | // database only records true for checked IN or false for checked OUT |
| 1547 | 1547 | // no record ( null ) means checked in NEVER, but we obviously don't save that |
| 1548 | 1548 | $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
@@ -1707,7 +1707,7 @@ discard block |
||
| 1707 | 1707 | public function transaction() |
| 1708 | 1708 | { |
| 1709 | 1709 | $transaction = $this->get_first_related('Transaction'); |
| 1710 | - if (! $transaction instanceof \EE_Transaction) { |
|
| 1710 | + if ( ! $transaction instanceof \EE_Transaction) { |
|
| 1711 | 1711 | throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
| 1712 | 1712 | } |
| 1713 | 1713 | return $transaction; |
@@ -1761,11 +1761,11 @@ discard block |
||
| 1761 | 1761 | ); |
| 1762 | 1762 | return; |
| 1763 | 1763 | } |
| 1764 | - if (! $this->reg_code()) { |
|
| 1764 | + if ( ! $this->reg_code()) { |
|
| 1765 | 1765 | parent::set('REG_code', $REG_code, $use_default); |
| 1766 | 1766 | } else { |
| 1767 | 1767 | EE_Error::doing_it_wrong( |
| 1768 | - __CLASS__ . '::' . __FUNCTION__, |
|
| 1768 | + __CLASS__.'::'.__FUNCTION__, |
|
| 1769 | 1769 | esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
| 1770 | 1770 | '4.6.0' |
| 1771 | 1771 | ); |
@@ -1916,7 +1916,7 @@ discard block |
||
| 1916 | 1916 | break; |
| 1917 | 1917 | } |
| 1918 | 1918 | } |
| 1919 | - if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1919 | + if ( ! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1920 | 1920 | throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
| 1921 | 1921 | } |
| 1922 | 1922 | return $line_item; |
@@ -17,2111 +17,2111 @@ |
||
| 17 | 17 | { |
| 18 | 18 | |
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * Used to reference when a registration has never been checked in. |
|
| 22 | - * |
|
| 23 | - * @deprecated use \EE_Checkin::status_checked_never instead |
|
| 24 | - * @type int |
|
| 25 | - */ |
|
| 26 | - const checkin_status_never = 2; |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * Used to reference when a registration has been checked in. |
|
| 30 | - * |
|
| 31 | - * @deprecated use \EE_Checkin::status_checked_in instead |
|
| 32 | - * @type int |
|
| 33 | - */ |
|
| 34 | - const checkin_status_in = 1; |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * Used to reference when a registration has been checked out. |
|
| 39 | - * |
|
| 40 | - * @deprecated use \EE_Checkin::status_checked_out instead |
|
| 41 | - * @type int |
|
| 42 | - */ |
|
| 43 | - const checkin_status_out = 0; |
|
| 44 | - |
|
| 45 | - |
|
| 46 | - /** |
|
| 47 | - * extra meta key for tracking reg status os trashed registrations |
|
| 48 | - * |
|
| 49 | - * @type string |
|
| 50 | - */ |
|
| 51 | - const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
| 52 | - |
|
| 53 | - |
|
| 54 | - /** |
|
| 55 | - * extra meta key for tracking if registration has reserved ticket |
|
| 56 | - * |
|
| 57 | - * @type string |
|
| 58 | - */ |
|
| 59 | - const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
| 60 | - |
|
| 61 | - |
|
| 62 | - /** |
|
| 63 | - * @param array $props_n_values incoming values |
|
| 64 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 65 | - * used.) |
|
| 66 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 67 | - * date_format and the second value is the time format |
|
| 68 | - * @return EE_Registration |
|
| 69 | - * @throws EE_Error |
|
| 70 | - */ |
|
| 71 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 72 | - { |
|
| 73 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 74 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 75 | - } |
|
| 76 | - |
|
| 77 | - |
|
| 78 | - /** |
|
| 79 | - * @param array $props_n_values incoming values from the database |
|
| 80 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 81 | - * the website will be used. |
|
| 82 | - * @return EE_Registration |
|
| 83 | - */ |
|
| 84 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 85 | - { |
|
| 86 | - return new self($props_n_values, true, $timezone); |
|
| 87 | - } |
|
| 88 | - |
|
| 89 | - |
|
| 90 | - /** |
|
| 91 | - * Set Event ID |
|
| 92 | - * |
|
| 93 | - * @param int $EVT_ID Event ID |
|
| 94 | - * @throws EE_Error |
|
| 95 | - * @throws RuntimeException |
|
| 96 | - */ |
|
| 97 | - public function set_event($EVT_ID = 0) |
|
| 98 | - { |
|
| 99 | - $this->set('EVT_ID', $EVT_ID); |
|
| 100 | - } |
|
| 101 | - |
|
| 102 | - |
|
| 103 | - /** |
|
| 104 | - * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
| 105 | - * be routed to internal methods |
|
| 106 | - * |
|
| 107 | - * @param string $field_name |
|
| 108 | - * @param mixed $field_value |
|
| 109 | - * @param bool $use_default |
|
| 110 | - * @throws EE_Error |
|
| 111 | - * @throws EntityNotFoundException |
|
| 112 | - * @throws InvalidArgumentException |
|
| 113 | - * @throws InvalidDataTypeException |
|
| 114 | - * @throws InvalidInterfaceException |
|
| 115 | - * @throws ReflectionException |
|
| 116 | - * @throws RuntimeException |
|
| 117 | - */ |
|
| 118 | - public function set($field_name, $field_value, $use_default = false) |
|
| 119 | - { |
|
| 120 | - switch ($field_name) { |
|
| 121 | - case 'REG_code': |
|
| 122 | - if (! empty($field_value) && $this->reg_code() === null) { |
|
| 123 | - $this->set_reg_code($field_value, $use_default); |
|
| 124 | - } |
|
| 125 | - break; |
|
| 126 | - case 'STS_ID': |
|
| 127 | - $this->set_status($field_value, $use_default); |
|
| 128 | - break; |
|
| 129 | - default: |
|
| 130 | - parent::set($field_name, $field_value, $use_default); |
|
| 131 | - } |
|
| 132 | - } |
|
| 133 | - |
|
| 134 | - |
|
| 135 | - /** |
|
| 136 | - * Set Status ID |
|
| 137 | - * updates the registration status and ALSO... |
|
| 138 | - * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
| 139 | - * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
| 140 | - * |
|
| 141 | - * @param string $new_STS_ID |
|
| 142 | - * @param boolean $use_default |
|
| 143 | - * @param ContextInterface|null $context |
|
| 144 | - * @return bool |
|
| 145 | - * @throws DomainException |
|
| 146 | - * @throws EE_Error |
|
| 147 | - * @throws EntityNotFoundException |
|
| 148 | - * @throws InvalidArgumentException |
|
| 149 | - * @throws InvalidDataTypeException |
|
| 150 | - * @throws InvalidInterfaceException |
|
| 151 | - * @throws ReflectionException |
|
| 152 | - * @throws RuntimeException |
|
| 153 | - * @throws UnexpectedEntityException |
|
| 154 | - */ |
|
| 155 | - public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null) |
|
| 156 | - { |
|
| 157 | - // get current REG_Status |
|
| 158 | - $old_STS_ID = $this->status_ID(); |
|
| 159 | - // if status has changed |
|
| 160 | - if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
| 161 | - && ! empty($old_STS_ID) // and that old status is actually set |
|
| 162 | - && ! empty($new_STS_ID) // as well as the new status |
|
| 163 | - && $this->ID() // ensure registration is in the db |
|
| 164 | - ) { |
|
| 165 | - // update internal status first |
|
| 166 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 167 | - // THEN handle other changes that occur when reg status changes |
|
| 168 | - // TO approved |
|
| 169 | - if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
| 170 | - // reserve a space by incrementing ticket and datetime sold values |
|
| 171 | - $this->reserveRegistrationSpace(); |
|
| 172 | - do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 173 | - // OR FROM approved |
|
| 174 | - } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
| 175 | - // release a space by decrementing ticket and datetime sold values |
|
| 176 | - $this->releaseRegistrationSpace(); |
|
| 177 | - do_action( |
|
| 178 | - 'AHEE__EE_Registration__set_status__from_approved', |
|
| 179 | - $this, |
|
| 180 | - $old_STS_ID, |
|
| 181 | - $new_STS_ID, |
|
| 182 | - $context |
|
| 183 | - ); |
|
| 184 | - } |
|
| 185 | - // update status |
|
| 186 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 187 | - $this->updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, $context); |
|
| 188 | - if ($this->statusChangeUpdatesTransaction($context)) { |
|
| 189 | - $this->updateTransactionAfterStatusChange(); |
|
| 190 | - } |
|
| 191 | - do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 192 | - return true; |
|
| 193 | - } |
|
| 194 | - // even though the old value matches the new value, it's still good to |
|
| 195 | - // allow the parent set method to have a say |
|
| 196 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 197 | - return true; |
|
| 198 | - } |
|
| 199 | - |
|
| 200 | - |
|
| 201 | - /** |
|
| 202 | - * update REGs and TXN when cancelled or declined registrations involved |
|
| 203 | - * |
|
| 204 | - * @param string $new_STS_ID |
|
| 205 | - * @param string $old_STS_ID |
|
| 206 | - * @param ContextInterface|null $context |
|
| 207 | - * @throws EE_Error |
|
| 208 | - * @throws InvalidArgumentException |
|
| 209 | - * @throws InvalidDataTypeException |
|
| 210 | - * @throws InvalidInterfaceException |
|
| 211 | - * @throws ReflectionException |
|
| 212 | - * @throws RuntimeException |
|
| 213 | - */ |
|
| 214 | - private function updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, ContextInterface $context = null) |
|
| 215 | - { |
|
| 216 | - // these reg statuses should not be considered in any calculations involving monies owing |
|
| 217 | - $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
| 218 | - // true if registration has been cancelled or declined |
|
| 219 | - $this->updateIfCanceled( |
|
| 220 | - $closed_reg_statuses, |
|
| 221 | - $new_STS_ID, |
|
| 222 | - $old_STS_ID, |
|
| 223 | - $context |
|
| 224 | - ); |
|
| 225 | - $this->updateIfReinstated( |
|
| 226 | - $closed_reg_statuses, |
|
| 227 | - $new_STS_ID, |
|
| 228 | - $old_STS_ID, |
|
| 229 | - $context |
|
| 230 | - ); |
|
| 231 | - } |
|
| 232 | - |
|
| 233 | - |
|
| 234 | - /** |
|
| 235 | - * update REGs and TXN when cancelled or declined registrations involved |
|
| 236 | - * |
|
| 237 | - * @param array $closed_reg_statuses |
|
| 238 | - * @param string $new_STS_ID |
|
| 239 | - * @param string $old_STS_ID |
|
| 240 | - * @param ContextInterface|null $context |
|
| 241 | - * @throws EE_Error |
|
| 242 | - * @throws InvalidArgumentException |
|
| 243 | - * @throws InvalidDataTypeException |
|
| 244 | - * @throws InvalidInterfaceException |
|
| 245 | - * @throws ReflectionException |
|
| 246 | - * @throws RuntimeException |
|
| 247 | - */ |
|
| 248 | - private function updateIfCanceled( |
|
| 249 | - array $closed_reg_statuses, |
|
| 250 | - $new_STS_ID, |
|
| 251 | - $old_STS_ID, |
|
| 252 | - ContextInterface $context = null |
|
| 253 | - ) { |
|
| 254 | - // true if registration has been cancelled or declined |
|
| 255 | - if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 256 | - && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 257 | - ) { |
|
| 258 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 259 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 260 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 261 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 262 | - // cancelled or declined registration |
|
| 263 | - $registration_processor->update_registration_after_being_canceled_or_declined( |
|
| 264 | - $this, |
|
| 265 | - $closed_reg_statuses |
|
| 266 | - ); |
|
| 267 | - $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
| 268 | - $this, |
|
| 269 | - $closed_reg_statuses, |
|
| 270 | - false |
|
| 271 | - ); |
|
| 272 | - do_action( |
|
| 273 | - 'AHEE__EE_Registration__set_status__canceled_or_declined', |
|
| 274 | - $this, |
|
| 275 | - $old_STS_ID, |
|
| 276 | - $new_STS_ID, |
|
| 277 | - $context |
|
| 278 | - ); |
|
| 279 | - return; |
|
| 280 | - } |
|
| 281 | - } |
|
| 282 | - |
|
| 283 | - |
|
| 284 | - /** |
|
| 285 | - * update REGs and TXN when cancelled or declined registrations involved |
|
| 286 | - * |
|
| 287 | - * @param array $closed_reg_statuses |
|
| 288 | - * @param string $new_STS_ID |
|
| 289 | - * @param string $old_STS_ID |
|
| 290 | - * @param ContextInterface|null $context |
|
| 291 | - * @throws EE_Error |
|
| 292 | - * @throws InvalidArgumentException |
|
| 293 | - * @throws InvalidDataTypeException |
|
| 294 | - * @throws InvalidInterfaceException |
|
| 295 | - * @throws ReflectionException |
|
| 296 | - */ |
|
| 297 | - private function updateIfReinstated( |
|
| 298 | - array $closed_reg_statuses, |
|
| 299 | - $new_STS_ID, |
|
| 300 | - $old_STS_ID, |
|
| 301 | - ContextInterface $context = null |
|
| 302 | - ) { |
|
| 303 | - // true if reinstating cancelled or declined registration |
|
| 304 | - if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 305 | - && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 306 | - ) { |
|
| 307 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 308 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 309 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 310 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 311 | - // reinstating cancelled or declined registration |
|
| 312 | - $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
| 313 | - $this, |
|
| 314 | - $closed_reg_statuses |
|
| 315 | - ); |
|
| 316 | - $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
| 317 | - $this, |
|
| 318 | - $closed_reg_statuses, |
|
| 319 | - false |
|
| 320 | - ); |
|
| 321 | - do_action( |
|
| 322 | - 'AHEE__EE_Registration__set_status__after_reinstated', |
|
| 323 | - $this, |
|
| 324 | - $old_STS_ID, |
|
| 325 | - $new_STS_ID, |
|
| 326 | - $context |
|
| 327 | - ); |
|
| 328 | - } |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - |
|
| 332 | - /** |
|
| 333 | - * @param ContextInterface|null $context |
|
| 334 | - * @return bool |
|
| 335 | - */ |
|
| 336 | - private function statusChangeUpdatesTransaction(ContextInterface $context = null) |
|
| 337 | - { |
|
| 338 | - $contexts_that_do_not_update_transaction = (array) apply_filters( |
|
| 339 | - 'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction', |
|
| 340 | - array('spco_reg_step_attendee_information_process_registrations'), |
|
| 341 | - $context, |
|
| 342 | - $this |
|
| 343 | - ); |
|
| 344 | - return ! ( |
|
| 345 | - $context instanceof ContextInterface |
|
| 346 | - && in_array($context->slug(), $contexts_that_do_not_update_transaction, true) |
|
| 347 | - ); |
|
| 348 | - } |
|
| 349 | - |
|
| 350 | - |
|
| 351 | - /** |
|
| 352 | - * @throws EE_Error |
|
| 353 | - * @throws EntityNotFoundException |
|
| 354 | - * @throws InvalidArgumentException |
|
| 355 | - * @throws InvalidDataTypeException |
|
| 356 | - * @throws InvalidInterfaceException |
|
| 357 | - * @throws ReflectionException |
|
| 358 | - * @throws RuntimeException |
|
| 359 | - */ |
|
| 360 | - private function updateTransactionAfterStatusChange() |
|
| 361 | - { |
|
| 362 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
| 363 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
| 364 | - $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
| 365 | - $this->transaction()->update_status_based_on_total_paid(true); |
|
| 366 | - } |
|
| 367 | - |
|
| 368 | - |
|
| 369 | - /** |
|
| 370 | - * get Status ID |
|
| 371 | - */ |
|
| 372 | - public function status_ID() |
|
| 373 | - { |
|
| 374 | - return $this->get('STS_ID'); |
|
| 375 | - } |
|
| 376 | - |
|
| 377 | - |
|
| 378 | - /** |
|
| 379 | - * Gets the ticket this registration is for |
|
| 380 | - * |
|
| 381 | - * @param boolean $include_archived whether to include archived tickets or not. |
|
| 382 | - * |
|
| 383 | - * @return EE_Ticket|EE_Base_Class |
|
| 384 | - * @throws EE_Error |
|
| 385 | - */ |
|
| 386 | - public function ticket($include_archived = true) |
|
| 387 | - { |
|
| 388 | - $query_params = array(); |
|
| 389 | - if ($include_archived) { |
|
| 390 | - $query_params['default_where_conditions'] = 'none'; |
|
| 391 | - } |
|
| 392 | - return $this->get_first_related('Ticket', $query_params); |
|
| 393 | - } |
|
| 394 | - |
|
| 395 | - |
|
| 396 | - /** |
|
| 397 | - * Gets the event this registration is for |
|
| 398 | - * |
|
| 399 | - * @return EE_Event |
|
| 400 | - * @throws EE_Error |
|
| 401 | - * @throws EntityNotFoundException |
|
| 402 | - */ |
|
| 403 | - public function event() |
|
| 404 | - { |
|
| 405 | - $event = $this->get_first_related('Event'); |
|
| 406 | - if (! $event instanceof \EE_Event) { |
|
| 407 | - throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
| 408 | - } |
|
| 409 | - return $event; |
|
| 410 | - } |
|
| 411 | - |
|
| 412 | - |
|
| 413 | - /** |
|
| 414 | - * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
| 415 | - * with the author of the event this registration is for. |
|
| 416 | - * |
|
| 417 | - * @since 4.5.0 |
|
| 418 | - * @return int |
|
| 419 | - * @throws EE_Error |
|
| 420 | - * @throws EntityNotFoundException |
|
| 421 | - */ |
|
| 422 | - public function wp_user() |
|
| 423 | - { |
|
| 424 | - $event = $this->event(); |
|
| 425 | - if ($event instanceof EE_Event) { |
|
| 426 | - return $event->wp_user(); |
|
| 427 | - } |
|
| 428 | - return 0; |
|
| 429 | - } |
|
| 430 | - |
|
| 431 | - |
|
| 432 | - /** |
|
| 433 | - * increments this registration's related ticket sold and corresponding datetime sold values |
|
| 434 | - * |
|
| 435 | - * @return void |
|
| 436 | - * @throws DomainException |
|
| 437 | - * @throws EE_Error |
|
| 438 | - * @throws EntityNotFoundException |
|
| 439 | - * @throws InvalidArgumentException |
|
| 440 | - * @throws InvalidDataTypeException |
|
| 441 | - * @throws InvalidInterfaceException |
|
| 442 | - * @throws ReflectionException |
|
| 443 | - * @throws UnexpectedEntityException |
|
| 444 | - */ |
|
| 445 | - private function reserveRegistrationSpace() |
|
| 446 | - { |
|
| 447 | - // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
| 448 | - // so stop tracking that this reg has a ticket reserved |
|
| 449 | - $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 450 | - $ticket = $this->ticket(); |
|
| 451 | - $ticket->increaseSold(); |
|
| 452 | - // possibly set event status to sold out |
|
| 453 | - $this->event()->perform_sold_out_status_check(); |
|
| 454 | - } |
|
| 455 | - |
|
| 456 | - |
|
| 457 | - /** |
|
| 458 | - * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
| 459 | - * |
|
| 460 | - * @return void |
|
| 461 | - * @throws DomainException |
|
| 462 | - * @throws EE_Error |
|
| 463 | - * @throws EntityNotFoundException |
|
| 464 | - * @throws InvalidArgumentException |
|
| 465 | - * @throws InvalidDataTypeException |
|
| 466 | - * @throws InvalidInterfaceException |
|
| 467 | - * @throws ReflectionException |
|
| 468 | - * @throws UnexpectedEntityException |
|
| 469 | - */ |
|
| 470 | - private function releaseRegistrationSpace() |
|
| 471 | - { |
|
| 472 | - $ticket = $this->ticket(); |
|
| 473 | - $ticket->decreaseSold(); |
|
| 474 | - // possibly change event status from sold out back to previous status |
|
| 475 | - $this->event()->perform_sold_out_status_check(); |
|
| 476 | - } |
|
| 477 | - |
|
| 478 | - |
|
| 479 | - /** |
|
| 480 | - * tracks this registration's ticket reservation in extra meta |
|
| 481 | - * and can increment related ticket reserved and corresponding datetime reserved values |
|
| 482 | - * |
|
| 483 | - * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
| 484 | - * @return void |
|
| 485 | - * @throws EE_Error |
|
| 486 | - * @throws InvalidArgumentException |
|
| 487 | - * @throws InvalidDataTypeException |
|
| 488 | - * @throws InvalidInterfaceException |
|
| 489 | - * @throws ReflectionException |
|
| 490 | - */ |
|
| 491 | - public function reserve_ticket($update_ticket = false, $source = 'unknown') |
|
| 492 | - { |
|
| 493 | - // only reserve ticket if space is not currently reserved |
|
| 494 | - if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) !== true) { |
|
| 495 | - $this->update_extra_meta('reserve_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 496 | - // IMPORTANT !!! |
|
| 497 | - // although checking $update_ticket first would be more efficient, |
|
| 498 | - // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 499 | - if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) |
|
| 500 | - && $update_ticket |
|
| 501 | - ) { |
|
| 502 | - $ticket = $this->ticket(); |
|
| 503 | - $ticket->increaseReserved(1, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 504 | - $ticket->save(); |
|
| 505 | - } |
|
| 506 | - } |
|
| 507 | - } |
|
| 508 | - |
|
| 509 | - |
|
| 510 | - /** |
|
| 511 | - * stops tracking this registration's ticket reservation in extra meta |
|
| 512 | - * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
| 513 | - * |
|
| 514 | - * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
| 515 | - * @return void |
|
| 516 | - * @throws EE_Error |
|
| 517 | - * @throws InvalidArgumentException |
|
| 518 | - * @throws InvalidDataTypeException |
|
| 519 | - * @throws InvalidInterfaceException |
|
| 520 | - * @throws ReflectionException |
|
| 521 | - */ |
|
| 522 | - public function release_reserved_ticket($update_ticket = false, $source = 'unknown') |
|
| 523 | - { |
|
| 524 | - // only release ticket if space is currently reserved |
|
| 525 | - if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) === true) { |
|
| 526 | - $this->update_extra_meta('release_reserved_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 527 | - // IMPORTANT !!! |
|
| 528 | - // although checking $update_ticket first would be more efficient, |
|
| 529 | - // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 530 | - if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, false) |
|
| 531 | - && $update_ticket |
|
| 532 | - ) { |
|
| 533 | - $ticket = $this->ticket(); |
|
| 534 | - $ticket->decreaseReserved(1, true, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 535 | - } |
|
| 536 | - } |
|
| 537 | - } |
|
| 538 | - |
|
| 539 | - |
|
| 540 | - /** |
|
| 541 | - * Set Attendee ID |
|
| 542 | - * |
|
| 543 | - * @param int $ATT_ID Attendee ID |
|
| 544 | - * @throws EE_Error |
|
| 545 | - * @throws RuntimeException |
|
| 546 | - */ |
|
| 547 | - public function set_attendee_id($ATT_ID = 0) |
|
| 548 | - { |
|
| 549 | - $this->set('ATT_ID', $ATT_ID); |
|
| 550 | - } |
|
| 551 | - |
|
| 552 | - |
|
| 553 | - /** |
|
| 554 | - * Set Transaction ID |
|
| 555 | - * |
|
| 556 | - * @param int $TXN_ID Transaction ID |
|
| 557 | - * @throws EE_Error |
|
| 558 | - * @throws RuntimeException |
|
| 559 | - */ |
|
| 560 | - public function set_transaction_id($TXN_ID = 0) |
|
| 561 | - { |
|
| 562 | - $this->set('TXN_ID', $TXN_ID); |
|
| 563 | - } |
|
| 564 | - |
|
| 565 | - |
|
| 566 | - /** |
|
| 567 | - * Set Session |
|
| 568 | - * |
|
| 569 | - * @param string $REG_session PHP Session ID |
|
| 570 | - * @throws EE_Error |
|
| 571 | - * @throws RuntimeException |
|
| 572 | - */ |
|
| 573 | - public function set_session($REG_session = '') |
|
| 574 | - { |
|
| 575 | - $this->set('REG_session', $REG_session); |
|
| 576 | - } |
|
| 577 | - |
|
| 578 | - |
|
| 579 | - /** |
|
| 580 | - * Set Registration URL Link |
|
| 581 | - * |
|
| 582 | - * @param string $REG_url_link Registration URL Link |
|
| 583 | - * @throws EE_Error |
|
| 584 | - * @throws RuntimeException |
|
| 585 | - */ |
|
| 586 | - public function set_reg_url_link($REG_url_link = '') |
|
| 587 | - { |
|
| 588 | - $this->set('REG_url_link', $REG_url_link); |
|
| 589 | - } |
|
| 590 | - |
|
| 591 | - |
|
| 592 | - /** |
|
| 593 | - * Set Attendee Counter |
|
| 594 | - * |
|
| 595 | - * @param int $REG_count Primary Attendee |
|
| 596 | - * @throws EE_Error |
|
| 597 | - * @throws RuntimeException |
|
| 598 | - */ |
|
| 599 | - public function set_count($REG_count = 1) |
|
| 600 | - { |
|
| 601 | - $this->set('REG_count', $REG_count); |
|
| 602 | - } |
|
| 603 | - |
|
| 604 | - |
|
| 605 | - /** |
|
| 606 | - * Set Group Size |
|
| 607 | - * |
|
| 608 | - * @param boolean $REG_group_size Group Registration |
|
| 609 | - * @throws EE_Error |
|
| 610 | - * @throws RuntimeException |
|
| 611 | - */ |
|
| 612 | - public function set_group_size($REG_group_size = false) |
|
| 613 | - { |
|
| 614 | - $this->set('REG_group_size', $REG_group_size); |
|
| 615 | - } |
|
| 616 | - |
|
| 617 | - |
|
| 618 | - /** |
|
| 619 | - * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
| 620 | - * EEM_Registration::status_id_not_approved |
|
| 621 | - * |
|
| 622 | - * @return boolean |
|
| 623 | - */ |
|
| 624 | - public function is_not_approved() |
|
| 625 | - { |
|
| 626 | - return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
| 627 | - } |
|
| 628 | - |
|
| 629 | - |
|
| 630 | - /** |
|
| 631 | - * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
| 632 | - * EEM_Registration::status_id_pending_payment |
|
| 633 | - * |
|
| 634 | - * @return boolean |
|
| 635 | - */ |
|
| 636 | - public function is_pending_payment() |
|
| 637 | - { |
|
| 638 | - return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
| 639 | - } |
|
| 640 | - |
|
| 641 | - |
|
| 642 | - /** |
|
| 643 | - * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
| 644 | - * |
|
| 645 | - * @return boolean |
|
| 646 | - */ |
|
| 647 | - public function is_approved() |
|
| 648 | - { |
|
| 649 | - return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
| 650 | - } |
|
| 651 | - |
|
| 652 | - |
|
| 653 | - /** |
|
| 654 | - * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
| 655 | - * |
|
| 656 | - * @return boolean |
|
| 657 | - */ |
|
| 658 | - public function is_cancelled() |
|
| 659 | - { |
|
| 660 | - return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
| 661 | - } |
|
| 662 | - |
|
| 663 | - |
|
| 664 | - /** |
|
| 665 | - * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
| 666 | - * |
|
| 667 | - * @return boolean |
|
| 668 | - */ |
|
| 669 | - public function is_declined() |
|
| 670 | - { |
|
| 671 | - return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
| 672 | - } |
|
| 673 | - |
|
| 674 | - |
|
| 675 | - /** |
|
| 676 | - * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
| 677 | - * EEM_Registration::status_id_incomplete |
|
| 678 | - * |
|
| 679 | - * @return boolean |
|
| 680 | - */ |
|
| 681 | - public function is_incomplete() |
|
| 682 | - { |
|
| 683 | - return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
| 684 | - } |
|
| 685 | - |
|
| 686 | - |
|
| 687 | - /** |
|
| 688 | - * Set Registration Date |
|
| 689 | - * |
|
| 690 | - * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
| 691 | - * Date |
|
| 692 | - * @throws EE_Error |
|
| 693 | - * @throws RuntimeException |
|
| 694 | - */ |
|
| 695 | - public function set_reg_date($REG_date = false) |
|
| 696 | - { |
|
| 697 | - $this->set('REG_date', $REG_date); |
|
| 698 | - } |
|
| 699 | - |
|
| 700 | - |
|
| 701 | - /** |
|
| 702 | - * Set final price owing for this registration after all ticket/price modifications |
|
| 703 | - * |
|
| 704 | - * @access public |
|
| 705 | - * @param float $REG_final_price |
|
| 706 | - * @throws EE_Error |
|
| 707 | - * @throws RuntimeException |
|
| 708 | - */ |
|
| 709 | - public function set_final_price($REG_final_price = 0.00) |
|
| 710 | - { |
|
| 711 | - $this->set('REG_final_price', $REG_final_price); |
|
| 712 | - } |
|
| 713 | - |
|
| 714 | - |
|
| 715 | - /** |
|
| 716 | - * Set amount paid towards this registration's final price |
|
| 717 | - * |
|
| 718 | - * @access public |
|
| 719 | - * @param float $REG_paid |
|
| 720 | - * @throws EE_Error |
|
| 721 | - * @throws RuntimeException |
|
| 722 | - */ |
|
| 723 | - public function set_paid($REG_paid = 0.00) |
|
| 724 | - { |
|
| 725 | - $this->set('REG_paid', $REG_paid); |
|
| 726 | - } |
|
| 727 | - |
|
| 728 | - |
|
| 729 | - /** |
|
| 730 | - * Attendee Is Going |
|
| 731 | - * |
|
| 732 | - * @param boolean $REG_att_is_going Attendee Is Going |
|
| 733 | - * @throws EE_Error |
|
| 734 | - * @throws RuntimeException |
|
| 735 | - */ |
|
| 736 | - public function set_att_is_going($REG_att_is_going = false) |
|
| 737 | - { |
|
| 738 | - $this->set('REG_att_is_going', $REG_att_is_going); |
|
| 739 | - } |
|
| 740 | - |
|
| 741 | - |
|
| 742 | - /** |
|
| 743 | - * Gets the related attendee |
|
| 744 | - * |
|
| 745 | - * @return EE_Attendee |
|
| 746 | - * @throws EE_Error |
|
| 747 | - */ |
|
| 748 | - public function attendee() |
|
| 749 | - { |
|
| 750 | - return $this->get_first_related('Attendee'); |
|
| 751 | - } |
|
| 752 | - |
|
| 753 | - /** |
|
| 754 | - * Gets the name of the attendee. |
|
| 755 | - * @since $VID:$ |
|
| 756 | - * @param bool $apply_html_entities set to true if you want to use HTML entities. |
|
| 757 | - * @return string |
|
| 758 | - * @throws EE_Error |
|
| 759 | - * @throws InvalidArgumentException |
|
| 760 | - * @throws InvalidDataTypeException |
|
| 761 | - * @throws InvalidInterfaceException |
|
| 762 | - * @throws ReflectionException |
|
| 763 | - */ |
|
| 764 | - public function attendeeName($apply_html_entities = false) |
|
| 765 | - { |
|
| 766 | - $attendee = $this->get_first_related('Attendee'); |
|
| 767 | - if ($attendee instanceof EE_Attendee) { |
|
| 768 | - $attendee_name = $attendee->full_name($apply_html_entities); |
|
| 769 | - } else { |
|
| 770 | - $attendee_name = esc_html__('Unknown', 'event_espresso'); |
|
| 771 | - } |
|
| 772 | - return $attendee_name; |
|
| 773 | - } |
|
| 774 | - |
|
| 775 | - |
|
| 776 | - /** |
|
| 777 | - * get Event ID |
|
| 778 | - */ |
|
| 779 | - public function event_ID() |
|
| 780 | - { |
|
| 781 | - return $this->get('EVT_ID'); |
|
| 782 | - } |
|
| 783 | - |
|
| 784 | - |
|
| 785 | - /** |
|
| 786 | - * get Event ID |
|
| 787 | - */ |
|
| 788 | - public function event_name() |
|
| 789 | - { |
|
| 790 | - $event = $this->event_obj(); |
|
| 791 | - if ($event) { |
|
| 792 | - return $event->name(); |
|
| 793 | - } else { |
|
| 794 | - return null; |
|
| 795 | - } |
|
| 796 | - } |
|
| 797 | - |
|
| 798 | - |
|
| 799 | - /** |
|
| 800 | - * Fetches the event this registration is for |
|
| 801 | - * |
|
| 802 | - * @return EE_Event |
|
| 803 | - * @throws EE_Error |
|
| 804 | - */ |
|
| 805 | - public function event_obj() |
|
| 806 | - { |
|
| 807 | - return $this->get_first_related('Event'); |
|
| 808 | - } |
|
| 809 | - |
|
| 810 | - |
|
| 811 | - /** |
|
| 812 | - * get Attendee ID |
|
| 813 | - */ |
|
| 814 | - public function attendee_ID() |
|
| 815 | - { |
|
| 816 | - return $this->get('ATT_ID'); |
|
| 817 | - } |
|
| 818 | - |
|
| 819 | - |
|
| 820 | - /** |
|
| 821 | - * get PHP Session ID |
|
| 822 | - */ |
|
| 823 | - public function session_ID() |
|
| 824 | - { |
|
| 825 | - return $this->get('REG_session'); |
|
| 826 | - } |
|
| 827 | - |
|
| 828 | - |
|
| 829 | - /** |
|
| 830 | - * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
| 831 | - * |
|
| 832 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 833 | - * @return string |
|
| 834 | - */ |
|
| 835 | - public function receipt_url($messenger = 'html') |
|
| 836 | - { |
|
| 837 | - |
|
| 838 | - /** |
|
| 839 | - * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
| 840 | - * already in use on old system. If there is then we just return the standard url for it. |
|
| 841 | - * |
|
| 842 | - * @since 4.5.0 |
|
| 843 | - */ |
|
| 844 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
| 845 | - $has_custom = EEH_Template::locate_template( |
|
| 846 | - $template_relative_path, |
|
| 847 | - array(), |
|
| 848 | - true, |
|
| 849 | - true, |
|
| 850 | - true |
|
| 851 | - ); |
|
| 852 | - |
|
| 853 | - if ($has_custom) { |
|
| 854 | - return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
| 855 | - } |
|
| 856 | - return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
| 857 | - } |
|
| 858 | - |
|
| 859 | - |
|
| 860 | - /** |
|
| 861 | - * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
| 862 | - * |
|
| 863 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 864 | - * @return string |
|
| 865 | - * @throws EE_Error |
|
| 866 | - */ |
|
| 867 | - public function invoice_url($messenger = 'html') |
|
| 868 | - { |
|
| 869 | - /** |
|
| 870 | - * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
| 871 | - * already in use on old system. If there is then we just return the standard url for it. |
|
| 872 | - * |
|
| 873 | - * @since 4.5.0 |
|
| 874 | - */ |
|
| 875 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
| 876 | - $has_custom = EEH_Template::locate_template( |
|
| 877 | - $template_relative_path, |
|
| 878 | - array(), |
|
| 879 | - true, |
|
| 880 | - true, |
|
| 881 | - true |
|
| 882 | - ); |
|
| 883 | - |
|
| 884 | - if ($has_custom) { |
|
| 885 | - if ($messenger == 'html') { |
|
| 886 | - return $this->invoice_url('launch'); |
|
| 887 | - } |
|
| 888 | - $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
| 889 | - |
|
| 890 | - $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
| 891 | - if ($messenger == 'html') { |
|
| 892 | - $query_args['html'] = true; |
|
| 893 | - } |
|
| 894 | - return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
| 895 | - } |
|
| 896 | - return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
| 897 | - } |
|
| 898 | - |
|
| 899 | - |
|
| 900 | - /** |
|
| 901 | - * get Registration URL Link |
|
| 902 | - * |
|
| 903 | - * @access public |
|
| 904 | - * @return string |
|
| 905 | - * @throws EE_Error |
|
| 906 | - */ |
|
| 907 | - public function reg_url_link() |
|
| 908 | - { |
|
| 909 | - return (string) $this->get('REG_url_link'); |
|
| 910 | - } |
|
| 911 | - |
|
| 912 | - |
|
| 913 | - /** |
|
| 914 | - * Echoes out invoice_url() |
|
| 915 | - * |
|
| 916 | - * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
| 917 | - * @return void |
|
| 918 | - * @throws EE_Error |
|
| 919 | - */ |
|
| 920 | - public function e_invoice_url($type = 'launch') |
|
| 921 | - { |
|
| 922 | - echo $this->invoice_url($type); |
|
| 923 | - } |
|
| 924 | - |
|
| 925 | - |
|
| 926 | - /** |
|
| 927 | - * Echoes out payment_overview_url |
|
| 928 | - */ |
|
| 929 | - public function e_payment_overview_url() |
|
| 930 | - { |
|
| 931 | - echo $this->payment_overview_url(); |
|
| 932 | - } |
|
| 933 | - |
|
| 934 | - |
|
| 935 | - /** |
|
| 936 | - * Gets the URL for the checkout payment options reg step |
|
| 937 | - * with this registration's REG_url_link added as a query parameter |
|
| 938 | - * |
|
| 939 | - * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
| 940 | - * payment overview url. |
|
| 941 | - * @return string |
|
| 942 | - * @throws InvalidInterfaceException |
|
| 943 | - * @throws InvalidDataTypeException |
|
| 944 | - * @throws EE_Error |
|
| 945 | - * @throws InvalidArgumentException |
|
| 946 | - */ |
|
| 947 | - public function payment_overview_url($clear_session = false) |
|
| 948 | - { |
|
| 949 | - return add_query_arg( |
|
| 950 | - (array) apply_filters( |
|
| 951 | - 'FHEE__EE_Registration__payment_overview_url__query_args', |
|
| 952 | - array( |
|
| 953 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
| 954 | - 'step' => 'payment_options', |
|
| 955 | - 'revisit' => true, |
|
| 956 | - 'clear_session' => (bool) $clear_session, |
|
| 957 | - ), |
|
| 958 | - $this |
|
| 959 | - ), |
|
| 960 | - EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 961 | - ); |
|
| 962 | - } |
|
| 963 | - |
|
| 964 | - |
|
| 965 | - /** |
|
| 966 | - * Gets the URL for the checkout attendee information reg step |
|
| 967 | - * with this registration's REG_url_link added as a query parameter |
|
| 968 | - * |
|
| 969 | - * @return string |
|
| 970 | - * @throws InvalidInterfaceException |
|
| 971 | - * @throws InvalidDataTypeException |
|
| 972 | - * @throws EE_Error |
|
| 973 | - * @throws InvalidArgumentException |
|
| 974 | - */ |
|
| 975 | - public function edit_attendee_information_url() |
|
| 976 | - { |
|
| 977 | - return add_query_arg( |
|
| 978 | - (array) apply_filters( |
|
| 979 | - 'FHEE__EE_Registration__edit_attendee_information_url__query_args', |
|
| 980 | - array( |
|
| 981 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
| 982 | - 'step' => 'attendee_information', |
|
| 983 | - 'revisit' => true, |
|
| 984 | - ), |
|
| 985 | - $this |
|
| 986 | - ), |
|
| 987 | - EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 988 | - ); |
|
| 989 | - } |
|
| 990 | - |
|
| 991 | - |
|
| 992 | - /** |
|
| 993 | - * Simply generates and returns the appropriate admin_url link to edit this registration |
|
| 994 | - * |
|
| 995 | - * @return string |
|
| 996 | - * @throws EE_Error |
|
| 997 | - */ |
|
| 998 | - public function get_admin_edit_url() |
|
| 999 | - { |
|
| 1000 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1001 | - array( |
|
| 1002 | - 'page' => 'espresso_registrations', |
|
| 1003 | - 'action' => 'view_registration', |
|
| 1004 | - '_REG_ID' => $this->ID(), |
|
| 1005 | - ), |
|
| 1006 | - admin_url('admin.php') |
|
| 1007 | - ); |
|
| 1008 | - } |
|
| 1009 | - |
|
| 1010 | - |
|
| 1011 | - /** |
|
| 1012 | - * is_primary_registrant? |
|
| 1013 | - */ |
|
| 1014 | - public function is_primary_registrant() |
|
| 1015 | - { |
|
| 1016 | - return $this->get('REG_count') === 1 ? true : false; |
|
| 1017 | - } |
|
| 1018 | - |
|
| 1019 | - |
|
| 1020 | - /** |
|
| 1021 | - * This returns the primary registration object for this registration group (which may be this object). |
|
| 1022 | - * |
|
| 1023 | - * @return EE_Registration |
|
| 1024 | - * @throws EE_Error |
|
| 1025 | - */ |
|
| 1026 | - public function get_primary_registration() |
|
| 1027 | - { |
|
| 1028 | - if ($this->is_primary_registrant()) { |
|
| 1029 | - return $this; |
|
| 1030 | - } |
|
| 1031 | - |
|
| 1032 | - // k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
| 1033 | - /** @var EE_Registration $primary_registrant */ |
|
| 1034 | - $primary_registrant = EEM_Registration::instance()->get_one( |
|
| 1035 | - array( |
|
| 1036 | - array( |
|
| 1037 | - 'TXN_ID' => $this->transaction_ID(), |
|
| 1038 | - 'REG_count' => 1, |
|
| 1039 | - ), |
|
| 1040 | - ) |
|
| 1041 | - ); |
|
| 1042 | - return $primary_registrant; |
|
| 1043 | - } |
|
| 1044 | - |
|
| 1045 | - |
|
| 1046 | - /** |
|
| 1047 | - * get Attendee Number |
|
| 1048 | - * |
|
| 1049 | - * @access public |
|
| 1050 | - */ |
|
| 1051 | - public function count() |
|
| 1052 | - { |
|
| 1053 | - return $this->get('REG_count'); |
|
| 1054 | - } |
|
| 1055 | - |
|
| 1056 | - |
|
| 1057 | - /** |
|
| 1058 | - * get Group Size |
|
| 1059 | - */ |
|
| 1060 | - public function group_size() |
|
| 1061 | - { |
|
| 1062 | - return $this->get('REG_group_size'); |
|
| 1063 | - } |
|
| 1064 | - |
|
| 1065 | - |
|
| 1066 | - /** |
|
| 1067 | - * get Registration Date |
|
| 1068 | - */ |
|
| 1069 | - public function date() |
|
| 1070 | - { |
|
| 1071 | - return $this->get('REG_date'); |
|
| 1072 | - } |
|
| 1073 | - |
|
| 1074 | - |
|
| 1075 | - /** |
|
| 1076 | - * gets a pretty date |
|
| 1077 | - * |
|
| 1078 | - * @param string $date_format |
|
| 1079 | - * @param string $time_format |
|
| 1080 | - * @return string |
|
| 1081 | - * @throws EE_Error |
|
| 1082 | - */ |
|
| 1083 | - public function pretty_date($date_format = null, $time_format = null) |
|
| 1084 | - { |
|
| 1085 | - return $this->get_datetime('REG_date', $date_format, $time_format); |
|
| 1086 | - } |
|
| 1087 | - |
|
| 1088 | - |
|
| 1089 | - /** |
|
| 1090 | - * final_price |
|
| 1091 | - * the registration's share of the transaction total, so that the |
|
| 1092 | - * sum of all the transaction's REG_final_prices equal the transaction's total |
|
| 1093 | - * |
|
| 1094 | - * @return float |
|
| 1095 | - * @throws EE_Error |
|
| 1096 | - */ |
|
| 1097 | - public function final_price() |
|
| 1098 | - { |
|
| 1099 | - return $this->get('REG_final_price'); |
|
| 1100 | - } |
|
| 1101 | - |
|
| 1102 | - |
|
| 1103 | - /** |
|
| 1104 | - * pretty_final_price |
|
| 1105 | - * final price as formatted string, with correct decimal places and currency symbol |
|
| 1106 | - * |
|
| 1107 | - * @return string |
|
| 1108 | - * @throws EE_Error |
|
| 1109 | - */ |
|
| 1110 | - public function pretty_final_price() |
|
| 1111 | - { |
|
| 1112 | - return $this->get_pretty('REG_final_price'); |
|
| 1113 | - } |
|
| 1114 | - |
|
| 1115 | - |
|
| 1116 | - /** |
|
| 1117 | - * get paid (yeah) |
|
| 1118 | - * |
|
| 1119 | - * @return float |
|
| 1120 | - * @throws EE_Error |
|
| 1121 | - */ |
|
| 1122 | - public function paid() |
|
| 1123 | - { |
|
| 1124 | - return $this->get('REG_paid'); |
|
| 1125 | - } |
|
| 1126 | - |
|
| 1127 | - |
|
| 1128 | - /** |
|
| 1129 | - * pretty_paid |
|
| 1130 | - * |
|
| 1131 | - * @return float |
|
| 1132 | - * @throws EE_Error |
|
| 1133 | - */ |
|
| 1134 | - public function pretty_paid() |
|
| 1135 | - { |
|
| 1136 | - return $this->get_pretty('REG_paid'); |
|
| 1137 | - } |
|
| 1138 | - |
|
| 1139 | - |
|
| 1140 | - /** |
|
| 1141 | - * owes_monies_and_can_pay |
|
| 1142 | - * whether or not this registration has monies owing and it's' status allows payment |
|
| 1143 | - * |
|
| 1144 | - * @param array $requires_payment |
|
| 1145 | - * @return bool |
|
| 1146 | - * @throws EE_Error |
|
| 1147 | - */ |
|
| 1148 | - public function owes_monies_and_can_pay($requires_payment = array()) |
|
| 1149 | - { |
|
| 1150 | - // these reg statuses require payment (if event is not free) |
|
| 1151 | - $requires_payment = ! empty($requires_payment) |
|
| 1152 | - ? $requires_payment |
|
| 1153 | - : EEM_Registration::reg_statuses_that_allow_payment(); |
|
| 1154 | - if (in_array($this->status_ID(), $requires_payment) && |
|
| 1155 | - $this->final_price() != 0 && |
|
| 1156 | - $this->final_price() != $this->paid() |
|
| 1157 | - ) { |
|
| 1158 | - return true; |
|
| 1159 | - } else { |
|
| 1160 | - return false; |
|
| 1161 | - } |
|
| 1162 | - } |
|
| 1163 | - |
|
| 1164 | - |
|
| 1165 | - /** |
|
| 1166 | - * Prints out the return value of $this->pretty_status() |
|
| 1167 | - * |
|
| 1168 | - * @param bool $show_icons |
|
| 1169 | - * @return void |
|
| 1170 | - * @throws EE_Error |
|
| 1171 | - */ |
|
| 1172 | - public function e_pretty_status($show_icons = false) |
|
| 1173 | - { |
|
| 1174 | - echo $this->pretty_status($show_icons); |
|
| 1175 | - } |
|
| 1176 | - |
|
| 1177 | - |
|
| 1178 | - /** |
|
| 1179 | - * Returns a nice version of the status for displaying to customers |
|
| 1180 | - * |
|
| 1181 | - * @param bool $show_icons |
|
| 1182 | - * @return string |
|
| 1183 | - * @throws EE_Error |
|
| 1184 | - */ |
|
| 1185 | - public function pretty_status($show_icons = false) |
|
| 1186 | - { |
|
| 1187 | - $status = EEM_Status::instance()->localized_status( |
|
| 1188 | - array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
| 1189 | - false, |
|
| 1190 | - 'sentence' |
|
| 1191 | - ); |
|
| 1192 | - $icon = ''; |
|
| 1193 | - switch ($this->status_ID()) { |
|
| 1194 | - case EEM_Registration::status_id_approved: |
|
| 1195 | - $icon = $show_icons |
|
| 1196 | - ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
| 1197 | - : ''; |
|
| 1198 | - break; |
|
| 1199 | - case EEM_Registration::status_id_pending_payment: |
|
| 1200 | - $icon = $show_icons |
|
| 1201 | - ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
| 1202 | - : ''; |
|
| 1203 | - break; |
|
| 1204 | - case EEM_Registration::status_id_not_approved: |
|
| 1205 | - $icon = $show_icons |
|
| 1206 | - ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
| 1207 | - : ''; |
|
| 1208 | - break; |
|
| 1209 | - case EEM_Registration::status_id_cancelled: |
|
| 1210 | - $icon = $show_icons |
|
| 1211 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
| 1212 | - : ''; |
|
| 1213 | - break; |
|
| 1214 | - case EEM_Registration::status_id_incomplete: |
|
| 1215 | - $icon = $show_icons |
|
| 1216 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
| 1217 | - : ''; |
|
| 1218 | - break; |
|
| 1219 | - case EEM_Registration::status_id_declined: |
|
| 1220 | - $icon = $show_icons |
|
| 1221 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
| 1222 | - : ''; |
|
| 1223 | - break; |
|
| 1224 | - case EEM_Registration::status_id_wait_list: |
|
| 1225 | - $icon = $show_icons |
|
| 1226 | - ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
| 1227 | - : ''; |
|
| 1228 | - break; |
|
| 1229 | - } |
|
| 1230 | - return $icon . $status[ $this->status_ID() ]; |
|
| 1231 | - } |
|
| 1232 | - |
|
| 1233 | - |
|
| 1234 | - /** |
|
| 1235 | - * get Attendee Is Going |
|
| 1236 | - */ |
|
| 1237 | - public function att_is_going() |
|
| 1238 | - { |
|
| 1239 | - return $this->get('REG_att_is_going'); |
|
| 1240 | - } |
|
| 1241 | - |
|
| 1242 | - |
|
| 1243 | - /** |
|
| 1244 | - * Gets related answers |
|
| 1245 | - * |
|
| 1246 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1247 | - * @return EE_Answer[] |
|
| 1248 | - * @throws EE_Error |
|
| 1249 | - */ |
|
| 1250 | - public function answers($query_params = null) |
|
| 1251 | - { |
|
| 1252 | - return $this->get_many_related('Answer', $query_params); |
|
| 1253 | - } |
|
| 1254 | - |
|
| 1255 | - |
|
| 1256 | - /** |
|
| 1257 | - * Gets the registration's answer value to the specified question |
|
| 1258 | - * (either the question's ID or a question object) |
|
| 1259 | - * |
|
| 1260 | - * @param EE_Question|int $question |
|
| 1261 | - * @param bool $pretty_value |
|
| 1262 | - * @return array|string if pretty_value= true, the result will always be a string |
|
| 1263 | - * (because the answer might be an array of answer values, so passing pretty_value=true |
|
| 1264 | - * will convert it into some kind of string) |
|
| 1265 | - * @throws EE_Error |
|
| 1266 | - */ |
|
| 1267 | - public function answer_value_to_question($question, $pretty_value = true) |
|
| 1268 | - { |
|
| 1269 | - $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
| 1270 | - return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
| 1271 | - } |
|
| 1272 | - |
|
| 1273 | - |
|
| 1274 | - /** |
|
| 1275 | - * question_groups |
|
| 1276 | - * returns an array of EE_Question_Group objects for this registration |
|
| 1277 | - * |
|
| 1278 | - * @return EE_Question_Group[] |
|
| 1279 | - * @throws EE_Error |
|
| 1280 | - * @throws InvalidArgumentException |
|
| 1281 | - * @throws InvalidDataTypeException |
|
| 1282 | - * @throws InvalidInterfaceException |
|
| 1283 | - * @throws ReflectionException |
|
| 1284 | - */ |
|
| 1285 | - public function question_groups() |
|
| 1286 | - { |
|
| 1287 | - return EEM_Event::instance()->get_question_groups_for_event($this->event_ID(), $this); |
|
| 1288 | - } |
|
| 1289 | - |
|
| 1290 | - |
|
| 1291 | - /** |
|
| 1292 | - * count_question_groups |
|
| 1293 | - * returns a count of the number of EE_Question_Group objects for this registration |
|
| 1294 | - * |
|
| 1295 | - * @return int |
|
| 1296 | - * @throws EE_Error |
|
| 1297 | - * @throws EntityNotFoundException |
|
| 1298 | - * @throws InvalidArgumentException |
|
| 1299 | - * @throws InvalidDataTypeException |
|
| 1300 | - * @throws InvalidInterfaceException |
|
| 1301 | - * @throws ReflectionException |
|
| 1302 | - */ |
|
| 1303 | - public function count_question_groups() |
|
| 1304 | - { |
|
| 1305 | - return EEM_Event::instance()->count_related( |
|
| 1306 | - $this->event_ID(), |
|
| 1307 | - 'Question_Group', |
|
| 1308 | - [ |
|
| 1309 | - [ |
|
| 1310 | - 'Event_Question_Group.' |
|
| 1311 | - . EEM_Event_Question_Group::instance()->fieldNameForContext($this->is_primary_registrant()) => true, |
|
| 1312 | - ] |
|
| 1313 | - ] |
|
| 1314 | - ); |
|
| 1315 | - } |
|
| 1316 | - |
|
| 1317 | - |
|
| 1318 | - /** |
|
| 1319 | - * Returns the registration date in the 'standard' string format |
|
| 1320 | - * (function may be improved in the future to allow for different formats and timezones) |
|
| 1321 | - * |
|
| 1322 | - * @return string |
|
| 1323 | - * @throws EE_Error |
|
| 1324 | - */ |
|
| 1325 | - public function reg_date() |
|
| 1326 | - { |
|
| 1327 | - return $this->get_datetime('REG_date'); |
|
| 1328 | - } |
|
| 1329 | - |
|
| 1330 | - |
|
| 1331 | - /** |
|
| 1332 | - * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
| 1333 | - * the ticket this registration purchased, or the datetime they have registered |
|
| 1334 | - * to attend) |
|
| 1335 | - * |
|
| 1336 | - * @return EE_Datetime_Ticket |
|
| 1337 | - * @throws EE_Error |
|
| 1338 | - */ |
|
| 1339 | - public function datetime_ticket() |
|
| 1340 | - { |
|
| 1341 | - return $this->get_first_related('Datetime_Ticket'); |
|
| 1342 | - } |
|
| 1343 | - |
|
| 1344 | - |
|
| 1345 | - /** |
|
| 1346 | - * Sets the registration's datetime_ticket. |
|
| 1347 | - * |
|
| 1348 | - * @param EE_Datetime_Ticket $datetime_ticket |
|
| 1349 | - * @return EE_Datetime_Ticket |
|
| 1350 | - * @throws EE_Error |
|
| 1351 | - */ |
|
| 1352 | - public function set_datetime_ticket($datetime_ticket) |
|
| 1353 | - { |
|
| 1354 | - return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
| 1355 | - } |
|
| 1356 | - |
|
| 1357 | - /** |
|
| 1358 | - * Gets deleted |
|
| 1359 | - * |
|
| 1360 | - * @return bool |
|
| 1361 | - * @throws EE_Error |
|
| 1362 | - */ |
|
| 1363 | - public function deleted() |
|
| 1364 | - { |
|
| 1365 | - return $this->get('REG_deleted'); |
|
| 1366 | - } |
|
| 1367 | - |
|
| 1368 | - /** |
|
| 1369 | - * Sets deleted |
|
| 1370 | - * |
|
| 1371 | - * @param boolean $deleted |
|
| 1372 | - * @return bool |
|
| 1373 | - * @throws EE_Error |
|
| 1374 | - * @throws RuntimeException |
|
| 1375 | - */ |
|
| 1376 | - public function set_deleted($deleted) |
|
| 1377 | - { |
|
| 1378 | - if ($deleted) { |
|
| 1379 | - $this->delete(); |
|
| 1380 | - } else { |
|
| 1381 | - $this->restore(); |
|
| 1382 | - } |
|
| 1383 | - } |
|
| 1384 | - |
|
| 1385 | - |
|
| 1386 | - /** |
|
| 1387 | - * Get the status object of this object |
|
| 1388 | - * |
|
| 1389 | - * @return EE_Status |
|
| 1390 | - * @throws EE_Error |
|
| 1391 | - */ |
|
| 1392 | - public function status_obj() |
|
| 1393 | - { |
|
| 1394 | - return $this->get_first_related('Status'); |
|
| 1395 | - } |
|
| 1396 | - |
|
| 1397 | - |
|
| 1398 | - /** |
|
| 1399 | - * Returns the number of times this registration has checked into any of the datetimes |
|
| 1400 | - * its available for |
|
| 1401 | - * |
|
| 1402 | - * @return int |
|
| 1403 | - * @throws EE_Error |
|
| 1404 | - */ |
|
| 1405 | - public function count_checkins() |
|
| 1406 | - { |
|
| 1407 | - return $this->get_model()->count_related($this, 'Checkin'); |
|
| 1408 | - } |
|
| 1409 | - |
|
| 1410 | - |
|
| 1411 | - /** |
|
| 1412 | - * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
| 1413 | - * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
| 1414 | - * |
|
| 1415 | - * @return int |
|
| 1416 | - * @throws EE_Error |
|
| 1417 | - */ |
|
| 1418 | - public function count_checkins_not_checkedout() |
|
| 1419 | - { |
|
| 1420 | - return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
| 1421 | - } |
|
| 1422 | - |
|
| 1423 | - |
|
| 1424 | - /** |
|
| 1425 | - * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
| 1426 | - * |
|
| 1427 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1428 | - * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
| 1429 | - * consider registration status as well as datetime access. |
|
| 1430 | - * @return bool |
|
| 1431 | - * @throws EE_Error |
|
| 1432 | - */ |
|
| 1433 | - public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
| 1434 | - { |
|
| 1435 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1436 | - |
|
| 1437 | - // first check registration status |
|
| 1438 | - if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
| 1439 | - return false; |
|
| 1440 | - } |
|
| 1441 | - // is there a datetime ticket that matches this dtt_ID? |
|
| 1442 | - if (! (EEM_Datetime_Ticket::instance()->exists( |
|
| 1443 | - array( |
|
| 1444 | - array( |
|
| 1445 | - 'TKT_ID' => $this->get('TKT_ID'), |
|
| 1446 | - 'DTT_ID' => $DTT_ID, |
|
| 1447 | - ), |
|
| 1448 | - ) |
|
| 1449 | - )) |
|
| 1450 | - ) { |
|
| 1451 | - return false; |
|
| 1452 | - } |
|
| 1453 | - |
|
| 1454 | - // final check is against TKT_uses |
|
| 1455 | - return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
| 1456 | - } |
|
| 1457 | - |
|
| 1458 | - |
|
| 1459 | - /** |
|
| 1460 | - * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
| 1461 | - * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
| 1462 | - * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
| 1463 | - * then return false. Otherwise return true. |
|
| 1464 | - * |
|
| 1465 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1466 | - * @return bool true means can checkin. false means cannot checkin. |
|
| 1467 | - * @throws EE_Error |
|
| 1468 | - */ |
|
| 1469 | - public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
| 1470 | - { |
|
| 1471 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1472 | - |
|
| 1473 | - if (! $DTT_ID) { |
|
| 1474 | - return false; |
|
| 1475 | - } |
|
| 1476 | - |
|
| 1477 | - $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
| 1478 | - |
|
| 1479 | - // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
| 1480 | - // check-in or not. |
|
| 1481 | - if (! $max_uses || $max_uses === EE_INF) { |
|
| 1482 | - return true; |
|
| 1483 | - } |
|
| 1484 | - |
|
| 1485 | - // does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
| 1486 | - // go ahead and toggle. |
|
| 1487 | - if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
| 1488 | - return true; |
|
| 1489 | - } |
|
| 1490 | - |
|
| 1491 | - // made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
| 1492 | - // disallows further check-ins. |
|
| 1493 | - $count_unique_dtt_checkins = EEM_Checkin::instance()->count( |
|
| 1494 | - array( |
|
| 1495 | - array( |
|
| 1496 | - 'REG_ID' => $this->ID(), |
|
| 1497 | - 'CHK_in' => true, |
|
| 1498 | - ), |
|
| 1499 | - ), |
|
| 1500 | - 'DTT_ID', |
|
| 1501 | - true |
|
| 1502 | - ); |
|
| 1503 | - // checkins have already reached their max number of uses |
|
| 1504 | - // so registrant can NOT checkin |
|
| 1505 | - if ($count_unique_dtt_checkins >= $max_uses) { |
|
| 1506 | - EE_Error::add_error( |
|
| 1507 | - esc_html__( |
|
| 1508 | - 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
| 1509 | - 'event_espresso' |
|
| 1510 | - ), |
|
| 1511 | - __FILE__, |
|
| 1512 | - __FUNCTION__, |
|
| 1513 | - __LINE__ |
|
| 1514 | - ); |
|
| 1515 | - return false; |
|
| 1516 | - } |
|
| 1517 | - return true; |
|
| 1518 | - } |
|
| 1519 | - |
|
| 1520 | - |
|
| 1521 | - /** |
|
| 1522 | - * toggle Check-in status for this registration |
|
| 1523 | - * Check-ins are toggled in the following order: |
|
| 1524 | - * never checked in -> checked in |
|
| 1525 | - * checked in -> checked out |
|
| 1526 | - * checked out -> checked in |
|
| 1527 | - * |
|
| 1528 | - * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
| 1529 | - * If not included or null, then it is assumed latest datetime is being toggled. |
|
| 1530 | - * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
| 1531 | - * can be checked in or not. Otherwise this forces change in checkin status. |
|
| 1532 | - * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
| 1533 | - * @throws EE_Error |
|
| 1534 | - */ |
|
| 1535 | - public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
| 1536 | - { |
|
| 1537 | - if (empty($DTT_ID)) { |
|
| 1538 | - $datetime = $this->get_latest_related_datetime(); |
|
| 1539 | - $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
| 1540 | - // verify the registration can checkin for the given DTT_ID |
|
| 1541 | - } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1542 | - EE_Error::add_error( |
|
| 1543 | - sprintf( |
|
| 1544 | - esc_html__( |
|
| 1545 | - 'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access', |
|
| 1546 | - 'event_espresso' |
|
| 1547 | - ), |
|
| 1548 | - $this->ID(), |
|
| 1549 | - $DTT_ID |
|
| 1550 | - ), |
|
| 1551 | - __FILE__, |
|
| 1552 | - __FUNCTION__, |
|
| 1553 | - __LINE__ |
|
| 1554 | - ); |
|
| 1555 | - return false; |
|
| 1556 | - } |
|
| 1557 | - $status_paths = array( |
|
| 1558 | - EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
| 1559 | - EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
| 1560 | - EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
| 1561 | - ); |
|
| 1562 | - // start by getting the current status so we know what status we'll be changing to. |
|
| 1563 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
| 1564 | - $status_to = $status_paths[ $cur_status ]; |
|
| 1565 | - // database only records true for checked IN or false for checked OUT |
|
| 1566 | - // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
| 1567 | - $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
| 1568 | - // add relation - note Check-ins are always creating new rows |
|
| 1569 | - // because we are keeping track of Check-ins over time. |
|
| 1570 | - // Eventually we'll probably want to show a list table |
|
| 1571 | - // for the individual Check-ins so that they can be managed. |
|
| 1572 | - $checkin = EE_Checkin::new_instance( |
|
| 1573 | - array( |
|
| 1574 | - 'REG_ID' => $this->ID(), |
|
| 1575 | - 'DTT_ID' => $DTT_ID, |
|
| 1576 | - 'CHK_in' => $new_status, |
|
| 1577 | - ) |
|
| 1578 | - ); |
|
| 1579 | - // if the record could not be saved then return false |
|
| 1580 | - if ($checkin->save() === 0) { |
|
| 1581 | - if (WP_DEBUG) { |
|
| 1582 | - global $wpdb; |
|
| 1583 | - $error = sprintf( |
|
| 1584 | - esc_html__( |
|
| 1585 | - 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
| 1586 | - 'event_espresso' |
|
| 1587 | - ), |
|
| 1588 | - '<br />', |
|
| 1589 | - $wpdb->last_error |
|
| 1590 | - ); |
|
| 1591 | - } else { |
|
| 1592 | - $error = esc_html__( |
|
| 1593 | - 'Registration check in update failed because of an unknown database error', |
|
| 1594 | - 'event_espresso' |
|
| 1595 | - ); |
|
| 1596 | - } |
|
| 1597 | - EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
| 1598 | - return false; |
|
| 1599 | - } |
|
| 1600 | - return $status_to; |
|
| 1601 | - } |
|
| 1602 | - |
|
| 1603 | - |
|
| 1604 | - /** |
|
| 1605 | - * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
| 1606 | - * "Latest" is defined by the `DTT_EVT_start` column. |
|
| 1607 | - * |
|
| 1608 | - * @return EE_Datetime|null |
|
| 1609 | - * @throws EE_Error |
|
| 1610 | - */ |
|
| 1611 | - public function get_latest_related_datetime() |
|
| 1612 | - { |
|
| 1613 | - return EEM_Datetime::instance()->get_one( |
|
| 1614 | - array( |
|
| 1615 | - array( |
|
| 1616 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1617 | - ), |
|
| 1618 | - 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
| 1619 | - ) |
|
| 1620 | - ); |
|
| 1621 | - } |
|
| 1622 | - |
|
| 1623 | - |
|
| 1624 | - /** |
|
| 1625 | - * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
| 1626 | - * "Earliest" is defined by the `DTT_EVT_start` column. |
|
| 1627 | - * |
|
| 1628 | - * @throws EE_Error |
|
| 1629 | - */ |
|
| 1630 | - public function get_earliest_related_datetime() |
|
| 1631 | - { |
|
| 1632 | - return EEM_Datetime::instance()->get_one( |
|
| 1633 | - array( |
|
| 1634 | - array( |
|
| 1635 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1636 | - ), |
|
| 1637 | - 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
| 1638 | - ) |
|
| 1639 | - ); |
|
| 1640 | - } |
|
| 1641 | - |
|
| 1642 | - |
|
| 1643 | - /** |
|
| 1644 | - * This method simply returns the check-in status for this registration and the given datetime. |
|
| 1645 | - * If neither the datetime nor the checkin values are provided as arguments, |
|
| 1646 | - * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
| 1647 | - * |
|
| 1648 | - * @param int $DTT_ID The ID of the datetime we're checking against |
|
| 1649 | - * (if empty we'll get the primary datetime for |
|
| 1650 | - * this registration (via event) and use it's ID); |
|
| 1651 | - * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
| 1652 | - * |
|
| 1653 | - * @return int Integer representing Check-in status. |
|
| 1654 | - * @throws EE_Error |
|
| 1655 | - */ |
|
| 1656 | - public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
| 1657 | - { |
|
| 1658 | - $checkin_query_params = array( |
|
| 1659 | - 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
| 1660 | - ); |
|
| 1661 | - |
|
| 1662 | - if ($DTT_ID > 0) { |
|
| 1663 | - $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
| 1664 | - } |
|
| 1665 | - |
|
| 1666 | - // get checkin object (if exists) |
|
| 1667 | - $checkin = $checkin instanceof EE_Checkin |
|
| 1668 | - ? $checkin |
|
| 1669 | - : $this->get_first_related('Checkin', $checkin_query_params); |
|
| 1670 | - if ($checkin instanceof EE_Checkin) { |
|
| 1671 | - if ($checkin->get('CHK_in')) { |
|
| 1672 | - return EE_Checkin::status_checked_in; // checked in |
|
| 1673 | - } |
|
| 1674 | - return EE_Checkin::status_checked_out; // had checked in but is now checked out. |
|
| 1675 | - } |
|
| 1676 | - return EE_Checkin::status_checked_never; // never been checked in |
|
| 1677 | - } |
|
| 1678 | - |
|
| 1679 | - |
|
| 1680 | - /** |
|
| 1681 | - * This method returns a localized message for the toggled Check-in message. |
|
| 1682 | - * |
|
| 1683 | - * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
| 1684 | - * then it is assumed Check-in for primary datetime was toggled. |
|
| 1685 | - * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
| 1686 | - * message can be customized with the attendee name. |
|
| 1687 | - * @return string internationalized message |
|
| 1688 | - * @throws EE_Error |
|
| 1689 | - */ |
|
| 1690 | - public function get_checkin_msg($DTT_ID, $error = false) |
|
| 1691 | - { |
|
| 1692 | - // let's get the attendee first so we can include the name of the attendee |
|
| 1693 | - $attendee = $this->get_first_related('Attendee'); |
|
| 1694 | - if ($attendee instanceof EE_Attendee) { |
|
| 1695 | - if ($error) { |
|
| 1696 | - return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
| 1697 | - } |
|
| 1698 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
| 1699 | - // what is the status message going to be? |
|
| 1700 | - switch ($cur_status) { |
|
| 1701 | - case EE_Checkin::status_checked_never: |
|
| 1702 | - return sprintf( |
|
| 1703 | - __("%s has been removed from Check-in records", "event_espresso"), |
|
| 1704 | - $attendee->full_name() |
|
| 1705 | - ); |
|
| 1706 | - break; |
|
| 1707 | - case EE_Checkin::status_checked_in: |
|
| 1708 | - return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
| 1709 | - break; |
|
| 1710 | - case EE_Checkin::status_checked_out: |
|
| 1711 | - return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
| 1712 | - break; |
|
| 1713 | - } |
|
| 1714 | - } |
|
| 1715 | - return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
| 1716 | - } |
|
| 1717 | - |
|
| 1718 | - |
|
| 1719 | - /** |
|
| 1720 | - * Returns the related EE_Transaction to this registration |
|
| 1721 | - * |
|
| 1722 | - * @return EE_Transaction |
|
| 1723 | - * @throws EE_Error |
|
| 1724 | - * @throws EntityNotFoundException |
|
| 1725 | - */ |
|
| 1726 | - public function transaction() |
|
| 1727 | - { |
|
| 1728 | - $transaction = $this->get_first_related('Transaction'); |
|
| 1729 | - if (! $transaction instanceof \EE_Transaction) { |
|
| 1730 | - throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
| 1731 | - } |
|
| 1732 | - return $transaction; |
|
| 1733 | - } |
|
| 1734 | - |
|
| 1735 | - |
|
| 1736 | - /** |
|
| 1737 | - * get Registration Code |
|
| 1738 | - */ |
|
| 1739 | - public function reg_code() |
|
| 1740 | - { |
|
| 1741 | - return $this->get('REG_code'); |
|
| 1742 | - } |
|
| 1743 | - |
|
| 1744 | - |
|
| 1745 | - /** |
|
| 1746 | - * get Transaction ID |
|
| 1747 | - */ |
|
| 1748 | - public function transaction_ID() |
|
| 1749 | - { |
|
| 1750 | - return $this->get('TXN_ID'); |
|
| 1751 | - } |
|
| 1752 | - |
|
| 1753 | - |
|
| 1754 | - /** |
|
| 1755 | - * @return int |
|
| 1756 | - * @throws EE_Error |
|
| 1757 | - */ |
|
| 1758 | - public function ticket_ID() |
|
| 1759 | - { |
|
| 1760 | - return $this->get('TKT_ID'); |
|
| 1761 | - } |
|
| 1762 | - |
|
| 1763 | - |
|
| 1764 | - /** |
|
| 1765 | - * Set Registration Code |
|
| 1766 | - * |
|
| 1767 | - * @access public |
|
| 1768 | - * @param string $REG_code Registration Code |
|
| 1769 | - * @param boolean $use_default |
|
| 1770 | - * @throws EE_Error |
|
| 1771 | - */ |
|
| 1772 | - public function set_reg_code($REG_code, $use_default = false) |
|
| 1773 | - { |
|
| 1774 | - if (empty($REG_code)) { |
|
| 1775 | - EE_Error::add_error( |
|
| 1776 | - esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
| 1777 | - __FILE__, |
|
| 1778 | - __FUNCTION__, |
|
| 1779 | - __LINE__ |
|
| 1780 | - ); |
|
| 1781 | - return; |
|
| 1782 | - } |
|
| 1783 | - if (! $this->reg_code()) { |
|
| 1784 | - parent::set('REG_code', $REG_code, $use_default); |
|
| 1785 | - } else { |
|
| 1786 | - EE_Error::doing_it_wrong( |
|
| 1787 | - __CLASS__ . '::' . __FUNCTION__, |
|
| 1788 | - esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
| 1789 | - '4.6.0' |
|
| 1790 | - ); |
|
| 1791 | - } |
|
| 1792 | - } |
|
| 1793 | - |
|
| 1794 | - |
|
| 1795 | - /** |
|
| 1796 | - * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
| 1797 | - * Note, if you want to just get all registrations in the same transaction (group), use: |
|
| 1798 | - * $registration->transaction()->registrations(); |
|
| 1799 | - * |
|
| 1800 | - * @since 4.5.0 |
|
| 1801 | - * @return EE_Registration[] or empty array if this isn't a group registration. |
|
| 1802 | - * @throws EE_Error |
|
| 1803 | - */ |
|
| 1804 | - public function get_all_other_registrations_in_group() |
|
| 1805 | - { |
|
| 1806 | - if ($this->group_size() < 2) { |
|
| 1807 | - return array(); |
|
| 1808 | - } |
|
| 1809 | - |
|
| 1810 | - $query[0] = array( |
|
| 1811 | - 'TXN_ID' => $this->transaction_ID(), |
|
| 1812 | - 'REG_ID' => array('!=', $this->ID()), |
|
| 1813 | - 'TKT_ID' => $this->ticket_ID(), |
|
| 1814 | - ); |
|
| 1815 | - /** @var EE_Registration[] $registrations */ |
|
| 1816 | - $registrations = $this->get_model()->get_all($query); |
|
| 1817 | - return $registrations; |
|
| 1818 | - } |
|
| 1819 | - |
|
| 1820 | - /** |
|
| 1821 | - * Return the link to the admin details for the object. |
|
| 1822 | - * |
|
| 1823 | - * @return string |
|
| 1824 | - * @throws EE_Error |
|
| 1825 | - */ |
|
| 1826 | - public function get_admin_details_link() |
|
| 1827 | - { |
|
| 1828 | - EE_Registry::instance()->load_helper('URL'); |
|
| 1829 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1830 | - array( |
|
| 1831 | - 'page' => 'espresso_registrations', |
|
| 1832 | - 'action' => 'view_registration', |
|
| 1833 | - '_REG_ID' => $this->ID(), |
|
| 1834 | - ), |
|
| 1835 | - admin_url('admin.php') |
|
| 1836 | - ); |
|
| 1837 | - } |
|
| 1838 | - |
|
| 1839 | - /** |
|
| 1840 | - * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
| 1841 | - * |
|
| 1842 | - * @return string |
|
| 1843 | - * @throws EE_Error |
|
| 1844 | - */ |
|
| 1845 | - public function get_admin_edit_link() |
|
| 1846 | - { |
|
| 1847 | - return $this->get_admin_details_link(); |
|
| 1848 | - } |
|
| 1849 | - |
|
| 1850 | - /** |
|
| 1851 | - * Returns the link to a settings page for the object. |
|
| 1852 | - * |
|
| 1853 | - * @return string |
|
| 1854 | - * @throws EE_Error |
|
| 1855 | - */ |
|
| 1856 | - public function get_admin_settings_link() |
|
| 1857 | - { |
|
| 1858 | - return $this->get_admin_details_link(); |
|
| 1859 | - } |
|
| 1860 | - |
|
| 1861 | - /** |
|
| 1862 | - * Returns the link to the "overview" for the object (typically the "list table" view). |
|
| 1863 | - * |
|
| 1864 | - * @return string |
|
| 1865 | - */ |
|
| 1866 | - public function get_admin_overview_link() |
|
| 1867 | - { |
|
| 1868 | - EE_Registry::instance()->load_helper('URL'); |
|
| 1869 | - return EEH_URL::add_query_args_and_nonce( |
|
| 1870 | - array( |
|
| 1871 | - 'page' => 'espresso_registrations', |
|
| 1872 | - ), |
|
| 1873 | - admin_url('admin.php') |
|
| 1874 | - ); |
|
| 1875 | - } |
|
| 1876 | - |
|
| 1877 | - |
|
| 1878 | - /** |
|
| 1879 | - * @param array $query_params |
|
| 1880 | - * |
|
| 1881 | - * @return \EE_Registration[] |
|
| 1882 | - * @throws EE_Error |
|
| 1883 | - */ |
|
| 1884 | - public function payments($query_params = array()) |
|
| 1885 | - { |
|
| 1886 | - return $this->get_many_related('Payment', $query_params); |
|
| 1887 | - } |
|
| 1888 | - |
|
| 1889 | - |
|
| 1890 | - /** |
|
| 1891 | - * @param array $query_params |
|
| 1892 | - * |
|
| 1893 | - * @return \EE_Registration_Payment[] |
|
| 1894 | - * @throws EE_Error |
|
| 1895 | - */ |
|
| 1896 | - public function registration_payments($query_params = array()) |
|
| 1897 | - { |
|
| 1898 | - return $this->get_many_related('Registration_Payment', $query_params); |
|
| 1899 | - } |
|
| 1900 | - |
|
| 1901 | - |
|
| 1902 | - /** |
|
| 1903 | - * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
| 1904 | - * Note: if there are no payments on the registration there will be no payment method returned. |
|
| 1905 | - * |
|
| 1906 | - * @return EE_Payment_Method|null |
|
| 1907 | - */ |
|
| 1908 | - public function payment_method() |
|
| 1909 | - { |
|
| 1910 | - return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
| 1911 | - } |
|
| 1912 | - |
|
| 1913 | - |
|
| 1914 | - /** |
|
| 1915 | - * @return \EE_Line_Item |
|
| 1916 | - * @throws EntityNotFoundException |
|
| 1917 | - * @throws EE_Error |
|
| 1918 | - */ |
|
| 1919 | - public function ticket_line_item() |
|
| 1920 | - { |
|
| 1921 | - $ticket = $this->ticket(); |
|
| 1922 | - $transaction = $this->transaction(); |
|
| 1923 | - $line_item = null; |
|
| 1924 | - $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 1925 | - $transaction->total_line_item(), |
|
| 1926 | - 'Ticket', |
|
| 1927 | - array($ticket->ID()) |
|
| 1928 | - ); |
|
| 1929 | - foreach ($ticket_line_items as $ticket_line_item) { |
|
| 1930 | - if ($ticket_line_item instanceof \EE_Line_Item |
|
| 1931 | - && $ticket_line_item->OBJ_type() === 'Ticket' |
|
| 1932 | - && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
| 1933 | - ) { |
|
| 1934 | - $line_item = $ticket_line_item; |
|
| 1935 | - break; |
|
| 1936 | - } |
|
| 1937 | - } |
|
| 1938 | - if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1939 | - throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
| 1940 | - } |
|
| 1941 | - return $line_item; |
|
| 1942 | - } |
|
| 1943 | - |
|
| 1944 | - |
|
| 1945 | - /** |
|
| 1946 | - * Soft Deletes this model object. |
|
| 1947 | - * |
|
| 1948 | - * @return boolean | int |
|
| 1949 | - * @throws RuntimeException |
|
| 1950 | - * @throws EE_Error |
|
| 1951 | - */ |
|
| 1952 | - public function delete() |
|
| 1953 | - { |
|
| 1954 | - if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
| 1955 | - $this->set_status(EEM_Registration::status_id_cancelled); |
|
| 1956 | - } |
|
| 1957 | - return parent::delete(); |
|
| 1958 | - } |
|
| 1959 | - |
|
| 1960 | - |
|
| 1961 | - /** |
|
| 1962 | - * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
| 1963 | - * |
|
| 1964 | - * @throws EE_Error |
|
| 1965 | - * @throws RuntimeException |
|
| 1966 | - */ |
|
| 1967 | - public function restore() |
|
| 1968 | - { |
|
| 1969 | - $previous_status = $this->get_extra_meta( |
|
| 1970 | - EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
| 1971 | - true, |
|
| 1972 | - EEM_Registration::status_id_cancelled |
|
| 1973 | - ); |
|
| 1974 | - if ($previous_status) { |
|
| 1975 | - $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
| 1976 | - $this->set_status($previous_status); |
|
| 1977 | - } |
|
| 1978 | - return parent::restore(); |
|
| 1979 | - } |
|
| 1980 | - |
|
| 1981 | - |
|
| 1982 | - /** |
|
| 1983 | - * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price |
|
| 1984 | - * |
|
| 1985 | - * @param boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic |
|
| 1986 | - * depending on whether the reg status changes to or from "Approved" |
|
| 1987 | - * @return boolean whether the Registration status was updated |
|
| 1988 | - * @throws EE_Error |
|
| 1989 | - * @throws RuntimeException |
|
| 1990 | - */ |
|
| 1991 | - public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true) |
|
| 1992 | - { |
|
| 1993 | - $paid = $this->paid(); |
|
| 1994 | - $price = $this->final_price(); |
|
| 1995 | - switch (true) { |
|
| 1996 | - // overpaid or paid |
|
| 1997 | - case EEH_Money::compare_floats($paid, $price, '>'): |
|
| 1998 | - case EEH_Money::compare_floats($paid, $price): |
|
| 1999 | - $new_status = EEM_Registration::status_id_approved; |
|
| 2000 | - break; |
|
| 2001 | - // underpaid |
|
| 2002 | - case EEH_Money::compare_floats($paid, $price, '<'): |
|
| 2003 | - $new_status = EEM_Registration::status_id_pending_payment; |
|
| 2004 | - break; |
|
| 2005 | - // uhhh Houston... |
|
| 2006 | - default: |
|
| 2007 | - throw new RuntimeException( |
|
| 2008 | - esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso') |
|
| 2009 | - ); |
|
| 2010 | - } |
|
| 2011 | - if ($new_status !== $this->status_ID()) { |
|
| 2012 | - if ($trigger_set_status_logic) { |
|
| 2013 | - return $this->set_status($new_status); |
|
| 2014 | - } |
|
| 2015 | - parent::set('STS_ID', $new_status); |
|
| 2016 | - return true; |
|
| 2017 | - } |
|
| 2018 | - return false; |
|
| 2019 | - } |
|
| 2020 | - |
|
| 2021 | - |
|
| 2022 | - /*************************** DEPRECATED ***************************/ |
|
| 2023 | - |
|
| 2024 | - |
|
| 2025 | - /** |
|
| 2026 | - * @deprecated |
|
| 2027 | - * @since 4.7.0 |
|
| 2028 | - * @access public |
|
| 2029 | - */ |
|
| 2030 | - public function price_paid() |
|
| 2031 | - { |
|
| 2032 | - EE_Error::doing_it_wrong( |
|
| 2033 | - 'EE_Registration::price_paid()', |
|
| 2034 | - esc_html__( |
|
| 2035 | - 'This method is deprecated, please use EE_Registration::final_price() instead.', |
|
| 2036 | - 'event_espresso' |
|
| 2037 | - ), |
|
| 2038 | - '4.7.0' |
|
| 2039 | - ); |
|
| 2040 | - return $this->final_price(); |
|
| 2041 | - } |
|
| 2042 | - |
|
| 2043 | - |
|
| 2044 | - /** |
|
| 2045 | - * @deprecated |
|
| 2046 | - * @since 4.7.0 |
|
| 2047 | - * @access public |
|
| 2048 | - * @param float $REG_final_price |
|
| 2049 | - * @throws EE_Error |
|
| 2050 | - * @throws RuntimeException |
|
| 2051 | - */ |
|
| 2052 | - public function set_price_paid($REG_final_price = 0.00) |
|
| 2053 | - { |
|
| 2054 | - EE_Error::doing_it_wrong( |
|
| 2055 | - 'EE_Registration::set_price_paid()', |
|
| 2056 | - esc_html__( |
|
| 2057 | - 'This method is deprecated, please use EE_Registration::set_final_price() instead.', |
|
| 2058 | - 'event_espresso' |
|
| 2059 | - ), |
|
| 2060 | - '4.7.0' |
|
| 2061 | - ); |
|
| 2062 | - $this->set_final_price($REG_final_price); |
|
| 2063 | - } |
|
| 2064 | - |
|
| 2065 | - |
|
| 2066 | - /** |
|
| 2067 | - * @deprecated |
|
| 2068 | - * @since 4.7.0 |
|
| 2069 | - * @return string |
|
| 2070 | - * @throws EE_Error |
|
| 2071 | - */ |
|
| 2072 | - public function pretty_price_paid() |
|
| 2073 | - { |
|
| 2074 | - EE_Error::doing_it_wrong( |
|
| 2075 | - 'EE_Registration::pretty_price_paid()', |
|
| 2076 | - esc_html__( |
|
| 2077 | - 'This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
| 2078 | - 'event_espresso' |
|
| 2079 | - ), |
|
| 2080 | - '4.7.0' |
|
| 2081 | - ); |
|
| 2082 | - return $this->pretty_final_price(); |
|
| 2083 | - } |
|
| 2084 | - |
|
| 2085 | - |
|
| 2086 | - /** |
|
| 2087 | - * Gets the primary datetime related to this registration via the related Event to this registration |
|
| 2088 | - * |
|
| 2089 | - * @deprecated 4.9.17 |
|
| 2090 | - * @return EE_Datetime |
|
| 2091 | - * @throws EE_Error |
|
| 2092 | - * @throws EntityNotFoundException |
|
| 2093 | - */ |
|
| 2094 | - public function get_related_primary_datetime() |
|
| 2095 | - { |
|
| 2096 | - EE_Error::doing_it_wrong( |
|
| 2097 | - __METHOD__, |
|
| 2098 | - esc_html__( |
|
| 2099 | - 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
| 2100 | - 'event_espresso' |
|
| 2101 | - ), |
|
| 2102 | - '4.9.17', |
|
| 2103 | - '5.0.0' |
|
| 2104 | - ); |
|
| 2105 | - return $this->event()->primary_datetime(); |
|
| 2106 | - } |
|
| 2107 | - |
|
| 2108 | - public function name() |
|
| 2109 | - { |
|
| 2110 | - $attendee = $this->attendee(); |
|
| 2111 | - if ($attendee instanceof EE_Attendee) { |
|
| 2112 | - $attendee_name = $attendee->full_name(); |
|
| 2113 | - } else { |
|
| 2114 | - $attendee_name = esc_html__('Unknown', 'event_espresso'); |
|
| 2115 | - } |
|
| 2116 | - return esc_html( |
|
| 2117 | - sprintf( |
|
| 2118 | - // translators: 1: registration code, 2: number, 3: group size, 4: attendee name. |
|
| 2119 | - __('Registration with code "%1$s", %2$d of %3$d for %4$s', 'event_espresso'), |
|
| 2120 | - $this->reg_code(), |
|
| 2121 | - $this->count(), |
|
| 2122 | - $this->group_size(), |
|
| 2123 | - $attendee_name |
|
| 2124 | - ) |
|
| 2125 | - ); |
|
| 2126 | - } |
|
| 20 | + /** |
|
| 21 | + * Used to reference when a registration has never been checked in. |
|
| 22 | + * |
|
| 23 | + * @deprecated use \EE_Checkin::status_checked_never instead |
|
| 24 | + * @type int |
|
| 25 | + */ |
|
| 26 | + const checkin_status_never = 2; |
|
| 27 | + |
|
| 28 | + /** |
|
| 29 | + * Used to reference when a registration has been checked in. |
|
| 30 | + * |
|
| 31 | + * @deprecated use \EE_Checkin::status_checked_in instead |
|
| 32 | + * @type int |
|
| 33 | + */ |
|
| 34 | + const checkin_status_in = 1; |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * Used to reference when a registration has been checked out. |
|
| 39 | + * |
|
| 40 | + * @deprecated use \EE_Checkin::status_checked_out instead |
|
| 41 | + * @type int |
|
| 42 | + */ |
|
| 43 | + const checkin_status_out = 0; |
|
| 44 | + |
|
| 45 | + |
|
| 46 | + /** |
|
| 47 | + * extra meta key for tracking reg status os trashed registrations |
|
| 48 | + * |
|
| 49 | + * @type string |
|
| 50 | + */ |
|
| 51 | + const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
| 52 | + |
|
| 53 | + |
|
| 54 | + /** |
|
| 55 | + * extra meta key for tracking if registration has reserved ticket |
|
| 56 | + * |
|
| 57 | + * @type string |
|
| 58 | + */ |
|
| 59 | + const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
| 60 | + |
|
| 61 | + |
|
| 62 | + /** |
|
| 63 | + * @param array $props_n_values incoming values |
|
| 64 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 65 | + * used.) |
|
| 66 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 67 | + * date_format and the second value is the time format |
|
| 68 | + * @return EE_Registration |
|
| 69 | + * @throws EE_Error |
|
| 70 | + */ |
|
| 71 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
| 72 | + { |
|
| 73 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 74 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 75 | + } |
|
| 76 | + |
|
| 77 | + |
|
| 78 | + /** |
|
| 79 | + * @param array $props_n_values incoming values from the database |
|
| 80 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 81 | + * the website will be used. |
|
| 82 | + * @return EE_Registration |
|
| 83 | + */ |
|
| 84 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
| 85 | + { |
|
| 86 | + return new self($props_n_values, true, $timezone); |
|
| 87 | + } |
|
| 88 | + |
|
| 89 | + |
|
| 90 | + /** |
|
| 91 | + * Set Event ID |
|
| 92 | + * |
|
| 93 | + * @param int $EVT_ID Event ID |
|
| 94 | + * @throws EE_Error |
|
| 95 | + * @throws RuntimeException |
|
| 96 | + */ |
|
| 97 | + public function set_event($EVT_ID = 0) |
|
| 98 | + { |
|
| 99 | + $this->set('EVT_ID', $EVT_ID); |
|
| 100 | + } |
|
| 101 | + |
|
| 102 | + |
|
| 103 | + /** |
|
| 104 | + * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
| 105 | + * be routed to internal methods |
|
| 106 | + * |
|
| 107 | + * @param string $field_name |
|
| 108 | + * @param mixed $field_value |
|
| 109 | + * @param bool $use_default |
|
| 110 | + * @throws EE_Error |
|
| 111 | + * @throws EntityNotFoundException |
|
| 112 | + * @throws InvalidArgumentException |
|
| 113 | + * @throws InvalidDataTypeException |
|
| 114 | + * @throws InvalidInterfaceException |
|
| 115 | + * @throws ReflectionException |
|
| 116 | + * @throws RuntimeException |
|
| 117 | + */ |
|
| 118 | + public function set($field_name, $field_value, $use_default = false) |
|
| 119 | + { |
|
| 120 | + switch ($field_name) { |
|
| 121 | + case 'REG_code': |
|
| 122 | + if (! empty($field_value) && $this->reg_code() === null) { |
|
| 123 | + $this->set_reg_code($field_value, $use_default); |
|
| 124 | + } |
|
| 125 | + break; |
|
| 126 | + case 'STS_ID': |
|
| 127 | + $this->set_status($field_value, $use_default); |
|
| 128 | + break; |
|
| 129 | + default: |
|
| 130 | + parent::set($field_name, $field_value, $use_default); |
|
| 131 | + } |
|
| 132 | + } |
|
| 133 | + |
|
| 134 | + |
|
| 135 | + /** |
|
| 136 | + * Set Status ID |
|
| 137 | + * updates the registration status and ALSO... |
|
| 138 | + * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
| 139 | + * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
| 140 | + * |
|
| 141 | + * @param string $new_STS_ID |
|
| 142 | + * @param boolean $use_default |
|
| 143 | + * @param ContextInterface|null $context |
|
| 144 | + * @return bool |
|
| 145 | + * @throws DomainException |
|
| 146 | + * @throws EE_Error |
|
| 147 | + * @throws EntityNotFoundException |
|
| 148 | + * @throws InvalidArgumentException |
|
| 149 | + * @throws InvalidDataTypeException |
|
| 150 | + * @throws InvalidInterfaceException |
|
| 151 | + * @throws ReflectionException |
|
| 152 | + * @throws RuntimeException |
|
| 153 | + * @throws UnexpectedEntityException |
|
| 154 | + */ |
|
| 155 | + public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null) |
|
| 156 | + { |
|
| 157 | + // get current REG_Status |
|
| 158 | + $old_STS_ID = $this->status_ID(); |
|
| 159 | + // if status has changed |
|
| 160 | + if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
| 161 | + && ! empty($old_STS_ID) // and that old status is actually set |
|
| 162 | + && ! empty($new_STS_ID) // as well as the new status |
|
| 163 | + && $this->ID() // ensure registration is in the db |
|
| 164 | + ) { |
|
| 165 | + // update internal status first |
|
| 166 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 167 | + // THEN handle other changes that occur when reg status changes |
|
| 168 | + // TO approved |
|
| 169 | + if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
| 170 | + // reserve a space by incrementing ticket and datetime sold values |
|
| 171 | + $this->reserveRegistrationSpace(); |
|
| 172 | + do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 173 | + // OR FROM approved |
|
| 174 | + } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
| 175 | + // release a space by decrementing ticket and datetime sold values |
|
| 176 | + $this->releaseRegistrationSpace(); |
|
| 177 | + do_action( |
|
| 178 | + 'AHEE__EE_Registration__set_status__from_approved', |
|
| 179 | + $this, |
|
| 180 | + $old_STS_ID, |
|
| 181 | + $new_STS_ID, |
|
| 182 | + $context |
|
| 183 | + ); |
|
| 184 | + } |
|
| 185 | + // update status |
|
| 186 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 187 | + $this->updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, $context); |
|
| 188 | + if ($this->statusChangeUpdatesTransaction($context)) { |
|
| 189 | + $this->updateTransactionAfterStatusChange(); |
|
| 190 | + } |
|
| 191 | + do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context); |
|
| 192 | + return true; |
|
| 193 | + } |
|
| 194 | + // even though the old value matches the new value, it's still good to |
|
| 195 | + // allow the parent set method to have a say |
|
| 196 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
| 197 | + return true; |
|
| 198 | + } |
|
| 199 | + |
|
| 200 | + |
|
| 201 | + /** |
|
| 202 | + * update REGs and TXN when cancelled or declined registrations involved |
|
| 203 | + * |
|
| 204 | + * @param string $new_STS_ID |
|
| 205 | + * @param string $old_STS_ID |
|
| 206 | + * @param ContextInterface|null $context |
|
| 207 | + * @throws EE_Error |
|
| 208 | + * @throws InvalidArgumentException |
|
| 209 | + * @throws InvalidDataTypeException |
|
| 210 | + * @throws InvalidInterfaceException |
|
| 211 | + * @throws ReflectionException |
|
| 212 | + * @throws RuntimeException |
|
| 213 | + */ |
|
| 214 | + private function updateIfCanceledOrReinstated($new_STS_ID, $old_STS_ID, ContextInterface $context = null) |
|
| 215 | + { |
|
| 216 | + // these reg statuses should not be considered in any calculations involving monies owing |
|
| 217 | + $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
| 218 | + // true if registration has been cancelled or declined |
|
| 219 | + $this->updateIfCanceled( |
|
| 220 | + $closed_reg_statuses, |
|
| 221 | + $new_STS_ID, |
|
| 222 | + $old_STS_ID, |
|
| 223 | + $context |
|
| 224 | + ); |
|
| 225 | + $this->updateIfReinstated( |
|
| 226 | + $closed_reg_statuses, |
|
| 227 | + $new_STS_ID, |
|
| 228 | + $old_STS_ID, |
|
| 229 | + $context |
|
| 230 | + ); |
|
| 231 | + } |
|
| 232 | + |
|
| 233 | + |
|
| 234 | + /** |
|
| 235 | + * update REGs and TXN when cancelled or declined registrations involved |
|
| 236 | + * |
|
| 237 | + * @param array $closed_reg_statuses |
|
| 238 | + * @param string $new_STS_ID |
|
| 239 | + * @param string $old_STS_ID |
|
| 240 | + * @param ContextInterface|null $context |
|
| 241 | + * @throws EE_Error |
|
| 242 | + * @throws InvalidArgumentException |
|
| 243 | + * @throws InvalidDataTypeException |
|
| 244 | + * @throws InvalidInterfaceException |
|
| 245 | + * @throws ReflectionException |
|
| 246 | + * @throws RuntimeException |
|
| 247 | + */ |
|
| 248 | + private function updateIfCanceled( |
|
| 249 | + array $closed_reg_statuses, |
|
| 250 | + $new_STS_ID, |
|
| 251 | + $old_STS_ID, |
|
| 252 | + ContextInterface $context = null |
|
| 253 | + ) { |
|
| 254 | + // true if registration has been cancelled or declined |
|
| 255 | + if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 256 | + && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 257 | + ) { |
|
| 258 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 259 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 260 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 261 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 262 | + // cancelled or declined registration |
|
| 263 | + $registration_processor->update_registration_after_being_canceled_or_declined( |
|
| 264 | + $this, |
|
| 265 | + $closed_reg_statuses |
|
| 266 | + ); |
|
| 267 | + $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
| 268 | + $this, |
|
| 269 | + $closed_reg_statuses, |
|
| 270 | + false |
|
| 271 | + ); |
|
| 272 | + do_action( |
|
| 273 | + 'AHEE__EE_Registration__set_status__canceled_or_declined', |
|
| 274 | + $this, |
|
| 275 | + $old_STS_ID, |
|
| 276 | + $new_STS_ID, |
|
| 277 | + $context |
|
| 278 | + ); |
|
| 279 | + return; |
|
| 280 | + } |
|
| 281 | + } |
|
| 282 | + |
|
| 283 | + |
|
| 284 | + /** |
|
| 285 | + * update REGs and TXN when cancelled or declined registrations involved |
|
| 286 | + * |
|
| 287 | + * @param array $closed_reg_statuses |
|
| 288 | + * @param string $new_STS_ID |
|
| 289 | + * @param string $old_STS_ID |
|
| 290 | + * @param ContextInterface|null $context |
|
| 291 | + * @throws EE_Error |
|
| 292 | + * @throws InvalidArgumentException |
|
| 293 | + * @throws InvalidDataTypeException |
|
| 294 | + * @throws InvalidInterfaceException |
|
| 295 | + * @throws ReflectionException |
|
| 296 | + */ |
|
| 297 | + private function updateIfReinstated( |
|
| 298 | + array $closed_reg_statuses, |
|
| 299 | + $new_STS_ID, |
|
| 300 | + $old_STS_ID, |
|
| 301 | + ContextInterface $context = null |
|
| 302 | + ) { |
|
| 303 | + // true if reinstating cancelled or declined registration |
|
| 304 | + if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
| 305 | + && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
| 306 | + ) { |
|
| 307 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 308 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 309 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 310 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 311 | + // reinstating cancelled or declined registration |
|
| 312 | + $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
| 313 | + $this, |
|
| 314 | + $closed_reg_statuses |
|
| 315 | + ); |
|
| 316 | + $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
| 317 | + $this, |
|
| 318 | + $closed_reg_statuses, |
|
| 319 | + false |
|
| 320 | + ); |
|
| 321 | + do_action( |
|
| 322 | + 'AHEE__EE_Registration__set_status__after_reinstated', |
|
| 323 | + $this, |
|
| 324 | + $old_STS_ID, |
|
| 325 | + $new_STS_ID, |
|
| 326 | + $context |
|
| 327 | + ); |
|
| 328 | + } |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + |
|
| 332 | + /** |
|
| 333 | + * @param ContextInterface|null $context |
|
| 334 | + * @return bool |
|
| 335 | + */ |
|
| 336 | + private function statusChangeUpdatesTransaction(ContextInterface $context = null) |
|
| 337 | + { |
|
| 338 | + $contexts_that_do_not_update_transaction = (array) apply_filters( |
|
| 339 | + 'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction', |
|
| 340 | + array('spco_reg_step_attendee_information_process_registrations'), |
|
| 341 | + $context, |
|
| 342 | + $this |
|
| 343 | + ); |
|
| 344 | + return ! ( |
|
| 345 | + $context instanceof ContextInterface |
|
| 346 | + && in_array($context->slug(), $contexts_that_do_not_update_transaction, true) |
|
| 347 | + ); |
|
| 348 | + } |
|
| 349 | + |
|
| 350 | + |
|
| 351 | + /** |
|
| 352 | + * @throws EE_Error |
|
| 353 | + * @throws EntityNotFoundException |
|
| 354 | + * @throws InvalidArgumentException |
|
| 355 | + * @throws InvalidDataTypeException |
|
| 356 | + * @throws InvalidInterfaceException |
|
| 357 | + * @throws ReflectionException |
|
| 358 | + * @throws RuntimeException |
|
| 359 | + */ |
|
| 360 | + private function updateTransactionAfterStatusChange() |
|
| 361 | + { |
|
| 362 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
| 363 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
| 364 | + $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
| 365 | + $this->transaction()->update_status_based_on_total_paid(true); |
|
| 366 | + } |
|
| 367 | + |
|
| 368 | + |
|
| 369 | + /** |
|
| 370 | + * get Status ID |
|
| 371 | + */ |
|
| 372 | + public function status_ID() |
|
| 373 | + { |
|
| 374 | + return $this->get('STS_ID'); |
|
| 375 | + } |
|
| 376 | + |
|
| 377 | + |
|
| 378 | + /** |
|
| 379 | + * Gets the ticket this registration is for |
|
| 380 | + * |
|
| 381 | + * @param boolean $include_archived whether to include archived tickets or not. |
|
| 382 | + * |
|
| 383 | + * @return EE_Ticket|EE_Base_Class |
|
| 384 | + * @throws EE_Error |
|
| 385 | + */ |
|
| 386 | + public function ticket($include_archived = true) |
|
| 387 | + { |
|
| 388 | + $query_params = array(); |
|
| 389 | + if ($include_archived) { |
|
| 390 | + $query_params['default_where_conditions'] = 'none'; |
|
| 391 | + } |
|
| 392 | + return $this->get_first_related('Ticket', $query_params); |
|
| 393 | + } |
|
| 394 | + |
|
| 395 | + |
|
| 396 | + /** |
|
| 397 | + * Gets the event this registration is for |
|
| 398 | + * |
|
| 399 | + * @return EE_Event |
|
| 400 | + * @throws EE_Error |
|
| 401 | + * @throws EntityNotFoundException |
|
| 402 | + */ |
|
| 403 | + public function event() |
|
| 404 | + { |
|
| 405 | + $event = $this->get_first_related('Event'); |
|
| 406 | + if (! $event instanceof \EE_Event) { |
|
| 407 | + throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
| 408 | + } |
|
| 409 | + return $event; |
|
| 410 | + } |
|
| 411 | + |
|
| 412 | + |
|
| 413 | + /** |
|
| 414 | + * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
| 415 | + * with the author of the event this registration is for. |
|
| 416 | + * |
|
| 417 | + * @since 4.5.0 |
|
| 418 | + * @return int |
|
| 419 | + * @throws EE_Error |
|
| 420 | + * @throws EntityNotFoundException |
|
| 421 | + */ |
|
| 422 | + public function wp_user() |
|
| 423 | + { |
|
| 424 | + $event = $this->event(); |
|
| 425 | + if ($event instanceof EE_Event) { |
|
| 426 | + return $event->wp_user(); |
|
| 427 | + } |
|
| 428 | + return 0; |
|
| 429 | + } |
|
| 430 | + |
|
| 431 | + |
|
| 432 | + /** |
|
| 433 | + * increments this registration's related ticket sold and corresponding datetime sold values |
|
| 434 | + * |
|
| 435 | + * @return void |
|
| 436 | + * @throws DomainException |
|
| 437 | + * @throws EE_Error |
|
| 438 | + * @throws EntityNotFoundException |
|
| 439 | + * @throws InvalidArgumentException |
|
| 440 | + * @throws InvalidDataTypeException |
|
| 441 | + * @throws InvalidInterfaceException |
|
| 442 | + * @throws ReflectionException |
|
| 443 | + * @throws UnexpectedEntityException |
|
| 444 | + */ |
|
| 445 | + private function reserveRegistrationSpace() |
|
| 446 | + { |
|
| 447 | + // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
| 448 | + // so stop tracking that this reg has a ticket reserved |
|
| 449 | + $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 450 | + $ticket = $this->ticket(); |
|
| 451 | + $ticket->increaseSold(); |
|
| 452 | + // possibly set event status to sold out |
|
| 453 | + $this->event()->perform_sold_out_status_check(); |
|
| 454 | + } |
|
| 455 | + |
|
| 456 | + |
|
| 457 | + /** |
|
| 458 | + * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
| 459 | + * |
|
| 460 | + * @return void |
|
| 461 | + * @throws DomainException |
|
| 462 | + * @throws EE_Error |
|
| 463 | + * @throws EntityNotFoundException |
|
| 464 | + * @throws InvalidArgumentException |
|
| 465 | + * @throws InvalidDataTypeException |
|
| 466 | + * @throws InvalidInterfaceException |
|
| 467 | + * @throws ReflectionException |
|
| 468 | + * @throws UnexpectedEntityException |
|
| 469 | + */ |
|
| 470 | + private function releaseRegistrationSpace() |
|
| 471 | + { |
|
| 472 | + $ticket = $this->ticket(); |
|
| 473 | + $ticket->decreaseSold(); |
|
| 474 | + // possibly change event status from sold out back to previous status |
|
| 475 | + $this->event()->perform_sold_out_status_check(); |
|
| 476 | + } |
|
| 477 | + |
|
| 478 | + |
|
| 479 | + /** |
|
| 480 | + * tracks this registration's ticket reservation in extra meta |
|
| 481 | + * and can increment related ticket reserved and corresponding datetime reserved values |
|
| 482 | + * |
|
| 483 | + * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
| 484 | + * @return void |
|
| 485 | + * @throws EE_Error |
|
| 486 | + * @throws InvalidArgumentException |
|
| 487 | + * @throws InvalidDataTypeException |
|
| 488 | + * @throws InvalidInterfaceException |
|
| 489 | + * @throws ReflectionException |
|
| 490 | + */ |
|
| 491 | + public function reserve_ticket($update_ticket = false, $source = 'unknown') |
|
| 492 | + { |
|
| 493 | + // only reserve ticket if space is not currently reserved |
|
| 494 | + if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) !== true) { |
|
| 495 | + $this->update_extra_meta('reserve_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 496 | + // IMPORTANT !!! |
|
| 497 | + // although checking $update_ticket first would be more efficient, |
|
| 498 | + // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 499 | + if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) |
|
| 500 | + && $update_ticket |
|
| 501 | + ) { |
|
| 502 | + $ticket = $this->ticket(); |
|
| 503 | + $ticket->increaseReserved(1, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 504 | + $ticket->save(); |
|
| 505 | + } |
|
| 506 | + } |
|
| 507 | + } |
|
| 508 | + |
|
| 509 | + |
|
| 510 | + /** |
|
| 511 | + * stops tracking this registration's ticket reservation in extra meta |
|
| 512 | + * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
| 513 | + * |
|
| 514 | + * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
| 515 | + * @return void |
|
| 516 | + * @throws EE_Error |
|
| 517 | + * @throws InvalidArgumentException |
|
| 518 | + * @throws InvalidDataTypeException |
|
| 519 | + * @throws InvalidInterfaceException |
|
| 520 | + * @throws ReflectionException |
|
| 521 | + */ |
|
| 522 | + public function release_reserved_ticket($update_ticket = false, $source = 'unknown') |
|
| 523 | + { |
|
| 524 | + // only release ticket if space is currently reserved |
|
| 525 | + if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) === true) { |
|
| 526 | + $this->update_extra_meta('release_reserved_ticket', "{$this->ticket_ID()} from {$source}"); |
|
| 527 | + // IMPORTANT !!! |
|
| 528 | + // although checking $update_ticket first would be more efficient, |
|
| 529 | + // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
| 530 | + if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, false) |
|
| 531 | + && $update_ticket |
|
| 532 | + ) { |
|
| 533 | + $ticket = $this->ticket(); |
|
| 534 | + $ticket->decreaseReserved(1, true, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
| 535 | + } |
|
| 536 | + } |
|
| 537 | + } |
|
| 538 | + |
|
| 539 | + |
|
| 540 | + /** |
|
| 541 | + * Set Attendee ID |
|
| 542 | + * |
|
| 543 | + * @param int $ATT_ID Attendee ID |
|
| 544 | + * @throws EE_Error |
|
| 545 | + * @throws RuntimeException |
|
| 546 | + */ |
|
| 547 | + public function set_attendee_id($ATT_ID = 0) |
|
| 548 | + { |
|
| 549 | + $this->set('ATT_ID', $ATT_ID); |
|
| 550 | + } |
|
| 551 | + |
|
| 552 | + |
|
| 553 | + /** |
|
| 554 | + * Set Transaction ID |
|
| 555 | + * |
|
| 556 | + * @param int $TXN_ID Transaction ID |
|
| 557 | + * @throws EE_Error |
|
| 558 | + * @throws RuntimeException |
|
| 559 | + */ |
|
| 560 | + public function set_transaction_id($TXN_ID = 0) |
|
| 561 | + { |
|
| 562 | + $this->set('TXN_ID', $TXN_ID); |
|
| 563 | + } |
|
| 564 | + |
|
| 565 | + |
|
| 566 | + /** |
|
| 567 | + * Set Session |
|
| 568 | + * |
|
| 569 | + * @param string $REG_session PHP Session ID |
|
| 570 | + * @throws EE_Error |
|
| 571 | + * @throws RuntimeException |
|
| 572 | + */ |
|
| 573 | + public function set_session($REG_session = '') |
|
| 574 | + { |
|
| 575 | + $this->set('REG_session', $REG_session); |
|
| 576 | + } |
|
| 577 | + |
|
| 578 | + |
|
| 579 | + /** |
|
| 580 | + * Set Registration URL Link |
|
| 581 | + * |
|
| 582 | + * @param string $REG_url_link Registration URL Link |
|
| 583 | + * @throws EE_Error |
|
| 584 | + * @throws RuntimeException |
|
| 585 | + */ |
|
| 586 | + public function set_reg_url_link($REG_url_link = '') |
|
| 587 | + { |
|
| 588 | + $this->set('REG_url_link', $REG_url_link); |
|
| 589 | + } |
|
| 590 | + |
|
| 591 | + |
|
| 592 | + /** |
|
| 593 | + * Set Attendee Counter |
|
| 594 | + * |
|
| 595 | + * @param int $REG_count Primary Attendee |
|
| 596 | + * @throws EE_Error |
|
| 597 | + * @throws RuntimeException |
|
| 598 | + */ |
|
| 599 | + public function set_count($REG_count = 1) |
|
| 600 | + { |
|
| 601 | + $this->set('REG_count', $REG_count); |
|
| 602 | + } |
|
| 603 | + |
|
| 604 | + |
|
| 605 | + /** |
|
| 606 | + * Set Group Size |
|
| 607 | + * |
|
| 608 | + * @param boolean $REG_group_size Group Registration |
|
| 609 | + * @throws EE_Error |
|
| 610 | + * @throws RuntimeException |
|
| 611 | + */ |
|
| 612 | + public function set_group_size($REG_group_size = false) |
|
| 613 | + { |
|
| 614 | + $this->set('REG_group_size', $REG_group_size); |
|
| 615 | + } |
|
| 616 | + |
|
| 617 | + |
|
| 618 | + /** |
|
| 619 | + * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
| 620 | + * EEM_Registration::status_id_not_approved |
|
| 621 | + * |
|
| 622 | + * @return boolean |
|
| 623 | + */ |
|
| 624 | + public function is_not_approved() |
|
| 625 | + { |
|
| 626 | + return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
| 627 | + } |
|
| 628 | + |
|
| 629 | + |
|
| 630 | + /** |
|
| 631 | + * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
| 632 | + * EEM_Registration::status_id_pending_payment |
|
| 633 | + * |
|
| 634 | + * @return boolean |
|
| 635 | + */ |
|
| 636 | + public function is_pending_payment() |
|
| 637 | + { |
|
| 638 | + return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
| 639 | + } |
|
| 640 | + |
|
| 641 | + |
|
| 642 | + /** |
|
| 643 | + * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
| 644 | + * |
|
| 645 | + * @return boolean |
|
| 646 | + */ |
|
| 647 | + public function is_approved() |
|
| 648 | + { |
|
| 649 | + return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
| 650 | + } |
|
| 651 | + |
|
| 652 | + |
|
| 653 | + /** |
|
| 654 | + * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
| 655 | + * |
|
| 656 | + * @return boolean |
|
| 657 | + */ |
|
| 658 | + public function is_cancelled() |
|
| 659 | + { |
|
| 660 | + return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
| 661 | + } |
|
| 662 | + |
|
| 663 | + |
|
| 664 | + /** |
|
| 665 | + * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
| 666 | + * |
|
| 667 | + * @return boolean |
|
| 668 | + */ |
|
| 669 | + public function is_declined() |
|
| 670 | + { |
|
| 671 | + return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
| 672 | + } |
|
| 673 | + |
|
| 674 | + |
|
| 675 | + /** |
|
| 676 | + * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
| 677 | + * EEM_Registration::status_id_incomplete |
|
| 678 | + * |
|
| 679 | + * @return boolean |
|
| 680 | + */ |
|
| 681 | + public function is_incomplete() |
|
| 682 | + { |
|
| 683 | + return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
| 684 | + } |
|
| 685 | + |
|
| 686 | + |
|
| 687 | + /** |
|
| 688 | + * Set Registration Date |
|
| 689 | + * |
|
| 690 | + * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
| 691 | + * Date |
|
| 692 | + * @throws EE_Error |
|
| 693 | + * @throws RuntimeException |
|
| 694 | + */ |
|
| 695 | + public function set_reg_date($REG_date = false) |
|
| 696 | + { |
|
| 697 | + $this->set('REG_date', $REG_date); |
|
| 698 | + } |
|
| 699 | + |
|
| 700 | + |
|
| 701 | + /** |
|
| 702 | + * Set final price owing for this registration after all ticket/price modifications |
|
| 703 | + * |
|
| 704 | + * @access public |
|
| 705 | + * @param float $REG_final_price |
|
| 706 | + * @throws EE_Error |
|
| 707 | + * @throws RuntimeException |
|
| 708 | + */ |
|
| 709 | + public function set_final_price($REG_final_price = 0.00) |
|
| 710 | + { |
|
| 711 | + $this->set('REG_final_price', $REG_final_price); |
|
| 712 | + } |
|
| 713 | + |
|
| 714 | + |
|
| 715 | + /** |
|
| 716 | + * Set amount paid towards this registration's final price |
|
| 717 | + * |
|
| 718 | + * @access public |
|
| 719 | + * @param float $REG_paid |
|
| 720 | + * @throws EE_Error |
|
| 721 | + * @throws RuntimeException |
|
| 722 | + */ |
|
| 723 | + public function set_paid($REG_paid = 0.00) |
|
| 724 | + { |
|
| 725 | + $this->set('REG_paid', $REG_paid); |
|
| 726 | + } |
|
| 727 | + |
|
| 728 | + |
|
| 729 | + /** |
|
| 730 | + * Attendee Is Going |
|
| 731 | + * |
|
| 732 | + * @param boolean $REG_att_is_going Attendee Is Going |
|
| 733 | + * @throws EE_Error |
|
| 734 | + * @throws RuntimeException |
|
| 735 | + */ |
|
| 736 | + public function set_att_is_going($REG_att_is_going = false) |
|
| 737 | + { |
|
| 738 | + $this->set('REG_att_is_going', $REG_att_is_going); |
|
| 739 | + } |
|
| 740 | + |
|
| 741 | + |
|
| 742 | + /** |
|
| 743 | + * Gets the related attendee |
|
| 744 | + * |
|
| 745 | + * @return EE_Attendee |
|
| 746 | + * @throws EE_Error |
|
| 747 | + */ |
|
| 748 | + public function attendee() |
|
| 749 | + { |
|
| 750 | + return $this->get_first_related('Attendee'); |
|
| 751 | + } |
|
| 752 | + |
|
| 753 | + /** |
|
| 754 | + * Gets the name of the attendee. |
|
| 755 | + * @since $VID:$ |
|
| 756 | + * @param bool $apply_html_entities set to true if you want to use HTML entities. |
|
| 757 | + * @return string |
|
| 758 | + * @throws EE_Error |
|
| 759 | + * @throws InvalidArgumentException |
|
| 760 | + * @throws InvalidDataTypeException |
|
| 761 | + * @throws InvalidInterfaceException |
|
| 762 | + * @throws ReflectionException |
|
| 763 | + */ |
|
| 764 | + public function attendeeName($apply_html_entities = false) |
|
| 765 | + { |
|
| 766 | + $attendee = $this->get_first_related('Attendee'); |
|
| 767 | + if ($attendee instanceof EE_Attendee) { |
|
| 768 | + $attendee_name = $attendee->full_name($apply_html_entities); |
|
| 769 | + } else { |
|
| 770 | + $attendee_name = esc_html__('Unknown', 'event_espresso'); |
|
| 771 | + } |
|
| 772 | + return $attendee_name; |
|
| 773 | + } |
|
| 774 | + |
|
| 775 | + |
|
| 776 | + /** |
|
| 777 | + * get Event ID |
|
| 778 | + */ |
|
| 779 | + public function event_ID() |
|
| 780 | + { |
|
| 781 | + return $this->get('EVT_ID'); |
|
| 782 | + } |
|
| 783 | + |
|
| 784 | + |
|
| 785 | + /** |
|
| 786 | + * get Event ID |
|
| 787 | + */ |
|
| 788 | + public function event_name() |
|
| 789 | + { |
|
| 790 | + $event = $this->event_obj(); |
|
| 791 | + if ($event) { |
|
| 792 | + return $event->name(); |
|
| 793 | + } else { |
|
| 794 | + return null; |
|
| 795 | + } |
|
| 796 | + } |
|
| 797 | + |
|
| 798 | + |
|
| 799 | + /** |
|
| 800 | + * Fetches the event this registration is for |
|
| 801 | + * |
|
| 802 | + * @return EE_Event |
|
| 803 | + * @throws EE_Error |
|
| 804 | + */ |
|
| 805 | + public function event_obj() |
|
| 806 | + { |
|
| 807 | + return $this->get_first_related('Event'); |
|
| 808 | + } |
|
| 809 | + |
|
| 810 | + |
|
| 811 | + /** |
|
| 812 | + * get Attendee ID |
|
| 813 | + */ |
|
| 814 | + public function attendee_ID() |
|
| 815 | + { |
|
| 816 | + return $this->get('ATT_ID'); |
|
| 817 | + } |
|
| 818 | + |
|
| 819 | + |
|
| 820 | + /** |
|
| 821 | + * get PHP Session ID |
|
| 822 | + */ |
|
| 823 | + public function session_ID() |
|
| 824 | + { |
|
| 825 | + return $this->get('REG_session'); |
|
| 826 | + } |
|
| 827 | + |
|
| 828 | + |
|
| 829 | + /** |
|
| 830 | + * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
| 831 | + * |
|
| 832 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 833 | + * @return string |
|
| 834 | + */ |
|
| 835 | + public function receipt_url($messenger = 'html') |
|
| 836 | + { |
|
| 837 | + |
|
| 838 | + /** |
|
| 839 | + * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
| 840 | + * already in use on old system. If there is then we just return the standard url for it. |
|
| 841 | + * |
|
| 842 | + * @since 4.5.0 |
|
| 843 | + */ |
|
| 844 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
| 845 | + $has_custom = EEH_Template::locate_template( |
|
| 846 | + $template_relative_path, |
|
| 847 | + array(), |
|
| 848 | + true, |
|
| 849 | + true, |
|
| 850 | + true |
|
| 851 | + ); |
|
| 852 | + |
|
| 853 | + if ($has_custom) { |
|
| 854 | + return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
| 855 | + } |
|
| 856 | + return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
| 857 | + } |
|
| 858 | + |
|
| 859 | + |
|
| 860 | + /** |
|
| 861 | + * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
| 862 | + * |
|
| 863 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
| 864 | + * @return string |
|
| 865 | + * @throws EE_Error |
|
| 866 | + */ |
|
| 867 | + public function invoice_url($messenger = 'html') |
|
| 868 | + { |
|
| 869 | + /** |
|
| 870 | + * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
| 871 | + * already in use on old system. If there is then we just return the standard url for it. |
|
| 872 | + * |
|
| 873 | + * @since 4.5.0 |
|
| 874 | + */ |
|
| 875 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
| 876 | + $has_custom = EEH_Template::locate_template( |
|
| 877 | + $template_relative_path, |
|
| 878 | + array(), |
|
| 879 | + true, |
|
| 880 | + true, |
|
| 881 | + true |
|
| 882 | + ); |
|
| 883 | + |
|
| 884 | + if ($has_custom) { |
|
| 885 | + if ($messenger == 'html') { |
|
| 886 | + return $this->invoice_url('launch'); |
|
| 887 | + } |
|
| 888 | + $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
| 889 | + |
|
| 890 | + $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
| 891 | + if ($messenger == 'html') { |
|
| 892 | + $query_args['html'] = true; |
|
| 893 | + } |
|
| 894 | + return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
| 895 | + } |
|
| 896 | + return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
| 897 | + } |
|
| 898 | + |
|
| 899 | + |
|
| 900 | + /** |
|
| 901 | + * get Registration URL Link |
|
| 902 | + * |
|
| 903 | + * @access public |
|
| 904 | + * @return string |
|
| 905 | + * @throws EE_Error |
|
| 906 | + */ |
|
| 907 | + public function reg_url_link() |
|
| 908 | + { |
|
| 909 | + return (string) $this->get('REG_url_link'); |
|
| 910 | + } |
|
| 911 | + |
|
| 912 | + |
|
| 913 | + /** |
|
| 914 | + * Echoes out invoice_url() |
|
| 915 | + * |
|
| 916 | + * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
| 917 | + * @return void |
|
| 918 | + * @throws EE_Error |
|
| 919 | + */ |
|
| 920 | + public function e_invoice_url($type = 'launch') |
|
| 921 | + { |
|
| 922 | + echo $this->invoice_url($type); |
|
| 923 | + } |
|
| 924 | + |
|
| 925 | + |
|
| 926 | + /** |
|
| 927 | + * Echoes out payment_overview_url |
|
| 928 | + */ |
|
| 929 | + public function e_payment_overview_url() |
|
| 930 | + { |
|
| 931 | + echo $this->payment_overview_url(); |
|
| 932 | + } |
|
| 933 | + |
|
| 934 | + |
|
| 935 | + /** |
|
| 936 | + * Gets the URL for the checkout payment options reg step |
|
| 937 | + * with this registration's REG_url_link added as a query parameter |
|
| 938 | + * |
|
| 939 | + * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
| 940 | + * payment overview url. |
|
| 941 | + * @return string |
|
| 942 | + * @throws InvalidInterfaceException |
|
| 943 | + * @throws InvalidDataTypeException |
|
| 944 | + * @throws EE_Error |
|
| 945 | + * @throws InvalidArgumentException |
|
| 946 | + */ |
|
| 947 | + public function payment_overview_url($clear_session = false) |
|
| 948 | + { |
|
| 949 | + return add_query_arg( |
|
| 950 | + (array) apply_filters( |
|
| 951 | + 'FHEE__EE_Registration__payment_overview_url__query_args', |
|
| 952 | + array( |
|
| 953 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
| 954 | + 'step' => 'payment_options', |
|
| 955 | + 'revisit' => true, |
|
| 956 | + 'clear_session' => (bool) $clear_session, |
|
| 957 | + ), |
|
| 958 | + $this |
|
| 959 | + ), |
|
| 960 | + EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 961 | + ); |
|
| 962 | + } |
|
| 963 | + |
|
| 964 | + |
|
| 965 | + /** |
|
| 966 | + * Gets the URL for the checkout attendee information reg step |
|
| 967 | + * with this registration's REG_url_link added as a query parameter |
|
| 968 | + * |
|
| 969 | + * @return string |
|
| 970 | + * @throws InvalidInterfaceException |
|
| 971 | + * @throws InvalidDataTypeException |
|
| 972 | + * @throws EE_Error |
|
| 973 | + * @throws InvalidArgumentException |
|
| 974 | + */ |
|
| 975 | + public function edit_attendee_information_url() |
|
| 976 | + { |
|
| 977 | + return add_query_arg( |
|
| 978 | + (array) apply_filters( |
|
| 979 | + 'FHEE__EE_Registration__edit_attendee_information_url__query_args', |
|
| 980 | + array( |
|
| 981 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
| 982 | + 'step' => 'attendee_information', |
|
| 983 | + 'revisit' => true, |
|
| 984 | + ), |
|
| 985 | + $this |
|
| 986 | + ), |
|
| 987 | + EE_Registry::instance()->CFG->core->reg_page_url() |
|
| 988 | + ); |
|
| 989 | + } |
|
| 990 | + |
|
| 991 | + |
|
| 992 | + /** |
|
| 993 | + * Simply generates and returns the appropriate admin_url link to edit this registration |
|
| 994 | + * |
|
| 995 | + * @return string |
|
| 996 | + * @throws EE_Error |
|
| 997 | + */ |
|
| 998 | + public function get_admin_edit_url() |
|
| 999 | + { |
|
| 1000 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1001 | + array( |
|
| 1002 | + 'page' => 'espresso_registrations', |
|
| 1003 | + 'action' => 'view_registration', |
|
| 1004 | + '_REG_ID' => $this->ID(), |
|
| 1005 | + ), |
|
| 1006 | + admin_url('admin.php') |
|
| 1007 | + ); |
|
| 1008 | + } |
|
| 1009 | + |
|
| 1010 | + |
|
| 1011 | + /** |
|
| 1012 | + * is_primary_registrant? |
|
| 1013 | + */ |
|
| 1014 | + public function is_primary_registrant() |
|
| 1015 | + { |
|
| 1016 | + return $this->get('REG_count') === 1 ? true : false; |
|
| 1017 | + } |
|
| 1018 | + |
|
| 1019 | + |
|
| 1020 | + /** |
|
| 1021 | + * This returns the primary registration object for this registration group (which may be this object). |
|
| 1022 | + * |
|
| 1023 | + * @return EE_Registration |
|
| 1024 | + * @throws EE_Error |
|
| 1025 | + */ |
|
| 1026 | + public function get_primary_registration() |
|
| 1027 | + { |
|
| 1028 | + if ($this->is_primary_registrant()) { |
|
| 1029 | + return $this; |
|
| 1030 | + } |
|
| 1031 | + |
|
| 1032 | + // k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
| 1033 | + /** @var EE_Registration $primary_registrant */ |
|
| 1034 | + $primary_registrant = EEM_Registration::instance()->get_one( |
|
| 1035 | + array( |
|
| 1036 | + array( |
|
| 1037 | + 'TXN_ID' => $this->transaction_ID(), |
|
| 1038 | + 'REG_count' => 1, |
|
| 1039 | + ), |
|
| 1040 | + ) |
|
| 1041 | + ); |
|
| 1042 | + return $primary_registrant; |
|
| 1043 | + } |
|
| 1044 | + |
|
| 1045 | + |
|
| 1046 | + /** |
|
| 1047 | + * get Attendee Number |
|
| 1048 | + * |
|
| 1049 | + * @access public |
|
| 1050 | + */ |
|
| 1051 | + public function count() |
|
| 1052 | + { |
|
| 1053 | + return $this->get('REG_count'); |
|
| 1054 | + } |
|
| 1055 | + |
|
| 1056 | + |
|
| 1057 | + /** |
|
| 1058 | + * get Group Size |
|
| 1059 | + */ |
|
| 1060 | + public function group_size() |
|
| 1061 | + { |
|
| 1062 | + return $this->get('REG_group_size'); |
|
| 1063 | + } |
|
| 1064 | + |
|
| 1065 | + |
|
| 1066 | + /** |
|
| 1067 | + * get Registration Date |
|
| 1068 | + */ |
|
| 1069 | + public function date() |
|
| 1070 | + { |
|
| 1071 | + return $this->get('REG_date'); |
|
| 1072 | + } |
|
| 1073 | + |
|
| 1074 | + |
|
| 1075 | + /** |
|
| 1076 | + * gets a pretty date |
|
| 1077 | + * |
|
| 1078 | + * @param string $date_format |
|
| 1079 | + * @param string $time_format |
|
| 1080 | + * @return string |
|
| 1081 | + * @throws EE_Error |
|
| 1082 | + */ |
|
| 1083 | + public function pretty_date($date_format = null, $time_format = null) |
|
| 1084 | + { |
|
| 1085 | + return $this->get_datetime('REG_date', $date_format, $time_format); |
|
| 1086 | + } |
|
| 1087 | + |
|
| 1088 | + |
|
| 1089 | + /** |
|
| 1090 | + * final_price |
|
| 1091 | + * the registration's share of the transaction total, so that the |
|
| 1092 | + * sum of all the transaction's REG_final_prices equal the transaction's total |
|
| 1093 | + * |
|
| 1094 | + * @return float |
|
| 1095 | + * @throws EE_Error |
|
| 1096 | + */ |
|
| 1097 | + public function final_price() |
|
| 1098 | + { |
|
| 1099 | + return $this->get('REG_final_price'); |
|
| 1100 | + } |
|
| 1101 | + |
|
| 1102 | + |
|
| 1103 | + /** |
|
| 1104 | + * pretty_final_price |
|
| 1105 | + * final price as formatted string, with correct decimal places and currency symbol |
|
| 1106 | + * |
|
| 1107 | + * @return string |
|
| 1108 | + * @throws EE_Error |
|
| 1109 | + */ |
|
| 1110 | + public function pretty_final_price() |
|
| 1111 | + { |
|
| 1112 | + return $this->get_pretty('REG_final_price'); |
|
| 1113 | + } |
|
| 1114 | + |
|
| 1115 | + |
|
| 1116 | + /** |
|
| 1117 | + * get paid (yeah) |
|
| 1118 | + * |
|
| 1119 | + * @return float |
|
| 1120 | + * @throws EE_Error |
|
| 1121 | + */ |
|
| 1122 | + public function paid() |
|
| 1123 | + { |
|
| 1124 | + return $this->get('REG_paid'); |
|
| 1125 | + } |
|
| 1126 | + |
|
| 1127 | + |
|
| 1128 | + /** |
|
| 1129 | + * pretty_paid |
|
| 1130 | + * |
|
| 1131 | + * @return float |
|
| 1132 | + * @throws EE_Error |
|
| 1133 | + */ |
|
| 1134 | + public function pretty_paid() |
|
| 1135 | + { |
|
| 1136 | + return $this->get_pretty('REG_paid'); |
|
| 1137 | + } |
|
| 1138 | + |
|
| 1139 | + |
|
| 1140 | + /** |
|
| 1141 | + * owes_monies_and_can_pay |
|
| 1142 | + * whether or not this registration has monies owing and it's' status allows payment |
|
| 1143 | + * |
|
| 1144 | + * @param array $requires_payment |
|
| 1145 | + * @return bool |
|
| 1146 | + * @throws EE_Error |
|
| 1147 | + */ |
|
| 1148 | + public function owes_monies_and_can_pay($requires_payment = array()) |
|
| 1149 | + { |
|
| 1150 | + // these reg statuses require payment (if event is not free) |
|
| 1151 | + $requires_payment = ! empty($requires_payment) |
|
| 1152 | + ? $requires_payment |
|
| 1153 | + : EEM_Registration::reg_statuses_that_allow_payment(); |
|
| 1154 | + if (in_array($this->status_ID(), $requires_payment) && |
|
| 1155 | + $this->final_price() != 0 && |
|
| 1156 | + $this->final_price() != $this->paid() |
|
| 1157 | + ) { |
|
| 1158 | + return true; |
|
| 1159 | + } else { |
|
| 1160 | + return false; |
|
| 1161 | + } |
|
| 1162 | + } |
|
| 1163 | + |
|
| 1164 | + |
|
| 1165 | + /** |
|
| 1166 | + * Prints out the return value of $this->pretty_status() |
|
| 1167 | + * |
|
| 1168 | + * @param bool $show_icons |
|
| 1169 | + * @return void |
|
| 1170 | + * @throws EE_Error |
|
| 1171 | + */ |
|
| 1172 | + public function e_pretty_status($show_icons = false) |
|
| 1173 | + { |
|
| 1174 | + echo $this->pretty_status($show_icons); |
|
| 1175 | + } |
|
| 1176 | + |
|
| 1177 | + |
|
| 1178 | + /** |
|
| 1179 | + * Returns a nice version of the status for displaying to customers |
|
| 1180 | + * |
|
| 1181 | + * @param bool $show_icons |
|
| 1182 | + * @return string |
|
| 1183 | + * @throws EE_Error |
|
| 1184 | + */ |
|
| 1185 | + public function pretty_status($show_icons = false) |
|
| 1186 | + { |
|
| 1187 | + $status = EEM_Status::instance()->localized_status( |
|
| 1188 | + array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
| 1189 | + false, |
|
| 1190 | + 'sentence' |
|
| 1191 | + ); |
|
| 1192 | + $icon = ''; |
|
| 1193 | + switch ($this->status_ID()) { |
|
| 1194 | + case EEM_Registration::status_id_approved: |
|
| 1195 | + $icon = $show_icons |
|
| 1196 | + ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
| 1197 | + : ''; |
|
| 1198 | + break; |
|
| 1199 | + case EEM_Registration::status_id_pending_payment: |
|
| 1200 | + $icon = $show_icons |
|
| 1201 | + ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
| 1202 | + : ''; |
|
| 1203 | + break; |
|
| 1204 | + case EEM_Registration::status_id_not_approved: |
|
| 1205 | + $icon = $show_icons |
|
| 1206 | + ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
| 1207 | + : ''; |
|
| 1208 | + break; |
|
| 1209 | + case EEM_Registration::status_id_cancelled: |
|
| 1210 | + $icon = $show_icons |
|
| 1211 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
| 1212 | + : ''; |
|
| 1213 | + break; |
|
| 1214 | + case EEM_Registration::status_id_incomplete: |
|
| 1215 | + $icon = $show_icons |
|
| 1216 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
| 1217 | + : ''; |
|
| 1218 | + break; |
|
| 1219 | + case EEM_Registration::status_id_declined: |
|
| 1220 | + $icon = $show_icons |
|
| 1221 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
| 1222 | + : ''; |
|
| 1223 | + break; |
|
| 1224 | + case EEM_Registration::status_id_wait_list: |
|
| 1225 | + $icon = $show_icons |
|
| 1226 | + ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
| 1227 | + : ''; |
|
| 1228 | + break; |
|
| 1229 | + } |
|
| 1230 | + return $icon . $status[ $this->status_ID() ]; |
|
| 1231 | + } |
|
| 1232 | + |
|
| 1233 | + |
|
| 1234 | + /** |
|
| 1235 | + * get Attendee Is Going |
|
| 1236 | + */ |
|
| 1237 | + public function att_is_going() |
|
| 1238 | + { |
|
| 1239 | + return $this->get('REG_att_is_going'); |
|
| 1240 | + } |
|
| 1241 | + |
|
| 1242 | + |
|
| 1243 | + /** |
|
| 1244 | + * Gets related answers |
|
| 1245 | + * |
|
| 1246 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1247 | + * @return EE_Answer[] |
|
| 1248 | + * @throws EE_Error |
|
| 1249 | + */ |
|
| 1250 | + public function answers($query_params = null) |
|
| 1251 | + { |
|
| 1252 | + return $this->get_many_related('Answer', $query_params); |
|
| 1253 | + } |
|
| 1254 | + |
|
| 1255 | + |
|
| 1256 | + /** |
|
| 1257 | + * Gets the registration's answer value to the specified question |
|
| 1258 | + * (either the question's ID or a question object) |
|
| 1259 | + * |
|
| 1260 | + * @param EE_Question|int $question |
|
| 1261 | + * @param bool $pretty_value |
|
| 1262 | + * @return array|string if pretty_value= true, the result will always be a string |
|
| 1263 | + * (because the answer might be an array of answer values, so passing pretty_value=true |
|
| 1264 | + * will convert it into some kind of string) |
|
| 1265 | + * @throws EE_Error |
|
| 1266 | + */ |
|
| 1267 | + public function answer_value_to_question($question, $pretty_value = true) |
|
| 1268 | + { |
|
| 1269 | + $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
| 1270 | + return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
| 1271 | + } |
|
| 1272 | + |
|
| 1273 | + |
|
| 1274 | + /** |
|
| 1275 | + * question_groups |
|
| 1276 | + * returns an array of EE_Question_Group objects for this registration |
|
| 1277 | + * |
|
| 1278 | + * @return EE_Question_Group[] |
|
| 1279 | + * @throws EE_Error |
|
| 1280 | + * @throws InvalidArgumentException |
|
| 1281 | + * @throws InvalidDataTypeException |
|
| 1282 | + * @throws InvalidInterfaceException |
|
| 1283 | + * @throws ReflectionException |
|
| 1284 | + */ |
|
| 1285 | + public function question_groups() |
|
| 1286 | + { |
|
| 1287 | + return EEM_Event::instance()->get_question_groups_for_event($this->event_ID(), $this); |
|
| 1288 | + } |
|
| 1289 | + |
|
| 1290 | + |
|
| 1291 | + /** |
|
| 1292 | + * count_question_groups |
|
| 1293 | + * returns a count of the number of EE_Question_Group objects for this registration |
|
| 1294 | + * |
|
| 1295 | + * @return int |
|
| 1296 | + * @throws EE_Error |
|
| 1297 | + * @throws EntityNotFoundException |
|
| 1298 | + * @throws InvalidArgumentException |
|
| 1299 | + * @throws InvalidDataTypeException |
|
| 1300 | + * @throws InvalidInterfaceException |
|
| 1301 | + * @throws ReflectionException |
|
| 1302 | + */ |
|
| 1303 | + public function count_question_groups() |
|
| 1304 | + { |
|
| 1305 | + return EEM_Event::instance()->count_related( |
|
| 1306 | + $this->event_ID(), |
|
| 1307 | + 'Question_Group', |
|
| 1308 | + [ |
|
| 1309 | + [ |
|
| 1310 | + 'Event_Question_Group.' |
|
| 1311 | + . EEM_Event_Question_Group::instance()->fieldNameForContext($this->is_primary_registrant()) => true, |
|
| 1312 | + ] |
|
| 1313 | + ] |
|
| 1314 | + ); |
|
| 1315 | + } |
|
| 1316 | + |
|
| 1317 | + |
|
| 1318 | + /** |
|
| 1319 | + * Returns the registration date in the 'standard' string format |
|
| 1320 | + * (function may be improved in the future to allow for different formats and timezones) |
|
| 1321 | + * |
|
| 1322 | + * @return string |
|
| 1323 | + * @throws EE_Error |
|
| 1324 | + */ |
|
| 1325 | + public function reg_date() |
|
| 1326 | + { |
|
| 1327 | + return $this->get_datetime('REG_date'); |
|
| 1328 | + } |
|
| 1329 | + |
|
| 1330 | + |
|
| 1331 | + /** |
|
| 1332 | + * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
| 1333 | + * the ticket this registration purchased, or the datetime they have registered |
|
| 1334 | + * to attend) |
|
| 1335 | + * |
|
| 1336 | + * @return EE_Datetime_Ticket |
|
| 1337 | + * @throws EE_Error |
|
| 1338 | + */ |
|
| 1339 | + public function datetime_ticket() |
|
| 1340 | + { |
|
| 1341 | + return $this->get_first_related('Datetime_Ticket'); |
|
| 1342 | + } |
|
| 1343 | + |
|
| 1344 | + |
|
| 1345 | + /** |
|
| 1346 | + * Sets the registration's datetime_ticket. |
|
| 1347 | + * |
|
| 1348 | + * @param EE_Datetime_Ticket $datetime_ticket |
|
| 1349 | + * @return EE_Datetime_Ticket |
|
| 1350 | + * @throws EE_Error |
|
| 1351 | + */ |
|
| 1352 | + public function set_datetime_ticket($datetime_ticket) |
|
| 1353 | + { |
|
| 1354 | + return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
| 1355 | + } |
|
| 1356 | + |
|
| 1357 | + /** |
|
| 1358 | + * Gets deleted |
|
| 1359 | + * |
|
| 1360 | + * @return bool |
|
| 1361 | + * @throws EE_Error |
|
| 1362 | + */ |
|
| 1363 | + public function deleted() |
|
| 1364 | + { |
|
| 1365 | + return $this->get('REG_deleted'); |
|
| 1366 | + } |
|
| 1367 | + |
|
| 1368 | + /** |
|
| 1369 | + * Sets deleted |
|
| 1370 | + * |
|
| 1371 | + * @param boolean $deleted |
|
| 1372 | + * @return bool |
|
| 1373 | + * @throws EE_Error |
|
| 1374 | + * @throws RuntimeException |
|
| 1375 | + */ |
|
| 1376 | + public function set_deleted($deleted) |
|
| 1377 | + { |
|
| 1378 | + if ($deleted) { |
|
| 1379 | + $this->delete(); |
|
| 1380 | + } else { |
|
| 1381 | + $this->restore(); |
|
| 1382 | + } |
|
| 1383 | + } |
|
| 1384 | + |
|
| 1385 | + |
|
| 1386 | + /** |
|
| 1387 | + * Get the status object of this object |
|
| 1388 | + * |
|
| 1389 | + * @return EE_Status |
|
| 1390 | + * @throws EE_Error |
|
| 1391 | + */ |
|
| 1392 | + public function status_obj() |
|
| 1393 | + { |
|
| 1394 | + return $this->get_first_related('Status'); |
|
| 1395 | + } |
|
| 1396 | + |
|
| 1397 | + |
|
| 1398 | + /** |
|
| 1399 | + * Returns the number of times this registration has checked into any of the datetimes |
|
| 1400 | + * its available for |
|
| 1401 | + * |
|
| 1402 | + * @return int |
|
| 1403 | + * @throws EE_Error |
|
| 1404 | + */ |
|
| 1405 | + public function count_checkins() |
|
| 1406 | + { |
|
| 1407 | + return $this->get_model()->count_related($this, 'Checkin'); |
|
| 1408 | + } |
|
| 1409 | + |
|
| 1410 | + |
|
| 1411 | + /** |
|
| 1412 | + * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
| 1413 | + * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
| 1414 | + * |
|
| 1415 | + * @return int |
|
| 1416 | + * @throws EE_Error |
|
| 1417 | + */ |
|
| 1418 | + public function count_checkins_not_checkedout() |
|
| 1419 | + { |
|
| 1420 | + return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
| 1421 | + } |
|
| 1422 | + |
|
| 1423 | + |
|
| 1424 | + /** |
|
| 1425 | + * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
| 1426 | + * |
|
| 1427 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1428 | + * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
| 1429 | + * consider registration status as well as datetime access. |
|
| 1430 | + * @return bool |
|
| 1431 | + * @throws EE_Error |
|
| 1432 | + */ |
|
| 1433 | + public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
| 1434 | + { |
|
| 1435 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1436 | + |
|
| 1437 | + // first check registration status |
|
| 1438 | + if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
| 1439 | + return false; |
|
| 1440 | + } |
|
| 1441 | + // is there a datetime ticket that matches this dtt_ID? |
|
| 1442 | + if (! (EEM_Datetime_Ticket::instance()->exists( |
|
| 1443 | + array( |
|
| 1444 | + array( |
|
| 1445 | + 'TKT_ID' => $this->get('TKT_ID'), |
|
| 1446 | + 'DTT_ID' => $DTT_ID, |
|
| 1447 | + ), |
|
| 1448 | + ) |
|
| 1449 | + )) |
|
| 1450 | + ) { |
|
| 1451 | + return false; |
|
| 1452 | + } |
|
| 1453 | + |
|
| 1454 | + // final check is against TKT_uses |
|
| 1455 | + return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
| 1456 | + } |
|
| 1457 | + |
|
| 1458 | + |
|
| 1459 | + /** |
|
| 1460 | + * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
| 1461 | + * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
| 1462 | + * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
| 1463 | + * then return false. Otherwise return true. |
|
| 1464 | + * |
|
| 1465 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
| 1466 | + * @return bool true means can checkin. false means cannot checkin. |
|
| 1467 | + * @throws EE_Error |
|
| 1468 | + */ |
|
| 1469 | + public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
| 1470 | + { |
|
| 1471 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
| 1472 | + |
|
| 1473 | + if (! $DTT_ID) { |
|
| 1474 | + return false; |
|
| 1475 | + } |
|
| 1476 | + |
|
| 1477 | + $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
| 1478 | + |
|
| 1479 | + // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
| 1480 | + // check-in or not. |
|
| 1481 | + if (! $max_uses || $max_uses === EE_INF) { |
|
| 1482 | + return true; |
|
| 1483 | + } |
|
| 1484 | + |
|
| 1485 | + // does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
| 1486 | + // go ahead and toggle. |
|
| 1487 | + if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
| 1488 | + return true; |
|
| 1489 | + } |
|
| 1490 | + |
|
| 1491 | + // made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
| 1492 | + // disallows further check-ins. |
|
| 1493 | + $count_unique_dtt_checkins = EEM_Checkin::instance()->count( |
|
| 1494 | + array( |
|
| 1495 | + array( |
|
| 1496 | + 'REG_ID' => $this->ID(), |
|
| 1497 | + 'CHK_in' => true, |
|
| 1498 | + ), |
|
| 1499 | + ), |
|
| 1500 | + 'DTT_ID', |
|
| 1501 | + true |
|
| 1502 | + ); |
|
| 1503 | + // checkins have already reached their max number of uses |
|
| 1504 | + // so registrant can NOT checkin |
|
| 1505 | + if ($count_unique_dtt_checkins >= $max_uses) { |
|
| 1506 | + EE_Error::add_error( |
|
| 1507 | + esc_html__( |
|
| 1508 | + 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
| 1509 | + 'event_espresso' |
|
| 1510 | + ), |
|
| 1511 | + __FILE__, |
|
| 1512 | + __FUNCTION__, |
|
| 1513 | + __LINE__ |
|
| 1514 | + ); |
|
| 1515 | + return false; |
|
| 1516 | + } |
|
| 1517 | + return true; |
|
| 1518 | + } |
|
| 1519 | + |
|
| 1520 | + |
|
| 1521 | + /** |
|
| 1522 | + * toggle Check-in status for this registration |
|
| 1523 | + * Check-ins are toggled in the following order: |
|
| 1524 | + * never checked in -> checked in |
|
| 1525 | + * checked in -> checked out |
|
| 1526 | + * checked out -> checked in |
|
| 1527 | + * |
|
| 1528 | + * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
| 1529 | + * If not included or null, then it is assumed latest datetime is being toggled. |
|
| 1530 | + * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
| 1531 | + * can be checked in or not. Otherwise this forces change in checkin status. |
|
| 1532 | + * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
| 1533 | + * @throws EE_Error |
|
| 1534 | + */ |
|
| 1535 | + public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
| 1536 | + { |
|
| 1537 | + if (empty($DTT_ID)) { |
|
| 1538 | + $datetime = $this->get_latest_related_datetime(); |
|
| 1539 | + $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
| 1540 | + // verify the registration can checkin for the given DTT_ID |
|
| 1541 | + } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
| 1542 | + EE_Error::add_error( |
|
| 1543 | + sprintf( |
|
| 1544 | + esc_html__( |
|
| 1545 | + 'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access', |
|
| 1546 | + 'event_espresso' |
|
| 1547 | + ), |
|
| 1548 | + $this->ID(), |
|
| 1549 | + $DTT_ID |
|
| 1550 | + ), |
|
| 1551 | + __FILE__, |
|
| 1552 | + __FUNCTION__, |
|
| 1553 | + __LINE__ |
|
| 1554 | + ); |
|
| 1555 | + return false; |
|
| 1556 | + } |
|
| 1557 | + $status_paths = array( |
|
| 1558 | + EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
| 1559 | + EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
| 1560 | + EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
| 1561 | + ); |
|
| 1562 | + // start by getting the current status so we know what status we'll be changing to. |
|
| 1563 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
| 1564 | + $status_to = $status_paths[ $cur_status ]; |
|
| 1565 | + // database only records true for checked IN or false for checked OUT |
|
| 1566 | + // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
| 1567 | + $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
| 1568 | + // add relation - note Check-ins are always creating new rows |
|
| 1569 | + // because we are keeping track of Check-ins over time. |
|
| 1570 | + // Eventually we'll probably want to show a list table |
|
| 1571 | + // for the individual Check-ins so that they can be managed. |
|
| 1572 | + $checkin = EE_Checkin::new_instance( |
|
| 1573 | + array( |
|
| 1574 | + 'REG_ID' => $this->ID(), |
|
| 1575 | + 'DTT_ID' => $DTT_ID, |
|
| 1576 | + 'CHK_in' => $new_status, |
|
| 1577 | + ) |
|
| 1578 | + ); |
|
| 1579 | + // if the record could not be saved then return false |
|
| 1580 | + if ($checkin->save() === 0) { |
|
| 1581 | + if (WP_DEBUG) { |
|
| 1582 | + global $wpdb; |
|
| 1583 | + $error = sprintf( |
|
| 1584 | + esc_html__( |
|
| 1585 | + 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
| 1586 | + 'event_espresso' |
|
| 1587 | + ), |
|
| 1588 | + '<br />', |
|
| 1589 | + $wpdb->last_error |
|
| 1590 | + ); |
|
| 1591 | + } else { |
|
| 1592 | + $error = esc_html__( |
|
| 1593 | + 'Registration check in update failed because of an unknown database error', |
|
| 1594 | + 'event_espresso' |
|
| 1595 | + ); |
|
| 1596 | + } |
|
| 1597 | + EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
| 1598 | + return false; |
|
| 1599 | + } |
|
| 1600 | + return $status_to; |
|
| 1601 | + } |
|
| 1602 | + |
|
| 1603 | + |
|
| 1604 | + /** |
|
| 1605 | + * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
| 1606 | + * "Latest" is defined by the `DTT_EVT_start` column. |
|
| 1607 | + * |
|
| 1608 | + * @return EE_Datetime|null |
|
| 1609 | + * @throws EE_Error |
|
| 1610 | + */ |
|
| 1611 | + public function get_latest_related_datetime() |
|
| 1612 | + { |
|
| 1613 | + return EEM_Datetime::instance()->get_one( |
|
| 1614 | + array( |
|
| 1615 | + array( |
|
| 1616 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1617 | + ), |
|
| 1618 | + 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
| 1619 | + ) |
|
| 1620 | + ); |
|
| 1621 | + } |
|
| 1622 | + |
|
| 1623 | + |
|
| 1624 | + /** |
|
| 1625 | + * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
| 1626 | + * "Earliest" is defined by the `DTT_EVT_start` column. |
|
| 1627 | + * |
|
| 1628 | + * @throws EE_Error |
|
| 1629 | + */ |
|
| 1630 | + public function get_earliest_related_datetime() |
|
| 1631 | + { |
|
| 1632 | + return EEM_Datetime::instance()->get_one( |
|
| 1633 | + array( |
|
| 1634 | + array( |
|
| 1635 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
| 1636 | + ), |
|
| 1637 | + 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
| 1638 | + ) |
|
| 1639 | + ); |
|
| 1640 | + } |
|
| 1641 | + |
|
| 1642 | + |
|
| 1643 | + /** |
|
| 1644 | + * This method simply returns the check-in status for this registration and the given datetime. |
|
| 1645 | + * If neither the datetime nor the checkin values are provided as arguments, |
|
| 1646 | + * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
| 1647 | + * |
|
| 1648 | + * @param int $DTT_ID The ID of the datetime we're checking against |
|
| 1649 | + * (if empty we'll get the primary datetime for |
|
| 1650 | + * this registration (via event) and use it's ID); |
|
| 1651 | + * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
| 1652 | + * |
|
| 1653 | + * @return int Integer representing Check-in status. |
|
| 1654 | + * @throws EE_Error |
|
| 1655 | + */ |
|
| 1656 | + public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
| 1657 | + { |
|
| 1658 | + $checkin_query_params = array( |
|
| 1659 | + 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
| 1660 | + ); |
|
| 1661 | + |
|
| 1662 | + if ($DTT_ID > 0) { |
|
| 1663 | + $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
| 1664 | + } |
|
| 1665 | + |
|
| 1666 | + // get checkin object (if exists) |
|
| 1667 | + $checkin = $checkin instanceof EE_Checkin |
|
| 1668 | + ? $checkin |
|
| 1669 | + : $this->get_first_related('Checkin', $checkin_query_params); |
|
| 1670 | + if ($checkin instanceof EE_Checkin) { |
|
| 1671 | + if ($checkin->get('CHK_in')) { |
|
| 1672 | + return EE_Checkin::status_checked_in; // checked in |
|
| 1673 | + } |
|
| 1674 | + return EE_Checkin::status_checked_out; // had checked in but is now checked out. |
|
| 1675 | + } |
|
| 1676 | + return EE_Checkin::status_checked_never; // never been checked in |
|
| 1677 | + } |
|
| 1678 | + |
|
| 1679 | + |
|
| 1680 | + /** |
|
| 1681 | + * This method returns a localized message for the toggled Check-in message. |
|
| 1682 | + * |
|
| 1683 | + * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
| 1684 | + * then it is assumed Check-in for primary datetime was toggled. |
|
| 1685 | + * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
| 1686 | + * message can be customized with the attendee name. |
|
| 1687 | + * @return string internationalized message |
|
| 1688 | + * @throws EE_Error |
|
| 1689 | + */ |
|
| 1690 | + public function get_checkin_msg($DTT_ID, $error = false) |
|
| 1691 | + { |
|
| 1692 | + // let's get the attendee first so we can include the name of the attendee |
|
| 1693 | + $attendee = $this->get_first_related('Attendee'); |
|
| 1694 | + if ($attendee instanceof EE_Attendee) { |
|
| 1695 | + if ($error) { |
|
| 1696 | + return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
| 1697 | + } |
|
| 1698 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
| 1699 | + // what is the status message going to be? |
|
| 1700 | + switch ($cur_status) { |
|
| 1701 | + case EE_Checkin::status_checked_never: |
|
| 1702 | + return sprintf( |
|
| 1703 | + __("%s has been removed from Check-in records", "event_espresso"), |
|
| 1704 | + $attendee->full_name() |
|
| 1705 | + ); |
|
| 1706 | + break; |
|
| 1707 | + case EE_Checkin::status_checked_in: |
|
| 1708 | + return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
| 1709 | + break; |
|
| 1710 | + case EE_Checkin::status_checked_out: |
|
| 1711 | + return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
| 1712 | + break; |
|
| 1713 | + } |
|
| 1714 | + } |
|
| 1715 | + return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
| 1716 | + } |
|
| 1717 | + |
|
| 1718 | + |
|
| 1719 | + /** |
|
| 1720 | + * Returns the related EE_Transaction to this registration |
|
| 1721 | + * |
|
| 1722 | + * @return EE_Transaction |
|
| 1723 | + * @throws EE_Error |
|
| 1724 | + * @throws EntityNotFoundException |
|
| 1725 | + */ |
|
| 1726 | + public function transaction() |
|
| 1727 | + { |
|
| 1728 | + $transaction = $this->get_first_related('Transaction'); |
|
| 1729 | + if (! $transaction instanceof \EE_Transaction) { |
|
| 1730 | + throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
| 1731 | + } |
|
| 1732 | + return $transaction; |
|
| 1733 | + } |
|
| 1734 | + |
|
| 1735 | + |
|
| 1736 | + /** |
|
| 1737 | + * get Registration Code |
|
| 1738 | + */ |
|
| 1739 | + public function reg_code() |
|
| 1740 | + { |
|
| 1741 | + return $this->get('REG_code'); |
|
| 1742 | + } |
|
| 1743 | + |
|
| 1744 | + |
|
| 1745 | + /** |
|
| 1746 | + * get Transaction ID |
|
| 1747 | + */ |
|
| 1748 | + public function transaction_ID() |
|
| 1749 | + { |
|
| 1750 | + return $this->get('TXN_ID'); |
|
| 1751 | + } |
|
| 1752 | + |
|
| 1753 | + |
|
| 1754 | + /** |
|
| 1755 | + * @return int |
|
| 1756 | + * @throws EE_Error |
|
| 1757 | + */ |
|
| 1758 | + public function ticket_ID() |
|
| 1759 | + { |
|
| 1760 | + return $this->get('TKT_ID'); |
|
| 1761 | + } |
|
| 1762 | + |
|
| 1763 | + |
|
| 1764 | + /** |
|
| 1765 | + * Set Registration Code |
|
| 1766 | + * |
|
| 1767 | + * @access public |
|
| 1768 | + * @param string $REG_code Registration Code |
|
| 1769 | + * @param boolean $use_default |
|
| 1770 | + * @throws EE_Error |
|
| 1771 | + */ |
|
| 1772 | + public function set_reg_code($REG_code, $use_default = false) |
|
| 1773 | + { |
|
| 1774 | + if (empty($REG_code)) { |
|
| 1775 | + EE_Error::add_error( |
|
| 1776 | + esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
| 1777 | + __FILE__, |
|
| 1778 | + __FUNCTION__, |
|
| 1779 | + __LINE__ |
|
| 1780 | + ); |
|
| 1781 | + return; |
|
| 1782 | + } |
|
| 1783 | + if (! $this->reg_code()) { |
|
| 1784 | + parent::set('REG_code', $REG_code, $use_default); |
|
| 1785 | + } else { |
|
| 1786 | + EE_Error::doing_it_wrong( |
|
| 1787 | + __CLASS__ . '::' . __FUNCTION__, |
|
| 1788 | + esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
| 1789 | + '4.6.0' |
|
| 1790 | + ); |
|
| 1791 | + } |
|
| 1792 | + } |
|
| 1793 | + |
|
| 1794 | + |
|
| 1795 | + /** |
|
| 1796 | + * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
| 1797 | + * Note, if you want to just get all registrations in the same transaction (group), use: |
|
| 1798 | + * $registration->transaction()->registrations(); |
|
| 1799 | + * |
|
| 1800 | + * @since 4.5.0 |
|
| 1801 | + * @return EE_Registration[] or empty array if this isn't a group registration. |
|
| 1802 | + * @throws EE_Error |
|
| 1803 | + */ |
|
| 1804 | + public function get_all_other_registrations_in_group() |
|
| 1805 | + { |
|
| 1806 | + if ($this->group_size() < 2) { |
|
| 1807 | + return array(); |
|
| 1808 | + } |
|
| 1809 | + |
|
| 1810 | + $query[0] = array( |
|
| 1811 | + 'TXN_ID' => $this->transaction_ID(), |
|
| 1812 | + 'REG_ID' => array('!=', $this->ID()), |
|
| 1813 | + 'TKT_ID' => $this->ticket_ID(), |
|
| 1814 | + ); |
|
| 1815 | + /** @var EE_Registration[] $registrations */ |
|
| 1816 | + $registrations = $this->get_model()->get_all($query); |
|
| 1817 | + return $registrations; |
|
| 1818 | + } |
|
| 1819 | + |
|
| 1820 | + /** |
|
| 1821 | + * Return the link to the admin details for the object. |
|
| 1822 | + * |
|
| 1823 | + * @return string |
|
| 1824 | + * @throws EE_Error |
|
| 1825 | + */ |
|
| 1826 | + public function get_admin_details_link() |
|
| 1827 | + { |
|
| 1828 | + EE_Registry::instance()->load_helper('URL'); |
|
| 1829 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1830 | + array( |
|
| 1831 | + 'page' => 'espresso_registrations', |
|
| 1832 | + 'action' => 'view_registration', |
|
| 1833 | + '_REG_ID' => $this->ID(), |
|
| 1834 | + ), |
|
| 1835 | + admin_url('admin.php') |
|
| 1836 | + ); |
|
| 1837 | + } |
|
| 1838 | + |
|
| 1839 | + /** |
|
| 1840 | + * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
| 1841 | + * |
|
| 1842 | + * @return string |
|
| 1843 | + * @throws EE_Error |
|
| 1844 | + */ |
|
| 1845 | + public function get_admin_edit_link() |
|
| 1846 | + { |
|
| 1847 | + return $this->get_admin_details_link(); |
|
| 1848 | + } |
|
| 1849 | + |
|
| 1850 | + /** |
|
| 1851 | + * Returns the link to a settings page for the object. |
|
| 1852 | + * |
|
| 1853 | + * @return string |
|
| 1854 | + * @throws EE_Error |
|
| 1855 | + */ |
|
| 1856 | + public function get_admin_settings_link() |
|
| 1857 | + { |
|
| 1858 | + return $this->get_admin_details_link(); |
|
| 1859 | + } |
|
| 1860 | + |
|
| 1861 | + /** |
|
| 1862 | + * Returns the link to the "overview" for the object (typically the "list table" view). |
|
| 1863 | + * |
|
| 1864 | + * @return string |
|
| 1865 | + */ |
|
| 1866 | + public function get_admin_overview_link() |
|
| 1867 | + { |
|
| 1868 | + EE_Registry::instance()->load_helper('URL'); |
|
| 1869 | + return EEH_URL::add_query_args_and_nonce( |
|
| 1870 | + array( |
|
| 1871 | + 'page' => 'espresso_registrations', |
|
| 1872 | + ), |
|
| 1873 | + admin_url('admin.php') |
|
| 1874 | + ); |
|
| 1875 | + } |
|
| 1876 | + |
|
| 1877 | + |
|
| 1878 | + /** |
|
| 1879 | + * @param array $query_params |
|
| 1880 | + * |
|
| 1881 | + * @return \EE_Registration[] |
|
| 1882 | + * @throws EE_Error |
|
| 1883 | + */ |
|
| 1884 | + public function payments($query_params = array()) |
|
| 1885 | + { |
|
| 1886 | + return $this->get_many_related('Payment', $query_params); |
|
| 1887 | + } |
|
| 1888 | + |
|
| 1889 | + |
|
| 1890 | + /** |
|
| 1891 | + * @param array $query_params |
|
| 1892 | + * |
|
| 1893 | + * @return \EE_Registration_Payment[] |
|
| 1894 | + * @throws EE_Error |
|
| 1895 | + */ |
|
| 1896 | + public function registration_payments($query_params = array()) |
|
| 1897 | + { |
|
| 1898 | + return $this->get_many_related('Registration_Payment', $query_params); |
|
| 1899 | + } |
|
| 1900 | + |
|
| 1901 | + |
|
| 1902 | + /** |
|
| 1903 | + * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
| 1904 | + * Note: if there are no payments on the registration there will be no payment method returned. |
|
| 1905 | + * |
|
| 1906 | + * @return EE_Payment_Method|null |
|
| 1907 | + */ |
|
| 1908 | + public function payment_method() |
|
| 1909 | + { |
|
| 1910 | + return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
| 1911 | + } |
|
| 1912 | + |
|
| 1913 | + |
|
| 1914 | + /** |
|
| 1915 | + * @return \EE_Line_Item |
|
| 1916 | + * @throws EntityNotFoundException |
|
| 1917 | + * @throws EE_Error |
|
| 1918 | + */ |
|
| 1919 | + public function ticket_line_item() |
|
| 1920 | + { |
|
| 1921 | + $ticket = $this->ticket(); |
|
| 1922 | + $transaction = $this->transaction(); |
|
| 1923 | + $line_item = null; |
|
| 1924 | + $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
| 1925 | + $transaction->total_line_item(), |
|
| 1926 | + 'Ticket', |
|
| 1927 | + array($ticket->ID()) |
|
| 1928 | + ); |
|
| 1929 | + foreach ($ticket_line_items as $ticket_line_item) { |
|
| 1930 | + if ($ticket_line_item instanceof \EE_Line_Item |
|
| 1931 | + && $ticket_line_item->OBJ_type() === 'Ticket' |
|
| 1932 | + && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
| 1933 | + ) { |
|
| 1934 | + $line_item = $ticket_line_item; |
|
| 1935 | + break; |
|
| 1936 | + } |
|
| 1937 | + } |
|
| 1938 | + if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
| 1939 | + throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
| 1940 | + } |
|
| 1941 | + return $line_item; |
|
| 1942 | + } |
|
| 1943 | + |
|
| 1944 | + |
|
| 1945 | + /** |
|
| 1946 | + * Soft Deletes this model object. |
|
| 1947 | + * |
|
| 1948 | + * @return boolean | int |
|
| 1949 | + * @throws RuntimeException |
|
| 1950 | + * @throws EE_Error |
|
| 1951 | + */ |
|
| 1952 | + public function delete() |
|
| 1953 | + { |
|
| 1954 | + if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
| 1955 | + $this->set_status(EEM_Registration::status_id_cancelled); |
|
| 1956 | + } |
|
| 1957 | + return parent::delete(); |
|
| 1958 | + } |
|
| 1959 | + |
|
| 1960 | + |
|
| 1961 | + /** |
|
| 1962 | + * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
| 1963 | + * |
|
| 1964 | + * @throws EE_Error |
|
| 1965 | + * @throws RuntimeException |
|
| 1966 | + */ |
|
| 1967 | + public function restore() |
|
| 1968 | + { |
|
| 1969 | + $previous_status = $this->get_extra_meta( |
|
| 1970 | + EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
| 1971 | + true, |
|
| 1972 | + EEM_Registration::status_id_cancelled |
|
| 1973 | + ); |
|
| 1974 | + if ($previous_status) { |
|
| 1975 | + $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
| 1976 | + $this->set_status($previous_status); |
|
| 1977 | + } |
|
| 1978 | + return parent::restore(); |
|
| 1979 | + } |
|
| 1980 | + |
|
| 1981 | + |
|
| 1982 | + /** |
|
| 1983 | + * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price |
|
| 1984 | + * |
|
| 1985 | + * @param boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic |
|
| 1986 | + * depending on whether the reg status changes to or from "Approved" |
|
| 1987 | + * @return boolean whether the Registration status was updated |
|
| 1988 | + * @throws EE_Error |
|
| 1989 | + * @throws RuntimeException |
|
| 1990 | + */ |
|
| 1991 | + public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true) |
|
| 1992 | + { |
|
| 1993 | + $paid = $this->paid(); |
|
| 1994 | + $price = $this->final_price(); |
|
| 1995 | + switch (true) { |
|
| 1996 | + // overpaid or paid |
|
| 1997 | + case EEH_Money::compare_floats($paid, $price, '>'): |
|
| 1998 | + case EEH_Money::compare_floats($paid, $price): |
|
| 1999 | + $new_status = EEM_Registration::status_id_approved; |
|
| 2000 | + break; |
|
| 2001 | + // underpaid |
|
| 2002 | + case EEH_Money::compare_floats($paid, $price, '<'): |
|
| 2003 | + $new_status = EEM_Registration::status_id_pending_payment; |
|
| 2004 | + break; |
|
| 2005 | + // uhhh Houston... |
|
| 2006 | + default: |
|
| 2007 | + throw new RuntimeException( |
|
| 2008 | + esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso') |
|
| 2009 | + ); |
|
| 2010 | + } |
|
| 2011 | + if ($new_status !== $this->status_ID()) { |
|
| 2012 | + if ($trigger_set_status_logic) { |
|
| 2013 | + return $this->set_status($new_status); |
|
| 2014 | + } |
|
| 2015 | + parent::set('STS_ID', $new_status); |
|
| 2016 | + return true; |
|
| 2017 | + } |
|
| 2018 | + return false; |
|
| 2019 | + } |
|
| 2020 | + |
|
| 2021 | + |
|
| 2022 | + /*************************** DEPRECATED ***************************/ |
|
| 2023 | + |
|
| 2024 | + |
|
| 2025 | + /** |
|
| 2026 | + * @deprecated |
|
| 2027 | + * @since 4.7.0 |
|
| 2028 | + * @access public |
|
| 2029 | + */ |
|
| 2030 | + public function price_paid() |
|
| 2031 | + { |
|
| 2032 | + EE_Error::doing_it_wrong( |
|
| 2033 | + 'EE_Registration::price_paid()', |
|
| 2034 | + esc_html__( |
|
| 2035 | + 'This method is deprecated, please use EE_Registration::final_price() instead.', |
|
| 2036 | + 'event_espresso' |
|
| 2037 | + ), |
|
| 2038 | + '4.7.0' |
|
| 2039 | + ); |
|
| 2040 | + return $this->final_price(); |
|
| 2041 | + } |
|
| 2042 | + |
|
| 2043 | + |
|
| 2044 | + /** |
|
| 2045 | + * @deprecated |
|
| 2046 | + * @since 4.7.0 |
|
| 2047 | + * @access public |
|
| 2048 | + * @param float $REG_final_price |
|
| 2049 | + * @throws EE_Error |
|
| 2050 | + * @throws RuntimeException |
|
| 2051 | + */ |
|
| 2052 | + public function set_price_paid($REG_final_price = 0.00) |
|
| 2053 | + { |
|
| 2054 | + EE_Error::doing_it_wrong( |
|
| 2055 | + 'EE_Registration::set_price_paid()', |
|
| 2056 | + esc_html__( |
|
| 2057 | + 'This method is deprecated, please use EE_Registration::set_final_price() instead.', |
|
| 2058 | + 'event_espresso' |
|
| 2059 | + ), |
|
| 2060 | + '4.7.0' |
|
| 2061 | + ); |
|
| 2062 | + $this->set_final_price($REG_final_price); |
|
| 2063 | + } |
|
| 2064 | + |
|
| 2065 | + |
|
| 2066 | + /** |
|
| 2067 | + * @deprecated |
|
| 2068 | + * @since 4.7.0 |
|
| 2069 | + * @return string |
|
| 2070 | + * @throws EE_Error |
|
| 2071 | + */ |
|
| 2072 | + public function pretty_price_paid() |
|
| 2073 | + { |
|
| 2074 | + EE_Error::doing_it_wrong( |
|
| 2075 | + 'EE_Registration::pretty_price_paid()', |
|
| 2076 | + esc_html__( |
|
| 2077 | + 'This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
| 2078 | + 'event_espresso' |
|
| 2079 | + ), |
|
| 2080 | + '4.7.0' |
|
| 2081 | + ); |
|
| 2082 | + return $this->pretty_final_price(); |
|
| 2083 | + } |
|
| 2084 | + |
|
| 2085 | + |
|
| 2086 | + /** |
|
| 2087 | + * Gets the primary datetime related to this registration via the related Event to this registration |
|
| 2088 | + * |
|
| 2089 | + * @deprecated 4.9.17 |
|
| 2090 | + * @return EE_Datetime |
|
| 2091 | + * @throws EE_Error |
|
| 2092 | + * @throws EntityNotFoundException |
|
| 2093 | + */ |
|
| 2094 | + public function get_related_primary_datetime() |
|
| 2095 | + { |
|
| 2096 | + EE_Error::doing_it_wrong( |
|
| 2097 | + __METHOD__, |
|
| 2098 | + esc_html__( |
|
| 2099 | + 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
| 2100 | + 'event_espresso' |
|
| 2101 | + ), |
|
| 2102 | + '4.9.17', |
|
| 2103 | + '5.0.0' |
|
| 2104 | + ); |
|
| 2105 | + return $this->event()->primary_datetime(); |
|
| 2106 | + } |
|
| 2107 | + |
|
| 2108 | + public function name() |
|
| 2109 | + { |
|
| 2110 | + $attendee = $this->attendee(); |
|
| 2111 | + if ($attendee instanceof EE_Attendee) { |
|
| 2112 | + $attendee_name = $attendee->full_name(); |
|
| 2113 | + } else { |
|
| 2114 | + $attendee_name = esc_html__('Unknown', 'event_espresso'); |
|
| 2115 | + } |
|
| 2116 | + return esc_html( |
|
| 2117 | + sprintf( |
|
| 2118 | + // translators: 1: registration code, 2: number, 3: group size, 4: attendee name. |
|
| 2119 | + __('Registration with code "%1$s", %2$d of %3$d for %4$s', 'event_espresso'), |
|
| 2120 | + $this->reg_code(), |
|
| 2121 | + $this->count(), |
|
| 2122 | + $this->group_size(), |
|
| 2123 | + $attendee_name |
|
| 2124 | + ) |
|
| 2125 | + ); |
|
| 2126 | + } |
|
| 2127 | 2127 | } |
@@ -15,1796 +15,1796 @@ |
||
| 15 | 15 | class EED_Single_Page_Checkout extends EED_Module |
| 16 | 16 | { |
| 17 | 17 | |
| 18 | - /** |
|
| 19 | - * $_initialized - has the SPCO controller already been initialized ? |
|
| 20 | - * |
|
| 21 | - * @access private |
|
| 22 | - * @var bool $_initialized |
|
| 23 | - */ |
|
| 24 | - private static $_initialized = false; |
|
| 25 | - |
|
| 26 | - |
|
| 27 | - /** |
|
| 28 | - * $_checkout_verified - is the EE_Checkout verified as correct for this request ? |
|
| 29 | - * |
|
| 30 | - * @access private |
|
| 31 | - * @var bool $_valid_checkout |
|
| 32 | - */ |
|
| 33 | - private static $_checkout_verified = true; |
|
| 34 | - |
|
| 35 | - /** |
|
| 36 | - * $_reg_steps_array - holds initial array of reg steps |
|
| 37 | - * |
|
| 38 | - * @access private |
|
| 39 | - * @var array $_reg_steps_array |
|
| 40 | - */ |
|
| 41 | - private static $_reg_steps_array = array(); |
|
| 42 | - |
|
| 43 | - /** |
|
| 44 | - * $checkout - EE_Checkout object for handling the properties of the current checkout process |
|
| 45 | - * |
|
| 46 | - * @access public |
|
| 47 | - * @var EE_Checkout $checkout |
|
| 48 | - */ |
|
| 49 | - public $checkout; |
|
| 50 | - |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * @return EED_Module|EED_Single_Page_Checkout |
|
| 54 | - */ |
|
| 55 | - public static function instance() |
|
| 56 | - { |
|
| 57 | - add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true'); |
|
| 58 | - return parent::get_instance(__CLASS__); |
|
| 59 | - } |
|
| 60 | - |
|
| 61 | - |
|
| 62 | - /** |
|
| 63 | - * @return EE_CART |
|
| 64 | - */ |
|
| 65 | - public function cart() |
|
| 66 | - { |
|
| 67 | - return $this->checkout->cart; |
|
| 68 | - } |
|
| 69 | - |
|
| 70 | - |
|
| 71 | - /** |
|
| 72 | - * @return EE_Transaction |
|
| 73 | - */ |
|
| 74 | - public function transaction() |
|
| 75 | - { |
|
| 76 | - return $this->checkout->transaction; |
|
| 77 | - } |
|
| 78 | - |
|
| 79 | - |
|
| 80 | - /** |
|
| 81 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
| 82 | - * |
|
| 83 | - * @access public |
|
| 84 | - * @return void |
|
| 85 | - * @throws EE_Error |
|
| 86 | - */ |
|
| 87 | - public static function set_hooks() |
|
| 88 | - { |
|
| 89 | - EED_Single_Page_Checkout::set_definitions(); |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - |
|
| 93 | - /** |
|
| 94 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
| 95 | - * |
|
| 96 | - * @access public |
|
| 97 | - * @return void |
|
| 98 | - * @throws EE_Error |
|
| 99 | - */ |
|
| 100 | - public static function set_hooks_admin() |
|
| 101 | - { |
|
| 102 | - EED_Single_Page_Checkout::set_definitions(); |
|
| 103 | - if (! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
| 104 | - return; |
|
| 105 | - } |
|
| 106 | - // going to start an output buffer in case anything gets accidentally output |
|
| 107 | - // that might disrupt our JSON response |
|
| 108 | - ob_start(); |
|
| 109 | - EED_Single_Page_Checkout::load_request_handler(); |
|
| 110 | - EED_Single_Page_Checkout::load_reg_steps(); |
|
| 111 | - // set ajax hooks |
|
| 112 | - add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
| 113 | - add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
| 114 | - add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
| 115 | - add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
| 116 | - add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
| 117 | - add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
| 118 | - } |
|
| 119 | - |
|
| 120 | - |
|
| 121 | - /** |
|
| 122 | - * process ajax request |
|
| 123 | - * |
|
| 124 | - * @param string $ajax_action |
|
| 125 | - * @throws EE_Error |
|
| 126 | - */ |
|
| 127 | - public static function process_ajax_request($ajax_action) |
|
| 128 | - { |
|
| 129 | - EE_Registry::instance()->REQ->set('action', $ajax_action); |
|
| 130 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
| 131 | - } |
|
| 132 | - |
|
| 133 | - |
|
| 134 | - /** |
|
| 135 | - * ajax display registration step |
|
| 136 | - * |
|
| 137 | - * @throws EE_Error |
|
| 138 | - */ |
|
| 139 | - public static function display_reg_step() |
|
| 140 | - { |
|
| 141 | - EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step'); |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - |
|
| 145 | - /** |
|
| 146 | - * ajax process registration step |
|
| 147 | - * |
|
| 148 | - * @throws EE_Error |
|
| 149 | - */ |
|
| 150 | - public static function process_reg_step() |
|
| 151 | - { |
|
| 152 | - EED_Single_Page_Checkout::process_ajax_request('process_reg_step'); |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - |
|
| 156 | - /** |
|
| 157 | - * ajax process registration step |
|
| 158 | - * |
|
| 159 | - * @throws EE_Error |
|
| 160 | - */ |
|
| 161 | - public static function update_reg_step() |
|
| 162 | - { |
|
| 163 | - EED_Single_Page_Checkout::process_ajax_request('update_reg_step'); |
|
| 164 | - } |
|
| 165 | - |
|
| 166 | - |
|
| 167 | - /** |
|
| 168 | - * update_checkout |
|
| 169 | - * |
|
| 170 | - * @access public |
|
| 171 | - * @return void |
|
| 172 | - * @throws EE_Error |
|
| 173 | - */ |
|
| 174 | - public static function update_checkout() |
|
| 175 | - { |
|
| 176 | - EED_Single_Page_Checkout::process_ajax_request('update_checkout'); |
|
| 177 | - } |
|
| 178 | - |
|
| 179 | - |
|
| 180 | - /** |
|
| 181 | - * load_request_handler |
|
| 182 | - * |
|
| 183 | - * @access public |
|
| 184 | - * @return void |
|
| 185 | - */ |
|
| 186 | - public static function load_request_handler() |
|
| 187 | - { |
|
| 188 | - // load core Request_Handler class |
|
| 189 | - if (EE_Registry::instance()->REQ !== null) { |
|
| 190 | - EE_Registry::instance()->load_core('Request_Handler'); |
|
| 191 | - } |
|
| 192 | - } |
|
| 193 | - |
|
| 194 | - |
|
| 195 | - /** |
|
| 196 | - * set_definitions |
|
| 197 | - * |
|
| 198 | - * @access public |
|
| 199 | - * @return void |
|
| 200 | - * @throws EE_Error |
|
| 201 | - */ |
|
| 202 | - public static function set_definitions() |
|
| 203 | - { |
|
| 204 | - if (defined('SPCO_BASE_PATH')) { |
|
| 205 | - return; |
|
| 206 | - } |
|
| 207 | - define( |
|
| 208 | - 'SPCO_BASE_PATH', |
|
| 209 | - rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/') . '/' |
|
| 210 | - ); |
|
| 211 | - define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css/'); |
|
| 212 | - define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img/'); |
|
| 213 | - define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js/'); |
|
| 214 | - define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc/'); |
|
| 215 | - define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps/'); |
|
| 216 | - define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates/'); |
|
| 217 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true); |
|
| 218 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
| 219 | - ); |
|
| 220 | - } |
|
| 221 | - |
|
| 222 | - |
|
| 223 | - /** |
|
| 224 | - * load_reg_steps |
|
| 225 | - * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array |
|
| 226 | - * |
|
| 227 | - * @access private |
|
| 228 | - * @throws EE_Error |
|
| 229 | - */ |
|
| 230 | - public static function load_reg_steps() |
|
| 231 | - { |
|
| 232 | - static $reg_steps_loaded = false; |
|
| 233 | - if ($reg_steps_loaded) { |
|
| 234 | - return; |
|
| 235 | - } |
|
| 236 | - // filter list of reg_steps |
|
| 237 | - $reg_steps_to_load = (array) apply_filters( |
|
| 238 | - 'AHEE__SPCO__load_reg_steps__reg_steps_to_load', |
|
| 239 | - EED_Single_Page_Checkout::get_reg_steps() |
|
| 240 | - ); |
|
| 241 | - // sort by key (order) |
|
| 242 | - ksort($reg_steps_to_load); |
|
| 243 | - // loop through folders |
|
| 244 | - foreach ($reg_steps_to_load as $order => $reg_step) { |
|
| 245 | - // we need a |
|
| 246 | - if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
| 247 | - // copy over to the reg_steps_array |
|
| 248 | - EED_Single_Page_Checkout::$_reg_steps_array[ $order ] = $reg_step; |
|
| 249 | - // register custom key route for each reg step |
|
| 250 | - // ie: step=>"slug" - this is the entire reason we load the reg steps array now |
|
| 251 | - EE_Config::register_route( |
|
| 252 | - $reg_step['slug'], |
|
| 253 | - 'EED_Single_Page_Checkout', |
|
| 254 | - 'run', |
|
| 255 | - 'step' |
|
| 256 | - ); |
|
| 257 | - // add AJAX or other hooks |
|
| 258 | - if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) { |
|
| 259 | - // setup autoloaders if necessary |
|
| 260 | - if (! class_exists($reg_step['class_name'])) { |
|
| 261 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder( |
|
| 262 | - $reg_step['file_path'], |
|
| 263 | - true |
|
| 264 | - ); |
|
| 265 | - } |
|
| 266 | - if (is_callable($reg_step['class_name'], 'set_hooks')) { |
|
| 267 | - call_user_func(array($reg_step['class_name'], 'set_hooks')); |
|
| 268 | - } |
|
| 269 | - } |
|
| 270 | - } |
|
| 271 | - } |
|
| 272 | - $reg_steps_loaded = true; |
|
| 273 | - } |
|
| 274 | - |
|
| 275 | - |
|
| 276 | - /** |
|
| 277 | - * get_reg_steps |
|
| 278 | - * |
|
| 279 | - * @access public |
|
| 280 | - * @return array |
|
| 281 | - */ |
|
| 282 | - public static function get_reg_steps() |
|
| 283 | - { |
|
| 284 | - $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps; |
|
| 285 | - if (empty($reg_steps)) { |
|
| 286 | - $reg_steps = array( |
|
| 287 | - 10 => array( |
|
| 288 | - 'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information', |
|
| 289 | - 'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information', |
|
| 290 | - 'slug' => 'attendee_information', |
|
| 291 | - 'has_hooks' => false, |
|
| 292 | - ), |
|
| 293 | - 30 => array( |
|
| 294 | - 'file_path' => SPCO_REG_STEPS_PATH . 'payment_options', |
|
| 295 | - 'class_name' => 'EE_SPCO_Reg_Step_Payment_Options', |
|
| 296 | - 'slug' => 'payment_options', |
|
| 297 | - 'has_hooks' => true, |
|
| 298 | - ), |
|
| 299 | - 999 => array( |
|
| 300 | - 'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration', |
|
| 301 | - 'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration', |
|
| 302 | - 'slug' => 'finalize_registration', |
|
| 303 | - 'has_hooks' => false, |
|
| 304 | - ), |
|
| 305 | - ); |
|
| 306 | - } |
|
| 307 | - return $reg_steps; |
|
| 308 | - } |
|
| 309 | - |
|
| 310 | - |
|
| 311 | - /** |
|
| 312 | - * registration_checkout_for_admin |
|
| 313 | - * |
|
| 314 | - * @access public |
|
| 315 | - * @return string |
|
| 316 | - * @throws EE_Error |
|
| 317 | - */ |
|
| 318 | - public static function registration_checkout_for_admin() |
|
| 319 | - { |
|
| 320 | - EED_Single_Page_Checkout::load_request_handler(); |
|
| 321 | - EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
| 322 | - EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step'); |
|
| 323 | - EE_Registry::instance()->REQ->set('process_form_submission', false); |
|
| 324 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
| 325 | - EED_Single_Page_Checkout::instance()->_display_spco_reg_form(); |
|
| 326 | - return EE_Registry::instance()->REQ->get_output(); |
|
| 327 | - } |
|
| 328 | - |
|
| 329 | - |
|
| 330 | - /** |
|
| 331 | - * process_registration_from_admin |
|
| 332 | - * |
|
| 333 | - * @access public |
|
| 334 | - * @return \EE_Transaction |
|
| 335 | - * @throws EE_Error |
|
| 336 | - */ |
|
| 337 | - public static function process_registration_from_admin() |
|
| 338 | - { |
|
| 339 | - EED_Single_Page_Checkout::load_request_handler(); |
|
| 340 | - EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
| 341 | - EE_Registry::instance()->REQ->set('action', 'process_reg_step'); |
|
| 342 | - EE_Registry::instance()->REQ->set('process_form_submission', true); |
|
| 343 | - EED_Single_Page_Checkout::instance()->_initialize(); |
|
| 344 | - if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) { |
|
| 345 | - $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps); |
|
| 346 | - if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) { |
|
| 347 | - EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step); |
|
| 348 | - if ($final_reg_step->process_reg_step()) { |
|
| 349 | - $final_reg_step->set_completed(); |
|
| 350 | - EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array(); |
|
| 351 | - return EED_Single_Page_Checkout::instance()->checkout->transaction; |
|
| 352 | - } |
|
| 353 | - } |
|
| 354 | - } |
|
| 355 | - return null; |
|
| 356 | - } |
|
| 357 | - |
|
| 358 | - |
|
| 359 | - /** |
|
| 360 | - * run |
|
| 361 | - * |
|
| 362 | - * @access public |
|
| 363 | - * @param WP_Query $WP_Query |
|
| 364 | - * @return void |
|
| 365 | - * @throws EE_Error |
|
| 366 | - */ |
|
| 367 | - public function run($WP_Query) |
|
| 368 | - { |
|
| 369 | - if ($WP_Query instanceof WP_Query |
|
| 370 | - && $WP_Query->is_main_query() |
|
| 371 | - && apply_filters('FHEE__EED_Single_Page_Checkout__run', true) |
|
| 372 | - && $this->_is_reg_checkout() |
|
| 373 | - ) { |
|
| 374 | - $this->_initialize(); |
|
| 375 | - } |
|
| 376 | - } |
|
| 377 | - |
|
| 378 | - |
|
| 379 | - /** |
|
| 380 | - * determines whether current url matches reg page url |
|
| 381 | - * |
|
| 382 | - * @return bool |
|
| 383 | - */ |
|
| 384 | - protected function _is_reg_checkout() |
|
| 385 | - { |
|
| 386 | - // get current permalink for reg page without any extra query args |
|
| 387 | - $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id); |
|
| 388 | - // get request URI for current request, but without the scheme or host |
|
| 389 | - $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI'); |
|
| 390 | - $current_request_uri = html_entity_decode($current_request_uri); |
|
| 391 | - // get array of query args from the current request URI |
|
| 392 | - $query_args = \EEH_URL::get_query_string($current_request_uri); |
|
| 393 | - // grab page id if it is set |
|
| 394 | - $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0; |
|
| 395 | - // and remove the page id from the query args (we will re-add it later) |
|
| 396 | - unset($query_args['page_id']); |
|
| 397 | - // now strip all query args from current request URI |
|
| 398 | - $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri); |
|
| 399 | - // and re-add the page id if it was set |
|
| 400 | - if ($page_id) { |
|
| 401 | - $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri); |
|
| 402 | - } |
|
| 403 | - // remove slashes and ? |
|
| 404 | - $current_request_uri = trim($current_request_uri, '?/'); |
|
| 405 | - // is current request URI part of the known full reg page URL ? |
|
| 406 | - return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false; |
|
| 407 | - } |
|
| 408 | - |
|
| 409 | - |
|
| 410 | - /** |
|
| 411 | - * @param WP_Query $wp_query |
|
| 412 | - * @return void |
|
| 413 | - * @throws EE_Error |
|
| 414 | - */ |
|
| 415 | - public static function init($wp_query) |
|
| 416 | - { |
|
| 417 | - EED_Single_Page_Checkout::instance()->run($wp_query); |
|
| 418 | - } |
|
| 419 | - |
|
| 420 | - |
|
| 421 | - /** |
|
| 422 | - * _initialize - initial module setup |
|
| 423 | - * |
|
| 424 | - * @access private |
|
| 425 | - * @throws EE_Error |
|
| 426 | - * @return void |
|
| 427 | - */ |
|
| 428 | - private function _initialize() |
|
| 429 | - { |
|
| 430 | - // ensure SPCO doesn't run twice |
|
| 431 | - if (EED_Single_Page_Checkout::$_initialized) { |
|
| 432 | - return; |
|
| 433 | - } |
|
| 434 | - try { |
|
| 435 | - EED_Single_Page_Checkout::load_reg_steps(); |
|
| 436 | - $this->_verify_session(); |
|
| 437 | - // setup the EE_Checkout object |
|
| 438 | - $this->checkout = $this->_initialize_checkout(); |
|
| 439 | - // filter checkout |
|
| 440 | - $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout); |
|
| 441 | - // get the $_GET |
|
| 442 | - $this->_get_request_vars(); |
|
| 443 | - if ($this->_block_bots()) { |
|
| 444 | - return; |
|
| 445 | - } |
|
| 446 | - // filter continue_reg |
|
| 447 | - $this->checkout->continue_reg = apply_filters( |
|
| 448 | - 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
| 449 | - true, |
|
| 450 | - $this->checkout |
|
| 451 | - ); |
|
| 452 | - // load the reg steps array |
|
| 453 | - if (! $this->_load_and_instantiate_reg_steps()) { |
|
| 454 | - EED_Single_Page_Checkout::$_initialized = true; |
|
| 455 | - return; |
|
| 456 | - } |
|
| 457 | - // set the current step |
|
| 458 | - $this->checkout->set_current_step($this->checkout->step); |
|
| 459 | - // and the next step |
|
| 460 | - $this->checkout->set_next_step(); |
|
| 461 | - // verify that everything has been setup correctly |
|
| 462 | - if (! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) { |
|
| 463 | - EED_Single_Page_Checkout::$_initialized = true; |
|
| 464 | - return; |
|
| 465 | - } |
|
| 466 | - // lock the transaction |
|
| 467 | - $this->checkout->transaction->lock(); |
|
| 468 | - // make sure all of our cached objects are added to their respective model entity mappers |
|
| 469 | - $this->checkout->refresh_all_entities(); |
|
| 470 | - // set amount owing |
|
| 471 | - $this->checkout->amount_owing = $this->checkout->transaction->remaining(); |
|
| 472 | - // initialize each reg step, which gives them the chance to potentially alter the process |
|
| 473 | - $this->_initialize_reg_steps(); |
|
| 474 | - // DEBUG LOG |
|
| 475 | - // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
| 476 | - // get reg form |
|
| 477 | - if (! $this->_check_form_submission()) { |
|
| 478 | - EED_Single_Page_Checkout::$_initialized = true; |
|
| 479 | - return; |
|
| 480 | - } |
|
| 481 | - // checkout the action!!! |
|
| 482 | - $this->_process_form_action(); |
|
| 483 | - // add some style and make it dance |
|
| 484 | - $this->add_styles_and_scripts($this); |
|
| 485 | - // kk... SPCO has successfully run |
|
| 486 | - EED_Single_Page_Checkout::$_initialized = true; |
|
| 487 | - // set no cache headers and constants |
|
| 488 | - EE_System::do_not_cache(); |
|
| 489 | - // add anchor |
|
| 490 | - add_action('loop_start', array($this, 'set_checkout_anchor'), 1); |
|
| 491 | - // remove transaction lock |
|
| 492 | - add_action('shutdown', array($this, 'unlock_transaction'), 1); |
|
| 493 | - } catch (Exception $e) { |
|
| 494 | - EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
| 495 | - } |
|
| 496 | - } |
|
| 497 | - |
|
| 498 | - |
|
| 499 | - /** |
|
| 500 | - * _verify_session |
|
| 501 | - * checks that the session is valid and not expired |
|
| 502 | - * |
|
| 503 | - * @access private |
|
| 504 | - * @throws EE_Error |
|
| 505 | - */ |
|
| 506 | - private function _verify_session() |
|
| 507 | - { |
|
| 508 | - if (! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
| 509 | - throw new EE_Error(esc_html__('The EE_Session class could not be loaded.', 'event_espresso')); |
|
| 510 | - } |
|
| 511 | - $clear_session_requested = filter_var( |
|
| 512 | - EE_Registry::instance()->REQ->get('clear_session', false), |
|
| 513 | - FILTER_VALIDATE_BOOLEAN |
|
| 514 | - ); |
|
| 515 | - // is session still valid ? |
|
| 516 | - if ($clear_session_requested |
|
| 517 | - || (EE_Registry::instance()->SSN->expired() |
|
| 518 | - && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '' |
|
| 519 | - ) |
|
| 520 | - ) { |
|
| 521 | - $this->checkout = new EE_Checkout(); |
|
| 522 | - EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
| 523 | - // EE_Registry::instance()->SSN->reset_cart(); |
|
| 524 | - // EE_Registry::instance()->SSN->reset_checkout(); |
|
| 525 | - // EE_Registry::instance()->SSN->reset_transaction(); |
|
| 526 | - if (! $clear_session_requested) { |
|
| 527 | - EE_Error::add_attention( |
|
| 528 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'], |
|
| 529 | - __FILE__, |
|
| 530 | - __FUNCTION__, |
|
| 531 | - __LINE__ |
|
| 532 | - ); |
|
| 533 | - } |
|
| 534 | - // EE_Registry::instance()->SSN->reset_expired(); |
|
| 535 | - } |
|
| 536 | - } |
|
| 537 | - |
|
| 538 | - |
|
| 539 | - /** |
|
| 540 | - * _initialize_checkout |
|
| 541 | - * loads and instantiates EE_Checkout |
|
| 542 | - * |
|
| 543 | - * @access private |
|
| 544 | - * @throws EE_Error |
|
| 545 | - * @return EE_Checkout |
|
| 546 | - */ |
|
| 547 | - private function _initialize_checkout() |
|
| 548 | - { |
|
| 549 | - // look in session for existing checkout |
|
| 550 | - /** @type EE_Checkout $checkout */ |
|
| 551 | - $checkout = EE_Registry::instance()->SSN->checkout(); |
|
| 552 | - // verify |
|
| 553 | - if (! $checkout instanceof EE_Checkout) { |
|
| 554 | - // instantiate EE_Checkout object for handling the properties of the current checkout process |
|
| 555 | - $checkout = EE_Registry::instance()->load_file( |
|
| 556 | - SPCO_INC_PATH, |
|
| 557 | - 'EE_Checkout', |
|
| 558 | - 'class', |
|
| 559 | - array(), |
|
| 560 | - false |
|
| 561 | - ); |
|
| 562 | - } else { |
|
| 563 | - if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) { |
|
| 564 | - $this->unlock_transaction(); |
|
| 565 | - wp_safe_redirect($checkout->redirect_url); |
|
| 566 | - exit(); |
|
| 567 | - } |
|
| 568 | - } |
|
| 569 | - $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout); |
|
| 570 | - // verify again |
|
| 571 | - if (! $checkout instanceof EE_Checkout) { |
|
| 572 | - throw new EE_Error(esc_html__('The EE_Checkout class could not be loaded.', 'event_espresso')); |
|
| 573 | - } |
|
| 574 | - // reset anything that needs a clean slate for each request |
|
| 575 | - $checkout->reset_for_current_request(); |
|
| 576 | - return $checkout; |
|
| 577 | - } |
|
| 578 | - |
|
| 579 | - |
|
| 580 | - /** |
|
| 581 | - * _get_request_vars |
|
| 582 | - * |
|
| 583 | - * @access private |
|
| 584 | - * @return void |
|
| 585 | - * @throws EE_Error |
|
| 586 | - */ |
|
| 587 | - private function _get_request_vars() |
|
| 588 | - { |
|
| 589 | - // load classes |
|
| 590 | - EED_Single_Page_Checkout::load_request_handler(); |
|
| 591 | - // make sure this request is marked as belonging to EE |
|
| 592 | - EE_Registry::instance()->REQ->set_espresso_page(true); |
|
| 593 | - // which step is being requested ? |
|
| 594 | - $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step()); |
|
| 595 | - // which step is being edited ? |
|
| 596 | - $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', ''); |
|
| 597 | - // and what we're doing on the current step |
|
| 598 | - $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step'); |
|
| 599 | - // timestamp |
|
| 600 | - $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0); |
|
| 601 | - // returning to edit ? |
|
| 602 | - $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', ''); |
|
| 603 | - // add reg url link to registration query params |
|
| 604 | - if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) { |
|
| 605 | - $this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link; |
|
| 606 | - } |
|
| 607 | - // or some other kind of revisit ? |
|
| 608 | - $this->checkout->revisit = filter_var( |
|
| 609 | - EE_Registry::instance()->REQ->get('revisit', false), |
|
| 610 | - FILTER_VALIDATE_BOOLEAN |
|
| 611 | - ); |
|
| 612 | - // and whether or not to generate a reg form for this request |
|
| 613 | - $this->checkout->generate_reg_form = filter_var( |
|
| 614 | - EE_Registry::instance()->REQ->get('generate_reg_form', true), |
|
| 615 | - FILTER_VALIDATE_BOOLEAN |
|
| 616 | - ); |
|
| 617 | - // and whether or not to process a reg form submission for this request |
|
| 618 | - $this->checkout->process_form_submission = filter_var( |
|
| 619 | - EE_Registry::instance()->REQ->get( |
|
| 620 | - 'process_form_submission', |
|
| 621 | - $this->checkout->action === 'process_reg_step' |
|
| 622 | - ), |
|
| 623 | - FILTER_VALIDATE_BOOLEAN |
|
| 624 | - ); |
|
| 625 | - $this->checkout->process_form_submission = filter_var( |
|
| 626 | - $this->checkout->action !== 'display_spco_reg_step' |
|
| 627 | - ? $this->checkout->process_form_submission |
|
| 628 | - : false, |
|
| 629 | - FILTER_VALIDATE_BOOLEAN |
|
| 630 | - ); |
|
| 631 | - // $this->_display_request_vars(); |
|
| 632 | - } |
|
| 633 | - |
|
| 634 | - |
|
| 635 | - /** |
|
| 636 | - * _display_request_vars |
|
| 637 | - * |
|
| 638 | - * @access protected |
|
| 639 | - * @return void |
|
| 640 | - */ |
|
| 641 | - protected function _display_request_vars() |
|
| 642 | - { |
|
| 643 | - if (! WP_DEBUG) { |
|
| 644 | - return; |
|
| 645 | - } |
|
| 646 | - EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__); |
|
| 647 | - EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__); |
|
| 648 | - EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__); |
|
| 649 | - EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__); |
|
| 650 | - EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__); |
|
| 651 | - EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__); |
|
| 652 | - EEH_Debug_Tools::printr( |
|
| 653 | - $this->checkout->generate_reg_form, |
|
| 654 | - '$this->checkout->generate_reg_form', |
|
| 655 | - __FILE__, |
|
| 656 | - __LINE__ |
|
| 657 | - ); |
|
| 658 | - EEH_Debug_Tools::printr( |
|
| 659 | - $this->checkout->process_form_submission, |
|
| 660 | - '$this->checkout->process_form_submission', |
|
| 661 | - __FILE__, |
|
| 662 | - __LINE__ |
|
| 663 | - ); |
|
| 664 | - } |
|
| 665 | - |
|
| 666 | - |
|
| 667 | - /** |
|
| 668 | - * _block_bots |
|
| 669 | - * checks that the incoming request has either of the following set: |
|
| 670 | - * a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector |
|
| 671 | - * a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN |
|
| 672 | - * so if you're not coming from the Ticket Selector nor returning for a valid IP... |
|
| 673 | - * then where you coming from man? |
|
| 674 | - * |
|
| 675 | - * @return boolean |
|
| 676 | - */ |
|
| 677 | - private function _block_bots() |
|
| 678 | - { |
|
| 679 | - $invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
| 680 | - if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) { |
|
| 681 | - return true; |
|
| 682 | - } |
|
| 683 | - return false; |
|
| 684 | - } |
|
| 685 | - |
|
| 686 | - |
|
| 687 | - /** |
|
| 688 | - * _get_first_step |
|
| 689 | - * gets slug for first step in $_reg_steps_array |
|
| 690 | - * |
|
| 691 | - * @access private |
|
| 692 | - * @throws EE_Error |
|
| 693 | - * @return string |
|
| 694 | - */ |
|
| 695 | - private function _get_first_step() |
|
| 696 | - { |
|
| 697 | - $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array); |
|
| 698 | - return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information'; |
|
| 699 | - } |
|
| 700 | - |
|
| 701 | - |
|
| 702 | - /** |
|
| 703 | - * instantiates each reg step based on the loaded reg_steps array |
|
| 704 | - * |
|
| 705 | - * @return bool |
|
| 706 | - * @throws EE_Error |
|
| 707 | - * @throws InvalidArgumentException |
|
| 708 | - * @throws InvalidDataTypeException |
|
| 709 | - * @throws InvalidInterfaceException |
|
| 710 | - */ |
|
| 711 | - private function _load_and_instantiate_reg_steps() |
|
| 712 | - { |
|
| 713 | - do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout); |
|
| 714 | - // have reg_steps already been instantiated ? |
|
| 715 | - if (empty($this->checkout->reg_steps) |
|
| 716 | - || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout) |
|
| 717 | - ) { |
|
| 718 | - // if not, then loop through raw reg steps array |
|
| 719 | - foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) { |
|
| 720 | - if (! $this->_load_and_instantiate_reg_step($reg_step, $order)) { |
|
| 721 | - return false; |
|
| 722 | - } |
|
| 723 | - } |
|
| 724 | - if (isset($this->checkout->reg_steps['registration_confirmation'])) { |
|
| 725 | - // skip the registration_confirmation page ? |
|
| 726 | - if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) { |
|
| 727 | - // just remove it from the reg steps array |
|
| 728 | - $this->checkout->remove_reg_step('registration_confirmation', false); |
|
| 729 | - } elseif (EE_Registry::instance()->CFG->registration->reg_confirmation_last |
|
| 730 | - ) { |
|
| 731 | - // set the order to something big like 100 |
|
| 732 | - $this->checkout->set_reg_step_order('registration_confirmation', 100); |
|
| 733 | - } |
|
| 734 | - } |
|
| 735 | - // filter the array for good luck |
|
| 736 | - $this->checkout->reg_steps = apply_filters( |
|
| 737 | - 'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps', |
|
| 738 | - $this->checkout->reg_steps |
|
| 739 | - ); |
|
| 740 | - // finally re-sort based on the reg step class order properties |
|
| 741 | - $this->checkout->sort_reg_steps(); |
|
| 742 | - } else { |
|
| 743 | - foreach ($this->checkout->reg_steps as $reg_step) { |
|
| 744 | - // set all current step stati to FALSE |
|
| 745 | - $reg_step->set_is_current_step(false); |
|
| 746 | - } |
|
| 747 | - } |
|
| 748 | - if (empty($this->checkout->reg_steps)) { |
|
| 749 | - EE_Error::add_error( |
|
| 750 | - esc_html__('No Reg Steps were loaded..', 'event_espresso'), |
|
| 751 | - __FILE__, |
|
| 752 | - __FUNCTION__, |
|
| 753 | - __LINE__ |
|
| 754 | - ); |
|
| 755 | - return false; |
|
| 756 | - } |
|
| 757 | - // make reg step details available to JS |
|
| 758 | - $this->checkout->set_reg_step_JSON_info(); |
|
| 759 | - return true; |
|
| 760 | - } |
|
| 761 | - |
|
| 762 | - |
|
| 763 | - /** |
|
| 764 | - * _load_and_instantiate_reg_step |
|
| 765 | - * |
|
| 766 | - * @access private |
|
| 767 | - * @param array $reg_step |
|
| 768 | - * @param int $order |
|
| 769 | - * @return bool |
|
| 770 | - */ |
|
| 771 | - private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0) |
|
| 772 | - { |
|
| 773 | - // we need a file_path, class_name, and slug to add a reg step |
|
| 774 | - if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
| 775 | - // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step) |
|
| 776 | - if ($this->checkout->reg_url_link |
|
| 777 | - && $this->checkout->step !== $reg_step['slug'] |
|
| 778 | - && $reg_step['slug'] !== 'finalize_registration' |
|
| 779 | - // normally at this point we would NOT load the reg step, but this filter can change that |
|
| 780 | - && apply_filters( |
|
| 781 | - 'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step', |
|
| 782 | - true, |
|
| 783 | - $reg_step, |
|
| 784 | - $this->checkout |
|
| 785 | - ) |
|
| 786 | - ) { |
|
| 787 | - return true; |
|
| 788 | - } |
|
| 789 | - // instantiate step class using file path and class name |
|
| 790 | - $reg_step_obj = EE_Registry::instance()->load_file( |
|
| 791 | - $reg_step['file_path'], |
|
| 792 | - $reg_step['class_name'], |
|
| 793 | - 'class', |
|
| 794 | - $this->checkout, |
|
| 795 | - false |
|
| 796 | - ); |
|
| 797 | - // did we gets the goods ? |
|
| 798 | - if ($reg_step_obj instanceof EE_SPCO_Reg_Step) { |
|
| 799 | - // set reg step order based on config |
|
| 800 | - $reg_step_obj->set_order($order); |
|
| 801 | - // add instantiated reg step object to the master reg steps array |
|
| 802 | - $this->checkout->add_reg_step($reg_step_obj); |
|
| 803 | - } else { |
|
| 804 | - EE_Error::add_error( |
|
| 805 | - esc_html__('The current step could not be set.', 'event_espresso'), |
|
| 806 | - __FILE__, |
|
| 807 | - __FUNCTION__, |
|
| 808 | - __LINE__ |
|
| 809 | - ); |
|
| 810 | - return false; |
|
| 811 | - } |
|
| 812 | - } else { |
|
| 813 | - if (WP_DEBUG) { |
|
| 814 | - EE_Error::add_error( |
|
| 815 | - sprintf( |
|
| 816 | - esc_html__( |
|
| 817 | - 'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s', |
|
| 818 | - 'event_espresso' |
|
| 819 | - ), |
|
| 820 | - isset($reg_step['file_path']) ? $reg_step['file_path'] : '', |
|
| 821 | - isset($reg_step['class_name']) ? $reg_step['class_name'] : '', |
|
| 822 | - isset($reg_step['slug']) ? $reg_step['slug'] : '', |
|
| 823 | - '<ul>', |
|
| 824 | - '<li>', |
|
| 825 | - '</li>', |
|
| 826 | - '</ul>' |
|
| 827 | - ), |
|
| 828 | - __FILE__, |
|
| 829 | - __FUNCTION__, |
|
| 830 | - __LINE__ |
|
| 831 | - ); |
|
| 832 | - } |
|
| 833 | - return false; |
|
| 834 | - } |
|
| 835 | - return true; |
|
| 836 | - } |
|
| 837 | - |
|
| 838 | - |
|
| 839 | - /** |
|
| 840 | - * _verify_transaction_and_get_registrations |
|
| 841 | - * |
|
| 842 | - * @access private |
|
| 843 | - * @return bool |
|
| 844 | - * @throws InvalidDataTypeException |
|
| 845 | - * @throws InvalidEntityException |
|
| 846 | - * @throws EE_Error |
|
| 847 | - */ |
|
| 848 | - private function _verify_transaction_and_get_registrations() |
|
| 849 | - { |
|
| 850 | - // was there already a valid transaction in the checkout from the session ? |
|
| 851 | - if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
| 852 | - // get transaction from db or session |
|
| 853 | - $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin() |
|
| 854 | - ? $this->_get_transaction_and_cart_for_previous_visit() |
|
| 855 | - : $this->_get_cart_for_current_session_and_setup_new_transaction(); |
|
| 856 | - if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
| 857 | - EE_Error::add_error( |
|
| 858 | - esc_html__( |
|
| 859 | - 'Your Registration and Transaction information could not be retrieved from the db.', |
|
| 860 | - 'event_espresso' |
|
| 861 | - ), |
|
| 862 | - __FILE__, |
|
| 863 | - __FUNCTION__, |
|
| 864 | - __LINE__ |
|
| 865 | - ); |
|
| 866 | - $this->checkout->transaction = EE_Transaction::new_instance(); |
|
| 867 | - // add some style and make it dance |
|
| 868 | - $this->add_styles_and_scripts($this); |
|
| 869 | - EED_Single_Page_Checkout::$_initialized = true; |
|
| 870 | - return false; |
|
| 871 | - } |
|
| 872 | - // and the registrations for the transaction |
|
| 873 | - $this->_get_registrations($this->checkout->transaction); |
|
| 874 | - } |
|
| 875 | - return true; |
|
| 876 | - } |
|
| 877 | - |
|
| 878 | - |
|
| 879 | - /** |
|
| 880 | - * _get_transaction_and_cart_for_previous_visit |
|
| 881 | - * |
|
| 882 | - * @access private |
|
| 883 | - * @return mixed EE_Transaction|NULL |
|
| 884 | - */ |
|
| 885 | - private function _get_transaction_and_cart_for_previous_visit() |
|
| 886 | - { |
|
| 887 | - /** @var $TXN_model EEM_Transaction */ |
|
| 888 | - $TXN_model = EE_Registry::instance()->load_model('Transaction'); |
|
| 889 | - // because the reg_url_link is present in the request, |
|
| 890 | - // this is a return visit to SPCO, so we'll get the transaction data from the db |
|
| 891 | - $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link); |
|
| 892 | - // verify transaction |
|
| 893 | - if ($transaction instanceof EE_Transaction) { |
|
| 894 | - // and get the cart that was used for that transaction |
|
| 895 | - $this->checkout->cart = $this->_get_cart_for_transaction($transaction); |
|
| 896 | - return $transaction; |
|
| 897 | - } |
|
| 898 | - EE_Error::add_error( |
|
| 899 | - esc_html__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), |
|
| 900 | - __FILE__, |
|
| 901 | - __FUNCTION__, |
|
| 902 | - __LINE__ |
|
| 903 | - ); |
|
| 904 | - return null; |
|
| 905 | - } |
|
| 906 | - |
|
| 907 | - |
|
| 908 | - /** |
|
| 909 | - * _get_cart_for_transaction |
|
| 910 | - * |
|
| 911 | - * @access private |
|
| 912 | - * @param EE_Transaction $transaction |
|
| 913 | - * @return EE_Cart |
|
| 914 | - */ |
|
| 915 | - private function _get_cart_for_transaction($transaction) |
|
| 916 | - { |
|
| 917 | - return $this->checkout->get_cart_for_transaction($transaction); |
|
| 918 | - } |
|
| 919 | - |
|
| 920 | - |
|
| 921 | - /** |
|
| 922 | - * get_cart_for_transaction |
|
| 923 | - * |
|
| 924 | - * @access public |
|
| 925 | - * @param EE_Transaction $transaction |
|
| 926 | - * @return EE_Cart |
|
| 927 | - */ |
|
| 928 | - public function get_cart_for_transaction(EE_Transaction $transaction) |
|
| 929 | - { |
|
| 930 | - return $this->checkout->get_cart_for_transaction($transaction); |
|
| 931 | - } |
|
| 932 | - |
|
| 933 | - |
|
| 934 | - /** |
|
| 935 | - * _get_transaction_and_cart_for_current_session |
|
| 936 | - * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
| 937 | - * |
|
| 938 | - * @access private |
|
| 939 | - * @return EE_Transaction |
|
| 940 | - * @throws EE_Error |
|
| 941 | - */ |
|
| 942 | - private function _get_cart_for_current_session_and_setup_new_transaction() |
|
| 943 | - { |
|
| 944 | - // if there's no transaction, then this is the FIRST visit to SPCO |
|
| 945 | - // so load up the cart ( passing nothing for the TXN because it doesn't exist yet ) |
|
| 946 | - $this->checkout->cart = $this->_get_cart_for_transaction(null); |
|
| 947 | - // and then create a new transaction |
|
| 948 | - $transaction = $this->_initialize_transaction(); |
|
| 949 | - // verify transaction |
|
| 950 | - if ($transaction instanceof EE_Transaction) { |
|
| 951 | - // save it so that we have an ID for other objects to use |
|
| 952 | - $transaction->save(); |
|
| 953 | - // and save TXN data to the cart |
|
| 954 | - $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID()); |
|
| 955 | - } else { |
|
| 956 | - EE_Error::add_error( |
|
| 957 | - esc_html__('A Valid Transaction could not be initialized.', 'event_espresso'), |
|
| 958 | - __FILE__, |
|
| 959 | - __FUNCTION__, |
|
| 960 | - __LINE__ |
|
| 961 | - ); |
|
| 962 | - } |
|
| 963 | - return $transaction; |
|
| 964 | - } |
|
| 965 | - |
|
| 966 | - |
|
| 967 | - /** |
|
| 968 | - * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
| 969 | - * |
|
| 970 | - * @access private |
|
| 971 | - * @return mixed EE_Transaction|NULL |
|
| 972 | - */ |
|
| 973 | - private function _initialize_transaction() |
|
| 974 | - { |
|
| 975 | - try { |
|
| 976 | - // ensure cart totals have been calculated |
|
| 977 | - $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes(); |
|
| 978 | - // grab the cart grand total |
|
| 979 | - $cart_total = $this->checkout->cart->get_cart_grand_total(); |
|
| 980 | - // create new TXN |
|
| 981 | - $transaction = EE_Transaction::new_instance( |
|
| 982 | - array( |
|
| 983 | - 'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(), |
|
| 984 | - 'TXN_total' => $cart_total > 0 ? $cart_total : 0, |
|
| 985 | - 'TXN_paid' => 0, |
|
| 986 | - 'STS_ID' => EEM_Transaction::failed_status_code, |
|
| 987 | - ) |
|
| 988 | - ); |
|
| 989 | - // save it so that we have an ID for other objects to use |
|
| 990 | - $transaction->save(); |
|
| 991 | - // set cron job for following up on TXNs after their session has expired |
|
| 992 | - EE_Cron_Tasks::schedule_expired_transaction_check( |
|
| 993 | - EE_Registry::instance()->SSN->expiration() + 1, |
|
| 994 | - $transaction->ID() |
|
| 995 | - ); |
|
| 996 | - return $transaction; |
|
| 997 | - } catch (Exception $e) { |
|
| 998 | - EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
| 999 | - } |
|
| 1000 | - return null; |
|
| 1001 | - } |
|
| 1002 | - |
|
| 1003 | - |
|
| 1004 | - /** |
|
| 1005 | - * _get_registrations |
|
| 1006 | - * |
|
| 1007 | - * @access private |
|
| 1008 | - * @param EE_Transaction $transaction |
|
| 1009 | - * @return void |
|
| 1010 | - * @throws InvalidDataTypeException |
|
| 1011 | - * @throws InvalidEntityException |
|
| 1012 | - * @throws EE_Error |
|
| 1013 | - */ |
|
| 1014 | - private function _get_registrations(EE_Transaction $transaction) |
|
| 1015 | - { |
|
| 1016 | - // first step: grab the registrants { : o |
|
| 1017 | - $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
| 1018 | - $this->checkout->total_ticket_count = count($registrations); |
|
| 1019 | - // verify registrations have been set |
|
| 1020 | - if (empty($registrations)) { |
|
| 1021 | - // if no cached registrations, then check the db |
|
| 1022 | - $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
| 1023 | - // still nothing ? well as long as this isn't a revisit |
|
| 1024 | - if (empty($registrations) && ! $this->checkout->revisit) { |
|
| 1025 | - // generate new registrations from scratch |
|
| 1026 | - $registrations = $this->_initialize_registrations($transaction); |
|
| 1027 | - } |
|
| 1028 | - } |
|
| 1029 | - // sort by their original registration order |
|
| 1030 | - usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count')); |
|
| 1031 | - // then loop thru the array |
|
| 1032 | - foreach ($registrations as $registration) { |
|
| 1033 | - // verify each registration |
|
| 1034 | - if ($registration instanceof EE_Registration) { |
|
| 1035 | - // we display all attendee info for the primary registrant |
|
| 1036 | - if ($this->checkout->reg_url_link === $registration->reg_url_link() |
|
| 1037 | - && $registration->is_primary_registrant() |
|
| 1038 | - ) { |
|
| 1039 | - $this->checkout->primary_revisit = true; |
|
| 1040 | - break; |
|
| 1041 | - } |
|
| 1042 | - if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) { |
|
| 1043 | - // but hide info if it doesn't belong to you |
|
| 1044 | - $transaction->clear_cache('Registration', $registration->ID()); |
|
| 1045 | - $this->checkout->total_ticket_count--; |
|
| 1046 | - } |
|
| 1047 | - $this->checkout->set_reg_status_updated($registration->ID(), false); |
|
| 1048 | - } |
|
| 1049 | - } |
|
| 1050 | - } |
|
| 1051 | - |
|
| 1052 | - |
|
| 1053 | - /** |
|
| 1054 | - * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object |
|
| 1055 | - * |
|
| 1056 | - * @access private |
|
| 1057 | - * @param EE_Transaction $transaction |
|
| 1058 | - * @return array |
|
| 1059 | - * @throws InvalidDataTypeException |
|
| 1060 | - * @throws InvalidEntityException |
|
| 1061 | - * @throws EE_Error |
|
| 1062 | - */ |
|
| 1063 | - private function _initialize_registrations(EE_Transaction $transaction) |
|
| 1064 | - { |
|
| 1065 | - $att_nmbr = 0; |
|
| 1066 | - $registrations = array(); |
|
| 1067 | - if ($transaction instanceof EE_Transaction) { |
|
| 1068 | - /** @type EE_Registration_Processor $registration_processor */ |
|
| 1069 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 1070 | - $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count(); |
|
| 1071 | - // now let's add the cart items to the $transaction |
|
| 1072 | - foreach ($this->checkout->cart->get_tickets() as $line_item) { |
|
| 1073 | - // do the following for each ticket of this type they selected |
|
| 1074 | - for ($x = 1; $x <= $line_item->quantity(); $x++) { |
|
| 1075 | - $att_nmbr++; |
|
| 1076 | - /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */ |
|
| 1077 | - $CreateRegistrationCommand = EE_Registry::instance()->create( |
|
| 1078 | - 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand', |
|
| 1079 | - array( |
|
| 1080 | - $transaction, |
|
| 1081 | - $line_item, |
|
| 1082 | - $att_nmbr, |
|
| 1083 | - $this->checkout->total_ticket_count, |
|
| 1084 | - ) |
|
| 1085 | - ); |
|
| 1086 | - // override capabilities for frontend registrations |
|
| 1087 | - if (! is_admin()) { |
|
| 1088 | - $CreateRegistrationCommand->setCapCheck( |
|
| 1089 | - new PublicCapabilities('', 'create_new_registration') |
|
| 1090 | - ); |
|
| 1091 | - } |
|
| 1092 | - $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand); |
|
| 1093 | - if (! $registration instanceof EE_Registration) { |
|
| 1094 | - throw new InvalidEntityException($registration, 'EE_Registration'); |
|
| 1095 | - } |
|
| 1096 | - $registrations[ $registration->ID() ] = $registration; |
|
| 1097 | - } |
|
| 1098 | - } |
|
| 1099 | - $registration_processor->fix_reg_final_price_rounding_issue($transaction); |
|
| 1100 | - } |
|
| 1101 | - return $registrations; |
|
| 1102 | - } |
|
| 1103 | - |
|
| 1104 | - |
|
| 1105 | - /** |
|
| 1106 | - * sorts registrations by REG_count |
|
| 1107 | - * |
|
| 1108 | - * @access public |
|
| 1109 | - * @param EE_Registration $reg_A |
|
| 1110 | - * @param EE_Registration $reg_B |
|
| 1111 | - * @return int |
|
| 1112 | - */ |
|
| 1113 | - public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B) |
|
| 1114 | - { |
|
| 1115 | - // this shouldn't ever happen within the same TXN, but oh well |
|
| 1116 | - if ($reg_A->count() === $reg_B->count()) { |
|
| 1117 | - return 0; |
|
| 1118 | - } |
|
| 1119 | - return ($reg_A->count() > $reg_B->count()) ? 1 : -1; |
|
| 1120 | - } |
|
| 1121 | - |
|
| 1122 | - |
|
| 1123 | - /** |
|
| 1124 | - * _final_verifications |
|
| 1125 | - * just makes sure that everything is set up correctly before proceeding |
|
| 1126 | - * |
|
| 1127 | - * @access private |
|
| 1128 | - * @return bool |
|
| 1129 | - * @throws EE_Error |
|
| 1130 | - */ |
|
| 1131 | - private function _final_verifications() |
|
| 1132 | - { |
|
| 1133 | - // filter checkout |
|
| 1134 | - $this->checkout = apply_filters( |
|
| 1135 | - 'FHEE__EED_Single_Page_Checkout___final_verifications__checkout', |
|
| 1136 | - $this->checkout |
|
| 1137 | - ); |
|
| 1138 | - // verify that current step is still set correctly |
|
| 1139 | - if (! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) { |
|
| 1140 | - EE_Error::add_error( |
|
| 1141 | - esc_html__( |
|
| 1142 | - 'We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', |
|
| 1143 | - 'event_espresso' |
|
| 1144 | - ), |
|
| 1145 | - __FILE__, |
|
| 1146 | - __FUNCTION__, |
|
| 1147 | - __LINE__ |
|
| 1148 | - ); |
|
| 1149 | - return false; |
|
| 1150 | - } |
|
| 1151 | - // if returning to SPCO, then verify that primary registrant is set |
|
| 1152 | - if (! empty($this->checkout->reg_url_link)) { |
|
| 1153 | - $valid_registrant = $this->checkout->transaction->primary_registration(); |
|
| 1154 | - if (! $valid_registrant instanceof EE_Registration) { |
|
| 1155 | - EE_Error::add_error( |
|
| 1156 | - esc_html__( |
|
| 1157 | - 'We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', |
|
| 1158 | - 'event_espresso' |
|
| 1159 | - ), |
|
| 1160 | - __FILE__, |
|
| 1161 | - __FUNCTION__, |
|
| 1162 | - __LINE__ |
|
| 1163 | - ); |
|
| 1164 | - return false; |
|
| 1165 | - } |
|
| 1166 | - $valid_registrant = null; |
|
| 1167 | - foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) { |
|
| 1168 | - if ($registration instanceof EE_Registration |
|
| 1169 | - && $registration->reg_url_link() === $this->checkout->reg_url_link |
|
| 1170 | - ) { |
|
| 1171 | - $valid_registrant = $registration; |
|
| 1172 | - } |
|
| 1173 | - } |
|
| 1174 | - if (! $valid_registrant instanceof EE_Registration) { |
|
| 1175 | - // hmmm... maybe we have the wrong session because the user is opening multiple tabs ? |
|
| 1176 | - if (EED_Single_Page_Checkout::$_checkout_verified) { |
|
| 1177 | - // clear the session, mark the checkout as unverified, and try again |
|
| 1178 | - EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
| 1179 | - EED_Single_Page_Checkout::$_initialized = false; |
|
| 1180 | - EED_Single_Page_Checkout::$_checkout_verified = false; |
|
| 1181 | - $this->_initialize(); |
|
| 1182 | - EE_Error::reset_notices(); |
|
| 1183 | - return false; |
|
| 1184 | - } |
|
| 1185 | - EE_Error::add_error( |
|
| 1186 | - esc_html__( |
|
| 1187 | - 'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.', |
|
| 1188 | - 'event_espresso' |
|
| 1189 | - ), |
|
| 1190 | - __FILE__, |
|
| 1191 | - __FUNCTION__, |
|
| 1192 | - __LINE__ |
|
| 1193 | - ); |
|
| 1194 | - return false; |
|
| 1195 | - } |
|
| 1196 | - } |
|
| 1197 | - // now that things have been kinda sufficiently verified, |
|
| 1198 | - // let's add the checkout to the session so that it's available to other systems |
|
| 1199 | - EE_Registry::instance()->SSN->set_checkout($this->checkout); |
|
| 1200 | - return true; |
|
| 1201 | - } |
|
| 1202 | - |
|
| 1203 | - |
|
| 1204 | - /** |
|
| 1205 | - * _initialize_reg_steps |
|
| 1206 | - * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required |
|
| 1207 | - * then loops thru all of the active reg steps and calls the initialize_reg_step() method |
|
| 1208 | - * |
|
| 1209 | - * @access private |
|
| 1210 | - * @param bool $reinitializing |
|
| 1211 | - * @throws EE_Error |
|
| 1212 | - */ |
|
| 1213 | - private function _initialize_reg_steps($reinitializing = false) |
|
| 1214 | - { |
|
| 1215 | - $this->checkout->set_reg_step_initiated($this->checkout->current_step); |
|
| 1216 | - // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS |
|
| 1217 | - foreach ($this->checkout->reg_steps as $reg_step) { |
|
| 1218 | - if (! $reg_step->initialize_reg_step()) { |
|
| 1219 | - // if not initialized then maybe this step is being removed... |
|
| 1220 | - if (! $reinitializing && $reg_step->is_current_step()) { |
|
| 1221 | - // if it was the current step, then we need to start over here |
|
| 1222 | - $this->_initialize_reg_steps(true); |
|
| 1223 | - return; |
|
| 1224 | - } |
|
| 1225 | - continue; |
|
| 1226 | - } |
|
| 1227 | - // add css and JS for current step |
|
| 1228 | - $this->add_styles_and_scripts($reg_step); |
|
| 1229 | - if ($reg_step->is_current_step()) { |
|
| 1230 | - // the text that appears on the reg step form submit button |
|
| 1231 | - $reg_step->set_submit_button_text(); |
|
| 1232 | - } |
|
| 1233 | - } |
|
| 1234 | - // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information |
|
| 1235 | - do_action( |
|
| 1236 | - "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", |
|
| 1237 | - $this->checkout->current_step |
|
| 1238 | - ); |
|
| 1239 | - } |
|
| 1240 | - |
|
| 1241 | - |
|
| 1242 | - /** |
|
| 1243 | - * _check_form_submission |
|
| 1244 | - * |
|
| 1245 | - * @access private |
|
| 1246 | - * @return boolean |
|
| 1247 | - */ |
|
| 1248 | - private function _check_form_submission() |
|
| 1249 | - { |
|
| 1250 | - // does this request require the reg form to be generated ? |
|
| 1251 | - if ($this->checkout->generate_reg_form) { |
|
| 1252 | - // ever heard that song by Blue Rodeo ? |
|
| 1253 | - try { |
|
| 1254 | - $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form(); |
|
| 1255 | - // if not displaying a form, then check for form submission |
|
| 1256 | - if ($this->checkout->process_form_submission |
|
| 1257 | - && $this->checkout->current_step->reg_form->was_submitted() |
|
| 1258 | - ) { |
|
| 1259 | - // clear out any old data in case this step is being run again |
|
| 1260 | - $this->checkout->current_step->set_valid_data(array()); |
|
| 1261 | - // capture submitted form data |
|
| 1262 | - $this->checkout->current_step->reg_form->receive_form_submission( |
|
| 1263 | - apply_filters( |
|
| 1264 | - 'FHEE__Single_Page_Checkout___check_form_submission__request_params', |
|
| 1265 | - EE_Registry::instance()->REQ->params(), |
|
| 1266 | - $this->checkout |
|
| 1267 | - ) |
|
| 1268 | - ); |
|
| 1269 | - // validate submitted form data |
|
| 1270 | - if (! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) { |
|
| 1271 | - // thou shall not pass !!! |
|
| 1272 | - $this->checkout->continue_reg = false; |
|
| 1273 | - // any form validation errors? |
|
| 1274 | - if ($this->checkout->current_step->reg_form->submission_error_message() !== '') { |
|
| 1275 | - EE_Error::add_error( |
|
| 1276 | - $this->checkout->current_step->reg_form->submission_error_message(), |
|
| 1277 | - __FILE__, |
|
| 1278 | - __FUNCTION__, |
|
| 1279 | - __LINE__ |
|
| 1280 | - ); |
|
| 1281 | - } |
|
| 1282 | - // well not really... what will happen is |
|
| 1283 | - // we'll just get redirected back to redo the current step |
|
| 1284 | - $this->go_to_next_step(); |
|
| 1285 | - return false; |
|
| 1286 | - } |
|
| 1287 | - } |
|
| 1288 | - } catch (EE_Error $e) { |
|
| 1289 | - $e->get_error(); |
|
| 1290 | - } |
|
| 1291 | - } |
|
| 1292 | - return true; |
|
| 1293 | - } |
|
| 1294 | - |
|
| 1295 | - |
|
| 1296 | - /** |
|
| 1297 | - * _process_action |
|
| 1298 | - * |
|
| 1299 | - * @access private |
|
| 1300 | - * @return void |
|
| 1301 | - * @throws EE_Error |
|
| 1302 | - */ |
|
| 1303 | - private function _process_form_action() |
|
| 1304 | - { |
|
| 1305 | - // what cha wanna do? |
|
| 1306 | - switch ($this->checkout->action) { |
|
| 1307 | - // AJAX next step reg form |
|
| 1308 | - case 'display_spco_reg_step': |
|
| 1309 | - $this->checkout->redirect = false; |
|
| 1310 | - if (EE_Registry::instance()->REQ->ajax) { |
|
| 1311 | - $this->checkout->json_response->set_reg_step_html( |
|
| 1312 | - $this->checkout->current_step->display_reg_form() |
|
| 1313 | - ); |
|
| 1314 | - } |
|
| 1315 | - break; |
|
| 1316 | - default: |
|
| 1317 | - // meh... do one of those other steps first |
|
| 1318 | - if (! empty($this->checkout->action) |
|
| 1319 | - && is_callable(array($this->checkout->current_step, $this->checkout->action)) |
|
| 1320 | - ) { |
|
| 1321 | - // dynamically creates hook point like: |
|
| 1322 | - // AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step |
|
| 1323 | - do_action( |
|
| 1324 | - "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
| 1325 | - $this->checkout->current_step |
|
| 1326 | - ); |
|
| 1327 | - // call action on current step |
|
| 1328 | - if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) { |
|
| 1329 | - // good registrant, you get to proceed |
|
| 1330 | - if ($this->checkout->current_step->success_message() !== '' |
|
| 1331 | - && apply_filters( |
|
| 1332 | - 'FHEE__Single_Page_Checkout___process_form_action__display_success', |
|
| 1333 | - false |
|
| 1334 | - ) |
|
| 1335 | - ) { |
|
| 1336 | - EE_Error::add_success( |
|
| 1337 | - $this->checkout->current_step->success_message() |
|
| 1338 | - . '<br />' . $this->checkout->next_step->_instructions() |
|
| 1339 | - ); |
|
| 1340 | - } |
|
| 1341 | - // pack it up, pack it in... |
|
| 1342 | - $this->_setup_redirect(); |
|
| 1343 | - } |
|
| 1344 | - // dynamically creates hook point like: |
|
| 1345 | - // AHEE__Single_Page_Checkout__after_payment_options__process_reg_step |
|
| 1346 | - do_action( |
|
| 1347 | - "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
| 1348 | - $this->checkout->current_step |
|
| 1349 | - ); |
|
| 1350 | - } else { |
|
| 1351 | - EE_Error::add_error( |
|
| 1352 | - sprintf( |
|
| 1353 | - esc_html__( |
|
| 1354 | - 'The requested form action "%s" does not exist for the current "%s" registration step.', |
|
| 1355 | - 'event_espresso' |
|
| 1356 | - ), |
|
| 1357 | - $this->checkout->action, |
|
| 1358 | - $this->checkout->current_step->name() |
|
| 1359 | - ), |
|
| 1360 | - __FILE__, |
|
| 1361 | - __FUNCTION__, |
|
| 1362 | - __LINE__ |
|
| 1363 | - ); |
|
| 1364 | - } |
|
| 1365 | - // end default |
|
| 1366 | - } |
|
| 1367 | - // store our progress so far |
|
| 1368 | - $this->checkout->stash_transaction_and_checkout(); |
|
| 1369 | - // advance to the next step! If you pass GO, collect $200 |
|
| 1370 | - $this->go_to_next_step(); |
|
| 1371 | - } |
|
| 1372 | - |
|
| 1373 | - |
|
| 1374 | - /** |
|
| 1375 | - * @param EED_Single_Page_Checkout|EE_SPCO_Reg_Step $target |
|
| 1376 | - * @param object $target an object with the method `translate_js_strings` and `enqueue_styles_and_scripts`. |
|
| 1377 | - * @return void |
|
| 1378 | - */ |
|
| 1379 | - public function add_styles_and_scripts($target) |
|
| 1380 | - { |
|
| 1381 | - // i18n |
|
| 1382 | - $target->translate_js_strings(); |
|
| 1383 | - if ($this->checkout->admin_request) { |
|
| 1384 | - add_action('admin_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
| 1385 | - } else { |
|
| 1386 | - add_action('wp_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
| 1387 | - } |
|
| 1388 | - } |
|
| 1389 | - |
|
| 1390 | - /** |
|
| 1391 | - * translate_js_strings |
|
| 1392 | - * |
|
| 1393 | - * @access public |
|
| 1394 | - * @return void |
|
| 1395 | - */ |
|
| 1396 | - public function translate_js_strings() |
|
| 1397 | - { |
|
| 1398 | - EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit; |
|
| 1399 | - EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link; |
|
| 1400 | - EE_Registry::$i18n_js_strings['server_error'] = esc_html__( |
|
| 1401 | - 'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
| 1402 | - 'event_espresso' |
|
| 1403 | - ); |
|
| 1404 | - EE_Registry::$i18n_js_strings['invalid_json_response'] = esc_html__( |
|
| 1405 | - 'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
| 1406 | - 'event_espresso' |
|
| 1407 | - ); |
|
| 1408 | - EE_Registry::$i18n_js_strings['validation_error'] = esc_html__( |
|
| 1409 | - 'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', |
|
| 1410 | - 'event_espresso' |
|
| 1411 | - ); |
|
| 1412 | - EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__( |
|
| 1413 | - 'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', |
|
| 1414 | - 'event_espresso' |
|
| 1415 | - ); |
|
| 1416 | - EE_Registry::$i18n_js_strings['reg_step_error'] = esc_html__( |
|
| 1417 | - 'This registration step could not be completed. Please refresh the page and try again.', |
|
| 1418 | - 'event_espresso' |
|
| 1419 | - ); |
|
| 1420 | - EE_Registry::$i18n_js_strings['invalid_coupon'] = esc_html__( |
|
| 1421 | - 'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', |
|
| 1422 | - 'event_espresso' |
|
| 1423 | - ); |
|
| 1424 | - EE_Registry::$i18n_js_strings['process_registration'] = sprintf( |
|
| 1425 | - esc_html__( |
|
| 1426 | - 'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', |
|
| 1427 | - 'event_espresso' |
|
| 1428 | - ), |
|
| 1429 | - '<br/>', |
|
| 1430 | - '<br/>' |
|
| 1431 | - ); |
|
| 1432 | - EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language'); |
|
| 1433 | - EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id(); |
|
| 1434 | - EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency; |
|
| 1435 | - EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20'; |
|
| 1436 | - EE_Registry::$i18n_js_strings['timer_years'] = esc_html__('years', 'event_espresso'); |
|
| 1437 | - EE_Registry::$i18n_js_strings['timer_months'] = esc_html__('months', 'event_espresso'); |
|
| 1438 | - EE_Registry::$i18n_js_strings['timer_weeks'] = esc_html__('weeks', 'event_espresso'); |
|
| 1439 | - EE_Registry::$i18n_js_strings['timer_days'] = esc_html__('days', 'event_espresso'); |
|
| 1440 | - EE_Registry::$i18n_js_strings['timer_hours'] = esc_html__('hours', 'event_espresso'); |
|
| 1441 | - EE_Registry::$i18n_js_strings['timer_minutes'] = esc_html__('minutes', 'event_espresso'); |
|
| 1442 | - EE_Registry::$i18n_js_strings['timer_seconds'] = esc_html__('seconds', 'event_espresso'); |
|
| 1443 | - EE_Registry::$i18n_js_strings['timer_year'] = esc_html__('year', 'event_espresso'); |
|
| 1444 | - EE_Registry::$i18n_js_strings['timer_month'] = esc_html__('month', 'event_espresso'); |
|
| 1445 | - EE_Registry::$i18n_js_strings['timer_week'] = esc_html__('week', 'event_espresso'); |
|
| 1446 | - EE_Registry::$i18n_js_strings['timer_day'] = esc_html__('day', 'event_espresso'); |
|
| 1447 | - EE_Registry::$i18n_js_strings['timer_hour'] = esc_html__('hour', 'event_espresso'); |
|
| 1448 | - EE_Registry::$i18n_js_strings['timer_minute'] = esc_html__('minute', 'event_espresso'); |
|
| 1449 | - EE_Registry::$i18n_js_strings['timer_second'] = esc_html__('second', 'event_espresso'); |
|
| 1450 | - EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
| 1451 | - ); |
|
| 1452 | - EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters( |
|
| 1453 | - 'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', |
|
| 1454 | - true |
|
| 1455 | - ); |
|
| 1456 | - EE_Registry::$i18n_js_strings['session_extension'] = absint( |
|
| 1457 | - apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS) |
|
| 1458 | - ); |
|
| 1459 | - EE_Registry::$i18n_js_strings['session_expiration'] = gmdate( |
|
| 1460 | - 'M d, Y H:i:s', |
|
| 1461 | - EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
| 1462 | - ); |
|
| 1463 | - } |
|
| 1464 | - |
|
| 1465 | - |
|
| 1466 | - /** |
|
| 1467 | - * enqueue_styles_and_scripts |
|
| 1468 | - * |
|
| 1469 | - * @access public |
|
| 1470 | - * @return void |
|
| 1471 | - * @throws EE_Error |
|
| 1472 | - */ |
|
| 1473 | - public function enqueue_styles_and_scripts() |
|
| 1474 | - { |
|
| 1475 | - // load css |
|
| 1476 | - wp_register_style( |
|
| 1477 | - 'single_page_checkout', |
|
| 1478 | - SPCO_CSS_URL . 'single_page_checkout.css', |
|
| 1479 | - array('espresso_default'), |
|
| 1480 | - EVENT_ESPRESSO_VERSION |
|
| 1481 | - ); |
|
| 1482 | - wp_enqueue_style('single_page_checkout'); |
|
| 1483 | - // load JS |
|
| 1484 | - wp_register_script( |
|
| 1485 | - 'jquery_plugin', |
|
| 1486 | - EE_THIRD_PARTY_URL . 'jquery .plugin.min.js', |
|
| 1487 | - array('jquery'), |
|
| 1488 | - '1.0.1', |
|
| 1489 | - true |
|
| 1490 | - ); |
|
| 1491 | - wp_register_script( |
|
| 1492 | - 'jquery_countdown', |
|
| 1493 | - EE_THIRD_PARTY_URL . 'jquery .countdown.min.js', |
|
| 1494 | - array('jquery_plugin'), |
|
| 1495 | - '2.1.0', |
|
| 1496 | - true |
|
| 1497 | - ); |
|
| 1498 | - wp_register_script( |
|
| 1499 | - 'single_page_checkout', |
|
| 1500 | - SPCO_JS_URL . 'single_page_checkout.js', |
|
| 1501 | - array('espresso_core', 'underscore', 'ee_form_section_validation'), |
|
| 1502 | - EVENT_ESPRESSO_VERSION, |
|
| 1503 | - true |
|
| 1504 | - ); |
|
| 1505 | - if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) { |
|
| 1506 | - $this->checkout->registration_form->enqueue_js(); |
|
| 1507 | - } |
|
| 1508 | - if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) { |
|
| 1509 | - $this->checkout->current_step->reg_form->enqueue_js(); |
|
| 1510 | - } |
|
| 1511 | - wp_enqueue_script('single_page_checkout'); |
|
| 1512 | - if (apply_filters('FHEE__registration_page_wrapper_template__display_time_limit', false)) { |
|
| 1513 | - wp_enqueue_script('jquery_countdown'); |
|
| 1514 | - } |
|
| 1515 | - /** |
|
| 1516 | - * global action hook for enqueueing styles and scripts with |
|
| 1517 | - * spco calls. |
|
| 1518 | - */ |
|
| 1519 | - do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this); |
|
| 1520 | - /** |
|
| 1521 | - * dynamic action hook for enqueueing styles and scripts with spco calls. |
|
| 1522 | - * The hook will end up being something like: |
|
| 1523 | - * AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information |
|
| 1524 | - */ |
|
| 1525 | - do_action( |
|
| 1526 | - 'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), |
|
| 1527 | - $this |
|
| 1528 | - ); |
|
| 1529 | - } |
|
| 1530 | - |
|
| 1531 | - |
|
| 1532 | - /** |
|
| 1533 | - * display the Registration Single Page Checkout Form |
|
| 1534 | - * |
|
| 1535 | - * @access private |
|
| 1536 | - * @return void |
|
| 1537 | - * @throws EE_Error |
|
| 1538 | - */ |
|
| 1539 | - private function _display_spco_reg_form() |
|
| 1540 | - { |
|
| 1541 | - // if registering via the admin, just display the reg form for the current step |
|
| 1542 | - if ($this->checkout->admin_request) { |
|
| 1543 | - EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form()); |
|
| 1544 | - } else { |
|
| 1545 | - // add powered by EE msg |
|
| 1546 | - add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer')); |
|
| 1547 | - $empty_cart = count($this->checkout->transaction |
|
| 1548 | - ->registrations($this->checkout->reg_cache_where_params)) < 1; |
|
| 1549 | - EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart; |
|
| 1550 | - $cookies_not_set_msg = ''; |
|
| 1551 | - if ($empty_cart) { |
|
| 1552 | - $cookies_not_set_msg = apply_filters( |
|
| 1553 | - 'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg', |
|
| 1554 | - sprintf( |
|
| 1555 | - esc_html__( |
|
| 1556 | - '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s', |
|
| 1557 | - 'event_espresso' |
|
| 1558 | - ), |
|
| 1559 | - '<div class="ee-attention hidden" id="ee-cookies-not-set-msg">', |
|
| 1560 | - '</div>', |
|
| 1561 | - '<h6 class="important-notice">', |
|
| 1562 | - '</h6>', |
|
| 1563 | - '<p>', |
|
| 1564 | - '</p>', |
|
| 1565 | - '<br />', |
|
| 1566 | - '<a href="http://www.whatarecookies.com/enable.asp" target="_blank" rel="noopener noreferrer">', |
|
| 1567 | - '</a>' |
|
| 1568 | - ) |
|
| 1569 | - ); |
|
| 1570 | - } |
|
| 1571 | - $this->checkout->registration_form = new EE_Form_Section_Proper( |
|
| 1572 | - array( |
|
| 1573 | - 'name' => 'single-page-checkout', |
|
| 1574 | - 'html_id' => 'ee-single-page-checkout-dv', |
|
| 1575 | - 'layout_strategy' => |
|
| 1576 | - new EE_Template_Layout( |
|
| 1577 | - array( |
|
| 1578 | - 'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php', |
|
| 1579 | - 'template_args' => array( |
|
| 1580 | - 'empty_cart' => $empty_cart, |
|
| 1581 | - 'revisit' => $this->checkout->revisit, |
|
| 1582 | - 'reg_steps' => $this->checkout->reg_steps, |
|
| 1583 | - 'next_step' => $this->checkout->next_step instanceof EE_SPCO_Reg_Step |
|
| 1584 | - ? $this->checkout->next_step->slug() |
|
| 1585 | - : '', |
|
| 1586 | - 'empty_msg' => apply_filters( |
|
| 1587 | - 'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg', |
|
| 1588 | - sprintf( |
|
| 1589 | - esc_html__( |
|
| 1590 | - 'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', |
|
| 1591 | - 'event_espresso' |
|
| 1592 | - ), |
|
| 1593 | - '<a href="' |
|
| 1594 | - . get_post_type_archive_link('espresso_events') |
|
| 1595 | - . '" title="', |
|
| 1596 | - '">', |
|
| 1597 | - '</a>' |
|
| 1598 | - ) |
|
| 1599 | - ), |
|
| 1600 | - 'cookies_not_set_msg' => $cookies_not_set_msg, |
|
| 1601 | - 'registration_time_limit' => $this->checkout->get_registration_time_limit(), |
|
| 1602 | - 'session_expiration' => gmdate( |
|
| 1603 | - 'M d, Y H:i:s', |
|
| 1604 | - EE_Registry::instance()->SSN->expiration() |
|
| 1605 | - + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
| 1606 | - ), |
|
| 1607 | - ), |
|
| 1608 | - ) |
|
| 1609 | - ), |
|
| 1610 | - ) |
|
| 1611 | - ); |
|
| 1612 | - // load template and add to output sent that gets filtered into the_content() |
|
| 1613 | - EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html()); |
|
| 1614 | - } |
|
| 1615 | - } |
|
| 1616 | - |
|
| 1617 | - |
|
| 1618 | - /** |
|
| 1619 | - * add_extra_finalize_registration_inputs |
|
| 1620 | - * |
|
| 1621 | - * @access public |
|
| 1622 | - * @param $next_step |
|
| 1623 | - * @internal param string $label |
|
| 1624 | - * @return void |
|
| 1625 | - */ |
|
| 1626 | - public function add_extra_finalize_registration_inputs($next_step) |
|
| 1627 | - { |
|
| 1628 | - if ($next_step === 'finalize_registration') { |
|
| 1629 | - echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>'; |
|
| 1630 | - } |
|
| 1631 | - } |
|
| 1632 | - |
|
| 1633 | - |
|
| 1634 | - /** |
|
| 1635 | - * display_registration_footer |
|
| 1636 | - * |
|
| 1637 | - * @access public |
|
| 1638 | - * @return string |
|
| 1639 | - */ |
|
| 1640 | - public static function display_registration_footer() |
|
| 1641 | - { |
|
| 1642 | - if (apply_filters( |
|
| 1643 | - 'FHEE__EE_Front__Controller__show_reg_footer', |
|
| 1644 | - EE_Registry::instance()->CFG->admin->show_reg_footer |
|
| 1645 | - )) { |
|
| 1646 | - add_filter( |
|
| 1647 | - 'FHEE__EEH_Template__powered_by_event_espresso__url', |
|
| 1648 | - function ($url) { |
|
| 1649 | - return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url); |
|
| 1650 | - } |
|
| 1651 | - ); |
|
| 1652 | - echo apply_filters( |
|
| 1653 | - 'FHEE__EE_Front_Controller__display_registration_footer', |
|
| 1654 | - \EEH_Template::powered_by_event_espresso( |
|
| 1655 | - '', |
|
| 1656 | - 'espresso-registration-footer-dv', |
|
| 1657 | - array('utm_content' => 'registration_checkout') |
|
| 1658 | - ) |
|
| 1659 | - ); |
|
| 1660 | - } |
|
| 1661 | - return ''; |
|
| 1662 | - } |
|
| 1663 | - |
|
| 1664 | - |
|
| 1665 | - /** |
|
| 1666 | - * unlock_transaction |
|
| 1667 | - * |
|
| 1668 | - * @access public |
|
| 1669 | - * @return void |
|
| 1670 | - * @throws EE_Error |
|
| 1671 | - */ |
|
| 1672 | - public function unlock_transaction() |
|
| 1673 | - { |
|
| 1674 | - if ($this->checkout->transaction instanceof EE_Transaction) { |
|
| 1675 | - $this->checkout->transaction->unlock(); |
|
| 1676 | - } |
|
| 1677 | - } |
|
| 1678 | - |
|
| 1679 | - |
|
| 1680 | - /** |
|
| 1681 | - * _setup_redirect |
|
| 1682 | - * |
|
| 1683 | - * @access private |
|
| 1684 | - * @return void |
|
| 1685 | - */ |
|
| 1686 | - private function _setup_redirect() |
|
| 1687 | - { |
|
| 1688 | - if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) { |
|
| 1689 | - $this->checkout->redirect = true; |
|
| 1690 | - if (empty($this->checkout->redirect_url)) { |
|
| 1691 | - $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url(); |
|
| 1692 | - } |
|
| 1693 | - $this->checkout->redirect_url = apply_filters( |
|
| 1694 | - 'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url', |
|
| 1695 | - $this->checkout->redirect_url, |
|
| 1696 | - $this->checkout |
|
| 1697 | - ); |
|
| 1698 | - } |
|
| 1699 | - } |
|
| 1700 | - |
|
| 1701 | - |
|
| 1702 | - /** |
|
| 1703 | - * handle ajax message responses and redirects |
|
| 1704 | - * |
|
| 1705 | - * @access public |
|
| 1706 | - * @return void |
|
| 1707 | - * @throws EE_Error |
|
| 1708 | - */ |
|
| 1709 | - public function go_to_next_step() |
|
| 1710 | - { |
|
| 1711 | - if (EE_Registry::instance()->REQ->ajax) { |
|
| 1712 | - // capture contents of output buffer we started earlier in the request, and insert into JSON response |
|
| 1713 | - $this->checkout->json_response->set_unexpected_errors(ob_get_clean()); |
|
| 1714 | - } |
|
| 1715 | - $this->unlock_transaction(); |
|
| 1716 | - // just return for these conditions |
|
| 1717 | - if ($this->checkout->admin_request |
|
| 1718 | - || $this->checkout->action === 'redirect_form' |
|
| 1719 | - || $this->checkout->action === 'update_checkout' |
|
| 1720 | - ) { |
|
| 1721 | - return; |
|
| 1722 | - } |
|
| 1723 | - // AJAX response |
|
| 1724 | - $this->_handle_json_response(); |
|
| 1725 | - // redirect to next step or the Thank You page |
|
| 1726 | - $this->_handle_html_redirects(); |
|
| 1727 | - // hmmm... must be something wrong, so let's just display the form again ! |
|
| 1728 | - $this->_display_spco_reg_form(); |
|
| 1729 | - } |
|
| 1730 | - |
|
| 1731 | - |
|
| 1732 | - /** |
|
| 1733 | - * _handle_json_response |
|
| 1734 | - * |
|
| 1735 | - * @access protected |
|
| 1736 | - * @return void |
|
| 1737 | - */ |
|
| 1738 | - protected function _handle_json_response() |
|
| 1739 | - { |
|
| 1740 | - // if this is an ajax request |
|
| 1741 | - if (EE_Registry::instance()->REQ->ajax) { |
|
| 1742 | - $this->checkout->json_response->set_registration_time_limit( |
|
| 1743 | - $this->checkout->get_registration_time_limit() |
|
| 1744 | - ); |
|
| 1745 | - $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing); |
|
| 1746 | - // just send the ajax ( |
|
| 1747 | - $json_response = apply_filters( |
|
| 1748 | - 'FHEE__EE_Single_Page_Checkout__JSON_response', |
|
| 1749 | - $this->checkout->json_response |
|
| 1750 | - ); |
|
| 1751 | - echo $json_response; |
|
| 1752 | - exit(); |
|
| 1753 | - } |
|
| 1754 | - } |
|
| 1755 | - |
|
| 1756 | - |
|
| 1757 | - /** |
|
| 1758 | - * _handle_redirects |
|
| 1759 | - * |
|
| 1760 | - * @access protected |
|
| 1761 | - * @return void |
|
| 1762 | - */ |
|
| 1763 | - protected function _handle_html_redirects() |
|
| 1764 | - { |
|
| 1765 | - // going somewhere ? |
|
| 1766 | - if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) { |
|
| 1767 | - // store notices in a transient |
|
| 1768 | - EE_Error::get_notices(false, true, true); |
|
| 1769 | - wp_safe_redirect($this->checkout->redirect_url); |
|
| 1770 | - exit(); |
|
| 1771 | - } |
|
| 1772 | - } |
|
| 1773 | - |
|
| 1774 | - |
|
| 1775 | - /** |
|
| 1776 | - * set_checkout_anchor |
|
| 1777 | - * |
|
| 1778 | - * @access public |
|
| 1779 | - * @return void |
|
| 1780 | - */ |
|
| 1781 | - public function set_checkout_anchor() |
|
| 1782 | - { |
|
| 1783 | - echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>'; |
|
| 1784 | - } |
|
| 1785 | - |
|
| 1786 | - /** |
|
| 1787 | - * getRegistrationExpirationNotice |
|
| 1788 | - * |
|
| 1789 | - * @since 4.9.59.p |
|
| 1790 | - * @access public |
|
| 1791 | - * @return string |
|
| 1792 | - */ |
|
| 1793 | - public static function getRegistrationExpirationNotice() |
|
| 1794 | - { |
|
| 1795 | - return sprintf( |
|
| 1796 | - esc_html__( |
|
| 1797 | - '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please accept our apologies for any inconvenience this may have caused.%8$s', |
|
| 1798 | - 'event_espresso' |
|
| 1799 | - ), |
|
| 1800 | - '<h4 class="important-notice">', |
|
| 1801 | - '</h4>', |
|
| 1802 | - '<br />', |
|
| 1803 | - '<p>', |
|
| 1804 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
| 1805 | - '">', |
|
| 1806 | - '</a>', |
|
| 1807 | - '</p>' |
|
| 1808 | - ); |
|
| 1809 | - } |
|
| 18 | + /** |
|
| 19 | + * $_initialized - has the SPCO controller already been initialized ? |
|
| 20 | + * |
|
| 21 | + * @access private |
|
| 22 | + * @var bool $_initialized |
|
| 23 | + */ |
|
| 24 | + private static $_initialized = false; |
|
| 25 | + |
|
| 26 | + |
|
| 27 | + /** |
|
| 28 | + * $_checkout_verified - is the EE_Checkout verified as correct for this request ? |
|
| 29 | + * |
|
| 30 | + * @access private |
|
| 31 | + * @var bool $_valid_checkout |
|
| 32 | + */ |
|
| 33 | + private static $_checkout_verified = true; |
|
| 34 | + |
|
| 35 | + /** |
|
| 36 | + * $_reg_steps_array - holds initial array of reg steps |
|
| 37 | + * |
|
| 38 | + * @access private |
|
| 39 | + * @var array $_reg_steps_array |
|
| 40 | + */ |
|
| 41 | + private static $_reg_steps_array = array(); |
|
| 42 | + |
|
| 43 | + /** |
|
| 44 | + * $checkout - EE_Checkout object for handling the properties of the current checkout process |
|
| 45 | + * |
|
| 46 | + * @access public |
|
| 47 | + * @var EE_Checkout $checkout |
|
| 48 | + */ |
|
| 49 | + public $checkout; |
|
| 50 | + |
|
| 51 | + |
|
| 52 | + /** |
|
| 53 | + * @return EED_Module|EED_Single_Page_Checkout |
|
| 54 | + */ |
|
| 55 | + public static function instance() |
|
| 56 | + { |
|
| 57 | + add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true'); |
|
| 58 | + return parent::get_instance(__CLASS__); |
|
| 59 | + } |
|
| 60 | + |
|
| 61 | + |
|
| 62 | + /** |
|
| 63 | + * @return EE_CART |
|
| 64 | + */ |
|
| 65 | + public function cart() |
|
| 66 | + { |
|
| 67 | + return $this->checkout->cart; |
|
| 68 | + } |
|
| 69 | + |
|
| 70 | + |
|
| 71 | + /** |
|
| 72 | + * @return EE_Transaction |
|
| 73 | + */ |
|
| 74 | + public function transaction() |
|
| 75 | + { |
|
| 76 | + return $this->checkout->transaction; |
|
| 77 | + } |
|
| 78 | + |
|
| 79 | + |
|
| 80 | + /** |
|
| 81 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
| 82 | + * |
|
| 83 | + * @access public |
|
| 84 | + * @return void |
|
| 85 | + * @throws EE_Error |
|
| 86 | + */ |
|
| 87 | + public static function set_hooks() |
|
| 88 | + { |
|
| 89 | + EED_Single_Page_Checkout::set_definitions(); |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + |
|
| 93 | + /** |
|
| 94 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
| 95 | + * |
|
| 96 | + * @access public |
|
| 97 | + * @return void |
|
| 98 | + * @throws EE_Error |
|
| 99 | + */ |
|
| 100 | + public static function set_hooks_admin() |
|
| 101 | + { |
|
| 102 | + EED_Single_Page_Checkout::set_definitions(); |
|
| 103 | + if (! (defined('DOING_AJAX') && DOING_AJAX)) { |
|
| 104 | + return; |
|
| 105 | + } |
|
| 106 | + // going to start an output buffer in case anything gets accidentally output |
|
| 107 | + // that might disrupt our JSON response |
|
| 108 | + ob_start(); |
|
| 109 | + EED_Single_Page_Checkout::load_request_handler(); |
|
| 110 | + EED_Single_Page_Checkout::load_reg_steps(); |
|
| 111 | + // set ajax hooks |
|
| 112 | + add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
| 113 | + add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step')); |
|
| 114 | + add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
| 115 | + add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step')); |
|
| 116 | + add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
| 117 | + add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step')); |
|
| 118 | + } |
|
| 119 | + |
|
| 120 | + |
|
| 121 | + /** |
|
| 122 | + * process ajax request |
|
| 123 | + * |
|
| 124 | + * @param string $ajax_action |
|
| 125 | + * @throws EE_Error |
|
| 126 | + */ |
|
| 127 | + public static function process_ajax_request($ajax_action) |
|
| 128 | + { |
|
| 129 | + EE_Registry::instance()->REQ->set('action', $ajax_action); |
|
| 130 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
| 131 | + } |
|
| 132 | + |
|
| 133 | + |
|
| 134 | + /** |
|
| 135 | + * ajax display registration step |
|
| 136 | + * |
|
| 137 | + * @throws EE_Error |
|
| 138 | + */ |
|
| 139 | + public static function display_reg_step() |
|
| 140 | + { |
|
| 141 | + EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step'); |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + |
|
| 145 | + /** |
|
| 146 | + * ajax process registration step |
|
| 147 | + * |
|
| 148 | + * @throws EE_Error |
|
| 149 | + */ |
|
| 150 | + public static function process_reg_step() |
|
| 151 | + { |
|
| 152 | + EED_Single_Page_Checkout::process_ajax_request('process_reg_step'); |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + |
|
| 156 | + /** |
|
| 157 | + * ajax process registration step |
|
| 158 | + * |
|
| 159 | + * @throws EE_Error |
|
| 160 | + */ |
|
| 161 | + public static function update_reg_step() |
|
| 162 | + { |
|
| 163 | + EED_Single_Page_Checkout::process_ajax_request('update_reg_step'); |
|
| 164 | + } |
|
| 165 | + |
|
| 166 | + |
|
| 167 | + /** |
|
| 168 | + * update_checkout |
|
| 169 | + * |
|
| 170 | + * @access public |
|
| 171 | + * @return void |
|
| 172 | + * @throws EE_Error |
|
| 173 | + */ |
|
| 174 | + public static function update_checkout() |
|
| 175 | + { |
|
| 176 | + EED_Single_Page_Checkout::process_ajax_request('update_checkout'); |
|
| 177 | + } |
|
| 178 | + |
|
| 179 | + |
|
| 180 | + /** |
|
| 181 | + * load_request_handler |
|
| 182 | + * |
|
| 183 | + * @access public |
|
| 184 | + * @return void |
|
| 185 | + */ |
|
| 186 | + public static function load_request_handler() |
|
| 187 | + { |
|
| 188 | + // load core Request_Handler class |
|
| 189 | + if (EE_Registry::instance()->REQ !== null) { |
|
| 190 | + EE_Registry::instance()->load_core('Request_Handler'); |
|
| 191 | + } |
|
| 192 | + } |
|
| 193 | + |
|
| 194 | + |
|
| 195 | + /** |
|
| 196 | + * set_definitions |
|
| 197 | + * |
|
| 198 | + * @access public |
|
| 199 | + * @return void |
|
| 200 | + * @throws EE_Error |
|
| 201 | + */ |
|
| 202 | + public static function set_definitions() |
|
| 203 | + { |
|
| 204 | + if (defined('SPCO_BASE_PATH')) { |
|
| 205 | + return; |
|
| 206 | + } |
|
| 207 | + define( |
|
| 208 | + 'SPCO_BASE_PATH', |
|
| 209 | + rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/') . '/' |
|
| 210 | + ); |
|
| 211 | + define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css/'); |
|
| 212 | + define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img/'); |
|
| 213 | + define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js/'); |
|
| 214 | + define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc/'); |
|
| 215 | + define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps/'); |
|
| 216 | + define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates/'); |
|
| 217 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true); |
|
| 218 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
| 219 | + ); |
|
| 220 | + } |
|
| 221 | + |
|
| 222 | + |
|
| 223 | + /** |
|
| 224 | + * load_reg_steps |
|
| 225 | + * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array |
|
| 226 | + * |
|
| 227 | + * @access private |
|
| 228 | + * @throws EE_Error |
|
| 229 | + */ |
|
| 230 | + public static function load_reg_steps() |
|
| 231 | + { |
|
| 232 | + static $reg_steps_loaded = false; |
|
| 233 | + if ($reg_steps_loaded) { |
|
| 234 | + return; |
|
| 235 | + } |
|
| 236 | + // filter list of reg_steps |
|
| 237 | + $reg_steps_to_load = (array) apply_filters( |
|
| 238 | + 'AHEE__SPCO__load_reg_steps__reg_steps_to_load', |
|
| 239 | + EED_Single_Page_Checkout::get_reg_steps() |
|
| 240 | + ); |
|
| 241 | + // sort by key (order) |
|
| 242 | + ksort($reg_steps_to_load); |
|
| 243 | + // loop through folders |
|
| 244 | + foreach ($reg_steps_to_load as $order => $reg_step) { |
|
| 245 | + // we need a |
|
| 246 | + if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
| 247 | + // copy over to the reg_steps_array |
|
| 248 | + EED_Single_Page_Checkout::$_reg_steps_array[ $order ] = $reg_step; |
|
| 249 | + // register custom key route for each reg step |
|
| 250 | + // ie: step=>"slug" - this is the entire reason we load the reg steps array now |
|
| 251 | + EE_Config::register_route( |
|
| 252 | + $reg_step['slug'], |
|
| 253 | + 'EED_Single_Page_Checkout', |
|
| 254 | + 'run', |
|
| 255 | + 'step' |
|
| 256 | + ); |
|
| 257 | + // add AJAX or other hooks |
|
| 258 | + if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) { |
|
| 259 | + // setup autoloaders if necessary |
|
| 260 | + if (! class_exists($reg_step['class_name'])) { |
|
| 261 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder( |
|
| 262 | + $reg_step['file_path'], |
|
| 263 | + true |
|
| 264 | + ); |
|
| 265 | + } |
|
| 266 | + if (is_callable($reg_step['class_name'], 'set_hooks')) { |
|
| 267 | + call_user_func(array($reg_step['class_name'], 'set_hooks')); |
|
| 268 | + } |
|
| 269 | + } |
|
| 270 | + } |
|
| 271 | + } |
|
| 272 | + $reg_steps_loaded = true; |
|
| 273 | + } |
|
| 274 | + |
|
| 275 | + |
|
| 276 | + /** |
|
| 277 | + * get_reg_steps |
|
| 278 | + * |
|
| 279 | + * @access public |
|
| 280 | + * @return array |
|
| 281 | + */ |
|
| 282 | + public static function get_reg_steps() |
|
| 283 | + { |
|
| 284 | + $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps; |
|
| 285 | + if (empty($reg_steps)) { |
|
| 286 | + $reg_steps = array( |
|
| 287 | + 10 => array( |
|
| 288 | + 'file_path' => SPCO_REG_STEPS_PATH . 'attendee_information', |
|
| 289 | + 'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information', |
|
| 290 | + 'slug' => 'attendee_information', |
|
| 291 | + 'has_hooks' => false, |
|
| 292 | + ), |
|
| 293 | + 30 => array( |
|
| 294 | + 'file_path' => SPCO_REG_STEPS_PATH . 'payment_options', |
|
| 295 | + 'class_name' => 'EE_SPCO_Reg_Step_Payment_Options', |
|
| 296 | + 'slug' => 'payment_options', |
|
| 297 | + 'has_hooks' => true, |
|
| 298 | + ), |
|
| 299 | + 999 => array( |
|
| 300 | + 'file_path' => SPCO_REG_STEPS_PATH . 'finalize_registration', |
|
| 301 | + 'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration', |
|
| 302 | + 'slug' => 'finalize_registration', |
|
| 303 | + 'has_hooks' => false, |
|
| 304 | + ), |
|
| 305 | + ); |
|
| 306 | + } |
|
| 307 | + return $reg_steps; |
|
| 308 | + } |
|
| 309 | + |
|
| 310 | + |
|
| 311 | + /** |
|
| 312 | + * registration_checkout_for_admin |
|
| 313 | + * |
|
| 314 | + * @access public |
|
| 315 | + * @return string |
|
| 316 | + * @throws EE_Error |
|
| 317 | + */ |
|
| 318 | + public static function registration_checkout_for_admin() |
|
| 319 | + { |
|
| 320 | + EED_Single_Page_Checkout::load_request_handler(); |
|
| 321 | + EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
| 322 | + EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step'); |
|
| 323 | + EE_Registry::instance()->REQ->set('process_form_submission', false); |
|
| 324 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
| 325 | + EED_Single_Page_Checkout::instance()->_display_spco_reg_form(); |
|
| 326 | + return EE_Registry::instance()->REQ->get_output(); |
|
| 327 | + } |
|
| 328 | + |
|
| 329 | + |
|
| 330 | + /** |
|
| 331 | + * process_registration_from_admin |
|
| 332 | + * |
|
| 333 | + * @access public |
|
| 334 | + * @return \EE_Transaction |
|
| 335 | + * @throws EE_Error |
|
| 336 | + */ |
|
| 337 | + public static function process_registration_from_admin() |
|
| 338 | + { |
|
| 339 | + EED_Single_Page_Checkout::load_request_handler(); |
|
| 340 | + EE_Registry::instance()->REQ->set('step', 'attendee_information'); |
|
| 341 | + EE_Registry::instance()->REQ->set('action', 'process_reg_step'); |
|
| 342 | + EE_Registry::instance()->REQ->set('process_form_submission', true); |
|
| 343 | + EED_Single_Page_Checkout::instance()->_initialize(); |
|
| 344 | + if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) { |
|
| 345 | + $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps); |
|
| 346 | + if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) { |
|
| 347 | + EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step); |
|
| 348 | + if ($final_reg_step->process_reg_step()) { |
|
| 349 | + $final_reg_step->set_completed(); |
|
| 350 | + EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array(); |
|
| 351 | + return EED_Single_Page_Checkout::instance()->checkout->transaction; |
|
| 352 | + } |
|
| 353 | + } |
|
| 354 | + } |
|
| 355 | + return null; |
|
| 356 | + } |
|
| 357 | + |
|
| 358 | + |
|
| 359 | + /** |
|
| 360 | + * run |
|
| 361 | + * |
|
| 362 | + * @access public |
|
| 363 | + * @param WP_Query $WP_Query |
|
| 364 | + * @return void |
|
| 365 | + * @throws EE_Error |
|
| 366 | + */ |
|
| 367 | + public function run($WP_Query) |
|
| 368 | + { |
|
| 369 | + if ($WP_Query instanceof WP_Query |
|
| 370 | + && $WP_Query->is_main_query() |
|
| 371 | + && apply_filters('FHEE__EED_Single_Page_Checkout__run', true) |
|
| 372 | + && $this->_is_reg_checkout() |
|
| 373 | + ) { |
|
| 374 | + $this->_initialize(); |
|
| 375 | + } |
|
| 376 | + } |
|
| 377 | + |
|
| 378 | + |
|
| 379 | + /** |
|
| 380 | + * determines whether current url matches reg page url |
|
| 381 | + * |
|
| 382 | + * @return bool |
|
| 383 | + */ |
|
| 384 | + protected function _is_reg_checkout() |
|
| 385 | + { |
|
| 386 | + // get current permalink for reg page without any extra query args |
|
| 387 | + $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id); |
|
| 388 | + // get request URI for current request, but without the scheme or host |
|
| 389 | + $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI'); |
|
| 390 | + $current_request_uri = html_entity_decode($current_request_uri); |
|
| 391 | + // get array of query args from the current request URI |
|
| 392 | + $query_args = \EEH_URL::get_query_string($current_request_uri); |
|
| 393 | + // grab page id if it is set |
|
| 394 | + $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0; |
|
| 395 | + // and remove the page id from the query args (we will re-add it later) |
|
| 396 | + unset($query_args['page_id']); |
|
| 397 | + // now strip all query args from current request URI |
|
| 398 | + $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri); |
|
| 399 | + // and re-add the page id if it was set |
|
| 400 | + if ($page_id) { |
|
| 401 | + $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri); |
|
| 402 | + } |
|
| 403 | + // remove slashes and ? |
|
| 404 | + $current_request_uri = trim($current_request_uri, '?/'); |
|
| 405 | + // is current request URI part of the known full reg page URL ? |
|
| 406 | + return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false; |
|
| 407 | + } |
|
| 408 | + |
|
| 409 | + |
|
| 410 | + /** |
|
| 411 | + * @param WP_Query $wp_query |
|
| 412 | + * @return void |
|
| 413 | + * @throws EE_Error |
|
| 414 | + */ |
|
| 415 | + public static function init($wp_query) |
|
| 416 | + { |
|
| 417 | + EED_Single_Page_Checkout::instance()->run($wp_query); |
|
| 418 | + } |
|
| 419 | + |
|
| 420 | + |
|
| 421 | + /** |
|
| 422 | + * _initialize - initial module setup |
|
| 423 | + * |
|
| 424 | + * @access private |
|
| 425 | + * @throws EE_Error |
|
| 426 | + * @return void |
|
| 427 | + */ |
|
| 428 | + private function _initialize() |
|
| 429 | + { |
|
| 430 | + // ensure SPCO doesn't run twice |
|
| 431 | + if (EED_Single_Page_Checkout::$_initialized) { |
|
| 432 | + return; |
|
| 433 | + } |
|
| 434 | + try { |
|
| 435 | + EED_Single_Page_Checkout::load_reg_steps(); |
|
| 436 | + $this->_verify_session(); |
|
| 437 | + // setup the EE_Checkout object |
|
| 438 | + $this->checkout = $this->_initialize_checkout(); |
|
| 439 | + // filter checkout |
|
| 440 | + $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout); |
|
| 441 | + // get the $_GET |
|
| 442 | + $this->_get_request_vars(); |
|
| 443 | + if ($this->_block_bots()) { |
|
| 444 | + return; |
|
| 445 | + } |
|
| 446 | + // filter continue_reg |
|
| 447 | + $this->checkout->continue_reg = apply_filters( |
|
| 448 | + 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
| 449 | + true, |
|
| 450 | + $this->checkout |
|
| 451 | + ); |
|
| 452 | + // load the reg steps array |
|
| 453 | + if (! $this->_load_and_instantiate_reg_steps()) { |
|
| 454 | + EED_Single_Page_Checkout::$_initialized = true; |
|
| 455 | + return; |
|
| 456 | + } |
|
| 457 | + // set the current step |
|
| 458 | + $this->checkout->set_current_step($this->checkout->step); |
|
| 459 | + // and the next step |
|
| 460 | + $this->checkout->set_next_step(); |
|
| 461 | + // verify that everything has been setup correctly |
|
| 462 | + if (! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) { |
|
| 463 | + EED_Single_Page_Checkout::$_initialized = true; |
|
| 464 | + return; |
|
| 465 | + } |
|
| 466 | + // lock the transaction |
|
| 467 | + $this->checkout->transaction->lock(); |
|
| 468 | + // make sure all of our cached objects are added to their respective model entity mappers |
|
| 469 | + $this->checkout->refresh_all_entities(); |
|
| 470 | + // set amount owing |
|
| 471 | + $this->checkout->amount_owing = $this->checkout->transaction->remaining(); |
|
| 472 | + // initialize each reg step, which gives them the chance to potentially alter the process |
|
| 473 | + $this->_initialize_reg_steps(); |
|
| 474 | + // DEBUG LOG |
|
| 475 | + // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
| 476 | + // get reg form |
|
| 477 | + if (! $this->_check_form_submission()) { |
|
| 478 | + EED_Single_Page_Checkout::$_initialized = true; |
|
| 479 | + return; |
|
| 480 | + } |
|
| 481 | + // checkout the action!!! |
|
| 482 | + $this->_process_form_action(); |
|
| 483 | + // add some style and make it dance |
|
| 484 | + $this->add_styles_and_scripts($this); |
|
| 485 | + // kk... SPCO has successfully run |
|
| 486 | + EED_Single_Page_Checkout::$_initialized = true; |
|
| 487 | + // set no cache headers and constants |
|
| 488 | + EE_System::do_not_cache(); |
|
| 489 | + // add anchor |
|
| 490 | + add_action('loop_start', array($this, 'set_checkout_anchor'), 1); |
|
| 491 | + // remove transaction lock |
|
| 492 | + add_action('shutdown', array($this, 'unlock_transaction'), 1); |
|
| 493 | + } catch (Exception $e) { |
|
| 494 | + EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
| 495 | + } |
|
| 496 | + } |
|
| 497 | + |
|
| 498 | + |
|
| 499 | + /** |
|
| 500 | + * _verify_session |
|
| 501 | + * checks that the session is valid and not expired |
|
| 502 | + * |
|
| 503 | + * @access private |
|
| 504 | + * @throws EE_Error |
|
| 505 | + */ |
|
| 506 | + private function _verify_session() |
|
| 507 | + { |
|
| 508 | + if (! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
| 509 | + throw new EE_Error(esc_html__('The EE_Session class could not be loaded.', 'event_espresso')); |
|
| 510 | + } |
|
| 511 | + $clear_session_requested = filter_var( |
|
| 512 | + EE_Registry::instance()->REQ->get('clear_session', false), |
|
| 513 | + FILTER_VALIDATE_BOOLEAN |
|
| 514 | + ); |
|
| 515 | + // is session still valid ? |
|
| 516 | + if ($clear_session_requested |
|
| 517 | + || (EE_Registry::instance()->SSN->expired() |
|
| 518 | + && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === '' |
|
| 519 | + ) |
|
| 520 | + ) { |
|
| 521 | + $this->checkout = new EE_Checkout(); |
|
| 522 | + EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
| 523 | + // EE_Registry::instance()->SSN->reset_cart(); |
|
| 524 | + // EE_Registry::instance()->SSN->reset_checkout(); |
|
| 525 | + // EE_Registry::instance()->SSN->reset_transaction(); |
|
| 526 | + if (! $clear_session_requested) { |
|
| 527 | + EE_Error::add_attention( |
|
| 528 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'], |
|
| 529 | + __FILE__, |
|
| 530 | + __FUNCTION__, |
|
| 531 | + __LINE__ |
|
| 532 | + ); |
|
| 533 | + } |
|
| 534 | + // EE_Registry::instance()->SSN->reset_expired(); |
|
| 535 | + } |
|
| 536 | + } |
|
| 537 | + |
|
| 538 | + |
|
| 539 | + /** |
|
| 540 | + * _initialize_checkout |
|
| 541 | + * loads and instantiates EE_Checkout |
|
| 542 | + * |
|
| 543 | + * @access private |
|
| 544 | + * @throws EE_Error |
|
| 545 | + * @return EE_Checkout |
|
| 546 | + */ |
|
| 547 | + private function _initialize_checkout() |
|
| 548 | + { |
|
| 549 | + // look in session for existing checkout |
|
| 550 | + /** @type EE_Checkout $checkout */ |
|
| 551 | + $checkout = EE_Registry::instance()->SSN->checkout(); |
|
| 552 | + // verify |
|
| 553 | + if (! $checkout instanceof EE_Checkout) { |
|
| 554 | + // instantiate EE_Checkout object for handling the properties of the current checkout process |
|
| 555 | + $checkout = EE_Registry::instance()->load_file( |
|
| 556 | + SPCO_INC_PATH, |
|
| 557 | + 'EE_Checkout', |
|
| 558 | + 'class', |
|
| 559 | + array(), |
|
| 560 | + false |
|
| 561 | + ); |
|
| 562 | + } else { |
|
| 563 | + if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) { |
|
| 564 | + $this->unlock_transaction(); |
|
| 565 | + wp_safe_redirect($checkout->redirect_url); |
|
| 566 | + exit(); |
|
| 567 | + } |
|
| 568 | + } |
|
| 569 | + $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout); |
|
| 570 | + // verify again |
|
| 571 | + if (! $checkout instanceof EE_Checkout) { |
|
| 572 | + throw new EE_Error(esc_html__('The EE_Checkout class could not be loaded.', 'event_espresso')); |
|
| 573 | + } |
|
| 574 | + // reset anything that needs a clean slate for each request |
|
| 575 | + $checkout->reset_for_current_request(); |
|
| 576 | + return $checkout; |
|
| 577 | + } |
|
| 578 | + |
|
| 579 | + |
|
| 580 | + /** |
|
| 581 | + * _get_request_vars |
|
| 582 | + * |
|
| 583 | + * @access private |
|
| 584 | + * @return void |
|
| 585 | + * @throws EE_Error |
|
| 586 | + */ |
|
| 587 | + private function _get_request_vars() |
|
| 588 | + { |
|
| 589 | + // load classes |
|
| 590 | + EED_Single_Page_Checkout::load_request_handler(); |
|
| 591 | + // make sure this request is marked as belonging to EE |
|
| 592 | + EE_Registry::instance()->REQ->set_espresso_page(true); |
|
| 593 | + // which step is being requested ? |
|
| 594 | + $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step()); |
|
| 595 | + // which step is being edited ? |
|
| 596 | + $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', ''); |
|
| 597 | + // and what we're doing on the current step |
|
| 598 | + $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step'); |
|
| 599 | + // timestamp |
|
| 600 | + $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0); |
|
| 601 | + // returning to edit ? |
|
| 602 | + $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', ''); |
|
| 603 | + // add reg url link to registration query params |
|
| 604 | + if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) { |
|
| 605 | + $this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link; |
|
| 606 | + } |
|
| 607 | + // or some other kind of revisit ? |
|
| 608 | + $this->checkout->revisit = filter_var( |
|
| 609 | + EE_Registry::instance()->REQ->get('revisit', false), |
|
| 610 | + FILTER_VALIDATE_BOOLEAN |
|
| 611 | + ); |
|
| 612 | + // and whether or not to generate a reg form for this request |
|
| 613 | + $this->checkout->generate_reg_form = filter_var( |
|
| 614 | + EE_Registry::instance()->REQ->get('generate_reg_form', true), |
|
| 615 | + FILTER_VALIDATE_BOOLEAN |
|
| 616 | + ); |
|
| 617 | + // and whether or not to process a reg form submission for this request |
|
| 618 | + $this->checkout->process_form_submission = filter_var( |
|
| 619 | + EE_Registry::instance()->REQ->get( |
|
| 620 | + 'process_form_submission', |
|
| 621 | + $this->checkout->action === 'process_reg_step' |
|
| 622 | + ), |
|
| 623 | + FILTER_VALIDATE_BOOLEAN |
|
| 624 | + ); |
|
| 625 | + $this->checkout->process_form_submission = filter_var( |
|
| 626 | + $this->checkout->action !== 'display_spco_reg_step' |
|
| 627 | + ? $this->checkout->process_form_submission |
|
| 628 | + : false, |
|
| 629 | + FILTER_VALIDATE_BOOLEAN |
|
| 630 | + ); |
|
| 631 | + // $this->_display_request_vars(); |
|
| 632 | + } |
|
| 633 | + |
|
| 634 | + |
|
| 635 | + /** |
|
| 636 | + * _display_request_vars |
|
| 637 | + * |
|
| 638 | + * @access protected |
|
| 639 | + * @return void |
|
| 640 | + */ |
|
| 641 | + protected function _display_request_vars() |
|
| 642 | + { |
|
| 643 | + if (! WP_DEBUG) { |
|
| 644 | + return; |
|
| 645 | + } |
|
| 646 | + EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__); |
|
| 647 | + EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__); |
|
| 648 | + EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__); |
|
| 649 | + EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__); |
|
| 650 | + EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__); |
|
| 651 | + EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__); |
|
| 652 | + EEH_Debug_Tools::printr( |
|
| 653 | + $this->checkout->generate_reg_form, |
|
| 654 | + '$this->checkout->generate_reg_form', |
|
| 655 | + __FILE__, |
|
| 656 | + __LINE__ |
|
| 657 | + ); |
|
| 658 | + EEH_Debug_Tools::printr( |
|
| 659 | + $this->checkout->process_form_submission, |
|
| 660 | + '$this->checkout->process_form_submission', |
|
| 661 | + __FILE__, |
|
| 662 | + __LINE__ |
|
| 663 | + ); |
|
| 664 | + } |
|
| 665 | + |
|
| 666 | + |
|
| 667 | + /** |
|
| 668 | + * _block_bots |
|
| 669 | + * checks that the incoming request has either of the following set: |
|
| 670 | + * a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector |
|
| 671 | + * a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN |
|
| 672 | + * so if you're not coming from the Ticket Selector nor returning for a valid IP... |
|
| 673 | + * then where you coming from man? |
|
| 674 | + * |
|
| 675 | + * @return boolean |
|
| 676 | + */ |
|
| 677 | + private function _block_bots() |
|
| 678 | + { |
|
| 679 | + $invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
| 680 | + if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) { |
|
| 681 | + return true; |
|
| 682 | + } |
|
| 683 | + return false; |
|
| 684 | + } |
|
| 685 | + |
|
| 686 | + |
|
| 687 | + /** |
|
| 688 | + * _get_first_step |
|
| 689 | + * gets slug for first step in $_reg_steps_array |
|
| 690 | + * |
|
| 691 | + * @access private |
|
| 692 | + * @throws EE_Error |
|
| 693 | + * @return string |
|
| 694 | + */ |
|
| 695 | + private function _get_first_step() |
|
| 696 | + { |
|
| 697 | + $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array); |
|
| 698 | + return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information'; |
|
| 699 | + } |
|
| 700 | + |
|
| 701 | + |
|
| 702 | + /** |
|
| 703 | + * instantiates each reg step based on the loaded reg_steps array |
|
| 704 | + * |
|
| 705 | + * @return bool |
|
| 706 | + * @throws EE_Error |
|
| 707 | + * @throws InvalidArgumentException |
|
| 708 | + * @throws InvalidDataTypeException |
|
| 709 | + * @throws InvalidInterfaceException |
|
| 710 | + */ |
|
| 711 | + private function _load_and_instantiate_reg_steps() |
|
| 712 | + { |
|
| 713 | + do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout); |
|
| 714 | + // have reg_steps already been instantiated ? |
|
| 715 | + if (empty($this->checkout->reg_steps) |
|
| 716 | + || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout) |
|
| 717 | + ) { |
|
| 718 | + // if not, then loop through raw reg steps array |
|
| 719 | + foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) { |
|
| 720 | + if (! $this->_load_and_instantiate_reg_step($reg_step, $order)) { |
|
| 721 | + return false; |
|
| 722 | + } |
|
| 723 | + } |
|
| 724 | + if (isset($this->checkout->reg_steps['registration_confirmation'])) { |
|
| 725 | + // skip the registration_confirmation page ? |
|
| 726 | + if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) { |
|
| 727 | + // just remove it from the reg steps array |
|
| 728 | + $this->checkout->remove_reg_step('registration_confirmation', false); |
|
| 729 | + } elseif (EE_Registry::instance()->CFG->registration->reg_confirmation_last |
|
| 730 | + ) { |
|
| 731 | + // set the order to something big like 100 |
|
| 732 | + $this->checkout->set_reg_step_order('registration_confirmation', 100); |
|
| 733 | + } |
|
| 734 | + } |
|
| 735 | + // filter the array for good luck |
|
| 736 | + $this->checkout->reg_steps = apply_filters( |
|
| 737 | + 'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps', |
|
| 738 | + $this->checkout->reg_steps |
|
| 739 | + ); |
|
| 740 | + // finally re-sort based on the reg step class order properties |
|
| 741 | + $this->checkout->sort_reg_steps(); |
|
| 742 | + } else { |
|
| 743 | + foreach ($this->checkout->reg_steps as $reg_step) { |
|
| 744 | + // set all current step stati to FALSE |
|
| 745 | + $reg_step->set_is_current_step(false); |
|
| 746 | + } |
|
| 747 | + } |
|
| 748 | + if (empty($this->checkout->reg_steps)) { |
|
| 749 | + EE_Error::add_error( |
|
| 750 | + esc_html__('No Reg Steps were loaded..', 'event_espresso'), |
|
| 751 | + __FILE__, |
|
| 752 | + __FUNCTION__, |
|
| 753 | + __LINE__ |
|
| 754 | + ); |
|
| 755 | + return false; |
|
| 756 | + } |
|
| 757 | + // make reg step details available to JS |
|
| 758 | + $this->checkout->set_reg_step_JSON_info(); |
|
| 759 | + return true; |
|
| 760 | + } |
|
| 761 | + |
|
| 762 | + |
|
| 763 | + /** |
|
| 764 | + * _load_and_instantiate_reg_step |
|
| 765 | + * |
|
| 766 | + * @access private |
|
| 767 | + * @param array $reg_step |
|
| 768 | + * @param int $order |
|
| 769 | + * @return bool |
|
| 770 | + */ |
|
| 771 | + private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0) |
|
| 772 | + { |
|
| 773 | + // we need a file_path, class_name, and slug to add a reg step |
|
| 774 | + if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) { |
|
| 775 | + // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step) |
|
| 776 | + if ($this->checkout->reg_url_link |
|
| 777 | + && $this->checkout->step !== $reg_step['slug'] |
|
| 778 | + && $reg_step['slug'] !== 'finalize_registration' |
|
| 779 | + // normally at this point we would NOT load the reg step, but this filter can change that |
|
| 780 | + && apply_filters( |
|
| 781 | + 'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step', |
|
| 782 | + true, |
|
| 783 | + $reg_step, |
|
| 784 | + $this->checkout |
|
| 785 | + ) |
|
| 786 | + ) { |
|
| 787 | + return true; |
|
| 788 | + } |
|
| 789 | + // instantiate step class using file path and class name |
|
| 790 | + $reg_step_obj = EE_Registry::instance()->load_file( |
|
| 791 | + $reg_step['file_path'], |
|
| 792 | + $reg_step['class_name'], |
|
| 793 | + 'class', |
|
| 794 | + $this->checkout, |
|
| 795 | + false |
|
| 796 | + ); |
|
| 797 | + // did we gets the goods ? |
|
| 798 | + if ($reg_step_obj instanceof EE_SPCO_Reg_Step) { |
|
| 799 | + // set reg step order based on config |
|
| 800 | + $reg_step_obj->set_order($order); |
|
| 801 | + // add instantiated reg step object to the master reg steps array |
|
| 802 | + $this->checkout->add_reg_step($reg_step_obj); |
|
| 803 | + } else { |
|
| 804 | + EE_Error::add_error( |
|
| 805 | + esc_html__('The current step could not be set.', 'event_espresso'), |
|
| 806 | + __FILE__, |
|
| 807 | + __FUNCTION__, |
|
| 808 | + __LINE__ |
|
| 809 | + ); |
|
| 810 | + return false; |
|
| 811 | + } |
|
| 812 | + } else { |
|
| 813 | + if (WP_DEBUG) { |
|
| 814 | + EE_Error::add_error( |
|
| 815 | + sprintf( |
|
| 816 | + esc_html__( |
|
| 817 | + 'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s', |
|
| 818 | + 'event_espresso' |
|
| 819 | + ), |
|
| 820 | + isset($reg_step['file_path']) ? $reg_step['file_path'] : '', |
|
| 821 | + isset($reg_step['class_name']) ? $reg_step['class_name'] : '', |
|
| 822 | + isset($reg_step['slug']) ? $reg_step['slug'] : '', |
|
| 823 | + '<ul>', |
|
| 824 | + '<li>', |
|
| 825 | + '</li>', |
|
| 826 | + '</ul>' |
|
| 827 | + ), |
|
| 828 | + __FILE__, |
|
| 829 | + __FUNCTION__, |
|
| 830 | + __LINE__ |
|
| 831 | + ); |
|
| 832 | + } |
|
| 833 | + return false; |
|
| 834 | + } |
|
| 835 | + return true; |
|
| 836 | + } |
|
| 837 | + |
|
| 838 | + |
|
| 839 | + /** |
|
| 840 | + * _verify_transaction_and_get_registrations |
|
| 841 | + * |
|
| 842 | + * @access private |
|
| 843 | + * @return bool |
|
| 844 | + * @throws InvalidDataTypeException |
|
| 845 | + * @throws InvalidEntityException |
|
| 846 | + * @throws EE_Error |
|
| 847 | + */ |
|
| 848 | + private function _verify_transaction_and_get_registrations() |
|
| 849 | + { |
|
| 850 | + // was there already a valid transaction in the checkout from the session ? |
|
| 851 | + if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
| 852 | + // get transaction from db or session |
|
| 853 | + $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin() |
|
| 854 | + ? $this->_get_transaction_and_cart_for_previous_visit() |
|
| 855 | + : $this->_get_cart_for_current_session_and_setup_new_transaction(); |
|
| 856 | + if (! $this->checkout->transaction instanceof EE_Transaction) { |
|
| 857 | + EE_Error::add_error( |
|
| 858 | + esc_html__( |
|
| 859 | + 'Your Registration and Transaction information could not be retrieved from the db.', |
|
| 860 | + 'event_espresso' |
|
| 861 | + ), |
|
| 862 | + __FILE__, |
|
| 863 | + __FUNCTION__, |
|
| 864 | + __LINE__ |
|
| 865 | + ); |
|
| 866 | + $this->checkout->transaction = EE_Transaction::new_instance(); |
|
| 867 | + // add some style and make it dance |
|
| 868 | + $this->add_styles_and_scripts($this); |
|
| 869 | + EED_Single_Page_Checkout::$_initialized = true; |
|
| 870 | + return false; |
|
| 871 | + } |
|
| 872 | + // and the registrations for the transaction |
|
| 873 | + $this->_get_registrations($this->checkout->transaction); |
|
| 874 | + } |
|
| 875 | + return true; |
|
| 876 | + } |
|
| 877 | + |
|
| 878 | + |
|
| 879 | + /** |
|
| 880 | + * _get_transaction_and_cart_for_previous_visit |
|
| 881 | + * |
|
| 882 | + * @access private |
|
| 883 | + * @return mixed EE_Transaction|NULL |
|
| 884 | + */ |
|
| 885 | + private function _get_transaction_and_cart_for_previous_visit() |
|
| 886 | + { |
|
| 887 | + /** @var $TXN_model EEM_Transaction */ |
|
| 888 | + $TXN_model = EE_Registry::instance()->load_model('Transaction'); |
|
| 889 | + // because the reg_url_link is present in the request, |
|
| 890 | + // this is a return visit to SPCO, so we'll get the transaction data from the db |
|
| 891 | + $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link); |
|
| 892 | + // verify transaction |
|
| 893 | + if ($transaction instanceof EE_Transaction) { |
|
| 894 | + // and get the cart that was used for that transaction |
|
| 895 | + $this->checkout->cart = $this->_get_cart_for_transaction($transaction); |
|
| 896 | + return $transaction; |
|
| 897 | + } |
|
| 898 | + EE_Error::add_error( |
|
| 899 | + esc_html__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'), |
|
| 900 | + __FILE__, |
|
| 901 | + __FUNCTION__, |
|
| 902 | + __LINE__ |
|
| 903 | + ); |
|
| 904 | + return null; |
|
| 905 | + } |
|
| 906 | + |
|
| 907 | + |
|
| 908 | + /** |
|
| 909 | + * _get_cart_for_transaction |
|
| 910 | + * |
|
| 911 | + * @access private |
|
| 912 | + * @param EE_Transaction $transaction |
|
| 913 | + * @return EE_Cart |
|
| 914 | + */ |
|
| 915 | + private function _get_cart_for_transaction($transaction) |
|
| 916 | + { |
|
| 917 | + return $this->checkout->get_cart_for_transaction($transaction); |
|
| 918 | + } |
|
| 919 | + |
|
| 920 | + |
|
| 921 | + /** |
|
| 922 | + * get_cart_for_transaction |
|
| 923 | + * |
|
| 924 | + * @access public |
|
| 925 | + * @param EE_Transaction $transaction |
|
| 926 | + * @return EE_Cart |
|
| 927 | + */ |
|
| 928 | + public function get_cart_for_transaction(EE_Transaction $transaction) |
|
| 929 | + { |
|
| 930 | + return $this->checkout->get_cart_for_transaction($transaction); |
|
| 931 | + } |
|
| 932 | + |
|
| 933 | + |
|
| 934 | + /** |
|
| 935 | + * _get_transaction_and_cart_for_current_session |
|
| 936 | + * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
| 937 | + * |
|
| 938 | + * @access private |
|
| 939 | + * @return EE_Transaction |
|
| 940 | + * @throws EE_Error |
|
| 941 | + */ |
|
| 942 | + private function _get_cart_for_current_session_and_setup_new_transaction() |
|
| 943 | + { |
|
| 944 | + // if there's no transaction, then this is the FIRST visit to SPCO |
|
| 945 | + // so load up the cart ( passing nothing for the TXN because it doesn't exist yet ) |
|
| 946 | + $this->checkout->cart = $this->_get_cart_for_transaction(null); |
|
| 947 | + // and then create a new transaction |
|
| 948 | + $transaction = $this->_initialize_transaction(); |
|
| 949 | + // verify transaction |
|
| 950 | + if ($transaction instanceof EE_Transaction) { |
|
| 951 | + // save it so that we have an ID for other objects to use |
|
| 952 | + $transaction->save(); |
|
| 953 | + // and save TXN data to the cart |
|
| 954 | + $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID()); |
|
| 955 | + } else { |
|
| 956 | + EE_Error::add_error( |
|
| 957 | + esc_html__('A Valid Transaction could not be initialized.', 'event_espresso'), |
|
| 958 | + __FILE__, |
|
| 959 | + __FUNCTION__, |
|
| 960 | + __LINE__ |
|
| 961 | + ); |
|
| 962 | + } |
|
| 963 | + return $transaction; |
|
| 964 | + } |
|
| 965 | + |
|
| 966 | + |
|
| 967 | + /** |
|
| 968 | + * generates a new EE_Transaction object and adds it to the $_transaction property. |
|
| 969 | + * |
|
| 970 | + * @access private |
|
| 971 | + * @return mixed EE_Transaction|NULL |
|
| 972 | + */ |
|
| 973 | + private function _initialize_transaction() |
|
| 974 | + { |
|
| 975 | + try { |
|
| 976 | + // ensure cart totals have been calculated |
|
| 977 | + $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes(); |
|
| 978 | + // grab the cart grand total |
|
| 979 | + $cart_total = $this->checkout->cart->get_cart_grand_total(); |
|
| 980 | + // create new TXN |
|
| 981 | + $transaction = EE_Transaction::new_instance( |
|
| 982 | + array( |
|
| 983 | + 'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(), |
|
| 984 | + 'TXN_total' => $cart_total > 0 ? $cart_total : 0, |
|
| 985 | + 'TXN_paid' => 0, |
|
| 986 | + 'STS_ID' => EEM_Transaction::failed_status_code, |
|
| 987 | + ) |
|
| 988 | + ); |
|
| 989 | + // save it so that we have an ID for other objects to use |
|
| 990 | + $transaction->save(); |
|
| 991 | + // set cron job for following up on TXNs after their session has expired |
|
| 992 | + EE_Cron_Tasks::schedule_expired_transaction_check( |
|
| 993 | + EE_Registry::instance()->SSN->expiration() + 1, |
|
| 994 | + $transaction->ID() |
|
| 995 | + ); |
|
| 996 | + return $transaction; |
|
| 997 | + } catch (Exception $e) { |
|
| 998 | + EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
| 999 | + } |
|
| 1000 | + return null; |
|
| 1001 | + } |
|
| 1002 | + |
|
| 1003 | + |
|
| 1004 | + /** |
|
| 1005 | + * _get_registrations |
|
| 1006 | + * |
|
| 1007 | + * @access private |
|
| 1008 | + * @param EE_Transaction $transaction |
|
| 1009 | + * @return void |
|
| 1010 | + * @throws InvalidDataTypeException |
|
| 1011 | + * @throws InvalidEntityException |
|
| 1012 | + * @throws EE_Error |
|
| 1013 | + */ |
|
| 1014 | + private function _get_registrations(EE_Transaction $transaction) |
|
| 1015 | + { |
|
| 1016 | + // first step: grab the registrants { : o |
|
| 1017 | + $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
| 1018 | + $this->checkout->total_ticket_count = count($registrations); |
|
| 1019 | + // verify registrations have been set |
|
| 1020 | + if (empty($registrations)) { |
|
| 1021 | + // if no cached registrations, then check the db |
|
| 1022 | + $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false); |
|
| 1023 | + // still nothing ? well as long as this isn't a revisit |
|
| 1024 | + if (empty($registrations) && ! $this->checkout->revisit) { |
|
| 1025 | + // generate new registrations from scratch |
|
| 1026 | + $registrations = $this->_initialize_registrations($transaction); |
|
| 1027 | + } |
|
| 1028 | + } |
|
| 1029 | + // sort by their original registration order |
|
| 1030 | + usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count')); |
|
| 1031 | + // then loop thru the array |
|
| 1032 | + foreach ($registrations as $registration) { |
|
| 1033 | + // verify each registration |
|
| 1034 | + if ($registration instanceof EE_Registration) { |
|
| 1035 | + // we display all attendee info for the primary registrant |
|
| 1036 | + if ($this->checkout->reg_url_link === $registration->reg_url_link() |
|
| 1037 | + && $registration->is_primary_registrant() |
|
| 1038 | + ) { |
|
| 1039 | + $this->checkout->primary_revisit = true; |
|
| 1040 | + break; |
|
| 1041 | + } |
|
| 1042 | + if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) { |
|
| 1043 | + // but hide info if it doesn't belong to you |
|
| 1044 | + $transaction->clear_cache('Registration', $registration->ID()); |
|
| 1045 | + $this->checkout->total_ticket_count--; |
|
| 1046 | + } |
|
| 1047 | + $this->checkout->set_reg_status_updated($registration->ID(), false); |
|
| 1048 | + } |
|
| 1049 | + } |
|
| 1050 | + } |
|
| 1051 | + |
|
| 1052 | + |
|
| 1053 | + /** |
|
| 1054 | + * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object |
|
| 1055 | + * |
|
| 1056 | + * @access private |
|
| 1057 | + * @param EE_Transaction $transaction |
|
| 1058 | + * @return array |
|
| 1059 | + * @throws InvalidDataTypeException |
|
| 1060 | + * @throws InvalidEntityException |
|
| 1061 | + * @throws EE_Error |
|
| 1062 | + */ |
|
| 1063 | + private function _initialize_registrations(EE_Transaction $transaction) |
|
| 1064 | + { |
|
| 1065 | + $att_nmbr = 0; |
|
| 1066 | + $registrations = array(); |
|
| 1067 | + if ($transaction instanceof EE_Transaction) { |
|
| 1068 | + /** @type EE_Registration_Processor $registration_processor */ |
|
| 1069 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
| 1070 | + $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count(); |
|
| 1071 | + // now let's add the cart items to the $transaction |
|
| 1072 | + foreach ($this->checkout->cart->get_tickets() as $line_item) { |
|
| 1073 | + // do the following for each ticket of this type they selected |
|
| 1074 | + for ($x = 1; $x <= $line_item->quantity(); $x++) { |
|
| 1075 | + $att_nmbr++; |
|
| 1076 | + /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */ |
|
| 1077 | + $CreateRegistrationCommand = EE_Registry::instance()->create( |
|
| 1078 | + 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand', |
|
| 1079 | + array( |
|
| 1080 | + $transaction, |
|
| 1081 | + $line_item, |
|
| 1082 | + $att_nmbr, |
|
| 1083 | + $this->checkout->total_ticket_count, |
|
| 1084 | + ) |
|
| 1085 | + ); |
|
| 1086 | + // override capabilities for frontend registrations |
|
| 1087 | + if (! is_admin()) { |
|
| 1088 | + $CreateRegistrationCommand->setCapCheck( |
|
| 1089 | + new PublicCapabilities('', 'create_new_registration') |
|
| 1090 | + ); |
|
| 1091 | + } |
|
| 1092 | + $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand); |
|
| 1093 | + if (! $registration instanceof EE_Registration) { |
|
| 1094 | + throw new InvalidEntityException($registration, 'EE_Registration'); |
|
| 1095 | + } |
|
| 1096 | + $registrations[ $registration->ID() ] = $registration; |
|
| 1097 | + } |
|
| 1098 | + } |
|
| 1099 | + $registration_processor->fix_reg_final_price_rounding_issue($transaction); |
|
| 1100 | + } |
|
| 1101 | + return $registrations; |
|
| 1102 | + } |
|
| 1103 | + |
|
| 1104 | + |
|
| 1105 | + /** |
|
| 1106 | + * sorts registrations by REG_count |
|
| 1107 | + * |
|
| 1108 | + * @access public |
|
| 1109 | + * @param EE_Registration $reg_A |
|
| 1110 | + * @param EE_Registration $reg_B |
|
| 1111 | + * @return int |
|
| 1112 | + */ |
|
| 1113 | + public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B) |
|
| 1114 | + { |
|
| 1115 | + // this shouldn't ever happen within the same TXN, but oh well |
|
| 1116 | + if ($reg_A->count() === $reg_B->count()) { |
|
| 1117 | + return 0; |
|
| 1118 | + } |
|
| 1119 | + return ($reg_A->count() > $reg_B->count()) ? 1 : -1; |
|
| 1120 | + } |
|
| 1121 | + |
|
| 1122 | + |
|
| 1123 | + /** |
|
| 1124 | + * _final_verifications |
|
| 1125 | + * just makes sure that everything is set up correctly before proceeding |
|
| 1126 | + * |
|
| 1127 | + * @access private |
|
| 1128 | + * @return bool |
|
| 1129 | + * @throws EE_Error |
|
| 1130 | + */ |
|
| 1131 | + private function _final_verifications() |
|
| 1132 | + { |
|
| 1133 | + // filter checkout |
|
| 1134 | + $this->checkout = apply_filters( |
|
| 1135 | + 'FHEE__EED_Single_Page_Checkout___final_verifications__checkout', |
|
| 1136 | + $this->checkout |
|
| 1137 | + ); |
|
| 1138 | + // verify that current step is still set correctly |
|
| 1139 | + if (! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) { |
|
| 1140 | + EE_Error::add_error( |
|
| 1141 | + esc_html__( |
|
| 1142 | + 'We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', |
|
| 1143 | + 'event_espresso' |
|
| 1144 | + ), |
|
| 1145 | + __FILE__, |
|
| 1146 | + __FUNCTION__, |
|
| 1147 | + __LINE__ |
|
| 1148 | + ); |
|
| 1149 | + return false; |
|
| 1150 | + } |
|
| 1151 | + // if returning to SPCO, then verify that primary registrant is set |
|
| 1152 | + if (! empty($this->checkout->reg_url_link)) { |
|
| 1153 | + $valid_registrant = $this->checkout->transaction->primary_registration(); |
|
| 1154 | + if (! $valid_registrant instanceof EE_Registration) { |
|
| 1155 | + EE_Error::add_error( |
|
| 1156 | + esc_html__( |
|
| 1157 | + 'We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', |
|
| 1158 | + 'event_espresso' |
|
| 1159 | + ), |
|
| 1160 | + __FILE__, |
|
| 1161 | + __FUNCTION__, |
|
| 1162 | + __LINE__ |
|
| 1163 | + ); |
|
| 1164 | + return false; |
|
| 1165 | + } |
|
| 1166 | + $valid_registrant = null; |
|
| 1167 | + foreach ($this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration) { |
|
| 1168 | + if ($registration instanceof EE_Registration |
|
| 1169 | + && $registration->reg_url_link() === $this->checkout->reg_url_link |
|
| 1170 | + ) { |
|
| 1171 | + $valid_registrant = $registration; |
|
| 1172 | + } |
|
| 1173 | + } |
|
| 1174 | + if (! $valid_registrant instanceof EE_Registration) { |
|
| 1175 | + // hmmm... maybe we have the wrong session because the user is opening multiple tabs ? |
|
| 1176 | + if (EED_Single_Page_Checkout::$_checkout_verified) { |
|
| 1177 | + // clear the session, mark the checkout as unverified, and try again |
|
| 1178 | + EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
| 1179 | + EED_Single_Page_Checkout::$_initialized = false; |
|
| 1180 | + EED_Single_Page_Checkout::$_checkout_verified = false; |
|
| 1181 | + $this->_initialize(); |
|
| 1182 | + EE_Error::reset_notices(); |
|
| 1183 | + return false; |
|
| 1184 | + } |
|
| 1185 | + EE_Error::add_error( |
|
| 1186 | + esc_html__( |
|
| 1187 | + 'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.', |
|
| 1188 | + 'event_espresso' |
|
| 1189 | + ), |
|
| 1190 | + __FILE__, |
|
| 1191 | + __FUNCTION__, |
|
| 1192 | + __LINE__ |
|
| 1193 | + ); |
|
| 1194 | + return false; |
|
| 1195 | + } |
|
| 1196 | + } |
|
| 1197 | + // now that things have been kinda sufficiently verified, |
|
| 1198 | + // let's add the checkout to the session so that it's available to other systems |
|
| 1199 | + EE_Registry::instance()->SSN->set_checkout($this->checkout); |
|
| 1200 | + return true; |
|
| 1201 | + } |
|
| 1202 | + |
|
| 1203 | + |
|
| 1204 | + /** |
|
| 1205 | + * _initialize_reg_steps |
|
| 1206 | + * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required |
|
| 1207 | + * then loops thru all of the active reg steps and calls the initialize_reg_step() method |
|
| 1208 | + * |
|
| 1209 | + * @access private |
|
| 1210 | + * @param bool $reinitializing |
|
| 1211 | + * @throws EE_Error |
|
| 1212 | + */ |
|
| 1213 | + private function _initialize_reg_steps($reinitializing = false) |
|
| 1214 | + { |
|
| 1215 | + $this->checkout->set_reg_step_initiated($this->checkout->current_step); |
|
| 1216 | + // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS |
|
| 1217 | + foreach ($this->checkout->reg_steps as $reg_step) { |
|
| 1218 | + if (! $reg_step->initialize_reg_step()) { |
|
| 1219 | + // if not initialized then maybe this step is being removed... |
|
| 1220 | + if (! $reinitializing && $reg_step->is_current_step()) { |
|
| 1221 | + // if it was the current step, then we need to start over here |
|
| 1222 | + $this->_initialize_reg_steps(true); |
|
| 1223 | + return; |
|
| 1224 | + } |
|
| 1225 | + continue; |
|
| 1226 | + } |
|
| 1227 | + // add css and JS for current step |
|
| 1228 | + $this->add_styles_and_scripts($reg_step); |
|
| 1229 | + if ($reg_step->is_current_step()) { |
|
| 1230 | + // the text that appears on the reg step form submit button |
|
| 1231 | + $reg_step->set_submit_button_text(); |
|
| 1232 | + } |
|
| 1233 | + } |
|
| 1234 | + // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information |
|
| 1235 | + do_action( |
|
| 1236 | + "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}", |
|
| 1237 | + $this->checkout->current_step |
|
| 1238 | + ); |
|
| 1239 | + } |
|
| 1240 | + |
|
| 1241 | + |
|
| 1242 | + /** |
|
| 1243 | + * _check_form_submission |
|
| 1244 | + * |
|
| 1245 | + * @access private |
|
| 1246 | + * @return boolean |
|
| 1247 | + */ |
|
| 1248 | + private function _check_form_submission() |
|
| 1249 | + { |
|
| 1250 | + // does this request require the reg form to be generated ? |
|
| 1251 | + if ($this->checkout->generate_reg_form) { |
|
| 1252 | + // ever heard that song by Blue Rodeo ? |
|
| 1253 | + try { |
|
| 1254 | + $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form(); |
|
| 1255 | + // if not displaying a form, then check for form submission |
|
| 1256 | + if ($this->checkout->process_form_submission |
|
| 1257 | + && $this->checkout->current_step->reg_form->was_submitted() |
|
| 1258 | + ) { |
|
| 1259 | + // clear out any old data in case this step is being run again |
|
| 1260 | + $this->checkout->current_step->set_valid_data(array()); |
|
| 1261 | + // capture submitted form data |
|
| 1262 | + $this->checkout->current_step->reg_form->receive_form_submission( |
|
| 1263 | + apply_filters( |
|
| 1264 | + 'FHEE__Single_Page_Checkout___check_form_submission__request_params', |
|
| 1265 | + EE_Registry::instance()->REQ->params(), |
|
| 1266 | + $this->checkout |
|
| 1267 | + ) |
|
| 1268 | + ); |
|
| 1269 | + // validate submitted form data |
|
| 1270 | + if (! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) { |
|
| 1271 | + // thou shall not pass !!! |
|
| 1272 | + $this->checkout->continue_reg = false; |
|
| 1273 | + // any form validation errors? |
|
| 1274 | + if ($this->checkout->current_step->reg_form->submission_error_message() !== '') { |
|
| 1275 | + EE_Error::add_error( |
|
| 1276 | + $this->checkout->current_step->reg_form->submission_error_message(), |
|
| 1277 | + __FILE__, |
|
| 1278 | + __FUNCTION__, |
|
| 1279 | + __LINE__ |
|
| 1280 | + ); |
|
| 1281 | + } |
|
| 1282 | + // well not really... what will happen is |
|
| 1283 | + // we'll just get redirected back to redo the current step |
|
| 1284 | + $this->go_to_next_step(); |
|
| 1285 | + return false; |
|
| 1286 | + } |
|
| 1287 | + } |
|
| 1288 | + } catch (EE_Error $e) { |
|
| 1289 | + $e->get_error(); |
|
| 1290 | + } |
|
| 1291 | + } |
|
| 1292 | + return true; |
|
| 1293 | + } |
|
| 1294 | + |
|
| 1295 | + |
|
| 1296 | + /** |
|
| 1297 | + * _process_action |
|
| 1298 | + * |
|
| 1299 | + * @access private |
|
| 1300 | + * @return void |
|
| 1301 | + * @throws EE_Error |
|
| 1302 | + */ |
|
| 1303 | + private function _process_form_action() |
|
| 1304 | + { |
|
| 1305 | + // what cha wanna do? |
|
| 1306 | + switch ($this->checkout->action) { |
|
| 1307 | + // AJAX next step reg form |
|
| 1308 | + case 'display_spco_reg_step': |
|
| 1309 | + $this->checkout->redirect = false; |
|
| 1310 | + if (EE_Registry::instance()->REQ->ajax) { |
|
| 1311 | + $this->checkout->json_response->set_reg_step_html( |
|
| 1312 | + $this->checkout->current_step->display_reg_form() |
|
| 1313 | + ); |
|
| 1314 | + } |
|
| 1315 | + break; |
|
| 1316 | + default: |
|
| 1317 | + // meh... do one of those other steps first |
|
| 1318 | + if (! empty($this->checkout->action) |
|
| 1319 | + && is_callable(array($this->checkout->current_step, $this->checkout->action)) |
|
| 1320 | + ) { |
|
| 1321 | + // dynamically creates hook point like: |
|
| 1322 | + // AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step |
|
| 1323 | + do_action( |
|
| 1324 | + "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
| 1325 | + $this->checkout->current_step |
|
| 1326 | + ); |
|
| 1327 | + // call action on current step |
|
| 1328 | + if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) { |
|
| 1329 | + // good registrant, you get to proceed |
|
| 1330 | + if ($this->checkout->current_step->success_message() !== '' |
|
| 1331 | + && apply_filters( |
|
| 1332 | + 'FHEE__Single_Page_Checkout___process_form_action__display_success', |
|
| 1333 | + false |
|
| 1334 | + ) |
|
| 1335 | + ) { |
|
| 1336 | + EE_Error::add_success( |
|
| 1337 | + $this->checkout->current_step->success_message() |
|
| 1338 | + . '<br />' . $this->checkout->next_step->_instructions() |
|
| 1339 | + ); |
|
| 1340 | + } |
|
| 1341 | + // pack it up, pack it in... |
|
| 1342 | + $this->_setup_redirect(); |
|
| 1343 | + } |
|
| 1344 | + // dynamically creates hook point like: |
|
| 1345 | + // AHEE__Single_Page_Checkout__after_payment_options__process_reg_step |
|
| 1346 | + do_action( |
|
| 1347 | + "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}", |
|
| 1348 | + $this->checkout->current_step |
|
| 1349 | + ); |
|
| 1350 | + } else { |
|
| 1351 | + EE_Error::add_error( |
|
| 1352 | + sprintf( |
|
| 1353 | + esc_html__( |
|
| 1354 | + 'The requested form action "%s" does not exist for the current "%s" registration step.', |
|
| 1355 | + 'event_espresso' |
|
| 1356 | + ), |
|
| 1357 | + $this->checkout->action, |
|
| 1358 | + $this->checkout->current_step->name() |
|
| 1359 | + ), |
|
| 1360 | + __FILE__, |
|
| 1361 | + __FUNCTION__, |
|
| 1362 | + __LINE__ |
|
| 1363 | + ); |
|
| 1364 | + } |
|
| 1365 | + // end default |
|
| 1366 | + } |
|
| 1367 | + // store our progress so far |
|
| 1368 | + $this->checkout->stash_transaction_and_checkout(); |
|
| 1369 | + // advance to the next step! If you pass GO, collect $200 |
|
| 1370 | + $this->go_to_next_step(); |
|
| 1371 | + } |
|
| 1372 | + |
|
| 1373 | + |
|
| 1374 | + /** |
|
| 1375 | + * @param EED_Single_Page_Checkout|EE_SPCO_Reg_Step $target |
|
| 1376 | + * @param object $target an object with the method `translate_js_strings` and `enqueue_styles_and_scripts`. |
|
| 1377 | + * @return void |
|
| 1378 | + */ |
|
| 1379 | + public function add_styles_and_scripts($target) |
|
| 1380 | + { |
|
| 1381 | + // i18n |
|
| 1382 | + $target->translate_js_strings(); |
|
| 1383 | + if ($this->checkout->admin_request) { |
|
| 1384 | + add_action('admin_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
| 1385 | + } else { |
|
| 1386 | + add_action('wp_enqueue_scripts', array($target, 'enqueue_styles_and_scripts'), 10); |
|
| 1387 | + } |
|
| 1388 | + } |
|
| 1389 | + |
|
| 1390 | + /** |
|
| 1391 | + * translate_js_strings |
|
| 1392 | + * |
|
| 1393 | + * @access public |
|
| 1394 | + * @return void |
|
| 1395 | + */ |
|
| 1396 | + public function translate_js_strings() |
|
| 1397 | + { |
|
| 1398 | + EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit; |
|
| 1399 | + EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link; |
|
| 1400 | + EE_Registry::$i18n_js_strings['server_error'] = esc_html__( |
|
| 1401 | + 'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
| 1402 | + 'event_espresso' |
|
| 1403 | + ); |
|
| 1404 | + EE_Registry::$i18n_js_strings['invalid_json_response'] = esc_html__( |
|
| 1405 | + 'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.', |
|
| 1406 | + 'event_espresso' |
|
| 1407 | + ); |
|
| 1408 | + EE_Registry::$i18n_js_strings['validation_error'] = esc_html__( |
|
| 1409 | + 'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.', |
|
| 1410 | + 'event_espresso' |
|
| 1411 | + ); |
|
| 1412 | + EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__( |
|
| 1413 | + 'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.', |
|
| 1414 | + 'event_espresso' |
|
| 1415 | + ); |
|
| 1416 | + EE_Registry::$i18n_js_strings['reg_step_error'] = esc_html__( |
|
| 1417 | + 'This registration step could not be completed. Please refresh the page and try again.', |
|
| 1418 | + 'event_espresso' |
|
| 1419 | + ); |
|
| 1420 | + EE_Registry::$i18n_js_strings['invalid_coupon'] = esc_html__( |
|
| 1421 | + 'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.', |
|
| 1422 | + 'event_espresso' |
|
| 1423 | + ); |
|
| 1424 | + EE_Registry::$i18n_js_strings['process_registration'] = sprintf( |
|
| 1425 | + esc_html__( |
|
| 1426 | + 'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.', |
|
| 1427 | + 'event_espresso' |
|
| 1428 | + ), |
|
| 1429 | + '<br/>', |
|
| 1430 | + '<br/>' |
|
| 1431 | + ); |
|
| 1432 | + EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language'); |
|
| 1433 | + EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id(); |
|
| 1434 | + EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency; |
|
| 1435 | + EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20'; |
|
| 1436 | + EE_Registry::$i18n_js_strings['timer_years'] = esc_html__('years', 'event_espresso'); |
|
| 1437 | + EE_Registry::$i18n_js_strings['timer_months'] = esc_html__('months', 'event_espresso'); |
|
| 1438 | + EE_Registry::$i18n_js_strings['timer_weeks'] = esc_html__('weeks', 'event_espresso'); |
|
| 1439 | + EE_Registry::$i18n_js_strings['timer_days'] = esc_html__('days', 'event_espresso'); |
|
| 1440 | + EE_Registry::$i18n_js_strings['timer_hours'] = esc_html__('hours', 'event_espresso'); |
|
| 1441 | + EE_Registry::$i18n_js_strings['timer_minutes'] = esc_html__('minutes', 'event_espresso'); |
|
| 1442 | + EE_Registry::$i18n_js_strings['timer_seconds'] = esc_html__('seconds', 'event_espresso'); |
|
| 1443 | + EE_Registry::$i18n_js_strings['timer_year'] = esc_html__('year', 'event_espresso'); |
|
| 1444 | + EE_Registry::$i18n_js_strings['timer_month'] = esc_html__('month', 'event_espresso'); |
|
| 1445 | + EE_Registry::$i18n_js_strings['timer_week'] = esc_html__('week', 'event_espresso'); |
|
| 1446 | + EE_Registry::$i18n_js_strings['timer_day'] = esc_html__('day', 'event_espresso'); |
|
| 1447 | + EE_Registry::$i18n_js_strings['timer_hour'] = esc_html__('hour', 'event_espresso'); |
|
| 1448 | + EE_Registry::$i18n_js_strings['timer_minute'] = esc_html__('minute', 'event_espresso'); |
|
| 1449 | + EE_Registry::$i18n_js_strings['timer_second'] = esc_html__('second', 'event_espresso'); |
|
| 1450 | + EE_Registry::$i18n_js_strings['registration_expiration_notice'] = EED_Single_Page_Checkout::getRegistrationExpirationNotice( |
|
| 1451 | + ); |
|
| 1452 | + EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters( |
|
| 1453 | + 'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', |
|
| 1454 | + true |
|
| 1455 | + ); |
|
| 1456 | + EE_Registry::$i18n_js_strings['session_extension'] = absint( |
|
| 1457 | + apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS) |
|
| 1458 | + ); |
|
| 1459 | + EE_Registry::$i18n_js_strings['session_expiration'] = gmdate( |
|
| 1460 | + 'M d, Y H:i:s', |
|
| 1461 | + EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
| 1462 | + ); |
|
| 1463 | + } |
|
| 1464 | + |
|
| 1465 | + |
|
| 1466 | + /** |
|
| 1467 | + * enqueue_styles_and_scripts |
|
| 1468 | + * |
|
| 1469 | + * @access public |
|
| 1470 | + * @return void |
|
| 1471 | + * @throws EE_Error |
|
| 1472 | + */ |
|
| 1473 | + public function enqueue_styles_and_scripts() |
|
| 1474 | + { |
|
| 1475 | + // load css |
|
| 1476 | + wp_register_style( |
|
| 1477 | + 'single_page_checkout', |
|
| 1478 | + SPCO_CSS_URL . 'single_page_checkout.css', |
|
| 1479 | + array('espresso_default'), |
|
| 1480 | + EVENT_ESPRESSO_VERSION |
|
| 1481 | + ); |
|
| 1482 | + wp_enqueue_style('single_page_checkout'); |
|
| 1483 | + // load JS |
|
| 1484 | + wp_register_script( |
|
| 1485 | + 'jquery_plugin', |
|
| 1486 | + EE_THIRD_PARTY_URL . 'jquery .plugin.min.js', |
|
| 1487 | + array('jquery'), |
|
| 1488 | + '1.0.1', |
|
| 1489 | + true |
|
| 1490 | + ); |
|
| 1491 | + wp_register_script( |
|
| 1492 | + 'jquery_countdown', |
|
| 1493 | + EE_THIRD_PARTY_URL . 'jquery .countdown.min.js', |
|
| 1494 | + array('jquery_plugin'), |
|
| 1495 | + '2.1.0', |
|
| 1496 | + true |
|
| 1497 | + ); |
|
| 1498 | + wp_register_script( |
|
| 1499 | + 'single_page_checkout', |
|
| 1500 | + SPCO_JS_URL . 'single_page_checkout.js', |
|
| 1501 | + array('espresso_core', 'underscore', 'ee_form_section_validation'), |
|
| 1502 | + EVENT_ESPRESSO_VERSION, |
|
| 1503 | + true |
|
| 1504 | + ); |
|
| 1505 | + if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) { |
|
| 1506 | + $this->checkout->registration_form->enqueue_js(); |
|
| 1507 | + } |
|
| 1508 | + if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) { |
|
| 1509 | + $this->checkout->current_step->reg_form->enqueue_js(); |
|
| 1510 | + } |
|
| 1511 | + wp_enqueue_script('single_page_checkout'); |
|
| 1512 | + if (apply_filters('FHEE__registration_page_wrapper_template__display_time_limit', false)) { |
|
| 1513 | + wp_enqueue_script('jquery_countdown'); |
|
| 1514 | + } |
|
| 1515 | + /** |
|
| 1516 | + * global action hook for enqueueing styles and scripts with |
|
| 1517 | + * spco calls. |
|
| 1518 | + */ |
|
| 1519 | + do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this); |
|
| 1520 | + /** |
|
| 1521 | + * dynamic action hook for enqueueing styles and scripts with spco calls. |
|
| 1522 | + * The hook will end up being something like: |
|
| 1523 | + * AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information |
|
| 1524 | + */ |
|
| 1525 | + do_action( |
|
| 1526 | + 'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(), |
|
| 1527 | + $this |
|
| 1528 | + ); |
|
| 1529 | + } |
|
| 1530 | + |
|
| 1531 | + |
|
| 1532 | + /** |
|
| 1533 | + * display the Registration Single Page Checkout Form |
|
| 1534 | + * |
|
| 1535 | + * @access private |
|
| 1536 | + * @return void |
|
| 1537 | + * @throws EE_Error |
|
| 1538 | + */ |
|
| 1539 | + private function _display_spco_reg_form() |
|
| 1540 | + { |
|
| 1541 | + // if registering via the admin, just display the reg form for the current step |
|
| 1542 | + if ($this->checkout->admin_request) { |
|
| 1543 | + EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form()); |
|
| 1544 | + } else { |
|
| 1545 | + // add powered by EE msg |
|
| 1546 | + add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer')); |
|
| 1547 | + $empty_cart = count($this->checkout->transaction |
|
| 1548 | + ->registrations($this->checkout->reg_cache_where_params)) < 1; |
|
| 1549 | + EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart; |
|
| 1550 | + $cookies_not_set_msg = ''; |
|
| 1551 | + if ($empty_cart) { |
|
| 1552 | + $cookies_not_set_msg = apply_filters( |
|
| 1553 | + 'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg', |
|
| 1554 | + sprintf( |
|
| 1555 | + esc_html__( |
|
| 1556 | + '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s', |
|
| 1557 | + 'event_espresso' |
|
| 1558 | + ), |
|
| 1559 | + '<div class="ee-attention hidden" id="ee-cookies-not-set-msg">', |
|
| 1560 | + '</div>', |
|
| 1561 | + '<h6 class="important-notice">', |
|
| 1562 | + '</h6>', |
|
| 1563 | + '<p>', |
|
| 1564 | + '</p>', |
|
| 1565 | + '<br />', |
|
| 1566 | + '<a href="http://www.whatarecookies.com/enable.asp" target="_blank" rel="noopener noreferrer">', |
|
| 1567 | + '</a>' |
|
| 1568 | + ) |
|
| 1569 | + ); |
|
| 1570 | + } |
|
| 1571 | + $this->checkout->registration_form = new EE_Form_Section_Proper( |
|
| 1572 | + array( |
|
| 1573 | + 'name' => 'single-page-checkout', |
|
| 1574 | + 'html_id' => 'ee-single-page-checkout-dv', |
|
| 1575 | + 'layout_strategy' => |
|
| 1576 | + new EE_Template_Layout( |
|
| 1577 | + array( |
|
| 1578 | + 'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php', |
|
| 1579 | + 'template_args' => array( |
|
| 1580 | + 'empty_cart' => $empty_cart, |
|
| 1581 | + 'revisit' => $this->checkout->revisit, |
|
| 1582 | + 'reg_steps' => $this->checkout->reg_steps, |
|
| 1583 | + 'next_step' => $this->checkout->next_step instanceof EE_SPCO_Reg_Step |
|
| 1584 | + ? $this->checkout->next_step->slug() |
|
| 1585 | + : '', |
|
| 1586 | + 'empty_msg' => apply_filters( |
|
| 1587 | + 'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg', |
|
| 1588 | + sprintf( |
|
| 1589 | + esc_html__( |
|
| 1590 | + 'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.', |
|
| 1591 | + 'event_espresso' |
|
| 1592 | + ), |
|
| 1593 | + '<a href="' |
|
| 1594 | + . get_post_type_archive_link('espresso_events') |
|
| 1595 | + . '" title="', |
|
| 1596 | + '">', |
|
| 1597 | + '</a>' |
|
| 1598 | + ) |
|
| 1599 | + ), |
|
| 1600 | + 'cookies_not_set_msg' => $cookies_not_set_msg, |
|
| 1601 | + 'registration_time_limit' => $this->checkout->get_registration_time_limit(), |
|
| 1602 | + 'session_expiration' => gmdate( |
|
| 1603 | + 'M d, Y H:i:s', |
|
| 1604 | + EE_Registry::instance()->SSN->expiration() |
|
| 1605 | + + (get_option('gmt_offset') * HOUR_IN_SECONDS) |
|
| 1606 | + ), |
|
| 1607 | + ), |
|
| 1608 | + ) |
|
| 1609 | + ), |
|
| 1610 | + ) |
|
| 1611 | + ); |
|
| 1612 | + // load template and add to output sent that gets filtered into the_content() |
|
| 1613 | + EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html()); |
|
| 1614 | + } |
|
| 1615 | + } |
|
| 1616 | + |
|
| 1617 | + |
|
| 1618 | + /** |
|
| 1619 | + * add_extra_finalize_registration_inputs |
|
| 1620 | + * |
|
| 1621 | + * @access public |
|
| 1622 | + * @param $next_step |
|
| 1623 | + * @internal param string $label |
|
| 1624 | + * @return void |
|
| 1625 | + */ |
|
| 1626 | + public function add_extra_finalize_registration_inputs($next_step) |
|
| 1627 | + { |
|
| 1628 | + if ($next_step === 'finalize_registration') { |
|
| 1629 | + echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>'; |
|
| 1630 | + } |
|
| 1631 | + } |
|
| 1632 | + |
|
| 1633 | + |
|
| 1634 | + /** |
|
| 1635 | + * display_registration_footer |
|
| 1636 | + * |
|
| 1637 | + * @access public |
|
| 1638 | + * @return string |
|
| 1639 | + */ |
|
| 1640 | + public static function display_registration_footer() |
|
| 1641 | + { |
|
| 1642 | + if (apply_filters( |
|
| 1643 | + 'FHEE__EE_Front__Controller__show_reg_footer', |
|
| 1644 | + EE_Registry::instance()->CFG->admin->show_reg_footer |
|
| 1645 | + )) { |
|
| 1646 | + add_filter( |
|
| 1647 | + 'FHEE__EEH_Template__powered_by_event_espresso__url', |
|
| 1648 | + function ($url) { |
|
| 1649 | + return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url); |
|
| 1650 | + } |
|
| 1651 | + ); |
|
| 1652 | + echo apply_filters( |
|
| 1653 | + 'FHEE__EE_Front_Controller__display_registration_footer', |
|
| 1654 | + \EEH_Template::powered_by_event_espresso( |
|
| 1655 | + '', |
|
| 1656 | + 'espresso-registration-footer-dv', |
|
| 1657 | + array('utm_content' => 'registration_checkout') |
|
| 1658 | + ) |
|
| 1659 | + ); |
|
| 1660 | + } |
|
| 1661 | + return ''; |
|
| 1662 | + } |
|
| 1663 | + |
|
| 1664 | + |
|
| 1665 | + /** |
|
| 1666 | + * unlock_transaction |
|
| 1667 | + * |
|
| 1668 | + * @access public |
|
| 1669 | + * @return void |
|
| 1670 | + * @throws EE_Error |
|
| 1671 | + */ |
|
| 1672 | + public function unlock_transaction() |
|
| 1673 | + { |
|
| 1674 | + if ($this->checkout->transaction instanceof EE_Transaction) { |
|
| 1675 | + $this->checkout->transaction->unlock(); |
|
| 1676 | + } |
|
| 1677 | + } |
|
| 1678 | + |
|
| 1679 | + |
|
| 1680 | + /** |
|
| 1681 | + * _setup_redirect |
|
| 1682 | + * |
|
| 1683 | + * @access private |
|
| 1684 | + * @return void |
|
| 1685 | + */ |
|
| 1686 | + private function _setup_redirect() |
|
| 1687 | + { |
|
| 1688 | + if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) { |
|
| 1689 | + $this->checkout->redirect = true; |
|
| 1690 | + if (empty($this->checkout->redirect_url)) { |
|
| 1691 | + $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url(); |
|
| 1692 | + } |
|
| 1693 | + $this->checkout->redirect_url = apply_filters( |
|
| 1694 | + 'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url', |
|
| 1695 | + $this->checkout->redirect_url, |
|
| 1696 | + $this->checkout |
|
| 1697 | + ); |
|
| 1698 | + } |
|
| 1699 | + } |
|
| 1700 | + |
|
| 1701 | + |
|
| 1702 | + /** |
|
| 1703 | + * handle ajax message responses and redirects |
|
| 1704 | + * |
|
| 1705 | + * @access public |
|
| 1706 | + * @return void |
|
| 1707 | + * @throws EE_Error |
|
| 1708 | + */ |
|
| 1709 | + public function go_to_next_step() |
|
| 1710 | + { |
|
| 1711 | + if (EE_Registry::instance()->REQ->ajax) { |
|
| 1712 | + // capture contents of output buffer we started earlier in the request, and insert into JSON response |
|
| 1713 | + $this->checkout->json_response->set_unexpected_errors(ob_get_clean()); |
|
| 1714 | + } |
|
| 1715 | + $this->unlock_transaction(); |
|
| 1716 | + // just return for these conditions |
|
| 1717 | + if ($this->checkout->admin_request |
|
| 1718 | + || $this->checkout->action === 'redirect_form' |
|
| 1719 | + || $this->checkout->action === 'update_checkout' |
|
| 1720 | + ) { |
|
| 1721 | + return; |
|
| 1722 | + } |
|
| 1723 | + // AJAX response |
|
| 1724 | + $this->_handle_json_response(); |
|
| 1725 | + // redirect to next step or the Thank You page |
|
| 1726 | + $this->_handle_html_redirects(); |
|
| 1727 | + // hmmm... must be something wrong, so let's just display the form again ! |
|
| 1728 | + $this->_display_spco_reg_form(); |
|
| 1729 | + } |
|
| 1730 | + |
|
| 1731 | + |
|
| 1732 | + /** |
|
| 1733 | + * _handle_json_response |
|
| 1734 | + * |
|
| 1735 | + * @access protected |
|
| 1736 | + * @return void |
|
| 1737 | + */ |
|
| 1738 | + protected function _handle_json_response() |
|
| 1739 | + { |
|
| 1740 | + // if this is an ajax request |
|
| 1741 | + if (EE_Registry::instance()->REQ->ajax) { |
|
| 1742 | + $this->checkout->json_response->set_registration_time_limit( |
|
| 1743 | + $this->checkout->get_registration_time_limit() |
|
| 1744 | + ); |
|
| 1745 | + $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing); |
|
| 1746 | + // just send the ajax ( |
|
| 1747 | + $json_response = apply_filters( |
|
| 1748 | + 'FHEE__EE_Single_Page_Checkout__JSON_response', |
|
| 1749 | + $this->checkout->json_response |
|
| 1750 | + ); |
|
| 1751 | + echo $json_response; |
|
| 1752 | + exit(); |
|
| 1753 | + } |
|
| 1754 | + } |
|
| 1755 | + |
|
| 1756 | + |
|
| 1757 | + /** |
|
| 1758 | + * _handle_redirects |
|
| 1759 | + * |
|
| 1760 | + * @access protected |
|
| 1761 | + * @return void |
|
| 1762 | + */ |
|
| 1763 | + protected function _handle_html_redirects() |
|
| 1764 | + { |
|
| 1765 | + // going somewhere ? |
|
| 1766 | + if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) { |
|
| 1767 | + // store notices in a transient |
|
| 1768 | + EE_Error::get_notices(false, true, true); |
|
| 1769 | + wp_safe_redirect($this->checkout->redirect_url); |
|
| 1770 | + exit(); |
|
| 1771 | + } |
|
| 1772 | + } |
|
| 1773 | + |
|
| 1774 | + |
|
| 1775 | + /** |
|
| 1776 | + * set_checkout_anchor |
|
| 1777 | + * |
|
| 1778 | + * @access public |
|
| 1779 | + * @return void |
|
| 1780 | + */ |
|
| 1781 | + public function set_checkout_anchor() |
|
| 1782 | + { |
|
| 1783 | + echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>'; |
|
| 1784 | + } |
|
| 1785 | + |
|
| 1786 | + /** |
|
| 1787 | + * getRegistrationExpirationNotice |
|
| 1788 | + * |
|
| 1789 | + * @since 4.9.59.p |
|
| 1790 | + * @access public |
|
| 1791 | + * @return string |
|
| 1792 | + */ |
|
| 1793 | + public static function getRegistrationExpirationNotice() |
|
| 1794 | + { |
|
| 1795 | + return sprintf( |
|
| 1796 | + esc_html__( |
|
| 1797 | + '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please accept our apologies for any inconvenience this may have caused.%8$s', |
|
| 1798 | + 'event_espresso' |
|
| 1799 | + ), |
|
| 1800 | + '<h4 class="important-notice">', |
|
| 1801 | + '</h4>', |
|
| 1802 | + '<br />', |
|
| 1803 | + '<p>', |
|
| 1804 | + '<a href="' . get_post_type_archive_link('espresso_events') . '" title="', |
|
| 1805 | + '">', |
|
| 1806 | + '</a>', |
|
| 1807 | + '</p>' |
|
| 1808 | + ); |
|
| 1809 | + } |
|
| 1810 | 1810 | } |
@@ -33,725 +33,725 @@ |
||
| 33 | 33 | class DisplayTicketSelector |
| 34 | 34 | { |
| 35 | 35 | |
| 36 | - /** |
|
| 37 | - * event that ticket selector is being generated for |
|
| 38 | - * |
|
| 39 | - * @access protected |
|
| 40 | - * @var EE_Event $event |
|
| 41 | - */ |
|
| 42 | - protected $event; |
|
| 43 | - |
|
| 44 | - /** |
|
| 45 | - * Used to flag when the ticket selector is being called from an external iframe. |
|
| 46 | - * |
|
| 47 | - * @var bool $iframe |
|
| 48 | - */ |
|
| 49 | - protected $iframe = false; |
|
| 50 | - |
|
| 51 | - /** |
|
| 52 | - * max attendees that can register for event at one time |
|
| 53 | - * |
|
| 54 | - * @var int $max_attendees |
|
| 55 | - */ |
|
| 56 | - private $max_attendees = EE_INF; |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * @var string $date_format |
|
| 60 | - */ |
|
| 61 | - private $date_format; |
|
| 62 | - |
|
| 63 | - /** |
|
| 64 | - * @var string $time_format |
|
| 65 | - */ |
|
| 66 | - private $time_format; |
|
| 67 | - |
|
| 68 | - /** |
|
| 69 | - * @var boolean $display_full_ui |
|
| 70 | - */ |
|
| 71 | - private $display_full_ui; |
|
| 72 | - |
|
| 73 | - |
|
| 74 | - /** |
|
| 75 | - * DisplayTicketSelector constructor. |
|
| 76 | - * |
|
| 77 | - * @param bool $iframe |
|
| 78 | - */ |
|
| 79 | - public function __construct($iframe = false) |
|
| 80 | - { |
|
| 81 | - $this->iframe = $iframe; |
|
| 82 | - $this->date_format = apply_filters( |
|
| 83 | - 'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format', |
|
| 84 | - get_option('date_format') |
|
| 85 | - ); |
|
| 86 | - $this->time_format = apply_filters( |
|
| 87 | - 'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format', |
|
| 88 | - get_option('time_format') |
|
| 89 | - ); |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - |
|
| 93 | - /** |
|
| 94 | - * @return bool |
|
| 95 | - */ |
|
| 96 | - public function isIframe() |
|
| 97 | - { |
|
| 98 | - return $this->iframe; |
|
| 99 | - } |
|
| 100 | - |
|
| 101 | - |
|
| 102 | - /** |
|
| 103 | - * @param boolean $iframe |
|
| 104 | - */ |
|
| 105 | - public function setIframe($iframe = true) |
|
| 106 | - { |
|
| 107 | - $this->iframe = filter_var($iframe, FILTER_VALIDATE_BOOLEAN); |
|
| 108 | - } |
|
| 109 | - |
|
| 110 | - |
|
| 111 | - /** |
|
| 112 | - * finds and sets the \EE_Event object for use throughout class |
|
| 113 | - * |
|
| 114 | - * @param mixed $event |
|
| 115 | - * @return bool |
|
| 116 | - * @throws EE_Error |
|
| 117 | - * @throws InvalidDataTypeException |
|
| 118 | - * @throws InvalidInterfaceException |
|
| 119 | - * @throws InvalidArgumentException |
|
| 120 | - */ |
|
| 121 | - protected function setEvent($event = null) |
|
| 122 | - { |
|
| 123 | - if ($event === null) { |
|
| 124 | - global $post; |
|
| 125 | - $event = $post; |
|
| 126 | - } |
|
| 127 | - if ($event instanceof EE_Event) { |
|
| 128 | - $this->event = $event; |
|
| 129 | - } elseif ($event instanceof WP_Post) { |
|
| 130 | - if (isset($event->EE_Event) && $event->EE_Event instanceof EE_Event) { |
|
| 131 | - $this->event = $event->EE_Event; |
|
| 132 | - } elseif ($event->post_type === 'espresso_events') { |
|
| 133 | - $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object($event); |
|
| 134 | - $this->event = $event->EE_Event; |
|
| 135 | - } |
|
| 136 | - } else { |
|
| 137 | - $user_msg = __('No Event object or an invalid Event object was supplied.', 'event_espresso'); |
|
| 138 | - $dev_msg = $user_msg . __( |
|
| 139 | - '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.', |
|
| 140 | - 'event_espresso' |
|
| 141 | - ); |
|
| 142 | - EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 143 | - return false; |
|
| 144 | - } |
|
| 145 | - return true; |
|
| 146 | - } |
|
| 147 | - |
|
| 148 | - |
|
| 149 | - /** |
|
| 150 | - * @return int |
|
| 151 | - */ |
|
| 152 | - public function getMaxAttendees() |
|
| 153 | - { |
|
| 154 | - return $this->max_attendees; |
|
| 155 | - } |
|
| 156 | - |
|
| 157 | - |
|
| 158 | - /** |
|
| 159 | - * @param int $max_attendees |
|
| 160 | - */ |
|
| 161 | - public function setMaxAttendees($max_attendees) |
|
| 162 | - { |
|
| 163 | - $this->max_attendees = absint( |
|
| 164 | - apply_filters( |
|
| 165 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets', |
|
| 166 | - $max_attendees |
|
| 167 | - ) |
|
| 168 | - ); |
|
| 169 | - } |
|
| 170 | - |
|
| 171 | - |
|
| 172 | - /** |
|
| 173 | - * Returns whether or not the full ticket selector should be shown or not. |
|
| 174 | - * Currently, it displays on the frontend (including ajax requests) but not the backend |
|
| 175 | - * |
|
| 176 | - * @return bool |
|
| 177 | - */ |
|
| 178 | - private function display_full_ui() |
|
| 179 | - { |
|
| 180 | - if ($this->display_full_ui === null) { |
|
| 181 | - $this->display_full_ui = ! is_admin() || (defined('DOING_AJAX') && DOING_AJAX); |
|
| 182 | - } |
|
| 183 | - return $this->display_full_ui; |
|
| 184 | - } |
|
| 185 | - |
|
| 186 | - |
|
| 187 | - /** |
|
| 188 | - * creates buttons for selecting number of attendees for an event |
|
| 189 | - * |
|
| 190 | - * @param WP_Post|int $event |
|
| 191 | - * @param bool $view_details |
|
| 192 | - * @return string |
|
| 193 | - * @throws EE_Error |
|
| 194 | - * @throws InvalidArgumentException |
|
| 195 | - * @throws InvalidDataTypeException |
|
| 196 | - * @throws InvalidInterfaceException |
|
| 197 | - */ |
|
| 198 | - public function display($event = null, $view_details = false) |
|
| 199 | - { |
|
| 200 | - // reset filter for displaying submit button |
|
| 201 | - remove_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
| 202 | - // poke and prod incoming event till it tells us what it is |
|
| 203 | - if (! $this->setEvent($event)) { |
|
| 204 | - return false; |
|
| 205 | - } |
|
| 206 | - // begin gathering template arguments by getting event status |
|
| 207 | - $template_args = array('event_status' => $this->event->get_active_status()); |
|
| 208 | - if ($this->activeEventAndShowTicketSelector( |
|
| 209 | - $event, |
|
| 210 | - $template_args['event_status'], |
|
| 211 | - $view_details |
|
| 212 | - )) { |
|
| 213 | - return ! is_single() ? $this->displayViewDetailsButton() : ''; |
|
| 214 | - } |
|
| 215 | - // filter the maximum qty that can appear in the Ticket Selector qty dropdowns |
|
| 216 | - $this->setMaxAttendees($this->event->additional_limit()); |
|
| 217 | - if ($this->getMaxAttendees() < 1) { |
|
| 218 | - return $this->ticketSalesClosedMessage(); |
|
| 219 | - } |
|
| 220 | - // is the event expired ? |
|
| 221 | - $template_args['event_is_expired'] = ! is_admin() ? $this->event->is_expired() : false; |
|
| 222 | - if ($template_args['event_is_expired']) { |
|
| 223 | - return $this->expiredEventMessage(); |
|
| 224 | - } |
|
| 225 | - // get all tickets for this event ordered by the datetime |
|
| 226 | - $tickets = $this->getTickets(); |
|
| 227 | - if (count($tickets) < 1) { |
|
| 228 | - return $this->noTicketAvailableMessage(); |
|
| 229 | - } |
|
| 230 | - // redirecting to another site for registration ?? |
|
| 231 | - $external_url = (string) $this->event->external_url() |
|
| 232 | - && $this->event->external_url() !== get_the_permalink() |
|
| 233 | - ? $this->event->external_url() |
|
| 234 | - : ''; |
|
| 235 | - // if redirecting to another site for registration, then we don't load the TS |
|
| 236 | - $ticket_selector = $external_url |
|
| 237 | - ? $this->externalEventRegistration() |
|
| 238 | - : $this->loadTicketSelector($tickets, $template_args); |
|
| 239 | - // now set up the form (but not for the admin) |
|
| 240 | - $ticket_selector = $this->display_full_ui() |
|
| 241 | - ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
| 242 | - : $ticket_selector; |
|
| 243 | - // submit button and form close tag |
|
| 244 | - $ticket_selector .= $this->display_full_ui() ? $this->displaySubmitButton($external_url) : ''; |
|
| 245 | - return $ticket_selector; |
|
| 246 | - } |
|
| 247 | - |
|
| 248 | - |
|
| 249 | - /** |
|
| 250 | - * displayTicketSelector |
|
| 251 | - * examines the event properties and determines whether a Ticket Selector should be displayed |
|
| 252 | - * |
|
| 253 | - * @param WP_Post|int $event |
|
| 254 | - * @param string $_event_active_status |
|
| 255 | - * @param bool $view_details |
|
| 256 | - * @return bool |
|
| 257 | - * @throws EE_Error |
|
| 258 | - */ |
|
| 259 | - protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details) |
|
| 260 | - { |
|
| 261 | - $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event; |
|
| 262 | - return $this->display_full_ui() |
|
| 263 | - && ( |
|
| 264 | - ! $this->event->display_ticket_selector() |
|
| 265 | - || $view_details |
|
| 266 | - || post_password_required($event_post) |
|
| 267 | - || ( |
|
| 268 | - $_event_active_status !== EE_Datetime::active |
|
| 269 | - && $_event_active_status !== EE_Datetime::upcoming |
|
| 270 | - && $_event_active_status !== EE_Datetime::sold_out |
|
| 271 | - && ! ( |
|
| 272 | - $_event_active_status === EE_Datetime::inactive |
|
| 273 | - && is_user_logged_in() |
|
| 274 | - ) |
|
| 275 | - ) |
|
| 276 | - ); |
|
| 277 | - } |
|
| 278 | - |
|
| 279 | - |
|
| 280 | - /** |
|
| 281 | - * noTicketAvailableMessage |
|
| 282 | - * notice displayed if event is expired |
|
| 283 | - * |
|
| 284 | - * @return string |
|
| 285 | - * @throws EE_Error |
|
| 286 | - */ |
|
| 287 | - protected function expiredEventMessage() |
|
| 288 | - { |
|
| 289 | - return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
| 290 | - 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
|
| 291 | - 'event_espresso' |
|
| 292 | - ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
| 293 | - } |
|
| 294 | - |
|
| 295 | - |
|
| 296 | - /** |
|
| 297 | - * noTicketAvailableMessage |
|
| 298 | - * notice displayed if event has no more tickets available |
|
| 299 | - * |
|
| 300 | - * @return string |
|
| 301 | - * @throws EE_Error |
|
| 302 | - */ |
|
| 303 | - protected function noTicketAvailableMessage() |
|
| 304 | - { |
|
| 305 | - $no_ticket_available_msg = esc_html__('We\'re sorry, but all ticket sales have ended.', 'event_espresso'); |
|
| 306 | - if (current_user_can('edit_post', $this->event->ID())) { |
|
| 307 | - $no_ticket_available_msg .= sprintf( |
|
| 308 | - esc_html__( |
|
| 309 | - '%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', |
|
| 310 | - 'event_espresso' |
|
| 311 | - ), |
|
| 312 | - '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 313 | - '</b><br />', |
|
| 314 | - '<span class="edit-link"><a class="post-edit-link" href="' |
|
| 315 | - . get_edit_post_link($this->event->ID()) |
|
| 316 | - . '">', |
|
| 317 | - '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->' |
|
| 318 | - ); |
|
| 319 | - } |
|
| 320 | - return ' |
|
| 36 | + /** |
|
| 37 | + * event that ticket selector is being generated for |
|
| 38 | + * |
|
| 39 | + * @access protected |
|
| 40 | + * @var EE_Event $event |
|
| 41 | + */ |
|
| 42 | + protected $event; |
|
| 43 | + |
|
| 44 | + /** |
|
| 45 | + * Used to flag when the ticket selector is being called from an external iframe. |
|
| 46 | + * |
|
| 47 | + * @var bool $iframe |
|
| 48 | + */ |
|
| 49 | + protected $iframe = false; |
|
| 50 | + |
|
| 51 | + /** |
|
| 52 | + * max attendees that can register for event at one time |
|
| 53 | + * |
|
| 54 | + * @var int $max_attendees |
|
| 55 | + */ |
|
| 56 | + private $max_attendees = EE_INF; |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * @var string $date_format |
|
| 60 | + */ |
|
| 61 | + private $date_format; |
|
| 62 | + |
|
| 63 | + /** |
|
| 64 | + * @var string $time_format |
|
| 65 | + */ |
|
| 66 | + private $time_format; |
|
| 67 | + |
|
| 68 | + /** |
|
| 69 | + * @var boolean $display_full_ui |
|
| 70 | + */ |
|
| 71 | + private $display_full_ui; |
|
| 72 | + |
|
| 73 | + |
|
| 74 | + /** |
|
| 75 | + * DisplayTicketSelector constructor. |
|
| 76 | + * |
|
| 77 | + * @param bool $iframe |
|
| 78 | + */ |
|
| 79 | + public function __construct($iframe = false) |
|
| 80 | + { |
|
| 81 | + $this->iframe = $iframe; |
|
| 82 | + $this->date_format = apply_filters( |
|
| 83 | + 'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format', |
|
| 84 | + get_option('date_format') |
|
| 85 | + ); |
|
| 86 | + $this->time_format = apply_filters( |
|
| 87 | + 'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format', |
|
| 88 | + get_option('time_format') |
|
| 89 | + ); |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + |
|
| 93 | + /** |
|
| 94 | + * @return bool |
|
| 95 | + */ |
|
| 96 | + public function isIframe() |
|
| 97 | + { |
|
| 98 | + return $this->iframe; |
|
| 99 | + } |
|
| 100 | + |
|
| 101 | + |
|
| 102 | + /** |
|
| 103 | + * @param boolean $iframe |
|
| 104 | + */ |
|
| 105 | + public function setIframe($iframe = true) |
|
| 106 | + { |
|
| 107 | + $this->iframe = filter_var($iframe, FILTER_VALIDATE_BOOLEAN); |
|
| 108 | + } |
|
| 109 | + |
|
| 110 | + |
|
| 111 | + /** |
|
| 112 | + * finds and sets the \EE_Event object for use throughout class |
|
| 113 | + * |
|
| 114 | + * @param mixed $event |
|
| 115 | + * @return bool |
|
| 116 | + * @throws EE_Error |
|
| 117 | + * @throws InvalidDataTypeException |
|
| 118 | + * @throws InvalidInterfaceException |
|
| 119 | + * @throws InvalidArgumentException |
|
| 120 | + */ |
|
| 121 | + protected function setEvent($event = null) |
|
| 122 | + { |
|
| 123 | + if ($event === null) { |
|
| 124 | + global $post; |
|
| 125 | + $event = $post; |
|
| 126 | + } |
|
| 127 | + if ($event instanceof EE_Event) { |
|
| 128 | + $this->event = $event; |
|
| 129 | + } elseif ($event instanceof WP_Post) { |
|
| 130 | + if (isset($event->EE_Event) && $event->EE_Event instanceof EE_Event) { |
|
| 131 | + $this->event = $event->EE_Event; |
|
| 132 | + } elseif ($event->post_type === 'espresso_events') { |
|
| 133 | + $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object($event); |
|
| 134 | + $this->event = $event->EE_Event; |
|
| 135 | + } |
|
| 136 | + } else { |
|
| 137 | + $user_msg = __('No Event object or an invalid Event object was supplied.', 'event_espresso'); |
|
| 138 | + $dev_msg = $user_msg . __( |
|
| 139 | + '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.', |
|
| 140 | + 'event_espresso' |
|
| 141 | + ); |
|
| 142 | + EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 143 | + return false; |
|
| 144 | + } |
|
| 145 | + return true; |
|
| 146 | + } |
|
| 147 | + |
|
| 148 | + |
|
| 149 | + /** |
|
| 150 | + * @return int |
|
| 151 | + */ |
|
| 152 | + public function getMaxAttendees() |
|
| 153 | + { |
|
| 154 | + return $this->max_attendees; |
|
| 155 | + } |
|
| 156 | + |
|
| 157 | + |
|
| 158 | + /** |
|
| 159 | + * @param int $max_attendees |
|
| 160 | + */ |
|
| 161 | + public function setMaxAttendees($max_attendees) |
|
| 162 | + { |
|
| 163 | + $this->max_attendees = absint( |
|
| 164 | + apply_filters( |
|
| 165 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets', |
|
| 166 | + $max_attendees |
|
| 167 | + ) |
|
| 168 | + ); |
|
| 169 | + } |
|
| 170 | + |
|
| 171 | + |
|
| 172 | + /** |
|
| 173 | + * Returns whether or not the full ticket selector should be shown or not. |
|
| 174 | + * Currently, it displays on the frontend (including ajax requests) but not the backend |
|
| 175 | + * |
|
| 176 | + * @return bool |
|
| 177 | + */ |
|
| 178 | + private function display_full_ui() |
|
| 179 | + { |
|
| 180 | + if ($this->display_full_ui === null) { |
|
| 181 | + $this->display_full_ui = ! is_admin() || (defined('DOING_AJAX') && DOING_AJAX); |
|
| 182 | + } |
|
| 183 | + return $this->display_full_ui; |
|
| 184 | + } |
|
| 185 | + |
|
| 186 | + |
|
| 187 | + /** |
|
| 188 | + * creates buttons for selecting number of attendees for an event |
|
| 189 | + * |
|
| 190 | + * @param WP_Post|int $event |
|
| 191 | + * @param bool $view_details |
|
| 192 | + * @return string |
|
| 193 | + * @throws EE_Error |
|
| 194 | + * @throws InvalidArgumentException |
|
| 195 | + * @throws InvalidDataTypeException |
|
| 196 | + * @throws InvalidInterfaceException |
|
| 197 | + */ |
|
| 198 | + public function display($event = null, $view_details = false) |
|
| 199 | + { |
|
| 200 | + // reset filter for displaying submit button |
|
| 201 | + remove_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
| 202 | + // poke and prod incoming event till it tells us what it is |
|
| 203 | + if (! $this->setEvent($event)) { |
|
| 204 | + return false; |
|
| 205 | + } |
|
| 206 | + // begin gathering template arguments by getting event status |
|
| 207 | + $template_args = array('event_status' => $this->event->get_active_status()); |
|
| 208 | + if ($this->activeEventAndShowTicketSelector( |
|
| 209 | + $event, |
|
| 210 | + $template_args['event_status'], |
|
| 211 | + $view_details |
|
| 212 | + )) { |
|
| 213 | + return ! is_single() ? $this->displayViewDetailsButton() : ''; |
|
| 214 | + } |
|
| 215 | + // filter the maximum qty that can appear in the Ticket Selector qty dropdowns |
|
| 216 | + $this->setMaxAttendees($this->event->additional_limit()); |
|
| 217 | + if ($this->getMaxAttendees() < 1) { |
|
| 218 | + return $this->ticketSalesClosedMessage(); |
|
| 219 | + } |
|
| 220 | + // is the event expired ? |
|
| 221 | + $template_args['event_is_expired'] = ! is_admin() ? $this->event->is_expired() : false; |
|
| 222 | + if ($template_args['event_is_expired']) { |
|
| 223 | + return $this->expiredEventMessage(); |
|
| 224 | + } |
|
| 225 | + // get all tickets for this event ordered by the datetime |
|
| 226 | + $tickets = $this->getTickets(); |
|
| 227 | + if (count($tickets) < 1) { |
|
| 228 | + return $this->noTicketAvailableMessage(); |
|
| 229 | + } |
|
| 230 | + // redirecting to another site for registration ?? |
|
| 231 | + $external_url = (string) $this->event->external_url() |
|
| 232 | + && $this->event->external_url() !== get_the_permalink() |
|
| 233 | + ? $this->event->external_url() |
|
| 234 | + : ''; |
|
| 235 | + // if redirecting to another site for registration, then we don't load the TS |
|
| 236 | + $ticket_selector = $external_url |
|
| 237 | + ? $this->externalEventRegistration() |
|
| 238 | + : $this->loadTicketSelector($tickets, $template_args); |
|
| 239 | + // now set up the form (but not for the admin) |
|
| 240 | + $ticket_selector = $this->display_full_ui() |
|
| 241 | + ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
| 242 | + : $ticket_selector; |
|
| 243 | + // submit button and form close tag |
|
| 244 | + $ticket_selector .= $this->display_full_ui() ? $this->displaySubmitButton($external_url) : ''; |
|
| 245 | + return $ticket_selector; |
|
| 246 | + } |
|
| 247 | + |
|
| 248 | + |
|
| 249 | + /** |
|
| 250 | + * displayTicketSelector |
|
| 251 | + * examines the event properties and determines whether a Ticket Selector should be displayed |
|
| 252 | + * |
|
| 253 | + * @param WP_Post|int $event |
|
| 254 | + * @param string $_event_active_status |
|
| 255 | + * @param bool $view_details |
|
| 256 | + * @return bool |
|
| 257 | + * @throws EE_Error |
|
| 258 | + */ |
|
| 259 | + protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details) |
|
| 260 | + { |
|
| 261 | + $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event; |
|
| 262 | + return $this->display_full_ui() |
|
| 263 | + && ( |
|
| 264 | + ! $this->event->display_ticket_selector() |
|
| 265 | + || $view_details |
|
| 266 | + || post_password_required($event_post) |
|
| 267 | + || ( |
|
| 268 | + $_event_active_status !== EE_Datetime::active |
|
| 269 | + && $_event_active_status !== EE_Datetime::upcoming |
|
| 270 | + && $_event_active_status !== EE_Datetime::sold_out |
|
| 271 | + && ! ( |
|
| 272 | + $_event_active_status === EE_Datetime::inactive |
|
| 273 | + && is_user_logged_in() |
|
| 274 | + ) |
|
| 275 | + ) |
|
| 276 | + ); |
|
| 277 | + } |
|
| 278 | + |
|
| 279 | + |
|
| 280 | + /** |
|
| 281 | + * noTicketAvailableMessage |
|
| 282 | + * notice displayed if event is expired |
|
| 283 | + * |
|
| 284 | + * @return string |
|
| 285 | + * @throws EE_Error |
|
| 286 | + */ |
|
| 287 | + protected function expiredEventMessage() |
|
| 288 | + { |
|
| 289 | + return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
| 290 | + 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
|
| 291 | + 'event_espresso' |
|
| 292 | + ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
| 293 | + } |
|
| 294 | + |
|
| 295 | + |
|
| 296 | + /** |
|
| 297 | + * noTicketAvailableMessage |
|
| 298 | + * notice displayed if event has no more tickets available |
|
| 299 | + * |
|
| 300 | + * @return string |
|
| 301 | + * @throws EE_Error |
|
| 302 | + */ |
|
| 303 | + protected function noTicketAvailableMessage() |
|
| 304 | + { |
|
| 305 | + $no_ticket_available_msg = esc_html__('We\'re sorry, but all ticket sales have ended.', 'event_espresso'); |
|
| 306 | + if (current_user_can('edit_post', $this->event->ID())) { |
|
| 307 | + $no_ticket_available_msg .= sprintf( |
|
| 308 | + esc_html__( |
|
| 309 | + '%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', |
|
| 310 | + 'event_espresso' |
|
| 311 | + ), |
|
| 312 | + '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 313 | + '</b><br />', |
|
| 314 | + '<span class="edit-link"><a class="post-edit-link" href="' |
|
| 315 | + . get_edit_post_link($this->event->ID()) |
|
| 316 | + . '">', |
|
| 317 | + '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->' |
|
| 318 | + ); |
|
| 319 | + } |
|
| 320 | + return ' |
|
| 321 | 321 | <div class="ee-event-expired-notice"> |
| 322 | 322 | <span class="important-notice">' . $no_ticket_available_msg . '</span> |
| 323 | 323 | </div><!-- .ee-event-expired-notice -->'; |
| 324 | - } |
|
| 325 | - |
|
| 326 | - |
|
| 327 | - /** |
|
| 328 | - * ticketSalesClosed |
|
| 329 | - * notice displayed if event ticket sales are turned off |
|
| 330 | - * |
|
| 331 | - * @return string |
|
| 332 | - * @throws EE_Error |
|
| 333 | - */ |
|
| 334 | - protected function ticketSalesClosedMessage() |
|
| 335 | - { |
|
| 336 | - $sales_closed_msg = esc_html__( |
|
| 337 | - 'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.', |
|
| 338 | - 'event_espresso' |
|
| 339 | - ); |
|
| 340 | - if (current_user_can('edit_post', $this->event->ID())) { |
|
| 341 | - $sales_closed_msg .= sprintf( |
|
| 342 | - esc_html__( |
|
| 343 | - '%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', |
|
| 344 | - 'event_espresso' |
|
| 345 | - ), |
|
| 346 | - '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 347 | - '</b><br />', |
|
| 348 | - '<span class="edit-link"><a class="post-edit-link" href="' |
|
| 349 | - . get_edit_post_link($this->event->ID()) |
|
| 350 | - . '">', |
|
| 351 | - '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
|
| 352 | - ); |
|
| 353 | - } |
|
| 354 | - return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
| 355 | - } |
|
| 356 | - |
|
| 357 | - |
|
| 358 | - /** |
|
| 359 | - * getTickets |
|
| 360 | - * |
|
| 361 | - * @return \EE_Base_Class[]|\EE_Ticket[] |
|
| 362 | - * @throws EE_Error |
|
| 363 | - * @throws InvalidDataTypeException |
|
| 364 | - * @throws InvalidInterfaceException |
|
| 365 | - * @throws InvalidArgumentException |
|
| 366 | - */ |
|
| 367 | - protected function getTickets() |
|
| 368 | - { |
|
| 369 | - $show_expired_tickets = is_admin() || ( |
|
| 370 | - EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
| 371 | - && EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets |
|
| 372 | - ); |
|
| 373 | - |
|
| 374 | - $ticket_query_args = array( |
|
| 375 | - array('Datetime.EVT_ID' => $this->event->ID()), |
|
| 376 | - 'order_by' => array( |
|
| 377 | - 'TKT_order' => 'ASC', |
|
| 378 | - 'TKT_required' => 'DESC', |
|
| 379 | - 'TKT_start_date' => 'ASC', |
|
| 380 | - 'TKT_end_date' => 'ASC', |
|
| 381 | - 'Datetime.DTT_EVT_start' => 'DESC', |
|
| 382 | - ), |
|
| 383 | - ); |
|
| 384 | - if (! $show_expired_tickets) { |
|
| 385 | - // use the correct applicable time query depending on what version of core is being run. |
|
| 386 | - $current_time = method_exists('EEM_Datetime', 'current_time_for_query') |
|
| 387 | - ? time() |
|
| 388 | - : current_time('timestamp'); |
|
| 389 | - $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time); |
|
| 390 | - } |
|
| 391 | - return EEM_Ticket::instance()->get_all($ticket_query_args); |
|
| 392 | - } |
|
| 393 | - |
|
| 394 | - |
|
| 395 | - /** |
|
| 396 | - * loadTicketSelector |
|
| 397 | - * begins to assemble template arguments |
|
| 398 | - * and decides whether to load a "simple" ticket selector, or the standard |
|
| 399 | - * |
|
| 400 | - * @param \EE_Ticket[] $tickets |
|
| 401 | - * @param array $template_args |
|
| 402 | - * @return string |
|
| 403 | - * @throws EE_Error |
|
| 404 | - */ |
|
| 405 | - protected function loadTicketSelector(array $tickets, array $template_args) |
|
| 406 | - { |
|
| 407 | - $template_args['event'] = $this->event; |
|
| 408 | - $template_args['EVT_ID'] = $this->event->ID(); |
|
| 409 | - $template_args['event_is_expired'] = $this->event->is_expired(); |
|
| 410 | - $template_args['max_atndz'] = $this->getMaxAttendees(); |
|
| 411 | - $template_args['date_format'] = $this->date_format; |
|
| 412 | - $template_args['time_format'] = $this->time_format; |
|
| 413 | - /** |
|
| 414 | - * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected |
|
| 415 | - * |
|
| 416 | - * @since 4.9.13 |
|
| 417 | - * @param string '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to |
|
| 418 | - * @param int $EVT_ID The Event ID |
|
| 419 | - */ |
|
| 420 | - $template_args['anchor_id'] = apply_filters( |
|
| 421 | - 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
|
| 422 | - '#tkt-slctr-tbl-' . $this->event->ID(), |
|
| 423 | - $this->event->ID() |
|
| 424 | - ); |
|
| 425 | - $template_args['tickets'] = $tickets; |
|
| 426 | - $template_args['ticket_count'] = count($tickets); |
|
| 427 | - $ticket_selector = $this->simpleTicketSelector($tickets, $template_args); |
|
| 428 | - return $ticket_selector instanceof TicketSelectorSimple |
|
| 429 | - ? $ticket_selector |
|
| 430 | - : new TicketSelectorStandard( |
|
| 431 | - $this->event, |
|
| 432 | - $tickets, |
|
| 433 | - $this->getMaxAttendees(), |
|
| 434 | - $template_args, |
|
| 435 | - $this->date_format, |
|
| 436 | - $this->time_format |
|
| 437 | - ); |
|
| 438 | - } |
|
| 439 | - |
|
| 440 | - |
|
| 441 | - /** |
|
| 442 | - * simpleTicketSelector |
|
| 443 | - * there's one ticket, and max attendees is set to one, |
|
| 444 | - * so if the event is free, then this is a "simple" ticket selector |
|
| 445 | - * a.k.a. "Dude Where's my Ticket Selector?" |
|
| 446 | - * |
|
| 447 | - * @param \EE_Ticket[] $tickets |
|
| 448 | - * @param array $template_args |
|
| 449 | - * @return string |
|
| 450 | - * @throws EE_Error |
|
| 451 | - */ |
|
| 452 | - protected function simpleTicketSelector($tickets, array $template_args) |
|
| 453 | - { |
|
| 454 | - // if there is only ONE ticket with a max qty of ONE |
|
| 455 | - if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) { |
|
| 456 | - return ''; |
|
| 457 | - } |
|
| 458 | - /** @var \EE_Ticket $ticket */ |
|
| 459 | - $ticket = reset($tickets); |
|
| 460 | - // if the ticket is free... then not much need for the ticket selector |
|
| 461 | - if (apply_filters( |
|
| 462 | - 'FHEE__ticket_selector_chart_template__hide_ticket_selector', |
|
| 463 | - $ticket->is_free(), |
|
| 464 | - $this->event->ID() |
|
| 465 | - )) { |
|
| 466 | - return new TicketSelectorSimple( |
|
| 467 | - $this->event, |
|
| 468 | - $ticket, |
|
| 469 | - $this->getMaxAttendees(), |
|
| 470 | - $template_args |
|
| 471 | - ); |
|
| 472 | - } |
|
| 473 | - return ''; |
|
| 474 | - } |
|
| 475 | - |
|
| 476 | - |
|
| 477 | - /** |
|
| 478 | - * externalEventRegistration |
|
| 479 | - * |
|
| 480 | - * @return string |
|
| 481 | - */ |
|
| 482 | - public function externalEventRegistration() |
|
| 483 | - { |
|
| 484 | - // if not we still need to trigger the display of the submit button |
|
| 485 | - add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
| 486 | - // display notice to admin that registration is external |
|
| 487 | - return $this->display_full_ui() |
|
| 488 | - ? esc_html__( |
|
| 489 | - 'Registration is at an external URL for this event.', |
|
| 490 | - 'event_espresso' |
|
| 491 | - ) |
|
| 492 | - : ''; |
|
| 493 | - } |
|
| 494 | - |
|
| 495 | - |
|
| 496 | - /** |
|
| 497 | - * formOpen |
|
| 498 | - * |
|
| 499 | - * @param int $ID |
|
| 500 | - * @param string $external_url |
|
| 501 | - * @return string |
|
| 502 | - */ |
|
| 503 | - public function formOpen($ID = 0, $external_url = '') |
|
| 504 | - { |
|
| 505 | - // if redirecting, we don't need any anything else |
|
| 506 | - if ($external_url) { |
|
| 507 | - $html = '<form method="GET" '; |
|
| 508 | - $html .= 'action="' . EEH_URL::refactor_url($external_url) . '" '; |
|
| 509 | - $html .= 'name="ticket-selector-form-' . $ID . '"'; |
|
| 510 | - // open link in new window ? |
|
| 511 | - $html .= apply_filters( |
|
| 512 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
|
| 513 | - $this->isIframe(), |
|
| 514 | - $this |
|
| 515 | - ) |
|
| 516 | - ? ' target="_blank"' |
|
| 517 | - : ''; |
|
| 518 | - $html .= '>'; |
|
| 519 | - $query_args = EEH_URL::get_query_string($external_url); |
|
| 520 | - foreach ((array) $query_args as $query_arg => $value) { |
|
| 521 | - $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
| 522 | - } |
|
| 523 | - return $html; |
|
| 524 | - } |
|
| 525 | - // if there is no submit button, then don't start building a form |
|
| 526 | - // because the "View Details" button will build its own form |
|
| 527 | - if (! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 528 | - return ''; |
|
| 529 | - } |
|
| 530 | - $checkout_url = EEH_Event_View::event_link_url($ID); |
|
| 531 | - if (! $checkout_url) { |
|
| 532 | - EE_Error::add_error( |
|
| 533 | - esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
| 534 | - __FILE__, |
|
| 535 | - __FUNCTION__, |
|
| 536 | - __LINE__ |
|
| 537 | - ); |
|
| 538 | - } |
|
| 539 | - // set no cache headers and constants |
|
| 540 | - EE_System::do_not_cache(); |
|
| 541 | - $html = '<form method="POST" '; |
|
| 542 | - $html .= 'action="' . $checkout_url . '" '; |
|
| 543 | - $html .= 'name="ticket-selector-form-' . $ID . '"'; |
|
| 544 | - $html .= $this->iframe ? ' target="_blank"' : ''; |
|
| 545 | - $html .= '>'; |
|
| 546 | - $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
|
| 547 | - $html = apply_filters('FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event); |
|
| 548 | - return $html; |
|
| 549 | - } |
|
| 550 | - |
|
| 551 | - |
|
| 552 | - /** |
|
| 553 | - * displaySubmitButton |
|
| 554 | - * |
|
| 555 | - * @param string $external_url |
|
| 556 | - * @return string |
|
| 557 | - * @throws EE_Error |
|
| 558 | - */ |
|
| 559 | - public function displaySubmitButton($external_url = '') |
|
| 560 | - { |
|
| 561 | - $html = ''; |
|
| 562 | - if ($this->display_full_ui()) { |
|
| 563 | - // standard TS displayed with submit button, ie: "Register Now" |
|
| 564 | - if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 565 | - $html .= $this->displayRegisterNowButton(); |
|
| 566 | - $html .= empty($external_url) |
|
| 567 | - ? $this->ticketSelectorEndDiv() |
|
| 568 | - : $this->clearTicketSelector(); |
|
| 569 | - $html .= '<br/>' . $this->formClose(); |
|
| 570 | - } elseif ($this->getMaxAttendees() === 1) { |
|
| 571 | - // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
|
| 572 | - if ($this->event->is_sold_out()) { |
|
| 573 | - // then instead of a View Details or Submit button, just display a "Sold Out" message |
|
| 574 | - $html .= apply_filters( |
|
| 575 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg', |
|
| 576 | - sprintf( |
|
| 577 | - __( |
|
| 578 | - '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s', |
|
| 579 | - 'event_espresso' |
|
| 580 | - ), |
|
| 581 | - '<p class="no-ticket-selector-msg clear-float">', |
|
| 582 | - $this->event->name(), |
|
| 583 | - '</p>', |
|
| 584 | - '<br />' |
|
| 585 | - ), |
|
| 586 | - $this->event |
|
| 587 | - ); |
|
| 588 | - if (apply_filters( |
|
| 589 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 590 | - false, |
|
| 591 | - $this->event |
|
| 592 | - )) { |
|
| 593 | - $html .= $this->displayRegisterNowButton(); |
|
| 594 | - } |
|
| 595 | - // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
|
| 596 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 597 | - } elseif (apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
|
| 598 | - && ! is_single() |
|
| 599 | - ) { |
|
| 600 | - // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event, |
|
| 601 | - // but no tickets are available, so display event's "View Details" button. |
|
| 602 | - // it is being viewed via somewhere other than a single post |
|
| 603 | - $html .= $this->displayViewDetailsButton(true); |
|
| 604 | - } else { |
|
| 605 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 606 | - } |
|
| 607 | - } elseif (is_archive()) { |
|
| 608 | - // event list, no tickets available so display event's "View Details" button |
|
| 609 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 610 | - $html .= $this->displayViewDetailsButton(); |
|
| 611 | - } else { |
|
| 612 | - if (apply_filters( |
|
| 613 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 614 | - false, |
|
| 615 | - $this->event |
|
| 616 | - )) { |
|
| 617 | - $html .= $this->displayRegisterNowButton(); |
|
| 618 | - } |
|
| 619 | - // no submit or view details button, and no additional content |
|
| 620 | - $html .= $this->ticketSelectorEndDiv(); |
|
| 621 | - } |
|
| 622 | - if (! $this->iframe && ! is_archive()) { |
|
| 623 | - $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector')); |
|
| 624 | - } |
|
| 625 | - } |
|
| 626 | - return apply_filters( |
|
| 627 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displaySubmitButton__html', |
|
| 628 | - $html, |
|
| 629 | - $this->event, |
|
| 630 | - $this |
|
| 631 | - ); |
|
| 632 | - } |
|
| 633 | - |
|
| 634 | - |
|
| 635 | - /** |
|
| 636 | - * @return string |
|
| 637 | - * @throws EE_Error |
|
| 638 | - */ |
|
| 639 | - public function displayRegisterNowButton() |
|
| 640 | - { |
|
| 641 | - $btn_text = apply_filters( |
|
| 642 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text', |
|
| 643 | - __('Register Now', 'event_espresso'), |
|
| 644 | - $this->event |
|
| 645 | - ); |
|
| 646 | - $external_url = (string) $this->event->external_url() |
|
| 647 | - && $this->event->external_url() !== get_the_permalink() |
|
| 648 | - ? $this->event->external_url() |
|
| 649 | - : ''; |
|
| 650 | - $html = EEH_HTML::div( |
|
| 651 | - '', |
|
| 652 | - 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', |
|
| 653 | - 'ticket-selector-submit-btn-wrap' |
|
| 654 | - ); |
|
| 655 | - $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
| 656 | - $html .= ' class="ticket-selector-submit-btn '; |
|
| 657 | - $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
|
| 658 | - $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
| 659 | - $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 660 | - $html .= apply_filters( |
|
| 661 | - 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
|
| 662 | - '', |
|
| 663 | - $this->event, |
|
| 664 | - $this->iframe |
|
| 665 | - ); |
|
| 666 | - return $html; |
|
| 667 | - } |
|
| 668 | - |
|
| 669 | - |
|
| 670 | - /** |
|
| 671 | - * displayViewDetailsButton |
|
| 672 | - * |
|
| 673 | - * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event |
|
| 674 | - * (ie: $_max_atndz === 1) where there are no available tickets, |
|
| 675 | - * either because they are sold out, expired, or not yet on sale. |
|
| 676 | - * In this case, we need to close the form BEFORE adding any closing divs |
|
| 677 | - * @return string |
|
| 678 | - * @throws EE_Error |
|
| 679 | - */ |
|
| 680 | - public function displayViewDetailsButton($DWMTS = false) |
|
| 681 | - { |
|
| 682 | - if (! $this->event->get_permalink()) { |
|
| 683 | - EE_Error::add_error( |
|
| 684 | - esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
| 685 | - __FILE__, |
|
| 686 | - __FUNCTION__, |
|
| 687 | - __LINE__ |
|
| 688 | - ); |
|
| 689 | - } |
|
| 690 | - $view_details_btn = '<form method="POST" action="'; |
|
| 691 | - $view_details_btn .= apply_filters( |
|
| 692 | - 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url', |
|
| 693 | - $this->event->get_permalink(), |
|
| 694 | - $this->event |
|
| 695 | - ); |
|
| 696 | - $view_details_btn .= '"'; |
|
| 697 | - // open link in new window ? |
|
| 698 | - $view_details_btn .= apply_filters( |
|
| 699 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank', |
|
| 700 | - $this->isIframe(), |
|
| 701 | - $this |
|
| 702 | - ) |
|
| 703 | - ? ' target="_blank"' |
|
| 704 | - : ''; |
|
| 705 | - $view_details_btn .= '>'; |
|
| 706 | - $btn_text = apply_filters( |
|
| 707 | - 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
|
| 708 | - esc_html__('View Details', 'event_espresso'), |
|
| 709 | - $this->event |
|
| 710 | - ); |
|
| 711 | - $view_details_btn .= '<input id="ticket-selector-submit-' |
|
| 712 | - . $this->event->ID() |
|
| 713 | - . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
|
| 714 | - . $btn_text |
|
| 715 | - . '" />'; |
|
| 716 | - $view_details_btn .= apply_filters('FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event); |
|
| 717 | - if ($DWMTS) { |
|
| 718 | - $view_details_btn .= $this->formClose(); |
|
| 719 | - $view_details_btn .= $this->ticketSelectorEndDiv(); |
|
| 720 | - $view_details_btn .= '<br/>'; |
|
| 721 | - } else { |
|
| 722 | - $view_details_btn .= $this->clearTicketSelector(); |
|
| 723 | - $view_details_btn .= '<br/>'; |
|
| 724 | - $view_details_btn .= $this->formClose(); |
|
| 725 | - } |
|
| 726 | - return $view_details_btn; |
|
| 727 | - } |
|
| 728 | - |
|
| 729 | - |
|
| 730 | - /** |
|
| 731 | - * @return string |
|
| 732 | - */ |
|
| 733 | - public function ticketSelectorEndDiv() |
|
| 734 | - { |
|
| 735 | - return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
| 736 | - } |
|
| 737 | - |
|
| 738 | - |
|
| 739 | - /** |
|
| 740 | - * @return string |
|
| 741 | - */ |
|
| 742 | - public function clearTicketSelector() |
|
| 743 | - { |
|
| 744 | - // standard TS displayed, appears after a "Register Now" or "view Details" button |
|
| 745 | - return '<div class="clear"></div><!-- clearTicketSelector -->'; |
|
| 746 | - } |
|
| 747 | - |
|
| 748 | - |
|
| 749 | - /** |
|
| 750 | - * @access public |
|
| 751 | - * @return string |
|
| 752 | - */ |
|
| 753 | - public function formClose() |
|
| 754 | - { |
|
| 755 | - return '</form>'; |
|
| 756 | - } |
|
| 324 | + } |
|
| 325 | + |
|
| 326 | + |
|
| 327 | + /** |
|
| 328 | + * ticketSalesClosed |
|
| 329 | + * notice displayed if event ticket sales are turned off |
|
| 330 | + * |
|
| 331 | + * @return string |
|
| 332 | + * @throws EE_Error |
|
| 333 | + */ |
|
| 334 | + protected function ticketSalesClosedMessage() |
|
| 335 | + { |
|
| 336 | + $sales_closed_msg = esc_html__( |
|
| 337 | + 'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.', |
|
| 338 | + 'event_espresso' |
|
| 339 | + ); |
|
| 340 | + if (current_user_can('edit_post', $this->event->ID())) { |
|
| 341 | + $sales_closed_msg .= sprintf( |
|
| 342 | + esc_html__( |
|
| 343 | + '%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', |
|
| 344 | + 'event_espresso' |
|
| 345 | + ), |
|
| 346 | + '<div class="ee-attention" style="text-align: left;"><b>', |
|
| 347 | + '</b><br />', |
|
| 348 | + '<span class="edit-link"><a class="post-edit-link" href="' |
|
| 349 | + . get_edit_post_link($this->event->ID()) |
|
| 350 | + . '">', |
|
| 351 | + '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
|
| 352 | + ); |
|
| 353 | + } |
|
| 354 | + return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
| 355 | + } |
|
| 356 | + |
|
| 357 | + |
|
| 358 | + /** |
|
| 359 | + * getTickets |
|
| 360 | + * |
|
| 361 | + * @return \EE_Base_Class[]|\EE_Ticket[] |
|
| 362 | + * @throws EE_Error |
|
| 363 | + * @throws InvalidDataTypeException |
|
| 364 | + * @throws InvalidInterfaceException |
|
| 365 | + * @throws InvalidArgumentException |
|
| 366 | + */ |
|
| 367 | + protected function getTickets() |
|
| 368 | + { |
|
| 369 | + $show_expired_tickets = is_admin() || ( |
|
| 370 | + EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
| 371 | + && EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets |
|
| 372 | + ); |
|
| 373 | + |
|
| 374 | + $ticket_query_args = array( |
|
| 375 | + array('Datetime.EVT_ID' => $this->event->ID()), |
|
| 376 | + 'order_by' => array( |
|
| 377 | + 'TKT_order' => 'ASC', |
|
| 378 | + 'TKT_required' => 'DESC', |
|
| 379 | + 'TKT_start_date' => 'ASC', |
|
| 380 | + 'TKT_end_date' => 'ASC', |
|
| 381 | + 'Datetime.DTT_EVT_start' => 'DESC', |
|
| 382 | + ), |
|
| 383 | + ); |
|
| 384 | + if (! $show_expired_tickets) { |
|
| 385 | + // use the correct applicable time query depending on what version of core is being run. |
|
| 386 | + $current_time = method_exists('EEM_Datetime', 'current_time_for_query') |
|
| 387 | + ? time() |
|
| 388 | + : current_time('timestamp'); |
|
| 389 | + $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time); |
|
| 390 | + } |
|
| 391 | + return EEM_Ticket::instance()->get_all($ticket_query_args); |
|
| 392 | + } |
|
| 393 | + |
|
| 394 | + |
|
| 395 | + /** |
|
| 396 | + * loadTicketSelector |
|
| 397 | + * begins to assemble template arguments |
|
| 398 | + * and decides whether to load a "simple" ticket selector, or the standard |
|
| 399 | + * |
|
| 400 | + * @param \EE_Ticket[] $tickets |
|
| 401 | + * @param array $template_args |
|
| 402 | + * @return string |
|
| 403 | + * @throws EE_Error |
|
| 404 | + */ |
|
| 405 | + protected function loadTicketSelector(array $tickets, array $template_args) |
|
| 406 | + { |
|
| 407 | + $template_args['event'] = $this->event; |
|
| 408 | + $template_args['EVT_ID'] = $this->event->ID(); |
|
| 409 | + $template_args['event_is_expired'] = $this->event->is_expired(); |
|
| 410 | + $template_args['max_atndz'] = $this->getMaxAttendees(); |
|
| 411 | + $template_args['date_format'] = $this->date_format; |
|
| 412 | + $template_args['time_format'] = $this->time_format; |
|
| 413 | + /** |
|
| 414 | + * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected |
|
| 415 | + * |
|
| 416 | + * @since 4.9.13 |
|
| 417 | + * @param string '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to |
|
| 418 | + * @param int $EVT_ID The Event ID |
|
| 419 | + */ |
|
| 420 | + $template_args['anchor_id'] = apply_filters( |
|
| 421 | + 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
|
| 422 | + '#tkt-slctr-tbl-' . $this->event->ID(), |
|
| 423 | + $this->event->ID() |
|
| 424 | + ); |
|
| 425 | + $template_args['tickets'] = $tickets; |
|
| 426 | + $template_args['ticket_count'] = count($tickets); |
|
| 427 | + $ticket_selector = $this->simpleTicketSelector($tickets, $template_args); |
|
| 428 | + return $ticket_selector instanceof TicketSelectorSimple |
|
| 429 | + ? $ticket_selector |
|
| 430 | + : new TicketSelectorStandard( |
|
| 431 | + $this->event, |
|
| 432 | + $tickets, |
|
| 433 | + $this->getMaxAttendees(), |
|
| 434 | + $template_args, |
|
| 435 | + $this->date_format, |
|
| 436 | + $this->time_format |
|
| 437 | + ); |
|
| 438 | + } |
|
| 439 | + |
|
| 440 | + |
|
| 441 | + /** |
|
| 442 | + * simpleTicketSelector |
|
| 443 | + * there's one ticket, and max attendees is set to one, |
|
| 444 | + * so if the event is free, then this is a "simple" ticket selector |
|
| 445 | + * a.k.a. "Dude Where's my Ticket Selector?" |
|
| 446 | + * |
|
| 447 | + * @param \EE_Ticket[] $tickets |
|
| 448 | + * @param array $template_args |
|
| 449 | + * @return string |
|
| 450 | + * @throws EE_Error |
|
| 451 | + */ |
|
| 452 | + protected function simpleTicketSelector($tickets, array $template_args) |
|
| 453 | + { |
|
| 454 | + // if there is only ONE ticket with a max qty of ONE |
|
| 455 | + if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) { |
|
| 456 | + return ''; |
|
| 457 | + } |
|
| 458 | + /** @var \EE_Ticket $ticket */ |
|
| 459 | + $ticket = reset($tickets); |
|
| 460 | + // if the ticket is free... then not much need for the ticket selector |
|
| 461 | + if (apply_filters( |
|
| 462 | + 'FHEE__ticket_selector_chart_template__hide_ticket_selector', |
|
| 463 | + $ticket->is_free(), |
|
| 464 | + $this->event->ID() |
|
| 465 | + )) { |
|
| 466 | + return new TicketSelectorSimple( |
|
| 467 | + $this->event, |
|
| 468 | + $ticket, |
|
| 469 | + $this->getMaxAttendees(), |
|
| 470 | + $template_args |
|
| 471 | + ); |
|
| 472 | + } |
|
| 473 | + return ''; |
|
| 474 | + } |
|
| 475 | + |
|
| 476 | + |
|
| 477 | + /** |
|
| 478 | + * externalEventRegistration |
|
| 479 | + * |
|
| 480 | + * @return string |
|
| 481 | + */ |
|
| 482 | + public function externalEventRegistration() |
|
| 483 | + { |
|
| 484 | + // if not we still need to trigger the display of the submit button |
|
| 485 | + add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
| 486 | + // display notice to admin that registration is external |
|
| 487 | + return $this->display_full_ui() |
|
| 488 | + ? esc_html__( |
|
| 489 | + 'Registration is at an external URL for this event.', |
|
| 490 | + 'event_espresso' |
|
| 491 | + ) |
|
| 492 | + : ''; |
|
| 493 | + } |
|
| 494 | + |
|
| 495 | + |
|
| 496 | + /** |
|
| 497 | + * formOpen |
|
| 498 | + * |
|
| 499 | + * @param int $ID |
|
| 500 | + * @param string $external_url |
|
| 501 | + * @return string |
|
| 502 | + */ |
|
| 503 | + public function formOpen($ID = 0, $external_url = '') |
|
| 504 | + { |
|
| 505 | + // if redirecting, we don't need any anything else |
|
| 506 | + if ($external_url) { |
|
| 507 | + $html = '<form method="GET" '; |
|
| 508 | + $html .= 'action="' . EEH_URL::refactor_url($external_url) . '" '; |
|
| 509 | + $html .= 'name="ticket-selector-form-' . $ID . '"'; |
|
| 510 | + // open link in new window ? |
|
| 511 | + $html .= apply_filters( |
|
| 512 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
|
| 513 | + $this->isIframe(), |
|
| 514 | + $this |
|
| 515 | + ) |
|
| 516 | + ? ' target="_blank"' |
|
| 517 | + : ''; |
|
| 518 | + $html .= '>'; |
|
| 519 | + $query_args = EEH_URL::get_query_string($external_url); |
|
| 520 | + foreach ((array) $query_args as $query_arg => $value) { |
|
| 521 | + $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
| 522 | + } |
|
| 523 | + return $html; |
|
| 524 | + } |
|
| 525 | + // if there is no submit button, then don't start building a form |
|
| 526 | + // because the "View Details" button will build its own form |
|
| 527 | + if (! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 528 | + return ''; |
|
| 529 | + } |
|
| 530 | + $checkout_url = EEH_Event_View::event_link_url($ID); |
|
| 531 | + if (! $checkout_url) { |
|
| 532 | + EE_Error::add_error( |
|
| 533 | + esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
| 534 | + __FILE__, |
|
| 535 | + __FUNCTION__, |
|
| 536 | + __LINE__ |
|
| 537 | + ); |
|
| 538 | + } |
|
| 539 | + // set no cache headers and constants |
|
| 540 | + EE_System::do_not_cache(); |
|
| 541 | + $html = '<form method="POST" '; |
|
| 542 | + $html .= 'action="' . $checkout_url . '" '; |
|
| 543 | + $html .= 'name="ticket-selector-form-' . $ID . '"'; |
|
| 544 | + $html .= $this->iframe ? ' target="_blank"' : ''; |
|
| 545 | + $html .= '>'; |
|
| 546 | + $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
|
| 547 | + $html = apply_filters('FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event); |
|
| 548 | + return $html; |
|
| 549 | + } |
|
| 550 | + |
|
| 551 | + |
|
| 552 | + /** |
|
| 553 | + * displaySubmitButton |
|
| 554 | + * |
|
| 555 | + * @param string $external_url |
|
| 556 | + * @return string |
|
| 557 | + * @throws EE_Error |
|
| 558 | + */ |
|
| 559 | + public function displaySubmitButton($external_url = '') |
|
| 560 | + { |
|
| 561 | + $html = ''; |
|
| 562 | + if ($this->display_full_ui()) { |
|
| 563 | + // standard TS displayed with submit button, ie: "Register Now" |
|
| 564 | + if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 565 | + $html .= $this->displayRegisterNowButton(); |
|
| 566 | + $html .= empty($external_url) |
|
| 567 | + ? $this->ticketSelectorEndDiv() |
|
| 568 | + : $this->clearTicketSelector(); |
|
| 569 | + $html .= '<br/>' . $this->formClose(); |
|
| 570 | + } elseif ($this->getMaxAttendees() === 1) { |
|
| 571 | + // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
|
| 572 | + if ($this->event->is_sold_out()) { |
|
| 573 | + // then instead of a View Details or Submit button, just display a "Sold Out" message |
|
| 574 | + $html .= apply_filters( |
|
| 575 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg', |
|
| 576 | + sprintf( |
|
| 577 | + __( |
|
| 578 | + '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s', |
|
| 579 | + 'event_espresso' |
|
| 580 | + ), |
|
| 581 | + '<p class="no-ticket-selector-msg clear-float">', |
|
| 582 | + $this->event->name(), |
|
| 583 | + '</p>', |
|
| 584 | + '<br />' |
|
| 585 | + ), |
|
| 586 | + $this->event |
|
| 587 | + ); |
|
| 588 | + if (apply_filters( |
|
| 589 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 590 | + false, |
|
| 591 | + $this->event |
|
| 592 | + )) { |
|
| 593 | + $html .= $this->displayRegisterNowButton(); |
|
| 594 | + } |
|
| 595 | + // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
|
| 596 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 597 | + } elseif (apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
|
| 598 | + && ! is_single() |
|
| 599 | + ) { |
|
| 600 | + // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event, |
|
| 601 | + // but no tickets are available, so display event's "View Details" button. |
|
| 602 | + // it is being viewed via somewhere other than a single post |
|
| 603 | + $html .= $this->displayViewDetailsButton(true); |
|
| 604 | + } else { |
|
| 605 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 606 | + } |
|
| 607 | + } elseif (is_archive()) { |
|
| 608 | + // event list, no tickets available so display event's "View Details" button |
|
| 609 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 610 | + $html .= $this->displayViewDetailsButton(); |
|
| 611 | + } else { |
|
| 612 | + if (apply_filters( |
|
| 613 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
| 614 | + false, |
|
| 615 | + $this->event |
|
| 616 | + )) { |
|
| 617 | + $html .= $this->displayRegisterNowButton(); |
|
| 618 | + } |
|
| 619 | + // no submit or view details button, and no additional content |
|
| 620 | + $html .= $this->ticketSelectorEndDiv(); |
|
| 621 | + } |
|
| 622 | + if (! $this->iframe && ! is_archive()) { |
|
| 623 | + $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector')); |
|
| 624 | + } |
|
| 625 | + } |
|
| 626 | + return apply_filters( |
|
| 627 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displaySubmitButton__html', |
|
| 628 | + $html, |
|
| 629 | + $this->event, |
|
| 630 | + $this |
|
| 631 | + ); |
|
| 632 | + } |
|
| 633 | + |
|
| 634 | + |
|
| 635 | + /** |
|
| 636 | + * @return string |
|
| 637 | + * @throws EE_Error |
|
| 638 | + */ |
|
| 639 | + public function displayRegisterNowButton() |
|
| 640 | + { |
|
| 641 | + $btn_text = apply_filters( |
|
| 642 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text', |
|
| 643 | + __('Register Now', 'event_espresso'), |
|
| 644 | + $this->event |
|
| 645 | + ); |
|
| 646 | + $external_url = (string) $this->event->external_url() |
|
| 647 | + && $this->event->external_url() !== get_the_permalink() |
|
| 648 | + ? $this->event->external_url() |
|
| 649 | + : ''; |
|
| 650 | + $html = EEH_HTML::div( |
|
| 651 | + '', |
|
| 652 | + 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', |
|
| 653 | + 'ticket-selector-submit-btn-wrap' |
|
| 654 | + ); |
|
| 655 | + $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
| 656 | + $html .= ' class="ticket-selector-submit-btn '; |
|
| 657 | + $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
|
| 658 | + $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
| 659 | + $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 660 | + $html .= apply_filters( |
|
| 661 | + 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
|
| 662 | + '', |
|
| 663 | + $this->event, |
|
| 664 | + $this->iframe |
|
| 665 | + ); |
|
| 666 | + return $html; |
|
| 667 | + } |
|
| 668 | + |
|
| 669 | + |
|
| 670 | + /** |
|
| 671 | + * displayViewDetailsButton |
|
| 672 | + * |
|
| 673 | + * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event |
|
| 674 | + * (ie: $_max_atndz === 1) where there are no available tickets, |
|
| 675 | + * either because they are sold out, expired, or not yet on sale. |
|
| 676 | + * In this case, we need to close the form BEFORE adding any closing divs |
|
| 677 | + * @return string |
|
| 678 | + * @throws EE_Error |
|
| 679 | + */ |
|
| 680 | + public function displayViewDetailsButton($DWMTS = false) |
|
| 681 | + { |
|
| 682 | + if (! $this->event->get_permalink()) { |
|
| 683 | + EE_Error::add_error( |
|
| 684 | + esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
| 685 | + __FILE__, |
|
| 686 | + __FUNCTION__, |
|
| 687 | + __LINE__ |
|
| 688 | + ); |
|
| 689 | + } |
|
| 690 | + $view_details_btn = '<form method="POST" action="'; |
|
| 691 | + $view_details_btn .= apply_filters( |
|
| 692 | + 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url', |
|
| 693 | + $this->event->get_permalink(), |
|
| 694 | + $this->event |
|
| 695 | + ); |
|
| 696 | + $view_details_btn .= '"'; |
|
| 697 | + // open link in new window ? |
|
| 698 | + $view_details_btn .= apply_filters( |
|
| 699 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank', |
|
| 700 | + $this->isIframe(), |
|
| 701 | + $this |
|
| 702 | + ) |
|
| 703 | + ? ' target="_blank"' |
|
| 704 | + : ''; |
|
| 705 | + $view_details_btn .= '>'; |
|
| 706 | + $btn_text = apply_filters( |
|
| 707 | + 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
|
| 708 | + esc_html__('View Details', 'event_espresso'), |
|
| 709 | + $this->event |
|
| 710 | + ); |
|
| 711 | + $view_details_btn .= '<input id="ticket-selector-submit-' |
|
| 712 | + . $this->event->ID() |
|
| 713 | + . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
|
| 714 | + . $btn_text |
|
| 715 | + . '" />'; |
|
| 716 | + $view_details_btn .= apply_filters('FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event); |
|
| 717 | + if ($DWMTS) { |
|
| 718 | + $view_details_btn .= $this->formClose(); |
|
| 719 | + $view_details_btn .= $this->ticketSelectorEndDiv(); |
|
| 720 | + $view_details_btn .= '<br/>'; |
|
| 721 | + } else { |
|
| 722 | + $view_details_btn .= $this->clearTicketSelector(); |
|
| 723 | + $view_details_btn .= '<br/>'; |
|
| 724 | + $view_details_btn .= $this->formClose(); |
|
| 725 | + } |
|
| 726 | + return $view_details_btn; |
|
| 727 | + } |
|
| 728 | + |
|
| 729 | + |
|
| 730 | + /** |
|
| 731 | + * @return string |
|
| 732 | + */ |
|
| 733 | + public function ticketSelectorEndDiv() |
|
| 734 | + { |
|
| 735 | + return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
| 736 | + } |
|
| 737 | + |
|
| 738 | + |
|
| 739 | + /** |
|
| 740 | + * @return string |
|
| 741 | + */ |
|
| 742 | + public function clearTicketSelector() |
|
| 743 | + { |
|
| 744 | + // standard TS displayed, appears after a "Register Now" or "view Details" button |
|
| 745 | + return '<div class="clear"></div><!-- clearTicketSelector -->'; |
|
| 746 | + } |
|
| 747 | + |
|
| 748 | + |
|
| 749 | + /** |
|
| 750 | + * @access public |
|
| 751 | + * @return string |
|
| 752 | + */ |
|
| 753 | + public function formClose() |
|
| 754 | + { |
|
| 755 | + return '</form>'; |
|
| 756 | + } |
|
| 757 | 757 | } |
@@ -135,11 +135,11 @@ discard block |
||
| 135 | 135 | } |
| 136 | 136 | } else { |
| 137 | 137 | $user_msg = __('No Event object or an invalid Event object was supplied.', 'event_espresso'); |
| 138 | - $dev_msg = $user_msg . __( |
|
| 138 | + $dev_msg = $user_msg.__( |
|
| 139 | 139 | '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.', |
| 140 | 140 | 'event_espresso' |
| 141 | 141 | ); |
| 142 | - EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 142 | + EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 143 | 143 | return false; |
| 144 | 144 | } |
| 145 | 145 | return true; |
@@ -200,7 +200,7 @@ discard block |
||
| 200 | 200 | // reset filter for displaying submit button |
| 201 | 201 | remove_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
| 202 | 202 | // poke and prod incoming event till it tells us what it is |
| 203 | - if (! $this->setEvent($event)) { |
|
| 203 | + if ( ! $this->setEvent($event)) { |
|
| 204 | 204 | return false; |
| 205 | 205 | } |
| 206 | 206 | // begin gathering template arguments by getting event status |
@@ -238,7 +238,7 @@ discard block |
||
| 238 | 238 | : $this->loadTicketSelector($tickets, $template_args); |
| 239 | 239 | // now set up the form (but not for the admin) |
| 240 | 240 | $ticket_selector = $this->display_full_ui() |
| 241 | - ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
| 241 | + ? $this->formOpen($this->event->ID(), $external_url).$ticket_selector |
|
| 242 | 242 | : $ticket_selector; |
| 243 | 243 | // submit button and form close tag |
| 244 | 244 | $ticket_selector .= $this->display_full_ui() ? $this->displaySubmitButton($external_url) : ''; |
@@ -286,10 +286,10 @@ discard block |
||
| 286 | 286 | */ |
| 287 | 287 | protected function expiredEventMessage() |
| 288 | 288 | { |
| 289 | - return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
| 289 | + return '<div class="ee-event-expired-notice"><span class="important-notice">'.esc_html__( |
|
| 290 | 290 | 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
| 291 | 291 | 'event_espresso' |
| 292 | - ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
| 292 | + ).'</span></div><!-- .ee-event-expired-notice -->'; |
|
| 293 | 293 | } |
| 294 | 294 | |
| 295 | 295 | |
@@ -319,7 +319,7 @@ discard block |
||
| 319 | 319 | } |
| 320 | 320 | return ' |
| 321 | 321 | <div class="ee-event-expired-notice"> |
| 322 | - <span class="important-notice">' . $no_ticket_available_msg . '</span> |
|
| 322 | + <span class="important-notice">' . $no_ticket_available_msg.'</span> |
|
| 323 | 323 | </div><!-- .ee-event-expired-notice -->'; |
| 324 | 324 | } |
| 325 | 325 | |
@@ -351,7 +351,7 @@ discard block |
||
| 351 | 351 | '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
| 352 | 352 | ); |
| 353 | 353 | } |
| 354 | - return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
| 354 | + return '<p><span class="important-notice">'.$sales_closed_msg.'</span></p>'; |
|
| 355 | 355 | } |
| 356 | 356 | |
| 357 | 357 | |
@@ -381,7 +381,7 @@ discard block |
||
| 381 | 381 | 'Datetime.DTT_EVT_start' => 'DESC', |
| 382 | 382 | ), |
| 383 | 383 | ); |
| 384 | - if (! $show_expired_tickets) { |
|
| 384 | + if ( ! $show_expired_tickets) { |
|
| 385 | 385 | // use the correct applicable time query depending on what version of core is being run. |
| 386 | 386 | $current_time = method_exists('EEM_Datetime', 'current_time_for_query') |
| 387 | 387 | ? time() |
@@ -419,7 +419,7 @@ discard block |
||
| 419 | 419 | */ |
| 420 | 420 | $template_args['anchor_id'] = apply_filters( |
| 421 | 421 | 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
| 422 | - '#tkt-slctr-tbl-' . $this->event->ID(), |
|
| 422 | + '#tkt-slctr-tbl-'.$this->event->ID(), |
|
| 423 | 423 | $this->event->ID() |
| 424 | 424 | ); |
| 425 | 425 | $template_args['tickets'] = $tickets; |
@@ -505,8 +505,8 @@ discard block |
||
| 505 | 505 | // if redirecting, we don't need any anything else |
| 506 | 506 | if ($external_url) { |
| 507 | 507 | $html = '<form method="GET" '; |
| 508 | - $html .= 'action="' . EEH_URL::refactor_url($external_url) . '" '; |
|
| 509 | - $html .= 'name="ticket-selector-form-' . $ID . '"'; |
|
| 508 | + $html .= 'action="'.EEH_URL::refactor_url($external_url).'" '; |
|
| 509 | + $html .= 'name="ticket-selector-form-'.$ID.'"'; |
|
| 510 | 510 | // open link in new window ? |
| 511 | 511 | $html .= apply_filters( |
| 512 | 512 | 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
@@ -518,17 +518,17 @@ discard block |
||
| 518 | 518 | $html .= '>'; |
| 519 | 519 | $query_args = EEH_URL::get_query_string($external_url); |
| 520 | 520 | foreach ((array) $query_args as $query_arg => $value) { |
| 521 | - $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
| 521 | + $html .= '<input type="hidden" name="'.$query_arg.'" value="'.$value.'">'; |
|
| 522 | 522 | } |
| 523 | 523 | return $html; |
| 524 | 524 | } |
| 525 | 525 | // if there is no submit button, then don't start building a form |
| 526 | 526 | // because the "View Details" button will build its own form |
| 527 | - if (! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 527 | + if ( ! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
| 528 | 528 | return ''; |
| 529 | 529 | } |
| 530 | 530 | $checkout_url = EEH_Event_View::event_link_url($ID); |
| 531 | - if (! $checkout_url) { |
|
| 531 | + if ( ! $checkout_url) { |
|
| 532 | 532 | EE_Error::add_error( |
| 533 | 533 | esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
| 534 | 534 | __FILE__, |
@@ -539,8 +539,8 @@ discard block |
||
| 539 | 539 | // set no cache headers and constants |
| 540 | 540 | EE_System::do_not_cache(); |
| 541 | 541 | $html = '<form method="POST" '; |
| 542 | - $html .= 'action="' . $checkout_url . '" '; |
|
| 543 | - $html .= 'name="ticket-selector-form-' . $ID . '"'; |
|
| 542 | + $html .= 'action="'.$checkout_url.'" '; |
|
| 543 | + $html .= 'name="ticket-selector-form-'.$ID.'"'; |
|
| 544 | 544 | $html .= $this->iframe ? ' target="_blank"' : ''; |
| 545 | 545 | $html .= '>'; |
| 546 | 546 | $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
@@ -566,7 +566,7 @@ discard block |
||
| 566 | 566 | $html .= empty($external_url) |
| 567 | 567 | ? $this->ticketSelectorEndDiv() |
| 568 | 568 | : $this->clearTicketSelector(); |
| 569 | - $html .= '<br/>' . $this->formClose(); |
|
| 569 | + $html .= '<br/>'.$this->formClose(); |
|
| 570 | 570 | } elseif ($this->getMaxAttendees() === 1) { |
| 571 | 571 | // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
| 572 | 572 | if ($this->event->is_sold_out()) { |
@@ -619,7 +619,7 @@ discard block |
||
| 619 | 619 | // no submit or view details button, and no additional content |
| 620 | 620 | $html .= $this->ticketSelectorEndDiv(); |
| 621 | 621 | } |
| 622 | - if (! $this->iframe && ! is_archive()) { |
|
| 622 | + if ( ! $this->iframe && ! is_archive()) { |
|
| 623 | 623 | $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector')); |
| 624 | 624 | } |
| 625 | 625 | } |
@@ -649,14 +649,14 @@ discard block |
||
| 649 | 649 | : ''; |
| 650 | 650 | $html = EEH_HTML::div( |
| 651 | 651 | '', |
| 652 | - 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', |
|
| 652 | + 'ticket-selector-submit-'.$this->event->ID().'-btn-wrap', |
|
| 653 | 653 | 'ticket-selector-submit-btn-wrap' |
| 654 | 654 | ); |
| 655 | - $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
| 655 | + $html .= '<input id="ticket-selector-submit-'.$this->event->ID().'-btn"'; |
|
| 656 | 656 | $html .= ' class="ticket-selector-submit-btn '; |
| 657 | 657 | $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
| 658 | - $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
| 659 | - $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 658 | + $html .= ' type="submit" value="'.$btn_text.'" />'; |
|
| 659 | + $html .= EEH_HTML::divx().'<!-- .ticket-selector-submit-btn-wrap -->'; |
|
| 660 | 660 | $html .= apply_filters( |
| 661 | 661 | 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
| 662 | 662 | '', |
@@ -679,7 +679,7 @@ discard block |
||
| 679 | 679 | */ |
| 680 | 680 | public function displayViewDetailsButton($DWMTS = false) |
| 681 | 681 | { |
| 682 | - if (! $this->event->get_permalink()) { |
|
| 682 | + if ( ! $this->event->get_permalink()) { |
|
| 683 | 683 | EE_Error::add_error( |
| 684 | 684 | esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
| 685 | 685 | __FILE__, |
@@ -732,7 +732,7 @@ discard block |
||
| 732 | 732 | */ |
| 733 | 733 | public function ticketSelectorEndDiv() |
| 734 | 734 | { |
| 735 | - return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
| 735 | + return $this->clearTicketSelector().'</div><!-- ticketSelectorEndDiv -->'; |
|
| 736 | 736 | } |
| 737 | 737 | |
| 738 | 738 | |
@@ -6,16 +6,16 @@ discard block |
||
| 6 | 6 | <?php if (!is_admin()) : ?> |
| 7 | 7 | <p id="spco-attendee_information-pg" class="spco-steps-pg small-text drk-grey-text"> |
| 8 | 8 | <?php echo apply_filters( |
| 9 | - 'FHEE__registration_page_attendee_information__attendee_information_pg', |
|
| 10 | - sprintf( |
|
| 11 | - esc_html__( |
|
| 12 | - 'In order to process your registration, we ask you to provide the following information.%1$sPlease note that all fields marked with an asterisk (%2$s) are required.', |
|
| 13 | - 'event_espresso' |
|
| 14 | - ), |
|
| 15 | - '<br />', |
|
| 16 | - '<span class="asterisk">*</span>' |
|
| 17 | - ) |
|
| 18 | - ); ?> |
|
| 9 | + 'FHEE__registration_page_attendee_information__attendee_information_pg', |
|
| 10 | + sprintf( |
|
| 11 | + esc_html__( |
|
| 12 | + 'In order to process your registration, we ask you to provide the following information.%1$sPlease note that all fields marked with an asterisk (%2$s) are required.', |
|
| 13 | + 'event_espresso' |
|
| 14 | + ), |
|
| 15 | + '<br />', |
|
| 16 | + '<span class="asterisk">*</span>' |
|
| 17 | + ) |
|
| 18 | + ); ?> |
|
| 19 | 19 | </p> |
| 20 | 20 | <?php endif; ?> |
| 21 | 21 | |
@@ -25,8 +25,8 @@ discard block |
||
| 25 | 25 | $prev_ticket = 0; |
| 26 | 26 | |
| 27 | 27 | if (count($registrations) > 0) { |
| 28 | - $ticketID = key($template_args['ticket_count']); |
|
| 29 | - ?> |
|
| 28 | + $ticketID = key($template_args['ticket_count']); |
|
| 29 | + ?> |
|
| 30 | 30 | |
| 31 | 31 | <div id="spco-attendee-panel-dv-<?php echo $ticketID; ?>" |
| 32 | 32 | class="spco-attendee-panel-dv spco-attendee-ticket-<?php echo $ticketID; ?>"> |
@@ -41,52 +41,52 @@ discard block |
||
| 41 | 41 | <th scope="col" width="" class="jst-left"><?php esc_html_e('Name and Description', 'event_espresso'); ?></th> |
| 42 | 42 | <th scope="col" width="7.5%" class="jst-rght"> |
| 43 | 43 | <?php esc_html_e( |
| 44 | - 'Qty', |
|
| 45 | - 'event_espresso' |
|
| 46 | - ); ?></th> |
|
| 44 | + 'Qty', |
|
| 45 | + 'event_espresso' |
|
| 46 | + ); ?></th> |
|
| 47 | 47 | <th scope="col" width="17.5%" class="jst-rght"> |
| 48 | 48 | <?php esc_html_e( |
| 49 | - 'Price', |
|
| 50 | - 'event_espresso' |
|
| 51 | - ); ?></th> |
|
| 49 | + 'Price', |
|
| 50 | + 'event_espresso' |
|
| 51 | + ); ?></th> |
|
| 52 | 52 | <th scope="col" width="17.5%" class="jst-rght"> |
| 53 | 53 | <?php esc_html_e( |
| 54 | - 'Total', |
|
| 55 | - 'event_espresso' |
|
| 56 | - ); ?></th> |
|
| 54 | + 'Total', |
|
| 55 | + 'event_espresso' |
|
| 56 | + ); ?></th> |
|
| 57 | 57 | </tr> |
| 58 | 58 | </thead> |
| 59 | 59 | <tbody> |
| 60 | 60 | <?php |
| 61 | - // Store previous values to avoid duplicated rows. |
|
| 62 | - $prev_ticket = 0; |
|
| 63 | - // Display all tickets inside. |
|
| 64 | - foreach ($registrations as $registration) { |
|
| 65 | - if ($registration instanceof EE_Registration) { |
|
| 66 | - if ($registration->ticket()->ID() !== $prev_ticket) { |
|
| 67 | - echo $ticket_line_item[ $registration->ticket()->ID() ]; |
|
| 68 | - } |
|
| 61 | + // Store previous values to avoid duplicated rows. |
|
| 62 | + $prev_ticket = 0; |
|
| 63 | + // Display all tickets inside. |
|
| 64 | + foreach ($registrations as $registration) { |
|
| 65 | + if ($registration instanceof EE_Registration) { |
|
| 66 | + if ($registration->ticket()->ID() !== $prev_ticket) { |
|
| 67 | + echo $ticket_line_item[ $registration->ticket()->ID() ]; |
|
| 68 | + } |
|
| 69 | 69 | |
| 70 | - $prev_ticket = $registration->ticket()->ID(); |
|
| 71 | - } |
|
| 72 | - } |
|
| 73 | - ?> |
|
| 70 | + $prev_ticket = $registration->ticket()->ID(); |
|
| 71 | + } |
|
| 72 | + } |
|
| 73 | + ?> |
|
| 74 | 74 | </tbody> |
| 75 | 75 | </table> |
| 76 | 76 | </div> |
| 77 | 77 | </div> |
| 78 | 78 | |
| 79 | 79 | <?php |
| 80 | - // Display the forms below the table. |
|
| 81 | - foreach ($registrations as $registration) { |
|
| 82 | - if ($registration instanceof EE_Registration) { |
|
| 83 | - // Attendee Questions. |
|
| 84 | - $reg_form = EE_Template_Layout::get_subform_name($registration->reg_url_link()); |
|
| 85 | - echo ${$reg_form}; |
|
| 86 | - } // if ( $registration instanceof EE_Registration ) |
|
| 87 | - } // end foreach ( $registrations as $registration ) |
|
| 80 | + // Display the forms below the table. |
|
| 81 | + foreach ($registrations as $registration) { |
|
| 82 | + if ($registration instanceof EE_Registration) { |
|
| 83 | + // Attendee Questions. |
|
| 84 | + $reg_form = EE_Template_Layout::get_subform_name($registration->reg_url_link()); |
|
| 85 | + echo ${$reg_form}; |
|
| 86 | + } // if ( $registration instanceof EE_Registration ) |
|
| 87 | + } // end foreach ( $registrations as $registration ) |
|
| 88 | 88 | |
| 89 | - echo $default_hidden_inputs; |
|
| 89 | + echo $default_hidden_inputs; |
|
| 90 | 90 | } // end if ( count( $registrations ) > 0 ) |
| 91 | 91 | |
| 92 | 92 | ?> |
@@ -3,7 +3,7 @@ discard block |
||
| 3 | 3 | /** @var array $ticket_line_item */ |
| 4 | 4 | /** @var string $default_hidden_inputs */ |
| 5 | 5 | ?> |
| 6 | -<?php if (!is_admin()) : ?> |
|
| 6 | +<?php if ( ! is_admin()) : ?> |
|
| 7 | 7 | <p id="spco-attendee_information-pg" class="spco-steps-pg small-text drk-grey-text"> |
| 8 | 8 | <?php echo apply_filters( |
| 9 | 9 | 'FHEE__registration_page_attendee_information__attendee_information_pg', |
@@ -32,7 +32,7 @@ discard block |
||
| 32 | 32 | class="spco-attendee-panel-dv spco-attendee-ticket-<?php echo $ticketID; ?>"> |
| 33 | 33 | |
| 34 | 34 | <div class="spco-ticket-info-dv small-text"> |
| 35 | - <?php if (!is_admin()) : ?> |
|
| 35 | + <?php if ( ! is_admin()) : ?> |
|
| 36 | 36 | <h5><?php esc_html_e('Details', 'event_espresso'); ?></h5> |
| 37 | 37 | <?php endif; ?> |
| 38 | 38 | <table class="spco-ticket-details"> |
@@ -64,7 +64,7 @@ discard block |
||
| 64 | 64 | foreach ($registrations as $registration) { |
| 65 | 65 | if ($registration instanceof EE_Registration) { |
| 66 | 66 | if ($registration->ticket()->ID() !== $prev_ticket) { |
| 67 | - echo $ticket_line_item[ $registration->ticket()->ID() ]; |
|
| 67 | + echo $ticket_line_item[$registration->ticket()->ID()]; |
|
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | $prev_ticket = $registration->ticket()->ID(); |
@@ -28,602 +28,602 @@ |
||
| 28 | 28 | class EEM_Line_Item extends EEM_Base |
| 29 | 29 | { |
| 30 | 30 | |
| 31 | - /** |
|
| 32 | - * Tax sub-total is just the total of all the taxes, which should be children |
|
| 33 | - * of this line item. There should only ever be one tax sub-total, and it should |
|
| 34 | - * be a direct child of. Its quantity and LIN_unit_price = 1. |
|
| 35 | - */ |
|
| 36 | - const type_tax_sub_total = 'tax-sub-total'; |
|
| 37 | - |
|
| 38 | - /** |
|
| 39 | - * Tax line items indicate a tax applied to all the taxable line items. |
|
| 40 | - * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal |
|
| 41 | - * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1. |
|
| 42 | - */ |
|
| 43 | - const type_tax = 'tax'; |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * Indicating individual items purchased, or discounts or surcharges. |
|
| 47 | - * The sum of all the regular line items plus the tax items should equal the grand total. |
|
| 48 | - * Possible children are sub-line-items and cancellations. |
|
| 49 | - * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children |
|
| 50 | - * LIN_totals. Its LIN_percent = 0. |
|
| 51 | - * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1). |
|
| 52 | - * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1. |
|
| 53 | - */ |
|
| 54 | - const type_line_item = 'line-item'; |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * Line item indicating all the factors that make a single line item. |
|
| 58 | - * Sub-line items should have NO children line items. |
|
| 59 | - * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's |
|
| 60 | - * contribution towards the price of ONE of their parent items, and its LIN_total should be |
|
| 61 | - * = LIN_quantity * LIN_unit_price. Its LIN_percent = 0. |
|
| 62 | - * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should |
|
| 63 | - * = LIN_percent / 100 * sum of lower-priority sibling line items.. |
|
| 64 | - */ |
|
| 65 | - const type_sub_line_item = 'sub-item'; |
|
| 66 | - |
|
| 67 | - /** |
|
| 68 | - * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal). |
|
| 69 | - * Direct children should be event subtotals. |
|
| 70 | - * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals. |
|
| 71 | - */ |
|
| 72 | - const type_sub_total = 'sub-total'; |
|
| 73 | - |
|
| 74 | - /** |
|
| 75 | - * Line item for the grand total of an order. |
|
| 76 | - * Its direct children should be tax subtotals and (pre-tax) subtotals, |
|
| 77 | - * and possibly a regular line item indicating a transaction-wide discount/surcharge. |
|
| 78 | - * Should have a quantity of 1, a LIN_total and LIN_unit_price of the entire order's amount. |
|
| 79 | - */ |
|
| 80 | - const type_total = 'total'; |
|
| 81 | - |
|
| 82 | - /** |
|
| 83 | - * When a line item is cancelled, a sub-line-item of type 'cancellation' |
|
| 84 | - * should be created, indicating the quantity that were cancelled |
|
| 85 | - * (because a line item could have a quantity of 1, and its cancellation item |
|
| 86 | - * could be for 3, indicating that originally 4 were purchased, but 3 have been |
|
| 87 | - * cancelled, and only one remains). |
|
| 88 | - * When items are refunded, a cancellation line item should be made, which points |
|
| 89 | - * to teh payment model object which actually refunded the payment. |
|
| 90 | - * Cancellations should NOT have any children line items; the should NOT affect |
|
| 91 | - * any calculations, and are only meant as a record that cancellations have occurred. |
|
| 92 | - * Their LIN_percent should be 0. |
|
| 93 | - */ |
|
| 94 | - const type_cancellation = 'cancellation'; |
|
| 95 | - |
|
| 96 | - // various line item object types |
|
| 97 | - const OBJ_TYPE_EVENT = 'Event'; |
|
| 98 | - |
|
| 99 | - const OBJ_TYPE_PRICE = 'Price'; |
|
| 100 | - |
|
| 101 | - const OBJ_TYPE_PROMOTION = 'Promotion'; |
|
| 102 | - |
|
| 103 | - const OBJ_TYPE_TICKET = 'Ticket'; |
|
| 104 | - |
|
| 105 | - const OBJ_TYPE_TRANSACTION = 'Transaction'; |
|
| 106 | - |
|
| 107 | - /** |
|
| 108 | - * @var EEM_Line_Item $_instance |
|
| 109 | - */ |
|
| 110 | - protected static $_instance; |
|
| 111 | - |
|
| 112 | - |
|
| 113 | - /** |
|
| 114 | - * private constructor to prevent direct creation |
|
| 115 | - * |
|
| 116 | - * @Constructor |
|
| 117 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
| 118 | - * (and any incoming timezone data that gets saved). |
|
| 119 | - * Note this just sends the timezone info to the date time model field objects. |
|
| 120 | - * Default is NULL |
|
| 121 | - * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
| 122 | - * @throws EE_Error |
|
| 123 | - * @throws InvalidArgumentException |
|
| 124 | - */ |
|
| 125 | - protected function __construct($timezone) |
|
| 126 | - { |
|
| 127 | - $this->singular_item = esc_html__('Line Item', 'event_espresso'); |
|
| 128 | - $this->plural_item = esc_html__('Line Items', 'event_espresso'); |
|
| 129 | - |
|
| 130 | - $this->_tables = array( |
|
| 131 | - 'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID'), |
|
| 132 | - ); |
|
| 133 | - $line_items_can_be_for = apply_filters( |
|
| 134 | - 'FHEE__EEM_Line_Item__line_items_can_be_for', |
|
| 135 | - array('Ticket', 'Price', 'Event') |
|
| 136 | - ); |
|
| 137 | - $this->_fields = array( |
|
| 138 | - 'Line_Item' => array( |
|
| 139 | - 'LIN_ID' => new EE_Primary_Key_Int_Field( |
|
| 140 | - 'LIN_ID', |
|
| 141 | - esc_html__('ID', 'event_espresso') |
|
| 142 | - ), |
|
| 143 | - 'LIN_code' => new EE_Slug_Field( |
|
| 144 | - 'LIN_code', |
|
| 145 | - esc_html__('Code for index into Cart', 'event_espresso'), |
|
| 146 | - true |
|
| 147 | - ), |
|
| 148 | - 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
| 149 | - 'TXN_ID', |
|
| 150 | - esc_html__('Transaction ID', 'event_espresso'), |
|
| 151 | - true, |
|
| 152 | - null, |
|
| 153 | - 'Transaction' |
|
| 154 | - ), |
|
| 155 | - 'LIN_name' => new EE_Full_HTML_Field( |
|
| 156 | - 'LIN_name', |
|
| 157 | - esc_html__('Line Item Name', 'event_espresso'), |
|
| 158 | - false, |
|
| 159 | - '' |
|
| 160 | - ), |
|
| 161 | - 'LIN_desc' => new EE_Full_HTML_Field( |
|
| 162 | - 'LIN_desc', |
|
| 163 | - esc_html__('Line Item Description', 'event_espresso'), |
|
| 164 | - true |
|
| 165 | - ), |
|
| 166 | - 'LIN_unit_price' => new EE_Money_Field( |
|
| 167 | - 'LIN_unit_price', |
|
| 168 | - esc_html__('Unit Price', 'event_espresso'), |
|
| 169 | - false, |
|
| 170 | - 0 |
|
| 171 | - ), |
|
| 172 | - 'LIN_percent' => new EE_Float_Field( |
|
| 173 | - 'LIN_percent', |
|
| 174 | - esc_html__('Percent', 'event_espresso'), |
|
| 175 | - false, |
|
| 176 | - 0 |
|
| 177 | - ), |
|
| 178 | - 'LIN_is_taxable' => new EE_Boolean_Field( |
|
| 179 | - 'LIN_is_taxable', |
|
| 180 | - esc_html__('Taxable', 'event_espresso'), |
|
| 181 | - false, |
|
| 182 | - false |
|
| 183 | - ), |
|
| 184 | - 'LIN_order' => new EE_Integer_Field( |
|
| 185 | - 'LIN_order', |
|
| 186 | - esc_html__('Order of Application towards total of parent', 'event_espresso'), |
|
| 187 | - false, |
|
| 188 | - 1 |
|
| 189 | - ), |
|
| 190 | - 'LIN_total' => new EE_Money_Field( |
|
| 191 | - 'LIN_total', |
|
| 192 | - esc_html__('Total (unit price x quantity)', 'event_espresso'), |
|
| 193 | - false, |
|
| 194 | - 0 |
|
| 195 | - ), |
|
| 196 | - 'LIN_quantity' => new EE_Integer_Field( |
|
| 197 | - 'LIN_quantity', |
|
| 198 | - esc_html__('Quantity', 'event_espresso'), |
|
| 199 | - true, |
|
| 200 | - 1 |
|
| 201 | - ), |
|
| 202 | - 'LIN_parent' => new EE_Integer_Field( |
|
| 203 | - 'LIN_parent', |
|
| 204 | - esc_html__("Parent ID (this item goes towards that Line Item's total)", 'event_espresso'), |
|
| 205 | - true, |
|
| 206 | - null |
|
| 207 | - ), |
|
| 208 | - 'LIN_type' => new EE_Enum_Text_Field( |
|
| 209 | - 'LIN_type', |
|
| 210 | - esc_html__('Type', 'event_espresso'), |
|
| 211 | - false, |
|
| 212 | - 'line-item', |
|
| 213 | - array( |
|
| 214 | - self::type_line_item => esc_html__('Line Item', 'event_espresso'), |
|
| 215 | - self::type_sub_line_item => esc_html__('Sub-Item', 'event_espresso'), |
|
| 216 | - self::type_sub_total => esc_html__('Subtotal', 'event_espresso'), |
|
| 217 | - self::type_tax_sub_total => esc_html__('Tax Subtotal', 'event_espresso'), |
|
| 218 | - self::type_tax => esc_html__('Tax', 'event_espresso'), |
|
| 219 | - self::type_total => esc_html__('Total', 'event_espresso'), |
|
| 220 | - self::type_cancellation => esc_html__('Cancellation', 'event_espresso'), |
|
| 221 | - ) |
|
| 222 | - ), |
|
| 223 | - 'OBJ_ID' => new EE_Foreign_Key_Int_Field( |
|
| 224 | - 'OBJ_ID', |
|
| 225 | - esc_html__('ID of Item purchased.', 'event_espresso'), |
|
| 226 | - true, |
|
| 227 | - null, |
|
| 228 | - $line_items_can_be_for |
|
| 229 | - ), |
|
| 230 | - 'OBJ_type' => new EE_Any_Foreign_Model_Name_Field( |
|
| 231 | - 'OBJ_type', |
|
| 232 | - esc_html__('Model Name this Line Item is for', 'event_espresso'), |
|
| 233 | - true, |
|
| 234 | - null, |
|
| 235 | - $line_items_can_be_for |
|
| 236 | - ), |
|
| 237 | - 'LIN_timestamp' => new EE_Datetime_Field( |
|
| 238 | - 'LIN_timestamp', |
|
| 239 | - esc_html__('When the line item was created', 'event_espresso'), |
|
| 240 | - false, |
|
| 241 | - EE_Datetime_Field::now, |
|
| 242 | - $timezone |
|
| 243 | - ), |
|
| 244 | - ), |
|
| 245 | - ); |
|
| 246 | - $this->_model_relations = array( |
|
| 247 | - 'Transaction' => new EE_Belongs_To_Relation(), |
|
| 248 | - 'Ticket' => new EE_Belongs_To_Any_Relation(), |
|
| 249 | - 'Price' => new EE_Belongs_To_Any_Relation(), |
|
| 250 | - 'Event' => new EE_Belongs_To_Any_Relation(), |
|
| 251 | - ); |
|
| 252 | - $this->_model_chain_to_wp_user = 'Transaction.Registration.Event'; |
|
| 253 | - $this->_caps_slug = 'transactions'; |
|
| 254 | - parent::__construct($timezone); |
|
| 255 | - } |
|
| 256 | - |
|
| 257 | - |
|
| 258 | - /** |
|
| 259 | - * Gets all the line items for this transaction of the given type |
|
| 260 | - * |
|
| 261 | - * @param string $line_item_type like one of EEM_Line_Item::type_* |
|
| 262 | - * @param EE_Transaction|int $transaction |
|
| 263 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 264 | - * @throws EE_Error |
|
| 265 | - * @throws InvalidArgumentException |
|
| 266 | - * @throws InvalidDataTypeException |
|
| 267 | - * @throws InvalidInterfaceException |
|
| 268 | - */ |
|
| 269 | - public function get_all_of_type_for_transaction($line_item_type, $transaction) |
|
| 270 | - { |
|
| 271 | - $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
| 272 | - return $this->get_all(array( |
|
| 273 | - array( |
|
| 274 | - 'LIN_type' => $line_item_type, |
|
| 275 | - 'TXN_ID' => $transaction, |
|
| 276 | - ), |
|
| 277 | - )); |
|
| 278 | - } |
|
| 279 | - |
|
| 280 | - |
|
| 281 | - /** |
|
| 282 | - * Gets all line items unrelated to tickets that are normal line items |
|
| 283 | - * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category) |
|
| 284 | - * |
|
| 285 | - * @param EE_Transaction|int $transaction |
|
| 286 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 287 | - * @throws EE_Error |
|
| 288 | - * @throws InvalidArgumentException |
|
| 289 | - * @throws InvalidDataTypeException |
|
| 290 | - * @throws InvalidInterfaceException |
|
| 291 | - */ |
|
| 292 | - public function get_all_non_ticket_line_items_for_transaction($transaction) |
|
| 293 | - { |
|
| 294 | - $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
| 295 | - return $this->get_all(array( |
|
| 296 | - array( |
|
| 297 | - 'LIN_type' => self::type_line_item, |
|
| 298 | - 'TXN_ID' => $transaction, |
|
| 299 | - 'OR' => array( |
|
| 300 | - 'OBJ_type*notticket' => array('!=', EEM_Line_Item::OBJ_TYPE_TICKET), |
|
| 301 | - 'OBJ_type*null' => array('IS_NULL'), |
|
| 302 | - ), |
|
| 303 | - ), |
|
| 304 | - )); |
|
| 305 | - } |
|
| 306 | - |
|
| 307 | - |
|
| 308 | - /** |
|
| 309 | - * Deletes line items with no transaction who have passed the transaction cutoff time. |
|
| 310 | - * This needs to be very efficient |
|
| 311 | - * because if there are spam bots afoot there will be LOTS of line items. Also MySQL doesn't allow a limit when |
|
| 312 | - * deleting and joining tables like this. |
|
| 313 | - * |
|
| 314 | - * @return int count of how many deleted |
|
| 315 | - * @throws EE_Error |
|
| 316 | - * @throws InvalidArgumentException |
|
| 317 | - * @throws InvalidDataTypeException |
|
| 318 | - * @throws InvalidInterfaceException |
|
| 319 | - */ |
|
| 320 | - public function delete_line_items_with_no_transaction() |
|
| 321 | - { |
|
| 322 | - /** @type WPDB $wpdb */ |
|
| 323 | - global $wpdb; |
|
| 324 | - $time_to_leave_alone = apply_filters( |
|
| 325 | - 'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', |
|
| 326 | - WEEK_IN_SECONDS |
|
| 327 | - ); |
|
| 328 | - $query = $wpdb->prepare( |
|
| 329 | - 'DELETE li |
|
| 31 | + /** |
|
| 32 | + * Tax sub-total is just the total of all the taxes, which should be children |
|
| 33 | + * of this line item. There should only ever be one tax sub-total, and it should |
|
| 34 | + * be a direct child of. Its quantity and LIN_unit_price = 1. |
|
| 35 | + */ |
|
| 36 | + const type_tax_sub_total = 'tax-sub-total'; |
|
| 37 | + |
|
| 38 | + /** |
|
| 39 | + * Tax line items indicate a tax applied to all the taxable line items. |
|
| 40 | + * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal |
|
| 41 | + * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1. |
|
| 42 | + */ |
|
| 43 | + const type_tax = 'tax'; |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * Indicating individual items purchased, or discounts or surcharges. |
|
| 47 | + * The sum of all the regular line items plus the tax items should equal the grand total. |
|
| 48 | + * Possible children are sub-line-items and cancellations. |
|
| 49 | + * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children |
|
| 50 | + * LIN_totals. Its LIN_percent = 0. |
|
| 51 | + * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1). |
|
| 52 | + * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1. |
|
| 53 | + */ |
|
| 54 | + const type_line_item = 'line-item'; |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * Line item indicating all the factors that make a single line item. |
|
| 58 | + * Sub-line items should have NO children line items. |
|
| 59 | + * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's |
|
| 60 | + * contribution towards the price of ONE of their parent items, and its LIN_total should be |
|
| 61 | + * = LIN_quantity * LIN_unit_price. Its LIN_percent = 0. |
|
| 62 | + * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should |
|
| 63 | + * = LIN_percent / 100 * sum of lower-priority sibling line items.. |
|
| 64 | + */ |
|
| 65 | + const type_sub_line_item = 'sub-item'; |
|
| 66 | + |
|
| 67 | + /** |
|
| 68 | + * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal). |
|
| 69 | + * Direct children should be event subtotals. |
|
| 70 | + * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals. |
|
| 71 | + */ |
|
| 72 | + const type_sub_total = 'sub-total'; |
|
| 73 | + |
|
| 74 | + /** |
|
| 75 | + * Line item for the grand total of an order. |
|
| 76 | + * Its direct children should be tax subtotals and (pre-tax) subtotals, |
|
| 77 | + * and possibly a regular line item indicating a transaction-wide discount/surcharge. |
|
| 78 | + * Should have a quantity of 1, a LIN_total and LIN_unit_price of the entire order's amount. |
|
| 79 | + */ |
|
| 80 | + const type_total = 'total'; |
|
| 81 | + |
|
| 82 | + /** |
|
| 83 | + * When a line item is cancelled, a sub-line-item of type 'cancellation' |
|
| 84 | + * should be created, indicating the quantity that were cancelled |
|
| 85 | + * (because a line item could have a quantity of 1, and its cancellation item |
|
| 86 | + * could be for 3, indicating that originally 4 were purchased, but 3 have been |
|
| 87 | + * cancelled, and only one remains). |
|
| 88 | + * When items are refunded, a cancellation line item should be made, which points |
|
| 89 | + * to teh payment model object which actually refunded the payment. |
|
| 90 | + * Cancellations should NOT have any children line items; the should NOT affect |
|
| 91 | + * any calculations, and are only meant as a record that cancellations have occurred. |
|
| 92 | + * Their LIN_percent should be 0. |
|
| 93 | + */ |
|
| 94 | + const type_cancellation = 'cancellation'; |
|
| 95 | + |
|
| 96 | + // various line item object types |
|
| 97 | + const OBJ_TYPE_EVENT = 'Event'; |
|
| 98 | + |
|
| 99 | + const OBJ_TYPE_PRICE = 'Price'; |
|
| 100 | + |
|
| 101 | + const OBJ_TYPE_PROMOTION = 'Promotion'; |
|
| 102 | + |
|
| 103 | + const OBJ_TYPE_TICKET = 'Ticket'; |
|
| 104 | + |
|
| 105 | + const OBJ_TYPE_TRANSACTION = 'Transaction'; |
|
| 106 | + |
|
| 107 | + /** |
|
| 108 | + * @var EEM_Line_Item $_instance |
|
| 109 | + */ |
|
| 110 | + protected static $_instance; |
|
| 111 | + |
|
| 112 | + |
|
| 113 | + /** |
|
| 114 | + * private constructor to prevent direct creation |
|
| 115 | + * |
|
| 116 | + * @Constructor |
|
| 117 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
| 118 | + * (and any incoming timezone data that gets saved). |
|
| 119 | + * Note this just sends the timezone info to the date time model field objects. |
|
| 120 | + * Default is NULL |
|
| 121 | + * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
| 122 | + * @throws EE_Error |
|
| 123 | + * @throws InvalidArgumentException |
|
| 124 | + */ |
|
| 125 | + protected function __construct($timezone) |
|
| 126 | + { |
|
| 127 | + $this->singular_item = esc_html__('Line Item', 'event_espresso'); |
|
| 128 | + $this->plural_item = esc_html__('Line Items', 'event_espresso'); |
|
| 129 | + |
|
| 130 | + $this->_tables = array( |
|
| 131 | + 'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID'), |
|
| 132 | + ); |
|
| 133 | + $line_items_can_be_for = apply_filters( |
|
| 134 | + 'FHEE__EEM_Line_Item__line_items_can_be_for', |
|
| 135 | + array('Ticket', 'Price', 'Event') |
|
| 136 | + ); |
|
| 137 | + $this->_fields = array( |
|
| 138 | + 'Line_Item' => array( |
|
| 139 | + 'LIN_ID' => new EE_Primary_Key_Int_Field( |
|
| 140 | + 'LIN_ID', |
|
| 141 | + esc_html__('ID', 'event_espresso') |
|
| 142 | + ), |
|
| 143 | + 'LIN_code' => new EE_Slug_Field( |
|
| 144 | + 'LIN_code', |
|
| 145 | + esc_html__('Code for index into Cart', 'event_espresso'), |
|
| 146 | + true |
|
| 147 | + ), |
|
| 148 | + 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
| 149 | + 'TXN_ID', |
|
| 150 | + esc_html__('Transaction ID', 'event_espresso'), |
|
| 151 | + true, |
|
| 152 | + null, |
|
| 153 | + 'Transaction' |
|
| 154 | + ), |
|
| 155 | + 'LIN_name' => new EE_Full_HTML_Field( |
|
| 156 | + 'LIN_name', |
|
| 157 | + esc_html__('Line Item Name', 'event_espresso'), |
|
| 158 | + false, |
|
| 159 | + '' |
|
| 160 | + ), |
|
| 161 | + 'LIN_desc' => new EE_Full_HTML_Field( |
|
| 162 | + 'LIN_desc', |
|
| 163 | + esc_html__('Line Item Description', 'event_espresso'), |
|
| 164 | + true |
|
| 165 | + ), |
|
| 166 | + 'LIN_unit_price' => new EE_Money_Field( |
|
| 167 | + 'LIN_unit_price', |
|
| 168 | + esc_html__('Unit Price', 'event_espresso'), |
|
| 169 | + false, |
|
| 170 | + 0 |
|
| 171 | + ), |
|
| 172 | + 'LIN_percent' => new EE_Float_Field( |
|
| 173 | + 'LIN_percent', |
|
| 174 | + esc_html__('Percent', 'event_espresso'), |
|
| 175 | + false, |
|
| 176 | + 0 |
|
| 177 | + ), |
|
| 178 | + 'LIN_is_taxable' => new EE_Boolean_Field( |
|
| 179 | + 'LIN_is_taxable', |
|
| 180 | + esc_html__('Taxable', 'event_espresso'), |
|
| 181 | + false, |
|
| 182 | + false |
|
| 183 | + ), |
|
| 184 | + 'LIN_order' => new EE_Integer_Field( |
|
| 185 | + 'LIN_order', |
|
| 186 | + esc_html__('Order of Application towards total of parent', 'event_espresso'), |
|
| 187 | + false, |
|
| 188 | + 1 |
|
| 189 | + ), |
|
| 190 | + 'LIN_total' => new EE_Money_Field( |
|
| 191 | + 'LIN_total', |
|
| 192 | + esc_html__('Total (unit price x quantity)', 'event_espresso'), |
|
| 193 | + false, |
|
| 194 | + 0 |
|
| 195 | + ), |
|
| 196 | + 'LIN_quantity' => new EE_Integer_Field( |
|
| 197 | + 'LIN_quantity', |
|
| 198 | + esc_html__('Quantity', 'event_espresso'), |
|
| 199 | + true, |
|
| 200 | + 1 |
|
| 201 | + ), |
|
| 202 | + 'LIN_parent' => new EE_Integer_Field( |
|
| 203 | + 'LIN_parent', |
|
| 204 | + esc_html__("Parent ID (this item goes towards that Line Item's total)", 'event_espresso'), |
|
| 205 | + true, |
|
| 206 | + null |
|
| 207 | + ), |
|
| 208 | + 'LIN_type' => new EE_Enum_Text_Field( |
|
| 209 | + 'LIN_type', |
|
| 210 | + esc_html__('Type', 'event_espresso'), |
|
| 211 | + false, |
|
| 212 | + 'line-item', |
|
| 213 | + array( |
|
| 214 | + self::type_line_item => esc_html__('Line Item', 'event_espresso'), |
|
| 215 | + self::type_sub_line_item => esc_html__('Sub-Item', 'event_espresso'), |
|
| 216 | + self::type_sub_total => esc_html__('Subtotal', 'event_espresso'), |
|
| 217 | + self::type_tax_sub_total => esc_html__('Tax Subtotal', 'event_espresso'), |
|
| 218 | + self::type_tax => esc_html__('Tax', 'event_espresso'), |
|
| 219 | + self::type_total => esc_html__('Total', 'event_espresso'), |
|
| 220 | + self::type_cancellation => esc_html__('Cancellation', 'event_espresso'), |
|
| 221 | + ) |
|
| 222 | + ), |
|
| 223 | + 'OBJ_ID' => new EE_Foreign_Key_Int_Field( |
|
| 224 | + 'OBJ_ID', |
|
| 225 | + esc_html__('ID of Item purchased.', 'event_espresso'), |
|
| 226 | + true, |
|
| 227 | + null, |
|
| 228 | + $line_items_can_be_for |
|
| 229 | + ), |
|
| 230 | + 'OBJ_type' => new EE_Any_Foreign_Model_Name_Field( |
|
| 231 | + 'OBJ_type', |
|
| 232 | + esc_html__('Model Name this Line Item is for', 'event_espresso'), |
|
| 233 | + true, |
|
| 234 | + null, |
|
| 235 | + $line_items_can_be_for |
|
| 236 | + ), |
|
| 237 | + 'LIN_timestamp' => new EE_Datetime_Field( |
|
| 238 | + 'LIN_timestamp', |
|
| 239 | + esc_html__('When the line item was created', 'event_espresso'), |
|
| 240 | + false, |
|
| 241 | + EE_Datetime_Field::now, |
|
| 242 | + $timezone |
|
| 243 | + ), |
|
| 244 | + ), |
|
| 245 | + ); |
|
| 246 | + $this->_model_relations = array( |
|
| 247 | + 'Transaction' => new EE_Belongs_To_Relation(), |
|
| 248 | + 'Ticket' => new EE_Belongs_To_Any_Relation(), |
|
| 249 | + 'Price' => new EE_Belongs_To_Any_Relation(), |
|
| 250 | + 'Event' => new EE_Belongs_To_Any_Relation(), |
|
| 251 | + ); |
|
| 252 | + $this->_model_chain_to_wp_user = 'Transaction.Registration.Event'; |
|
| 253 | + $this->_caps_slug = 'transactions'; |
|
| 254 | + parent::__construct($timezone); |
|
| 255 | + } |
|
| 256 | + |
|
| 257 | + |
|
| 258 | + /** |
|
| 259 | + * Gets all the line items for this transaction of the given type |
|
| 260 | + * |
|
| 261 | + * @param string $line_item_type like one of EEM_Line_Item::type_* |
|
| 262 | + * @param EE_Transaction|int $transaction |
|
| 263 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 264 | + * @throws EE_Error |
|
| 265 | + * @throws InvalidArgumentException |
|
| 266 | + * @throws InvalidDataTypeException |
|
| 267 | + * @throws InvalidInterfaceException |
|
| 268 | + */ |
|
| 269 | + public function get_all_of_type_for_transaction($line_item_type, $transaction) |
|
| 270 | + { |
|
| 271 | + $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
| 272 | + return $this->get_all(array( |
|
| 273 | + array( |
|
| 274 | + 'LIN_type' => $line_item_type, |
|
| 275 | + 'TXN_ID' => $transaction, |
|
| 276 | + ), |
|
| 277 | + )); |
|
| 278 | + } |
|
| 279 | + |
|
| 280 | + |
|
| 281 | + /** |
|
| 282 | + * Gets all line items unrelated to tickets that are normal line items |
|
| 283 | + * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category) |
|
| 284 | + * |
|
| 285 | + * @param EE_Transaction|int $transaction |
|
| 286 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 287 | + * @throws EE_Error |
|
| 288 | + * @throws InvalidArgumentException |
|
| 289 | + * @throws InvalidDataTypeException |
|
| 290 | + * @throws InvalidInterfaceException |
|
| 291 | + */ |
|
| 292 | + public function get_all_non_ticket_line_items_for_transaction($transaction) |
|
| 293 | + { |
|
| 294 | + $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
| 295 | + return $this->get_all(array( |
|
| 296 | + array( |
|
| 297 | + 'LIN_type' => self::type_line_item, |
|
| 298 | + 'TXN_ID' => $transaction, |
|
| 299 | + 'OR' => array( |
|
| 300 | + 'OBJ_type*notticket' => array('!=', EEM_Line_Item::OBJ_TYPE_TICKET), |
|
| 301 | + 'OBJ_type*null' => array('IS_NULL'), |
|
| 302 | + ), |
|
| 303 | + ), |
|
| 304 | + )); |
|
| 305 | + } |
|
| 306 | + |
|
| 307 | + |
|
| 308 | + /** |
|
| 309 | + * Deletes line items with no transaction who have passed the transaction cutoff time. |
|
| 310 | + * This needs to be very efficient |
|
| 311 | + * because if there are spam bots afoot there will be LOTS of line items. Also MySQL doesn't allow a limit when |
|
| 312 | + * deleting and joining tables like this. |
|
| 313 | + * |
|
| 314 | + * @return int count of how many deleted |
|
| 315 | + * @throws EE_Error |
|
| 316 | + * @throws InvalidArgumentException |
|
| 317 | + * @throws InvalidDataTypeException |
|
| 318 | + * @throws InvalidInterfaceException |
|
| 319 | + */ |
|
| 320 | + public function delete_line_items_with_no_transaction() |
|
| 321 | + { |
|
| 322 | + /** @type WPDB $wpdb */ |
|
| 323 | + global $wpdb; |
|
| 324 | + $time_to_leave_alone = apply_filters( |
|
| 325 | + 'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', |
|
| 326 | + WEEK_IN_SECONDS |
|
| 327 | + ); |
|
| 328 | + $query = $wpdb->prepare( |
|
| 329 | + 'DELETE li |
|
| 330 | 330 | FROM ' . $this->table() . ' li |
| 331 | 331 | LEFT JOIN ' . EEM_Transaction::instance()->table() . ' t ON li.TXN_ID = t.TXN_ID |
| 332 | 332 | WHERE t.TXN_ID IS NULL AND li.LIN_timestamp < %s', |
| 333 | - // use GMT time because that's what TXN_timestamps are in |
|
| 334 | - date('Y-m-d H:i:s', time() - $time_to_leave_alone) |
|
| 335 | - ); |
|
| 336 | - return $wpdb->query($query); |
|
| 337 | - } |
|
| 338 | - |
|
| 339 | - |
|
| 340 | - /** |
|
| 341 | - * get_line_item_for_transaction_object |
|
| 342 | - * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket |
|
| 343 | - * |
|
| 344 | - * @param int $TXN_ID |
|
| 345 | - * @param EE_Base_Class $object |
|
| 346 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 347 | - * @throws EE_Error |
|
| 348 | - * @throws InvalidArgumentException |
|
| 349 | - * @throws InvalidDataTypeException |
|
| 350 | - * @throws InvalidInterfaceException |
|
| 351 | - * @throws ReflectionException |
|
| 352 | - */ |
|
| 353 | - public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object) |
|
| 354 | - { |
|
| 355 | - return $this->get_all(array( |
|
| 356 | - array( |
|
| 357 | - 'TXN_ID' => $TXN_ID, |
|
| 358 | - 'OBJ_type' => str_replace('EE_', '', get_class($object)), |
|
| 359 | - 'OBJ_ID' => $object->ID(), |
|
| 360 | - ), |
|
| 361 | - )); |
|
| 362 | - } |
|
| 363 | - |
|
| 364 | - |
|
| 365 | - /** |
|
| 366 | - * get_object_line_items_for_transaction |
|
| 367 | - * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs |
|
| 368 | - * |
|
| 369 | - * @param int $TXN_ID |
|
| 370 | - * @param string $OBJ_type |
|
| 371 | - * @param array $OBJ_IDs |
|
| 372 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 373 | - * @throws EE_Error |
|
| 374 | - */ |
|
| 375 | - public function get_object_line_items_for_transaction( |
|
| 376 | - $TXN_ID, |
|
| 377 | - $OBJ_type = EEM_Line_Item::OBJ_TYPE_EVENT, |
|
| 378 | - $OBJ_IDs = array() |
|
| 379 | - ) { |
|
| 380 | - $query_params = array( |
|
| 381 | - 'OBJ_type' => $OBJ_type, |
|
| 382 | - // if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query |
|
| 383 | - 'OBJ_ID' => is_array($OBJ_IDs) && ! isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs, |
|
| 384 | - ); |
|
| 385 | - if ($TXN_ID) { |
|
| 386 | - $query_params['TXN_ID'] = $TXN_ID; |
|
| 387 | - } |
|
| 388 | - return $this->get_all(array($query_params)); |
|
| 389 | - } |
|
| 390 | - |
|
| 391 | - |
|
| 392 | - /** |
|
| 393 | - * get_all_ticket_line_items_for_transaction |
|
| 394 | - * |
|
| 395 | - * @param EE_Transaction $transaction |
|
| 396 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 397 | - * @throws EE_Error |
|
| 398 | - * @throws InvalidArgumentException |
|
| 399 | - * @throws InvalidDataTypeException |
|
| 400 | - * @throws InvalidInterfaceException |
|
| 401 | - * @throws ReflectionException |
|
| 402 | - */ |
|
| 403 | - public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction) |
|
| 404 | - { |
|
| 405 | - return $this->get_all(array( |
|
| 406 | - array( |
|
| 407 | - 'TXN_ID' => $transaction->ID(), |
|
| 408 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 409 | - ), |
|
| 410 | - )); |
|
| 411 | - } |
|
| 412 | - |
|
| 413 | - |
|
| 414 | - /** |
|
| 415 | - * get_ticket_line_item_for_transaction |
|
| 416 | - * |
|
| 417 | - * @param int $TXN_ID |
|
| 418 | - * @param int $TKT_ID |
|
| 419 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 420 | - * @throws EE_Error |
|
| 421 | - * @throws InvalidArgumentException |
|
| 422 | - * @throws InvalidDataTypeException |
|
| 423 | - * @throws InvalidInterfaceException |
|
| 424 | - */ |
|
| 425 | - public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID) |
|
| 426 | - { |
|
| 427 | - return $this->get_one(array( |
|
| 428 | - array( |
|
| 429 | - 'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID), |
|
| 430 | - 'OBJ_ID' => $TKT_ID, |
|
| 431 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 432 | - ), |
|
| 433 | - )); |
|
| 434 | - } |
|
| 435 | - |
|
| 436 | - |
|
| 437 | - /** |
|
| 438 | - * get_existing_promotion_line_item |
|
| 439 | - * searches the cart for existing line items for the specified promotion |
|
| 440 | - * |
|
| 441 | - * @since 1.0.0 |
|
| 442 | - * @param EE_Line_Item $parent_line_item |
|
| 443 | - * @param EE_Promotion $promotion |
|
| 444 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 445 | - * @throws EE_Error |
|
| 446 | - * @throws InvalidArgumentException |
|
| 447 | - * @throws InvalidDataTypeException |
|
| 448 | - * @throws InvalidInterfaceException |
|
| 449 | - * @throws ReflectionException |
|
| 450 | - */ |
|
| 451 | - public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion) |
|
| 452 | - { |
|
| 453 | - return $this->get_one(array( |
|
| 454 | - array( |
|
| 455 | - 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
| 456 | - 'LIN_parent' => $parent_line_item->ID(), |
|
| 457 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
| 458 | - 'OBJ_ID' => $promotion->ID(), |
|
| 459 | - ), |
|
| 460 | - )); |
|
| 461 | - } |
|
| 462 | - |
|
| 463 | - |
|
| 464 | - /** |
|
| 465 | - * get_all_promotion_line_items |
|
| 466 | - * searches the cart for any and all existing promotion line items |
|
| 467 | - * |
|
| 468 | - * @since 1.0.0 |
|
| 469 | - * @param EE_Line_Item $parent_line_item |
|
| 470 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 471 | - * @throws EE_Error |
|
| 472 | - * @throws InvalidArgumentException |
|
| 473 | - * @throws InvalidDataTypeException |
|
| 474 | - * @throws InvalidInterfaceException |
|
| 475 | - * @throws ReflectionException |
|
| 476 | - */ |
|
| 477 | - public function get_all_promotion_line_items(EE_Line_Item $parent_line_item) |
|
| 478 | - { |
|
| 479 | - return $this->get_all(array( |
|
| 480 | - array( |
|
| 481 | - 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
| 482 | - 'LIN_parent' => $parent_line_item->ID(), |
|
| 483 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
| 484 | - ), |
|
| 485 | - )); |
|
| 486 | - } |
|
| 487 | - |
|
| 488 | - |
|
| 489 | - /** |
|
| 490 | - * Gets the registration's corresponding line item. |
|
| 491 | - * Note: basically does NOT support having multiple line items for a single ticket, |
|
| 492 | - * which would happen if some of the registrations had a price modifier while others didn't. |
|
| 493 | - * In order to support that, we'd probably need a LIN_ID on registrations or something. |
|
| 494 | - * |
|
| 495 | - * @param EE_Registration $registration |
|
| 496 | - * @return EE_Base_Class|EE_Line_ITem|EE_Soft_Delete_Base_Class|NULL |
|
| 497 | - * @throws EE_Error |
|
| 498 | - */ |
|
| 499 | - public function get_line_item_for_registration(EE_Registration $registration) |
|
| 500 | - { |
|
| 501 | - return $this->get_one($this->line_item_for_registration_query_params($registration)); |
|
| 502 | - } |
|
| 503 | - |
|
| 504 | - |
|
| 505 | - /** |
|
| 506 | - * Gets the query params used to retrieve a specific line item for the given registration |
|
| 507 | - * |
|
| 508 | - * @param EE_Registration $registration |
|
| 509 | - * @param array $original_query_params any extra query params you'd like to be merged with |
|
| 510 | - * @return array @see |
|
| 511 | - * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 512 | - * @throws EE_Error |
|
| 513 | - */ |
|
| 514 | - public function line_item_for_registration_query_params( |
|
| 515 | - EE_Registration $registration, |
|
| 516 | - $original_query_params = array() |
|
| 517 | - ) { |
|
| 518 | - return array_replace_recursive($original_query_params, array( |
|
| 519 | - array( |
|
| 520 | - 'OBJ_ID' => $registration->ticket_ID(), |
|
| 521 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 522 | - 'TXN_ID' => $registration->transaction_ID(), |
|
| 523 | - ), |
|
| 524 | - )); |
|
| 525 | - } |
|
| 526 | - |
|
| 527 | - |
|
| 528 | - /** |
|
| 529 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 530 | - * @throws InvalidInterfaceException |
|
| 531 | - * @throws InvalidDataTypeException |
|
| 532 | - * @throws EE_Error |
|
| 533 | - * @throws InvalidArgumentException |
|
| 534 | - */ |
|
| 535 | - public function get_total_line_items_with_no_transaction() |
|
| 536 | - { |
|
| 537 | - return $this->get_total_line_items_for_carts(); |
|
| 538 | - } |
|
| 539 | - |
|
| 540 | - |
|
| 541 | - /** |
|
| 542 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 543 | - * @throws InvalidInterfaceException |
|
| 544 | - * @throws InvalidDataTypeException |
|
| 545 | - * @throws EE_Error |
|
| 546 | - * @throws InvalidArgumentException |
|
| 547 | - */ |
|
| 548 | - public function get_total_line_items_for_active_carts() |
|
| 549 | - { |
|
| 550 | - return $this->get_total_line_items_for_carts(false); |
|
| 551 | - } |
|
| 552 | - |
|
| 553 | - |
|
| 554 | - /** |
|
| 555 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 556 | - * @throws InvalidInterfaceException |
|
| 557 | - * @throws InvalidDataTypeException |
|
| 558 | - * @throws EE_Error |
|
| 559 | - * @throws InvalidArgumentException |
|
| 560 | - */ |
|
| 561 | - public function get_total_line_items_for_expired_carts() |
|
| 562 | - { |
|
| 563 | - return $this->get_total_line_items_for_carts(true); |
|
| 564 | - } |
|
| 565 | - |
|
| 566 | - |
|
| 567 | - /** |
|
| 568 | - * Returns an array of grand total line items where the TXN_ID is 0. |
|
| 569 | - * If $expired is set to true, then only line items for expired sessions will be returned. |
|
| 570 | - * If $expired is set to false, then only line items for active sessions will be returned. |
|
| 571 | - * |
|
| 572 | - * @param null $expired |
|
| 573 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 574 | - * @throws EE_Error |
|
| 575 | - * @throws InvalidArgumentException |
|
| 576 | - * @throws InvalidDataTypeException |
|
| 577 | - * @throws InvalidInterfaceException |
|
| 578 | - */ |
|
| 579 | - private function get_total_line_items_for_carts($expired = null) |
|
| 580 | - { |
|
| 581 | - $where_params = array( |
|
| 582 | - 'TXN_ID' => 0, |
|
| 583 | - 'LIN_type' => 'total', |
|
| 584 | - ); |
|
| 585 | - if ($expired !== null) { |
|
| 586 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
| 587 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
| 588 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
| 589 | - ); |
|
| 590 | - $where_params['LIN_timestamp'] = array( |
|
| 591 | - $expired ? '<=' : '>', |
|
| 592 | - $session_lifespan->expiration(), |
|
| 593 | - ); |
|
| 594 | - } |
|
| 595 | - return $this->get_all(array($where_params)); |
|
| 596 | - } |
|
| 597 | - |
|
| 598 | - |
|
| 599 | - /** |
|
| 600 | - * Returns an array of ticket total line items where the TXN_ID is 0 |
|
| 601 | - * AND the timestamp is older than the session lifespan. |
|
| 602 | - * |
|
| 603 | - * @param int $timestamp |
|
| 604 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 605 | - * @throws EE_Error |
|
| 606 | - * @throws InvalidArgumentException |
|
| 607 | - * @throws InvalidDataTypeException |
|
| 608 | - * @throws InvalidInterfaceException |
|
| 609 | - */ |
|
| 610 | - public function getTicketLineItemsForExpiredCarts($timestamp = 0) |
|
| 611 | - { |
|
| 612 | - if (! absint($timestamp)) { |
|
| 613 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
| 614 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
| 615 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
| 616 | - ); |
|
| 617 | - $timestamp = $session_lifespan->expiration(); |
|
| 618 | - } |
|
| 619 | - return $this->get_all( |
|
| 620 | - array( |
|
| 621 | - array( |
|
| 622 | - 'TXN_ID' => 0, |
|
| 623 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 624 | - 'LIN_timestamp' => array('<=', $timestamp), |
|
| 625 | - ), |
|
| 626 | - ) |
|
| 627 | - ); |
|
| 628 | - } |
|
| 333 | + // use GMT time because that's what TXN_timestamps are in |
|
| 334 | + date('Y-m-d H:i:s', time() - $time_to_leave_alone) |
|
| 335 | + ); |
|
| 336 | + return $wpdb->query($query); |
|
| 337 | + } |
|
| 338 | + |
|
| 339 | + |
|
| 340 | + /** |
|
| 341 | + * get_line_item_for_transaction_object |
|
| 342 | + * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket |
|
| 343 | + * |
|
| 344 | + * @param int $TXN_ID |
|
| 345 | + * @param EE_Base_Class $object |
|
| 346 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 347 | + * @throws EE_Error |
|
| 348 | + * @throws InvalidArgumentException |
|
| 349 | + * @throws InvalidDataTypeException |
|
| 350 | + * @throws InvalidInterfaceException |
|
| 351 | + * @throws ReflectionException |
|
| 352 | + */ |
|
| 353 | + public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object) |
|
| 354 | + { |
|
| 355 | + return $this->get_all(array( |
|
| 356 | + array( |
|
| 357 | + 'TXN_ID' => $TXN_ID, |
|
| 358 | + 'OBJ_type' => str_replace('EE_', '', get_class($object)), |
|
| 359 | + 'OBJ_ID' => $object->ID(), |
|
| 360 | + ), |
|
| 361 | + )); |
|
| 362 | + } |
|
| 363 | + |
|
| 364 | + |
|
| 365 | + /** |
|
| 366 | + * get_object_line_items_for_transaction |
|
| 367 | + * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs |
|
| 368 | + * |
|
| 369 | + * @param int $TXN_ID |
|
| 370 | + * @param string $OBJ_type |
|
| 371 | + * @param array $OBJ_IDs |
|
| 372 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 373 | + * @throws EE_Error |
|
| 374 | + */ |
|
| 375 | + public function get_object_line_items_for_transaction( |
|
| 376 | + $TXN_ID, |
|
| 377 | + $OBJ_type = EEM_Line_Item::OBJ_TYPE_EVENT, |
|
| 378 | + $OBJ_IDs = array() |
|
| 379 | + ) { |
|
| 380 | + $query_params = array( |
|
| 381 | + 'OBJ_type' => $OBJ_type, |
|
| 382 | + // if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query |
|
| 383 | + 'OBJ_ID' => is_array($OBJ_IDs) && ! isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs, |
|
| 384 | + ); |
|
| 385 | + if ($TXN_ID) { |
|
| 386 | + $query_params['TXN_ID'] = $TXN_ID; |
|
| 387 | + } |
|
| 388 | + return $this->get_all(array($query_params)); |
|
| 389 | + } |
|
| 390 | + |
|
| 391 | + |
|
| 392 | + /** |
|
| 393 | + * get_all_ticket_line_items_for_transaction |
|
| 394 | + * |
|
| 395 | + * @param EE_Transaction $transaction |
|
| 396 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 397 | + * @throws EE_Error |
|
| 398 | + * @throws InvalidArgumentException |
|
| 399 | + * @throws InvalidDataTypeException |
|
| 400 | + * @throws InvalidInterfaceException |
|
| 401 | + * @throws ReflectionException |
|
| 402 | + */ |
|
| 403 | + public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction) |
|
| 404 | + { |
|
| 405 | + return $this->get_all(array( |
|
| 406 | + array( |
|
| 407 | + 'TXN_ID' => $transaction->ID(), |
|
| 408 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 409 | + ), |
|
| 410 | + )); |
|
| 411 | + } |
|
| 412 | + |
|
| 413 | + |
|
| 414 | + /** |
|
| 415 | + * get_ticket_line_item_for_transaction |
|
| 416 | + * |
|
| 417 | + * @param int $TXN_ID |
|
| 418 | + * @param int $TKT_ID |
|
| 419 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 420 | + * @throws EE_Error |
|
| 421 | + * @throws InvalidArgumentException |
|
| 422 | + * @throws InvalidDataTypeException |
|
| 423 | + * @throws InvalidInterfaceException |
|
| 424 | + */ |
|
| 425 | + public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID) |
|
| 426 | + { |
|
| 427 | + return $this->get_one(array( |
|
| 428 | + array( |
|
| 429 | + 'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID), |
|
| 430 | + 'OBJ_ID' => $TKT_ID, |
|
| 431 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 432 | + ), |
|
| 433 | + )); |
|
| 434 | + } |
|
| 435 | + |
|
| 436 | + |
|
| 437 | + /** |
|
| 438 | + * get_existing_promotion_line_item |
|
| 439 | + * searches the cart for existing line items for the specified promotion |
|
| 440 | + * |
|
| 441 | + * @since 1.0.0 |
|
| 442 | + * @param EE_Line_Item $parent_line_item |
|
| 443 | + * @param EE_Promotion $promotion |
|
| 444 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 445 | + * @throws EE_Error |
|
| 446 | + * @throws InvalidArgumentException |
|
| 447 | + * @throws InvalidDataTypeException |
|
| 448 | + * @throws InvalidInterfaceException |
|
| 449 | + * @throws ReflectionException |
|
| 450 | + */ |
|
| 451 | + public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion) |
|
| 452 | + { |
|
| 453 | + return $this->get_one(array( |
|
| 454 | + array( |
|
| 455 | + 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
| 456 | + 'LIN_parent' => $parent_line_item->ID(), |
|
| 457 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
| 458 | + 'OBJ_ID' => $promotion->ID(), |
|
| 459 | + ), |
|
| 460 | + )); |
|
| 461 | + } |
|
| 462 | + |
|
| 463 | + |
|
| 464 | + /** |
|
| 465 | + * get_all_promotion_line_items |
|
| 466 | + * searches the cart for any and all existing promotion line items |
|
| 467 | + * |
|
| 468 | + * @since 1.0.0 |
|
| 469 | + * @param EE_Line_Item $parent_line_item |
|
| 470 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 471 | + * @throws EE_Error |
|
| 472 | + * @throws InvalidArgumentException |
|
| 473 | + * @throws InvalidDataTypeException |
|
| 474 | + * @throws InvalidInterfaceException |
|
| 475 | + * @throws ReflectionException |
|
| 476 | + */ |
|
| 477 | + public function get_all_promotion_line_items(EE_Line_Item $parent_line_item) |
|
| 478 | + { |
|
| 479 | + return $this->get_all(array( |
|
| 480 | + array( |
|
| 481 | + 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
| 482 | + 'LIN_parent' => $parent_line_item->ID(), |
|
| 483 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
| 484 | + ), |
|
| 485 | + )); |
|
| 486 | + } |
|
| 487 | + |
|
| 488 | + |
|
| 489 | + /** |
|
| 490 | + * Gets the registration's corresponding line item. |
|
| 491 | + * Note: basically does NOT support having multiple line items for a single ticket, |
|
| 492 | + * which would happen if some of the registrations had a price modifier while others didn't. |
|
| 493 | + * In order to support that, we'd probably need a LIN_ID on registrations or something. |
|
| 494 | + * |
|
| 495 | + * @param EE_Registration $registration |
|
| 496 | + * @return EE_Base_Class|EE_Line_ITem|EE_Soft_Delete_Base_Class|NULL |
|
| 497 | + * @throws EE_Error |
|
| 498 | + */ |
|
| 499 | + public function get_line_item_for_registration(EE_Registration $registration) |
|
| 500 | + { |
|
| 501 | + return $this->get_one($this->line_item_for_registration_query_params($registration)); |
|
| 502 | + } |
|
| 503 | + |
|
| 504 | + |
|
| 505 | + /** |
|
| 506 | + * Gets the query params used to retrieve a specific line item for the given registration |
|
| 507 | + * |
|
| 508 | + * @param EE_Registration $registration |
|
| 509 | + * @param array $original_query_params any extra query params you'd like to be merged with |
|
| 510 | + * @return array @see |
|
| 511 | + * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 512 | + * @throws EE_Error |
|
| 513 | + */ |
|
| 514 | + public function line_item_for_registration_query_params( |
|
| 515 | + EE_Registration $registration, |
|
| 516 | + $original_query_params = array() |
|
| 517 | + ) { |
|
| 518 | + return array_replace_recursive($original_query_params, array( |
|
| 519 | + array( |
|
| 520 | + 'OBJ_ID' => $registration->ticket_ID(), |
|
| 521 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 522 | + 'TXN_ID' => $registration->transaction_ID(), |
|
| 523 | + ), |
|
| 524 | + )); |
|
| 525 | + } |
|
| 526 | + |
|
| 527 | + |
|
| 528 | + /** |
|
| 529 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 530 | + * @throws InvalidInterfaceException |
|
| 531 | + * @throws InvalidDataTypeException |
|
| 532 | + * @throws EE_Error |
|
| 533 | + * @throws InvalidArgumentException |
|
| 534 | + */ |
|
| 535 | + public function get_total_line_items_with_no_transaction() |
|
| 536 | + { |
|
| 537 | + return $this->get_total_line_items_for_carts(); |
|
| 538 | + } |
|
| 539 | + |
|
| 540 | + |
|
| 541 | + /** |
|
| 542 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 543 | + * @throws InvalidInterfaceException |
|
| 544 | + * @throws InvalidDataTypeException |
|
| 545 | + * @throws EE_Error |
|
| 546 | + * @throws InvalidArgumentException |
|
| 547 | + */ |
|
| 548 | + public function get_total_line_items_for_active_carts() |
|
| 549 | + { |
|
| 550 | + return $this->get_total_line_items_for_carts(false); |
|
| 551 | + } |
|
| 552 | + |
|
| 553 | + |
|
| 554 | + /** |
|
| 555 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 556 | + * @throws InvalidInterfaceException |
|
| 557 | + * @throws InvalidDataTypeException |
|
| 558 | + * @throws EE_Error |
|
| 559 | + * @throws InvalidArgumentException |
|
| 560 | + */ |
|
| 561 | + public function get_total_line_items_for_expired_carts() |
|
| 562 | + { |
|
| 563 | + return $this->get_total_line_items_for_carts(true); |
|
| 564 | + } |
|
| 565 | + |
|
| 566 | + |
|
| 567 | + /** |
|
| 568 | + * Returns an array of grand total line items where the TXN_ID is 0. |
|
| 569 | + * If $expired is set to true, then only line items for expired sessions will be returned. |
|
| 570 | + * If $expired is set to false, then only line items for active sessions will be returned. |
|
| 571 | + * |
|
| 572 | + * @param null $expired |
|
| 573 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 574 | + * @throws EE_Error |
|
| 575 | + * @throws InvalidArgumentException |
|
| 576 | + * @throws InvalidDataTypeException |
|
| 577 | + * @throws InvalidInterfaceException |
|
| 578 | + */ |
|
| 579 | + private function get_total_line_items_for_carts($expired = null) |
|
| 580 | + { |
|
| 581 | + $where_params = array( |
|
| 582 | + 'TXN_ID' => 0, |
|
| 583 | + 'LIN_type' => 'total', |
|
| 584 | + ); |
|
| 585 | + if ($expired !== null) { |
|
| 586 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
| 587 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
| 588 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
| 589 | + ); |
|
| 590 | + $where_params['LIN_timestamp'] = array( |
|
| 591 | + $expired ? '<=' : '>', |
|
| 592 | + $session_lifespan->expiration(), |
|
| 593 | + ); |
|
| 594 | + } |
|
| 595 | + return $this->get_all(array($where_params)); |
|
| 596 | + } |
|
| 597 | + |
|
| 598 | + |
|
| 599 | + /** |
|
| 600 | + * Returns an array of ticket total line items where the TXN_ID is 0 |
|
| 601 | + * AND the timestamp is older than the session lifespan. |
|
| 602 | + * |
|
| 603 | + * @param int $timestamp |
|
| 604 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 605 | + * @throws EE_Error |
|
| 606 | + * @throws InvalidArgumentException |
|
| 607 | + * @throws InvalidDataTypeException |
|
| 608 | + * @throws InvalidInterfaceException |
|
| 609 | + */ |
|
| 610 | + public function getTicketLineItemsForExpiredCarts($timestamp = 0) |
|
| 611 | + { |
|
| 612 | + if (! absint($timestamp)) { |
|
| 613 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
| 614 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
| 615 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
| 616 | + ); |
|
| 617 | + $timestamp = $session_lifespan->expiration(); |
|
| 618 | + } |
|
| 619 | + return $this->get_all( |
|
| 620 | + array( |
|
| 621 | + array( |
|
| 622 | + 'TXN_ID' => 0, |
|
| 623 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
| 624 | + 'LIN_timestamp' => array('<=', $timestamp), |
|
| 625 | + ), |
|
| 626 | + ) |
|
| 627 | + ); |
|
| 628 | + } |
|
| 629 | 629 | } |
@@ -13,816 +13,816 @@ discard block |
||
| 13 | 13 | class EEM_Registration extends EEM_Soft_Delete_Base |
| 14 | 14 | { |
| 15 | 15 | |
| 16 | - /** |
|
| 17 | - * @var EEM_Registration $_instance |
|
| 18 | - */ |
|
| 19 | - protected static $_instance; |
|
| 20 | - |
|
| 21 | - /** |
|
| 22 | - * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values |
|
| 23 | - * are status codes (eg, approved, cancelled, etc) |
|
| 24 | - * |
|
| 25 | - * @var array |
|
| 26 | - */ |
|
| 27 | - private static $_reg_status; |
|
| 28 | - |
|
| 29 | - /** |
|
| 30 | - * The value of REG_count for a primary registrant |
|
| 31 | - */ |
|
| 32 | - const PRIMARY_REGISTRANT_COUNT = 1; |
|
| 33 | - |
|
| 34 | - /** |
|
| 35 | - * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration. |
|
| 36 | - * Initial status for registrations when they are first created |
|
| 37 | - * Payments are NOT allowed. |
|
| 38 | - * Automatically toggled to whatever the default Event registration status is upon completion of the attendee |
|
| 39 | - * information reg step NO space reserved. Registration is NOT active |
|
| 40 | - */ |
|
| 41 | - const status_id_incomplete = 'RIC'; |
|
| 42 | - |
|
| 43 | - /** |
|
| 44 | - * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration. |
|
| 45 | - * Payments are NOT allowed. |
|
| 46 | - * Event Admin must manually toggle STS_ID for it to change |
|
| 47 | - * No space reserved. |
|
| 48 | - * Registration is active |
|
| 49 | - */ |
|
| 50 | - const status_id_not_approved = 'RNA'; |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT . |
|
| 54 | - * Payments are allowed. |
|
| 55 | - * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
| 56 | - * No space reserved. |
|
| 57 | - * Registration is active |
|
| 58 | - */ |
|
| 59 | - const status_id_pending_payment = 'RPP'; |
|
| 60 | - |
|
| 61 | - /** |
|
| 62 | - * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST . |
|
| 63 | - * Payments are allowed. |
|
| 64 | - * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
| 65 | - * No space reserved. |
|
| 66 | - * Registration is active |
|
| 67 | - */ |
|
| 68 | - const status_id_wait_list = 'RWL'; |
|
| 69 | - |
|
| 70 | - /** |
|
| 71 | - * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration. |
|
| 72 | - * the TXN may or may not be completed ( paid in full ) |
|
| 73 | - * Payments are allowed. |
|
| 74 | - * A space IS reserved. |
|
| 75 | - * Registration is active |
|
| 76 | - */ |
|
| 77 | - const status_id_approved = 'RAP'; |
|
| 78 | - |
|
| 79 | - /** |
|
| 80 | - * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee. |
|
| 81 | - * Payments are NOT allowed. |
|
| 82 | - * NO space reserved. |
|
| 83 | - * Registration is NOT active |
|
| 84 | - */ |
|
| 85 | - const status_id_cancelled = 'RCN'; |
|
| 86 | - |
|
| 87 | - /** |
|
| 88 | - * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin |
|
| 89 | - * Payments are NOT allowed. |
|
| 90 | - * No space reserved. |
|
| 91 | - * Registration is NOT active |
|
| 92 | - */ |
|
| 93 | - const status_id_declined = 'RDC'; |
|
| 94 | - |
|
| 95 | - /** |
|
| 96 | - * @var TableAnalysis $table_analysis |
|
| 97 | - */ |
|
| 98 | - protected $_table_analysis; |
|
| 99 | - |
|
| 100 | - |
|
| 101 | - /** |
|
| 102 | - * private constructor to prevent direct creation |
|
| 103 | - * |
|
| 104 | - * @Constructor |
|
| 105 | - * @access protected |
|
| 106 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
| 107 | - * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
| 108 | - * date time model field objects. Default is NULL (and will be assumed using the set |
|
| 109 | - * timezone in the 'timezone_string' wp option) |
|
| 110 | - * @throws EE_Error |
|
| 111 | - */ |
|
| 112 | - protected function __construct($timezone = null) |
|
| 113 | - { |
|
| 114 | - $this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true); |
|
| 115 | - $this->singular_item = esc_html__('Registration', 'event_espresso'); |
|
| 116 | - $this->plural_item = esc_html__('Registrations', 'event_espresso'); |
|
| 117 | - $this->_tables = array( |
|
| 118 | - 'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'), |
|
| 119 | - ); |
|
| 120 | - $this->_fields = array( |
|
| 121 | - 'Registration' => array( |
|
| 122 | - 'REG_ID' => new EE_Primary_Key_Int_Field( |
|
| 123 | - 'REG_ID', |
|
| 124 | - esc_html__('Registration ID', 'event_espresso') |
|
| 125 | - ), |
|
| 126 | - 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
| 127 | - 'EVT_ID', |
|
| 128 | - esc_html__('Event ID', 'event_espresso'), |
|
| 129 | - false, |
|
| 130 | - 0, |
|
| 131 | - 'Event' |
|
| 132 | - ), |
|
| 133 | - 'ATT_ID' => new EE_Foreign_Key_Int_Field( |
|
| 134 | - 'ATT_ID', |
|
| 135 | - esc_html__('Attendee ID', 'event_espresso'), |
|
| 136 | - false, |
|
| 137 | - 0, |
|
| 138 | - 'Attendee' |
|
| 139 | - ), |
|
| 140 | - 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
| 141 | - 'TXN_ID', |
|
| 142 | - esc_html__('Transaction ID', 'event_espresso'), |
|
| 143 | - false, |
|
| 144 | - 0, |
|
| 145 | - 'Transaction' |
|
| 146 | - ), |
|
| 147 | - 'TKT_ID' => new EE_Foreign_Key_Int_Field( |
|
| 148 | - 'TKT_ID', |
|
| 149 | - esc_html__('Ticket ID', 'event_espresso'), |
|
| 150 | - false, |
|
| 151 | - 0, |
|
| 152 | - 'Ticket' |
|
| 153 | - ), |
|
| 154 | - 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
| 155 | - 'STS_ID', |
|
| 156 | - esc_html__('Status ID', 'event_espresso'), |
|
| 157 | - false, |
|
| 158 | - EEM_Registration::status_id_incomplete, |
|
| 159 | - 'Status' |
|
| 160 | - ), |
|
| 161 | - 'REG_date' => new EE_Datetime_Field( |
|
| 162 | - 'REG_date', |
|
| 163 | - esc_html__('Time registration occurred', 'event_espresso'), |
|
| 164 | - false, |
|
| 165 | - EE_Datetime_Field::now, |
|
| 166 | - $timezone |
|
| 167 | - ), |
|
| 168 | - 'REG_final_price' => new EE_Money_Field( |
|
| 169 | - 'REG_final_price', |
|
| 170 | - esc_html__('Registration\'s share of the transaction total', 'event_espresso'), |
|
| 171 | - false, |
|
| 172 | - 0 |
|
| 173 | - ), |
|
| 174 | - 'REG_paid' => new EE_Money_Field( |
|
| 175 | - 'REG_paid', |
|
| 176 | - esc_html__('Amount paid to date towards registration', 'event_espresso'), |
|
| 177 | - false, |
|
| 178 | - 0 |
|
| 179 | - ), |
|
| 180 | - 'REG_session' => new EE_Plain_Text_Field( |
|
| 181 | - 'REG_session', |
|
| 182 | - esc_html__('Session ID of registration', 'event_espresso'), |
|
| 183 | - false, |
|
| 184 | - '' |
|
| 185 | - ), |
|
| 186 | - 'REG_code' => new EE_Plain_Text_Field( |
|
| 187 | - 'REG_code', |
|
| 188 | - esc_html__('Unique Code for this registration', 'event_espresso'), |
|
| 189 | - false, |
|
| 190 | - '' |
|
| 191 | - ), |
|
| 192 | - 'REG_url_link' => new EE_Plain_Text_Field( |
|
| 193 | - 'REG_url_link', |
|
| 194 | - esc_html__('String to be used in URL for identifying registration', 'event_espresso'), |
|
| 195 | - false, |
|
| 196 | - '' |
|
| 197 | - ), |
|
| 198 | - 'REG_count' => new EE_Integer_Field( |
|
| 199 | - 'REG_count', |
|
| 200 | - esc_html__('Count of this registration in the group registration ', 'event_espresso'), |
|
| 201 | - true, |
|
| 202 | - 1 |
|
| 203 | - ), |
|
| 204 | - 'REG_group_size' => new EE_Integer_Field( |
|
| 205 | - 'REG_group_size', |
|
| 206 | - esc_html__('Number of registrations on this group', 'event_espresso'), |
|
| 207 | - false, |
|
| 208 | - 1 |
|
| 209 | - ), |
|
| 210 | - 'REG_att_is_going' => new EE_Boolean_Field( |
|
| 211 | - 'REG_att_is_going', |
|
| 212 | - esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'), |
|
| 213 | - false, |
|
| 214 | - false |
|
| 215 | - ), |
|
| 216 | - 'REG_deleted' => new EE_Trashed_Flag_Field( |
|
| 217 | - 'REG_deleted', |
|
| 218 | - esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'), |
|
| 219 | - false, |
|
| 220 | - false |
|
| 221 | - ), |
|
| 222 | - ), |
|
| 223 | - ); |
|
| 224 | - $this->_model_relations = array( |
|
| 225 | - 'Event' => new EE_Belongs_To_Relation(), |
|
| 226 | - 'Attendee' => new EE_Belongs_To_Relation(), |
|
| 227 | - 'Transaction' => new EE_Belongs_To_Relation(), |
|
| 228 | - 'Ticket' => new EE_Belongs_To_Relation(), |
|
| 229 | - 'Status' => new EE_Belongs_To_Relation(), |
|
| 230 | - 'Answer' => new EE_Has_Many_Relation(), |
|
| 231 | - 'Checkin' => new EE_Has_Many_Relation(), |
|
| 232 | - 'Registration_Payment' => new EE_Has_Many_Relation(), |
|
| 233 | - 'Payment' => new EE_HABTM_Relation('Registration_Payment'), |
|
| 234 | - 'Message' => new EE_Has_Many_Any_Relation(false) |
|
| 235 | - // allow deletes even if there are messages in the queue related |
|
| 236 | - ); |
|
| 237 | - $this->_model_chain_to_wp_user = 'Event'; |
|
| 238 | - parent::__construct($timezone); |
|
| 239 | - } |
|
| 240 | - |
|
| 241 | - |
|
| 242 | - /** |
|
| 243 | - * a list of ALL valid registration statuses currently in use within the system |
|
| 244 | - * generated by combining the filterable active and inactive reg status arrays |
|
| 245 | - * |
|
| 246 | - * @return array |
|
| 247 | - */ |
|
| 248 | - public static function reg_statuses() |
|
| 249 | - { |
|
| 250 | - return array_unique( |
|
| 251 | - array_merge( |
|
| 252 | - EEM_Registration::active_reg_statuses(), |
|
| 253 | - EEM_Registration::inactive_reg_statuses() |
|
| 254 | - ) |
|
| 255 | - ); |
|
| 256 | - } |
|
| 257 | - |
|
| 258 | - |
|
| 259 | - /** |
|
| 260 | - * reg_statuses_that_allow_payment |
|
| 261 | - * a filterable list of registration statuses that allow a registrant to make a payment |
|
| 262 | - * |
|
| 263 | - * @access public |
|
| 264 | - * @return array |
|
| 265 | - */ |
|
| 266 | - public static function reg_statuses_that_allow_payment() |
|
| 267 | - { |
|
| 268 | - return apply_filters( |
|
| 269 | - 'FHEE__EEM_Registration__reg_statuses_that_allow_payment', |
|
| 270 | - array( |
|
| 271 | - EEM_Registration::status_id_approved, |
|
| 272 | - EEM_Registration::status_id_pending_payment, |
|
| 273 | - ) |
|
| 274 | - ); |
|
| 275 | - } |
|
| 276 | - |
|
| 277 | - |
|
| 278 | - /** |
|
| 279 | - * active_reg_statuses |
|
| 280 | - * a filterable list of registration statuses that are considered active |
|
| 281 | - * |
|
| 282 | - * @access public |
|
| 283 | - * @return array |
|
| 284 | - */ |
|
| 285 | - public static function active_reg_statuses() |
|
| 286 | - { |
|
| 287 | - return apply_filters( |
|
| 288 | - 'FHEE__EEM_Registration__active_reg_statuses', |
|
| 289 | - array( |
|
| 290 | - EEM_Registration::status_id_approved, |
|
| 291 | - EEM_Registration::status_id_pending_payment, |
|
| 292 | - EEM_Registration::status_id_wait_list, |
|
| 293 | - EEM_Registration::status_id_not_approved, |
|
| 294 | - ) |
|
| 295 | - ); |
|
| 296 | - } |
|
| 297 | - |
|
| 298 | - |
|
| 299 | - /** |
|
| 300 | - * inactive_reg_statuses |
|
| 301 | - * a filterable list of registration statuses that are not considered active |
|
| 302 | - * |
|
| 303 | - * @access public |
|
| 304 | - * @return array |
|
| 305 | - */ |
|
| 306 | - public static function inactive_reg_statuses() |
|
| 307 | - { |
|
| 308 | - return apply_filters( |
|
| 309 | - 'FHEE__EEM_Registration__inactive_reg_statuses', |
|
| 310 | - array( |
|
| 311 | - EEM_Registration::status_id_incomplete, |
|
| 312 | - EEM_Registration::status_id_cancelled, |
|
| 313 | - EEM_Registration::status_id_declined, |
|
| 314 | - ) |
|
| 315 | - ); |
|
| 316 | - } |
|
| 317 | - |
|
| 318 | - |
|
| 319 | - /** |
|
| 320 | - * closed_reg_statuses |
|
| 321 | - * a filterable list of registration statuses that are considered "closed" |
|
| 322 | - * meaning they should not be considered in any calculations involving monies owing |
|
| 323 | - * |
|
| 324 | - * @access public |
|
| 325 | - * @return array |
|
| 326 | - */ |
|
| 327 | - public static function closed_reg_statuses() |
|
| 328 | - { |
|
| 329 | - return apply_filters( |
|
| 330 | - 'FHEE__EEM_Registration__closed_reg_statuses', |
|
| 331 | - array( |
|
| 332 | - EEM_Registration::status_id_cancelled, |
|
| 333 | - EEM_Registration::status_id_declined, |
|
| 334 | - EEM_Registration::status_id_wait_list, |
|
| 335 | - ) |
|
| 336 | - ); |
|
| 337 | - } |
|
| 338 | - |
|
| 339 | - |
|
| 340 | - /** |
|
| 341 | - * get list of registration statuses |
|
| 342 | - * |
|
| 343 | - * @access public |
|
| 344 | - * @param array $exclude The status ids to exclude from the returned results |
|
| 345 | - * @param bool $translated If true will return the values as singular localized strings |
|
| 346 | - * @return array |
|
| 347 | - * @throws EE_Error |
|
| 348 | - */ |
|
| 349 | - public static function reg_status_array($exclude = array(), $translated = false) |
|
| 350 | - { |
|
| 351 | - EEM_Registration::instance()->_get_registration_status_array($exclude); |
|
| 352 | - return $translated |
|
| 353 | - ? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence') |
|
| 354 | - : self::$_reg_status; |
|
| 355 | - } |
|
| 356 | - |
|
| 357 | - |
|
| 358 | - /** |
|
| 359 | - * get list of registration statuses |
|
| 360 | - * |
|
| 361 | - * @access private |
|
| 362 | - * @param array $exclude |
|
| 363 | - * @return void |
|
| 364 | - * @throws EE_Error |
|
| 365 | - */ |
|
| 366 | - private function _get_registration_status_array($exclude = array()) |
|
| 367 | - { |
|
| 368 | - // in the very rare circumstance that we are deleting a model's table's data |
|
| 369 | - // and the table hasn't actually been created, this could have an error |
|
| 370 | - /** @type WPDB $wpdb */ |
|
| 371 | - global $wpdb; |
|
| 372 | - if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) { |
|
| 373 | - $results = $wpdb->get_results( |
|
| 374 | - "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'" |
|
| 375 | - ); |
|
| 376 | - self::$_reg_status = array(); |
|
| 377 | - foreach ($results as $status) { |
|
| 378 | - if (!in_array($status->STS_ID, $exclude, true)) { |
|
| 379 | - self::$_reg_status[ $status->STS_ID ] = $status->STS_code; |
|
| 380 | - } |
|
| 381 | - } |
|
| 382 | - } |
|
| 383 | - } |
|
| 384 | - |
|
| 385 | - |
|
| 386 | - /** |
|
| 387 | - * Gets the injected table analyzer, or throws an exception |
|
| 388 | - * |
|
| 389 | - * @return TableAnalysis |
|
| 390 | - * @throws EE_Error |
|
| 391 | - */ |
|
| 392 | - protected function _get_table_analysis() |
|
| 393 | - { |
|
| 394 | - if ($this->_table_analysis instanceof TableAnalysis) { |
|
| 395 | - return $this->_table_analysis; |
|
| 396 | - } |
|
| 397 | - throw new EE_Error( |
|
| 398 | - sprintf( |
|
| 399 | - esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'), |
|
| 400 | - get_class($this) |
|
| 401 | - ) |
|
| 402 | - ); |
|
| 403 | - } |
|
| 404 | - |
|
| 405 | - |
|
| 406 | - /** |
|
| 407 | - * This returns a wpdb->results array of all registration date month and years matching the incoming query params |
|
| 408 | - * and grouped by month and year. |
|
| 409 | - * |
|
| 410 | - * @param array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
| 411 | - * @return array |
|
| 412 | - * @throws EE_Error |
|
| 413 | - */ |
|
| 414 | - public function get_reg_months_and_years($where_params) |
|
| 415 | - { |
|
| 416 | - $query_params[0] = $where_params; |
|
| 417 | - $query_params['group_by'] = array('reg_year', 'reg_month'); |
|
| 418 | - $query_params['order_by'] = array('REG_date' => 'DESC'); |
|
| 419 | - $columns_to_select = array( |
|
| 420 | - 'reg_year' => array('YEAR(REG_date)', '%s'), |
|
| 421 | - 'reg_month' => array('MONTHNAME(REG_date)', '%s'), |
|
| 422 | - ); |
|
| 423 | - return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select); |
|
| 424 | - } |
|
| 425 | - |
|
| 426 | - |
|
| 427 | - /** |
|
| 428 | - * retrieve ALL registrations for a particular Attendee from db |
|
| 429 | - * |
|
| 430 | - * @param int $ATT_ID |
|
| 431 | - * @return EE_Base_Class[]|EE_Registration[]|null |
|
| 432 | - * @throws EE_Error |
|
| 433 | - */ |
|
| 434 | - public function get_all_registrations_for_attendee($ATT_ID = 0) |
|
| 435 | - { |
|
| 436 | - if (!$ATT_ID) { |
|
| 437 | - return null; |
|
| 438 | - } |
|
| 439 | - return $this->get_all(array(array('ATT_ID' => $ATT_ID))); |
|
| 440 | - } |
|
| 441 | - |
|
| 442 | - |
|
| 443 | - /** |
|
| 444 | - * Gets a registration given their REG_url_link. Yes, this should usually |
|
| 445 | - * be passed via a GET parameter. |
|
| 446 | - * |
|
| 447 | - * @param string $REG_url_link |
|
| 448 | - * @return EE_Base_Class|EE_Registration|null |
|
| 449 | - * @throws EE_Error |
|
| 450 | - */ |
|
| 451 | - public function get_registration_for_reg_url_link($REG_url_link) |
|
| 452 | - { |
|
| 453 | - if (!$REG_url_link) { |
|
| 454 | - return null; |
|
| 455 | - } |
|
| 456 | - return $this->get_one(array(array('REG_url_link' => $REG_url_link))); |
|
| 457 | - } |
|
| 458 | - |
|
| 459 | - |
|
| 460 | - /** |
|
| 461 | - * retrieve registration for a specific transaction attendee from db |
|
| 462 | - * |
|
| 463 | - * @access public |
|
| 464 | - * @param int $TXN_ID |
|
| 465 | - * @param int $ATT_ID |
|
| 466 | - * @param int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the |
|
| 467 | - * attendee number is required |
|
| 468 | - * @return mixed array on success, FALSE on fail |
|
| 469 | - * @throws EE_Error |
|
| 470 | - */ |
|
| 471 | - public function get_registration_for_transaction_attendee($TXN_ID = 0, $ATT_ID = 0, $att_nmbr = 0) |
|
| 472 | - { |
|
| 473 | - return $this->get_one(array( |
|
| 474 | - array( |
|
| 475 | - 'TXN_ID' => $TXN_ID, |
|
| 476 | - 'ATT_ID' => $ATT_ID, |
|
| 477 | - ), |
|
| 478 | - 'limit' => array(min($att_nmbr - 1, 0), 1), |
|
| 479 | - )); |
|
| 480 | - } |
|
| 481 | - |
|
| 482 | - |
|
| 483 | - /** |
|
| 484 | - * get the number of registrations per day for the Registration Admin page Reports Tab. |
|
| 485 | - * (doesn't utilize models because it's a fairly specialized query) |
|
| 486 | - * |
|
| 487 | - * @access public |
|
| 488 | - * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
| 489 | - * @return stdClass[] with properties regDate and total |
|
| 490 | - * @throws EE_Error |
|
| 491 | - */ |
|
| 492 | - public function get_registrations_per_day_report($period = '-1 month') |
|
| 493 | - { |
|
| 494 | - $sql_date = $this->convert_datetime_for_query( |
|
| 495 | - 'REG_date', |
|
| 496 | - date('Y-m-d H:i:s', strtotime($period)), |
|
| 497 | - 'Y-m-d H:i:s', |
|
| 498 | - 'UTC' |
|
| 499 | - ); |
|
| 500 | - $where = array( |
|
| 501 | - 'REG_date' => array('>=', $sql_date), |
|
| 502 | - 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
| 503 | - ); |
|
| 504 | - if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) { |
|
| 505 | - $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
| 506 | - } |
|
| 507 | - $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date'); |
|
| 508 | - $results = $this->_get_all_wpdb_results( |
|
| 509 | - array( |
|
| 510 | - $where, |
|
| 511 | - 'group_by' => 'regDate', |
|
| 512 | - 'order_by' => array('REG_date' => 'ASC'), |
|
| 513 | - ), |
|
| 514 | - OBJECT, |
|
| 515 | - array( |
|
| 516 | - 'regDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
| 517 | - 'total' => array('count(REG_ID)', '%d'), |
|
| 518 | - ) |
|
| 519 | - ); |
|
| 520 | - return $results; |
|
| 521 | - } |
|
| 522 | - |
|
| 523 | - |
|
| 524 | - /** |
|
| 525 | - * Get the number of registrations per day including the count of registrations for each Registration Status. |
|
| 526 | - * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
| 527 | - * |
|
| 528 | - * @param string $period |
|
| 529 | - * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID |
|
| 530 | - * @throws EE_Error |
|
| 531 | - * (i.e. RAP) |
|
| 532 | - */ |
|
| 533 | - public function get_registrations_per_day_and_per_status_report($period = '-1 month') |
|
| 534 | - { |
|
| 535 | - global $wpdb; |
|
| 536 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 537 | - $event_table = $wpdb->posts; |
|
| 538 | - $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
| 539 | - // prepare the query interval for displaying offset |
|
| 540 | - $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date'); |
|
| 541 | - // inner date query |
|
| 542 | - $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} "; |
|
| 543 | - $inner_where = ' WHERE'; |
|
| 544 | - // exclude events not authored by user if permissions in effect |
|
| 545 | - if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 546 | - $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
| 547 | - $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
| 548 | - } |
|
| 549 | - $inner_where .= " REG_date >= '{$sql_date}'"; |
|
| 550 | - $inner_date_query .= $inner_where; |
|
| 551 | - // start main query |
|
| 552 | - $select = "SELECT DATE({$query_interval}) as Registration_REG_date, "; |
|
| 553 | - $join = ''; |
|
| 554 | - $join_parts = array(); |
|
| 555 | - $select_parts = array(); |
|
| 556 | - // loop through registration stati to do parts for each status. |
|
| 557 | - foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
| 558 | - if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
| 559 | - continue; |
|
| 560 | - } |
|
| 561 | - $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
| 562 | - $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'"; |
|
| 563 | - } |
|
| 564 | - // setup the selects |
|
| 565 | - $select .= implode(', ', $select_parts); |
|
| 566 | - $select .= " FROM ($inner_date_query) AS dates LEFT JOIN "; |
|
| 567 | - // setup the joins |
|
| 568 | - $join .= implode(' LEFT JOIN ', $join_parts); |
|
| 569 | - // now let's put it all together |
|
| 570 | - $query = $select . $join . ' GROUP BY Registration_REG_date'; |
|
| 571 | - // and execute it |
|
| 572 | - return $wpdb->get_results($query, ARRAY_A); |
|
| 573 | - } |
|
| 574 | - |
|
| 575 | - |
|
| 576 | - /** |
|
| 577 | - * get the number of registrations per event for the Registration Admin page Reports Tab |
|
| 578 | - * |
|
| 579 | - * @access public |
|
| 580 | - * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
| 581 | - * @return stdClass[] each with properties event_name, reg_limit, and total |
|
| 582 | - * @throws EE_Error |
|
| 583 | - */ |
|
| 584 | - public function get_registrations_per_event_report($period = '-1 month') |
|
| 585 | - { |
|
| 586 | - $date_sql = $this->convert_datetime_for_query( |
|
| 587 | - 'REG_date', |
|
| 588 | - date('Y-m-d H:i:s', strtotime($period)), |
|
| 589 | - 'Y-m-d H:i:s', |
|
| 590 | - 'UTC' |
|
| 591 | - ); |
|
| 592 | - $where = array( |
|
| 593 | - 'REG_date' => array('>=', $date_sql), |
|
| 594 | - 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
| 595 | - ); |
|
| 596 | - if (!EE_Registry::instance()->CAP->current_user_can( |
|
| 597 | - 'ee_read_others_registrations', |
|
| 598 | - 'reg_per_event_report' |
|
| 599 | - ) |
|
| 600 | - ) { |
|
| 601 | - $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
| 602 | - } |
|
| 603 | - $results = $this->_get_all_wpdb_results( |
|
| 604 | - array( |
|
| 605 | - $where, |
|
| 606 | - 'group_by' => 'Event.EVT_name', |
|
| 607 | - 'order_by' => 'Event.EVT_name', |
|
| 608 | - 'limit' => array(0, 24), |
|
| 609 | - ), |
|
| 610 | - OBJECT, |
|
| 611 | - array( |
|
| 612 | - 'event_name' => array('Event_CPT.post_title', '%s'), |
|
| 613 | - 'total' => array('COUNT(REG_ID)', '%s'), |
|
| 614 | - ) |
|
| 615 | - ); |
|
| 616 | - return $results; |
|
| 617 | - } |
|
| 618 | - |
|
| 619 | - |
|
| 620 | - /** |
|
| 621 | - * Get the number of registrations per event grouped by registration status. |
|
| 622 | - * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
| 623 | - * |
|
| 624 | - * @param string $period |
|
| 625 | - * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID |
|
| 626 | - * @throws EE_Error |
|
| 627 | - * (i.e. RAP) |
|
| 628 | - */ |
|
| 629 | - public function get_registrations_per_event_and_per_status_report($period = '-1 month') |
|
| 630 | - { |
|
| 631 | - global $wpdb; |
|
| 632 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 633 | - $event_table = $wpdb->posts; |
|
| 634 | - $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
| 635 | - // inner date query |
|
| 636 | - $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table "; |
|
| 637 | - $inner_where = ' WHERE'; |
|
| 638 | - // exclude events not authored by user if permissions in effect |
|
| 639 | - if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 640 | - $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
| 641 | - $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
| 642 | - } |
|
| 643 | - $inner_where .= " REG_date >= '{$sql_date}'"; |
|
| 644 | - $inner_date_query .= $inner_where; |
|
| 645 | - // build main query |
|
| 646 | - $select = 'SELECT Event.post_title as Registration_Event, '; |
|
| 647 | - $join = ''; |
|
| 648 | - $join_parts = array(); |
|
| 649 | - $select_parts = array(); |
|
| 650 | - // loop through registration stati to do parts for each status. |
|
| 651 | - foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
| 652 | - if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
| 653 | - continue; |
|
| 654 | - } |
|
| 655 | - $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
| 656 | - $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date"; |
|
| 657 | - } |
|
| 658 | - // setup the selects |
|
| 659 | - $select .= implode(', ', $select_parts); |
|
| 660 | - $select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN "; |
|
| 661 | - // setup remaining joins |
|
| 662 | - $join .= implode(' LEFT JOIN ', $join_parts); |
|
| 663 | - // now put it all together |
|
| 664 | - $query = $select . $join . ' GROUP BY Registration_Event'; |
|
| 665 | - // and execute |
|
| 666 | - return $wpdb->get_results($query, ARRAY_A); |
|
| 667 | - } |
|
| 668 | - |
|
| 669 | - |
|
| 670 | - /** |
|
| 671 | - * Returns the EE_Registration of the primary attendee on the transaction id provided |
|
| 672 | - * |
|
| 673 | - * @param int $TXN_ID |
|
| 674 | - * @return EE_Base_Class|EE_Registration|null |
|
| 675 | - * @throws EE_Error |
|
| 676 | - */ |
|
| 677 | - public function get_primary_registration_for_transaction_ID($TXN_ID = 0) |
|
| 678 | - { |
|
| 679 | - if (!$TXN_ID) { |
|
| 680 | - return null; |
|
| 681 | - } |
|
| 682 | - return $this->get_one(array( |
|
| 683 | - array( |
|
| 684 | - 'TXN_ID' => $TXN_ID, |
|
| 685 | - 'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT, |
|
| 686 | - ), |
|
| 687 | - )); |
|
| 688 | - } |
|
| 689 | - |
|
| 690 | - |
|
| 691 | - /** |
|
| 692 | - * get_event_registration_count |
|
| 693 | - * |
|
| 694 | - * @access public |
|
| 695 | - * @param int $EVT_ID |
|
| 696 | - * @param boolean $for_incomplete_payments |
|
| 697 | - * @return int |
|
| 698 | - * @throws EE_Error |
|
| 699 | - */ |
|
| 700 | - public function get_event_registration_count($EVT_ID, $for_incomplete_payments = false) |
|
| 701 | - { |
|
| 702 | - // we only count approved registrations towards registration limits |
|
| 703 | - $query_params = array(array('EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved)); |
|
| 704 | - if ($for_incomplete_payments) { |
|
| 705 | - $query_params[0]['Transaction.STS_ID'] = array('!=', EEM_Transaction::complete_status_code); |
|
| 706 | - } |
|
| 707 | - return $this->count($query_params); |
|
| 708 | - } |
|
| 709 | - |
|
| 710 | - |
|
| 711 | - /** |
|
| 712 | - * Deletes all registrations with no transactions. Note that this needs to be very efficient |
|
| 713 | - * and so it uses wpdb directly. Also, we can't put a limit on this because MySQL doesn't allow a limit on a delete |
|
| 714 | - * when joining tables like this. |
|
| 715 | - * |
|
| 716 | - * @global WPDB $wpdb |
|
| 717 | - * @return int number deleted |
|
| 718 | - * @throws EE_Error |
|
| 719 | - */ |
|
| 720 | - public function delete_registrations_with_no_transaction() |
|
| 721 | - { |
|
| 722 | - /** @type WPDB $wpdb */ |
|
| 723 | - global $wpdb; |
|
| 724 | - return $wpdb->query( |
|
| 725 | - 'DELETE r FROM ' |
|
| 726 | - . $this->table() |
|
| 727 | - . ' r LEFT JOIN ' |
|
| 728 | - . EEM_Transaction::instance()->table() |
|
| 729 | - . ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL' |
|
| 730 | - ); |
|
| 731 | - } |
|
| 732 | - |
|
| 733 | - |
|
| 734 | - /** |
|
| 735 | - * Count registrations checked into (or out of) a datetime |
|
| 736 | - * |
|
| 737 | - * @param int $DTT_ID datetime ID |
|
| 738 | - * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
| 739 | - * @return int |
|
| 740 | - * @throws EE_Error |
|
| 741 | - */ |
|
| 742 | - public function count_registrations_checked_into_datetime($DTT_ID, $checked_in = true) |
|
| 743 | - { |
|
| 744 | - global $wpdb; |
|
| 745 | - // subquery to get latest checkin |
|
| 746 | - $query = $wpdb->prepare( |
|
| 747 | - 'SELECT ' |
|
| 748 | - . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
| 749 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
| 750 | - . '( SELECT ' |
|
| 751 | - . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
| 752 | - . 'REG_ID AS REG_ID ' |
|
| 753 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' ' |
|
| 754 | - . 'WHERE DTT_ID=%d ' |
|
| 755 | - . 'GROUP BY REG_ID' |
|
| 756 | - . ') AS most_recent_checkin_per_reg ' |
|
| 757 | - . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
| 758 | - . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
| 759 | - . 'WHERE ' |
|
| 760 | - . 'checkins.CHK_in=%d', |
|
| 761 | - $DTT_ID, |
|
| 762 | - $checked_in |
|
| 763 | - ); |
|
| 764 | - return (int) $wpdb->get_var($query); |
|
| 765 | - } |
|
| 766 | - |
|
| 767 | - |
|
| 768 | - /** |
|
| 769 | - * Count registrations checked into (or out of) an event. |
|
| 770 | - * |
|
| 771 | - * @param int $EVT_ID event ID |
|
| 772 | - * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
| 773 | - * @return int |
|
| 774 | - * @throws EE_Error |
|
| 775 | - */ |
|
| 776 | - public function count_registrations_checked_into_event($EVT_ID, $checked_in = true) |
|
| 777 | - { |
|
| 778 | - global $wpdb; |
|
| 779 | - // subquery to get latest checkin |
|
| 780 | - $query = $wpdb->prepare( |
|
| 781 | - 'SELECT ' |
|
| 782 | - . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
| 783 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
| 784 | - . '( SELECT ' |
|
| 785 | - . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
| 786 | - . 'REG_ID AS REG_ID ' |
|
| 787 | - . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c ' |
|
| 788 | - . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d ' |
|
| 789 | - . 'ON c.DTT_ID=d.DTT_ID ' |
|
| 790 | - . 'WHERE d.EVT_ID=%d ' |
|
| 791 | - . 'GROUP BY REG_ID' |
|
| 792 | - . ') AS most_recent_checkin_per_reg ' |
|
| 793 | - . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
| 794 | - . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
| 795 | - . 'WHERE ' |
|
| 796 | - . 'checkins.CHK_in=%d', |
|
| 797 | - $EVT_ID, |
|
| 798 | - $checked_in |
|
| 799 | - ); |
|
| 800 | - return (int) $wpdb->get_var($query); |
|
| 801 | - } |
|
| 802 | - |
|
| 803 | - |
|
| 804 | - /** |
|
| 805 | - * The purpose of this method is to retrieve an array of |
|
| 806 | - * EE_Registration objects that represent the latest registration |
|
| 807 | - * for each ATT_ID given in the function argument. |
|
| 808 | - * |
|
| 809 | - * @param array $attendee_ids |
|
| 810 | - * @return EE_Base_Class[]|EE_Registration[] |
|
| 811 | - * @throws EE_Error |
|
| 812 | - */ |
|
| 813 | - public function get_latest_registration_for_each_of_given_contacts($attendee_ids = array()) |
|
| 814 | - { |
|
| 815 | - // first do a native wp_query to get the latest REG_ID's matching these attendees. |
|
| 816 | - global $wpdb; |
|
| 817 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 818 | - $attendee_table = $wpdb->posts; |
|
| 819 | - $attendee_ids = is_array($attendee_ids) |
|
| 820 | - ? array_map('absint', $attendee_ids) |
|
| 821 | - : array((int) $attendee_ids); |
|
| 822 | - $ATT_IDs = implode(',', $attendee_ids); |
|
| 823 | - // first we do a query to get the registration ids |
|
| 824 | - // (because a group by before order by causes the order by to be ignored.) |
|
| 825 | - $registration_id_query = " |
|
| 16 | + /** |
|
| 17 | + * @var EEM_Registration $_instance |
|
| 18 | + */ |
|
| 19 | + protected static $_instance; |
|
| 20 | + |
|
| 21 | + /** |
|
| 22 | + * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values |
|
| 23 | + * are status codes (eg, approved, cancelled, etc) |
|
| 24 | + * |
|
| 25 | + * @var array |
|
| 26 | + */ |
|
| 27 | + private static $_reg_status; |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * The value of REG_count for a primary registrant |
|
| 31 | + */ |
|
| 32 | + const PRIMARY_REGISTRANT_COUNT = 1; |
|
| 33 | + |
|
| 34 | + /** |
|
| 35 | + * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration. |
|
| 36 | + * Initial status for registrations when they are first created |
|
| 37 | + * Payments are NOT allowed. |
|
| 38 | + * Automatically toggled to whatever the default Event registration status is upon completion of the attendee |
|
| 39 | + * information reg step NO space reserved. Registration is NOT active |
|
| 40 | + */ |
|
| 41 | + const status_id_incomplete = 'RIC'; |
|
| 42 | + |
|
| 43 | + /** |
|
| 44 | + * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration. |
|
| 45 | + * Payments are NOT allowed. |
|
| 46 | + * Event Admin must manually toggle STS_ID for it to change |
|
| 47 | + * No space reserved. |
|
| 48 | + * Registration is active |
|
| 49 | + */ |
|
| 50 | + const status_id_not_approved = 'RNA'; |
|
| 51 | + |
|
| 52 | + /** |
|
| 53 | + * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT . |
|
| 54 | + * Payments are allowed. |
|
| 55 | + * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
| 56 | + * No space reserved. |
|
| 57 | + * Registration is active |
|
| 58 | + */ |
|
| 59 | + const status_id_pending_payment = 'RPP'; |
|
| 60 | + |
|
| 61 | + /** |
|
| 62 | + * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST . |
|
| 63 | + * Payments are allowed. |
|
| 64 | + * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee |
|
| 65 | + * No space reserved. |
|
| 66 | + * Registration is active |
|
| 67 | + */ |
|
| 68 | + const status_id_wait_list = 'RWL'; |
|
| 69 | + |
|
| 70 | + /** |
|
| 71 | + * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration. |
|
| 72 | + * the TXN may or may not be completed ( paid in full ) |
|
| 73 | + * Payments are allowed. |
|
| 74 | + * A space IS reserved. |
|
| 75 | + * Registration is active |
|
| 76 | + */ |
|
| 77 | + const status_id_approved = 'RAP'; |
|
| 78 | + |
|
| 79 | + /** |
|
| 80 | + * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee. |
|
| 81 | + * Payments are NOT allowed. |
|
| 82 | + * NO space reserved. |
|
| 83 | + * Registration is NOT active |
|
| 84 | + */ |
|
| 85 | + const status_id_cancelled = 'RCN'; |
|
| 86 | + |
|
| 87 | + /** |
|
| 88 | + * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin |
|
| 89 | + * Payments are NOT allowed. |
|
| 90 | + * No space reserved. |
|
| 91 | + * Registration is NOT active |
|
| 92 | + */ |
|
| 93 | + const status_id_declined = 'RDC'; |
|
| 94 | + |
|
| 95 | + /** |
|
| 96 | + * @var TableAnalysis $table_analysis |
|
| 97 | + */ |
|
| 98 | + protected $_table_analysis; |
|
| 99 | + |
|
| 100 | + |
|
| 101 | + /** |
|
| 102 | + * private constructor to prevent direct creation |
|
| 103 | + * |
|
| 104 | + * @Constructor |
|
| 105 | + * @access protected |
|
| 106 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
| 107 | + * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
| 108 | + * date time model field objects. Default is NULL (and will be assumed using the set |
|
| 109 | + * timezone in the 'timezone_string' wp option) |
|
| 110 | + * @throws EE_Error |
|
| 111 | + */ |
|
| 112 | + protected function __construct($timezone = null) |
|
| 113 | + { |
|
| 114 | + $this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true); |
|
| 115 | + $this->singular_item = esc_html__('Registration', 'event_espresso'); |
|
| 116 | + $this->plural_item = esc_html__('Registrations', 'event_espresso'); |
|
| 117 | + $this->_tables = array( |
|
| 118 | + 'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'), |
|
| 119 | + ); |
|
| 120 | + $this->_fields = array( |
|
| 121 | + 'Registration' => array( |
|
| 122 | + 'REG_ID' => new EE_Primary_Key_Int_Field( |
|
| 123 | + 'REG_ID', |
|
| 124 | + esc_html__('Registration ID', 'event_espresso') |
|
| 125 | + ), |
|
| 126 | + 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
| 127 | + 'EVT_ID', |
|
| 128 | + esc_html__('Event ID', 'event_espresso'), |
|
| 129 | + false, |
|
| 130 | + 0, |
|
| 131 | + 'Event' |
|
| 132 | + ), |
|
| 133 | + 'ATT_ID' => new EE_Foreign_Key_Int_Field( |
|
| 134 | + 'ATT_ID', |
|
| 135 | + esc_html__('Attendee ID', 'event_espresso'), |
|
| 136 | + false, |
|
| 137 | + 0, |
|
| 138 | + 'Attendee' |
|
| 139 | + ), |
|
| 140 | + 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
| 141 | + 'TXN_ID', |
|
| 142 | + esc_html__('Transaction ID', 'event_espresso'), |
|
| 143 | + false, |
|
| 144 | + 0, |
|
| 145 | + 'Transaction' |
|
| 146 | + ), |
|
| 147 | + 'TKT_ID' => new EE_Foreign_Key_Int_Field( |
|
| 148 | + 'TKT_ID', |
|
| 149 | + esc_html__('Ticket ID', 'event_espresso'), |
|
| 150 | + false, |
|
| 151 | + 0, |
|
| 152 | + 'Ticket' |
|
| 153 | + ), |
|
| 154 | + 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
| 155 | + 'STS_ID', |
|
| 156 | + esc_html__('Status ID', 'event_espresso'), |
|
| 157 | + false, |
|
| 158 | + EEM_Registration::status_id_incomplete, |
|
| 159 | + 'Status' |
|
| 160 | + ), |
|
| 161 | + 'REG_date' => new EE_Datetime_Field( |
|
| 162 | + 'REG_date', |
|
| 163 | + esc_html__('Time registration occurred', 'event_espresso'), |
|
| 164 | + false, |
|
| 165 | + EE_Datetime_Field::now, |
|
| 166 | + $timezone |
|
| 167 | + ), |
|
| 168 | + 'REG_final_price' => new EE_Money_Field( |
|
| 169 | + 'REG_final_price', |
|
| 170 | + esc_html__('Registration\'s share of the transaction total', 'event_espresso'), |
|
| 171 | + false, |
|
| 172 | + 0 |
|
| 173 | + ), |
|
| 174 | + 'REG_paid' => new EE_Money_Field( |
|
| 175 | + 'REG_paid', |
|
| 176 | + esc_html__('Amount paid to date towards registration', 'event_espresso'), |
|
| 177 | + false, |
|
| 178 | + 0 |
|
| 179 | + ), |
|
| 180 | + 'REG_session' => new EE_Plain_Text_Field( |
|
| 181 | + 'REG_session', |
|
| 182 | + esc_html__('Session ID of registration', 'event_espresso'), |
|
| 183 | + false, |
|
| 184 | + '' |
|
| 185 | + ), |
|
| 186 | + 'REG_code' => new EE_Plain_Text_Field( |
|
| 187 | + 'REG_code', |
|
| 188 | + esc_html__('Unique Code for this registration', 'event_espresso'), |
|
| 189 | + false, |
|
| 190 | + '' |
|
| 191 | + ), |
|
| 192 | + 'REG_url_link' => new EE_Plain_Text_Field( |
|
| 193 | + 'REG_url_link', |
|
| 194 | + esc_html__('String to be used in URL for identifying registration', 'event_espresso'), |
|
| 195 | + false, |
|
| 196 | + '' |
|
| 197 | + ), |
|
| 198 | + 'REG_count' => new EE_Integer_Field( |
|
| 199 | + 'REG_count', |
|
| 200 | + esc_html__('Count of this registration in the group registration ', 'event_espresso'), |
|
| 201 | + true, |
|
| 202 | + 1 |
|
| 203 | + ), |
|
| 204 | + 'REG_group_size' => new EE_Integer_Field( |
|
| 205 | + 'REG_group_size', |
|
| 206 | + esc_html__('Number of registrations on this group', 'event_espresso'), |
|
| 207 | + false, |
|
| 208 | + 1 |
|
| 209 | + ), |
|
| 210 | + 'REG_att_is_going' => new EE_Boolean_Field( |
|
| 211 | + 'REG_att_is_going', |
|
| 212 | + esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'), |
|
| 213 | + false, |
|
| 214 | + false |
|
| 215 | + ), |
|
| 216 | + 'REG_deleted' => new EE_Trashed_Flag_Field( |
|
| 217 | + 'REG_deleted', |
|
| 218 | + esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'), |
|
| 219 | + false, |
|
| 220 | + false |
|
| 221 | + ), |
|
| 222 | + ), |
|
| 223 | + ); |
|
| 224 | + $this->_model_relations = array( |
|
| 225 | + 'Event' => new EE_Belongs_To_Relation(), |
|
| 226 | + 'Attendee' => new EE_Belongs_To_Relation(), |
|
| 227 | + 'Transaction' => new EE_Belongs_To_Relation(), |
|
| 228 | + 'Ticket' => new EE_Belongs_To_Relation(), |
|
| 229 | + 'Status' => new EE_Belongs_To_Relation(), |
|
| 230 | + 'Answer' => new EE_Has_Many_Relation(), |
|
| 231 | + 'Checkin' => new EE_Has_Many_Relation(), |
|
| 232 | + 'Registration_Payment' => new EE_Has_Many_Relation(), |
|
| 233 | + 'Payment' => new EE_HABTM_Relation('Registration_Payment'), |
|
| 234 | + 'Message' => new EE_Has_Many_Any_Relation(false) |
|
| 235 | + // allow deletes even if there are messages in the queue related |
|
| 236 | + ); |
|
| 237 | + $this->_model_chain_to_wp_user = 'Event'; |
|
| 238 | + parent::__construct($timezone); |
|
| 239 | + } |
|
| 240 | + |
|
| 241 | + |
|
| 242 | + /** |
|
| 243 | + * a list of ALL valid registration statuses currently in use within the system |
|
| 244 | + * generated by combining the filterable active and inactive reg status arrays |
|
| 245 | + * |
|
| 246 | + * @return array |
|
| 247 | + */ |
|
| 248 | + public static function reg_statuses() |
|
| 249 | + { |
|
| 250 | + return array_unique( |
|
| 251 | + array_merge( |
|
| 252 | + EEM_Registration::active_reg_statuses(), |
|
| 253 | + EEM_Registration::inactive_reg_statuses() |
|
| 254 | + ) |
|
| 255 | + ); |
|
| 256 | + } |
|
| 257 | + |
|
| 258 | + |
|
| 259 | + /** |
|
| 260 | + * reg_statuses_that_allow_payment |
|
| 261 | + * a filterable list of registration statuses that allow a registrant to make a payment |
|
| 262 | + * |
|
| 263 | + * @access public |
|
| 264 | + * @return array |
|
| 265 | + */ |
|
| 266 | + public static function reg_statuses_that_allow_payment() |
|
| 267 | + { |
|
| 268 | + return apply_filters( |
|
| 269 | + 'FHEE__EEM_Registration__reg_statuses_that_allow_payment', |
|
| 270 | + array( |
|
| 271 | + EEM_Registration::status_id_approved, |
|
| 272 | + EEM_Registration::status_id_pending_payment, |
|
| 273 | + ) |
|
| 274 | + ); |
|
| 275 | + } |
|
| 276 | + |
|
| 277 | + |
|
| 278 | + /** |
|
| 279 | + * active_reg_statuses |
|
| 280 | + * a filterable list of registration statuses that are considered active |
|
| 281 | + * |
|
| 282 | + * @access public |
|
| 283 | + * @return array |
|
| 284 | + */ |
|
| 285 | + public static function active_reg_statuses() |
|
| 286 | + { |
|
| 287 | + return apply_filters( |
|
| 288 | + 'FHEE__EEM_Registration__active_reg_statuses', |
|
| 289 | + array( |
|
| 290 | + EEM_Registration::status_id_approved, |
|
| 291 | + EEM_Registration::status_id_pending_payment, |
|
| 292 | + EEM_Registration::status_id_wait_list, |
|
| 293 | + EEM_Registration::status_id_not_approved, |
|
| 294 | + ) |
|
| 295 | + ); |
|
| 296 | + } |
|
| 297 | + |
|
| 298 | + |
|
| 299 | + /** |
|
| 300 | + * inactive_reg_statuses |
|
| 301 | + * a filterable list of registration statuses that are not considered active |
|
| 302 | + * |
|
| 303 | + * @access public |
|
| 304 | + * @return array |
|
| 305 | + */ |
|
| 306 | + public static function inactive_reg_statuses() |
|
| 307 | + { |
|
| 308 | + return apply_filters( |
|
| 309 | + 'FHEE__EEM_Registration__inactive_reg_statuses', |
|
| 310 | + array( |
|
| 311 | + EEM_Registration::status_id_incomplete, |
|
| 312 | + EEM_Registration::status_id_cancelled, |
|
| 313 | + EEM_Registration::status_id_declined, |
|
| 314 | + ) |
|
| 315 | + ); |
|
| 316 | + } |
|
| 317 | + |
|
| 318 | + |
|
| 319 | + /** |
|
| 320 | + * closed_reg_statuses |
|
| 321 | + * a filterable list of registration statuses that are considered "closed" |
|
| 322 | + * meaning they should not be considered in any calculations involving monies owing |
|
| 323 | + * |
|
| 324 | + * @access public |
|
| 325 | + * @return array |
|
| 326 | + */ |
|
| 327 | + public static function closed_reg_statuses() |
|
| 328 | + { |
|
| 329 | + return apply_filters( |
|
| 330 | + 'FHEE__EEM_Registration__closed_reg_statuses', |
|
| 331 | + array( |
|
| 332 | + EEM_Registration::status_id_cancelled, |
|
| 333 | + EEM_Registration::status_id_declined, |
|
| 334 | + EEM_Registration::status_id_wait_list, |
|
| 335 | + ) |
|
| 336 | + ); |
|
| 337 | + } |
|
| 338 | + |
|
| 339 | + |
|
| 340 | + /** |
|
| 341 | + * get list of registration statuses |
|
| 342 | + * |
|
| 343 | + * @access public |
|
| 344 | + * @param array $exclude The status ids to exclude from the returned results |
|
| 345 | + * @param bool $translated If true will return the values as singular localized strings |
|
| 346 | + * @return array |
|
| 347 | + * @throws EE_Error |
|
| 348 | + */ |
|
| 349 | + public static function reg_status_array($exclude = array(), $translated = false) |
|
| 350 | + { |
|
| 351 | + EEM_Registration::instance()->_get_registration_status_array($exclude); |
|
| 352 | + return $translated |
|
| 353 | + ? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence') |
|
| 354 | + : self::$_reg_status; |
|
| 355 | + } |
|
| 356 | + |
|
| 357 | + |
|
| 358 | + /** |
|
| 359 | + * get list of registration statuses |
|
| 360 | + * |
|
| 361 | + * @access private |
|
| 362 | + * @param array $exclude |
|
| 363 | + * @return void |
|
| 364 | + * @throws EE_Error |
|
| 365 | + */ |
|
| 366 | + private function _get_registration_status_array($exclude = array()) |
|
| 367 | + { |
|
| 368 | + // in the very rare circumstance that we are deleting a model's table's data |
|
| 369 | + // and the table hasn't actually been created, this could have an error |
|
| 370 | + /** @type WPDB $wpdb */ |
|
| 371 | + global $wpdb; |
|
| 372 | + if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) { |
|
| 373 | + $results = $wpdb->get_results( |
|
| 374 | + "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'" |
|
| 375 | + ); |
|
| 376 | + self::$_reg_status = array(); |
|
| 377 | + foreach ($results as $status) { |
|
| 378 | + if (!in_array($status->STS_ID, $exclude, true)) { |
|
| 379 | + self::$_reg_status[ $status->STS_ID ] = $status->STS_code; |
|
| 380 | + } |
|
| 381 | + } |
|
| 382 | + } |
|
| 383 | + } |
|
| 384 | + |
|
| 385 | + |
|
| 386 | + /** |
|
| 387 | + * Gets the injected table analyzer, or throws an exception |
|
| 388 | + * |
|
| 389 | + * @return TableAnalysis |
|
| 390 | + * @throws EE_Error |
|
| 391 | + */ |
|
| 392 | + protected function _get_table_analysis() |
|
| 393 | + { |
|
| 394 | + if ($this->_table_analysis instanceof TableAnalysis) { |
|
| 395 | + return $this->_table_analysis; |
|
| 396 | + } |
|
| 397 | + throw new EE_Error( |
|
| 398 | + sprintf( |
|
| 399 | + esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'), |
|
| 400 | + get_class($this) |
|
| 401 | + ) |
|
| 402 | + ); |
|
| 403 | + } |
|
| 404 | + |
|
| 405 | + |
|
| 406 | + /** |
|
| 407 | + * This returns a wpdb->results array of all registration date month and years matching the incoming query params |
|
| 408 | + * and grouped by month and year. |
|
| 409 | + * |
|
| 410 | + * @param array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
| 411 | + * @return array |
|
| 412 | + * @throws EE_Error |
|
| 413 | + */ |
|
| 414 | + public function get_reg_months_and_years($where_params) |
|
| 415 | + { |
|
| 416 | + $query_params[0] = $where_params; |
|
| 417 | + $query_params['group_by'] = array('reg_year', 'reg_month'); |
|
| 418 | + $query_params['order_by'] = array('REG_date' => 'DESC'); |
|
| 419 | + $columns_to_select = array( |
|
| 420 | + 'reg_year' => array('YEAR(REG_date)', '%s'), |
|
| 421 | + 'reg_month' => array('MONTHNAME(REG_date)', '%s'), |
|
| 422 | + ); |
|
| 423 | + return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select); |
|
| 424 | + } |
|
| 425 | + |
|
| 426 | + |
|
| 427 | + /** |
|
| 428 | + * retrieve ALL registrations for a particular Attendee from db |
|
| 429 | + * |
|
| 430 | + * @param int $ATT_ID |
|
| 431 | + * @return EE_Base_Class[]|EE_Registration[]|null |
|
| 432 | + * @throws EE_Error |
|
| 433 | + */ |
|
| 434 | + public function get_all_registrations_for_attendee($ATT_ID = 0) |
|
| 435 | + { |
|
| 436 | + if (!$ATT_ID) { |
|
| 437 | + return null; |
|
| 438 | + } |
|
| 439 | + return $this->get_all(array(array('ATT_ID' => $ATT_ID))); |
|
| 440 | + } |
|
| 441 | + |
|
| 442 | + |
|
| 443 | + /** |
|
| 444 | + * Gets a registration given their REG_url_link. Yes, this should usually |
|
| 445 | + * be passed via a GET parameter. |
|
| 446 | + * |
|
| 447 | + * @param string $REG_url_link |
|
| 448 | + * @return EE_Base_Class|EE_Registration|null |
|
| 449 | + * @throws EE_Error |
|
| 450 | + */ |
|
| 451 | + public function get_registration_for_reg_url_link($REG_url_link) |
|
| 452 | + { |
|
| 453 | + if (!$REG_url_link) { |
|
| 454 | + return null; |
|
| 455 | + } |
|
| 456 | + return $this->get_one(array(array('REG_url_link' => $REG_url_link))); |
|
| 457 | + } |
|
| 458 | + |
|
| 459 | + |
|
| 460 | + /** |
|
| 461 | + * retrieve registration for a specific transaction attendee from db |
|
| 462 | + * |
|
| 463 | + * @access public |
|
| 464 | + * @param int $TXN_ID |
|
| 465 | + * @param int $ATT_ID |
|
| 466 | + * @param int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the |
|
| 467 | + * attendee number is required |
|
| 468 | + * @return mixed array on success, FALSE on fail |
|
| 469 | + * @throws EE_Error |
|
| 470 | + */ |
|
| 471 | + public function get_registration_for_transaction_attendee($TXN_ID = 0, $ATT_ID = 0, $att_nmbr = 0) |
|
| 472 | + { |
|
| 473 | + return $this->get_one(array( |
|
| 474 | + array( |
|
| 475 | + 'TXN_ID' => $TXN_ID, |
|
| 476 | + 'ATT_ID' => $ATT_ID, |
|
| 477 | + ), |
|
| 478 | + 'limit' => array(min($att_nmbr - 1, 0), 1), |
|
| 479 | + )); |
|
| 480 | + } |
|
| 481 | + |
|
| 482 | + |
|
| 483 | + /** |
|
| 484 | + * get the number of registrations per day for the Registration Admin page Reports Tab. |
|
| 485 | + * (doesn't utilize models because it's a fairly specialized query) |
|
| 486 | + * |
|
| 487 | + * @access public |
|
| 488 | + * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
| 489 | + * @return stdClass[] with properties regDate and total |
|
| 490 | + * @throws EE_Error |
|
| 491 | + */ |
|
| 492 | + public function get_registrations_per_day_report($period = '-1 month') |
|
| 493 | + { |
|
| 494 | + $sql_date = $this->convert_datetime_for_query( |
|
| 495 | + 'REG_date', |
|
| 496 | + date('Y-m-d H:i:s', strtotime($period)), |
|
| 497 | + 'Y-m-d H:i:s', |
|
| 498 | + 'UTC' |
|
| 499 | + ); |
|
| 500 | + $where = array( |
|
| 501 | + 'REG_date' => array('>=', $sql_date), |
|
| 502 | + 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
| 503 | + ); |
|
| 504 | + if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) { |
|
| 505 | + $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
| 506 | + } |
|
| 507 | + $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date'); |
|
| 508 | + $results = $this->_get_all_wpdb_results( |
|
| 509 | + array( |
|
| 510 | + $where, |
|
| 511 | + 'group_by' => 'regDate', |
|
| 512 | + 'order_by' => array('REG_date' => 'ASC'), |
|
| 513 | + ), |
|
| 514 | + OBJECT, |
|
| 515 | + array( |
|
| 516 | + 'regDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
| 517 | + 'total' => array('count(REG_ID)', '%d'), |
|
| 518 | + ) |
|
| 519 | + ); |
|
| 520 | + return $results; |
|
| 521 | + } |
|
| 522 | + |
|
| 523 | + |
|
| 524 | + /** |
|
| 525 | + * Get the number of registrations per day including the count of registrations for each Registration Status. |
|
| 526 | + * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
| 527 | + * |
|
| 528 | + * @param string $period |
|
| 529 | + * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID |
|
| 530 | + * @throws EE_Error |
|
| 531 | + * (i.e. RAP) |
|
| 532 | + */ |
|
| 533 | + public function get_registrations_per_day_and_per_status_report($period = '-1 month') |
|
| 534 | + { |
|
| 535 | + global $wpdb; |
|
| 536 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 537 | + $event_table = $wpdb->posts; |
|
| 538 | + $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
| 539 | + // prepare the query interval for displaying offset |
|
| 540 | + $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date'); |
|
| 541 | + // inner date query |
|
| 542 | + $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} "; |
|
| 543 | + $inner_where = ' WHERE'; |
|
| 544 | + // exclude events not authored by user if permissions in effect |
|
| 545 | + if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 546 | + $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
| 547 | + $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
| 548 | + } |
|
| 549 | + $inner_where .= " REG_date >= '{$sql_date}'"; |
|
| 550 | + $inner_date_query .= $inner_where; |
|
| 551 | + // start main query |
|
| 552 | + $select = "SELECT DATE({$query_interval}) as Registration_REG_date, "; |
|
| 553 | + $join = ''; |
|
| 554 | + $join_parts = array(); |
|
| 555 | + $select_parts = array(); |
|
| 556 | + // loop through registration stati to do parts for each status. |
|
| 557 | + foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
| 558 | + if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
| 559 | + continue; |
|
| 560 | + } |
|
| 561 | + $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
| 562 | + $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'"; |
|
| 563 | + } |
|
| 564 | + // setup the selects |
|
| 565 | + $select .= implode(', ', $select_parts); |
|
| 566 | + $select .= " FROM ($inner_date_query) AS dates LEFT JOIN "; |
|
| 567 | + // setup the joins |
|
| 568 | + $join .= implode(' LEFT JOIN ', $join_parts); |
|
| 569 | + // now let's put it all together |
|
| 570 | + $query = $select . $join . ' GROUP BY Registration_REG_date'; |
|
| 571 | + // and execute it |
|
| 572 | + return $wpdb->get_results($query, ARRAY_A); |
|
| 573 | + } |
|
| 574 | + |
|
| 575 | + |
|
| 576 | + /** |
|
| 577 | + * get the number of registrations per event for the Registration Admin page Reports Tab |
|
| 578 | + * |
|
| 579 | + * @access public |
|
| 580 | + * @param $period string which can be passed to php's strtotime function (eg "-1 month") |
|
| 581 | + * @return stdClass[] each with properties event_name, reg_limit, and total |
|
| 582 | + * @throws EE_Error |
|
| 583 | + */ |
|
| 584 | + public function get_registrations_per_event_report($period = '-1 month') |
|
| 585 | + { |
|
| 586 | + $date_sql = $this->convert_datetime_for_query( |
|
| 587 | + 'REG_date', |
|
| 588 | + date('Y-m-d H:i:s', strtotime($period)), |
|
| 589 | + 'Y-m-d H:i:s', |
|
| 590 | + 'UTC' |
|
| 591 | + ); |
|
| 592 | + $where = array( |
|
| 593 | + 'REG_date' => array('>=', $date_sql), |
|
| 594 | + 'STS_ID' => array('!=', EEM_Registration::status_id_incomplete), |
|
| 595 | + ); |
|
| 596 | + if (!EE_Registry::instance()->CAP->current_user_can( |
|
| 597 | + 'ee_read_others_registrations', |
|
| 598 | + 'reg_per_event_report' |
|
| 599 | + ) |
|
| 600 | + ) { |
|
| 601 | + $where['Event.EVT_wp_user'] = get_current_user_id(); |
|
| 602 | + } |
|
| 603 | + $results = $this->_get_all_wpdb_results( |
|
| 604 | + array( |
|
| 605 | + $where, |
|
| 606 | + 'group_by' => 'Event.EVT_name', |
|
| 607 | + 'order_by' => 'Event.EVT_name', |
|
| 608 | + 'limit' => array(0, 24), |
|
| 609 | + ), |
|
| 610 | + OBJECT, |
|
| 611 | + array( |
|
| 612 | + 'event_name' => array('Event_CPT.post_title', '%s'), |
|
| 613 | + 'total' => array('COUNT(REG_ID)', '%s'), |
|
| 614 | + ) |
|
| 615 | + ); |
|
| 616 | + return $results; |
|
| 617 | + } |
|
| 618 | + |
|
| 619 | + |
|
| 620 | + /** |
|
| 621 | + * Get the number of registrations per event grouped by registration status. |
|
| 622 | + * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results. |
|
| 623 | + * |
|
| 624 | + * @param string $period |
|
| 625 | + * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID |
|
| 626 | + * @throws EE_Error |
|
| 627 | + * (i.e. RAP) |
|
| 628 | + */ |
|
| 629 | + public function get_registrations_per_event_and_per_status_report($period = '-1 month') |
|
| 630 | + { |
|
| 631 | + global $wpdb; |
|
| 632 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 633 | + $event_table = $wpdb->posts; |
|
| 634 | + $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
| 635 | + // inner date query |
|
| 636 | + $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table "; |
|
| 637 | + $inner_where = ' WHERE'; |
|
| 638 | + // exclude events not authored by user if permissions in effect |
|
| 639 | + if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 640 | + $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID"; |
|
| 641 | + $inner_where .= ' post_author = ' . get_current_user_id() . ' AND'; |
|
| 642 | + } |
|
| 643 | + $inner_where .= " REG_date >= '{$sql_date}'"; |
|
| 644 | + $inner_date_query .= $inner_where; |
|
| 645 | + // build main query |
|
| 646 | + $select = 'SELECT Event.post_title as Registration_Event, '; |
|
| 647 | + $join = ''; |
|
| 648 | + $join_parts = array(); |
|
| 649 | + $select_parts = array(); |
|
| 650 | + // loop through registration stati to do parts for each status. |
|
| 651 | + foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) { |
|
| 652 | + if ($STS_ID === EEM_Registration::status_id_incomplete) { |
|
| 653 | + continue; |
|
| 654 | + } |
|
| 655 | + $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}"; |
|
| 656 | + $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date"; |
|
| 657 | + } |
|
| 658 | + // setup the selects |
|
| 659 | + $select .= implode(', ', $select_parts); |
|
| 660 | + $select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN "; |
|
| 661 | + // setup remaining joins |
|
| 662 | + $join .= implode(' LEFT JOIN ', $join_parts); |
|
| 663 | + // now put it all together |
|
| 664 | + $query = $select . $join . ' GROUP BY Registration_Event'; |
|
| 665 | + // and execute |
|
| 666 | + return $wpdb->get_results($query, ARRAY_A); |
|
| 667 | + } |
|
| 668 | + |
|
| 669 | + |
|
| 670 | + /** |
|
| 671 | + * Returns the EE_Registration of the primary attendee on the transaction id provided |
|
| 672 | + * |
|
| 673 | + * @param int $TXN_ID |
|
| 674 | + * @return EE_Base_Class|EE_Registration|null |
|
| 675 | + * @throws EE_Error |
|
| 676 | + */ |
|
| 677 | + public function get_primary_registration_for_transaction_ID($TXN_ID = 0) |
|
| 678 | + { |
|
| 679 | + if (!$TXN_ID) { |
|
| 680 | + return null; |
|
| 681 | + } |
|
| 682 | + return $this->get_one(array( |
|
| 683 | + array( |
|
| 684 | + 'TXN_ID' => $TXN_ID, |
|
| 685 | + 'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT, |
|
| 686 | + ), |
|
| 687 | + )); |
|
| 688 | + } |
|
| 689 | + |
|
| 690 | + |
|
| 691 | + /** |
|
| 692 | + * get_event_registration_count |
|
| 693 | + * |
|
| 694 | + * @access public |
|
| 695 | + * @param int $EVT_ID |
|
| 696 | + * @param boolean $for_incomplete_payments |
|
| 697 | + * @return int |
|
| 698 | + * @throws EE_Error |
|
| 699 | + */ |
|
| 700 | + public function get_event_registration_count($EVT_ID, $for_incomplete_payments = false) |
|
| 701 | + { |
|
| 702 | + // we only count approved registrations towards registration limits |
|
| 703 | + $query_params = array(array('EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved)); |
|
| 704 | + if ($for_incomplete_payments) { |
|
| 705 | + $query_params[0]['Transaction.STS_ID'] = array('!=', EEM_Transaction::complete_status_code); |
|
| 706 | + } |
|
| 707 | + return $this->count($query_params); |
|
| 708 | + } |
|
| 709 | + |
|
| 710 | + |
|
| 711 | + /** |
|
| 712 | + * Deletes all registrations with no transactions. Note that this needs to be very efficient |
|
| 713 | + * and so it uses wpdb directly. Also, we can't put a limit on this because MySQL doesn't allow a limit on a delete |
|
| 714 | + * when joining tables like this. |
|
| 715 | + * |
|
| 716 | + * @global WPDB $wpdb |
|
| 717 | + * @return int number deleted |
|
| 718 | + * @throws EE_Error |
|
| 719 | + */ |
|
| 720 | + public function delete_registrations_with_no_transaction() |
|
| 721 | + { |
|
| 722 | + /** @type WPDB $wpdb */ |
|
| 723 | + global $wpdb; |
|
| 724 | + return $wpdb->query( |
|
| 725 | + 'DELETE r FROM ' |
|
| 726 | + . $this->table() |
|
| 727 | + . ' r LEFT JOIN ' |
|
| 728 | + . EEM_Transaction::instance()->table() |
|
| 729 | + . ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL' |
|
| 730 | + ); |
|
| 731 | + } |
|
| 732 | + |
|
| 733 | + |
|
| 734 | + /** |
|
| 735 | + * Count registrations checked into (or out of) a datetime |
|
| 736 | + * |
|
| 737 | + * @param int $DTT_ID datetime ID |
|
| 738 | + * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
| 739 | + * @return int |
|
| 740 | + * @throws EE_Error |
|
| 741 | + */ |
|
| 742 | + public function count_registrations_checked_into_datetime($DTT_ID, $checked_in = true) |
|
| 743 | + { |
|
| 744 | + global $wpdb; |
|
| 745 | + // subquery to get latest checkin |
|
| 746 | + $query = $wpdb->prepare( |
|
| 747 | + 'SELECT ' |
|
| 748 | + . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
| 749 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
| 750 | + . '( SELECT ' |
|
| 751 | + . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
| 752 | + . 'REG_ID AS REG_ID ' |
|
| 753 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' ' |
|
| 754 | + . 'WHERE DTT_ID=%d ' |
|
| 755 | + . 'GROUP BY REG_ID' |
|
| 756 | + . ') AS most_recent_checkin_per_reg ' |
|
| 757 | + . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
| 758 | + . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
| 759 | + . 'WHERE ' |
|
| 760 | + . 'checkins.CHK_in=%d', |
|
| 761 | + $DTT_ID, |
|
| 762 | + $checked_in |
|
| 763 | + ); |
|
| 764 | + return (int) $wpdb->get_var($query); |
|
| 765 | + } |
|
| 766 | + |
|
| 767 | + |
|
| 768 | + /** |
|
| 769 | + * Count registrations checked into (or out of) an event. |
|
| 770 | + * |
|
| 771 | + * @param int $EVT_ID event ID |
|
| 772 | + * @param boolean $checked_in whether to count registrations checked IN or OUT |
|
| 773 | + * @return int |
|
| 774 | + * @throws EE_Error |
|
| 775 | + */ |
|
| 776 | + public function count_registrations_checked_into_event($EVT_ID, $checked_in = true) |
|
| 777 | + { |
|
| 778 | + global $wpdb; |
|
| 779 | + // subquery to get latest checkin |
|
| 780 | + $query = $wpdb->prepare( |
|
| 781 | + 'SELECT ' |
|
| 782 | + . 'COUNT( DISTINCT checkins.REG_ID ) ' |
|
| 783 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' |
|
| 784 | + . '( SELECT ' |
|
| 785 | + . 'max( CHK_timestamp ) AS latest_checkin, ' |
|
| 786 | + . 'REG_ID AS REG_ID ' |
|
| 787 | + . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c ' |
|
| 788 | + . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d ' |
|
| 789 | + . 'ON c.DTT_ID=d.DTT_ID ' |
|
| 790 | + . 'WHERE d.EVT_ID=%d ' |
|
| 791 | + . 'GROUP BY REG_ID' |
|
| 792 | + . ') AS most_recent_checkin_per_reg ' |
|
| 793 | + . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' |
|
| 794 | + . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' |
|
| 795 | + . 'WHERE ' |
|
| 796 | + . 'checkins.CHK_in=%d', |
|
| 797 | + $EVT_ID, |
|
| 798 | + $checked_in |
|
| 799 | + ); |
|
| 800 | + return (int) $wpdb->get_var($query); |
|
| 801 | + } |
|
| 802 | + |
|
| 803 | + |
|
| 804 | + /** |
|
| 805 | + * The purpose of this method is to retrieve an array of |
|
| 806 | + * EE_Registration objects that represent the latest registration |
|
| 807 | + * for each ATT_ID given in the function argument. |
|
| 808 | + * |
|
| 809 | + * @param array $attendee_ids |
|
| 810 | + * @return EE_Base_Class[]|EE_Registration[] |
|
| 811 | + * @throws EE_Error |
|
| 812 | + */ |
|
| 813 | + public function get_latest_registration_for_each_of_given_contacts($attendee_ids = array()) |
|
| 814 | + { |
|
| 815 | + // first do a native wp_query to get the latest REG_ID's matching these attendees. |
|
| 816 | + global $wpdb; |
|
| 817 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 818 | + $attendee_table = $wpdb->posts; |
|
| 819 | + $attendee_ids = is_array($attendee_ids) |
|
| 820 | + ? array_map('absint', $attendee_ids) |
|
| 821 | + : array((int) $attendee_ids); |
|
| 822 | + $ATT_IDs = implode(',', $attendee_ids); |
|
| 823 | + // first we do a query to get the registration ids |
|
| 824 | + // (because a group by before order by causes the order by to be ignored.) |
|
| 825 | + $registration_id_query = " |
|
| 826 | 826 | SELECT registrations.registration_ids as registration_id |
| 827 | 827 | FROM ( |
| 828 | 828 | SELECT |
@@ -836,61 +836,61 @@ discard block |
||
| 836 | 836 | ) AS registrations |
| 837 | 837 | GROUP BY registrations.attendee_ids |
| 838 | 838 | "; |
| 839 | - $registration_ids = $wpdb->get_results($registration_id_query, ARRAY_A); |
|
| 840 | - if (empty($registration_ids)) { |
|
| 841 | - return array(); |
|
| 842 | - } |
|
| 843 | - $ids_for_model_query = array(); |
|
| 844 | - // let's flatten the ids so they can be used in the model query. |
|
| 845 | - foreach ($registration_ids as $registration_id) { |
|
| 846 | - if (isset($registration_id['registration_id'])) { |
|
| 847 | - $ids_for_model_query[] = $registration_id['registration_id']; |
|
| 848 | - } |
|
| 849 | - } |
|
| 850 | - // construct query |
|
| 851 | - $_where = array( |
|
| 852 | - 'REG_ID' => array('IN', $ids_for_model_query), |
|
| 853 | - ); |
|
| 854 | - return $this->get_all(array($_where)); |
|
| 855 | - } |
|
| 856 | - |
|
| 857 | - |
|
| 858 | - |
|
| 859 | - /** |
|
| 860 | - * returns a count of registrations for the supplied event having the status as specified |
|
| 861 | - * |
|
| 862 | - * @param int $EVT_ID |
|
| 863 | - * @param array $statuses |
|
| 864 | - * @return int |
|
| 865 | - * @throws InvalidArgumentException |
|
| 866 | - * @throws InvalidStatusException |
|
| 867 | - * @throws EE_Error |
|
| 868 | - */ |
|
| 869 | - public function event_reg_count_for_statuses($EVT_ID, $statuses = array()) |
|
| 870 | - { |
|
| 871 | - $EVT_ID = absint($EVT_ID); |
|
| 872 | - if (! $EVT_ID) { |
|
| 873 | - throw new InvalidArgumentException( |
|
| 874 | - esc_html__('An invalid Event ID was supplied.', 'event_espresso') |
|
| 875 | - ); |
|
| 876 | - } |
|
| 877 | - $statuses = is_array($statuses) ? $statuses : array($statuses); |
|
| 878 | - $statuses = ! empty($statuses) ? $statuses : array(EEM_Registration::status_id_approved); |
|
| 879 | - $valid_reg_statuses = EEM_Registration::reg_statuses(); |
|
| 880 | - foreach ($statuses as $status) { |
|
| 881 | - if (! in_array($status, $valid_reg_statuses, true)) { |
|
| 882 | - throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso')); |
|
| 883 | - } |
|
| 884 | - } |
|
| 885 | - return $this->count( |
|
| 886 | - array( |
|
| 887 | - array( |
|
| 888 | - 'EVT_ID' => $EVT_ID, |
|
| 889 | - 'STS_ID' => array('IN', $statuses), |
|
| 890 | - ), |
|
| 891 | - ), |
|
| 892 | - 'REG_ID', |
|
| 893 | - true |
|
| 894 | - ); |
|
| 895 | - } |
|
| 839 | + $registration_ids = $wpdb->get_results($registration_id_query, ARRAY_A); |
|
| 840 | + if (empty($registration_ids)) { |
|
| 841 | + return array(); |
|
| 842 | + } |
|
| 843 | + $ids_for_model_query = array(); |
|
| 844 | + // let's flatten the ids so they can be used in the model query. |
|
| 845 | + foreach ($registration_ids as $registration_id) { |
|
| 846 | + if (isset($registration_id['registration_id'])) { |
|
| 847 | + $ids_for_model_query[] = $registration_id['registration_id']; |
|
| 848 | + } |
|
| 849 | + } |
|
| 850 | + // construct query |
|
| 851 | + $_where = array( |
|
| 852 | + 'REG_ID' => array('IN', $ids_for_model_query), |
|
| 853 | + ); |
|
| 854 | + return $this->get_all(array($_where)); |
|
| 855 | + } |
|
| 856 | + |
|
| 857 | + |
|
| 858 | + |
|
| 859 | + /** |
|
| 860 | + * returns a count of registrations for the supplied event having the status as specified |
|
| 861 | + * |
|
| 862 | + * @param int $EVT_ID |
|
| 863 | + * @param array $statuses |
|
| 864 | + * @return int |
|
| 865 | + * @throws InvalidArgumentException |
|
| 866 | + * @throws InvalidStatusException |
|
| 867 | + * @throws EE_Error |
|
| 868 | + */ |
|
| 869 | + public function event_reg_count_for_statuses($EVT_ID, $statuses = array()) |
|
| 870 | + { |
|
| 871 | + $EVT_ID = absint($EVT_ID); |
|
| 872 | + if (! $EVT_ID) { |
|
| 873 | + throw new InvalidArgumentException( |
|
| 874 | + esc_html__('An invalid Event ID was supplied.', 'event_espresso') |
|
| 875 | + ); |
|
| 876 | + } |
|
| 877 | + $statuses = is_array($statuses) ? $statuses : array($statuses); |
|
| 878 | + $statuses = ! empty($statuses) ? $statuses : array(EEM_Registration::status_id_approved); |
|
| 879 | + $valid_reg_statuses = EEM_Registration::reg_statuses(); |
|
| 880 | + foreach ($statuses as $status) { |
|
| 881 | + if (! in_array($status, $valid_reg_statuses, true)) { |
|
| 882 | + throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso')); |
|
| 883 | + } |
|
| 884 | + } |
|
| 885 | + return $this->count( |
|
| 886 | + array( |
|
| 887 | + array( |
|
| 888 | + 'EVT_ID' => $EVT_ID, |
|
| 889 | + 'STS_ID' => array('IN', $statuses), |
|
| 890 | + ), |
|
| 891 | + ), |
|
| 892 | + 'REG_ID', |
|
| 893 | + true |
|
| 894 | + ); |
|
| 895 | + } |
|
| 896 | 896 | } |
@@ -9,628 +9,628 @@ |
||
| 9 | 9 | class EEM_Message extends EEM_Base implements EEI_Query_Filter |
| 10 | 10 | { |
| 11 | 11 | |
| 12 | - // private instance of the Message object |
|
| 13 | - protected static $_instance = null; |
|
| 12 | + // private instance of the Message object |
|
| 13 | + protected static $_instance = null; |
|
| 14 | 14 | |
| 15 | 15 | |
| 16 | - /** |
|
| 17 | - * This priority indicates a message should be generated and sent ASAP |
|
| 18 | - * |
|
| 19 | - * @type int |
|
| 20 | - */ |
|
| 21 | - const priority_high = 10; |
|
| 22 | - |
|
| 23 | - |
|
| 24 | - /** |
|
| 25 | - * This priority indicates a message should be generated ASAP and queued for sending. |
|
| 26 | - * |
|
| 27 | - * @type |
|
| 28 | - */ |
|
| 29 | - const priority_medium = 20; |
|
| 30 | - |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * This priority indicates a message should be queued for generating. |
|
| 34 | - * |
|
| 35 | - * @type int |
|
| 36 | - */ |
|
| 37 | - const priority_low = 30; |
|
| 38 | - |
|
| 39 | - |
|
| 40 | - /** |
|
| 41 | - * indicates this message was sent at the time modified |
|
| 42 | - */ |
|
| 43 | - const status_sent = 'MSN'; |
|
| 44 | - |
|
| 45 | - |
|
| 46 | - /** |
|
| 47 | - * indicates this message is waiting to be sent |
|
| 48 | - */ |
|
| 49 | - const status_idle = 'MID'; |
|
| 50 | - |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * indicates an attempt was a made to send this message |
|
| 54 | - * at the scheduled time, but it failed at the time modified. This differs from MDO status in that it will ALWAYS |
|
| 55 | - * appear to the end user. |
|
| 56 | - */ |
|
| 57 | - const status_failed = 'MFL'; |
|
| 58 | - |
|
| 59 | - |
|
| 60 | - /** |
|
| 61 | - * indicates the message has been flagged for resending (at the time modified). |
|
| 62 | - */ |
|
| 63 | - const status_resend = 'MRS'; |
|
| 64 | - |
|
| 65 | - |
|
| 66 | - /** |
|
| 67 | - * indicates the message has been flagged for generation but has not been generated yet. Messages always start as |
|
| 68 | - * this status when added to the queue. |
|
| 69 | - */ |
|
| 70 | - const status_incomplete = 'MIC'; |
|
| 71 | - |
|
| 72 | - |
|
| 73 | - /** |
|
| 74 | - * Indicates everything was generated fine for the message, however, the messenger was unable to send. |
|
| 75 | - * This status means that its possible to retry sending the message. |
|
| 76 | - */ |
|
| 77 | - const status_retry = 'MRT'; |
|
| 78 | - |
|
| 79 | - |
|
| 80 | - /** |
|
| 81 | - * This is used for more informational messages that may not indicate anything is broken but still cannot be |
|
| 82 | - * generated or sent correctly. An example of a message that would get flagged this way would be when a not |
|
| 83 | - * approved message was queued for generation, but at time of generation, the attached registration(s) are |
|
| 84 | - * approved. So the message queued for generation is no longer valid. Messages for this status will only persist |
|
| 85 | - * in the db and be viewable in the message activity list table when the messages system is in debug mode. |
|
| 86 | - * |
|
| 87 | - * @see EEM_Message::debug() |
|
| 88 | - */ |
|
| 89 | - const status_debug_only = 'MDO'; |
|
| 90 | - |
|
| 91 | - |
|
| 92 | - /** |
|
| 93 | - * This status is given to messages it is processed by the messenger send method. |
|
| 94 | - * Messages with this status should rarely be seen in the Message List table, but if they are, that's usually |
|
| 95 | - * indicative of a PHP timeout or memory limit issue. |
|
| 96 | - */ |
|
| 97 | - const status_messenger_executing = 'MEX'; |
|
| 98 | - |
|
| 99 | - |
|
| 100 | - /** |
|
| 101 | - * Private constructor to prevent direct creation. |
|
| 102 | - * |
|
| 103 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and |
|
| 104 | - * any incoming timezone data that gets saved). Note this just sends the timezone info to |
|
| 105 | - * the date time model field objects. Default is null (and will be assumed using the set |
|
| 106 | - * timezone in the 'timezone_string' wp option) |
|
| 107 | - * @return EEM_Message |
|
| 108 | - */ |
|
| 109 | - protected function __construct($timezone = null) |
|
| 110 | - { |
|
| 111 | - $this->singular_item = __('Message', 'event_espresso'); |
|
| 112 | - $this->plural_item = __('Messages', 'event_espresso'); |
|
| 113 | - |
|
| 114 | - // used for token generator |
|
| 115 | - EE_Registry::instance()->load_helper('URL'); |
|
| 116 | - |
|
| 117 | - $this->_tables = array( |
|
| 118 | - 'Message' => new EE_Primary_Table('esp_message', 'MSG_ID'), |
|
| 119 | - ); |
|
| 120 | - |
|
| 121 | - $allowed_priority = array( |
|
| 122 | - self::priority_high => __('high', 'event_espresso'), |
|
| 123 | - self::priority_medium => __('medium', 'event_espresso'), |
|
| 124 | - self::priority_low => __('low', 'event_espresso'), |
|
| 125 | - ); |
|
| 126 | - |
|
| 127 | - $this->_fields = array( |
|
| 128 | - 'Message' => array( |
|
| 129 | - 'MSG_ID' => new EE_Primary_Key_Int_Field('MSG_ID', __('Message ID', 'event_espresso')), |
|
| 130 | - 'MSG_token' => new EE_Plain_Text_Field( |
|
| 131 | - 'MSG_token', |
|
| 132 | - __( |
|
| 133 | - 'Unique Token used to represent this row in publicly viewable contexts (eg. a url).', |
|
| 134 | - 'event_espresso' |
|
| 135 | - ), |
|
| 136 | - false, |
|
| 137 | - EEH_URL::generate_unique_token() |
|
| 138 | - ), |
|
| 139 | - 'GRP_ID' => new EE_Foreign_Key_Int_Field( |
|
| 140 | - 'GRP_ID', |
|
| 141 | - __('Foreign key to the EEM_Message_Template_Group table.', 'event_espresso'), |
|
| 142 | - true, |
|
| 143 | - 0, |
|
| 144 | - 'Message_Template_Group' |
|
| 145 | - ), |
|
| 146 | - 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
| 147 | - 'TXN_ID', |
|
| 148 | - __( |
|
| 149 | - 'Foreign key to the related EE_Transaction. This is required to give context for regenerating the specific message', |
|
| 150 | - 'event_espresso' |
|
| 151 | - ), |
|
| 152 | - true, |
|
| 153 | - 0, |
|
| 154 | - 'Transaction' |
|
| 155 | - ), |
|
| 156 | - 'MSG_messenger' => new EE_Plain_Text_Field( |
|
| 157 | - 'MSG_messenger', |
|
| 158 | - __( |
|
| 159 | - 'Corresponds to the EE_messenger::name used to send this message. This will also be used to attempt any resending of the message.', |
|
| 160 | - 'event_espresso' |
|
| 161 | - ), |
|
| 162 | - false, |
|
| 163 | - 'email' |
|
| 164 | - ), |
|
| 165 | - 'MSG_message_type' => new EE_Plain_Text_Field( |
|
| 166 | - 'MSG_message_type', |
|
| 167 | - __('Corresponds to the EE_message_type::name used to generate this message.', 'event_espresso'), |
|
| 168 | - false, |
|
| 169 | - 'receipt' |
|
| 170 | - ), |
|
| 171 | - 'MSG_context' => new EE_Plain_Text_Field('MSG_context', __('Context', 'event_espresso'), false), |
|
| 172 | - 'MSG_recipient_ID' => new EE_Foreign_Key_Int_Field( |
|
| 173 | - 'MSG_recipient_ID', |
|
| 174 | - __('Recipient ID', 'event_espresso'), |
|
| 175 | - true, |
|
| 176 | - null, |
|
| 177 | - array('Registration', 'Attendee', 'WP_User') |
|
| 178 | - ), |
|
| 179 | - 'MSG_recipient_type' => new EE_Any_Foreign_Model_Name_Field( |
|
| 180 | - 'MSG_recipient_type', |
|
| 181 | - __('Recipient Type', 'event_espresso'), |
|
| 182 | - true, |
|
| 183 | - null, |
|
| 184 | - array('Registration', 'Attendee', 'WP_User') |
|
| 185 | - ), |
|
| 186 | - 'MSG_content' => new EE_Maybe_Serialized_Text_Field( |
|
| 187 | - 'MSG_content', |
|
| 188 | - __('Content', 'event_espresso'), |
|
| 189 | - true, |
|
| 190 | - '' |
|
| 191 | - ), |
|
| 192 | - 'MSG_to' => new EE_Maybe_Serialized_Text_Field( |
|
| 193 | - 'MSG_to', |
|
| 194 | - __('Address To', 'event_espresso'), |
|
| 195 | - true |
|
| 196 | - ), |
|
| 197 | - 'MSG_from' => new EE_Maybe_Serialized_Text_Field( |
|
| 198 | - 'MSG_from', |
|
| 199 | - __('Address From', 'event_espresso'), |
|
| 200 | - true |
|
| 201 | - ), |
|
| 202 | - 'MSG_subject' => new EE_Maybe_Serialized_Text_Field( |
|
| 203 | - 'MSG_subject', |
|
| 204 | - __('Subject', 'event_espresso'), |
|
| 205 | - true, |
|
| 206 | - '' |
|
| 207 | - ), |
|
| 208 | - 'MSG_priority' => new EE_Enum_Integer_Field( |
|
| 209 | - 'MSG_priority', |
|
| 210 | - __('Priority', 'event_espresso'), |
|
| 211 | - false, |
|
| 212 | - self::priority_low, |
|
| 213 | - $allowed_priority |
|
| 214 | - ), |
|
| 215 | - 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
| 216 | - 'STS_ID', |
|
| 217 | - __('Status', 'event_espresso'), |
|
| 218 | - false, |
|
| 219 | - self::status_incomplete, |
|
| 220 | - 'Status' |
|
| 221 | - ), |
|
| 222 | - 'MSG_created' => new EE_Datetime_Field( |
|
| 223 | - 'MSG_created', |
|
| 224 | - __('Created', 'event_espresso'), |
|
| 225 | - false, |
|
| 226 | - EE_Datetime_Field::now |
|
| 227 | - ), |
|
| 228 | - 'MSG_modified' => new EE_Datetime_Field( |
|
| 229 | - 'MSG_modified', |
|
| 230 | - __('Modified', 'event_espresso'), |
|
| 231 | - true, |
|
| 232 | - EE_Datetime_Field::now |
|
| 233 | - ), |
|
| 234 | - ), |
|
| 235 | - ); |
|
| 236 | - $this->_model_relations = array( |
|
| 237 | - 'Attendee' => new EE_Belongs_To_Any_Relation(), |
|
| 238 | - 'Registration' => new EE_Belongs_To_Any_Relation(), |
|
| 239 | - 'WP_User' => new EE_Belongs_To_Any_Relation(), |
|
| 240 | - 'Message_Template_Group' => new EE_Belongs_To_Relation(), |
|
| 241 | - 'Transaction' => new EE_Belongs_To_Relation(), |
|
| 242 | - ); |
|
| 243 | - parent::__construct($timezone); |
|
| 244 | - } |
|
| 245 | - |
|
| 246 | - |
|
| 247 | - /** |
|
| 248 | - * @return \EE_Message |
|
| 249 | - */ |
|
| 250 | - public function create_default_object() |
|
| 251 | - { |
|
| 252 | - /** @type EE_Message $message */ |
|
| 253 | - $message = parent::create_default_object(); |
|
| 254 | - if ($message instanceof EE_Message) { |
|
| 255 | - return EE_Message_Factory::set_messenger_and_message_type($message); |
|
| 256 | - } |
|
| 257 | - return null; |
|
| 258 | - } |
|
| 259 | - |
|
| 260 | - |
|
| 261 | - /** |
|
| 262 | - * @param mixed $cols_n_values |
|
| 263 | - * @return \EE_Message |
|
| 264 | - */ |
|
| 265 | - public function instantiate_class_from_array_or_object($cols_n_values) |
|
| 266 | - { |
|
| 267 | - /** @type EE_Message $message */ |
|
| 268 | - $message = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
| 269 | - if ($message instanceof EE_Message) { |
|
| 270 | - return EE_Message_Factory::set_messenger_and_message_type($message); |
|
| 271 | - } |
|
| 272 | - return null; |
|
| 273 | - } |
|
| 274 | - |
|
| 275 | - |
|
| 276 | - /** |
|
| 277 | - * Returns whether or not a message of that type was sent for a given attendee. |
|
| 278 | - * |
|
| 279 | - * @param EE_Attendee|int $attendee |
|
| 280 | - * @param string $message_type the message type slug |
|
| 281 | - * @return boolean |
|
| 282 | - */ |
|
| 283 | - public function message_sent_for_attendee($attendee, $message_type) |
|
| 284 | - { |
|
| 285 | - $attendee_ID = EEM_Attendee::instance()->ensure_is_ID($attendee); |
|
| 286 | - return $this->exists(array( |
|
| 287 | - array( |
|
| 288 | - 'Attendee.ATT_ID' => $attendee_ID, |
|
| 289 | - 'MSG_message_type' => $message_type, |
|
| 290 | - 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
| 291 | - ), |
|
| 292 | - )); |
|
| 293 | - } |
|
| 294 | - |
|
| 295 | - |
|
| 296 | - /** |
|
| 297 | - * Returns whether or not a message of that type was sent for a given registration |
|
| 298 | - * |
|
| 299 | - * @param EE_Registration|int $registration |
|
| 300 | - * @param string $message_type the message type slug |
|
| 301 | - * @return boolean |
|
| 302 | - */ |
|
| 303 | - public function message_sent_for_registration($registration, $message_type) |
|
| 304 | - { |
|
| 305 | - $registrationID = EEM_Registration::instance()->ensure_is_ID($registration); |
|
| 306 | - return $this->exists(array( |
|
| 307 | - array( |
|
| 308 | - 'Registration.REG_ID' => $registrationID, |
|
| 309 | - 'MSG_message_type' => $message_type, |
|
| 310 | - 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
| 311 | - ), |
|
| 312 | - )); |
|
| 313 | - } |
|
| 314 | - |
|
| 315 | - |
|
| 316 | - /** |
|
| 317 | - * This retrieves an EE_Message object from the db matching the given token string. |
|
| 318 | - * |
|
| 319 | - * @param string $token |
|
| 320 | - * @return EE_Message |
|
| 321 | - */ |
|
| 322 | - public function get_one_by_token($token) |
|
| 323 | - { |
|
| 324 | - return $this->get_one(array( |
|
| 325 | - array( |
|
| 326 | - 'MSG_token' => $token, |
|
| 327 | - ), |
|
| 328 | - )); |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - |
|
| 332 | - /** |
|
| 333 | - * Returns stati that indicate the message HAS been sent |
|
| 334 | - * |
|
| 335 | - * @return array of strings for possible stati |
|
| 336 | - */ |
|
| 337 | - public function stati_indicating_sent() |
|
| 338 | - { |
|
| 339 | - return apply_filters('FHEE__EEM_Message__stati_indicating_sent', array(self::status_sent)); |
|
| 340 | - } |
|
| 341 | - |
|
| 342 | - |
|
| 343 | - /** |
|
| 344 | - * Returns stati that indicate the message is waiting to be sent. |
|
| 345 | - * |
|
| 346 | - * @return array of strings for possible stati. |
|
| 347 | - */ |
|
| 348 | - public function stati_indicating_to_send() |
|
| 349 | - { |
|
| 350 | - return apply_filters( |
|
| 351 | - 'FHEE__EEM_Message__stati_indicating_to_send', |
|
| 352 | - array(self::status_idle, self::status_resend) |
|
| 353 | - ); |
|
| 354 | - } |
|
| 355 | - |
|
| 356 | - |
|
| 357 | - /** |
|
| 358 | - * Returns stati that indicate the message has failed sending |
|
| 359 | - * |
|
| 360 | - * @return array array of strings for possible stati. |
|
| 361 | - */ |
|
| 362 | - public function stati_indicating_failed_sending() |
|
| 363 | - { |
|
| 364 | - $failed_stati = array( |
|
| 365 | - self::status_failed, |
|
| 366 | - self::status_retry, |
|
| 367 | - self::status_messenger_executing, |
|
| 368 | - ); |
|
| 369 | - // if WP_DEBUG is set, then let's include debug_only fails |
|
| 370 | - if (WP_DEBUG) { |
|
| 371 | - $failed_stati[] = self::status_debug_only; |
|
| 372 | - } |
|
| 373 | - return apply_filters('FHEE__EEM_Message__stati_indicating_failed_sending', $failed_stati); |
|
| 374 | - } |
|
| 375 | - |
|
| 376 | - |
|
| 377 | - /** |
|
| 378 | - * Returns filterable array of all EEM_Message statuses. |
|
| 379 | - * |
|
| 380 | - * @return array |
|
| 381 | - */ |
|
| 382 | - public function all_statuses() |
|
| 383 | - { |
|
| 384 | - return apply_filters( |
|
| 385 | - 'FHEE__EEM_Message__all_statuses', |
|
| 386 | - array( |
|
| 387 | - EEM_Message::status_sent, |
|
| 388 | - EEM_Message::status_incomplete, |
|
| 389 | - EEM_Message::status_idle, |
|
| 390 | - EEM_Message::status_resend, |
|
| 391 | - EEM_Message::status_retry, |
|
| 392 | - EEM_Message::status_failed, |
|
| 393 | - EEM_Message::status_messenger_executing, |
|
| 394 | - EEM_Message::status_debug_only, |
|
| 395 | - ) |
|
| 396 | - ); |
|
| 397 | - } |
|
| 398 | - |
|
| 399 | - /** |
|
| 400 | - * Detects any specific query variables in the request and uses those to setup appropriate |
|
| 401 | - * filter for any queries. |
|
| 402 | - * |
|
| 403 | - * @return array |
|
| 404 | - */ |
|
| 405 | - public function filter_by_query_params() |
|
| 406 | - { |
|
| 407 | - // expected possible query_vars, the key in this array matches an expected key in the request, |
|
| 408 | - // the value, matches the corresponding EEM_Base child reference. |
|
| 409 | - $expected_vars = $this->_expected_vars_for_query_inject(); |
|
| 410 | - $query_params[0] = array(); |
|
| 411 | - foreach ($expected_vars as $request_key => $model_name) { |
|
| 412 | - $request_value = EE_Registry::instance()->REQ->get($request_key); |
|
| 413 | - if ($request_value) { |
|
| 414 | - // special case |
|
| 415 | - switch ($request_key) { |
|
| 416 | - case '_REG_ID': |
|
| 417 | - $query_params[0]['AND**filter_by']['OR**filter_by_REG_ID'] = array( |
|
| 418 | - 'Transaction.Registration.REG_ID' => $request_value, |
|
| 419 | - ); |
|
| 420 | - break; |
|
| 421 | - case 'EVT_ID': |
|
| 422 | - $query_params[0]['AND**filter_by']['OR**filter_by_EVT_ID'] = array( |
|
| 423 | - 'Transaction.Registration.EVT_ID' => $request_value, |
|
| 424 | - ); |
|
| 425 | - break; |
|
| 426 | - default: |
|
| 427 | - $query_params[0]['AND**filter_by'][ 'OR**filter_by_' . $request_key ][ $model_name . '.' . $request_key ] = $request_value; |
|
| 428 | - break; |
|
| 429 | - } |
|
| 430 | - } |
|
| 431 | - } |
|
| 432 | - return $query_params; |
|
| 433 | - } |
|
| 434 | - |
|
| 435 | - |
|
| 436 | - /** |
|
| 437 | - * @return string |
|
| 438 | - */ |
|
| 439 | - public function get_pretty_label_for_results() |
|
| 440 | - { |
|
| 441 | - $expected_vars = $this->_expected_vars_for_query_inject(); |
|
| 442 | - $pretty_label = ''; |
|
| 443 | - $label_parts = array(); |
|
| 444 | - foreach ($expected_vars as $request_key => $model_name) { |
|
| 445 | - $model = EE_Registry::instance()->load_model($model_name); |
|
| 446 | - if ($model_field_value = EE_Registry::instance()->REQ->get($request_key)) { |
|
| 447 | - switch ($request_key) { |
|
| 448 | - case '_REG_ID': |
|
| 449 | - $label_parts[] = sprintf( |
|
| 450 | - esc_html__('Registration with the ID: %s', 'event_espresso'), |
|
| 451 | - $model_field_value |
|
| 452 | - ); |
|
| 453 | - break; |
|
| 454 | - case 'ATT_ID': |
|
| 455 | - /** @var EE_Attendee $attendee */ |
|
| 456 | - $attendee = $model->get_one_by_ID($model_field_value); |
|
| 457 | - $label_parts[] = $attendee instanceof EE_Attendee |
|
| 458 | - ? sprintf(esc_html__('Attendee %s', 'event_espresso'), $attendee->full_name()) |
|
| 459 | - : sprintf(esc_html__('Attendee ID: %s', 'event_espresso'), $model_field_value); |
|
| 460 | - break; |
|
| 461 | - case 'ID': |
|
| 462 | - /** @var EE_WP_User $wpUser */ |
|
| 463 | - $wpUser = $model->get_one_by_ID($model_field_value); |
|
| 464 | - $label_parts[] = $wpUser instanceof EE_WP_User |
|
| 465 | - ? sprintf(esc_html__('WP User: %s', 'event_espresso'), $wpUser->name()) |
|
| 466 | - : sprintf(esc_html__('WP User ID: %s', 'event_espresso'), $model_field_value); |
|
| 467 | - break; |
|
| 468 | - case 'TXN_ID': |
|
| 469 | - $label_parts[] = sprintf( |
|
| 470 | - esc_html__('Transaction with the ID: %s', 'event_espresso'), |
|
| 471 | - $model_field_value |
|
| 472 | - ); |
|
| 473 | - break; |
|
| 474 | - case 'EVT_ID': |
|
| 475 | - /** @var EE_Event $Event */ |
|
| 476 | - $Event = $model->get_one_by_ID($model_field_value); |
|
| 477 | - $label_parts[] = $Event instanceof EE_Event |
|
| 478 | - ? sprintf(esc_html__('for the Event: %s', 'event_espresso'), $Event->name()) |
|
| 479 | - : sprintf(esc_html__('for the Event with ID: %s', 'event_espresso'), $model_field_value); |
|
| 480 | - break; |
|
| 481 | - } |
|
| 482 | - } |
|
| 483 | - } |
|
| 484 | - |
|
| 485 | - if ($label_parts) { |
|
| 486 | - // prepend to the last element of $label_parts an "and". |
|
| 487 | - if (count($label_parts) > 1) { |
|
| 488 | - $label_parts_index_to_prepend = count($label_parts) - 1; |
|
| 489 | - $label_parts[ $label_parts_index_to_prepend ] = 'and' . $label_parts[ $label_parts_index_to_prepend ]; |
|
| 490 | - } |
|
| 491 | - |
|
| 492 | - $pretty_label .= sprintf( |
|
| 493 | - esc_html_x( |
|
| 494 | - 'Showing messages for %s', |
|
| 495 | - 'A label for the messages returned in a query that are filtered by items in the query. This could be Transaction, Event, Attendee, Registration, or WP_User.', |
|
| 496 | - 'event_espresso' |
|
| 497 | - ), |
|
| 498 | - implode(', ', $label_parts) |
|
| 499 | - ); |
|
| 500 | - } |
|
| 501 | - return $pretty_label; |
|
| 502 | - } |
|
| 503 | - |
|
| 504 | - |
|
| 505 | - /** |
|
| 506 | - * This returns the array of expected variables for the EEI_Query_Filter methods being implemented |
|
| 507 | - * The array is in the format: |
|
| 508 | - * array( |
|
| 509 | - * {$field_name} => {$model_name} |
|
| 510 | - * ); |
|
| 511 | - * |
|
| 512 | - * @since 4.9.0 |
|
| 513 | - * @return array |
|
| 514 | - */ |
|
| 515 | - protected function _expected_vars_for_query_inject() |
|
| 516 | - { |
|
| 517 | - return array( |
|
| 518 | - '_REG_ID' => 'Registration', |
|
| 519 | - 'ATT_ID' => 'Attendee', |
|
| 520 | - 'ID' => 'WP_User', |
|
| 521 | - 'TXN_ID' => 'Transaction', |
|
| 522 | - 'EVT_ID' => 'Event', |
|
| 523 | - ); |
|
| 524 | - } |
|
| 525 | - |
|
| 526 | - |
|
| 527 | - /** |
|
| 528 | - * This returns whether EEM_Message is in debug mode or not. |
|
| 529 | - * Currently "debug mode" is used to control the handling of the EEM_Message::debug_only status when |
|
| 530 | - * generating/sending messages. Debug mode can be set by either: |
|
| 531 | - * 1. Sending in a value for the $set_debug argument |
|
| 532 | - * 2. Defining `EE_DEBUG_MESSAGES` constant in wp-config.php |
|
| 533 | - * 3. Overriding the above via the provided filter. |
|
| 534 | - * |
|
| 535 | - * @param bool|null $set_debug If provided, then the debug mode will be set internally until reset via the |
|
| 536 | - * provided boolean. When no argument is provided (default null) then the debug |
|
| 537 | - * mode will be returned. |
|
| 538 | - * @return bool true means Messages is in debug mode. false means messages system is not in debug mode. |
|
| 539 | - */ |
|
| 540 | - public static function debug($set_debug = null) |
|
| 541 | - { |
|
| 542 | - static $is_debugging = null; |
|
| 543 | - |
|
| 544 | - // initialize (use constant if set). |
|
| 545 | - if (is_null($set_debug) && is_null($is_debugging)) { |
|
| 546 | - $is_debugging = defined('EE_DEBUG_MESSAGES') && EE_DEBUG_MESSAGES; |
|
| 547 | - } |
|
| 548 | - |
|
| 549 | - if (! is_null($set_debug)) { |
|
| 550 | - $is_debugging = filter_var($set_debug, FILTER_VALIDATE_BOOLEAN); |
|
| 551 | - } |
|
| 552 | - |
|
| 553 | - // return filtered value |
|
| 554 | - return apply_filters('FHEE__EEM_Message__debug', $is_debugging); |
|
| 555 | - } |
|
| 556 | - |
|
| 557 | - |
|
| 558 | - /** |
|
| 559 | - * Deletes old messages meeting certain criteria for removal from the database. |
|
| 560 | - * By default, this will delete messages that: |
|
| 561 | - * - are older than the value of the delete_threshold in months. |
|
| 562 | - * - have a STS_ID other than EEM_Message::status_idle |
|
| 563 | - * |
|
| 564 | - * @param int $delete_threshold This integer will be used to set the boundary for what messages are deleted in months. |
|
| 565 | - * @return bool|false|int Either the number of records affected or false if there was an error (you can call |
|
| 566 | - * $wpdb->last_error to find out what the error was. |
|
| 567 | - */ |
|
| 568 | - public function delete_old_messages($delete_threshold = 6) |
|
| 569 | - { |
|
| 570 | - $number_deleted = 0; |
|
| 571 | - /** |
|
| 572 | - * Allows code to change the boundary for what messages are kept. |
|
| 573 | - * Uses the value of the `delete_threshold` variable by default. |
|
| 574 | - * |
|
| 575 | - * @param int $seconds seconds that will be subtracted from the timestamp for now. |
|
| 576 | - * @return int |
|
| 577 | - */ |
|
| 578 | - $time_to_leave_alone = absint( |
|
| 579 | - apply_filters( |
|
| 580 | - 'FHEE__EEM_Message__delete_old_messages__time_to_leave_alone', |
|
| 581 | - ((int) $delete_threshold) * MONTH_IN_SECONDS |
|
| 582 | - ) |
|
| 583 | - ); |
|
| 584 | - |
|
| 585 | - |
|
| 586 | - /** |
|
| 587 | - * Allows code to change what message stati are ignored when deleting. |
|
| 588 | - * Defaults to only ignore EEM_Message::status_idle messages. |
|
| 589 | - * |
|
| 590 | - * @param string $message_stati_to_keep An array of message statuses that will be ignored when deleting. |
|
| 591 | - */ |
|
| 592 | - $message_stati_to_keep = (array) apply_filters( |
|
| 593 | - 'FHEE__EEM_Message__delete_old_messages__message_stati_to_keep', |
|
| 594 | - array( |
|
| 595 | - EEM_Message::status_idle |
|
| 596 | - ) |
|
| 597 | - ); |
|
| 598 | - |
|
| 599 | - // first get all the ids of messages being deleted |
|
| 600 | - $message_ids_to_delete = EEM_Message::instance()->get_col( |
|
| 601 | - array( |
|
| 602 | - 0 => array( |
|
| 603 | - 'STS_ID' => array('NOT_IN', $message_stati_to_keep), |
|
| 604 | - 'MSG_modified' => array('<', time() - $time_to_leave_alone) |
|
| 605 | - ), |
|
| 606 | - 'limit' => apply_filters( |
|
| 607 | - 'EEM_Message__delete_old_messages__limit', |
|
| 608 | - 2000, |
|
| 609 | - $delete_threshold |
|
| 610 | - ) |
|
| 611 | - ) |
|
| 612 | - ); |
|
| 613 | - |
|
| 614 | - if (! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) { |
|
| 615 | - global $wpdb; |
|
| 616 | - $number_deleted = $wpdb->query(' |
|
| 16 | + /** |
|
| 17 | + * This priority indicates a message should be generated and sent ASAP |
|
| 18 | + * |
|
| 19 | + * @type int |
|
| 20 | + */ |
|
| 21 | + const priority_high = 10; |
|
| 22 | + |
|
| 23 | + |
|
| 24 | + /** |
|
| 25 | + * This priority indicates a message should be generated ASAP and queued for sending. |
|
| 26 | + * |
|
| 27 | + * @type |
|
| 28 | + */ |
|
| 29 | + const priority_medium = 20; |
|
| 30 | + |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * This priority indicates a message should be queued for generating. |
|
| 34 | + * |
|
| 35 | + * @type int |
|
| 36 | + */ |
|
| 37 | + const priority_low = 30; |
|
| 38 | + |
|
| 39 | + |
|
| 40 | + /** |
|
| 41 | + * indicates this message was sent at the time modified |
|
| 42 | + */ |
|
| 43 | + const status_sent = 'MSN'; |
|
| 44 | + |
|
| 45 | + |
|
| 46 | + /** |
|
| 47 | + * indicates this message is waiting to be sent |
|
| 48 | + */ |
|
| 49 | + const status_idle = 'MID'; |
|
| 50 | + |
|
| 51 | + |
|
| 52 | + /** |
|
| 53 | + * indicates an attempt was a made to send this message |
|
| 54 | + * at the scheduled time, but it failed at the time modified. This differs from MDO status in that it will ALWAYS |
|
| 55 | + * appear to the end user. |
|
| 56 | + */ |
|
| 57 | + const status_failed = 'MFL'; |
|
| 58 | + |
|
| 59 | + |
|
| 60 | + /** |
|
| 61 | + * indicates the message has been flagged for resending (at the time modified). |
|
| 62 | + */ |
|
| 63 | + const status_resend = 'MRS'; |
|
| 64 | + |
|
| 65 | + |
|
| 66 | + /** |
|
| 67 | + * indicates the message has been flagged for generation but has not been generated yet. Messages always start as |
|
| 68 | + * this status when added to the queue. |
|
| 69 | + */ |
|
| 70 | + const status_incomplete = 'MIC'; |
|
| 71 | + |
|
| 72 | + |
|
| 73 | + /** |
|
| 74 | + * Indicates everything was generated fine for the message, however, the messenger was unable to send. |
|
| 75 | + * This status means that its possible to retry sending the message. |
|
| 76 | + */ |
|
| 77 | + const status_retry = 'MRT'; |
|
| 78 | + |
|
| 79 | + |
|
| 80 | + /** |
|
| 81 | + * This is used for more informational messages that may not indicate anything is broken but still cannot be |
|
| 82 | + * generated or sent correctly. An example of a message that would get flagged this way would be when a not |
|
| 83 | + * approved message was queued for generation, but at time of generation, the attached registration(s) are |
|
| 84 | + * approved. So the message queued for generation is no longer valid. Messages for this status will only persist |
|
| 85 | + * in the db and be viewable in the message activity list table when the messages system is in debug mode. |
|
| 86 | + * |
|
| 87 | + * @see EEM_Message::debug() |
|
| 88 | + */ |
|
| 89 | + const status_debug_only = 'MDO'; |
|
| 90 | + |
|
| 91 | + |
|
| 92 | + /** |
|
| 93 | + * This status is given to messages it is processed by the messenger send method. |
|
| 94 | + * Messages with this status should rarely be seen in the Message List table, but if they are, that's usually |
|
| 95 | + * indicative of a PHP timeout or memory limit issue. |
|
| 96 | + */ |
|
| 97 | + const status_messenger_executing = 'MEX'; |
|
| 98 | + |
|
| 99 | + |
|
| 100 | + /** |
|
| 101 | + * Private constructor to prevent direct creation. |
|
| 102 | + * |
|
| 103 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and |
|
| 104 | + * any incoming timezone data that gets saved). Note this just sends the timezone info to |
|
| 105 | + * the date time model field objects. Default is null (and will be assumed using the set |
|
| 106 | + * timezone in the 'timezone_string' wp option) |
|
| 107 | + * @return EEM_Message |
|
| 108 | + */ |
|
| 109 | + protected function __construct($timezone = null) |
|
| 110 | + { |
|
| 111 | + $this->singular_item = __('Message', 'event_espresso'); |
|
| 112 | + $this->plural_item = __('Messages', 'event_espresso'); |
|
| 113 | + |
|
| 114 | + // used for token generator |
|
| 115 | + EE_Registry::instance()->load_helper('URL'); |
|
| 116 | + |
|
| 117 | + $this->_tables = array( |
|
| 118 | + 'Message' => new EE_Primary_Table('esp_message', 'MSG_ID'), |
|
| 119 | + ); |
|
| 120 | + |
|
| 121 | + $allowed_priority = array( |
|
| 122 | + self::priority_high => __('high', 'event_espresso'), |
|
| 123 | + self::priority_medium => __('medium', 'event_espresso'), |
|
| 124 | + self::priority_low => __('low', 'event_espresso'), |
|
| 125 | + ); |
|
| 126 | + |
|
| 127 | + $this->_fields = array( |
|
| 128 | + 'Message' => array( |
|
| 129 | + 'MSG_ID' => new EE_Primary_Key_Int_Field('MSG_ID', __('Message ID', 'event_espresso')), |
|
| 130 | + 'MSG_token' => new EE_Plain_Text_Field( |
|
| 131 | + 'MSG_token', |
|
| 132 | + __( |
|
| 133 | + 'Unique Token used to represent this row in publicly viewable contexts (eg. a url).', |
|
| 134 | + 'event_espresso' |
|
| 135 | + ), |
|
| 136 | + false, |
|
| 137 | + EEH_URL::generate_unique_token() |
|
| 138 | + ), |
|
| 139 | + 'GRP_ID' => new EE_Foreign_Key_Int_Field( |
|
| 140 | + 'GRP_ID', |
|
| 141 | + __('Foreign key to the EEM_Message_Template_Group table.', 'event_espresso'), |
|
| 142 | + true, |
|
| 143 | + 0, |
|
| 144 | + 'Message_Template_Group' |
|
| 145 | + ), |
|
| 146 | + 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
| 147 | + 'TXN_ID', |
|
| 148 | + __( |
|
| 149 | + 'Foreign key to the related EE_Transaction. This is required to give context for regenerating the specific message', |
|
| 150 | + 'event_espresso' |
|
| 151 | + ), |
|
| 152 | + true, |
|
| 153 | + 0, |
|
| 154 | + 'Transaction' |
|
| 155 | + ), |
|
| 156 | + 'MSG_messenger' => new EE_Plain_Text_Field( |
|
| 157 | + 'MSG_messenger', |
|
| 158 | + __( |
|
| 159 | + 'Corresponds to the EE_messenger::name used to send this message. This will also be used to attempt any resending of the message.', |
|
| 160 | + 'event_espresso' |
|
| 161 | + ), |
|
| 162 | + false, |
|
| 163 | + 'email' |
|
| 164 | + ), |
|
| 165 | + 'MSG_message_type' => new EE_Plain_Text_Field( |
|
| 166 | + 'MSG_message_type', |
|
| 167 | + __('Corresponds to the EE_message_type::name used to generate this message.', 'event_espresso'), |
|
| 168 | + false, |
|
| 169 | + 'receipt' |
|
| 170 | + ), |
|
| 171 | + 'MSG_context' => new EE_Plain_Text_Field('MSG_context', __('Context', 'event_espresso'), false), |
|
| 172 | + 'MSG_recipient_ID' => new EE_Foreign_Key_Int_Field( |
|
| 173 | + 'MSG_recipient_ID', |
|
| 174 | + __('Recipient ID', 'event_espresso'), |
|
| 175 | + true, |
|
| 176 | + null, |
|
| 177 | + array('Registration', 'Attendee', 'WP_User') |
|
| 178 | + ), |
|
| 179 | + 'MSG_recipient_type' => new EE_Any_Foreign_Model_Name_Field( |
|
| 180 | + 'MSG_recipient_type', |
|
| 181 | + __('Recipient Type', 'event_espresso'), |
|
| 182 | + true, |
|
| 183 | + null, |
|
| 184 | + array('Registration', 'Attendee', 'WP_User') |
|
| 185 | + ), |
|
| 186 | + 'MSG_content' => new EE_Maybe_Serialized_Text_Field( |
|
| 187 | + 'MSG_content', |
|
| 188 | + __('Content', 'event_espresso'), |
|
| 189 | + true, |
|
| 190 | + '' |
|
| 191 | + ), |
|
| 192 | + 'MSG_to' => new EE_Maybe_Serialized_Text_Field( |
|
| 193 | + 'MSG_to', |
|
| 194 | + __('Address To', 'event_espresso'), |
|
| 195 | + true |
|
| 196 | + ), |
|
| 197 | + 'MSG_from' => new EE_Maybe_Serialized_Text_Field( |
|
| 198 | + 'MSG_from', |
|
| 199 | + __('Address From', 'event_espresso'), |
|
| 200 | + true |
|
| 201 | + ), |
|
| 202 | + 'MSG_subject' => new EE_Maybe_Serialized_Text_Field( |
|
| 203 | + 'MSG_subject', |
|
| 204 | + __('Subject', 'event_espresso'), |
|
| 205 | + true, |
|
| 206 | + '' |
|
| 207 | + ), |
|
| 208 | + 'MSG_priority' => new EE_Enum_Integer_Field( |
|
| 209 | + 'MSG_priority', |
|
| 210 | + __('Priority', 'event_espresso'), |
|
| 211 | + false, |
|
| 212 | + self::priority_low, |
|
| 213 | + $allowed_priority |
|
| 214 | + ), |
|
| 215 | + 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
| 216 | + 'STS_ID', |
|
| 217 | + __('Status', 'event_espresso'), |
|
| 218 | + false, |
|
| 219 | + self::status_incomplete, |
|
| 220 | + 'Status' |
|
| 221 | + ), |
|
| 222 | + 'MSG_created' => new EE_Datetime_Field( |
|
| 223 | + 'MSG_created', |
|
| 224 | + __('Created', 'event_espresso'), |
|
| 225 | + false, |
|
| 226 | + EE_Datetime_Field::now |
|
| 227 | + ), |
|
| 228 | + 'MSG_modified' => new EE_Datetime_Field( |
|
| 229 | + 'MSG_modified', |
|
| 230 | + __('Modified', 'event_espresso'), |
|
| 231 | + true, |
|
| 232 | + EE_Datetime_Field::now |
|
| 233 | + ), |
|
| 234 | + ), |
|
| 235 | + ); |
|
| 236 | + $this->_model_relations = array( |
|
| 237 | + 'Attendee' => new EE_Belongs_To_Any_Relation(), |
|
| 238 | + 'Registration' => new EE_Belongs_To_Any_Relation(), |
|
| 239 | + 'WP_User' => new EE_Belongs_To_Any_Relation(), |
|
| 240 | + 'Message_Template_Group' => new EE_Belongs_To_Relation(), |
|
| 241 | + 'Transaction' => new EE_Belongs_To_Relation(), |
|
| 242 | + ); |
|
| 243 | + parent::__construct($timezone); |
|
| 244 | + } |
|
| 245 | + |
|
| 246 | + |
|
| 247 | + /** |
|
| 248 | + * @return \EE_Message |
|
| 249 | + */ |
|
| 250 | + public function create_default_object() |
|
| 251 | + { |
|
| 252 | + /** @type EE_Message $message */ |
|
| 253 | + $message = parent::create_default_object(); |
|
| 254 | + if ($message instanceof EE_Message) { |
|
| 255 | + return EE_Message_Factory::set_messenger_and_message_type($message); |
|
| 256 | + } |
|
| 257 | + return null; |
|
| 258 | + } |
|
| 259 | + |
|
| 260 | + |
|
| 261 | + /** |
|
| 262 | + * @param mixed $cols_n_values |
|
| 263 | + * @return \EE_Message |
|
| 264 | + */ |
|
| 265 | + public function instantiate_class_from_array_or_object($cols_n_values) |
|
| 266 | + { |
|
| 267 | + /** @type EE_Message $message */ |
|
| 268 | + $message = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
| 269 | + if ($message instanceof EE_Message) { |
|
| 270 | + return EE_Message_Factory::set_messenger_and_message_type($message); |
|
| 271 | + } |
|
| 272 | + return null; |
|
| 273 | + } |
|
| 274 | + |
|
| 275 | + |
|
| 276 | + /** |
|
| 277 | + * Returns whether or not a message of that type was sent for a given attendee. |
|
| 278 | + * |
|
| 279 | + * @param EE_Attendee|int $attendee |
|
| 280 | + * @param string $message_type the message type slug |
|
| 281 | + * @return boolean |
|
| 282 | + */ |
|
| 283 | + public function message_sent_for_attendee($attendee, $message_type) |
|
| 284 | + { |
|
| 285 | + $attendee_ID = EEM_Attendee::instance()->ensure_is_ID($attendee); |
|
| 286 | + return $this->exists(array( |
|
| 287 | + array( |
|
| 288 | + 'Attendee.ATT_ID' => $attendee_ID, |
|
| 289 | + 'MSG_message_type' => $message_type, |
|
| 290 | + 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
| 291 | + ), |
|
| 292 | + )); |
|
| 293 | + } |
|
| 294 | + |
|
| 295 | + |
|
| 296 | + /** |
|
| 297 | + * Returns whether or not a message of that type was sent for a given registration |
|
| 298 | + * |
|
| 299 | + * @param EE_Registration|int $registration |
|
| 300 | + * @param string $message_type the message type slug |
|
| 301 | + * @return boolean |
|
| 302 | + */ |
|
| 303 | + public function message_sent_for_registration($registration, $message_type) |
|
| 304 | + { |
|
| 305 | + $registrationID = EEM_Registration::instance()->ensure_is_ID($registration); |
|
| 306 | + return $this->exists(array( |
|
| 307 | + array( |
|
| 308 | + 'Registration.REG_ID' => $registrationID, |
|
| 309 | + 'MSG_message_type' => $message_type, |
|
| 310 | + 'STS_ID' => array('IN', $this->stati_indicating_sent()), |
|
| 311 | + ), |
|
| 312 | + )); |
|
| 313 | + } |
|
| 314 | + |
|
| 315 | + |
|
| 316 | + /** |
|
| 317 | + * This retrieves an EE_Message object from the db matching the given token string. |
|
| 318 | + * |
|
| 319 | + * @param string $token |
|
| 320 | + * @return EE_Message |
|
| 321 | + */ |
|
| 322 | + public function get_one_by_token($token) |
|
| 323 | + { |
|
| 324 | + return $this->get_one(array( |
|
| 325 | + array( |
|
| 326 | + 'MSG_token' => $token, |
|
| 327 | + ), |
|
| 328 | + )); |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + |
|
| 332 | + /** |
|
| 333 | + * Returns stati that indicate the message HAS been sent |
|
| 334 | + * |
|
| 335 | + * @return array of strings for possible stati |
|
| 336 | + */ |
|
| 337 | + public function stati_indicating_sent() |
|
| 338 | + { |
|
| 339 | + return apply_filters('FHEE__EEM_Message__stati_indicating_sent', array(self::status_sent)); |
|
| 340 | + } |
|
| 341 | + |
|
| 342 | + |
|
| 343 | + /** |
|
| 344 | + * Returns stati that indicate the message is waiting to be sent. |
|
| 345 | + * |
|
| 346 | + * @return array of strings for possible stati. |
|
| 347 | + */ |
|
| 348 | + public function stati_indicating_to_send() |
|
| 349 | + { |
|
| 350 | + return apply_filters( |
|
| 351 | + 'FHEE__EEM_Message__stati_indicating_to_send', |
|
| 352 | + array(self::status_idle, self::status_resend) |
|
| 353 | + ); |
|
| 354 | + } |
|
| 355 | + |
|
| 356 | + |
|
| 357 | + /** |
|
| 358 | + * Returns stati that indicate the message has failed sending |
|
| 359 | + * |
|
| 360 | + * @return array array of strings for possible stati. |
|
| 361 | + */ |
|
| 362 | + public function stati_indicating_failed_sending() |
|
| 363 | + { |
|
| 364 | + $failed_stati = array( |
|
| 365 | + self::status_failed, |
|
| 366 | + self::status_retry, |
|
| 367 | + self::status_messenger_executing, |
|
| 368 | + ); |
|
| 369 | + // if WP_DEBUG is set, then let's include debug_only fails |
|
| 370 | + if (WP_DEBUG) { |
|
| 371 | + $failed_stati[] = self::status_debug_only; |
|
| 372 | + } |
|
| 373 | + return apply_filters('FHEE__EEM_Message__stati_indicating_failed_sending', $failed_stati); |
|
| 374 | + } |
|
| 375 | + |
|
| 376 | + |
|
| 377 | + /** |
|
| 378 | + * Returns filterable array of all EEM_Message statuses. |
|
| 379 | + * |
|
| 380 | + * @return array |
|
| 381 | + */ |
|
| 382 | + public function all_statuses() |
|
| 383 | + { |
|
| 384 | + return apply_filters( |
|
| 385 | + 'FHEE__EEM_Message__all_statuses', |
|
| 386 | + array( |
|
| 387 | + EEM_Message::status_sent, |
|
| 388 | + EEM_Message::status_incomplete, |
|
| 389 | + EEM_Message::status_idle, |
|
| 390 | + EEM_Message::status_resend, |
|
| 391 | + EEM_Message::status_retry, |
|
| 392 | + EEM_Message::status_failed, |
|
| 393 | + EEM_Message::status_messenger_executing, |
|
| 394 | + EEM_Message::status_debug_only, |
|
| 395 | + ) |
|
| 396 | + ); |
|
| 397 | + } |
|
| 398 | + |
|
| 399 | + /** |
|
| 400 | + * Detects any specific query variables in the request and uses those to setup appropriate |
|
| 401 | + * filter for any queries. |
|
| 402 | + * |
|
| 403 | + * @return array |
|
| 404 | + */ |
|
| 405 | + public function filter_by_query_params() |
|
| 406 | + { |
|
| 407 | + // expected possible query_vars, the key in this array matches an expected key in the request, |
|
| 408 | + // the value, matches the corresponding EEM_Base child reference. |
|
| 409 | + $expected_vars = $this->_expected_vars_for_query_inject(); |
|
| 410 | + $query_params[0] = array(); |
|
| 411 | + foreach ($expected_vars as $request_key => $model_name) { |
|
| 412 | + $request_value = EE_Registry::instance()->REQ->get($request_key); |
|
| 413 | + if ($request_value) { |
|
| 414 | + // special case |
|
| 415 | + switch ($request_key) { |
|
| 416 | + case '_REG_ID': |
|
| 417 | + $query_params[0]['AND**filter_by']['OR**filter_by_REG_ID'] = array( |
|
| 418 | + 'Transaction.Registration.REG_ID' => $request_value, |
|
| 419 | + ); |
|
| 420 | + break; |
|
| 421 | + case 'EVT_ID': |
|
| 422 | + $query_params[0]['AND**filter_by']['OR**filter_by_EVT_ID'] = array( |
|
| 423 | + 'Transaction.Registration.EVT_ID' => $request_value, |
|
| 424 | + ); |
|
| 425 | + break; |
|
| 426 | + default: |
|
| 427 | + $query_params[0]['AND**filter_by'][ 'OR**filter_by_' . $request_key ][ $model_name . '.' . $request_key ] = $request_value; |
|
| 428 | + break; |
|
| 429 | + } |
|
| 430 | + } |
|
| 431 | + } |
|
| 432 | + return $query_params; |
|
| 433 | + } |
|
| 434 | + |
|
| 435 | + |
|
| 436 | + /** |
|
| 437 | + * @return string |
|
| 438 | + */ |
|
| 439 | + public function get_pretty_label_for_results() |
|
| 440 | + { |
|
| 441 | + $expected_vars = $this->_expected_vars_for_query_inject(); |
|
| 442 | + $pretty_label = ''; |
|
| 443 | + $label_parts = array(); |
|
| 444 | + foreach ($expected_vars as $request_key => $model_name) { |
|
| 445 | + $model = EE_Registry::instance()->load_model($model_name); |
|
| 446 | + if ($model_field_value = EE_Registry::instance()->REQ->get($request_key)) { |
|
| 447 | + switch ($request_key) { |
|
| 448 | + case '_REG_ID': |
|
| 449 | + $label_parts[] = sprintf( |
|
| 450 | + esc_html__('Registration with the ID: %s', 'event_espresso'), |
|
| 451 | + $model_field_value |
|
| 452 | + ); |
|
| 453 | + break; |
|
| 454 | + case 'ATT_ID': |
|
| 455 | + /** @var EE_Attendee $attendee */ |
|
| 456 | + $attendee = $model->get_one_by_ID($model_field_value); |
|
| 457 | + $label_parts[] = $attendee instanceof EE_Attendee |
|
| 458 | + ? sprintf(esc_html__('Attendee %s', 'event_espresso'), $attendee->full_name()) |
|
| 459 | + : sprintf(esc_html__('Attendee ID: %s', 'event_espresso'), $model_field_value); |
|
| 460 | + break; |
|
| 461 | + case 'ID': |
|
| 462 | + /** @var EE_WP_User $wpUser */ |
|
| 463 | + $wpUser = $model->get_one_by_ID($model_field_value); |
|
| 464 | + $label_parts[] = $wpUser instanceof EE_WP_User |
|
| 465 | + ? sprintf(esc_html__('WP User: %s', 'event_espresso'), $wpUser->name()) |
|
| 466 | + : sprintf(esc_html__('WP User ID: %s', 'event_espresso'), $model_field_value); |
|
| 467 | + break; |
|
| 468 | + case 'TXN_ID': |
|
| 469 | + $label_parts[] = sprintf( |
|
| 470 | + esc_html__('Transaction with the ID: %s', 'event_espresso'), |
|
| 471 | + $model_field_value |
|
| 472 | + ); |
|
| 473 | + break; |
|
| 474 | + case 'EVT_ID': |
|
| 475 | + /** @var EE_Event $Event */ |
|
| 476 | + $Event = $model->get_one_by_ID($model_field_value); |
|
| 477 | + $label_parts[] = $Event instanceof EE_Event |
|
| 478 | + ? sprintf(esc_html__('for the Event: %s', 'event_espresso'), $Event->name()) |
|
| 479 | + : sprintf(esc_html__('for the Event with ID: %s', 'event_espresso'), $model_field_value); |
|
| 480 | + break; |
|
| 481 | + } |
|
| 482 | + } |
|
| 483 | + } |
|
| 484 | + |
|
| 485 | + if ($label_parts) { |
|
| 486 | + // prepend to the last element of $label_parts an "and". |
|
| 487 | + if (count($label_parts) > 1) { |
|
| 488 | + $label_parts_index_to_prepend = count($label_parts) - 1; |
|
| 489 | + $label_parts[ $label_parts_index_to_prepend ] = 'and' . $label_parts[ $label_parts_index_to_prepend ]; |
|
| 490 | + } |
|
| 491 | + |
|
| 492 | + $pretty_label .= sprintf( |
|
| 493 | + esc_html_x( |
|
| 494 | + 'Showing messages for %s', |
|
| 495 | + 'A label for the messages returned in a query that are filtered by items in the query. This could be Transaction, Event, Attendee, Registration, or WP_User.', |
|
| 496 | + 'event_espresso' |
|
| 497 | + ), |
|
| 498 | + implode(', ', $label_parts) |
|
| 499 | + ); |
|
| 500 | + } |
|
| 501 | + return $pretty_label; |
|
| 502 | + } |
|
| 503 | + |
|
| 504 | + |
|
| 505 | + /** |
|
| 506 | + * This returns the array of expected variables for the EEI_Query_Filter methods being implemented |
|
| 507 | + * The array is in the format: |
|
| 508 | + * array( |
|
| 509 | + * {$field_name} => {$model_name} |
|
| 510 | + * ); |
|
| 511 | + * |
|
| 512 | + * @since 4.9.0 |
|
| 513 | + * @return array |
|
| 514 | + */ |
|
| 515 | + protected function _expected_vars_for_query_inject() |
|
| 516 | + { |
|
| 517 | + return array( |
|
| 518 | + '_REG_ID' => 'Registration', |
|
| 519 | + 'ATT_ID' => 'Attendee', |
|
| 520 | + 'ID' => 'WP_User', |
|
| 521 | + 'TXN_ID' => 'Transaction', |
|
| 522 | + 'EVT_ID' => 'Event', |
|
| 523 | + ); |
|
| 524 | + } |
|
| 525 | + |
|
| 526 | + |
|
| 527 | + /** |
|
| 528 | + * This returns whether EEM_Message is in debug mode or not. |
|
| 529 | + * Currently "debug mode" is used to control the handling of the EEM_Message::debug_only status when |
|
| 530 | + * generating/sending messages. Debug mode can be set by either: |
|
| 531 | + * 1. Sending in a value for the $set_debug argument |
|
| 532 | + * 2. Defining `EE_DEBUG_MESSAGES` constant in wp-config.php |
|
| 533 | + * 3. Overriding the above via the provided filter. |
|
| 534 | + * |
|
| 535 | + * @param bool|null $set_debug If provided, then the debug mode will be set internally until reset via the |
|
| 536 | + * provided boolean. When no argument is provided (default null) then the debug |
|
| 537 | + * mode will be returned. |
|
| 538 | + * @return bool true means Messages is in debug mode. false means messages system is not in debug mode. |
|
| 539 | + */ |
|
| 540 | + public static function debug($set_debug = null) |
|
| 541 | + { |
|
| 542 | + static $is_debugging = null; |
|
| 543 | + |
|
| 544 | + // initialize (use constant if set). |
|
| 545 | + if (is_null($set_debug) && is_null($is_debugging)) { |
|
| 546 | + $is_debugging = defined('EE_DEBUG_MESSAGES') && EE_DEBUG_MESSAGES; |
|
| 547 | + } |
|
| 548 | + |
|
| 549 | + if (! is_null($set_debug)) { |
|
| 550 | + $is_debugging = filter_var($set_debug, FILTER_VALIDATE_BOOLEAN); |
|
| 551 | + } |
|
| 552 | + |
|
| 553 | + // return filtered value |
|
| 554 | + return apply_filters('FHEE__EEM_Message__debug', $is_debugging); |
|
| 555 | + } |
|
| 556 | + |
|
| 557 | + |
|
| 558 | + /** |
|
| 559 | + * Deletes old messages meeting certain criteria for removal from the database. |
|
| 560 | + * By default, this will delete messages that: |
|
| 561 | + * - are older than the value of the delete_threshold in months. |
|
| 562 | + * - have a STS_ID other than EEM_Message::status_idle |
|
| 563 | + * |
|
| 564 | + * @param int $delete_threshold This integer will be used to set the boundary for what messages are deleted in months. |
|
| 565 | + * @return bool|false|int Either the number of records affected or false if there was an error (you can call |
|
| 566 | + * $wpdb->last_error to find out what the error was. |
|
| 567 | + */ |
|
| 568 | + public function delete_old_messages($delete_threshold = 6) |
|
| 569 | + { |
|
| 570 | + $number_deleted = 0; |
|
| 571 | + /** |
|
| 572 | + * Allows code to change the boundary for what messages are kept. |
|
| 573 | + * Uses the value of the `delete_threshold` variable by default. |
|
| 574 | + * |
|
| 575 | + * @param int $seconds seconds that will be subtracted from the timestamp for now. |
|
| 576 | + * @return int |
|
| 577 | + */ |
|
| 578 | + $time_to_leave_alone = absint( |
|
| 579 | + apply_filters( |
|
| 580 | + 'FHEE__EEM_Message__delete_old_messages__time_to_leave_alone', |
|
| 581 | + ((int) $delete_threshold) * MONTH_IN_SECONDS |
|
| 582 | + ) |
|
| 583 | + ); |
|
| 584 | + |
|
| 585 | + |
|
| 586 | + /** |
|
| 587 | + * Allows code to change what message stati are ignored when deleting. |
|
| 588 | + * Defaults to only ignore EEM_Message::status_idle messages. |
|
| 589 | + * |
|
| 590 | + * @param string $message_stati_to_keep An array of message statuses that will be ignored when deleting. |
|
| 591 | + */ |
|
| 592 | + $message_stati_to_keep = (array) apply_filters( |
|
| 593 | + 'FHEE__EEM_Message__delete_old_messages__message_stati_to_keep', |
|
| 594 | + array( |
|
| 595 | + EEM_Message::status_idle |
|
| 596 | + ) |
|
| 597 | + ); |
|
| 598 | + |
|
| 599 | + // first get all the ids of messages being deleted |
|
| 600 | + $message_ids_to_delete = EEM_Message::instance()->get_col( |
|
| 601 | + array( |
|
| 602 | + 0 => array( |
|
| 603 | + 'STS_ID' => array('NOT_IN', $message_stati_to_keep), |
|
| 604 | + 'MSG_modified' => array('<', time() - $time_to_leave_alone) |
|
| 605 | + ), |
|
| 606 | + 'limit' => apply_filters( |
|
| 607 | + 'EEM_Message__delete_old_messages__limit', |
|
| 608 | + 2000, |
|
| 609 | + $delete_threshold |
|
| 610 | + ) |
|
| 611 | + ) |
|
| 612 | + ); |
|
| 613 | + |
|
| 614 | + if (! empty($message_ids_to_delete) && is_array($message_ids_to_delete)) { |
|
| 615 | + global $wpdb; |
|
| 616 | + $number_deleted = $wpdb->query(' |
|
| 617 | 617 | DELETE |
| 618 | 618 | FROM ' . $this->table() . ' |
| 619 | 619 | WHERE |
| 620 | 620 | MSG_ID IN (' . implode(",", $message_ids_to_delete) . ') |
| 621 | 621 | '); |
| 622 | - } |
|
| 623 | - |
|
| 624 | - /** |
|
| 625 | - * This will get called if the number of records deleted 0 or greater. So a successful deletion is one where |
|
| 626 | - * there were no errors. An unsuccessful deletion is where there were errors. Keep that in mind for the actions |
|
| 627 | - * below. |
|
| 628 | - */ |
|
| 629 | - if ($number_deleted !== false) { |
|
| 630 | - do_action('AHEE__EEM_Message__delete_old_messages__after_successful_deletion', $message_ids_to_delete, $number_deleted); |
|
| 631 | - } else { |
|
| 632 | - do_action('AHEE__EEM_Message__delete_old_messages__after_deletion_fail', $message_ids_to_delete, $number_deleted); |
|
| 633 | - } |
|
| 634 | - return $number_deleted; |
|
| 635 | - } |
|
| 622 | + } |
|
| 623 | + |
|
| 624 | + /** |
|
| 625 | + * This will get called if the number of records deleted 0 or greater. So a successful deletion is one where |
|
| 626 | + * there were no errors. An unsuccessful deletion is where there were errors. Keep that in mind for the actions |
|
| 627 | + * below. |
|
| 628 | + */ |
|
| 629 | + if ($number_deleted !== false) { |
|
| 630 | + do_action('AHEE__EEM_Message__delete_old_messages__after_successful_deletion', $message_ids_to_delete, $number_deleted); |
|
| 631 | + } else { |
|
| 632 | + do_action('AHEE__EEM_Message__delete_old_messages__after_deletion_fail', $message_ids_to_delete, $number_deleted); |
|
| 633 | + } |
|
| 634 | + return $number_deleted; |
|
| 635 | + } |
|
| 636 | 636 | } |
@@ -16,230 +16,230 @@ discard block |
||
| 16 | 16 | class EEM_Transaction extends EEM_Base |
| 17 | 17 | { |
| 18 | 18 | |
| 19 | - // private instance of the Transaction object |
|
| 20 | - protected static $_instance; |
|
| 21 | - |
|
| 22 | - /** |
|
| 23 | - * Status ID(STS_ID on esp_status table) to indicate the transaction is complete, |
|
| 24 | - * but payment is pending. This is the state for transactions where payment is promised |
|
| 25 | - * from an offline gateway. |
|
| 26 | - */ |
|
| 27 | - // const open_status_code = 'TPN'; |
|
| 28 | - |
|
| 29 | - /** |
|
| 30 | - * Status ID(STS_ID on esp_status table) to indicate the transaction failed, |
|
| 31 | - * either due to a technical reason (server or computer crash during registration), |
|
| 32 | - * or some other reason that prevent the collection of any useful contact information from any of the registrants |
|
| 33 | - */ |
|
| 34 | - const failed_status_code = 'TFL'; |
|
| 35 | - |
|
| 36 | - /** |
|
| 37 | - * Status ID(STS_ID on esp_status table) to indicate the transaction was abandoned, |
|
| 38 | - * either due to a technical reason (server or computer crash during registration), |
|
| 39 | - * or due to an abandoned cart after registrant chose not to complete the registration process |
|
| 40 | - * HOWEVER... |
|
| 41 | - * an abandoned TXN differs from a failed TXN in that it was able to capture contact information for at least one |
|
| 42 | - * registrant |
|
| 43 | - */ |
|
| 44 | - const abandoned_status_code = 'TAB'; |
|
| 45 | - |
|
| 46 | - /** |
|
| 47 | - * Status ID(STS_ID on esp_status table) to indicate an incomplete transaction, |
|
| 48 | - * meaning that monies are still owing: TXN_paid < TXN_total |
|
| 49 | - */ |
|
| 50 | - const incomplete_status_code = 'TIN'; |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * Status ID (STS_ID on esp_status table) to indicate a complete transaction. |
|
| 54 | - * meaning that NO monies are owing: TXN_paid == TXN_total |
|
| 55 | - */ |
|
| 56 | - const complete_status_code = 'TCM'; |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * Status ID(STS_ID on esp_status table) to indicate the transaction is overpaid. |
|
| 60 | - * This is the same as complete, but site admins actually owe clients the moneys! TXN_paid > TXN_total |
|
| 61 | - */ |
|
| 62 | - const overpaid_status_code = 'TOP'; |
|
| 63 | - |
|
| 64 | - |
|
| 65 | - /** |
|
| 66 | - * private constructor to prevent direct creation |
|
| 67 | - * |
|
| 68 | - * @Constructor |
|
| 69 | - * @access protected |
|
| 70 | - * |
|
| 71 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
| 72 | - * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
| 73 | - * date time model field objects. Default is NULL (and will be assumed using the set |
|
| 74 | - * timezone in the 'timezone_string' wp option) |
|
| 75 | - * |
|
| 76 | - * @return EEM_Transaction |
|
| 77 | - * @throws \EE_Error |
|
| 78 | - */ |
|
| 79 | - protected function __construct($timezone) |
|
| 80 | - { |
|
| 81 | - $this->singular_item = __('Transaction', 'event_espresso'); |
|
| 82 | - $this->plural_item = __('Transactions', 'event_espresso'); |
|
| 83 | - |
|
| 84 | - $this->_tables = array( |
|
| 85 | - 'TransactionTable' => new EE_Primary_Table('esp_transaction', 'TXN_ID') |
|
| 86 | - ); |
|
| 87 | - $this->_fields = array( |
|
| 88 | - 'TransactionTable' => array( |
|
| 89 | - 'TXN_ID' => new EE_Primary_Key_Int_Field('TXN_ID', __('Transaction ID', 'event_espresso')), |
|
| 90 | - 'TXN_timestamp' => new EE_Datetime_Field( |
|
| 91 | - 'TXN_timestamp', |
|
| 92 | - __('date when transaction was created', 'event_espresso'), |
|
| 93 | - false, |
|
| 94 | - EE_Datetime_Field::now, |
|
| 95 | - $timezone |
|
| 96 | - ), |
|
| 97 | - 'TXN_total' => new EE_Money_Field( |
|
| 98 | - 'TXN_total', |
|
| 99 | - __('Total value of Transaction', 'event_espresso'), |
|
| 100 | - false, |
|
| 101 | - 0 |
|
| 102 | - ), |
|
| 103 | - 'TXN_paid' => new EE_Money_Field( |
|
| 104 | - 'TXN_paid', |
|
| 105 | - __('Amount paid towards transaction to date', 'event_espresso'), |
|
| 106 | - false, |
|
| 107 | - 0 |
|
| 108 | - ), |
|
| 109 | - 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
| 110 | - 'STS_ID', |
|
| 111 | - __('Status ID', 'event_espresso'), |
|
| 112 | - false, |
|
| 113 | - EEM_Transaction::failed_status_code, |
|
| 114 | - 'Status' |
|
| 115 | - ), |
|
| 116 | - 'TXN_session_data' => new EE_Serialized_Text_Field( |
|
| 117 | - 'TXN_session_data', |
|
| 118 | - __('Serialized session data', 'event_espresso'), |
|
| 119 | - true, |
|
| 120 | - '' |
|
| 121 | - ), |
|
| 122 | - 'TXN_hash_salt' => new EE_Plain_Text_Field( |
|
| 123 | - 'TXN_hash_salt', |
|
| 124 | - __('Transaction Hash Salt', 'event_espresso'), |
|
| 125 | - true, |
|
| 126 | - '' |
|
| 127 | - ), |
|
| 128 | - 'PMD_ID' => new EE_Foreign_Key_Int_Field( |
|
| 129 | - 'PMD_ID', |
|
| 130 | - __("Last Used Payment Method", 'event_espresso'), |
|
| 131 | - true, |
|
| 132 | - null, |
|
| 133 | - 'Payment_Method' |
|
| 134 | - ), |
|
| 135 | - 'TXN_reg_steps' => new EE_Serialized_Text_Field( |
|
| 136 | - 'TXN_reg_steps', |
|
| 137 | - __('Registration Steps', 'event_espresso'), |
|
| 138 | - false, |
|
| 139 | - array() |
|
| 140 | - ), |
|
| 141 | - ) |
|
| 142 | - ); |
|
| 143 | - $this->_model_relations = array( |
|
| 144 | - 'Registration' => new EE_Has_Many_Relation(), |
|
| 145 | - 'Payment' => new EE_Has_Many_Relation(), |
|
| 146 | - 'Status' => new EE_Belongs_To_Relation(), |
|
| 147 | - 'Line_Item' => new EE_Has_Many_Relation(false), |
|
| 148 | - // you can delete a transaction without needing to delete its line items |
|
| 149 | - 'Payment_Method' => new EE_Belongs_To_Relation(), |
|
| 150 | - 'Message' => new EE_Has_Many_Relation() |
|
| 151 | - ); |
|
| 152 | - $this->_model_chain_to_wp_user = 'Registration.Event'; |
|
| 153 | - parent::__construct($timezone); |
|
| 154 | - } |
|
| 155 | - |
|
| 156 | - |
|
| 157 | - /** |
|
| 158 | - * txn_status_array |
|
| 159 | - * get list of transaction statuses |
|
| 160 | - * |
|
| 161 | - * @access public |
|
| 162 | - * @return array |
|
| 163 | - */ |
|
| 164 | - public static function txn_status_array() |
|
| 165 | - { |
|
| 166 | - return apply_filters( |
|
| 167 | - 'FHEE__EEM_Transaction__txn_status_array', |
|
| 168 | - array( |
|
| 169 | - EEM_Transaction::overpaid_status_code, |
|
| 170 | - EEM_Transaction::complete_status_code, |
|
| 171 | - EEM_Transaction::incomplete_status_code, |
|
| 172 | - EEM_Transaction::abandoned_status_code, |
|
| 173 | - EEM_Transaction::failed_status_code, |
|
| 174 | - ) |
|
| 175 | - ); |
|
| 176 | - } |
|
| 177 | - |
|
| 178 | - /** |
|
| 179 | - * get the revenue per day for the Transaction Admin page Reports Tab |
|
| 180 | - * |
|
| 181 | - * @access public |
|
| 182 | - * |
|
| 183 | - * @param string $period |
|
| 184 | - * |
|
| 185 | - * @return \stdClass[] |
|
| 186 | - */ |
|
| 187 | - public function get_revenue_per_day_report($period = '-1 month') |
|
| 188 | - { |
|
| 189 | - $sql_date = $this->convert_datetime_for_query( |
|
| 190 | - 'TXN_timestamp', |
|
| 191 | - date('Y-m-d H:i:s', strtotime($period)), |
|
| 192 | - 'Y-m-d H:i:s', |
|
| 193 | - 'UTC' |
|
| 194 | - ); |
|
| 195 | - |
|
| 196 | - $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'TXN_timestamp'); |
|
| 197 | - |
|
| 198 | - return $this->_get_all_wpdb_results( |
|
| 199 | - array( |
|
| 200 | - array( |
|
| 201 | - 'TXN_timestamp' => array('>=', $sql_date) |
|
| 202 | - ), |
|
| 203 | - 'group_by' => 'txnDate', |
|
| 204 | - 'order_by' => array('TXN_timestamp' => 'ASC') |
|
| 205 | - ), |
|
| 206 | - OBJECT, |
|
| 207 | - array( |
|
| 208 | - 'txnDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
| 209 | - 'revenue' => array('SUM(TransactionTable.TXN_paid)', '%d') |
|
| 210 | - ) |
|
| 211 | - ); |
|
| 212 | - } |
|
| 213 | - |
|
| 214 | - |
|
| 215 | - /** |
|
| 216 | - * get the revenue per event for the Transaction Admin page Reports Tab |
|
| 217 | - * |
|
| 218 | - * @access public |
|
| 219 | - * |
|
| 220 | - * @param string $period |
|
| 221 | - * |
|
| 222 | - * @throws \EE_Error |
|
| 223 | - * @return mixed |
|
| 224 | - */ |
|
| 225 | - public function get_revenue_per_event_report($period = '-1 month') |
|
| 226 | - { |
|
| 227 | - global $wpdb; |
|
| 228 | - $transaction_table = $wpdb->prefix . 'esp_transaction'; |
|
| 229 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 230 | - $registration_payment_table = $wpdb->prefix . 'esp_registration_payment'; |
|
| 231 | - $event_table = $wpdb->posts; |
|
| 232 | - $payment_table = $wpdb->prefix . 'esp_payment'; |
|
| 233 | - $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
| 234 | - $approved_payment_status = EEM_Payment::status_id_approved; |
|
| 235 | - $extra_event_on_join = ''; |
|
| 236 | - // exclude events not authored by user if permissions in effect |
|
| 237 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 238 | - $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id(); |
|
| 239 | - } |
|
| 240 | - |
|
| 241 | - return $wpdb->get_results( |
|
| 242 | - "SELECT |
|
| 19 | + // private instance of the Transaction object |
|
| 20 | + protected static $_instance; |
|
| 21 | + |
|
| 22 | + /** |
|
| 23 | + * Status ID(STS_ID on esp_status table) to indicate the transaction is complete, |
|
| 24 | + * but payment is pending. This is the state for transactions where payment is promised |
|
| 25 | + * from an offline gateway. |
|
| 26 | + */ |
|
| 27 | + // const open_status_code = 'TPN'; |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * Status ID(STS_ID on esp_status table) to indicate the transaction failed, |
|
| 31 | + * either due to a technical reason (server or computer crash during registration), |
|
| 32 | + * or some other reason that prevent the collection of any useful contact information from any of the registrants |
|
| 33 | + */ |
|
| 34 | + const failed_status_code = 'TFL'; |
|
| 35 | + |
|
| 36 | + /** |
|
| 37 | + * Status ID(STS_ID on esp_status table) to indicate the transaction was abandoned, |
|
| 38 | + * either due to a technical reason (server or computer crash during registration), |
|
| 39 | + * or due to an abandoned cart after registrant chose not to complete the registration process |
|
| 40 | + * HOWEVER... |
|
| 41 | + * an abandoned TXN differs from a failed TXN in that it was able to capture contact information for at least one |
|
| 42 | + * registrant |
|
| 43 | + */ |
|
| 44 | + const abandoned_status_code = 'TAB'; |
|
| 45 | + |
|
| 46 | + /** |
|
| 47 | + * Status ID(STS_ID on esp_status table) to indicate an incomplete transaction, |
|
| 48 | + * meaning that monies are still owing: TXN_paid < TXN_total |
|
| 49 | + */ |
|
| 50 | + const incomplete_status_code = 'TIN'; |
|
| 51 | + |
|
| 52 | + /** |
|
| 53 | + * Status ID (STS_ID on esp_status table) to indicate a complete transaction. |
|
| 54 | + * meaning that NO monies are owing: TXN_paid == TXN_total |
|
| 55 | + */ |
|
| 56 | + const complete_status_code = 'TCM'; |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * Status ID(STS_ID on esp_status table) to indicate the transaction is overpaid. |
|
| 60 | + * This is the same as complete, but site admins actually owe clients the moneys! TXN_paid > TXN_total |
|
| 61 | + */ |
|
| 62 | + const overpaid_status_code = 'TOP'; |
|
| 63 | + |
|
| 64 | + |
|
| 65 | + /** |
|
| 66 | + * private constructor to prevent direct creation |
|
| 67 | + * |
|
| 68 | + * @Constructor |
|
| 69 | + * @access protected |
|
| 70 | + * |
|
| 71 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any |
|
| 72 | + * incoming timezone data that gets saved). Note this just sends the timezone info to the |
|
| 73 | + * date time model field objects. Default is NULL (and will be assumed using the set |
|
| 74 | + * timezone in the 'timezone_string' wp option) |
|
| 75 | + * |
|
| 76 | + * @return EEM_Transaction |
|
| 77 | + * @throws \EE_Error |
|
| 78 | + */ |
|
| 79 | + protected function __construct($timezone) |
|
| 80 | + { |
|
| 81 | + $this->singular_item = __('Transaction', 'event_espresso'); |
|
| 82 | + $this->plural_item = __('Transactions', 'event_espresso'); |
|
| 83 | + |
|
| 84 | + $this->_tables = array( |
|
| 85 | + 'TransactionTable' => new EE_Primary_Table('esp_transaction', 'TXN_ID') |
|
| 86 | + ); |
|
| 87 | + $this->_fields = array( |
|
| 88 | + 'TransactionTable' => array( |
|
| 89 | + 'TXN_ID' => new EE_Primary_Key_Int_Field('TXN_ID', __('Transaction ID', 'event_espresso')), |
|
| 90 | + 'TXN_timestamp' => new EE_Datetime_Field( |
|
| 91 | + 'TXN_timestamp', |
|
| 92 | + __('date when transaction was created', 'event_espresso'), |
|
| 93 | + false, |
|
| 94 | + EE_Datetime_Field::now, |
|
| 95 | + $timezone |
|
| 96 | + ), |
|
| 97 | + 'TXN_total' => new EE_Money_Field( |
|
| 98 | + 'TXN_total', |
|
| 99 | + __('Total value of Transaction', 'event_espresso'), |
|
| 100 | + false, |
|
| 101 | + 0 |
|
| 102 | + ), |
|
| 103 | + 'TXN_paid' => new EE_Money_Field( |
|
| 104 | + 'TXN_paid', |
|
| 105 | + __('Amount paid towards transaction to date', 'event_espresso'), |
|
| 106 | + false, |
|
| 107 | + 0 |
|
| 108 | + ), |
|
| 109 | + 'STS_ID' => new EE_Foreign_Key_String_Field( |
|
| 110 | + 'STS_ID', |
|
| 111 | + __('Status ID', 'event_espresso'), |
|
| 112 | + false, |
|
| 113 | + EEM_Transaction::failed_status_code, |
|
| 114 | + 'Status' |
|
| 115 | + ), |
|
| 116 | + 'TXN_session_data' => new EE_Serialized_Text_Field( |
|
| 117 | + 'TXN_session_data', |
|
| 118 | + __('Serialized session data', 'event_espresso'), |
|
| 119 | + true, |
|
| 120 | + '' |
|
| 121 | + ), |
|
| 122 | + 'TXN_hash_salt' => new EE_Plain_Text_Field( |
|
| 123 | + 'TXN_hash_salt', |
|
| 124 | + __('Transaction Hash Salt', 'event_espresso'), |
|
| 125 | + true, |
|
| 126 | + '' |
|
| 127 | + ), |
|
| 128 | + 'PMD_ID' => new EE_Foreign_Key_Int_Field( |
|
| 129 | + 'PMD_ID', |
|
| 130 | + __("Last Used Payment Method", 'event_espresso'), |
|
| 131 | + true, |
|
| 132 | + null, |
|
| 133 | + 'Payment_Method' |
|
| 134 | + ), |
|
| 135 | + 'TXN_reg_steps' => new EE_Serialized_Text_Field( |
|
| 136 | + 'TXN_reg_steps', |
|
| 137 | + __('Registration Steps', 'event_espresso'), |
|
| 138 | + false, |
|
| 139 | + array() |
|
| 140 | + ), |
|
| 141 | + ) |
|
| 142 | + ); |
|
| 143 | + $this->_model_relations = array( |
|
| 144 | + 'Registration' => new EE_Has_Many_Relation(), |
|
| 145 | + 'Payment' => new EE_Has_Many_Relation(), |
|
| 146 | + 'Status' => new EE_Belongs_To_Relation(), |
|
| 147 | + 'Line_Item' => new EE_Has_Many_Relation(false), |
|
| 148 | + // you can delete a transaction without needing to delete its line items |
|
| 149 | + 'Payment_Method' => new EE_Belongs_To_Relation(), |
|
| 150 | + 'Message' => new EE_Has_Many_Relation() |
|
| 151 | + ); |
|
| 152 | + $this->_model_chain_to_wp_user = 'Registration.Event'; |
|
| 153 | + parent::__construct($timezone); |
|
| 154 | + } |
|
| 155 | + |
|
| 156 | + |
|
| 157 | + /** |
|
| 158 | + * txn_status_array |
|
| 159 | + * get list of transaction statuses |
|
| 160 | + * |
|
| 161 | + * @access public |
|
| 162 | + * @return array |
|
| 163 | + */ |
|
| 164 | + public static function txn_status_array() |
|
| 165 | + { |
|
| 166 | + return apply_filters( |
|
| 167 | + 'FHEE__EEM_Transaction__txn_status_array', |
|
| 168 | + array( |
|
| 169 | + EEM_Transaction::overpaid_status_code, |
|
| 170 | + EEM_Transaction::complete_status_code, |
|
| 171 | + EEM_Transaction::incomplete_status_code, |
|
| 172 | + EEM_Transaction::abandoned_status_code, |
|
| 173 | + EEM_Transaction::failed_status_code, |
|
| 174 | + ) |
|
| 175 | + ); |
|
| 176 | + } |
|
| 177 | + |
|
| 178 | + /** |
|
| 179 | + * get the revenue per day for the Transaction Admin page Reports Tab |
|
| 180 | + * |
|
| 181 | + * @access public |
|
| 182 | + * |
|
| 183 | + * @param string $period |
|
| 184 | + * |
|
| 185 | + * @return \stdClass[] |
|
| 186 | + */ |
|
| 187 | + public function get_revenue_per_day_report($period = '-1 month') |
|
| 188 | + { |
|
| 189 | + $sql_date = $this->convert_datetime_for_query( |
|
| 190 | + 'TXN_timestamp', |
|
| 191 | + date('Y-m-d H:i:s', strtotime($period)), |
|
| 192 | + 'Y-m-d H:i:s', |
|
| 193 | + 'UTC' |
|
| 194 | + ); |
|
| 195 | + |
|
| 196 | + $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'TXN_timestamp'); |
|
| 197 | + |
|
| 198 | + return $this->_get_all_wpdb_results( |
|
| 199 | + array( |
|
| 200 | + array( |
|
| 201 | + 'TXN_timestamp' => array('>=', $sql_date) |
|
| 202 | + ), |
|
| 203 | + 'group_by' => 'txnDate', |
|
| 204 | + 'order_by' => array('TXN_timestamp' => 'ASC') |
|
| 205 | + ), |
|
| 206 | + OBJECT, |
|
| 207 | + array( |
|
| 208 | + 'txnDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
| 209 | + 'revenue' => array('SUM(TransactionTable.TXN_paid)', '%d') |
|
| 210 | + ) |
|
| 211 | + ); |
|
| 212 | + } |
|
| 213 | + |
|
| 214 | + |
|
| 215 | + /** |
|
| 216 | + * get the revenue per event for the Transaction Admin page Reports Tab |
|
| 217 | + * |
|
| 218 | + * @access public |
|
| 219 | + * |
|
| 220 | + * @param string $period |
|
| 221 | + * |
|
| 222 | + * @throws \EE_Error |
|
| 223 | + * @return mixed |
|
| 224 | + */ |
|
| 225 | + public function get_revenue_per_event_report($period = '-1 month') |
|
| 226 | + { |
|
| 227 | + global $wpdb; |
|
| 228 | + $transaction_table = $wpdb->prefix . 'esp_transaction'; |
|
| 229 | + $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 230 | + $registration_payment_table = $wpdb->prefix . 'esp_registration_payment'; |
|
| 231 | + $event_table = $wpdb->posts; |
|
| 232 | + $payment_table = $wpdb->prefix . 'esp_payment'; |
|
| 233 | + $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
|
| 234 | + $approved_payment_status = EEM_Payment::status_id_approved; |
|
| 235 | + $extra_event_on_join = ''; |
|
| 236 | + // exclude events not authored by user if permissions in effect |
|
| 237 | + if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 238 | + $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id(); |
|
| 239 | + } |
|
| 240 | + |
|
| 241 | + return $wpdb->get_results( |
|
| 242 | + "SELECT |
|
| 243 | 243 | Transaction_Event.event_name AS event_name, |
| 244 | 244 | SUM(Transaction_Event.paid) AS revenue |
| 245 | 245 | FROM |
@@ -267,233 +267,233 @@ discard block |
||
| 267 | 267 | $extra_event_on_join |
| 268 | 268 | ) AS Transaction_Event |
| 269 | 269 | GROUP BY event_name", |
| 270 | - OBJECT |
|
| 271 | - ); |
|
| 272 | - } |
|
| 273 | - |
|
| 274 | - |
|
| 275 | - /** |
|
| 276 | - * Gets the current transaction given the reg_url_link, or assumes the reg_url_link is in the |
|
| 277 | - * $_REQUEST global variable. Either way, tries to find the current transaction (through |
|
| 278 | - * the registration pointed to by reg_url_link), if not returns null |
|
| 279 | - * |
|
| 280 | - * @param string $reg_url_link |
|
| 281 | - * |
|
| 282 | - * @return EE_Transaction |
|
| 283 | - */ |
|
| 284 | - public function get_transaction_from_reg_url_link($reg_url_link = '') |
|
| 285 | - { |
|
| 286 | - return $this->get_one(array( |
|
| 287 | - array( |
|
| 288 | - 'Registration.REG_url_link' => ! empty($reg_url_link) ? $reg_url_link : EE_Registry::instance()->REQ->get( |
|
| 289 | - 'e_reg_url_link', |
|
| 290 | - '' |
|
| 291 | - ) |
|
| 292 | - ) |
|
| 293 | - )); |
|
| 294 | - } |
|
| 295 | - |
|
| 296 | - |
|
| 297 | - /** |
|
| 298 | - * Updates the provided EE_Transaction with all the applicable payments |
|
| 299 | - * (or fetch the EE_Transaction from its ID) |
|
| 300 | - * |
|
| 301 | - * @deprecated |
|
| 302 | - * |
|
| 303 | - * @param EE_Transaction|int $transaction_obj_or_id |
|
| 304 | - * @param boolean $save_txn whether or not to save the transaction during this function call |
|
| 305 | - * |
|
| 306 | - * @return boolean |
|
| 307 | - * @throws \EE_Error |
|
| 308 | - */ |
|
| 309 | - public function update_based_on_payments($transaction_obj_or_id, $save_txn = true) |
|
| 310 | - { |
|
| 311 | - EE_Error::doing_it_wrong( |
|
| 312 | - __CLASS__ . '::' . __FUNCTION__, |
|
| 313 | - sprintf( |
|
| 314 | - __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
| 315 | - 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
|
| 316 | - ), |
|
| 317 | - '4.6.0' |
|
| 318 | - ); |
|
| 319 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 320 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 321 | - |
|
| 322 | - return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
| 323 | - $this->ensure_is_obj($transaction_obj_or_id) |
|
| 324 | - ); |
|
| 325 | - } |
|
| 326 | - |
|
| 327 | - /** |
|
| 328 | - * Deletes "junk" transactions that were probably added by bots. There might be TONS |
|
| 329 | - * of these, so we are very careful to NOT select (which the models do even when deleting), |
|
| 330 | - * and so we only use wpdb directly and only do minimal joins. |
|
| 331 | - * Transactions are considered "junk" if they're failed for longer than a week. |
|
| 332 | - * Also, there is an extra check for payments related to the transaction, because if a transaction has a payment on |
|
| 333 | - * it, it's probably not junk (regardless of what status it has). |
|
| 334 | - * The downside to this approach is that is addons are listening for object deletions |
|
| 335 | - * on EEM_Base::delete() they won't be notified of this. However, there is an action that plugins can hook into |
|
| 336 | - * to catch these types of deletions. |
|
| 337 | - * |
|
| 338 | - * @global WPDB $wpdb |
|
| 339 | - * @return mixed |
|
| 340 | - */ |
|
| 341 | - public function delete_junk_transactions() |
|
| 342 | - { |
|
| 343 | - /** @type WPDB $wpdb */ |
|
| 344 | - global $wpdb; |
|
| 345 | - $deleted = false; |
|
| 346 | - $time_to_leave_alone = apply_filters( |
|
| 347 | - 'FHEE__EEM_Transaction__delete_junk_transactions__time_to_leave_alone', |
|
| 348 | - WEEK_IN_SECONDS |
|
| 349 | - ); |
|
| 350 | - |
|
| 351 | - |
|
| 352 | - /** |
|
| 353 | - * This allows code to filter the query arguments used for retrieving the transaction IDs to delete. |
|
| 354 | - * Useful for plugins that want to exclude transactions matching certain query parameters. |
|
| 355 | - * The query parameters should be in the format accepted by the EEM_Base model queries. |
|
| 356 | - */ |
|
| 357 | - $ids_query = apply_filters( |
|
| 358 | - 'FHEE__EEM_Transaction__delete_junk_transactions__initial_query_args', |
|
| 359 | - array( |
|
| 360 | - 0 => array( |
|
| 361 | - 'STS_ID' => EEM_Transaction::failed_status_code, |
|
| 362 | - 'Payment.PAY_ID' => array( 'IS NULL' ), |
|
| 363 | - 'TXN_timestamp' => array('<', time() - $time_to_leave_alone) |
|
| 364 | - ), |
|
| 365 | - 'order_by' => ['TXN_timestamp' => 'ASC'], |
|
| 366 | - 'limit' => 1000 |
|
| 367 | - ), |
|
| 368 | - $time_to_leave_alone |
|
| 369 | - ); |
|
| 370 | - |
|
| 371 | - |
|
| 372 | - /** |
|
| 373 | - * This filter is for when code needs to filter the list of transaction ids that represent transactions |
|
| 374 | - * about to be deleted based on some other criteria that isn't easily done via the query args filter. |
|
| 375 | - */ |
|
| 376 | - $txn_ids = apply_filters( |
|
| 377 | - 'FHEE__EEM_Transaction__delete_junk_transactions__transaction_ids_to_delete', |
|
| 378 | - EEM_Transaction::instance()->get_col($ids_query, 'TXN_ID'), |
|
| 379 | - $time_to_leave_alone |
|
| 380 | - ); |
|
| 381 | - // now that we have the ids to delete |
|
| 382 | - if (! empty($txn_ids) && is_array($txn_ids)) { |
|
| 383 | - // first, make sure these TXN's are removed the "ee_locked_transactions" array |
|
| 384 | - EEM_Transaction::unset_locked_transactions($txn_ids); |
|
| 385 | - |
|
| 386 | - // Create IDs placeholder. |
|
| 387 | - $placeholders = array_fill(0, count($txn_ids), '%d'); |
|
| 270 | + OBJECT |
|
| 271 | + ); |
|
| 272 | + } |
|
| 273 | + |
|
| 274 | + |
|
| 275 | + /** |
|
| 276 | + * Gets the current transaction given the reg_url_link, or assumes the reg_url_link is in the |
|
| 277 | + * $_REQUEST global variable. Either way, tries to find the current transaction (through |
|
| 278 | + * the registration pointed to by reg_url_link), if not returns null |
|
| 279 | + * |
|
| 280 | + * @param string $reg_url_link |
|
| 281 | + * |
|
| 282 | + * @return EE_Transaction |
|
| 283 | + */ |
|
| 284 | + public function get_transaction_from_reg_url_link($reg_url_link = '') |
|
| 285 | + { |
|
| 286 | + return $this->get_one(array( |
|
| 287 | + array( |
|
| 288 | + 'Registration.REG_url_link' => ! empty($reg_url_link) ? $reg_url_link : EE_Registry::instance()->REQ->get( |
|
| 289 | + 'e_reg_url_link', |
|
| 290 | + '' |
|
| 291 | + ) |
|
| 292 | + ) |
|
| 293 | + )); |
|
| 294 | + } |
|
| 295 | + |
|
| 296 | + |
|
| 297 | + /** |
|
| 298 | + * Updates the provided EE_Transaction with all the applicable payments |
|
| 299 | + * (or fetch the EE_Transaction from its ID) |
|
| 300 | + * |
|
| 301 | + * @deprecated |
|
| 302 | + * |
|
| 303 | + * @param EE_Transaction|int $transaction_obj_or_id |
|
| 304 | + * @param boolean $save_txn whether or not to save the transaction during this function call |
|
| 305 | + * |
|
| 306 | + * @return boolean |
|
| 307 | + * @throws \EE_Error |
|
| 308 | + */ |
|
| 309 | + public function update_based_on_payments($transaction_obj_or_id, $save_txn = true) |
|
| 310 | + { |
|
| 311 | + EE_Error::doing_it_wrong( |
|
| 312 | + __CLASS__ . '::' . __FUNCTION__, |
|
| 313 | + sprintf( |
|
| 314 | + __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
| 315 | + 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
|
| 316 | + ), |
|
| 317 | + '4.6.0' |
|
| 318 | + ); |
|
| 319 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 320 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 321 | + |
|
| 322 | + return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
| 323 | + $this->ensure_is_obj($transaction_obj_or_id) |
|
| 324 | + ); |
|
| 325 | + } |
|
| 326 | + |
|
| 327 | + /** |
|
| 328 | + * Deletes "junk" transactions that were probably added by bots. There might be TONS |
|
| 329 | + * of these, so we are very careful to NOT select (which the models do even when deleting), |
|
| 330 | + * and so we only use wpdb directly and only do minimal joins. |
|
| 331 | + * Transactions are considered "junk" if they're failed for longer than a week. |
|
| 332 | + * Also, there is an extra check for payments related to the transaction, because if a transaction has a payment on |
|
| 333 | + * it, it's probably not junk (regardless of what status it has). |
|
| 334 | + * The downside to this approach is that is addons are listening for object deletions |
|
| 335 | + * on EEM_Base::delete() they won't be notified of this. However, there is an action that plugins can hook into |
|
| 336 | + * to catch these types of deletions. |
|
| 337 | + * |
|
| 338 | + * @global WPDB $wpdb |
|
| 339 | + * @return mixed |
|
| 340 | + */ |
|
| 341 | + public function delete_junk_transactions() |
|
| 342 | + { |
|
| 343 | + /** @type WPDB $wpdb */ |
|
| 344 | + global $wpdb; |
|
| 345 | + $deleted = false; |
|
| 346 | + $time_to_leave_alone = apply_filters( |
|
| 347 | + 'FHEE__EEM_Transaction__delete_junk_transactions__time_to_leave_alone', |
|
| 348 | + WEEK_IN_SECONDS |
|
| 349 | + ); |
|
| 350 | + |
|
| 351 | + |
|
| 352 | + /** |
|
| 353 | + * This allows code to filter the query arguments used for retrieving the transaction IDs to delete. |
|
| 354 | + * Useful for plugins that want to exclude transactions matching certain query parameters. |
|
| 355 | + * The query parameters should be in the format accepted by the EEM_Base model queries. |
|
| 356 | + */ |
|
| 357 | + $ids_query = apply_filters( |
|
| 358 | + 'FHEE__EEM_Transaction__delete_junk_transactions__initial_query_args', |
|
| 359 | + array( |
|
| 360 | + 0 => array( |
|
| 361 | + 'STS_ID' => EEM_Transaction::failed_status_code, |
|
| 362 | + 'Payment.PAY_ID' => array( 'IS NULL' ), |
|
| 363 | + 'TXN_timestamp' => array('<', time() - $time_to_leave_alone) |
|
| 364 | + ), |
|
| 365 | + 'order_by' => ['TXN_timestamp' => 'ASC'], |
|
| 366 | + 'limit' => 1000 |
|
| 367 | + ), |
|
| 368 | + $time_to_leave_alone |
|
| 369 | + ); |
|
| 370 | + |
|
| 371 | + |
|
| 372 | + /** |
|
| 373 | + * This filter is for when code needs to filter the list of transaction ids that represent transactions |
|
| 374 | + * about to be deleted based on some other criteria that isn't easily done via the query args filter. |
|
| 375 | + */ |
|
| 376 | + $txn_ids = apply_filters( |
|
| 377 | + 'FHEE__EEM_Transaction__delete_junk_transactions__transaction_ids_to_delete', |
|
| 378 | + EEM_Transaction::instance()->get_col($ids_query, 'TXN_ID'), |
|
| 379 | + $time_to_leave_alone |
|
| 380 | + ); |
|
| 381 | + // now that we have the ids to delete |
|
| 382 | + if (! empty($txn_ids) && is_array($txn_ids)) { |
|
| 383 | + // first, make sure these TXN's are removed the "ee_locked_transactions" array |
|
| 384 | + EEM_Transaction::unset_locked_transactions($txn_ids); |
|
| 385 | + |
|
| 386 | + // Create IDs placeholder. |
|
| 387 | + $placeholders = array_fill(0, count($txn_ids), '%d'); |
|
| 388 | 388 | |
| 389 | - // Glue it together to use inside $wpdb->prepare. |
|
| 390 | - $format = implode(', ', $placeholders); |
|
| 391 | - |
|
| 392 | - // let's get deletin'... |
|
| 393 | - // We got the ids from the original query to get them FROM |
|
| 394 | - // the db (which is sanitized) so no need to prepare them again. |
|
| 395 | - $query = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids); |
|
| 396 | - $deleted = $wpdb->query($query); |
|
| 397 | - } |
|
| 398 | - if ($deleted) { |
|
| 399 | - /** |
|
| 400 | - * Allows code to do something after the transactions have been deleted. |
|
| 401 | - */ |
|
| 402 | - do_action('AHEE__EEM_Transaction__delete_junk_transactions__successful_deletion', $txn_ids); |
|
| 403 | - } |
|
| 404 | - |
|
| 405 | - return $deleted; |
|
| 406 | - } |
|
| 407 | - |
|
| 408 | - |
|
| 409 | - /** |
|
| 410 | - * @param array $transaction_IDs |
|
| 411 | - * |
|
| 412 | - * @return bool |
|
| 413 | - */ |
|
| 414 | - public static function unset_locked_transactions(array $transaction_IDs) |
|
| 415 | - { |
|
| 416 | - $locked_transactions = get_option('ee_locked_transactions', array()); |
|
| 417 | - $update = false; |
|
| 418 | - foreach ($transaction_IDs as $TXN_ID) { |
|
| 419 | - if (isset($locked_transactions[ $TXN_ID ])) { |
|
| 420 | - unset($locked_transactions[ $TXN_ID ]); |
|
| 421 | - $update = true; |
|
| 422 | - } |
|
| 423 | - } |
|
| 424 | - if ($update) { |
|
| 425 | - update_option('ee_locked_transactions', $locked_transactions); |
|
| 426 | - } |
|
| 427 | - |
|
| 428 | - return $update; |
|
| 429 | - } |
|
| 430 | - |
|
| 431 | - |
|
| 432 | - |
|
| 433 | - /** |
|
| 434 | - * returns an array of EE_Transaction objects whose timestamp is greater than |
|
| 435 | - * the current time minus the session lifespan, which defaults to 60 minutes |
|
| 436 | - * |
|
| 437 | - * @return EE_Base_Class[]|EE_Transaction[] |
|
| 438 | - * @throws EE_Error |
|
| 439 | - * @throws InvalidArgumentException |
|
| 440 | - * @throws InvalidDataTypeException |
|
| 441 | - * @throws InvalidInterfaceException |
|
| 442 | - */ |
|
| 443 | - public function get_transactions_in_progress() |
|
| 444 | - { |
|
| 445 | - return $this->_get_transactions_in_progress(); |
|
| 446 | - } |
|
| 447 | - |
|
| 448 | - |
|
| 449 | - |
|
| 450 | - /** |
|
| 451 | - * returns an array of EE_Transaction objects whose timestamp is less than |
|
| 452 | - * the current time minus the session lifespan, which defaults to 60 minutes |
|
| 453 | - * |
|
| 454 | - * @return EE_Base_Class[]|EE_Transaction[] |
|
| 455 | - * @throws EE_Error |
|
| 456 | - * @throws InvalidArgumentException |
|
| 457 | - * @throws InvalidDataTypeException |
|
| 458 | - * @throws InvalidInterfaceException |
|
| 459 | - */ |
|
| 460 | - public function get_transactions_not_in_progress() |
|
| 461 | - { |
|
| 462 | - return $this->_get_transactions_in_progress('<='); |
|
| 463 | - } |
|
| 464 | - |
|
| 465 | - |
|
| 466 | - |
|
| 467 | - /** |
|
| 468 | - * @param string $comparison |
|
| 469 | - * @return EE_Base_Class[]|EE_Transaction[] |
|
| 470 | - * @throws EE_Error |
|
| 471 | - * @throws InvalidArgumentException |
|
| 472 | - * @throws InvalidDataTypeException |
|
| 473 | - * @throws InvalidInterfaceException |
|
| 474 | - */ |
|
| 475 | - private function _get_transactions_in_progress($comparison = '>=') |
|
| 476 | - { |
|
| 477 | - $comparison = $comparison === '>=' || $comparison === '<=' |
|
| 478 | - ? $comparison |
|
| 479 | - : '>='; |
|
| 480 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
| 481 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
| 482 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
| 483 | - ); |
|
| 484 | - return $this->get_all( |
|
| 485 | - array( |
|
| 486 | - array( |
|
| 487 | - 'TXN_timestamp' => array( |
|
| 488 | - $comparison, |
|
| 489 | - $session_lifespan->expiration() |
|
| 490 | - ), |
|
| 491 | - 'STS_ID' => array( |
|
| 492 | - '!=', |
|
| 493 | - EEM_Transaction::complete_status_code |
|
| 494 | - ), |
|
| 495 | - ) |
|
| 496 | - ) |
|
| 497 | - ); |
|
| 498 | - } |
|
| 389 | + // Glue it together to use inside $wpdb->prepare. |
|
| 390 | + $format = implode(', ', $placeholders); |
|
| 391 | + |
|
| 392 | + // let's get deletin'... |
|
| 393 | + // We got the ids from the original query to get them FROM |
|
| 394 | + // the db (which is sanitized) so no need to prepare them again. |
|
| 395 | + $query = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids); |
|
| 396 | + $deleted = $wpdb->query($query); |
|
| 397 | + } |
|
| 398 | + if ($deleted) { |
|
| 399 | + /** |
|
| 400 | + * Allows code to do something after the transactions have been deleted. |
|
| 401 | + */ |
|
| 402 | + do_action('AHEE__EEM_Transaction__delete_junk_transactions__successful_deletion', $txn_ids); |
|
| 403 | + } |
|
| 404 | + |
|
| 405 | + return $deleted; |
|
| 406 | + } |
|
| 407 | + |
|
| 408 | + |
|
| 409 | + /** |
|
| 410 | + * @param array $transaction_IDs |
|
| 411 | + * |
|
| 412 | + * @return bool |
|
| 413 | + */ |
|
| 414 | + public static function unset_locked_transactions(array $transaction_IDs) |
|
| 415 | + { |
|
| 416 | + $locked_transactions = get_option('ee_locked_transactions', array()); |
|
| 417 | + $update = false; |
|
| 418 | + foreach ($transaction_IDs as $TXN_ID) { |
|
| 419 | + if (isset($locked_transactions[ $TXN_ID ])) { |
|
| 420 | + unset($locked_transactions[ $TXN_ID ]); |
|
| 421 | + $update = true; |
|
| 422 | + } |
|
| 423 | + } |
|
| 424 | + if ($update) { |
|
| 425 | + update_option('ee_locked_transactions', $locked_transactions); |
|
| 426 | + } |
|
| 427 | + |
|
| 428 | + return $update; |
|
| 429 | + } |
|
| 430 | + |
|
| 431 | + |
|
| 432 | + |
|
| 433 | + /** |
|
| 434 | + * returns an array of EE_Transaction objects whose timestamp is greater than |
|
| 435 | + * the current time minus the session lifespan, which defaults to 60 minutes |
|
| 436 | + * |
|
| 437 | + * @return EE_Base_Class[]|EE_Transaction[] |
|
| 438 | + * @throws EE_Error |
|
| 439 | + * @throws InvalidArgumentException |
|
| 440 | + * @throws InvalidDataTypeException |
|
| 441 | + * @throws InvalidInterfaceException |
|
| 442 | + */ |
|
| 443 | + public function get_transactions_in_progress() |
|
| 444 | + { |
|
| 445 | + return $this->_get_transactions_in_progress(); |
|
| 446 | + } |
|
| 447 | + |
|
| 448 | + |
|
| 449 | + |
|
| 450 | + /** |
|
| 451 | + * returns an array of EE_Transaction objects whose timestamp is less than |
|
| 452 | + * the current time minus the session lifespan, which defaults to 60 minutes |
|
| 453 | + * |
|
| 454 | + * @return EE_Base_Class[]|EE_Transaction[] |
|
| 455 | + * @throws EE_Error |
|
| 456 | + * @throws InvalidArgumentException |
|
| 457 | + * @throws InvalidDataTypeException |
|
| 458 | + * @throws InvalidInterfaceException |
|
| 459 | + */ |
|
| 460 | + public function get_transactions_not_in_progress() |
|
| 461 | + { |
|
| 462 | + return $this->_get_transactions_in_progress('<='); |
|
| 463 | + } |
|
| 464 | + |
|
| 465 | + |
|
| 466 | + |
|
| 467 | + /** |
|
| 468 | + * @param string $comparison |
|
| 469 | + * @return EE_Base_Class[]|EE_Transaction[] |
|
| 470 | + * @throws EE_Error |
|
| 471 | + * @throws InvalidArgumentException |
|
| 472 | + * @throws InvalidDataTypeException |
|
| 473 | + * @throws InvalidInterfaceException |
|
| 474 | + */ |
|
| 475 | + private function _get_transactions_in_progress($comparison = '>=') |
|
| 476 | + { |
|
| 477 | + $comparison = $comparison === '>=' || $comparison === '<=' |
|
| 478 | + ? $comparison |
|
| 479 | + : '>='; |
|
| 480 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
| 481 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
| 482 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
| 483 | + ); |
|
| 484 | + return $this->get_all( |
|
| 485 | + array( |
|
| 486 | + array( |
|
| 487 | + 'TXN_timestamp' => array( |
|
| 488 | + $comparison, |
|
| 489 | + $session_lifespan->expiration() |
|
| 490 | + ), |
|
| 491 | + 'STS_ID' => array( |
|
| 492 | + '!=', |
|
| 493 | + EEM_Transaction::complete_status_code |
|
| 494 | + ), |
|
| 495 | + ) |
|
| 496 | + ) |
|
| 497 | + ); |
|
| 498 | + } |
|
| 499 | 499 | } |
@@ -140,7 +140,7 @@ discard block |
||
| 140 | 140 | ), |
| 141 | 141 | ) |
| 142 | 142 | ); |
| 143 | - $this->_model_relations = array( |
|
| 143 | + $this->_model_relations = array( |
|
| 144 | 144 | 'Registration' => new EE_Has_Many_Relation(), |
| 145 | 145 | 'Payment' => new EE_Has_Many_Relation(), |
| 146 | 146 | 'Status' => new EE_Belongs_To_Relation(), |
@@ -205,7 +205,7 @@ discard block |
||
| 205 | 205 | ), |
| 206 | 206 | OBJECT, |
| 207 | 207 | array( |
| 208 | - 'txnDate' => array('DATE(' . $query_interval . ')', '%s'), |
|
| 208 | + 'txnDate' => array('DATE('.$query_interval.')', '%s'), |
|
| 209 | 209 | 'revenue' => array('SUM(TransactionTable.TXN_paid)', '%d') |
| 210 | 210 | ) |
| 211 | 211 | ); |
@@ -225,17 +225,17 @@ discard block |
||
| 225 | 225 | public function get_revenue_per_event_report($period = '-1 month') |
| 226 | 226 | { |
| 227 | 227 | global $wpdb; |
| 228 | - $transaction_table = $wpdb->prefix . 'esp_transaction'; |
|
| 229 | - $registration_table = $wpdb->prefix . 'esp_registration'; |
|
| 230 | - $registration_payment_table = $wpdb->prefix . 'esp_registration_payment'; |
|
| 228 | + $transaction_table = $wpdb->prefix.'esp_transaction'; |
|
| 229 | + $registration_table = $wpdb->prefix.'esp_registration'; |
|
| 230 | + $registration_payment_table = $wpdb->prefix.'esp_registration_payment'; |
|
| 231 | 231 | $event_table = $wpdb->posts; |
| 232 | - $payment_table = $wpdb->prefix . 'esp_payment'; |
|
| 232 | + $payment_table = $wpdb->prefix.'esp_payment'; |
|
| 233 | 233 | $sql_date = date('Y-m-d H:i:s', strtotime($period)); |
| 234 | 234 | $approved_payment_status = EEM_Payment::status_id_approved; |
| 235 | 235 | $extra_event_on_join = ''; |
| 236 | 236 | // exclude events not authored by user if permissions in effect |
| 237 | - if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 238 | - $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id(); |
|
| 237 | + if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) { |
|
| 238 | + $extra_event_on_join = ' AND Event.post_author = '.get_current_user_id(); |
|
| 239 | 239 | } |
| 240 | 240 | |
| 241 | 241 | return $wpdb->get_results( |
@@ -309,7 +309,7 @@ discard block |
||
| 309 | 309 | public function update_based_on_payments($transaction_obj_or_id, $save_txn = true) |
| 310 | 310 | { |
| 311 | 311 | EE_Error::doing_it_wrong( |
| 312 | - __CLASS__ . '::' . __FUNCTION__, |
|
| 312 | + __CLASS__.'::'.__FUNCTION__, |
|
| 313 | 313 | sprintf( |
| 314 | 314 | __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
| 315 | 315 | 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
@@ -359,7 +359,7 @@ discard block |
||
| 359 | 359 | array( |
| 360 | 360 | 0 => array( |
| 361 | 361 | 'STS_ID' => EEM_Transaction::failed_status_code, |
| 362 | - 'Payment.PAY_ID' => array( 'IS NULL' ), |
|
| 362 | + 'Payment.PAY_ID' => array('IS NULL'), |
|
| 363 | 363 | 'TXN_timestamp' => array('<', time() - $time_to_leave_alone) |
| 364 | 364 | ), |
| 365 | 365 | 'order_by' => ['TXN_timestamp' => 'ASC'], |
@@ -379,7 +379,7 @@ discard block |
||
| 379 | 379 | $time_to_leave_alone |
| 380 | 380 | ); |
| 381 | 381 | // now that we have the ids to delete |
| 382 | - if (! empty($txn_ids) && is_array($txn_ids)) { |
|
| 382 | + if ( ! empty($txn_ids) && is_array($txn_ids)) { |
|
| 383 | 383 | // first, make sure these TXN's are removed the "ee_locked_transactions" array |
| 384 | 384 | EEM_Transaction::unset_locked_transactions($txn_ids); |
| 385 | 385 | |
@@ -392,7 +392,7 @@ discard block |
||
| 392 | 392 | // let's get deletin'... |
| 393 | 393 | // We got the ids from the original query to get them FROM |
| 394 | 394 | // the db (which is sanitized) so no need to prepare them again. |
| 395 | - $query = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids); |
|
| 395 | + $query = $wpdb->prepare("DELETE FROM ".$this->table()." WHERE TXN_ID IN ( $format )", $txn_ids); |
|
| 396 | 396 | $deleted = $wpdb->query($query); |
| 397 | 397 | } |
| 398 | 398 | if ($deleted) { |
@@ -416,8 +416,8 @@ discard block |
||
| 416 | 416 | $locked_transactions = get_option('ee_locked_transactions', array()); |
| 417 | 417 | $update = false; |
| 418 | 418 | foreach ($transaction_IDs as $TXN_ID) { |
| 419 | - if (isset($locked_transactions[ $TXN_ID ])) { |
|
| 420 | - unset($locked_transactions[ $TXN_ID ]); |
|
| 419 | + if (isset($locked_transactions[$TXN_ID])) { |
|
| 420 | + unset($locked_transactions[$TXN_ID]); |
|
| 421 | 421 | $update = true; |
| 422 | 422 | } |
| 423 | 423 | } |
@@ -16,1267 +16,1267 @@ |
||
| 16 | 16 | { |
| 17 | 17 | |
| 18 | 18 | |
| 19 | - /** |
|
| 20 | - * This is used to hold the reports template data which is setup early in the request. |
|
| 21 | - * |
|
| 22 | - * @type array |
|
| 23 | - */ |
|
| 24 | - protected $_reports_template_data = array(); |
|
| 19 | + /** |
|
| 20 | + * This is used to hold the reports template data which is setup early in the request. |
|
| 21 | + * |
|
| 22 | + * @type array |
|
| 23 | + */ |
|
| 24 | + protected $_reports_template_data = array(); |
|
| 25 | 25 | |
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * Extend_Registrations_Admin_Page constructor. |
|
| 29 | - * |
|
| 30 | - * @param bool $routing |
|
| 31 | - */ |
|
| 32 | - public function __construct($routing = true) |
|
| 33 | - { |
|
| 34 | - parent::__construct($routing); |
|
| 35 | - if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 37 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 38 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 39 | - } |
|
| 40 | - } |
|
| 27 | + /** |
|
| 28 | + * Extend_Registrations_Admin_Page constructor. |
|
| 29 | + * |
|
| 30 | + * @param bool $routing |
|
| 31 | + */ |
|
| 32 | + public function __construct($routing = true) |
|
| 33 | + { |
|
| 34 | + parent::__construct($routing); |
|
| 35 | + if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 37 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 38 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 39 | + } |
|
| 40 | + } |
|
| 41 | 41 | |
| 42 | 42 | |
| 43 | - /** |
|
| 44 | - * Extending page configuration. |
|
| 45 | - */ |
|
| 46 | - protected function _extend_page_config() |
|
| 47 | - { |
|
| 48 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 49 | - $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
| 50 | - ? $this->_req_data['_REG_ID'] |
|
| 51 | - : 0; |
|
| 52 | - $new_page_routes = array( |
|
| 53 | - 'reports' => array( |
|
| 54 | - 'func' => '_registration_reports', |
|
| 55 | - 'capability' => 'ee_read_registrations', |
|
| 56 | - ), |
|
| 57 | - 'registration_checkins' => array( |
|
| 58 | - 'func' => '_registration_checkin_list_table', |
|
| 59 | - 'capability' => 'ee_read_checkins', |
|
| 60 | - ), |
|
| 61 | - 'newsletter_selected_send' => array( |
|
| 62 | - 'func' => '_newsletter_selected_send', |
|
| 63 | - 'noheader' => true, |
|
| 64 | - 'capability' => 'ee_send_message', |
|
| 65 | - ), |
|
| 66 | - 'delete_checkin_rows' => array( |
|
| 67 | - 'func' => '_delete_checkin_rows', |
|
| 68 | - 'noheader' => true, |
|
| 69 | - 'capability' => 'ee_delete_checkins', |
|
| 70 | - ), |
|
| 71 | - 'delete_checkin_row' => array( |
|
| 72 | - 'func' => '_delete_checkin_row', |
|
| 73 | - 'noheader' => true, |
|
| 74 | - 'capability' => 'ee_delete_checkin', |
|
| 75 | - 'obj_id' => $reg_id, |
|
| 76 | - ), |
|
| 77 | - 'toggle_checkin_status' => array( |
|
| 78 | - 'func' => '_toggle_checkin_status', |
|
| 79 | - 'noheader' => true, |
|
| 80 | - 'capability' => 'ee_edit_checkin', |
|
| 81 | - 'obj_id' => $reg_id, |
|
| 82 | - ), |
|
| 83 | - 'toggle_checkin_status_bulk' => array( |
|
| 84 | - 'func' => '_toggle_checkin_status', |
|
| 85 | - 'noheader' => true, |
|
| 86 | - 'capability' => 'ee_edit_checkins', |
|
| 87 | - ), |
|
| 88 | - 'event_registrations' => array( |
|
| 89 | - 'func' => '_event_registrations_list_table', |
|
| 90 | - 'capability' => 'ee_read_checkins', |
|
| 91 | - ), |
|
| 92 | - 'registrations_checkin_report' => array( |
|
| 93 | - 'func' => '_registrations_checkin_report', |
|
| 94 | - 'noheader' => true, |
|
| 95 | - 'capability' => 'ee_read_registrations', |
|
| 96 | - ), |
|
| 97 | - ); |
|
| 98 | - $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
| 99 | - $new_page_config = array( |
|
| 100 | - 'reports' => array( |
|
| 101 | - 'nav' => array( |
|
| 102 | - 'label' => esc_html__('Reports', 'event_espresso'), |
|
| 103 | - 'order' => 30, |
|
| 104 | - ), |
|
| 105 | - 'help_tabs' => array( |
|
| 106 | - 'registrations_reports_help_tab' => array( |
|
| 107 | - 'title' => esc_html__('Registration Reports', 'event_espresso'), |
|
| 108 | - 'filename' => 'registrations_reports', |
|
| 109 | - ), |
|
| 110 | - ), |
|
| 111 | - /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
| 112 | - 'require_nonce' => false, |
|
| 113 | - ), |
|
| 114 | - 'event_registrations' => array( |
|
| 115 | - 'nav' => array( |
|
| 116 | - 'label' => esc_html__('Event Check-In', 'event_espresso'), |
|
| 117 | - 'order' => 10, |
|
| 118 | - 'persistent' => true, |
|
| 119 | - ), |
|
| 120 | - 'help_tabs' => array( |
|
| 121 | - 'registrations_event_checkin_help_tab' => array( |
|
| 122 | - 'title' => esc_html__('Registrations Event Check-In', 'event_espresso'), |
|
| 123 | - 'filename' => 'registrations_event_checkin', |
|
| 124 | - ), |
|
| 125 | - 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
| 126 | - 'title' => esc_html__('Event Check-In Table Column Headings', 'event_espresso'), |
|
| 127 | - 'filename' => 'registrations_event_checkin_table_column_headings', |
|
| 128 | - ), |
|
| 129 | - 'registrations_event_checkin_filters_help_tab' => array( |
|
| 130 | - 'title' => esc_html__('Event Check-In Filters', 'event_espresso'), |
|
| 131 | - 'filename' => 'registrations_event_checkin_filters', |
|
| 132 | - ), |
|
| 133 | - 'registrations_event_checkin_views_help_tab' => array( |
|
| 134 | - 'title' => esc_html__('Event Check-In Views', 'event_espresso'), |
|
| 135 | - 'filename' => 'registrations_event_checkin_views', |
|
| 136 | - ), |
|
| 137 | - 'registrations_event_checkin_other_help_tab' => array( |
|
| 138 | - 'title' => esc_html__('Event Check-In Other', 'event_espresso'), |
|
| 139 | - 'filename' => 'registrations_event_checkin_other', |
|
| 140 | - ), |
|
| 141 | - ), |
|
| 142 | - 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
| 143 | - 'qtips' => array('Registration_List_Table_Tips'), |
|
| 144 | - 'list_table' => 'EE_Event_Registrations_List_Table', |
|
| 145 | - 'metaboxes' => array(), |
|
| 146 | - 'require_nonce' => false, |
|
| 147 | - ), |
|
| 148 | - 'registration_checkins' => array( |
|
| 149 | - 'nav' => array( |
|
| 150 | - 'label' => esc_html__('Check-In Records', 'event_espresso'), |
|
| 151 | - 'order' => 15, |
|
| 152 | - 'persistent' => false, |
|
| 153 | - 'url' => '', |
|
| 154 | - ), |
|
| 155 | - 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
| 156 | - // 'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
| 157 | - 'metaboxes' => array(), |
|
| 158 | - 'require_nonce' => false, |
|
| 159 | - ), |
|
| 160 | - ); |
|
| 161 | - $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
| 162 | - $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
| 163 | - $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
| 164 | - } |
|
| 43 | + /** |
|
| 44 | + * Extending page configuration. |
|
| 45 | + */ |
|
| 46 | + protected function _extend_page_config() |
|
| 47 | + { |
|
| 48 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 49 | + $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
|
| 50 | + ? $this->_req_data['_REG_ID'] |
|
| 51 | + : 0; |
|
| 52 | + $new_page_routes = array( |
|
| 53 | + 'reports' => array( |
|
| 54 | + 'func' => '_registration_reports', |
|
| 55 | + 'capability' => 'ee_read_registrations', |
|
| 56 | + ), |
|
| 57 | + 'registration_checkins' => array( |
|
| 58 | + 'func' => '_registration_checkin_list_table', |
|
| 59 | + 'capability' => 'ee_read_checkins', |
|
| 60 | + ), |
|
| 61 | + 'newsletter_selected_send' => array( |
|
| 62 | + 'func' => '_newsletter_selected_send', |
|
| 63 | + 'noheader' => true, |
|
| 64 | + 'capability' => 'ee_send_message', |
|
| 65 | + ), |
|
| 66 | + 'delete_checkin_rows' => array( |
|
| 67 | + 'func' => '_delete_checkin_rows', |
|
| 68 | + 'noheader' => true, |
|
| 69 | + 'capability' => 'ee_delete_checkins', |
|
| 70 | + ), |
|
| 71 | + 'delete_checkin_row' => array( |
|
| 72 | + 'func' => '_delete_checkin_row', |
|
| 73 | + 'noheader' => true, |
|
| 74 | + 'capability' => 'ee_delete_checkin', |
|
| 75 | + 'obj_id' => $reg_id, |
|
| 76 | + ), |
|
| 77 | + 'toggle_checkin_status' => array( |
|
| 78 | + 'func' => '_toggle_checkin_status', |
|
| 79 | + 'noheader' => true, |
|
| 80 | + 'capability' => 'ee_edit_checkin', |
|
| 81 | + 'obj_id' => $reg_id, |
|
| 82 | + ), |
|
| 83 | + 'toggle_checkin_status_bulk' => array( |
|
| 84 | + 'func' => '_toggle_checkin_status', |
|
| 85 | + 'noheader' => true, |
|
| 86 | + 'capability' => 'ee_edit_checkins', |
|
| 87 | + ), |
|
| 88 | + 'event_registrations' => array( |
|
| 89 | + 'func' => '_event_registrations_list_table', |
|
| 90 | + 'capability' => 'ee_read_checkins', |
|
| 91 | + ), |
|
| 92 | + 'registrations_checkin_report' => array( |
|
| 93 | + 'func' => '_registrations_checkin_report', |
|
| 94 | + 'noheader' => true, |
|
| 95 | + 'capability' => 'ee_read_registrations', |
|
| 96 | + ), |
|
| 97 | + ); |
|
| 98 | + $this->_page_routes = array_merge($this->_page_routes, $new_page_routes); |
|
| 99 | + $new_page_config = array( |
|
| 100 | + 'reports' => array( |
|
| 101 | + 'nav' => array( |
|
| 102 | + 'label' => esc_html__('Reports', 'event_espresso'), |
|
| 103 | + 'order' => 30, |
|
| 104 | + ), |
|
| 105 | + 'help_tabs' => array( |
|
| 106 | + 'registrations_reports_help_tab' => array( |
|
| 107 | + 'title' => esc_html__('Registration Reports', 'event_espresso'), |
|
| 108 | + 'filename' => 'registrations_reports', |
|
| 109 | + ), |
|
| 110 | + ), |
|
| 111 | + /*'help_tour' => array( 'Registration_Reports_Help_Tour' ),*/ |
|
| 112 | + 'require_nonce' => false, |
|
| 113 | + ), |
|
| 114 | + 'event_registrations' => array( |
|
| 115 | + 'nav' => array( |
|
| 116 | + 'label' => esc_html__('Event Check-In', 'event_espresso'), |
|
| 117 | + 'order' => 10, |
|
| 118 | + 'persistent' => true, |
|
| 119 | + ), |
|
| 120 | + 'help_tabs' => array( |
|
| 121 | + 'registrations_event_checkin_help_tab' => array( |
|
| 122 | + 'title' => esc_html__('Registrations Event Check-In', 'event_espresso'), |
|
| 123 | + 'filename' => 'registrations_event_checkin', |
|
| 124 | + ), |
|
| 125 | + 'registrations_event_checkin_table_column_headings_help_tab' => array( |
|
| 126 | + 'title' => esc_html__('Event Check-In Table Column Headings', 'event_espresso'), |
|
| 127 | + 'filename' => 'registrations_event_checkin_table_column_headings', |
|
| 128 | + ), |
|
| 129 | + 'registrations_event_checkin_filters_help_tab' => array( |
|
| 130 | + 'title' => esc_html__('Event Check-In Filters', 'event_espresso'), |
|
| 131 | + 'filename' => 'registrations_event_checkin_filters', |
|
| 132 | + ), |
|
| 133 | + 'registrations_event_checkin_views_help_tab' => array( |
|
| 134 | + 'title' => esc_html__('Event Check-In Views', 'event_espresso'), |
|
| 135 | + 'filename' => 'registrations_event_checkin_views', |
|
| 136 | + ), |
|
| 137 | + 'registrations_event_checkin_other_help_tab' => array( |
|
| 138 | + 'title' => esc_html__('Event Check-In Other', 'event_espresso'), |
|
| 139 | + 'filename' => 'registrations_event_checkin_other', |
|
| 140 | + ), |
|
| 141 | + ), |
|
| 142 | + 'help_tour' => array('Event_Checkin_Help_Tour'), |
|
| 143 | + 'qtips' => array('Registration_List_Table_Tips'), |
|
| 144 | + 'list_table' => 'EE_Event_Registrations_List_Table', |
|
| 145 | + 'metaboxes' => array(), |
|
| 146 | + 'require_nonce' => false, |
|
| 147 | + ), |
|
| 148 | + 'registration_checkins' => array( |
|
| 149 | + 'nav' => array( |
|
| 150 | + 'label' => esc_html__('Check-In Records', 'event_espresso'), |
|
| 151 | + 'order' => 15, |
|
| 152 | + 'persistent' => false, |
|
| 153 | + 'url' => '', |
|
| 154 | + ), |
|
| 155 | + 'list_table' => 'EE_Registration_CheckIn_List_Table', |
|
| 156 | + // 'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ), |
|
| 157 | + 'metaboxes' => array(), |
|
| 158 | + 'require_nonce' => false, |
|
| 159 | + ), |
|
| 160 | + ); |
|
| 161 | + $this->_page_config = array_merge($this->_page_config, $new_page_config); |
|
| 162 | + $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table'; |
|
| 163 | + $this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table'; |
|
| 164 | + } |
|
| 165 | 165 | |
| 166 | 166 | |
| 167 | - /** |
|
| 168 | - * Ajax hooks for all routes in this page. |
|
| 169 | - */ |
|
| 170 | - protected function _ajax_hooks() |
|
| 171 | - { |
|
| 172 | - parent::_ajax_hooks(); |
|
| 173 | - add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
| 174 | - } |
|
| 167 | + /** |
|
| 168 | + * Ajax hooks for all routes in this page. |
|
| 169 | + */ |
|
| 170 | + protected function _ajax_hooks() |
|
| 171 | + { |
|
| 172 | + parent::_ajax_hooks(); |
|
| 173 | + add_action('wp_ajax_get_newsletter_form_content', array($this, 'get_newsletter_form_content')); |
|
| 174 | + } |
|
| 175 | 175 | |
| 176 | 176 | |
| 177 | - /** |
|
| 178 | - * Global scripts for all routes in this page. |
|
| 179 | - */ |
|
| 180 | - public function load_scripts_styles() |
|
| 181 | - { |
|
| 182 | - parent::load_scripts_styles(); |
|
| 183 | - // if newsletter message type is active then let's add filter and load js for it. |
|
| 184 | - if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
| 185 | - // enqueue newsletter js |
|
| 186 | - wp_enqueue_script( |
|
| 187 | - 'ee-newsletter-trigger', |
|
| 188 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 189 | - array('ee-dialog'), |
|
| 190 | - EVENT_ESPRESSO_VERSION, |
|
| 191 | - true |
|
| 192 | - ); |
|
| 193 | - wp_enqueue_style( |
|
| 194 | - 'ee-newsletter-trigger-css', |
|
| 195 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 196 | - array(), |
|
| 197 | - EVENT_ESPRESSO_VERSION |
|
| 198 | - ); |
|
| 199 | - // hook in buttons for newsletter message type trigger. |
|
| 200 | - add_action( |
|
| 201 | - 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
| 202 | - array($this, 'add_newsletter_action_buttons'), |
|
| 203 | - 10 |
|
| 204 | - ); |
|
| 205 | - } |
|
| 206 | - } |
|
| 177 | + /** |
|
| 178 | + * Global scripts for all routes in this page. |
|
| 179 | + */ |
|
| 180 | + public function load_scripts_styles() |
|
| 181 | + { |
|
| 182 | + parent::load_scripts_styles(); |
|
| 183 | + // if newsletter message type is active then let's add filter and load js for it. |
|
| 184 | + if (EEH_MSG_Template::is_mt_active('newsletter')) { |
|
| 185 | + // enqueue newsletter js |
|
| 186 | + wp_enqueue_script( |
|
| 187 | + 'ee-newsletter-trigger', |
|
| 188 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 189 | + array('ee-dialog'), |
|
| 190 | + EVENT_ESPRESSO_VERSION, |
|
| 191 | + true |
|
| 192 | + ); |
|
| 193 | + wp_enqueue_style( |
|
| 194 | + 'ee-newsletter-trigger-css', |
|
| 195 | + REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 196 | + array(), |
|
| 197 | + EVENT_ESPRESSO_VERSION |
|
| 198 | + ); |
|
| 199 | + // hook in buttons for newsletter message type trigger. |
|
| 200 | + add_action( |
|
| 201 | + 'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', |
|
| 202 | + array($this, 'add_newsletter_action_buttons'), |
|
| 203 | + 10 |
|
| 204 | + ); |
|
| 205 | + } |
|
| 206 | + } |
|
| 207 | 207 | |
| 208 | 208 | |
| 209 | - /** |
|
| 210 | - * Scripts and styles for just the reports route. |
|
| 211 | - */ |
|
| 212 | - public function load_scripts_styles_reports() |
|
| 213 | - { |
|
| 214 | - wp_register_script( |
|
| 215 | - 'ee-reg-reports-js', |
|
| 216 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 217 | - array('google-charts'), |
|
| 218 | - EVENT_ESPRESSO_VERSION, |
|
| 219 | - true |
|
| 220 | - ); |
|
| 221 | - wp_enqueue_script('ee-reg-reports-js'); |
|
| 222 | - $this->_registration_reports_js_setup(); |
|
| 223 | - } |
|
| 209 | + /** |
|
| 210 | + * Scripts and styles for just the reports route. |
|
| 211 | + */ |
|
| 212 | + public function load_scripts_styles_reports() |
|
| 213 | + { |
|
| 214 | + wp_register_script( |
|
| 215 | + 'ee-reg-reports-js', |
|
| 216 | + REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 217 | + array('google-charts'), |
|
| 218 | + EVENT_ESPRESSO_VERSION, |
|
| 219 | + true |
|
| 220 | + ); |
|
| 221 | + wp_enqueue_script('ee-reg-reports-js'); |
|
| 222 | + $this->_registration_reports_js_setup(); |
|
| 223 | + } |
|
| 224 | 224 | |
| 225 | 225 | |
| 226 | - /** |
|
| 227 | - * Register screen options for event_registrations route. |
|
| 228 | - */ |
|
| 229 | - protected function _add_screen_options_event_registrations() |
|
| 230 | - { |
|
| 231 | - $this->_per_page_screen_option(); |
|
| 232 | - } |
|
| 226 | + /** |
|
| 227 | + * Register screen options for event_registrations route. |
|
| 228 | + */ |
|
| 229 | + protected function _add_screen_options_event_registrations() |
|
| 230 | + { |
|
| 231 | + $this->_per_page_screen_option(); |
|
| 232 | + } |
|
| 233 | 233 | |
| 234 | 234 | |
| 235 | - /** |
|
| 236 | - * Register screen options for registration_checkins route |
|
| 237 | - */ |
|
| 238 | - protected function _add_screen_options_registration_checkins() |
|
| 239 | - { |
|
| 240 | - $page_title = $this->_admin_page_title; |
|
| 241 | - $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso'); |
|
| 242 | - $this->_per_page_screen_option(); |
|
| 243 | - $this->_admin_page_title = $page_title; |
|
| 244 | - } |
|
| 235 | + /** |
|
| 236 | + * Register screen options for registration_checkins route |
|
| 237 | + */ |
|
| 238 | + protected function _add_screen_options_registration_checkins() |
|
| 239 | + { |
|
| 240 | + $page_title = $this->_admin_page_title; |
|
| 241 | + $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso'); |
|
| 242 | + $this->_per_page_screen_option(); |
|
| 243 | + $this->_admin_page_title = $page_title; |
|
| 244 | + } |
|
| 245 | 245 | |
| 246 | 246 | |
| 247 | - /** |
|
| 248 | - * Set views property for event_registrations route. |
|
| 249 | - */ |
|
| 250 | - protected function _set_list_table_views_event_registrations() |
|
| 251 | - { |
|
| 252 | - $this->_views = array( |
|
| 253 | - 'all' => array( |
|
| 254 | - 'slug' => 'all', |
|
| 255 | - 'label' => esc_html__('All', 'event_espresso'), |
|
| 256 | - 'count' => 0, |
|
| 257 | - 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
| 258 | - ? array() |
|
| 259 | - : array( |
|
| 260 | - 'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'), |
|
| 261 | - ), |
|
| 262 | - ), |
|
| 263 | - ); |
|
| 264 | - } |
|
| 247 | + /** |
|
| 248 | + * Set views property for event_registrations route. |
|
| 249 | + */ |
|
| 250 | + protected function _set_list_table_views_event_registrations() |
|
| 251 | + { |
|
| 252 | + $this->_views = array( |
|
| 253 | + 'all' => array( |
|
| 254 | + 'slug' => 'all', |
|
| 255 | + 'label' => esc_html__('All', 'event_espresso'), |
|
| 256 | + 'count' => 0, |
|
| 257 | + 'bulk_action' => ! isset($this->_req_data['event_id']) |
|
| 258 | + ? array() |
|
| 259 | + : array( |
|
| 260 | + 'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'), |
|
| 261 | + ), |
|
| 262 | + ), |
|
| 263 | + ); |
|
| 264 | + } |
|
| 265 | 265 | |
| 266 | 266 | |
| 267 | - /** |
|
| 268 | - * Set views property for registration_checkins route. |
|
| 269 | - */ |
|
| 270 | - protected function _set_list_table_views_registration_checkins() |
|
| 271 | - { |
|
| 272 | - $this->_views = array( |
|
| 273 | - 'all' => array( |
|
| 274 | - 'slug' => 'all', |
|
| 275 | - 'label' => esc_html__('All', 'event_espresso'), |
|
| 276 | - 'count' => 0, |
|
| 277 | - 'bulk_action' => array('delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')), |
|
| 278 | - ), |
|
| 279 | - ); |
|
| 280 | - } |
|
| 267 | + /** |
|
| 268 | + * Set views property for registration_checkins route. |
|
| 269 | + */ |
|
| 270 | + protected function _set_list_table_views_registration_checkins() |
|
| 271 | + { |
|
| 272 | + $this->_views = array( |
|
| 273 | + 'all' => array( |
|
| 274 | + 'slug' => 'all', |
|
| 275 | + 'label' => esc_html__('All', 'event_espresso'), |
|
| 276 | + 'count' => 0, |
|
| 277 | + 'bulk_action' => array('delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')), |
|
| 278 | + ), |
|
| 279 | + ); |
|
| 280 | + } |
|
| 281 | 281 | |
| 282 | 282 | |
| 283 | - /** |
|
| 284 | - * callback for ajax action. |
|
| 285 | - * |
|
| 286 | - * @since 4.3.0 |
|
| 287 | - * @return void (JSON) |
|
| 288 | - * @throws EE_Error |
|
| 289 | - * @throws InvalidArgumentException |
|
| 290 | - * @throws InvalidDataTypeException |
|
| 291 | - * @throws InvalidInterfaceException |
|
| 292 | - */ |
|
| 293 | - public function get_newsletter_form_content() |
|
| 294 | - { |
|
| 295 | - // do a nonce check cause we're not coming in from an normal route here. |
|
| 296 | - $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
| 297 | - $this->_req_data['get_newsletter_form_content_nonce'] |
|
| 298 | - ) : ''; |
|
| 299 | - $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
| 300 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
| 301 | - // let's get the mtp for the incoming MTP_ ID |
|
| 302 | - if (! isset($this->_req_data['GRP_ID'])) { |
|
| 303 | - EE_Error::add_error( |
|
| 304 | - esc_html__( |
|
| 305 | - 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
|
| 306 | - 'event_espresso' |
|
| 307 | - ), |
|
| 308 | - __FILE__, |
|
| 309 | - __FUNCTION__, |
|
| 310 | - __LINE__ |
|
| 311 | - ); |
|
| 312 | - $this->_template_args['success'] = false; |
|
| 313 | - $this->_template_args['error'] = true; |
|
| 314 | - $this->_return_json(); |
|
| 315 | - } |
|
| 316 | - $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
| 317 | - if (! $MTPG instanceof EE_Message_Template_Group) { |
|
| 318 | - EE_Error::add_error( |
|
| 319 | - sprintf( |
|
| 320 | - esc_html__( |
|
| 321 | - 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
| 322 | - 'event_espresso' |
|
| 323 | - ), |
|
| 324 | - $this->_req_data['GRP_ID'] |
|
| 325 | - ), |
|
| 326 | - __FILE__, |
|
| 327 | - __FUNCTION__, |
|
| 328 | - __LINE__ |
|
| 329 | - ); |
|
| 330 | - $this->_template_args['success'] = false; |
|
| 331 | - $this->_template_args['error'] = true; |
|
| 332 | - $this->_return_json(); |
|
| 333 | - } |
|
| 334 | - $MTPs = $MTPG->context_templates(); |
|
| 335 | - $MTPs = $MTPs['attendee']; |
|
| 336 | - $template_fields = array(); |
|
| 337 | - /** @var EE_Message_Template $MTP */ |
|
| 338 | - foreach ($MTPs as $MTP) { |
|
| 339 | - $field = $MTP->get('MTP_template_field'); |
|
| 340 | - if ($field === 'content') { |
|
| 341 | - $content = $MTP->get('MTP_content'); |
|
| 342 | - if (! empty($content['newsletter_content'])) { |
|
| 343 | - $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
| 344 | - } |
|
| 345 | - continue; |
|
| 346 | - } |
|
| 347 | - $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
| 348 | - } |
|
| 349 | - $this->_template_args['success'] = true; |
|
| 350 | - $this->_template_args['error'] = false; |
|
| 351 | - $this->_template_args['data'] = array( |
|
| 352 | - 'batch_message_from' => isset($template_fields['from']) |
|
| 353 | - ? $template_fields['from'] |
|
| 354 | - : '', |
|
| 355 | - 'batch_message_subject' => isset($template_fields['subject']) |
|
| 356 | - ? $template_fields['subject'] |
|
| 357 | - : '', |
|
| 358 | - 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
| 359 | - ? $template_fields['newsletter_content'] |
|
| 360 | - : '', |
|
| 361 | - ); |
|
| 362 | - $this->_return_json(); |
|
| 363 | - } |
|
| 283 | + /** |
|
| 284 | + * callback for ajax action. |
|
| 285 | + * |
|
| 286 | + * @since 4.3.0 |
|
| 287 | + * @return void (JSON) |
|
| 288 | + * @throws EE_Error |
|
| 289 | + * @throws InvalidArgumentException |
|
| 290 | + * @throws InvalidDataTypeException |
|
| 291 | + * @throws InvalidInterfaceException |
|
| 292 | + */ |
|
| 293 | + public function get_newsletter_form_content() |
|
| 294 | + { |
|
| 295 | + // do a nonce check cause we're not coming in from an normal route here. |
|
| 296 | + $nonce = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field( |
|
| 297 | + $this->_req_data['get_newsletter_form_content_nonce'] |
|
| 298 | + ) : ''; |
|
| 299 | + $nonce_ref = 'get_newsletter_form_content_nonce'; |
|
| 300 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
| 301 | + // let's get the mtp for the incoming MTP_ ID |
|
| 302 | + if (! isset($this->_req_data['GRP_ID'])) { |
|
| 303 | + EE_Error::add_error( |
|
| 304 | + esc_html__( |
|
| 305 | + 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
|
| 306 | + 'event_espresso' |
|
| 307 | + ), |
|
| 308 | + __FILE__, |
|
| 309 | + __FUNCTION__, |
|
| 310 | + __LINE__ |
|
| 311 | + ); |
|
| 312 | + $this->_template_args['success'] = false; |
|
| 313 | + $this->_template_args['error'] = true; |
|
| 314 | + $this->_return_json(); |
|
| 315 | + } |
|
| 316 | + $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
|
| 317 | + if (! $MTPG instanceof EE_Message_Template_Group) { |
|
| 318 | + EE_Error::add_error( |
|
| 319 | + sprintf( |
|
| 320 | + esc_html__( |
|
| 321 | + 'The GRP_ID given (%d) does not appear to have a corresponding row in the database.', |
|
| 322 | + 'event_espresso' |
|
| 323 | + ), |
|
| 324 | + $this->_req_data['GRP_ID'] |
|
| 325 | + ), |
|
| 326 | + __FILE__, |
|
| 327 | + __FUNCTION__, |
|
| 328 | + __LINE__ |
|
| 329 | + ); |
|
| 330 | + $this->_template_args['success'] = false; |
|
| 331 | + $this->_template_args['error'] = true; |
|
| 332 | + $this->_return_json(); |
|
| 333 | + } |
|
| 334 | + $MTPs = $MTPG->context_templates(); |
|
| 335 | + $MTPs = $MTPs['attendee']; |
|
| 336 | + $template_fields = array(); |
|
| 337 | + /** @var EE_Message_Template $MTP */ |
|
| 338 | + foreach ($MTPs as $MTP) { |
|
| 339 | + $field = $MTP->get('MTP_template_field'); |
|
| 340 | + if ($field === 'content') { |
|
| 341 | + $content = $MTP->get('MTP_content'); |
|
| 342 | + if (! empty($content['newsletter_content'])) { |
|
| 343 | + $template_fields['newsletter_content'] = $content['newsletter_content']; |
|
| 344 | + } |
|
| 345 | + continue; |
|
| 346 | + } |
|
| 347 | + $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
| 348 | + } |
|
| 349 | + $this->_template_args['success'] = true; |
|
| 350 | + $this->_template_args['error'] = false; |
|
| 351 | + $this->_template_args['data'] = array( |
|
| 352 | + 'batch_message_from' => isset($template_fields['from']) |
|
| 353 | + ? $template_fields['from'] |
|
| 354 | + : '', |
|
| 355 | + 'batch_message_subject' => isset($template_fields['subject']) |
|
| 356 | + ? $template_fields['subject'] |
|
| 357 | + : '', |
|
| 358 | + 'batch_message_content' => isset($template_fields['newsletter_content']) |
|
| 359 | + ? $template_fields['newsletter_content'] |
|
| 360 | + : '', |
|
| 361 | + ); |
|
| 362 | + $this->_return_json(); |
|
| 363 | + } |
|
| 364 | 364 | |
| 365 | 365 | |
| 366 | - /** |
|
| 367 | - * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
| 368 | - * |
|
| 369 | - * @since 4.3.0 |
|
| 370 | - * @param EE_Admin_List_Table $list_table |
|
| 371 | - * @return void |
|
| 372 | - * @throws InvalidArgumentException |
|
| 373 | - * @throws InvalidDataTypeException |
|
| 374 | - * @throws InvalidInterfaceException |
|
| 375 | - */ |
|
| 376 | - public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
| 377 | - { |
|
| 378 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 379 | - 'ee_send_message', |
|
| 380 | - 'espresso_registrations_newsletter_selected_send' |
|
| 381 | - ) |
|
| 382 | - ) { |
|
| 383 | - return; |
|
| 384 | - } |
|
| 385 | - $routes_to_add_to = array( |
|
| 386 | - 'contact_list', |
|
| 387 | - 'event_registrations', |
|
| 388 | - 'default', |
|
| 389 | - ); |
|
| 390 | - if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
| 391 | - if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
| 392 | - || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
| 393 | - ) { |
|
| 394 | - echo ''; |
|
| 395 | - } else { |
|
| 396 | - $button_text = sprintf( |
|
| 397 | - esc_html__('Send Batch Message (%s selected)', 'event_espresso'), |
|
| 398 | - '<span class="send-selected-newsletter-count">0</span>' |
|
| 399 | - ); |
|
| 400 | - echo '<button id="selected-batch-send-trigger" class="button secondary-button">' |
|
| 401 | - . '<span class="dashicons dashicons-email "></span>' |
|
| 402 | - . $button_text |
|
| 403 | - . '</button>'; |
|
| 404 | - add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
| 405 | - } |
|
| 406 | - } |
|
| 407 | - } |
|
| 366 | + /** |
|
| 367 | + * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action |
|
| 368 | + * |
|
| 369 | + * @since 4.3.0 |
|
| 370 | + * @param EE_Admin_List_Table $list_table |
|
| 371 | + * @return void |
|
| 372 | + * @throws InvalidArgumentException |
|
| 373 | + * @throws InvalidDataTypeException |
|
| 374 | + * @throws InvalidInterfaceException |
|
| 375 | + */ |
|
| 376 | + public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
|
| 377 | + { |
|
| 378 | + if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 379 | + 'ee_send_message', |
|
| 380 | + 'espresso_registrations_newsletter_selected_send' |
|
| 381 | + ) |
|
| 382 | + ) { |
|
| 383 | + return; |
|
| 384 | + } |
|
| 385 | + $routes_to_add_to = array( |
|
| 386 | + 'contact_list', |
|
| 387 | + 'event_registrations', |
|
| 388 | + 'default', |
|
| 389 | + ); |
|
| 390 | + if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) { |
|
| 391 | + if (($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id'])) |
|
| 392 | + || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash') |
|
| 393 | + ) { |
|
| 394 | + echo ''; |
|
| 395 | + } else { |
|
| 396 | + $button_text = sprintf( |
|
| 397 | + esc_html__('Send Batch Message (%s selected)', 'event_espresso'), |
|
| 398 | + '<span class="send-selected-newsletter-count">0</span>' |
|
| 399 | + ); |
|
| 400 | + echo '<button id="selected-batch-send-trigger" class="button secondary-button">' |
|
| 401 | + . '<span class="dashicons dashicons-email "></span>' |
|
| 402 | + . $button_text |
|
| 403 | + . '</button>'; |
|
| 404 | + add_action('admin_footer', array($this, 'newsletter_send_form_skeleton')); |
|
| 405 | + } |
|
| 406 | + } |
|
| 407 | + } |
|
| 408 | 408 | |
| 409 | 409 | |
| 410 | - /** |
|
| 411 | - * @throws DomainException |
|
| 412 | - * @throws EE_Error |
|
| 413 | - * @throws InvalidArgumentException |
|
| 414 | - * @throws InvalidDataTypeException |
|
| 415 | - * @throws InvalidInterfaceException |
|
| 416 | - */ |
|
| 417 | - public function newsletter_send_form_skeleton() |
|
| 418 | - { |
|
| 419 | - $list_table = $this->_list_table_object; |
|
| 420 | - $codes = array(); |
|
| 421 | - // need to templates for the newsletter message type for the template selector. |
|
| 422 | - $values[] = array('text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
| 423 | - $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
| 424 | - array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
| 425 | - ); |
|
| 426 | - foreach ($mtps as $mtp) { |
|
| 427 | - $name = $mtp->name(); |
|
| 428 | - $values[] = array( |
|
| 429 | - 'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name, |
|
| 430 | - 'id' => $mtp->ID(), |
|
| 431 | - ); |
|
| 432 | - } |
|
| 433 | - // need to get a list of shortcodes that are available for the newsletter message type. |
|
| 434 | - $shortcodes = EEH_MSG_Template::get_shortcodes( |
|
| 435 | - 'newsletter', |
|
| 436 | - 'email', |
|
| 437 | - array(), |
|
| 438 | - 'attendee', |
|
| 439 | - false |
|
| 440 | - ); |
|
| 441 | - foreach ($shortcodes as $field => $shortcode_array) { |
|
| 442 | - $available_shortcodes = array(); |
|
| 443 | - foreach ($shortcode_array as $shortcode => $shortcode_details) { |
|
| 444 | - $field_id = $field === '[NEWSLETTER_CONTENT]' |
|
| 445 | - ? 'content' |
|
| 446 | - : $field; |
|
| 447 | - $field_id = 'batch-message-' . strtolower($field_id); |
|
| 448 | - $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
|
| 449 | - . $shortcode |
|
| 450 | - . '" data-linked-input-id="' . $field_id . '">' |
|
| 451 | - . $shortcode |
|
| 452 | - . '</span>'; |
|
| 453 | - } |
|
| 454 | - $codes[ $field ] = implode(', ', $available_shortcodes); |
|
| 455 | - } |
|
| 456 | - $shortcodes = $codes; |
|
| 457 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 458 | - $form_template_args = array( |
|
| 459 | - 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
| 460 | - 'form_route' => 'newsletter_selected_send', |
|
| 461 | - 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
| 462 | - 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
| 463 | - 'redirect_back_to' => $this->_req_action, |
|
| 464 | - 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
| 465 | - 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
| 466 | - 'shortcodes' => $shortcodes, |
|
| 467 | - 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
| 468 | - ); |
|
| 469 | - EEH_Template::display_template($form_template, $form_template_args); |
|
| 470 | - } |
|
| 410 | + /** |
|
| 411 | + * @throws DomainException |
|
| 412 | + * @throws EE_Error |
|
| 413 | + * @throws InvalidArgumentException |
|
| 414 | + * @throws InvalidDataTypeException |
|
| 415 | + * @throws InvalidInterfaceException |
|
| 416 | + */ |
|
| 417 | + public function newsletter_send_form_skeleton() |
|
| 418 | + { |
|
| 419 | + $list_table = $this->_list_table_object; |
|
| 420 | + $codes = array(); |
|
| 421 | + // need to templates for the newsletter message type for the template selector. |
|
| 422 | + $values[] = array('text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0); |
|
| 423 | + $mtps = EEM_Message_Template_Group::instance()->get_all( |
|
| 424 | + array(array('MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email')) |
|
| 425 | + ); |
|
| 426 | + foreach ($mtps as $mtp) { |
|
| 427 | + $name = $mtp->name(); |
|
| 428 | + $values[] = array( |
|
| 429 | + 'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name, |
|
| 430 | + 'id' => $mtp->ID(), |
|
| 431 | + ); |
|
| 432 | + } |
|
| 433 | + // need to get a list of shortcodes that are available for the newsletter message type. |
|
| 434 | + $shortcodes = EEH_MSG_Template::get_shortcodes( |
|
| 435 | + 'newsletter', |
|
| 436 | + 'email', |
|
| 437 | + array(), |
|
| 438 | + 'attendee', |
|
| 439 | + false |
|
| 440 | + ); |
|
| 441 | + foreach ($shortcodes as $field => $shortcode_array) { |
|
| 442 | + $available_shortcodes = array(); |
|
| 443 | + foreach ($shortcode_array as $shortcode => $shortcode_details) { |
|
| 444 | + $field_id = $field === '[NEWSLETTER_CONTENT]' |
|
| 445 | + ? 'content' |
|
| 446 | + : $field; |
|
| 447 | + $field_id = 'batch-message-' . strtolower($field_id); |
|
| 448 | + $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
|
| 449 | + . $shortcode |
|
| 450 | + . '" data-linked-input-id="' . $field_id . '">' |
|
| 451 | + . $shortcode |
|
| 452 | + . '</span>'; |
|
| 453 | + } |
|
| 454 | + $codes[ $field ] = implode(', ', $available_shortcodes); |
|
| 455 | + } |
|
| 456 | + $shortcodes = $codes; |
|
| 457 | + $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 458 | + $form_template_args = array( |
|
| 459 | + 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
|
| 460 | + 'form_route' => 'newsletter_selected_send', |
|
| 461 | + 'form_nonce_name' => 'newsletter_selected_send_nonce', |
|
| 462 | + 'form_nonce' => wp_create_nonce('newsletter_selected_send_nonce'), |
|
| 463 | + 'redirect_back_to' => $this->_req_action, |
|
| 464 | + 'ajax_nonce' => wp_create_nonce('get_newsletter_form_content_nonce'), |
|
| 465 | + 'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values), |
|
| 466 | + 'shortcodes' => $shortcodes, |
|
| 467 | + 'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration', |
|
| 468 | + ); |
|
| 469 | + EEH_Template::display_template($form_template, $form_template_args); |
|
| 470 | + } |
|
| 471 | 471 | |
| 472 | 472 | |
| 473 | - /** |
|
| 474 | - * Handles sending selected registrations/contacts a newsletter. |
|
| 475 | - * |
|
| 476 | - * @since 4.3.0 |
|
| 477 | - * @return void |
|
| 478 | - * @throws EE_Error |
|
| 479 | - * @throws InvalidArgumentException |
|
| 480 | - * @throws InvalidDataTypeException |
|
| 481 | - * @throws InvalidInterfaceException |
|
| 482 | - */ |
|
| 483 | - protected function _newsletter_selected_send() |
|
| 484 | - { |
|
| 485 | - $success = true; |
|
| 486 | - // first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
| 487 | - if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
| 488 | - EE_Error::add_error( |
|
| 489 | - esc_html__( |
|
| 490 | - 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
| 491 | - 'event_espresso' |
|
| 492 | - ), |
|
| 493 | - __FILE__, |
|
| 494 | - __FUNCTION__, |
|
| 495 | - __LINE__ |
|
| 496 | - ); |
|
| 497 | - $success = false; |
|
| 498 | - } |
|
| 499 | - if ($success) { |
|
| 500 | - // update Message template in case there are any changes |
|
| 501 | - $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
| 502 | - $this->_req_data['newsletter_mtp_selected'] |
|
| 503 | - ); |
|
| 504 | - $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
| 505 | - ? $Message_Template_Group->context_templates() |
|
| 506 | - : array(); |
|
| 507 | - if (empty($Message_Templates)) { |
|
| 508 | - EE_Error::add_error( |
|
| 509 | - esc_html__( |
|
| 510 | - 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
| 511 | - 'event_espresso' |
|
| 512 | - ), |
|
| 513 | - __FILE__, |
|
| 514 | - __FUNCTION__, |
|
| 515 | - __LINE__ |
|
| 516 | - ); |
|
| 517 | - } |
|
| 518 | - // let's just update the specific fields |
|
| 519 | - foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
| 520 | - if ($Message_Template instanceof EE_Message_Template) { |
|
| 521 | - $field = $Message_Template->get('MTP_template_field'); |
|
| 522 | - $content = $Message_Template->get('MTP_content'); |
|
| 523 | - $new_content = $content; |
|
| 524 | - switch ($field) { |
|
| 525 | - case 'from': |
|
| 526 | - $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
| 527 | - ? $this->_req_data['batch_message']['from'] |
|
| 528 | - : $content; |
|
| 529 | - break; |
|
| 530 | - case 'subject': |
|
| 531 | - $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
| 532 | - ? $this->_req_data['batch_message']['subject'] |
|
| 533 | - : $content; |
|
| 534 | - break; |
|
| 535 | - case 'content': |
|
| 536 | - $new_content = $content; |
|
| 537 | - $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
| 538 | - ? $this->_req_data['batch_message']['content'] |
|
| 539 | - : $content['newsletter_content']; |
|
| 540 | - break; |
|
| 541 | - default: |
|
| 542 | - // continue the foreach loop, we don't want to set $new_content nor save. |
|
| 543 | - continue 2; |
|
| 544 | - } |
|
| 545 | - $Message_Template->set('MTP_content', $new_content); |
|
| 546 | - $Message_Template->save(); |
|
| 547 | - } |
|
| 548 | - } |
|
| 549 | - // great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
| 550 | - $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
| 551 | - ? $this->_req_data['batch_message']['id_type'] |
|
| 552 | - : 'registration'; |
|
| 553 | - // id_type will affect how we assemble the ids. |
|
| 554 | - $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
| 555 | - ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
| 556 | - : array(); |
|
| 557 | - $registrations_used_for_contact_data = array(); |
|
| 558 | - // using switch because eventually we'll have other contexts that will be used for generating messages. |
|
| 559 | - switch ($id_type) { |
|
| 560 | - case 'registration': |
|
| 561 | - $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
| 562 | - array( |
|
| 563 | - array( |
|
| 564 | - 'REG_ID' => array('IN', $ids), |
|
| 565 | - ), |
|
| 566 | - ) |
|
| 567 | - ); |
|
| 568 | - break; |
|
| 569 | - case 'contact': |
|
| 570 | - $registrations_used_for_contact_data = EEM_Registration::instance() |
|
| 571 | - ->get_latest_registration_for_each_of_given_contacts( |
|
| 572 | - $ids |
|
| 573 | - ); |
|
| 574 | - break; |
|
| 575 | - } |
|
| 576 | - do_action_ref_array( |
|
| 577 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
| 578 | - array( |
|
| 579 | - $registrations_used_for_contact_data, |
|
| 580 | - $Message_Template_Group->ID(), |
|
| 581 | - ) |
|
| 582 | - ); |
|
| 583 | - // kept for backward compat, internally we no longer use this action. |
|
| 584 | - // @deprecated 4.8.36.rc.002 |
|
| 585 | - $contacts = $id_type === 'registration' |
|
| 586 | - ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
| 587 | - : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
| 588 | - do_action_ref_array( |
|
| 589 | - 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
| 590 | - array( |
|
| 591 | - $contacts, |
|
| 592 | - $Message_Template_Group->ID(), |
|
| 593 | - ) |
|
| 594 | - ); |
|
| 595 | - } |
|
| 596 | - $query_args = array( |
|
| 597 | - 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
| 598 | - ? $this->_req_data['redirect_back_to'] |
|
| 599 | - : 'default', |
|
| 600 | - ); |
|
| 601 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 602 | - } |
|
| 473 | + /** |
|
| 474 | + * Handles sending selected registrations/contacts a newsletter. |
|
| 475 | + * |
|
| 476 | + * @since 4.3.0 |
|
| 477 | + * @return void |
|
| 478 | + * @throws EE_Error |
|
| 479 | + * @throws InvalidArgumentException |
|
| 480 | + * @throws InvalidDataTypeException |
|
| 481 | + * @throws InvalidInterfaceException |
|
| 482 | + */ |
|
| 483 | + protected function _newsletter_selected_send() |
|
| 484 | + { |
|
| 485 | + $success = true; |
|
| 486 | + // first we need to make sure we have a GRP_ID so we know what template we're sending and updating! |
|
| 487 | + if (empty($this->_req_data['newsletter_mtp_selected'])) { |
|
| 488 | + EE_Error::add_error( |
|
| 489 | + esc_html__( |
|
| 490 | + 'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', |
|
| 491 | + 'event_espresso' |
|
| 492 | + ), |
|
| 493 | + __FILE__, |
|
| 494 | + __FUNCTION__, |
|
| 495 | + __LINE__ |
|
| 496 | + ); |
|
| 497 | + $success = false; |
|
| 498 | + } |
|
| 499 | + if ($success) { |
|
| 500 | + // update Message template in case there are any changes |
|
| 501 | + $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID( |
|
| 502 | + $this->_req_data['newsletter_mtp_selected'] |
|
| 503 | + ); |
|
| 504 | + $Message_Templates = $Message_Template_Group instanceof EE_Message_Template_Group |
|
| 505 | + ? $Message_Template_Group->context_templates() |
|
| 506 | + : array(); |
|
| 507 | + if (empty($Message_Templates)) { |
|
| 508 | + EE_Error::add_error( |
|
| 509 | + esc_html__( |
|
| 510 | + 'Unable to retrieve message template fields from the db. Messages not sent.', |
|
| 511 | + 'event_espresso' |
|
| 512 | + ), |
|
| 513 | + __FILE__, |
|
| 514 | + __FUNCTION__, |
|
| 515 | + __LINE__ |
|
| 516 | + ); |
|
| 517 | + } |
|
| 518 | + // let's just update the specific fields |
|
| 519 | + foreach ($Message_Templates['attendee'] as $Message_Template) { |
|
| 520 | + if ($Message_Template instanceof EE_Message_Template) { |
|
| 521 | + $field = $Message_Template->get('MTP_template_field'); |
|
| 522 | + $content = $Message_Template->get('MTP_content'); |
|
| 523 | + $new_content = $content; |
|
| 524 | + switch ($field) { |
|
| 525 | + case 'from': |
|
| 526 | + $new_content = ! empty($this->_req_data['batch_message']['from']) |
|
| 527 | + ? $this->_req_data['batch_message']['from'] |
|
| 528 | + : $content; |
|
| 529 | + break; |
|
| 530 | + case 'subject': |
|
| 531 | + $new_content = ! empty($this->_req_data['batch_message']['subject']) |
|
| 532 | + ? $this->_req_data['batch_message']['subject'] |
|
| 533 | + : $content; |
|
| 534 | + break; |
|
| 535 | + case 'content': |
|
| 536 | + $new_content = $content; |
|
| 537 | + $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content']) |
|
| 538 | + ? $this->_req_data['batch_message']['content'] |
|
| 539 | + : $content['newsletter_content']; |
|
| 540 | + break; |
|
| 541 | + default: |
|
| 542 | + // continue the foreach loop, we don't want to set $new_content nor save. |
|
| 543 | + continue 2; |
|
| 544 | + } |
|
| 545 | + $Message_Template->set('MTP_content', $new_content); |
|
| 546 | + $Message_Template->save(); |
|
| 547 | + } |
|
| 548 | + } |
|
| 549 | + // great fields are updated! now let's make sure we just have contact objects (EE_Attendee). |
|
| 550 | + $id_type = ! empty($this->_req_data['batch_message']['id_type']) |
|
| 551 | + ? $this->_req_data['batch_message']['id_type'] |
|
| 552 | + : 'registration'; |
|
| 553 | + // id_type will affect how we assemble the ids. |
|
| 554 | + $ids = ! empty($this->_req_data['batch_message']['ids']) |
|
| 555 | + ? json_decode(stripslashes($this->_req_data['batch_message']['ids'])) |
|
| 556 | + : array(); |
|
| 557 | + $registrations_used_for_contact_data = array(); |
|
| 558 | + // using switch because eventually we'll have other contexts that will be used for generating messages. |
|
| 559 | + switch ($id_type) { |
|
| 560 | + case 'registration': |
|
| 561 | + $registrations_used_for_contact_data = EEM_Registration::instance()->get_all( |
|
| 562 | + array( |
|
| 563 | + array( |
|
| 564 | + 'REG_ID' => array('IN', $ids), |
|
| 565 | + ), |
|
| 566 | + ) |
|
| 567 | + ); |
|
| 568 | + break; |
|
| 569 | + case 'contact': |
|
| 570 | + $registrations_used_for_contact_data = EEM_Registration::instance() |
|
| 571 | + ->get_latest_registration_for_each_of_given_contacts( |
|
| 572 | + $ids |
|
| 573 | + ); |
|
| 574 | + break; |
|
| 575 | + } |
|
| 576 | + do_action_ref_array( |
|
| 577 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations', |
|
| 578 | + array( |
|
| 579 | + $registrations_used_for_contact_data, |
|
| 580 | + $Message_Template_Group->ID(), |
|
| 581 | + ) |
|
| 582 | + ); |
|
| 583 | + // kept for backward compat, internally we no longer use this action. |
|
| 584 | + // @deprecated 4.8.36.rc.002 |
|
| 585 | + $contacts = $id_type === 'registration' |
|
| 586 | + ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids) |
|
| 587 | + : EEM_Attendee::instance()->get_all(array(array('ATT_ID' => array('in', $ids)))); |
|
| 588 | + do_action_ref_array( |
|
| 589 | + 'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', |
|
| 590 | + array( |
|
| 591 | + $contacts, |
|
| 592 | + $Message_Template_Group->ID(), |
|
| 593 | + ) |
|
| 594 | + ); |
|
| 595 | + } |
|
| 596 | + $query_args = array( |
|
| 597 | + 'action' => ! empty($this->_req_data['redirect_back_to']) |
|
| 598 | + ? $this->_req_data['redirect_back_to'] |
|
| 599 | + : 'default', |
|
| 600 | + ); |
|
| 601 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 602 | + } |
|
| 603 | 603 | |
| 604 | 604 | |
| 605 | - /** |
|
| 606 | - * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
| 607 | - * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
| 608 | - */ |
|
| 609 | - protected function _registration_reports_js_setup() |
|
| 610 | - { |
|
| 611 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
| 612 | - $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
| 613 | - } |
|
| 605 | + /** |
|
| 606 | + * This is called when javascript is being enqueued to setup the various data needed for the reports js. |
|
| 607 | + * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method. |
|
| 608 | + */ |
|
| 609 | + protected function _registration_reports_js_setup() |
|
| 610 | + { |
|
| 611 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report(); |
|
| 612 | + $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report(); |
|
| 613 | + } |
|
| 614 | 614 | |
| 615 | 615 | |
| 616 | - /** |
|
| 617 | - * generates Business Reports regarding Registrations |
|
| 618 | - * |
|
| 619 | - * @access protected |
|
| 620 | - * @return void |
|
| 621 | - * @throws DomainException |
|
| 622 | - */ |
|
| 623 | - protected function _registration_reports() |
|
| 624 | - { |
|
| 625 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 626 | - $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 627 | - $template_path, |
|
| 628 | - $this->_reports_template_data, |
|
| 629 | - true |
|
| 630 | - ); |
|
| 631 | - // the final template wrapper |
|
| 632 | - $this->display_admin_page_with_no_sidebar(); |
|
| 633 | - } |
|
| 616 | + /** |
|
| 617 | + * generates Business Reports regarding Registrations |
|
| 618 | + * |
|
| 619 | + * @access protected |
|
| 620 | + * @return void |
|
| 621 | + * @throws DomainException |
|
| 622 | + */ |
|
| 623 | + protected function _registration_reports() |
|
| 624 | + { |
|
| 625 | + $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 626 | + $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
|
| 627 | + $template_path, |
|
| 628 | + $this->_reports_template_data, |
|
| 629 | + true |
|
| 630 | + ); |
|
| 631 | + // the final template wrapper |
|
| 632 | + $this->display_admin_page_with_no_sidebar(); |
|
| 633 | + } |
|
| 634 | 634 | |
| 635 | 635 | |
| 636 | - /** |
|
| 637 | - * Generates Business Report showing total registrations per day. |
|
| 638 | - * |
|
| 639 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 640 | - * @return string |
|
| 641 | - * @throws EE_Error |
|
| 642 | - * @throws InvalidArgumentException |
|
| 643 | - * @throws InvalidDataTypeException |
|
| 644 | - * @throws InvalidInterfaceException |
|
| 645 | - */ |
|
| 646 | - private function _registrations_per_day_report($period = '-1 month') |
|
| 647 | - { |
|
| 648 | - $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
| 649 | - $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
| 650 | - $results = (array) $results; |
|
| 651 | - $regs = array(); |
|
| 652 | - $subtitle = ''; |
|
| 653 | - if ($results) { |
|
| 654 | - $column_titles = array(); |
|
| 655 | - $tracker = 0; |
|
| 656 | - foreach ($results as $result) { |
|
| 657 | - $report_column_values = array(); |
|
| 658 | - foreach ($result as $property_name => $property_value) { |
|
| 659 | - $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
| 660 | - : (int) $property_value; |
|
| 661 | - $report_column_values[] = $property_value; |
|
| 662 | - if ($tracker === 0) { |
|
| 663 | - if ($property_name === 'Registration_REG_date') { |
|
| 664 | - $column_titles[] = esc_html__( |
|
| 665 | - 'Date (only days with registrations are shown)', |
|
| 666 | - 'event_espresso' |
|
| 667 | - ); |
|
| 668 | - } else { |
|
| 669 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 670 | - } |
|
| 671 | - } |
|
| 672 | - } |
|
| 673 | - $tracker++; |
|
| 674 | - $regs[] = $report_column_values; |
|
| 675 | - } |
|
| 676 | - // make sure the column_titles is pushed to the beginning of the array |
|
| 677 | - array_unshift($regs, $column_titles); |
|
| 678 | - // setup the date range. |
|
| 679 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 680 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 681 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
| 682 | - $subtitle = sprintf( |
|
| 683 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 684 | - $beginning_date->format('Y-m-d'), |
|
| 685 | - $ending_date->format('Y-m-d') |
|
| 686 | - ); |
|
| 687 | - } |
|
| 688 | - $report_title = esc_html__('Total Registrations per Day', 'event_espresso'); |
|
| 689 | - $report_params = array( |
|
| 690 | - 'title' => $report_title, |
|
| 691 | - 'subtitle' => $subtitle, |
|
| 692 | - 'id' => $report_ID, |
|
| 693 | - 'regs' => $regs, |
|
| 694 | - 'noResults' => empty($regs), |
|
| 695 | - 'noRegsMsg' => sprintf( |
|
| 696 | - esc_html__( |
|
| 697 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
| 698 | - 'event_espresso' |
|
| 699 | - ), |
|
| 700 | - '<h2>' . $report_title . '</h2><p>', |
|
| 701 | - '</p>' |
|
| 702 | - ), |
|
| 703 | - ); |
|
| 704 | - wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
| 705 | - return $report_ID; |
|
| 706 | - } |
|
| 636 | + /** |
|
| 637 | + * Generates Business Report showing total registrations per day. |
|
| 638 | + * |
|
| 639 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 640 | + * @return string |
|
| 641 | + * @throws EE_Error |
|
| 642 | + * @throws InvalidArgumentException |
|
| 643 | + * @throws InvalidDataTypeException |
|
| 644 | + * @throws InvalidInterfaceException |
|
| 645 | + */ |
|
| 646 | + private function _registrations_per_day_report($period = '-1 month') |
|
| 647 | + { |
|
| 648 | + $report_ID = 'reg-admin-registrations-per-day-report-dv'; |
|
| 649 | + $results = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period); |
|
| 650 | + $results = (array) $results; |
|
| 651 | + $regs = array(); |
|
| 652 | + $subtitle = ''; |
|
| 653 | + if ($results) { |
|
| 654 | + $column_titles = array(); |
|
| 655 | + $tracker = 0; |
|
| 656 | + foreach ($results as $result) { |
|
| 657 | + $report_column_values = array(); |
|
| 658 | + foreach ($result as $property_name => $property_value) { |
|
| 659 | + $property_value = $property_name === 'Registration_REG_date' ? $property_value |
|
| 660 | + : (int) $property_value; |
|
| 661 | + $report_column_values[] = $property_value; |
|
| 662 | + if ($tracker === 0) { |
|
| 663 | + if ($property_name === 'Registration_REG_date') { |
|
| 664 | + $column_titles[] = esc_html__( |
|
| 665 | + 'Date (only days with registrations are shown)', |
|
| 666 | + 'event_espresso' |
|
| 667 | + ); |
|
| 668 | + } else { |
|
| 669 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 670 | + } |
|
| 671 | + } |
|
| 672 | + } |
|
| 673 | + $tracker++; |
|
| 674 | + $regs[] = $report_column_values; |
|
| 675 | + } |
|
| 676 | + // make sure the column_titles is pushed to the beginning of the array |
|
| 677 | + array_unshift($regs, $column_titles); |
|
| 678 | + // setup the date range. |
|
| 679 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 680 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 681 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
| 682 | + $subtitle = sprintf( |
|
| 683 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 684 | + $beginning_date->format('Y-m-d'), |
|
| 685 | + $ending_date->format('Y-m-d') |
|
| 686 | + ); |
|
| 687 | + } |
|
| 688 | + $report_title = esc_html__('Total Registrations per Day', 'event_espresso'); |
|
| 689 | + $report_params = array( |
|
| 690 | + 'title' => $report_title, |
|
| 691 | + 'subtitle' => $subtitle, |
|
| 692 | + 'id' => $report_ID, |
|
| 693 | + 'regs' => $regs, |
|
| 694 | + 'noResults' => empty($regs), |
|
| 695 | + 'noRegsMsg' => sprintf( |
|
| 696 | + esc_html__( |
|
| 697 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
| 698 | + 'event_espresso' |
|
| 699 | + ), |
|
| 700 | + '<h2>' . $report_title . '</h2><p>', |
|
| 701 | + '</p>' |
|
| 702 | + ), |
|
| 703 | + ); |
|
| 704 | + wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params); |
|
| 705 | + return $report_ID; |
|
| 706 | + } |
|
| 707 | 707 | |
| 708 | 708 | |
| 709 | - /** |
|
| 710 | - * Generates Business Report showing total registrations per event. |
|
| 711 | - * |
|
| 712 | - * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 713 | - * @return string |
|
| 714 | - * @throws EE_Error |
|
| 715 | - * @throws InvalidArgumentException |
|
| 716 | - * @throws InvalidDataTypeException |
|
| 717 | - * @throws InvalidInterfaceException |
|
| 718 | - */ |
|
| 719 | - private function _registrations_per_event_report($period = '-1 month') |
|
| 720 | - { |
|
| 721 | - $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
| 722 | - $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
| 723 | - $results = (array) $results; |
|
| 724 | - $regs = array(); |
|
| 725 | - $subtitle = ''; |
|
| 726 | - if ($results) { |
|
| 727 | - $column_titles = array(); |
|
| 728 | - $tracker = 0; |
|
| 729 | - foreach ($results as $result) { |
|
| 730 | - $report_column_values = array(); |
|
| 731 | - foreach ($result as $property_name => $property_value) { |
|
| 732 | - $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
| 733 | - $property_value, |
|
| 734 | - 4, |
|
| 735 | - '...' |
|
| 736 | - ) : (int) $property_value; |
|
| 737 | - $report_column_values[] = $property_value; |
|
| 738 | - if ($tracker === 0) { |
|
| 739 | - if ($property_name === 'Registration_Event') { |
|
| 740 | - $column_titles[] = esc_html__('Event', 'event_espresso'); |
|
| 741 | - } else { |
|
| 742 | - $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 743 | - } |
|
| 744 | - } |
|
| 745 | - } |
|
| 746 | - $tracker++; |
|
| 747 | - $regs[] = $report_column_values; |
|
| 748 | - } |
|
| 749 | - // make sure the column_titles is pushed to the beginning of the array |
|
| 750 | - array_unshift($regs, $column_titles); |
|
| 751 | - // setup the date range. |
|
| 752 | - $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 753 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 754 | - $ending_date = new DateTime("now", $DateTimeZone); |
|
| 755 | - $subtitle = sprintf( |
|
| 756 | - _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 757 | - $beginning_date->format('Y-m-d'), |
|
| 758 | - $ending_date->format('Y-m-d') |
|
| 759 | - ); |
|
| 760 | - } |
|
| 761 | - $report_title = esc_html__('Total Registrations per Event', 'event_espresso'); |
|
| 762 | - $report_params = array( |
|
| 763 | - 'title' => $report_title, |
|
| 764 | - 'subtitle' => $subtitle, |
|
| 765 | - 'id' => $report_ID, |
|
| 766 | - 'regs' => $regs, |
|
| 767 | - 'noResults' => empty($regs), |
|
| 768 | - 'noRegsMsg' => sprintf( |
|
| 769 | - esc_html__( |
|
| 770 | - '%sThere are currently no registration records in the last month for this report.%s', |
|
| 771 | - 'event_espresso' |
|
| 772 | - ), |
|
| 773 | - '<h2>' . $report_title . '</h2><p>', |
|
| 774 | - '</p>' |
|
| 775 | - ), |
|
| 776 | - ); |
|
| 777 | - wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
| 778 | - return $report_ID; |
|
| 779 | - } |
|
| 709 | + /** |
|
| 710 | + * Generates Business Report showing total registrations per event. |
|
| 711 | + * |
|
| 712 | + * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated. |
|
| 713 | + * @return string |
|
| 714 | + * @throws EE_Error |
|
| 715 | + * @throws InvalidArgumentException |
|
| 716 | + * @throws InvalidDataTypeException |
|
| 717 | + * @throws InvalidInterfaceException |
|
| 718 | + */ |
|
| 719 | + private function _registrations_per_event_report($period = '-1 month') |
|
| 720 | + { |
|
| 721 | + $report_ID = 'reg-admin-registrations-per-event-report-dv'; |
|
| 722 | + $results = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period); |
|
| 723 | + $results = (array) $results; |
|
| 724 | + $regs = array(); |
|
| 725 | + $subtitle = ''; |
|
| 726 | + if ($results) { |
|
| 727 | + $column_titles = array(); |
|
| 728 | + $tracker = 0; |
|
| 729 | + foreach ($results as $result) { |
|
| 730 | + $report_column_values = array(); |
|
| 731 | + foreach ($result as $property_name => $property_value) { |
|
| 732 | + $property_value = $property_name === 'Registration_Event' ? wp_trim_words( |
|
| 733 | + $property_value, |
|
| 734 | + 4, |
|
| 735 | + '...' |
|
| 736 | + ) : (int) $property_value; |
|
| 737 | + $report_column_values[] = $property_value; |
|
| 738 | + if ($tracker === 0) { |
|
| 739 | + if ($property_name === 'Registration_Event') { |
|
| 740 | + $column_titles[] = esc_html__('Event', 'event_espresso'); |
|
| 741 | + } else { |
|
| 742 | + $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence'); |
|
| 743 | + } |
|
| 744 | + } |
|
| 745 | + } |
|
| 746 | + $tracker++; |
|
| 747 | + $regs[] = $report_column_values; |
|
| 748 | + } |
|
| 749 | + // make sure the column_titles is pushed to the beginning of the array |
|
| 750 | + array_unshift($regs, $column_titles); |
|
| 751 | + // setup the date range. |
|
| 752 | + $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
| 753 | + $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 754 | + $ending_date = new DateTime("now", $DateTimeZone); |
|
| 755 | + $subtitle = sprintf( |
|
| 756 | + _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
|
| 757 | + $beginning_date->format('Y-m-d'), |
|
| 758 | + $ending_date->format('Y-m-d') |
|
| 759 | + ); |
|
| 760 | + } |
|
| 761 | + $report_title = esc_html__('Total Registrations per Event', 'event_espresso'); |
|
| 762 | + $report_params = array( |
|
| 763 | + 'title' => $report_title, |
|
| 764 | + 'subtitle' => $subtitle, |
|
| 765 | + 'id' => $report_ID, |
|
| 766 | + 'regs' => $regs, |
|
| 767 | + 'noResults' => empty($regs), |
|
| 768 | + 'noRegsMsg' => sprintf( |
|
| 769 | + esc_html__( |
|
| 770 | + '%sThere are currently no registration records in the last month for this report.%s', |
|
| 771 | + 'event_espresso' |
|
| 772 | + ), |
|
| 773 | + '<h2>' . $report_title . '</h2><p>', |
|
| 774 | + '</p>' |
|
| 775 | + ), |
|
| 776 | + ); |
|
| 777 | + wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params); |
|
| 778 | + return $report_ID; |
|
| 779 | + } |
|
| 780 | 780 | |
| 781 | 781 | |
| 782 | - /** |
|
| 783 | - * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
| 784 | - * |
|
| 785 | - * @access protected |
|
| 786 | - * @return void |
|
| 787 | - * @throws EE_Error |
|
| 788 | - * @throws InvalidArgumentException |
|
| 789 | - * @throws InvalidDataTypeException |
|
| 790 | - * @throws InvalidInterfaceException |
|
| 791 | - * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 792 | - */ |
|
| 793 | - protected function _registration_checkin_list_table() |
|
| 794 | - { |
|
| 795 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 796 | - $reg_id = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : null; |
|
| 797 | - /** @var EE_Registration $registration */ |
|
| 798 | - $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
| 799 | - if (! $registration instanceof EE_Registration) { |
|
| 800 | - throw new EE_Error( |
|
| 801 | - sprintf( |
|
| 802 | - esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
|
| 803 | - $reg_id |
|
| 804 | - ) |
|
| 805 | - ); |
|
| 806 | - } |
|
| 807 | - $attendee = $registration->attendee(); |
|
| 808 | - $this->_admin_page_title .= $this->get_action_link_or_button( |
|
| 809 | - 'new_registration', |
|
| 810 | - 'add-registrant', |
|
| 811 | - array('event_id' => $registration->event_ID()), |
|
| 812 | - 'add-new-h2' |
|
| 813 | - ); |
|
| 814 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 815 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 816 | - $legend_items = array( |
|
| 817 | - 'checkin' => array( |
|
| 818 | - 'class' => $checked_in->cssClasses(), |
|
| 819 | - 'desc' => $checked_in->legendLabel(), |
|
| 820 | - ), |
|
| 821 | - 'checkout' => array( |
|
| 822 | - 'class' => $checked_out->cssClasses(), |
|
| 823 | - 'desc' => $checked_out->legendLabel(), |
|
| 824 | - ), |
|
| 825 | - ); |
|
| 826 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 827 | - $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 828 | - /** @var EE_Datetime $datetime */ |
|
| 829 | - $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
| 830 | - $datetime_label = ''; |
|
| 831 | - if ($datetime instanceof EE_Datetime) { |
|
| 832 | - $datetime_label = $datetime->get_dtt_display_name(true); |
|
| 833 | - $datetime_label .= ! empty($datetime_label) |
|
| 834 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 835 | - : $datetime->get_dtt_display_name(); |
|
| 836 | - } |
|
| 837 | - $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
| 838 | - ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 839 | - array( |
|
| 840 | - 'action' => 'event_registrations', |
|
| 841 | - 'event_id' => $registration->event_ID(), |
|
| 842 | - 'DTT_ID' => $dtt_id, |
|
| 843 | - ), |
|
| 844 | - $this->_admin_base_url |
|
| 845 | - ) |
|
| 846 | - : ''; |
|
| 847 | - $datetime_link = ! empty($datetime_link) |
|
| 848 | - ? '<a href="' . $datetime_link . '">' |
|
| 849 | - . '<span id="checkin-dtt">' |
|
| 850 | - . $datetime_label |
|
| 851 | - . '</span></a>' |
|
| 852 | - : $datetime_label; |
|
| 853 | - $attendee_name = $attendee instanceof EE_Attendee |
|
| 854 | - ? $attendee->full_name() |
|
| 855 | - : ''; |
|
| 856 | - $attendee_link = $attendee instanceof EE_Attendee |
|
| 857 | - ? $attendee->get_admin_details_link() |
|
| 858 | - : ''; |
|
| 859 | - $attendee_link = ! empty($attendee_link) |
|
| 860 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 861 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 862 | - . '<span id="checkin-attendee-name">' |
|
| 863 | - . $attendee_name |
|
| 864 | - . '</span></a>' |
|
| 865 | - : ''; |
|
| 866 | - $event_link = $registration->event() instanceof EE_Event |
|
| 867 | - ? $registration->event()->get_admin_details_link() |
|
| 868 | - : ''; |
|
| 869 | - $event_link = ! empty($event_link) |
|
| 870 | - ? '<a href="' . $event_link . '"' |
|
| 871 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 872 | - . '<span id="checkin-event-name">' |
|
| 873 | - . $registration->event_name() |
|
| 874 | - . '</span>' |
|
| 875 | - . '</a>' |
|
| 876 | - : ''; |
|
| 877 | - $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
| 878 | - ? '<h2>' . sprintf( |
|
| 879 | - esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
| 880 | - $attendee_link, |
|
| 881 | - $datetime_link, |
|
| 882 | - $event_link |
|
| 883 | - ) . '</h2>' |
|
| 884 | - : ''; |
|
| 885 | - $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
| 886 | - ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
| 887 | - $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
| 888 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 889 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 890 | - } |
|
| 782 | + /** |
|
| 783 | + * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration) |
|
| 784 | + * |
|
| 785 | + * @access protected |
|
| 786 | + * @return void |
|
| 787 | + * @throws EE_Error |
|
| 788 | + * @throws InvalidArgumentException |
|
| 789 | + * @throws InvalidDataTypeException |
|
| 790 | + * @throws InvalidInterfaceException |
|
| 791 | + * @throws \EventEspresso\core\exceptions\EntityNotFoundException |
|
| 792 | + */ |
|
| 793 | + protected function _registration_checkin_list_table() |
|
| 794 | + { |
|
| 795 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 796 | + $reg_id = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : null; |
|
| 797 | + /** @var EE_Registration $registration */ |
|
| 798 | + $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
|
| 799 | + if (! $registration instanceof EE_Registration) { |
|
| 800 | + throw new EE_Error( |
|
| 801 | + sprintf( |
|
| 802 | + esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
|
| 803 | + $reg_id |
|
| 804 | + ) |
|
| 805 | + ); |
|
| 806 | + } |
|
| 807 | + $attendee = $registration->attendee(); |
|
| 808 | + $this->_admin_page_title .= $this->get_action_link_or_button( |
|
| 809 | + 'new_registration', |
|
| 810 | + 'add-registrant', |
|
| 811 | + array('event_id' => $registration->event_ID()), |
|
| 812 | + 'add-new-h2' |
|
| 813 | + ); |
|
| 814 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 815 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 816 | + $legend_items = array( |
|
| 817 | + 'checkin' => array( |
|
| 818 | + 'class' => $checked_in->cssClasses(), |
|
| 819 | + 'desc' => $checked_in->legendLabel(), |
|
| 820 | + ), |
|
| 821 | + 'checkout' => array( |
|
| 822 | + 'class' => $checked_out->cssClasses(), |
|
| 823 | + 'desc' => $checked_out->legendLabel(), |
|
| 824 | + ), |
|
| 825 | + ); |
|
| 826 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 827 | + $dtt_id = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 828 | + /** @var EE_Datetime $datetime */ |
|
| 829 | + $datetime = EEM_Datetime::instance()->get_one_by_ID($dtt_id); |
|
| 830 | + $datetime_label = ''; |
|
| 831 | + if ($datetime instanceof EE_Datetime) { |
|
| 832 | + $datetime_label = $datetime->get_dtt_display_name(true); |
|
| 833 | + $datetime_label .= ! empty($datetime_label) |
|
| 834 | + ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 835 | + : $datetime->get_dtt_display_name(); |
|
| 836 | + } |
|
| 837 | + $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
|
| 838 | + ? EE_Admin_Page::add_query_args_and_nonce( |
|
| 839 | + array( |
|
| 840 | + 'action' => 'event_registrations', |
|
| 841 | + 'event_id' => $registration->event_ID(), |
|
| 842 | + 'DTT_ID' => $dtt_id, |
|
| 843 | + ), |
|
| 844 | + $this->_admin_base_url |
|
| 845 | + ) |
|
| 846 | + : ''; |
|
| 847 | + $datetime_link = ! empty($datetime_link) |
|
| 848 | + ? '<a href="' . $datetime_link . '">' |
|
| 849 | + . '<span id="checkin-dtt">' |
|
| 850 | + . $datetime_label |
|
| 851 | + . '</span></a>' |
|
| 852 | + : $datetime_label; |
|
| 853 | + $attendee_name = $attendee instanceof EE_Attendee |
|
| 854 | + ? $attendee->full_name() |
|
| 855 | + : ''; |
|
| 856 | + $attendee_link = $attendee instanceof EE_Attendee |
|
| 857 | + ? $attendee->get_admin_details_link() |
|
| 858 | + : ''; |
|
| 859 | + $attendee_link = ! empty($attendee_link) |
|
| 860 | + ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 861 | + . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 862 | + . '<span id="checkin-attendee-name">' |
|
| 863 | + . $attendee_name |
|
| 864 | + . '</span></a>' |
|
| 865 | + : ''; |
|
| 866 | + $event_link = $registration->event() instanceof EE_Event |
|
| 867 | + ? $registration->event()->get_admin_details_link() |
|
| 868 | + : ''; |
|
| 869 | + $event_link = ! empty($event_link) |
|
| 870 | + ? '<a href="' . $event_link . '"' |
|
| 871 | + . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 872 | + . '<span id="checkin-event-name">' |
|
| 873 | + . $registration->event_name() |
|
| 874 | + . '</span>' |
|
| 875 | + . '</a>' |
|
| 876 | + : ''; |
|
| 877 | + $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
|
| 878 | + ? '<h2>' . sprintf( |
|
| 879 | + esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
|
| 880 | + $attendee_link, |
|
| 881 | + $datetime_link, |
|
| 882 | + $event_link |
|
| 883 | + ) . '</h2>' |
|
| 884 | + : ''; |
|
| 885 | + $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
|
| 886 | + ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
| 887 | + $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
|
| 888 | + ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 889 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 890 | + } |
|
| 891 | 891 | |
| 892 | 892 | |
| 893 | - /** |
|
| 894 | - * toggle the Check-in status for the given registration (coming from ajax) |
|
| 895 | - * |
|
| 896 | - * @return void (JSON) |
|
| 897 | - * @throws EE_Error |
|
| 898 | - * @throws InvalidArgumentException |
|
| 899 | - * @throws InvalidDataTypeException |
|
| 900 | - * @throws InvalidInterfaceException |
|
| 901 | - */ |
|
| 902 | - public function toggle_checkin_status() |
|
| 903 | - { |
|
| 904 | - // first make sure we have the necessary data |
|
| 905 | - if (! isset($this->_req_data['_regid'])) { |
|
| 906 | - EE_Error::add_error( |
|
| 907 | - esc_html__( |
|
| 908 | - 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
|
| 909 | - 'event_espresso' |
|
| 910 | - ), |
|
| 911 | - __FILE__, |
|
| 912 | - __FUNCTION__, |
|
| 913 | - __LINE__ |
|
| 914 | - ); |
|
| 915 | - $this->_template_args['success'] = false; |
|
| 916 | - $this->_template_args['error'] = true; |
|
| 917 | - $this->_return_json(); |
|
| 918 | - }; |
|
| 919 | - // do a nonce check cause we're not coming in from an normal route here. |
|
| 920 | - $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
| 921 | - : ''; |
|
| 922 | - $nonce_ref = 'checkin_nonce'; |
|
| 923 | - $this->_verify_nonce($nonce, $nonce_ref); |
|
| 924 | - // beautiful! Made it this far so let's get the status. |
|
| 925 | - $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
| 926 | - // setup new class to return via ajax |
|
| 927 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 928 | - $this->_template_args['success'] = true; |
|
| 929 | - $this->_return_json(); |
|
| 930 | - } |
|
| 893 | + /** |
|
| 894 | + * toggle the Check-in status for the given registration (coming from ajax) |
|
| 895 | + * |
|
| 896 | + * @return void (JSON) |
|
| 897 | + * @throws EE_Error |
|
| 898 | + * @throws InvalidArgumentException |
|
| 899 | + * @throws InvalidDataTypeException |
|
| 900 | + * @throws InvalidInterfaceException |
|
| 901 | + */ |
|
| 902 | + public function toggle_checkin_status() |
|
| 903 | + { |
|
| 904 | + // first make sure we have the necessary data |
|
| 905 | + if (! isset($this->_req_data['_regid'])) { |
|
| 906 | + EE_Error::add_error( |
|
| 907 | + esc_html__( |
|
| 908 | + 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
|
| 909 | + 'event_espresso' |
|
| 910 | + ), |
|
| 911 | + __FILE__, |
|
| 912 | + __FUNCTION__, |
|
| 913 | + __LINE__ |
|
| 914 | + ); |
|
| 915 | + $this->_template_args['success'] = false; |
|
| 916 | + $this->_template_args['error'] = true; |
|
| 917 | + $this->_return_json(); |
|
| 918 | + }; |
|
| 919 | + // do a nonce check cause we're not coming in from an normal route here. |
|
| 920 | + $nonce = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce']) |
|
| 921 | + : ''; |
|
| 922 | + $nonce_ref = 'checkin_nonce'; |
|
| 923 | + $this->_verify_nonce($nonce, $nonce_ref); |
|
| 924 | + // beautiful! Made it this far so let's get the status. |
|
| 925 | + $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
|
| 926 | + // setup new class to return via ajax |
|
| 927 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 928 | + $this->_template_args['success'] = true; |
|
| 929 | + $this->_return_json(); |
|
| 930 | + } |
|
| 931 | 931 | |
| 932 | 932 | |
| 933 | - /** |
|
| 934 | - * handles toggling the checkin status for the registration, |
|
| 935 | - * |
|
| 936 | - * @access protected |
|
| 937 | - * @return int|void |
|
| 938 | - * @throws EE_Error |
|
| 939 | - * @throws InvalidArgumentException |
|
| 940 | - * @throws InvalidDataTypeException |
|
| 941 | - * @throws InvalidInterfaceException |
|
| 942 | - */ |
|
| 943 | - protected function _toggle_checkin_status() |
|
| 944 | - { |
|
| 945 | - // first let's get the query args out of the way for the redirect |
|
| 946 | - $query_args = array( |
|
| 947 | - 'action' => 'event_registrations', |
|
| 948 | - 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 949 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
| 950 | - ); |
|
| 951 | - $new_status = false; |
|
| 952 | - // bulk action check in toggle |
|
| 953 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 954 | - // cycle thru checkboxes |
|
| 955 | - while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 956 | - $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 957 | - $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
| 958 | - } |
|
| 959 | - } elseif (isset($this->_req_data['_regid'])) { |
|
| 960 | - // coming from ajax request |
|
| 961 | - $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
| 962 | - $query_args['DTT_ID'] = $DTT_ID; |
|
| 963 | - $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
| 964 | - } else { |
|
| 965 | - EE_Error::add_error( |
|
| 966 | - esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
| 967 | - __FILE__, |
|
| 968 | - __FUNCTION__, |
|
| 969 | - __LINE__ |
|
| 970 | - ); |
|
| 971 | - } |
|
| 972 | - if (defined('DOING_AJAX')) { |
|
| 973 | - return $new_status; |
|
| 974 | - } |
|
| 975 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 976 | - } |
|
| 933 | + /** |
|
| 934 | + * handles toggling the checkin status for the registration, |
|
| 935 | + * |
|
| 936 | + * @access protected |
|
| 937 | + * @return int|void |
|
| 938 | + * @throws EE_Error |
|
| 939 | + * @throws InvalidArgumentException |
|
| 940 | + * @throws InvalidDataTypeException |
|
| 941 | + * @throws InvalidInterfaceException |
|
| 942 | + */ |
|
| 943 | + protected function _toggle_checkin_status() |
|
| 944 | + { |
|
| 945 | + // first let's get the query args out of the way for the redirect |
|
| 946 | + $query_args = array( |
|
| 947 | + 'action' => 'event_registrations', |
|
| 948 | + 'event_id' => isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null, |
|
| 949 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null, |
|
| 950 | + ); |
|
| 951 | + $new_status = false; |
|
| 952 | + // bulk action check in toggle |
|
| 953 | + if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 954 | + // cycle thru checkboxes |
|
| 955 | + while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 956 | + $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
|
| 957 | + $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID); |
|
| 958 | + } |
|
| 959 | + } elseif (isset($this->_req_data['_regid'])) { |
|
| 960 | + // coming from ajax request |
|
| 961 | + $DTT_ID = isset($this->_req_data['dttid']) ? $this->_req_data['dttid'] : null; |
|
| 962 | + $query_args['DTT_ID'] = $DTT_ID; |
|
| 963 | + $new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID); |
|
| 964 | + } else { |
|
| 965 | + EE_Error::add_error( |
|
| 966 | + esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'), |
|
| 967 | + __FILE__, |
|
| 968 | + __FUNCTION__, |
|
| 969 | + __LINE__ |
|
| 970 | + ); |
|
| 971 | + } |
|
| 972 | + if (defined('DOING_AJAX')) { |
|
| 973 | + return $new_status; |
|
| 974 | + } |
|
| 975 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 976 | + } |
|
| 977 | 977 | |
| 978 | 978 | |
| 979 | - /** |
|
| 980 | - * This is toggles a single Check-in for the given registration and datetime. |
|
| 981 | - * |
|
| 982 | - * @param int $REG_ID The registration we're toggling |
|
| 983 | - * @param int $DTT_ID The datetime we're toggling |
|
| 984 | - * @return int The new status toggled to. |
|
| 985 | - * @throws EE_Error |
|
| 986 | - * @throws InvalidArgumentException |
|
| 987 | - * @throws InvalidDataTypeException |
|
| 988 | - * @throws InvalidInterfaceException |
|
| 989 | - */ |
|
| 990 | - private function _toggle_checkin($REG_ID, $DTT_ID) |
|
| 991 | - { |
|
| 992 | - /** @var EE_Registration $REG */ |
|
| 993 | - $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
| 994 | - $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
| 995 | - if ($new_status !== false) { |
|
| 996 | - EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
| 997 | - } else { |
|
| 998 | - EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
| 999 | - $new_status = false; |
|
| 1000 | - } |
|
| 1001 | - return $new_status; |
|
| 1002 | - } |
|
| 979 | + /** |
|
| 980 | + * This is toggles a single Check-in for the given registration and datetime. |
|
| 981 | + * |
|
| 982 | + * @param int $REG_ID The registration we're toggling |
|
| 983 | + * @param int $DTT_ID The datetime we're toggling |
|
| 984 | + * @return int The new status toggled to. |
|
| 985 | + * @throws EE_Error |
|
| 986 | + * @throws InvalidArgumentException |
|
| 987 | + * @throws InvalidDataTypeException |
|
| 988 | + * @throws InvalidInterfaceException |
|
| 989 | + */ |
|
| 990 | + private function _toggle_checkin($REG_ID, $DTT_ID) |
|
| 991 | + { |
|
| 992 | + /** @var EE_Registration $REG */ |
|
| 993 | + $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID); |
|
| 994 | + $new_status = $REG->toggle_checkin_status($DTT_ID); |
|
| 995 | + if ($new_status !== false) { |
|
| 996 | + EE_Error::add_success($REG->get_checkin_msg($DTT_ID)); |
|
| 997 | + } else { |
|
| 998 | + EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__); |
|
| 999 | + $new_status = false; |
|
| 1000 | + } |
|
| 1001 | + return $new_status; |
|
| 1002 | + } |
|
| 1003 | 1003 | |
| 1004 | 1004 | |
| 1005 | - /** |
|
| 1006 | - * Takes care of deleting multiple EE_Checkin table rows |
|
| 1007 | - * |
|
| 1008 | - * @access protected |
|
| 1009 | - * @return void |
|
| 1010 | - * @throws EE_Error |
|
| 1011 | - * @throws InvalidArgumentException |
|
| 1012 | - * @throws InvalidDataTypeException |
|
| 1013 | - * @throws InvalidInterfaceException |
|
| 1014 | - */ |
|
| 1015 | - protected function _delete_checkin_rows() |
|
| 1016 | - { |
|
| 1017 | - $query_args = array( |
|
| 1018 | - 'action' => 'registration_checkins', |
|
| 1019 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1020 | - '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1021 | - ); |
|
| 1022 | - $errors = 0; |
|
| 1023 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1024 | - while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 1025 | - if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1026 | - $errors++; |
|
| 1027 | - } |
|
| 1028 | - } |
|
| 1029 | - } else { |
|
| 1030 | - EE_Error::add_error( |
|
| 1031 | - esc_html__( |
|
| 1032 | - 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
| 1033 | - 'event_espresso' |
|
| 1034 | - ), |
|
| 1035 | - __FILE__, |
|
| 1036 | - __FUNCTION__, |
|
| 1037 | - __LINE__ |
|
| 1038 | - ); |
|
| 1039 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1040 | - } |
|
| 1041 | - if ($errors > 0) { |
|
| 1042 | - EE_Error::add_error( |
|
| 1043 | - sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
| 1044 | - __FILE__, |
|
| 1045 | - __FUNCTION__, |
|
| 1046 | - __LINE__ |
|
| 1047 | - ); |
|
| 1048 | - } else { |
|
| 1049 | - EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
| 1050 | - } |
|
| 1051 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1052 | - } |
|
| 1005 | + /** |
|
| 1006 | + * Takes care of deleting multiple EE_Checkin table rows |
|
| 1007 | + * |
|
| 1008 | + * @access protected |
|
| 1009 | + * @return void |
|
| 1010 | + * @throws EE_Error |
|
| 1011 | + * @throws InvalidArgumentException |
|
| 1012 | + * @throws InvalidDataTypeException |
|
| 1013 | + * @throws InvalidInterfaceException |
|
| 1014 | + */ |
|
| 1015 | + protected function _delete_checkin_rows() |
|
| 1016 | + { |
|
| 1017 | + $query_args = array( |
|
| 1018 | + 'action' => 'registration_checkins', |
|
| 1019 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1020 | + '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1021 | + ); |
|
| 1022 | + $errors = 0; |
|
| 1023 | + if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1024 | + while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
|
| 1025 | + if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1026 | + $errors++; |
|
| 1027 | + } |
|
| 1028 | + } |
|
| 1029 | + } else { |
|
| 1030 | + EE_Error::add_error( |
|
| 1031 | + esc_html__( |
|
| 1032 | + 'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', |
|
| 1033 | + 'event_espresso' |
|
| 1034 | + ), |
|
| 1035 | + __FILE__, |
|
| 1036 | + __FUNCTION__, |
|
| 1037 | + __LINE__ |
|
| 1038 | + ); |
|
| 1039 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1040 | + } |
|
| 1041 | + if ($errors > 0) { |
|
| 1042 | + EE_Error::add_error( |
|
| 1043 | + sprintf(__('There were %d records that did not delete successfully', 'event_espresso'), $errors), |
|
| 1044 | + __FILE__, |
|
| 1045 | + __FUNCTION__, |
|
| 1046 | + __LINE__ |
|
| 1047 | + ); |
|
| 1048 | + } else { |
|
| 1049 | + EE_Error::add_success(__('Records were successfully deleted', 'event_espresso')); |
|
| 1050 | + } |
|
| 1051 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1052 | + } |
|
| 1053 | 1053 | |
| 1054 | 1054 | |
| 1055 | - /** |
|
| 1056 | - * Deletes a single EE_Checkin row |
|
| 1057 | - * |
|
| 1058 | - * @return void |
|
| 1059 | - * @throws EE_Error |
|
| 1060 | - * @throws InvalidArgumentException |
|
| 1061 | - * @throws InvalidDataTypeException |
|
| 1062 | - * @throws InvalidInterfaceException |
|
| 1063 | - */ |
|
| 1064 | - protected function _delete_checkin_row() |
|
| 1065 | - { |
|
| 1066 | - $query_args = array( |
|
| 1067 | - 'action' => 'registration_checkins', |
|
| 1068 | - 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1069 | - '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1070 | - ); |
|
| 1071 | - if (! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | - if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1073 | - EE_Error::add_error( |
|
| 1074 | - esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
| 1075 | - __FILE__, |
|
| 1076 | - __FUNCTION__, |
|
| 1077 | - __LINE__ |
|
| 1078 | - ); |
|
| 1079 | - } else { |
|
| 1080 | - EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
| 1081 | - } |
|
| 1082 | - } else { |
|
| 1083 | - EE_Error::add_error( |
|
| 1084 | - esc_html__( |
|
| 1085 | - 'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', |
|
| 1086 | - 'event_espresso' |
|
| 1087 | - ), |
|
| 1088 | - __FILE__, |
|
| 1089 | - __FUNCTION__, |
|
| 1090 | - __LINE__ |
|
| 1091 | - ); |
|
| 1092 | - } |
|
| 1093 | - $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1094 | - } |
|
| 1055 | + /** |
|
| 1056 | + * Deletes a single EE_Checkin row |
|
| 1057 | + * |
|
| 1058 | + * @return void |
|
| 1059 | + * @throws EE_Error |
|
| 1060 | + * @throws InvalidArgumentException |
|
| 1061 | + * @throws InvalidDataTypeException |
|
| 1062 | + * @throws InvalidInterfaceException |
|
| 1063 | + */ |
|
| 1064 | + protected function _delete_checkin_row() |
|
| 1065 | + { |
|
| 1066 | + $query_args = array( |
|
| 1067 | + 'action' => 'registration_checkins', |
|
| 1068 | + 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
|
| 1069 | + '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
|
| 1070 | + ); |
|
| 1071 | + if (! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | + if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1073 | + EE_Error::add_error( |
|
| 1074 | + esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
|
| 1075 | + __FILE__, |
|
| 1076 | + __FUNCTION__, |
|
| 1077 | + __LINE__ |
|
| 1078 | + ); |
|
| 1079 | + } else { |
|
| 1080 | + EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso')); |
|
| 1081 | + } |
|
| 1082 | + } else { |
|
| 1083 | + EE_Error::add_error( |
|
| 1084 | + esc_html__( |
|
| 1085 | + 'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', |
|
| 1086 | + 'event_espresso' |
|
| 1087 | + ), |
|
| 1088 | + __FILE__, |
|
| 1089 | + __FUNCTION__, |
|
| 1090 | + __LINE__ |
|
| 1091 | + ); |
|
| 1092 | + } |
|
| 1093 | + $this->_redirect_after_action(false, '', '', $query_args, true); |
|
| 1094 | + } |
|
| 1095 | 1095 | |
| 1096 | 1096 | |
| 1097 | - /** |
|
| 1098 | - * generates HTML for the Event Registrations List Table |
|
| 1099 | - * |
|
| 1100 | - * @access protected |
|
| 1101 | - * @return void |
|
| 1102 | - * @throws EE_Error |
|
| 1103 | - * @throws InvalidArgumentException |
|
| 1104 | - * @throws InvalidDataTypeException |
|
| 1105 | - * @throws InvalidInterfaceException |
|
| 1106 | - */ |
|
| 1107 | - protected function _event_registrations_list_table() |
|
| 1108 | - { |
|
| 1109 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1110 | - $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
| 1111 | - ? $this->get_action_link_or_button( |
|
| 1112 | - 'new_registration', |
|
| 1113 | - 'add-registrant', |
|
| 1114 | - array('event_id' => $this->_req_data['event_id']), |
|
| 1115 | - 'add-new-h2', |
|
| 1116 | - '', |
|
| 1117 | - false |
|
| 1118 | - ) |
|
| 1119 | - : ''; |
|
| 1120 | - $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 1121 | - $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 1122 | - $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
| 1123 | - $legend_items = array( |
|
| 1124 | - 'star-icon' => array( |
|
| 1125 | - 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
| 1126 | - 'desc' => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'), |
|
| 1127 | - ), |
|
| 1128 | - 'checkin' => array( |
|
| 1129 | - 'class' => $checked_in->cssClasses(), |
|
| 1130 | - 'desc' => $checked_in->legendLabel(), |
|
| 1131 | - ), |
|
| 1132 | - 'checkout' => array( |
|
| 1133 | - 'class' => $checked_out->cssClasses(), |
|
| 1134 | - 'desc' => $checked_out->legendLabel(), |
|
| 1135 | - ), |
|
| 1136 | - 'nocheckinrecord' => array( |
|
| 1137 | - 'class' => $checked_never->cssClasses(), |
|
| 1138 | - 'desc' => $checked_never->legendLabel(), |
|
| 1139 | - ), |
|
| 1140 | - 'approved_status' => array( |
|
| 1141 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1142 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
| 1143 | - ), |
|
| 1144 | - 'cancelled_status' => array( |
|
| 1145 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1146 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
| 1147 | - ), |
|
| 1148 | - 'declined_status' => array( |
|
| 1149 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1150 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
| 1151 | - ), |
|
| 1152 | - 'not_approved' => array( |
|
| 1153 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1154 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
| 1155 | - ), |
|
| 1156 | - 'pending_status' => array( |
|
| 1157 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1158 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
| 1159 | - ), |
|
| 1160 | - 'wait_list' => array( |
|
| 1161 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1162 | - 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
| 1163 | - ), |
|
| 1164 | - ); |
|
| 1165 | - $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 1166 | - $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
| 1167 | - /** @var EE_Event $event */ |
|
| 1168 | - $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 1169 | - $this->_template_args['before_list_table'] = $event instanceof EE_Event |
|
| 1170 | - ? '<h2>' . sprintf( |
|
| 1171 | - esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
|
| 1172 | - EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
| 1173 | - ) . '</h2>' |
|
| 1174 | - : ''; |
|
| 1175 | - // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
|
| 1176 | - // the event. |
|
| 1177 | - $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
| 1178 | - $datetime = null; |
|
| 1179 | - if ($event instanceof EE_Event) { |
|
| 1180 | - $datetimes_on_event = $event->datetimes(); |
|
| 1181 | - if (count($datetimes_on_event) === 1) { |
|
| 1182 | - $datetime = reset($datetimes_on_event); |
|
| 1183 | - } |
|
| 1184 | - } |
|
| 1185 | - $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
| 1186 | - if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
| 1187 | - $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
| 1188 | - $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
| 1189 | - $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
| 1190 | - $this->_template_args['before_list_table'] .= $datetime->name(); |
|
| 1191 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1192 | - $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
| 1193 | - } |
|
| 1194 | - // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
|
| 1195 | - // column represents |
|
| 1196 | - if (! $datetime instanceof EE_Datetime) { |
|
| 1197 | - $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
| 1198 | - . esc_html__( |
|
| 1199 | - 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
| 1200 | - 'event_espresso' |
|
| 1201 | - ) |
|
| 1202 | - . '</p>'; |
|
| 1203 | - } |
|
| 1204 | - $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 1205 | - } |
|
| 1097 | + /** |
|
| 1098 | + * generates HTML for the Event Registrations List Table |
|
| 1099 | + * |
|
| 1100 | + * @access protected |
|
| 1101 | + * @return void |
|
| 1102 | + * @throws EE_Error |
|
| 1103 | + * @throws InvalidArgumentException |
|
| 1104 | + * @throws InvalidDataTypeException |
|
| 1105 | + * @throws InvalidInterfaceException |
|
| 1106 | + */ |
|
| 1107 | + protected function _event_registrations_list_table() |
|
| 1108 | + { |
|
| 1109 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
| 1110 | + $this->_admin_page_title .= isset($this->_req_data['event_id']) |
|
| 1111 | + ? $this->get_action_link_or_button( |
|
| 1112 | + 'new_registration', |
|
| 1113 | + 'add-registrant', |
|
| 1114 | + array('event_id' => $this->_req_data['event_id']), |
|
| 1115 | + 'add-new-h2', |
|
| 1116 | + '', |
|
| 1117 | + false |
|
| 1118 | + ) |
|
| 1119 | + : ''; |
|
| 1120 | + $checked_in = new CheckinStatusDashicon(EE_Checkin::status_checked_in); |
|
| 1121 | + $checked_out = new CheckinStatusDashicon(EE_Checkin::status_checked_out); |
|
| 1122 | + $checked_never = new CheckinStatusDashicon(EE_Checkin::status_checked_never); |
|
| 1123 | + $legend_items = array( |
|
| 1124 | + 'star-icon' => array( |
|
| 1125 | + 'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8', |
|
| 1126 | + 'desc' => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'), |
|
| 1127 | + ), |
|
| 1128 | + 'checkin' => array( |
|
| 1129 | + 'class' => $checked_in->cssClasses(), |
|
| 1130 | + 'desc' => $checked_in->legendLabel(), |
|
| 1131 | + ), |
|
| 1132 | + 'checkout' => array( |
|
| 1133 | + 'class' => $checked_out->cssClasses(), |
|
| 1134 | + 'desc' => $checked_out->legendLabel(), |
|
| 1135 | + ), |
|
| 1136 | + 'nocheckinrecord' => array( |
|
| 1137 | + 'class' => $checked_never->cssClasses(), |
|
| 1138 | + 'desc' => $checked_never->legendLabel(), |
|
| 1139 | + ), |
|
| 1140 | + 'approved_status' => array( |
|
| 1141 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1142 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
|
| 1143 | + ), |
|
| 1144 | + 'cancelled_status' => array( |
|
| 1145 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1146 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
|
| 1147 | + ), |
|
| 1148 | + 'declined_status' => array( |
|
| 1149 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1150 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
|
| 1151 | + ), |
|
| 1152 | + 'not_approved' => array( |
|
| 1153 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1154 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
|
| 1155 | + ), |
|
| 1156 | + 'pending_status' => array( |
|
| 1157 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1158 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
|
| 1159 | + ), |
|
| 1160 | + 'wait_list' => array( |
|
| 1161 | + 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1162 | + 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
|
| 1163 | + ), |
|
| 1164 | + ); |
|
| 1165 | + $this->_template_args['after_list_table'] = $this->_display_legend($legend_items); |
|
| 1166 | + $event_id = isset($this->_req_data['event_id']) ? $this->_req_data['event_id'] : null; |
|
| 1167 | + /** @var EE_Event $event */ |
|
| 1168 | + $event = EEM_Event::instance()->get_one_by_ID($event_id); |
|
| 1169 | + $this->_template_args['before_list_table'] = $event instanceof EE_Event |
|
| 1170 | + ? '<h2>' . sprintf( |
|
| 1171 | + esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
|
| 1172 | + EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
|
| 1173 | + ) . '</h2>' |
|
| 1174 | + : ''; |
|
| 1175 | + // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
|
| 1176 | + // the event. |
|
| 1177 | + $DTT_ID = ! empty($this->_req_data['DTT_ID']) ? absint($this->_req_data['DTT_ID']) : 0; |
|
| 1178 | + $datetime = null; |
|
| 1179 | + if ($event instanceof EE_Event) { |
|
| 1180 | + $datetimes_on_event = $event->datetimes(); |
|
| 1181 | + if (count($datetimes_on_event) === 1) { |
|
| 1182 | + $datetime = reset($datetimes_on_event); |
|
| 1183 | + } |
|
| 1184 | + } |
|
| 1185 | + $datetime = $datetime instanceof EE_Datetime ? $datetime : EEM_Datetime::instance()->get_one_by_ID($DTT_ID); |
|
| 1186 | + if ($datetime instanceof EE_Datetime && $this->_template_args['before_list_table'] !== '') { |
|
| 1187 | + $this->_template_args['before_list_table'] = substr($this->_template_args['before_list_table'], 0, -5); |
|
| 1188 | + $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
|
| 1189 | + $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
|
| 1190 | + $this->_template_args['before_list_table'] .= $datetime->name(); |
|
| 1191 | + $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1192 | + $this->_template_args['before_list_table'] .= '</span></h2>'; |
|
| 1193 | + } |
|
| 1194 | + // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
|
| 1195 | + // column represents |
|
| 1196 | + if (! $datetime instanceof EE_Datetime) { |
|
| 1197 | + $this->_template_args['before_list_table'] .= '<br><p class="description">' |
|
| 1198 | + . esc_html__( |
|
| 1199 | + 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |
|
| 1200 | + 'event_espresso' |
|
| 1201 | + ) |
|
| 1202 | + . '</p>'; |
|
| 1203 | + } |
|
| 1204 | + $this->display_admin_list_table_page_with_no_sidebar(); |
|
| 1205 | + } |
|
| 1206 | 1206 | |
| 1207 | - /** |
|
| 1208 | - * Download the registrations check-in report (same as the normal registration report, but with different where |
|
| 1209 | - * conditions) |
|
| 1210 | - * |
|
| 1211 | - * @return void ends the request by a redirect or download |
|
| 1212 | - */ |
|
| 1213 | - public function _registrations_checkin_report() |
|
| 1214 | - { |
|
| 1215 | - $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
| 1216 | - } |
|
| 1207 | + /** |
|
| 1208 | + * Download the registrations check-in report (same as the normal registration report, but with different where |
|
| 1209 | + * conditions) |
|
| 1210 | + * |
|
| 1211 | + * @return void ends the request by a redirect or download |
|
| 1212 | + */ |
|
| 1213 | + public function _registrations_checkin_report() |
|
| 1214 | + { |
|
| 1215 | + $this->_registrations_report_base('_get_checkin_query_params_from_request'); |
|
| 1216 | + } |
|
| 1217 | 1217 | |
| 1218 | - /** |
|
| 1219 | - * Gets the query params from the request, plus adds a where condition for the registration status, |
|
| 1220 | - * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
| 1221 | - * |
|
| 1222 | - * @param array $request |
|
| 1223 | - * @param int $per_page |
|
| 1224 | - * @param bool $count |
|
| 1225 | - * @return array |
|
| 1226 | - * @throws EE_Error |
|
| 1227 | - */ |
|
| 1228 | - protected function _get_checkin_query_params_from_request( |
|
| 1229 | - $request, |
|
| 1230 | - $per_page = 10, |
|
| 1231 | - $count = false |
|
| 1232 | - ) { |
|
| 1233 | - $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
| 1234 | - // unlike the regular registrations list table, |
|
| 1235 | - $status_ids_array = apply_filters( |
|
| 1236 | - 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
| 1237 | - array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
| 1238 | - ); |
|
| 1239 | - $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
| 1240 | - return $query_params; |
|
| 1241 | - } |
|
| 1218 | + /** |
|
| 1219 | + * Gets the query params from the request, plus adds a where condition for the registration status, |
|
| 1220 | + * because on the checkin page we only ever want to see approved and pending-approval registrations |
|
| 1221 | + * |
|
| 1222 | + * @param array $request |
|
| 1223 | + * @param int $per_page |
|
| 1224 | + * @param bool $count |
|
| 1225 | + * @return array |
|
| 1226 | + * @throws EE_Error |
|
| 1227 | + */ |
|
| 1228 | + protected function _get_checkin_query_params_from_request( |
|
| 1229 | + $request, |
|
| 1230 | + $per_page = 10, |
|
| 1231 | + $count = false |
|
| 1232 | + ) { |
|
| 1233 | + $query_params = $this->_get_registration_query_parameters($request, $per_page, $count); |
|
| 1234 | + // unlike the regular registrations list table, |
|
| 1235 | + $status_ids_array = apply_filters( |
|
| 1236 | + 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', |
|
| 1237 | + array(EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved) |
|
| 1238 | + ); |
|
| 1239 | + $query_params[0]['STS_ID'] = array('IN', $status_ids_array); |
|
| 1240 | + return $query_params; |
|
| 1241 | + } |
|
| 1242 | 1242 | |
| 1243 | 1243 | |
| 1244 | - /** |
|
| 1245 | - * Gets registrations for an event |
|
| 1246 | - * |
|
| 1247 | - * @param int $per_page |
|
| 1248 | - * @param bool $count whether to return count or data. |
|
| 1249 | - * @param bool $trash |
|
| 1250 | - * @param string $orderby |
|
| 1251 | - * @return EE_Registration[]|int |
|
| 1252 | - * @throws EE_Error |
|
| 1253 | - * @throws InvalidArgumentException |
|
| 1254 | - * @throws InvalidDataTypeException |
|
| 1255 | - * @throws InvalidInterfaceException |
|
| 1256 | - */ |
|
| 1257 | - public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
| 1258 | - { |
|
| 1259 | - // normalize some request params that get setup by the parent `get_registrations` method. |
|
| 1260 | - $request = $this->_req_data; |
|
| 1261 | - $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
| 1262 | - $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1263 | - if ($trash) { |
|
| 1264 | - $request['status'] = 'trash'; |
|
| 1265 | - } |
|
| 1266 | - $query_params = $this->_get_checkin_query_params_from_request($request, $per_page, $count); |
|
| 1267 | - /** |
|
| 1268 | - * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
| 1269 | - * |
|
| 1270 | - * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
| 1271 | - * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1272 | - * or if you have the development copy of EE you can view this at the path: |
|
| 1273 | - * /docs/G--Model-System/model-query-params.md |
|
| 1274 | - */ |
|
| 1275 | - $query_params['group_by'] = ''; |
|
| 1244 | + /** |
|
| 1245 | + * Gets registrations for an event |
|
| 1246 | + * |
|
| 1247 | + * @param int $per_page |
|
| 1248 | + * @param bool $count whether to return count or data. |
|
| 1249 | + * @param bool $trash |
|
| 1250 | + * @param string $orderby |
|
| 1251 | + * @return EE_Registration[]|int |
|
| 1252 | + * @throws EE_Error |
|
| 1253 | + * @throws InvalidArgumentException |
|
| 1254 | + * @throws InvalidDataTypeException |
|
| 1255 | + * @throws InvalidInterfaceException |
|
| 1256 | + */ |
|
| 1257 | + public function get_event_attendees($per_page = 10, $count = false, $trash = false, $orderby = 'ATT_fname') |
|
| 1258 | + { |
|
| 1259 | + // normalize some request params that get setup by the parent `get_registrations` method. |
|
| 1260 | + $request = $this->_req_data; |
|
| 1261 | + $request['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby; |
|
| 1262 | + $request['order'] = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC'; |
|
| 1263 | + if ($trash) { |
|
| 1264 | + $request['status'] = 'trash'; |
|
| 1265 | + } |
|
| 1266 | + $query_params = $this->_get_checkin_query_params_from_request($request, $per_page, $count); |
|
| 1267 | + /** |
|
| 1268 | + * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected |
|
| 1269 | + * |
|
| 1270 | + * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093 |
|
| 1271 | + * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1272 | + * or if you have the development copy of EE you can view this at the path: |
|
| 1273 | + * /docs/G--Model-System/model-query-params.md |
|
| 1274 | + */ |
|
| 1275 | + $query_params['group_by'] = ''; |
|
| 1276 | 1276 | |
| 1277 | - return $count |
|
| 1278 | - ? EEM_Registration::instance()->count($query_params) |
|
| 1279 | - /** @type EE_Registration[] */ |
|
| 1280 | - : EEM_Registration::instance()->get_all($query_params); |
|
| 1281 | - } |
|
| 1277 | + return $count |
|
| 1278 | + ? EEM_Registration::instance()->count($query_params) |
|
| 1279 | + /** @type EE_Registration[] */ |
|
| 1280 | + : EEM_Registration::instance()->get_all($query_params); |
|
| 1281 | + } |
|
| 1282 | 1282 | } |
@@ -32,10 +32,10 @@ discard block |
||
| 32 | 32 | public function __construct($routing = true) |
| 33 | 33 | { |
| 34 | 34 | parent::__construct($routing); |
| 35 | - if (! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | - define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/'); |
|
| 37 | - define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/'); |
|
| 38 | - define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/'); |
|
| 35 | + if ( ! defined('REG_CAF_TEMPLATE_PATH')) { |
|
| 36 | + define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'registrations/templates/'); |
|
| 37 | + define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'registrations/assets/'); |
|
| 38 | + define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registrations/assets/'); |
|
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 | |
@@ -45,7 +45,7 @@ discard block |
||
| 45 | 45 | */ |
| 46 | 46 | protected function _extend_page_config() |
| 47 | 47 | { |
| 48 | - $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations'; |
|
| 48 | + $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'registrations'; |
|
| 49 | 49 | $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID']) |
| 50 | 50 | ? $this->_req_data['_REG_ID'] |
| 51 | 51 | : 0; |
@@ -185,14 +185,14 @@ discard block |
||
| 185 | 185 | // enqueue newsletter js |
| 186 | 186 | wp_enqueue_script( |
| 187 | 187 | 'ee-newsletter-trigger', |
| 188 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', |
|
| 188 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.js', |
|
| 189 | 189 | array('ee-dialog'), |
| 190 | 190 | EVENT_ESPRESSO_VERSION, |
| 191 | 191 | true |
| 192 | 192 | ); |
| 193 | 193 | wp_enqueue_style( |
| 194 | 194 | 'ee-newsletter-trigger-css', |
| 195 | - REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', |
|
| 195 | + REG_CAF_ASSETS_URL.'ee-newsletter-trigger.css', |
|
| 196 | 196 | array(), |
| 197 | 197 | EVENT_ESPRESSO_VERSION |
| 198 | 198 | ); |
@@ -213,7 +213,7 @@ discard block |
||
| 213 | 213 | { |
| 214 | 214 | wp_register_script( |
| 215 | 215 | 'ee-reg-reports-js', |
| 216 | - REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js', |
|
| 216 | + REG_CAF_ASSETS_URL.'ee-registration-admin-reports.js', |
|
| 217 | 217 | array('google-charts'), |
| 218 | 218 | EVENT_ESPRESSO_VERSION, |
| 219 | 219 | true |
@@ -299,7 +299,7 @@ discard block |
||
| 299 | 299 | $nonce_ref = 'get_newsletter_form_content_nonce'; |
| 300 | 300 | $this->_verify_nonce($nonce, $nonce_ref); |
| 301 | 301 | // let's get the mtp for the incoming MTP_ ID |
| 302 | - if (! isset($this->_req_data['GRP_ID'])) { |
|
| 302 | + if ( ! isset($this->_req_data['GRP_ID'])) { |
|
| 303 | 303 | EE_Error::add_error( |
| 304 | 304 | esc_html__( |
| 305 | 305 | 'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', |
@@ -314,7 +314,7 @@ discard block |
||
| 314 | 314 | $this->_return_json(); |
| 315 | 315 | } |
| 316 | 316 | $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']); |
| 317 | - if (! $MTPG instanceof EE_Message_Template_Group) { |
|
| 317 | + if ( ! $MTPG instanceof EE_Message_Template_Group) { |
|
| 318 | 318 | EE_Error::add_error( |
| 319 | 319 | sprintf( |
| 320 | 320 | esc_html__( |
@@ -339,12 +339,12 @@ discard block |
||
| 339 | 339 | $field = $MTP->get('MTP_template_field'); |
| 340 | 340 | if ($field === 'content') { |
| 341 | 341 | $content = $MTP->get('MTP_content'); |
| 342 | - if (! empty($content['newsletter_content'])) { |
|
| 342 | + if ( ! empty($content['newsletter_content'])) { |
|
| 343 | 343 | $template_fields['newsletter_content'] = $content['newsletter_content']; |
| 344 | 344 | } |
| 345 | 345 | continue; |
| 346 | 346 | } |
| 347 | - $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content'); |
|
| 347 | + $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content'); |
|
| 348 | 348 | } |
| 349 | 349 | $this->_template_args['success'] = true; |
| 350 | 350 | $this->_template_args['error'] = false; |
@@ -375,7 +375,7 @@ discard block |
||
| 375 | 375 | */ |
| 376 | 376 | public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table) |
| 377 | 377 | { |
| 378 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 378 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
| 379 | 379 | 'ee_send_message', |
| 380 | 380 | 'espresso_registrations_newsletter_selected_send' |
| 381 | 381 | ) |
@@ -444,17 +444,17 @@ discard block |
||
| 444 | 444 | $field_id = $field === '[NEWSLETTER_CONTENT]' |
| 445 | 445 | ? 'content' |
| 446 | 446 | : $field; |
| 447 | - $field_id = 'batch-message-' . strtolower($field_id); |
|
| 447 | + $field_id = 'batch-message-'.strtolower($field_id); |
|
| 448 | 448 | $available_shortcodes[] = '<span class="js-shortcode-selection" data-value="' |
| 449 | 449 | . $shortcode |
| 450 | - . '" data-linked-input-id="' . $field_id . '">' |
|
| 450 | + . '" data-linked-input-id="'.$field_id.'">' |
|
| 451 | 451 | . $shortcode |
| 452 | 452 | . '</span>'; |
| 453 | 453 | } |
| 454 | - $codes[ $field ] = implode(', ', $available_shortcodes); |
|
| 454 | + $codes[$field] = implode(', ', $available_shortcodes); |
|
| 455 | 455 | } |
| 456 | 456 | $shortcodes = $codes; |
| 457 | - $form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php'; |
|
| 457 | + $form_template = REG_CAF_TEMPLATE_PATH.'newsletter-send-form.template.php'; |
|
| 458 | 458 | $form_template_args = array( |
| 459 | 459 | 'form_action' => admin_url('admin.php?page=espresso_registrations'), |
| 460 | 460 | 'form_route' => 'newsletter_selected_send', |
@@ -622,7 +622,7 @@ discard block |
||
| 622 | 622 | */ |
| 623 | 623 | protected function _registration_reports() |
| 624 | 624 | { |
| 625 | - $template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php'; |
|
| 625 | + $template_path = EE_ADMIN_TEMPLATE.'admin_reports.template.php'; |
|
| 626 | 626 | $this->_template_args['admin_page_content'] = EEH_Template::display_template( |
| 627 | 627 | $template_path, |
| 628 | 628 | $this->_reports_template_data, |
@@ -677,7 +677,7 @@ discard block |
||
| 677 | 677 | array_unshift($regs, $column_titles); |
| 678 | 678 | // setup the date range. |
| 679 | 679 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
| 680 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 680 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
| 681 | 681 | $ending_date = new DateTime("now", $DateTimeZone); |
| 682 | 682 | $subtitle = sprintf( |
| 683 | 683 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -697,7 +697,7 @@ discard block |
||
| 697 | 697 | '%sThere are currently no registration records in the last month for this report.%s', |
| 698 | 698 | 'event_espresso' |
| 699 | 699 | ), |
| 700 | - '<h2>' . $report_title . '</h2><p>', |
|
| 700 | + '<h2>'.$report_title.'</h2><p>', |
|
| 701 | 701 | '</p>' |
| 702 | 702 | ), |
| 703 | 703 | ); |
@@ -750,7 +750,7 @@ discard block |
||
| 750 | 750 | array_unshift($regs, $column_titles); |
| 751 | 751 | // setup the date range. |
| 752 | 752 | $DateTimeZone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
| 753 | - $beginning_date = new DateTime("now " . $period, $DateTimeZone); |
|
| 753 | + $beginning_date = new DateTime("now ".$period, $DateTimeZone); |
|
| 754 | 754 | $ending_date = new DateTime("now", $DateTimeZone); |
| 755 | 755 | $subtitle = sprintf( |
| 756 | 756 | _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso'), |
@@ -770,7 +770,7 @@ discard block |
||
| 770 | 770 | '%sThere are currently no registration records in the last month for this report.%s', |
| 771 | 771 | 'event_espresso' |
| 772 | 772 | ), |
| 773 | - '<h2>' . $report_title . '</h2><p>', |
|
| 773 | + '<h2>'.$report_title.'</h2><p>', |
|
| 774 | 774 | '</p>' |
| 775 | 775 | ), |
| 776 | 776 | ); |
@@ -796,7 +796,7 @@ discard block |
||
| 796 | 796 | $reg_id = isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : null; |
| 797 | 797 | /** @var EE_Registration $registration */ |
| 798 | 798 | $registration = EEM_Registration::instance()->get_one_by_ID($reg_id); |
| 799 | - if (! $registration instanceof EE_Registration) { |
|
| 799 | + if ( ! $registration instanceof EE_Registration) { |
|
| 800 | 800 | throw new EE_Error( |
| 801 | 801 | sprintf( |
| 802 | 802 | esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'), |
@@ -831,7 +831,7 @@ discard block |
||
| 831 | 831 | if ($datetime instanceof EE_Datetime) { |
| 832 | 832 | $datetime_label = $datetime->get_dtt_display_name(true); |
| 833 | 833 | $datetime_label .= ! empty($datetime_label) |
| 834 | - ? ' (' . $datetime->get_dtt_display_name() . ')' |
|
| 834 | + ? ' ('.$datetime->get_dtt_display_name().')' |
|
| 835 | 835 | : $datetime->get_dtt_display_name(); |
| 836 | 836 | } |
| 837 | 837 | $datetime_link = ! empty($dtt_id) && $registration instanceof EE_Registration |
@@ -845,7 +845,7 @@ discard block |
||
| 845 | 845 | ) |
| 846 | 846 | : ''; |
| 847 | 847 | $datetime_link = ! empty($datetime_link) |
| 848 | - ? '<a href="' . $datetime_link . '">' |
|
| 848 | + ? '<a href="'.$datetime_link.'">' |
|
| 849 | 849 | . '<span id="checkin-dtt">' |
| 850 | 850 | . $datetime_label |
| 851 | 851 | . '</span></a>' |
@@ -857,8 +857,8 @@ discard block |
||
| 857 | 857 | ? $attendee->get_admin_details_link() |
| 858 | 858 | : ''; |
| 859 | 859 | $attendee_link = ! empty($attendee_link) |
| 860 | - ? '<a href="' . $attendee->get_admin_details_link() . '"' |
|
| 861 | - . ' title="' . esc_html__('Click for attendee details', 'event_espresso') . '">' |
|
| 860 | + ? '<a href="'.$attendee->get_admin_details_link().'"' |
|
| 861 | + . ' title="'.esc_html__('Click for attendee details', 'event_espresso').'">' |
|
| 862 | 862 | . '<span id="checkin-attendee-name">' |
| 863 | 863 | . $attendee_name |
| 864 | 864 | . '</span></a>' |
@@ -867,25 +867,25 @@ discard block |
||
| 867 | 867 | ? $registration->event()->get_admin_details_link() |
| 868 | 868 | : ''; |
| 869 | 869 | $event_link = ! empty($event_link) |
| 870 | - ? '<a href="' . $event_link . '"' |
|
| 871 | - . ' title="' . esc_html__('Click here to edit event.', 'event_espresso') . '">' |
|
| 870 | + ? '<a href="'.$event_link.'"' |
|
| 871 | + . ' title="'.esc_html__('Click here to edit event.', 'event_espresso').'">' |
|
| 872 | 872 | . '<span id="checkin-event-name">' |
| 873 | 873 | . $registration->event_name() |
| 874 | 874 | . '</span>' |
| 875 | 875 | . '</a>' |
| 876 | 876 | : ''; |
| 877 | 877 | $this->_template_args['before_list_table'] = ! empty($reg_id) && ! empty($dtt_id) |
| 878 | - ? '<h2>' . sprintf( |
|
| 878 | + ? '<h2>'.sprintf( |
|
| 879 | 879 | esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'), |
| 880 | 880 | $attendee_link, |
| 881 | 881 | $datetime_link, |
| 882 | 882 | $event_link |
| 883 | - ) . '</h2>' |
|
| 883 | + ).'</h2>' |
|
| 884 | 884 | : ''; |
| 885 | 885 | $this->_template_args['list_table_hidden_fields'] = ! empty($reg_id) |
| 886 | - ? '<input type="hidden" name="_REG_ID" value="' . $reg_id . '">' : ''; |
|
| 886 | + ? '<input type="hidden" name="_REG_ID" value="'.$reg_id.'">' : ''; |
|
| 887 | 887 | $this->_template_args['list_table_hidden_fields'] .= ! empty($dtt_id) |
| 888 | - ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : ''; |
|
| 888 | + ? '<input type="hidden" name="DTT_ID" value="'.$dtt_id.'">' : ''; |
|
| 889 | 889 | $this->display_admin_list_table_page_with_no_sidebar(); |
| 890 | 890 | } |
| 891 | 891 | |
@@ -902,7 +902,7 @@ discard block |
||
| 902 | 902 | public function toggle_checkin_status() |
| 903 | 903 | { |
| 904 | 904 | // first make sure we have the necessary data |
| 905 | - if (! isset($this->_req_data['_regid'])) { |
|
| 905 | + if ( ! isset($this->_req_data['_regid'])) { |
|
| 906 | 906 | EE_Error::add_error( |
| 907 | 907 | esc_html__( |
| 908 | 908 | 'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', |
@@ -924,7 +924,7 @@ discard block |
||
| 924 | 924 | // beautiful! Made it this far so let's get the status. |
| 925 | 925 | $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status()); |
| 926 | 926 | // setup new class to return via ajax |
| 927 | - $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses(); |
|
| 927 | + $this->_template_args['admin_page_content'] = 'clickable trigger-checkin '.$new_status->cssClasses(); |
|
| 928 | 928 | $this->_template_args['success'] = true; |
| 929 | 929 | $this->_return_json(); |
| 930 | 930 | } |
@@ -950,7 +950,7 @@ discard block |
||
| 950 | 950 | ); |
| 951 | 951 | $new_status = false; |
| 952 | 952 | // bulk action check in toggle |
| 953 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 953 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 954 | 954 | // cycle thru checkboxes |
| 955 | 955 | while (list($REG_ID, $value) = each($this->_req_data['checkbox'])) { |
| 956 | 956 | $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : null; |
@@ -1020,9 +1020,9 @@ discard block |
||
| 1020 | 1020 | '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
| 1021 | 1021 | ); |
| 1022 | 1022 | $errors = 0; |
| 1023 | - if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1023 | + if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) { |
|
| 1024 | 1024 | while (list($CHK_ID, $value) = each($this->_req_data['checkbox'])) { |
| 1025 | - if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1025 | + if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) { |
|
| 1026 | 1026 | $errors++; |
| 1027 | 1027 | } |
| 1028 | 1028 | } |
@@ -1068,8 +1068,8 @@ discard block |
||
| 1068 | 1068 | 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, |
| 1069 | 1069 | '_REG_ID' => isset($this->_req_data['_REG_ID']) ? $this->_req_data['_REG_ID'] : 0, |
| 1070 | 1070 | ); |
| 1071 | - if (! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | - if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1071 | + if ( ! empty($this->_req_data['CHK_ID'])) { |
|
| 1072 | + if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) { |
|
| 1073 | 1073 | EE_Error::add_error( |
| 1074 | 1074 | esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'), |
| 1075 | 1075 | __FILE__, |
@@ -1138,27 +1138,27 @@ discard block |
||
| 1138 | 1138 | 'desc' => $checked_never->legendLabel(), |
| 1139 | 1139 | ), |
| 1140 | 1140 | 'approved_status' => array( |
| 1141 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved, |
|
| 1141 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_approved, |
|
| 1142 | 1142 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'), |
| 1143 | 1143 | ), |
| 1144 | 1144 | 'cancelled_status' => array( |
| 1145 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled, |
|
| 1145 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_cancelled, |
|
| 1146 | 1146 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'), |
| 1147 | 1147 | ), |
| 1148 | 1148 | 'declined_status' => array( |
| 1149 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined, |
|
| 1149 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_declined, |
|
| 1150 | 1150 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'), |
| 1151 | 1151 | ), |
| 1152 | 1152 | 'not_approved' => array( |
| 1153 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved, |
|
| 1153 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_not_approved, |
|
| 1154 | 1154 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'), |
| 1155 | 1155 | ), |
| 1156 | 1156 | 'pending_status' => array( |
| 1157 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment, |
|
| 1157 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_pending_payment, |
|
| 1158 | 1158 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'), |
| 1159 | 1159 | ), |
| 1160 | 1160 | 'wait_list' => array( |
| 1161 | - 'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list, |
|
| 1161 | + 'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_wait_list, |
|
| 1162 | 1162 | 'desc' => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'), |
| 1163 | 1163 | ), |
| 1164 | 1164 | ); |
@@ -1167,10 +1167,10 @@ discard block |
||
| 1167 | 1167 | /** @var EE_Event $event */ |
| 1168 | 1168 | $event = EEM_Event::instance()->get_one_by_ID($event_id); |
| 1169 | 1169 | $this->_template_args['before_list_table'] = $event instanceof EE_Event |
| 1170 | - ? '<h2>' . sprintf( |
|
| 1170 | + ? '<h2>'.sprintf( |
|
| 1171 | 1171 | esc_html__('Viewing Registrations for Event: %s', 'event_espresso'), |
| 1172 | 1172 | EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') |
| 1173 | - ) . '</h2>' |
|
| 1173 | + ).'</h2>' |
|
| 1174 | 1174 | : ''; |
| 1175 | 1175 | // need to get the number of datetimes on the event and set default datetime_id if there is only one datetime on |
| 1176 | 1176 | // the event. |
@@ -1188,12 +1188,12 @@ discard block |
||
| 1188 | 1188 | $this->_template_args['before_list_table'] .= ' <span class="drk-grey-text">'; |
| 1189 | 1189 | $this->_template_args['before_list_table'] .= '<span class="dashicons dashicons-calendar"></span>'; |
| 1190 | 1190 | $this->_template_args['before_list_table'] .= $datetime->name(); |
| 1191 | - $this->_template_args['before_list_table'] .= ' ( ' . $datetime->date_and_time_range() . ' )'; |
|
| 1191 | + $this->_template_args['before_list_table'] .= ' ( '.$datetime->date_and_time_range().' )'; |
|
| 1192 | 1192 | $this->_template_args['before_list_table'] .= '</span></h2>'; |
| 1193 | 1193 | } |
| 1194 | 1194 | // if no datetime, then we're on the initial view, so let's give some helpful instructions on what the status |
| 1195 | 1195 | // column represents |
| 1196 | - if (! $datetime instanceof EE_Datetime) { |
|
| 1196 | + if ( ! $datetime instanceof EE_Datetime) { |
|
| 1197 | 1197 | $this->_template_args['before_list_table'] .= '<br><p class="description">' |
| 1198 | 1198 | . esc_html__( |
| 1199 | 1199 | 'In this view, the check-in status represents the latest check-in record for the registration in that row.', |