@@ -14,1748 +14,1748 @@ |
||
| 14 | 14 | class EE_Line_Item extends EE_Base_Class implements EEI_Line_Item |
| 15 | 15 | { |
| 16 | 16 | |
| 17 | - /** |
|
| 18 | - * for children line items (currently not a normal relation) |
|
| 19 | - * |
|
| 20 | - * @type EE_Line_Item[] |
|
| 21 | - */ |
|
| 22 | - protected $_children = array(); |
|
| 23 | - |
|
| 24 | - /** |
|
| 25 | - * for the parent line item |
|
| 26 | - * |
|
| 27 | - * @var EE_Line_Item |
|
| 28 | - */ |
|
| 29 | - protected $_parent; |
|
| 30 | - |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * @param array $props_n_values incoming values |
|
| 34 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 35 | - * used.) |
|
| 36 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 37 | - * date_format and the second value is the time format |
|
| 38 | - * @return EE_Line_Item |
|
| 39 | - * @throws EE_Error |
|
| 40 | - * @throws InvalidArgumentException |
|
| 41 | - * @throws InvalidDataTypeException |
|
| 42 | - * @throws InvalidInterfaceException |
|
| 43 | - * @throws ReflectionException |
|
| 44 | - */ |
|
| 45 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 46 | - { |
|
| 47 | - $has_object = parent::_check_for_object( |
|
| 48 | - $props_n_values, |
|
| 49 | - __CLASS__, |
|
| 50 | - $timezone, |
|
| 51 | - $date_formats |
|
| 52 | - ); |
|
| 53 | - return $has_object |
|
| 54 | - ? $has_object |
|
| 55 | - : new self($props_n_values, false, $timezone); |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - |
|
| 59 | - /** |
|
| 60 | - * @param array $props_n_values incoming values from the database |
|
| 61 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 62 | - * the website will be used. |
|
| 63 | - * @return EE_Line_Item |
|
| 64 | - * @throws EE_Error |
|
| 65 | - * @throws InvalidArgumentException |
|
| 66 | - * @throws InvalidDataTypeException |
|
| 67 | - * @throws InvalidInterfaceException |
|
| 68 | - * @throws ReflectionException |
|
| 69 | - */ |
|
| 70 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 71 | - { |
|
| 72 | - return new self($props_n_values, true, $timezone); |
|
| 73 | - } |
|
| 74 | - |
|
| 75 | - |
|
| 76 | - /** |
|
| 77 | - * Adds some defaults if they're not specified |
|
| 78 | - * |
|
| 79 | - * @param array $fieldValues |
|
| 80 | - * @param bool $bydb |
|
| 81 | - * @param string $timezone |
|
| 82 | - * @throws EE_Error |
|
| 83 | - * @throws InvalidArgumentException |
|
| 84 | - * @throws InvalidDataTypeException |
|
| 85 | - * @throws InvalidInterfaceException |
|
| 86 | - * @throws ReflectionException |
|
| 87 | - */ |
|
| 88 | - protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') |
|
| 89 | - { |
|
| 90 | - parent::__construct($fieldValues, $bydb, $timezone); |
|
| 91 | - if (! $this->get('LIN_code')) { |
|
| 92 | - $this->set_code($this->generate_code()); |
|
| 93 | - } |
|
| 94 | - } |
|
| 95 | - |
|
| 96 | - |
|
| 97 | - /** |
|
| 98 | - * Gets ID |
|
| 99 | - * |
|
| 100 | - * @return int |
|
| 101 | - * @throws EE_Error |
|
| 102 | - * @throws InvalidArgumentException |
|
| 103 | - * @throws InvalidDataTypeException |
|
| 104 | - * @throws InvalidInterfaceException |
|
| 105 | - * @throws ReflectionException |
|
| 106 | - */ |
|
| 107 | - public function ID() |
|
| 108 | - { |
|
| 109 | - return $this->get('LIN_ID'); |
|
| 110 | - } |
|
| 111 | - |
|
| 112 | - |
|
| 113 | - /** |
|
| 114 | - * Gets TXN_ID |
|
| 115 | - * |
|
| 116 | - * @return int |
|
| 117 | - * @throws EE_Error |
|
| 118 | - * @throws InvalidArgumentException |
|
| 119 | - * @throws InvalidDataTypeException |
|
| 120 | - * @throws InvalidInterfaceException |
|
| 121 | - * @throws ReflectionException |
|
| 122 | - */ |
|
| 123 | - public function TXN_ID() |
|
| 124 | - { |
|
| 125 | - return $this->get('TXN_ID'); |
|
| 126 | - } |
|
| 127 | - |
|
| 128 | - |
|
| 129 | - /** |
|
| 130 | - * Sets TXN_ID |
|
| 131 | - * |
|
| 132 | - * @param int $TXN_ID |
|
| 133 | - * @throws EE_Error |
|
| 134 | - * @throws InvalidArgumentException |
|
| 135 | - * @throws InvalidDataTypeException |
|
| 136 | - * @throws InvalidInterfaceException |
|
| 137 | - * @throws ReflectionException |
|
| 138 | - */ |
|
| 139 | - public function set_TXN_ID($TXN_ID) |
|
| 140 | - { |
|
| 141 | - $this->set('TXN_ID', $TXN_ID); |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - |
|
| 145 | - /** |
|
| 146 | - * Gets name |
|
| 147 | - * |
|
| 148 | - * @return string |
|
| 149 | - * @throws EE_Error |
|
| 150 | - * @throws InvalidArgumentException |
|
| 151 | - * @throws InvalidDataTypeException |
|
| 152 | - * @throws InvalidInterfaceException |
|
| 153 | - * @throws ReflectionException |
|
| 154 | - */ |
|
| 155 | - public function name() |
|
| 156 | - { |
|
| 157 | - $name = $this->get('LIN_name'); |
|
| 158 | - if (! $name) { |
|
| 159 | - $name = ucwords(str_replace('-', ' ', $this->type())); |
|
| 160 | - } |
|
| 161 | - return $name; |
|
| 162 | - } |
|
| 163 | - |
|
| 164 | - |
|
| 165 | - /** |
|
| 166 | - * Sets name |
|
| 167 | - * |
|
| 168 | - * @param string $name |
|
| 169 | - * @throws EE_Error |
|
| 170 | - * @throws InvalidArgumentException |
|
| 171 | - * @throws InvalidDataTypeException |
|
| 172 | - * @throws InvalidInterfaceException |
|
| 173 | - * @throws ReflectionException |
|
| 174 | - */ |
|
| 175 | - public function set_name($name) |
|
| 176 | - { |
|
| 177 | - $this->set('LIN_name', $name); |
|
| 178 | - } |
|
| 179 | - |
|
| 180 | - |
|
| 181 | - /** |
|
| 182 | - * Gets desc |
|
| 183 | - * |
|
| 184 | - * @return string |
|
| 185 | - * @throws EE_Error |
|
| 186 | - * @throws InvalidArgumentException |
|
| 187 | - * @throws InvalidDataTypeException |
|
| 188 | - * @throws InvalidInterfaceException |
|
| 189 | - * @throws ReflectionException |
|
| 190 | - */ |
|
| 191 | - public function desc() |
|
| 192 | - { |
|
| 193 | - return $this->get('LIN_desc'); |
|
| 194 | - } |
|
| 195 | - |
|
| 196 | - |
|
| 197 | - /** |
|
| 198 | - * Sets desc |
|
| 199 | - * |
|
| 200 | - * @param string $desc |
|
| 201 | - * @throws EE_Error |
|
| 202 | - * @throws InvalidArgumentException |
|
| 203 | - * @throws InvalidDataTypeException |
|
| 204 | - * @throws InvalidInterfaceException |
|
| 205 | - * @throws ReflectionException |
|
| 206 | - */ |
|
| 207 | - public function set_desc($desc) |
|
| 208 | - { |
|
| 209 | - $this->set('LIN_desc', $desc); |
|
| 210 | - } |
|
| 211 | - |
|
| 212 | - |
|
| 213 | - /** |
|
| 214 | - * Gets quantity |
|
| 215 | - * |
|
| 216 | - * @return int |
|
| 217 | - * @throws EE_Error |
|
| 218 | - * @throws InvalidArgumentException |
|
| 219 | - * @throws InvalidDataTypeException |
|
| 220 | - * @throws InvalidInterfaceException |
|
| 221 | - * @throws ReflectionException |
|
| 222 | - */ |
|
| 223 | - public function quantity() |
|
| 224 | - { |
|
| 225 | - return $this->get('LIN_quantity'); |
|
| 226 | - } |
|
| 227 | - |
|
| 228 | - |
|
| 229 | - /** |
|
| 230 | - * Sets quantity |
|
| 231 | - * |
|
| 232 | - * @param int $quantity |
|
| 233 | - * @throws EE_Error |
|
| 234 | - * @throws InvalidArgumentException |
|
| 235 | - * @throws InvalidDataTypeException |
|
| 236 | - * @throws InvalidInterfaceException |
|
| 237 | - * @throws ReflectionException |
|
| 238 | - */ |
|
| 239 | - public function set_quantity($quantity) |
|
| 240 | - { |
|
| 241 | - $this->set('LIN_quantity', max($quantity, 0)); |
|
| 242 | - } |
|
| 243 | - |
|
| 244 | - |
|
| 245 | - /** |
|
| 246 | - * Gets item_id |
|
| 247 | - * |
|
| 248 | - * @return string |
|
| 249 | - * @throws EE_Error |
|
| 250 | - * @throws InvalidArgumentException |
|
| 251 | - * @throws InvalidDataTypeException |
|
| 252 | - * @throws InvalidInterfaceException |
|
| 253 | - * @throws ReflectionException |
|
| 254 | - */ |
|
| 255 | - public function OBJ_ID() |
|
| 256 | - { |
|
| 257 | - return $this->get('OBJ_ID'); |
|
| 258 | - } |
|
| 259 | - |
|
| 260 | - |
|
| 261 | - /** |
|
| 262 | - * Sets item_id |
|
| 263 | - * |
|
| 264 | - * @param string $item_id |
|
| 265 | - * @throws EE_Error |
|
| 266 | - * @throws InvalidArgumentException |
|
| 267 | - * @throws InvalidDataTypeException |
|
| 268 | - * @throws InvalidInterfaceException |
|
| 269 | - * @throws ReflectionException |
|
| 270 | - */ |
|
| 271 | - public function set_OBJ_ID($item_id) |
|
| 272 | - { |
|
| 273 | - $this->set('OBJ_ID', $item_id); |
|
| 274 | - } |
|
| 275 | - |
|
| 276 | - |
|
| 277 | - /** |
|
| 278 | - * Gets item_type |
|
| 279 | - * |
|
| 280 | - * @return string |
|
| 281 | - * @throws EE_Error |
|
| 282 | - * @throws InvalidArgumentException |
|
| 283 | - * @throws InvalidDataTypeException |
|
| 284 | - * @throws InvalidInterfaceException |
|
| 285 | - * @throws ReflectionException |
|
| 286 | - */ |
|
| 287 | - public function OBJ_type() |
|
| 288 | - { |
|
| 289 | - return $this->get('OBJ_type'); |
|
| 290 | - } |
|
| 291 | - |
|
| 292 | - |
|
| 293 | - /** |
|
| 294 | - * Gets item_type |
|
| 295 | - * |
|
| 296 | - * @return string |
|
| 297 | - * @throws EE_Error |
|
| 298 | - * @throws InvalidArgumentException |
|
| 299 | - * @throws InvalidDataTypeException |
|
| 300 | - * @throws InvalidInterfaceException |
|
| 301 | - * @throws ReflectionException |
|
| 302 | - */ |
|
| 303 | - public function OBJ_type_i18n() |
|
| 304 | - { |
|
| 305 | - $obj_type = $this->OBJ_type(); |
|
| 306 | - switch ($obj_type) { |
|
| 307 | - case EEM_Line_Item::OBJ_TYPE_EVENT: |
|
| 308 | - $obj_type = esc_html__('Event', 'event_espresso'); |
|
| 309 | - break; |
|
| 310 | - case EEM_Line_Item::OBJ_TYPE_PRICE: |
|
| 311 | - $obj_type = esc_html__('Price', 'event_espresso'); |
|
| 312 | - break; |
|
| 313 | - case EEM_Line_Item::OBJ_TYPE_PROMOTION: |
|
| 314 | - $obj_type = esc_html__('Promotion', 'event_espresso'); |
|
| 315 | - break; |
|
| 316 | - case EEM_Line_Item::OBJ_TYPE_TICKET: |
|
| 317 | - $obj_type = esc_html__('Ticket', 'event_espresso'); |
|
| 318 | - break; |
|
| 319 | - case EEM_Line_Item::OBJ_TYPE_TRANSACTION: |
|
| 320 | - $obj_type = esc_html__('Transaction', 'event_espresso'); |
|
| 321 | - break; |
|
| 322 | - } |
|
| 323 | - return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this); |
|
| 324 | - } |
|
| 325 | - |
|
| 326 | - |
|
| 327 | - /** |
|
| 328 | - * Sets item_type |
|
| 329 | - * |
|
| 330 | - * @param string $OBJ_type |
|
| 331 | - * @throws EE_Error |
|
| 332 | - * @throws InvalidArgumentException |
|
| 333 | - * @throws InvalidDataTypeException |
|
| 334 | - * @throws InvalidInterfaceException |
|
| 335 | - * @throws ReflectionException |
|
| 336 | - */ |
|
| 337 | - public function set_OBJ_type($OBJ_type) |
|
| 338 | - { |
|
| 339 | - $this->set('OBJ_type', $OBJ_type); |
|
| 340 | - } |
|
| 341 | - |
|
| 342 | - |
|
| 343 | - /** |
|
| 344 | - * Gets unit_price |
|
| 345 | - * |
|
| 346 | - * @return float |
|
| 347 | - * @throws EE_Error |
|
| 348 | - * @throws InvalidArgumentException |
|
| 349 | - * @throws InvalidDataTypeException |
|
| 350 | - * @throws InvalidInterfaceException |
|
| 351 | - * @throws ReflectionException |
|
| 352 | - */ |
|
| 353 | - public function unit_price() |
|
| 354 | - { |
|
| 355 | - return $this->get('LIN_unit_price'); |
|
| 356 | - } |
|
| 357 | - |
|
| 358 | - |
|
| 359 | - /** |
|
| 360 | - * Sets unit_price |
|
| 361 | - * |
|
| 362 | - * @param float $unit_price |
|
| 363 | - * @throws EE_Error |
|
| 364 | - * @throws InvalidArgumentException |
|
| 365 | - * @throws InvalidDataTypeException |
|
| 366 | - * @throws InvalidInterfaceException |
|
| 367 | - * @throws ReflectionException |
|
| 368 | - */ |
|
| 369 | - public function set_unit_price($unit_price) |
|
| 370 | - { |
|
| 371 | - $this->set('LIN_unit_price', $unit_price); |
|
| 372 | - } |
|
| 373 | - |
|
| 374 | - |
|
| 375 | - /** |
|
| 376 | - * Checks if this item is a percentage modifier or not |
|
| 377 | - * |
|
| 378 | - * @return boolean |
|
| 379 | - * @throws EE_Error |
|
| 380 | - * @throws InvalidArgumentException |
|
| 381 | - * @throws InvalidDataTypeException |
|
| 382 | - * @throws InvalidInterfaceException |
|
| 383 | - * @throws ReflectionException |
|
| 384 | - */ |
|
| 385 | - public function is_percent() |
|
| 386 | - { |
|
| 387 | - if ($this->is_tax_sub_total()) { |
|
| 388 | - // tax subtotals HAVE a percent on them, that percentage only applies |
|
| 389 | - // to taxable items, so its' an exception. Treat it like a flat line item |
|
| 390 | - return false; |
|
| 391 | - } |
|
| 392 | - $unit_price = abs($this->get('LIN_unit_price')); |
|
| 393 | - $percent = abs($this->get('LIN_percent')); |
|
| 394 | - if ($unit_price < .001 && $percent) { |
|
| 395 | - return true; |
|
| 396 | - } |
|
| 397 | - if ($unit_price >= .001 && ! $percent) { |
|
| 398 | - return false; |
|
| 399 | - } |
|
| 400 | - if ($unit_price >= .001 && $percent) { |
|
| 401 | - throw new EE_Error( |
|
| 402 | - sprintf( |
|
| 403 | - esc_html__( |
|
| 404 | - 'A Line Item can not have a unit price of (%s) AND a percent (%s)!', |
|
| 405 | - 'event_espresso' |
|
| 406 | - ), |
|
| 407 | - $unit_price, |
|
| 408 | - $percent |
|
| 409 | - ) |
|
| 410 | - ); |
|
| 411 | - } |
|
| 412 | - // if they're both 0, assume its not a percent item |
|
| 413 | - return false; |
|
| 414 | - } |
|
| 415 | - |
|
| 416 | - |
|
| 417 | - /** |
|
| 418 | - * Gets percent (between 100-.001) |
|
| 419 | - * |
|
| 420 | - * @return float |
|
| 421 | - * @throws EE_Error |
|
| 422 | - * @throws InvalidArgumentException |
|
| 423 | - * @throws InvalidDataTypeException |
|
| 424 | - * @throws InvalidInterfaceException |
|
| 425 | - * @throws ReflectionException |
|
| 426 | - */ |
|
| 427 | - public function percent() |
|
| 428 | - { |
|
| 429 | - return $this->get('LIN_percent'); |
|
| 430 | - } |
|
| 431 | - |
|
| 432 | - |
|
| 433 | - /** |
|
| 434 | - * Sets percent (between 100-0.01) |
|
| 435 | - * |
|
| 436 | - * @param float $percent |
|
| 437 | - * @throws EE_Error |
|
| 438 | - * @throws InvalidArgumentException |
|
| 439 | - * @throws InvalidDataTypeException |
|
| 440 | - * @throws InvalidInterfaceException |
|
| 441 | - * @throws ReflectionException |
|
| 442 | - */ |
|
| 443 | - public function set_percent($percent) |
|
| 444 | - { |
|
| 445 | - $this->set('LIN_percent', $percent); |
|
| 446 | - } |
|
| 447 | - |
|
| 448 | - |
|
| 449 | - /** |
|
| 450 | - * Gets total |
|
| 451 | - * |
|
| 452 | - * @return float |
|
| 453 | - * @throws EE_Error |
|
| 454 | - * @throws InvalidArgumentException |
|
| 455 | - * @throws InvalidDataTypeException |
|
| 456 | - * @throws InvalidInterfaceException |
|
| 457 | - * @throws ReflectionException |
|
| 458 | - */ |
|
| 459 | - public function total() |
|
| 460 | - { |
|
| 461 | - return $this->get('LIN_total'); |
|
| 462 | - } |
|
| 463 | - |
|
| 464 | - |
|
| 465 | - /** |
|
| 466 | - * Sets total |
|
| 467 | - * |
|
| 468 | - * @param float $total |
|
| 469 | - * @throws EE_Error |
|
| 470 | - * @throws InvalidArgumentException |
|
| 471 | - * @throws InvalidDataTypeException |
|
| 472 | - * @throws InvalidInterfaceException |
|
| 473 | - * @throws ReflectionException |
|
| 474 | - */ |
|
| 475 | - public function set_total($total) |
|
| 476 | - { |
|
| 477 | - $this->set('LIN_total', $total); |
|
| 478 | - } |
|
| 479 | - |
|
| 480 | - |
|
| 481 | - /** |
|
| 482 | - * Gets order |
|
| 483 | - * |
|
| 484 | - * @return int |
|
| 485 | - * @throws EE_Error |
|
| 486 | - * @throws InvalidArgumentException |
|
| 487 | - * @throws InvalidDataTypeException |
|
| 488 | - * @throws InvalidInterfaceException |
|
| 489 | - * @throws ReflectionException |
|
| 490 | - */ |
|
| 491 | - public function order() |
|
| 492 | - { |
|
| 493 | - return $this->get('LIN_order'); |
|
| 494 | - } |
|
| 495 | - |
|
| 496 | - |
|
| 497 | - /** |
|
| 498 | - * Sets order |
|
| 499 | - * |
|
| 500 | - * @param int $order |
|
| 501 | - * @throws EE_Error |
|
| 502 | - * @throws InvalidArgumentException |
|
| 503 | - * @throws InvalidDataTypeException |
|
| 504 | - * @throws InvalidInterfaceException |
|
| 505 | - * @throws ReflectionException |
|
| 506 | - */ |
|
| 507 | - public function set_order($order) |
|
| 508 | - { |
|
| 509 | - $this->set('LIN_order', $order); |
|
| 510 | - } |
|
| 511 | - |
|
| 512 | - |
|
| 513 | - /** |
|
| 514 | - * Gets parent |
|
| 515 | - * |
|
| 516 | - * @return int |
|
| 517 | - * @throws EE_Error |
|
| 518 | - * @throws InvalidArgumentException |
|
| 519 | - * @throws InvalidDataTypeException |
|
| 520 | - * @throws InvalidInterfaceException |
|
| 521 | - * @throws ReflectionException |
|
| 522 | - */ |
|
| 523 | - public function parent_ID() |
|
| 524 | - { |
|
| 525 | - return $this->get('LIN_parent'); |
|
| 526 | - } |
|
| 527 | - |
|
| 528 | - |
|
| 529 | - /** |
|
| 530 | - * Sets parent |
|
| 531 | - * |
|
| 532 | - * @param int $parent |
|
| 533 | - * @throws EE_Error |
|
| 534 | - * @throws InvalidArgumentException |
|
| 535 | - * @throws InvalidDataTypeException |
|
| 536 | - * @throws InvalidInterfaceException |
|
| 537 | - * @throws ReflectionException |
|
| 538 | - */ |
|
| 539 | - public function set_parent_ID($parent) |
|
| 540 | - { |
|
| 541 | - $this->set('LIN_parent', $parent); |
|
| 542 | - } |
|
| 543 | - |
|
| 544 | - |
|
| 545 | - /** |
|
| 546 | - * Gets type |
|
| 547 | - * |
|
| 548 | - * @return string |
|
| 549 | - * @throws EE_Error |
|
| 550 | - * @throws InvalidArgumentException |
|
| 551 | - * @throws InvalidDataTypeException |
|
| 552 | - * @throws InvalidInterfaceException |
|
| 553 | - * @throws ReflectionException |
|
| 554 | - */ |
|
| 555 | - public function type() |
|
| 556 | - { |
|
| 557 | - return $this->get('LIN_type'); |
|
| 558 | - } |
|
| 559 | - |
|
| 560 | - |
|
| 561 | - /** |
|
| 562 | - * Sets type |
|
| 563 | - * |
|
| 564 | - * @param string $type |
|
| 565 | - * @throws EE_Error |
|
| 566 | - * @throws InvalidArgumentException |
|
| 567 | - * @throws InvalidDataTypeException |
|
| 568 | - * @throws InvalidInterfaceException |
|
| 569 | - * @throws ReflectionException |
|
| 570 | - */ |
|
| 571 | - public function set_type($type) |
|
| 572 | - { |
|
| 573 | - $this->set('LIN_type', $type); |
|
| 574 | - } |
|
| 575 | - |
|
| 576 | - |
|
| 577 | - /** |
|
| 578 | - * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\ |
|
| 579 | - * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB |
|
| 580 | - * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()` |
|
| 581 | - * or indirectly by `EE_Line_item::add_child_line_item()`) |
|
| 582 | - * |
|
| 583 | - * @return EE_Base_Class|EE_Line_Item |
|
| 584 | - * @throws EE_Error |
|
| 585 | - * @throws InvalidArgumentException |
|
| 586 | - * @throws InvalidDataTypeException |
|
| 587 | - * @throws InvalidInterfaceException |
|
| 588 | - * @throws ReflectionException |
|
| 589 | - */ |
|
| 590 | - public function parent() |
|
| 591 | - { |
|
| 592 | - return $this->ID() |
|
| 593 | - ? $this->get_model()->get_one_by_ID($this->parent_ID()) |
|
| 594 | - : $this->_parent; |
|
| 595 | - } |
|
| 596 | - |
|
| 597 | - |
|
| 598 | - /** |
|
| 599 | - * Gets ALL the children of this line item (ie, all the parts that contribute towards this total). |
|
| 600 | - * |
|
| 601 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 602 | - * @throws EE_Error |
|
| 603 | - * @throws InvalidArgumentException |
|
| 604 | - * @throws InvalidDataTypeException |
|
| 605 | - * @throws InvalidInterfaceException |
|
| 606 | - * @throws ReflectionException |
|
| 607 | - */ |
|
| 608 | - public function children() |
|
| 609 | - { |
|
| 610 | - if ($this->ID()) { |
|
| 611 | - return $this->get_model()->get_all( |
|
| 612 | - array( |
|
| 613 | - array('LIN_parent' => $this->ID()), |
|
| 614 | - 'order_by' => array('LIN_order' => 'ASC'), |
|
| 615 | - ) |
|
| 616 | - ); |
|
| 617 | - } |
|
| 618 | - if (! is_array($this->_children)) { |
|
| 619 | - $this->_children = array(); |
|
| 620 | - } |
|
| 621 | - return $this->_children; |
|
| 622 | - } |
|
| 623 | - |
|
| 624 | - |
|
| 625 | - /** |
|
| 626 | - * Gets code |
|
| 627 | - * |
|
| 628 | - * @return string |
|
| 629 | - * @throws EE_Error |
|
| 630 | - * @throws InvalidArgumentException |
|
| 631 | - * @throws InvalidDataTypeException |
|
| 632 | - * @throws InvalidInterfaceException |
|
| 633 | - * @throws ReflectionException |
|
| 634 | - */ |
|
| 635 | - public function code() |
|
| 636 | - { |
|
| 637 | - return $this->get('LIN_code'); |
|
| 638 | - } |
|
| 639 | - |
|
| 640 | - |
|
| 641 | - /** |
|
| 642 | - * Sets code |
|
| 643 | - * |
|
| 644 | - * @param string $code |
|
| 645 | - * @throws EE_Error |
|
| 646 | - * @throws InvalidArgumentException |
|
| 647 | - * @throws InvalidDataTypeException |
|
| 648 | - * @throws InvalidInterfaceException |
|
| 649 | - * @throws ReflectionException |
|
| 650 | - */ |
|
| 651 | - public function set_code($code) |
|
| 652 | - { |
|
| 653 | - $this->set('LIN_code', $code); |
|
| 654 | - } |
|
| 655 | - |
|
| 656 | - |
|
| 657 | - /** |
|
| 658 | - * Gets is_taxable |
|
| 659 | - * |
|
| 660 | - * @return boolean |
|
| 661 | - * @throws EE_Error |
|
| 662 | - * @throws InvalidArgumentException |
|
| 663 | - * @throws InvalidDataTypeException |
|
| 664 | - * @throws InvalidInterfaceException |
|
| 665 | - * @throws ReflectionException |
|
| 666 | - */ |
|
| 667 | - public function is_taxable() |
|
| 668 | - { |
|
| 669 | - return $this->get('LIN_is_taxable'); |
|
| 670 | - } |
|
| 671 | - |
|
| 672 | - |
|
| 673 | - /** |
|
| 674 | - * Sets is_taxable |
|
| 675 | - * |
|
| 676 | - * @param boolean $is_taxable |
|
| 677 | - * @throws EE_Error |
|
| 678 | - * @throws InvalidArgumentException |
|
| 679 | - * @throws InvalidDataTypeException |
|
| 680 | - * @throws InvalidInterfaceException |
|
| 681 | - * @throws ReflectionException |
|
| 682 | - */ |
|
| 683 | - public function set_is_taxable($is_taxable) |
|
| 684 | - { |
|
| 685 | - $this->set('LIN_is_taxable', $is_taxable); |
|
| 686 | - } |
|
| 687 | - |
|
| 688 | - |
|
| 689 | - /** |
|
| 690 | - * Gets the object that this model-joins-to. |
|
| 691 | - * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on |
|
| 692 | - * EEM_Promotion_Object |
|
| 693 | - * Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object |
|
| 694 | - * |
|
| 695 | - * @return EE_Base_Class | NULL |
|
| 696 | - * @throws EE_Error |
|
| 697 | - * @throws InvalidArgumentException |
|
| 698 | - * @throws InvalidDataTypeException |
|
| 699 | - * @throws InvalidInterfaceException |
|
| 700 | - * @throws ReflectionException |
|
| 701 | - */ |
|
| 702 | - public function get_object() |
|
| 703 | - { |
|
| 704 | - $model_name_of_related_obj = $this->OBJ_type(); |
|
| 705 | - return $this->get_model()->has_relation($model_name_of_related_obj) |
|
| 706 | - ? $this->get_first_related($model_name_of_related_obj) |
|
| 707 | - : null; |
|
| 708 | - } |
|
| 709 | - |
|
| 710 | - |
|
| 711 | - /** |
|
| 712 | - * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket. |
|
| 713 | - * (IE, if this line item is for a price or something else, will return NULL) |
|
| 714 | - * |
|
| 715 | - * @param array $query_params |
|
| 716 | - * @return EE_Base_Class|EE_Ticket |
|
| 717 | - * @throws EE_Error |
|
| 718 | - * @throws InvalidArgumentException |
|
| 719 | - * @throws InvalidDataTypeException |
|
| 720 | - * @throws InvalidInterfaceException |
|
| 721 | - * @throws ReflectionException |
|
| 722 | - */ |
|
| 723 | - public function ticket($query_params = array()) |
|
| 724 | - { |
|
| 725 | - // we're going to assume that when this method is called |
|
| 726 | - // we always want to receive the attached ticket EVEN if that ticket is archived. |
|
| 727 | - // This can be overridden via the incoming $query_params argument |
|
| 728 | - $remove_defaults = array('default_where_conditions' => 'none'); |
|
| 729 | - $query_params = array_merge($remove_defaults, $query_params); |
|
| 730 | - return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TICKET, $query_params); |
|
| 731 | - } |
|
| 732 | - |
|
| 733 | - |
|
| 734 | - /** |
|
| 735 | - * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket |
|
| 736 | - * |
|
| 737 | - * @return EE_Datetime | NULL |
|
| 738 | - * @throws EE_Error |
|
| 739 | - * @throws InvalidArgumentException |
|
| 740 | - * @throws InvalidDataTypeException |
|
| 741 | - * @throws InvalidInterfaceException |
|
| 742 | - * @throws ReflectionException |
|
| 743 | - */ |
|
| 744 | - public function get_ticket_datetime() |
|
| 745 | - { |
|
| 746 | - if ($this->OBJ_type() === EEM_Line_Item::OBJ_TYPE_TICKET) { |
|
| 747 | - $ticket = $this->ticket(); |
|
| 748 | - if ($ticket instanceof EE_Ticket) { |
|
| 749 | - $datetime = $ticket->first_datetime(); |
|
| 750 | - if ($datetime instanceof EE_Datetime) { |
|
| 751 | - return $datetime; |
|
| 752 | - } |
|
| 753 | - } |
|
| 754 | - } |
|
| 755 | - return null; |
|
| 756 | - } |
|
| 757 | - |
|
| 758 | - |
|
| 759 | - /** |
|
| 760 | - * Gets the event's name that's related to the ticket, if this is for |
|
| 761 | - * a ticket |
|
| 762 | - * |
|
| 763 | - * @return string |
|
| 764 | - * @throws EE_Error |
|
| 765 | - * @throws InvalidArgumentException |
|
| 766 | - * @throws InvalidDataTypeException |
|
| 767 | - * @throws InvalidInterfaceException |
|
| 768 | - * @throws ReflectionException |
|
| 769 | - */ |
|
| 770 | - public function ticket_event_name() |
|
| 771 | - { |
|
| 772 | - $event_name = esc_html__('Unknown', 'event_espresso'); |
|
| 773 | - $event = $this->ticket_event(); |
|
| 774 | - if ($event instanceof EE_Event) { |
|
| 775 | - $event_name = $event->name(); |
|
| 776 | - } |
|
| 777 | - return $event_name; |
|
| 778 | - } |
|
| 779 | - |
|
| 780 | - |
|
| 781 | - /** |
|
| 782 | - * Gets the event that's related to the ticket, if this line item represents a ticket. |
|
| 783 | - * |
|
| 784 | - * @return EE_Event|null |
|
| 785 | - * @throws EE_Error |
|
| 786 | - * @throws InvalidArgumentException |
|
| 787 | - * @throws InvalidDataTypeException |
|
| 788 | - * @throws InvalidInterfaceException |
|
| 789 | - * @throws ReflectionException |
|
| 790 | - */ |
|
| 791 | - public function ticket_event() |
|
| 792 | - { |
|
| 793 | - $event = null; |
|
| 794 | - $ticket = $this->ticket(); |
|
| 795 | - if ($ticket instanceof EE_Ticket) { |
|
| 796 | - $datetime = $ticket->first_datetime(); |
|
| 797 | - if ($datetime instanceof EE_Datetime) { |
|
| 798 | - $event = $datetime->event(); |
|
| 799 | - } |
|
| 800 | - } |
|
| 801 | - return $event; |
|
| 802 | - } |
|
| 803 | - |
|
| 804 | - |
|
| 805 | - /** |
|
| 806 | - * Gets the first datetime for this lien item, assuming it's for a ticket |
|
| 807 | - * |
|
| 808 | - * @param string $date_format |
|
| 809 | - * @param string $time_format |
|
| 810 | - * @return string |
|
| 811 | - * @throws EE_Error |
|
| 812 | - * @throws InvalidArgumentException |
|
| 813 | - * @throws InvalidDataTypeException |
|
| 814 | - * @throws InvalidInterfaceException |
|
| 815 | - * @throws ReflectionException |
|
| 816 | - */ |
|
| 817 | - public function ticket_datetime_start($date_format = '', $time_format = '') |
|
| 818 | - { |
|
| 819 | - $first_datetime_string = esc_html__('Unknown', 'event_espresso'); |
|
| 820 | - $datetime = $this->get_ticket_datetime(); |
|
| 821 | - if ($datetime) { |
|
| 822 | - $first_datetime_string = $datetime->start_date_and_time($date_format, $time_format); |
|
| 823 | - } |
|
| 824 | - return $first_datetime_string; |
|
| 825 | - } |
|
| 826 | - |
|
| 827 | - |
|
| 828 | - /** |
|
| 829 | - * Adds the line item as a child to this line item. If there is another child line |
|
| 830 | - * item with the same LIN_code, it is overwritten by this new one |
|
| 831 | - * |
|
| 832 | - * @param EEI_Line_Item $line_item |
|
| 833 | - * @param bool $set_order |
|
| 834 | - * @return bool success |
|
| 835 | - * @throws EE_Error |
|
| 836 | - * @throws InvalidArgumentException |
|
| 837 | - * @throws InvalidDataTypeException |
|
| 838 | - * @throws InvalidInterfaceException |
|
| 839 | - * @throws ReflectionException |
|
| 840 | - */ |
|
| 841 | - public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true) |
|
| 842 | - { |
|
| 843 | - // should we calculate the LIN_order for this line item ? |
|
| 844 | - if ($set_order || $line_item->order() === null) { |
|
| 845 | - $line_item->set_order(count($this->children())); |
|
| 846 | - } |
|
| 847 | - if ($this->ID()) { |
|
| 848 | - // check for any duplicate line items (with the same code), if so, this replaces it |
|
| 849 | - $line_item_with_same_code = $this->get_child_line_item($line_item->code()); |
|
| 850 | - if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) { |
|
| 851 | - $this->delete_child_line_item($line_item_with_same_code->code()); |
|
| 852 | - } |
|
| 853 | - $line_item->set_parent_ID($this->ID()); |
|
| 854 | - if ($this->TXN_ID()) { |
|
| 855 | - $line_item->set_TXN_ID($this->TXN_ID()); |
|
| 856 | - } |
|
| 857 | - return $line_item->save(); |
|
| 858 | - } |
|
| 859 | - $this->_children[ $line_item->code() ] = $line_item; |
|
| 860 | - if ($line_item->parent() !== $this) { |
|
| 861 | - $line_item->set_parent($this); |
|
| 862 | - } |
|
| 863 | - return true; |
|
| 864 | - } |
|
| 865 | - |
|
| 866 | - |
|
| 867 | - /** |
|
| 868 | - * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation. |
|
| 869 | - * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save() |
|
| 870 | - * However, if this line item is NOT saved to the DB, this just caches the parent on |
|
| 871 | - * the EE_Line_Item::_parent property. |
|
| 872 | - * |
|
| 873 | - * @param EE_Line_Item $line_item |
|
| 874 | - * @throws EE_Error |
|
| 875 | - * @throws InvalidArgumentException |
|
| 876 | - * @throws InvalidDataTypeException |
|
| 877 | - * @throws InvalidInterfaceException |
|
| 878 | - * @throws ReflectionException |
|
| 879 | - */ |
|
| 880 | - public function set_parent($line_item) |
|
| 881 | - { |
|
| 882 | - if ($this->ID()) { |
|
| 883 | - if (! $line_item->ID()) { |
|
| 884 | - $line_item->save(); |
|
| 885 | - } |
|
| 886 | - $this->set_parent_ID($line_item->ID()); |
|
| 887 | - $this->save(); |
|
| 888 | - } else { |
|
| 889 | - $this->_parent = $line_item; |
|
| 890 | - $this->set_parent_ID($line_item->ID()); |
|
| 891 | - } |
|
| 892 | - } |
|
| 893 | - |
|
| 894 | - |
|
| 895 | - /** |
|
| 896 | - * Gets the child line item as specified by its code. Because this returns an object (by reference) |
|
| 897 | - * you can modify this child line item and the parent (this object) can know about them |
|
| 898 | - * because it also has a reference to that line item |
|
| 899 | - * |
|
| 900 | - * @param string $code |
|
| 901 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 902 | - * @throws EE_Error |
|
| 903 | - * @throws InvalidArgumentException |
|
| 904 | - * @throws InvalidDataTypeException |
|
| 905 | - * @throws InvalidInterfaceException |
|
| 906 | - * @throws ReflectionException |
|
| 907 | - */ |
|
| 908 | - public function get_child_line_item($code) |
|
| 909 | - { |
|
| 910 | - if ($this->ID()) { |
|
| 911 | - return $this->get_model()->get_one( |
|
| 912 | - array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code)) |
|
| 913 | - ); |
|
| 914 | - } |
|
| 915 | - return isset($this->_children[ $code ]) |
|
| 916 | - ? $this->_children[ $code ] |
|
| 917 | - : null; |
|
| 918 | - } |
|
| 919 | - |
|
| 920 | - |
|
| 921 | - /** |
|
| 922 | - * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD |
|
| 923 | - * cached on it) |
|
| 924 | - * |
|
| 925 | - * @return int |
|
| 926 | - * @throws EE_Error |
|
| 927 | - * @throws InvalidArgumentException |
|
| 928 | - * @throws InvalidDataTypeException |
|
| 929 | - * @throws InvalidInterfaceException |
|
| 930 | - * @throws ReflectionException |
|
| 931 | - */ |
|
| 932 | - public function delete_children_line_items() |
|
| 933 | - { |
|
| 934 | - if ($this->ID()) { |
|
| 935 | - return $this->get_model()->delete(array(array('LIN_parent' => $this->ID()))); |
|
| 936 | - } |
|
| 937 | - $count = count($this->_children); |
|
| 938 | - $this->_children = array(); |
|
| 939 | - return $count; |
|
| 940 | - } |
|
| 941 | - |
|
| 942 | - |
|
| 943 | - /** |
|
| 944 | - * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line |
|
| 945 | - * HAS NOT been saved to the DB, removes the child line item with index $code. |
|
| 946 | - * Also searches through the child's children for a matching line item. However, once a line item has been found |
|
| 947 | - * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be |
|
| 948 | - * deleted) |
|
| 949 | - * |
|
| 950 | - * @param string $code |
|
| 951 | - * @param bool $stop_search_once_found |
|
| 952 | - * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to |
|
| 953 | - * the DB yet) |
|
| 954 | - * @throws EE_Error |
|
| 955 | - * @throws InvalidArgumentException |
|
| 956 | - * @throws InvalidDataTypeException |
|
| 957 | - * @throws InvalidInterfaceException |
|
| 958 | - * @throws ReflectionException |
|
| 959 | - */ |
|
| 960 | - public function delete_child_line_item($code, $stop_search_once_found = true) |
|
| 961 | - { |
|
| 962 | - if ($this->ID()) { |
|
| 963 | - $items_deleted = 0; |
|
| 964 | - if ($this->code() === $code) { |
|
| 965 | - $items_deleted += EEH_Line_Item::delete_all_child_items($this); |
|
| 966 | - $items_deleted += (int) $this->delete(); |
|
| 967 | - if ($stop_search_once_found) { |
|
| 968 | - return $items_deleted; |
|
| 969 | - } |
|
| 970 | - } |
|
| 971 | - foreach ($this->children() as $child_line_item) { |
|
| 972 | - $items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found); |
|
| 973 | - } |
|
| 974 | - return $items_deleted; |
|
| 975 | - } |
|
| 976 | - if (isset($this->_children[ $code ])) { |
|
| 977 | - unset($this->_children[ $code ]); |
|
| 978 | - return 1; |
|
| 979 | - } |
|
| 980 | - return 0; |
|
| 981 | - } |
|
| 982 | - |
|
| 983 | - |
|
| 984 | - /** |
|
| 985 | - * If this line item is in the database, is of the type subtotal, and |
|
| 986 | - * has no children, why do we have it? It should be deleted so this function |
|
| 987 | - * does that |
|
| 988 | - * |
|
| 989 | - * @return boolean |
|
| 990 | - * @throws EE_Error |
|
| 991 | - * @throws InvalidArgumentException |
|
| 992 | - * @throws InvalidDataTypeException |
|
| 993 | - * @throws InvalidInterfaceException |
|
| 994 | - * @throws ReflectionException |
|
| 995 | - */ |
|
| 996 | - public function delete_if_childless_subtotal() |
|
| 997 | - { |
|
| 998 | - if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) { |
|
| 999 | - return $this->delete(); |
|
| 1000 | - } |
|
| 1001 | - return false; |
|
| 1002 | - } |
|
| 1003 | - |
|
| 1004 | - |
|
| 1005 | - /** |
|
| 1006 | - * Creates a code and returns a string. doesn't assign the code to this model object |
|
| 1007 | - * |
|
| 1008 | - * @return string |
|
| 1009 | - * @throws EE_Error |
|
| 1010 | - * @throws InvalidArgumentException |
|
| 1011 | - * @throws InvalidDataTypeException |
|
| 1012 | - * @throws InvalidInterfaceException |
|
| 1013 | - * @throws ReflectionException |
|
| 1014 | - */ |
|
| 1015 | - public function generate_code() |
|
| 1016 | - { |
|
| 1017 | - // each line item in the cart requires a unique identifier |
|
| 1018 | - return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime()); |
|
| 1019 | - } |
|
| 1020 | - |
|
| 1021 | - |
|
| 1022 | - /** |
|
| 1023 | - * @return bool |
|
| 1024 | - * @throws EE_Error |
|
| 1025 | - * @throws InvalidArgumentException |
|
| 1026 | - * @throws InvalidDataTypeException |
|
| 1027 | - * @throws InvalidInterfaceException |
|
| 1028 | - * @throws ReflectionException |
|
| 1029 | - */ |
|
| 1030 | - public function is_tax() |
|
| 1031 | - { |
|
| 1032 | - return $this->type() === EEM_Line_Item::type_tax; |
|
| 1033 | - } |
|
| 1034 | - |
|
| 1035 | - |
|
| 1036 | - /** |
|
| 1037 | - * @return bool |
|
| 1038 | - * @throws EE_Error |
|
| 1039 | - * @throws InvalidArgumentException |
|
| 1040 | - * @throws InvalidDataTypeException |
|
| 1041 | - * @throws InvalidInterfaceException |
|
| 1042 | - * @throws ReflectionException |
|
| 1043 | - */ |
|
| 1044 | - public function is_tax_sub_total() |
|
| 1045 | - { |
|
| 1046 | - return $this->type() === EEM_Line_Item::type_tax_sub_total; |
|
| 1047 | - } |
|
| 1048 | - |
|
| 1049 | - |
|
| 1050 | - /** |
|
| 1051 | - * @return bool |
|
| 1052 | - * @throws EE_Error |
|
| 1053 | - * @throws InvalidArgumentException |
|
| 1054 | - * @throws InvalidDataTypeException |
|
| 1055 | - * @throws InvalidInterfaceException |
|
| 1056 | - * @throws ReflectionException |
|
| 1057 | - */ |
|
| 1058 | - public function is_line_item() |
|
| 1059 | - { |
|
| 1060 | - return $this->type() === EEM_Line_Item::type_line_item; |
|
| 1061 | - } |
|
| 1062 | - |
|
| 1063 | - |
|
| 1064 | - /** |
|
| 1065 | - * @return bool |
|
| 1066 | - * @throws EE_Error |
|
| 1067 | - * @throws InvalidArgumentException |
|
| 1068 | - * @throws InvalidDataTypeException |
|
| 1069 | - * @throws InvalidInterfaceException |
|
| 1070 | - * @throws ReflectionException |
|
| 1071 | - */ |
|
| 1072 | - public function is_sub_line_item() |
|
| 1073 | - { |
|
| 1074 | - return $this->type() === EEM_Line_Item::type_sub_line_item; |
|
| 1075 | - } |
|
| 1076 | - |
|
| 1077 | - |
|
| 1078 | - /** |
|
| 1079 | - * @return bool |
|
| 1080 | - * @throws EE_Error |
|
| 1081 | - * @throws InvalidArgumentException |
|
| 1082 | - * @throws InvalidDataTypeException |
|
| 1083 | - * @throws InvalidInterfaceException |
|
| 1084 | - * @throws ReflectionException |
|
| 1085 | - */ |
|
| 1086 | - public function is_sub_total() |
|
| 1087 | - { |
|
| 1088 | - return $this->type() === EEM_Line_Item::type_sub_total; |
|
| 1089 | - } |
|
| 1090 | - |
|
| 1091 | - |
|
| 1092 | - /** |
|
| 1093 | - * Whether or not this line item is a cancellation line item |
|
| 1094 | - * |
|
| 1095 | - * @return boolean |
|
| 1096 | - * @throws EE_Error |
|
| 1097 | - * @throws InvalidArgumentException |
|
| 1098 | - * @throws InvalidDataTypeException |
|
| 1099 | - * @throws InvalidInterfaceException |
|
| 1100 | - * @throws ReflectionException |
|
| 1101 | - */ |
|
| 1102 | - public function is_cancellation() |
|
| 1103 | - { |
|
| 1104 | - return EEM_Line_Item::type_cancellation === $this->type(); |
|
| 1105 | - } |
|
| 1106 | - |
|
| 1107 | - |
|
| 1108 | - /** |
|
| 1109 | - * @return bool |
|
| 1110 | - * @throws EE_Error |
|
| 1111 | - * @throws InvalidArgumentException |
|
| 1112 | - * @throws InvalidDataTypeException |
|
| 1113 | - * @throws InvalidInterfaceException |
|
| 1114 | - * @throws ReflectionException |
|
| 1115 | - */ |
|
| 1116 | - public function is_total() |
|
| 1117 | - { |
|
| 1118 | - return $this->type() === EEM_Line_Item::type_total; |
|
| 1119 | - } |
|
| 1120 | - |
|
| 1121 | - |
|
| 1122 | - /** |
|
| 1123 | - * @return bool |
|
| 1124 | - * @throws EE_Error |
|
| 1125 | - * @throws InvalidArgumentException |
|
| 1126 | - * @throws InvalidDataTypeException |
|
| 1127 | - * @throws InvalidInterfaceException |
|
| 1128 | - * @throws ReflectionException |
|
| 1129 | - */ |
|
| 1130 | - public function is_cancelled() |
|
| 1131 | - { |
|
| 1132 | - return $this->type() === EEM_Line_Item::type_cancellation; |
|
| 1133 | - } |
|
| 1134 | - |
|
| 1135 | - |
|
| 1136 | - /** |
|
| 1137 | - * @return string like '2, 004.00', formatted according to the localized currency |
|
| 1138 | - * @throws EE_Error |
|
| 1139 | - * @throws InvalidArgumentException |
|
| 1140 | - * @throws InvalidDataTypeException |
|
| 1141 | - * @throws InvalidInterfaceException |
|
| 1142 | - * @throws ReflectionException |
|
| 1143 | - */ |
|
| 1144 | - public function unit_price_no_code() |
|
| 1145 | - { |
|
| 1146 | - return $this->get_pretty('LIN_unit_price', 'no_currency_code'); |
|
| 1147 | - } |
|
| 1148 | - |
|
| 1149 | - |
|
| 1150 | - /** |
|
| 1151 | - * @return string like '2, 004.00', formatted according to the localized currency |
|
| 1152 | - * @throws EE_Error |
|
| 1153 | - * @throws InvalidArgumentException |
|
| 1154 | - * @throws InvalidDataTypeException |
|
| 1155 | - * @throws InvalidInterfaceException |
|
| 1156 | - * @throws ReflectionException |
|
| 1157 | - */ |
|
| 1158 | - public function total_no_code() |
|
| 1159 | - { |
|
| 1160 | - return $this->get_pretty('LIN_total', 'no_currency_code'); |
|
| 1161 | - } |
|
| 1162 | - |
|
| 1163 | - |
|
| 1164 | - /** |
|
| 1165 | - * Gets the final total on this item, taking taxes into account. |
|
| 1166 | - * Has the side-effect of setting the sub-total as it was just calculated. |
|
| 1167 | - * If this is used on a grand-total line item, also updates the transaction's |
|
| 1168 | - * TXN_total (provided this line item is allowed to persist, otherwise we don't |
|
| 1169 | - * want to change a persistable transaction with info from a non-persistent line item) |
|
| 1170 | - * |
|
| 1171 | - * @param bool $update_txn_status |
|
| 1172 | - * @return float |
|
| 1173 | - * @throws EE_Error |
|
| 1174 | - * @throws InvalidArgumentException |
|
| 1175 | - * @throws InvalidDataTypeException |
|
| 1176 | - * @throws InvalidInterfaceException |
|
| 1177 | - * @throws ReflectionException |
|
| 1178 | - * @throws RuntimeException |
|
| 1179 | - */ |
|
| 1180 | - public function recalculate_total_including_taxes($update_txn_status = false) |
|
| 1181 | - { |
|
| 1182 | - $pre_tax_total = $this->recalculate_pre_tax_total(); |
|
| 1183 | - $tax_total = $this->recalculate_taxes_and_tax_total(); |
|
| 1184 | - $total = $pre_tax_total + $tax_total; |
|
| 1185 | - // no negative totals plz |
|
| 1186 | - $total = max($total, 0); |
|
| 1187 | - $this->set_total($total); |
|
| 1188 | - // only update the related transaction's total |
|
| 1189 | - // if we intend to save this line item and its a grand total |
|
| 1190 | - if ( |
|
| 1191 | - $this->allow_persist() && $this->type() === EEM_Line_Item::type_total |
|
| 1192 | - && $this->transaction() |
|
| 1193 | - instanceof |
|
| 1194 | - EE_Transaction |
|
| 1195 | - ) { |
|
| 1196 | - $this->transaction()->set_total($total); |
|
| 1197 | - if ($update_txn_status) { |
|
| 1198 | - // don't save the TXN because that will be done below |
|
| 1199 | - // and the following method only saves if the status changes |
|
| 1200 | - $this->transaction()->update_status_based_on_total_paid(false); |
|
| 1201 | - } |
|
| 1202 | - if ($this->transaction()->ID()) { |
|
| 1203 | - $this->transaction()->save(); |
|
| 1204 | - } |
|
| 1205 | - } |
|
| 1206 | - $this->maybe_save(); |
|
| 1207 | - return $total; |
|
| 1208 | - } |
|
| 1209 | - |
|
| 1210 | - |
|
| 1211 | - /** |
|
| 1212 | - * Recursively goes through all the children and recalculates sub-totals EXCEPT for |
|
| 1213 | - * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its |
|
| 1214 | - * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and |
|
| 1215 | - * when this is called on the grand total |
|
| 1216 | - * |
|
| 1217 | - * @return float |
|
| 1218 | - * @throws EE_Error |
|
| 1219 | - * @throws InvalidArgumentException |
|
| 1220 | - * @throws InvalidDataTypeException |
|
| 1221 | - * @throws InvalidInterfaceException |
|
| 1222 | - * @throws ReflectionException |
|
| 1223 | - */ |
|
| 1224 | - public function recalculate_pre_tax_total() |
|
| 1225 | - { |
|
| 1226 | - $total = 0; |
|
| 1227 | - $my_children = $this->children(); |
|
| 1228 | - $has_children = ! empty($my_children); |
|
| 1229 | - if ($has_children && $this->is_line_item()) { |
|
| 1230 | - $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children); |
|
| 1231 | - } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
| 1232 | - $total = $this->unit_price() * $this->quantity(); |
|
| 1233 | - } elseif ($this->is_sub_total() || $this->is_total()) { |
|
| 1234 | - $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children); |
|
| 1235 | - } elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) { |
|
| 1236 | - // completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total |
|
| 1237 | - return 0; |
|
| 1238 | - } |
|
| 1239 | - // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events) |
|
| 1240 | - if (! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()) { |
|
| 1241 | - if ($this->OBJ_type() !== EEM_Line_Item::OBJ_TYPE_EVENT) { |
|
| 1242 | - $this->set_quantity(1); |
|
| 1243 | - } |
|
| 1244 | - if (! $this->is_percent()) { |
|
| 1245 | - $this->set_unit_price($total); |
|
| 1246 | - } |
|
| 1247 | - } |
|
| 1248 | - // we don't want to bother saving grand totals, because that needs to factor in taxes anyways |
|
| 1249 | - // so it ought to be |
|
| 1250 | - if (! $this->is_total()) { |
|
| 1251 | - $this->set_total($total); |
|
| 1252 | - // if not a percent line item, make sure we keep the unit price in sync |
|
| 1253 | - if ( |
|
| 1254 | - $has_children |
|
| 1255 | - && $this->is_line_item() |
|
| 1256 | - && ! $this->is_percent() |
|
| 1257 | - ) { |
|
| 1258 | - if ($this->quantity() === 0) { |
|
| 1259 | - $new_unit_price = 0; |
|
| 1260 | - } else { |
|
| 1261 | - $new_unit_price = $this->total() / $this->quantity(); |
|
| 1262 | - } |
|
| 1263 | - $this->set_unit_price($new_unit_price); |
|
| 1264 | - } |
|
| 1265 | - $this->maybe_save(); |
|
| 1266 | - } |
|
| 1267 | - return $total; |
|
| 1268 | - } |
|
| 1269 | - |
|
| 1270 | - |
|
| 1271 | - /** |
|
| 1272 | - * Calculates the pretax total when this line item is a subtotal or total line item. |
|
| 1273 | - * Basically does a sum-then-round approach (ie, any percent line item that are children |
|
| 1274 | - * will calculate their total based on the un-rounded total we're working with so far, and |
|
| 1275 | - * THEN round the result; instead of rounding as we go like with sub-line-items) |
|
| 1276 | - * |
|
| 1277 | - * @param float $calculated_total_so_far |
|
| 1278 | - * @param EE_Line_Item[] $my_children |
|
| 1279 | - * @return float |
|
| 1280 | - * @throws EE_Error |
|
| 1281 | - * @throws InvalidArgumentException |
|
| 1282 | - * @throws InvalidDataTypeException |
|
| 1283 | - * @throws InvalidInterfaceException |
|
| 1284 | - * @throws ReflectionException |
|
| 1285 | - */ |
|
| 1286 | - protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null) |
|
| 1287 | - { |
|
| 1288 | - if ($my_children === null) { |
|
| 1289 | - $my_children = $this->children(); |
|
| 1290 | - } |
|
| 1291 | - $subtotal_quantity = 0; |
|
| 1292 | - // get the total of all its children |
|
| 1293 | - foreach ($my_children as $child_line_item) { |
|
| 1294 | - if ($child_line_item instanceof EE_Line_Item) { |
|
| 1295 | - // skip line item if it is cancelled or is a tax |
|
| 1296 | - if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
| 1297 | - continue; |
|
| 1298 | - } |
|
| 1299 | - // percentage line items are based on total so far |
|
| 1300 | - if ($child_line_item->is_percent()) { |
|
| 1301 | - // round as we go so that the line items add up ok |
|
| 1302 | - $percent_total = round( |
|
| 1303 | - $calculated_total_so_far * $child_line_item->percent() / 100, |
|
| 1304 | - EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1305 | - ); |
|
| 1306 | - $child_line_item->set_total($percent_total); |
|
| 1307 | - // so far all percent line items should have a quantity of 1 |
|
| 1308 | - // (ie, no double percent discounts. Although that might be requested someday) |
|
| 1309 | - $child_line_item->set_quantity(1); |
|
| 1310 | - $child_line_item->maybe_save(); |
|
| 1311 | - $calculated_total_so_far += $percent_total; |
|
| 1312 | - } else { |
|
| 1313 | - // verify flat sub-line-item quantities match their parent |
|
| 1314 | - if ($child_line_item->is_sub_line_item()) { |
|
| 1315 | - $child_line_item->set_quantity($this->quantity()); |
|
| 1316 | - } |
|
| 1317 | - $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1318 | - $subtotal_quantity += $child_line_item->quantity(); |
|
| 1319 | - } |
|
| 1320 | - } |
|
| 1321 | - } |
|
| 1322 | - if ($this->is_sub_total()) { |
|
| 1323 | - // no negative totals plz |
|
| 1324 | - $calculated_total_so_far = max($calculated_total_so_far, 0); |
|
| 1325 | - $subtotal_quantity = $subtotal_quantity > 0 ? 1 : 0; |
|
| 1326 | - $this->set_quantity($subtotal_quantity); |
|
| 1327 | - $this->maybe_save(); |
|
| 1328 | - } |
|
| 1329 | - return $calculated_total_so_far; |
|
| 1330 | - } |
|
| 1331 | - |
|
| 1332 | - |
|
| 1333 | - /** |
|
| 1334 | - * Calculates the pretax total for a normal line item, in a round-then-sum approach |
|
| 1335 | - * (where each sub-line-item is applied to the base price for the line item |
|
| 1336 | - * and the result is immediately rounded, rather than summing all the sub-line-items |
|
| 1337 | - * then rounding, like we do when recalculating pretax totals on totals and subtotals). |
|
| 1338 | - * |
|
| 1339 | - * @param float $calculated_total_so_far |
|
| 1340 | - * @param EE_Line_Item[] $my_children |
|
| 1341 | - * @return float |
|
| 1342 | - * @throws EE_Error |
|
| 1343 | - * @throws InvalidArgumentException |
|
| 1344 | - * @throws InvalidDataTypeException |
|
| 1345 | - * @throws InvalidInterfaceException |
|
| 1346 | - * @throws ReflectionException |
|
| 1347 | - */ |
|
| 1348 | - protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null) |
|
| 1349 | - { |
|
| 1350 | - if ($my_children === null) { |
|
| 1351 | - $my_children = $this->children(); |
|
| 1352 | - } |
|
| 1353 | - // we need to keep track of the running total for a single item, |
|
| 1354 | - // because we need to round as we go |
|
| 1355 | - $unit_price_for_total = 0; |
|
| 1356 | - $quantity_for_total = 1; |
|
| 1357 | - // get the total of all its children |
|
| 1358 | - foreach ($my_children as $child_line_item) { |
|
| 1359 | - if ($child_line_item instanceof EE_Line_Item) { |
|
| 1360 | - // skip line item if it is cancelled or is a tax |
|
| 1361 | - if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
| 1362 | - continue; |
|
| 1363 | - } |
|
| 1364 | - if ($child_line_item->is_percent()) { |
|
| 1365 | - // it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity |
|
| 1366 | - // not total multiplied by percent, because that ignores rounding along-the-way |
|
| 1367 | - $percent_unit_price = round( |
|
| 1368 | - $unit_price_for_total * $child_line_item->percent() / 100, |
|
| 1369 | - EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1370 | - ); |
|
| 1371 | - $percent_total = $percent_unit_price * $quantity_for_total; |
|
| 1372 | - $child_line_item->set_total($percent_total); |
|
| 1373 | - // so far all percent line items should have a quantity of 1 |
|
| 1374 | - // (ie, no double percent discounts. Although that might be requested someday) |
|
| 1375 | - $child_line_item->set_quantity(1); |
|
| 1376 | - $child_line_item->maybe_save(); |
|
| 1377 | - $calculated_total_so_far += $percent_total; |
|
| 1378 | - $unit_price_for_total += $percent_unit_price; |
|
| 1379 | - } else { |
|
| 1380 | - // verify flat sub-line-item quantities match their parent |
|
| 1381 | - if ($child_line_item->is_sub_line_item()) { |
|
| 1382 | - $child_line_item->set_quantity($this->quantity()); |
|
| 1383 | - } |
|
| 1384 | - $quantity_for_total = $child_line_item->quantity(); |
|
| 1385 | - $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1386 | - $unit_price_for_total += $child_line_item->unit_price(); |
|
| 1387 | - } |
|
| 1388 | - } |
|
| 1389 | - } |
|
| 1390 | - return $calculated_total_so_far; |
|
| 1391 | - } |
|
| 1392 | - |
|
| 1393 | - |
|
| 1394 | - /** |
|
| 1395 | - * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets |
|
| 1396 | - * the totals on each tax calculated, and returns the final tax total. Re-saves tax line items |
|
| 1397 | - * and tax sub-total if already in the DB |
|
| 1398 | - * |
|
| 1399 | - * @return float |
|
| 1400 | - * @throws EE_Error |
|
| 1401 | - * @throws InvalidArgumentException |
|
| 1402 | - * @throws InvalidDataTypeException |
|
| 1403 | - * @throws InvalidInterfaceException |
|
| 1404 | - * @throws ReflectionException |
|
| 1405 | - */ |
|
| 1406 | - public function recalculate_taxes_and_tax_total() |
|
| 1407 | - { |
|
| 1408 | - // get all taxes |
|
| 1409 | - $taxes = $this->tax_descendants(); |
|
| 1410 | - // calculate the pretax total |
|
| 1411 | - $taxable_total = $this->taxable_total(); |
|
| 1412 | - $tax_total = 0; |
|
| 1413 | - foreach ($taxes as $tax) { |
|
| 1414 | - $total_on_this_tax = $taxable_total * $tax->percent() / 100; |
|
| 1415 | - // remember the total on this line item |
|
| 1416 | - $tax->set_total($total_on_this_tax); |
|
| 1417 | - $tax->maybe_save(); |
|
| 1418 | - $tax_total += $tax->total(); |
|
| 1419 | - } |
|
| 1420 | - $this->_recalculate_tax_sub_total(); |
|
| 1421 | - return $tax_total; |
|
| 1422 | - } |
|
| 1423 | - |
|
| 1424 | - |
|
| 1425 | - /** |
|
| 1426 | - * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated |
|
| 1427 | - * |
|
| 1428 | - * @return void |
|
| 1429 | - * @throws EE_Error |
|
| 1430 | - * @throws InvalidArgumentException |
|
| 1431 | - * @throws InvalidDataTypeException |
|
| 1432 | - * @throws InvalidInterfaceException |
|
| 1433 | - * @throws ReflectionException |
|
| 1434 | - */ |
|
| 1435 | - private function _recalculate_tax_sub_total() |
|
| 1436 | - { |
|
| 1437 | - if ($this->is_tax_sub_total()) { |
|
| 1438 | - $total = 0; |
|
| 1439 | - $total_percent = 0; |
|
| 1440 | - // simply loop through all its children (which should be taxes) and sum their total |
|
| 1441 | - foreach ($this->children() as $child_tax) { |
|
| 1442 | - if ($child_tax instanceof EE_Line_Item) { |
|
| 1443 | - $total += $child_tax->total(); |
|
| 1444 | - $total_percent += $child_tax->percent(); |
|
| 1445 | - } |
|
| 1446 | - } |
|
| 1447 | - $this->set_total($total); |
|
| 1448 | - $this->set_percent($total_percent); |
|
| 1449 | - $this->maybe_save(); |
|
| 1450 | - } elseif ($this->is_total()) { |
|
| 1451 | - foreach ($this->children() as $maybe_tax_subtotal) { |
|
| 1452 | - if ($maybe_tax_subtotal instanceof EE_Line_Item) { |
|
| 1453 | - $maybe_tax_subtotal->_recalculate_tax_sub_total(); |
|
| 1454 | - } |
|
| 1455 | - } |
|
| 1456 | - } |
|
| 1457 | - } |
|
| 1458 | - |
|
| 1459 | - |
|
| 1460 | - /** |
|
| 1461 | - * Gets the total tax on this line item. Assumes taxes have already been calculated using |
|
| 1462 | - * recalculate_taxes_and_total |
|
| 1463 | - * |
|
| 1464 | - * @return float |
|
| 1465 | - * @throws EE_Error |
|
| 1466 | - * @throws InvalidArgumentException |
|
| 1467 | - * @throws InvalidDataTypeException |
|
| 1468 | - * @throws InvalidInterfaceException |
|
| 1469 | - * @throws ReflectionException |
|
| 1470 | - */ |
|
| 1471 | - public function get_total_tax() |
|
| 1472 | - { |
|
| 1473 | - $this->_recalculate_tax_sub_total(); |
|
| 1474 | - $total = 0; |
|
| 1475 | - foreach ($this->tax_descendants() as $tax_line_item) { |
|
| 1476 | - if ($tax_line_item instanceof EE_Line_Item) { |
|
| 1477 | - $total += $tax_line_item->total(); |
|
| 1478 | - } |
|
| 1479 | - } |
|
| 1480 | - return $total; |
|
| 1481 | - } |
|
| 1482 | - |
|
| 1483 | - |
|
| 1484 | - /** |
|
| 1485 | - * Gets the total for all the items purchased only |
|
| 1486 | - * |
|
| 1487 | - * @return float |
|
| 1488 | - * @throws EE_Error |
|
| 1489 | - * @throws InvalidArgumentException |
|
| 1490 | - * @throws InvalidDataTypeException |
|
| 1491 | - * @throws InvalidInterfaceException |
|
| 1492 | - * @throws ReflectionException |
|
| 1493 | - */ |
|
| 1494 | - public function get_items_total() |
|
| 1495 | - { |
|
| 1496 | - // by default, let's make sure we're consistent with the existing line item |
|
| 1497 | - if ($this->is_total()) { |
|
| 1498 | - $pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this); |
|
| 1499 | - if ($pretax_subtotal_li instanceof EE_Line_Item) { |
|
| 1500 | - return $pretax_subtotal_li->total(); |
|
| 1501 | - } |
|
| 1502 | - } |
|
| 1503 | - $total = 0; |
|
| 1504 | - foreach ($this->get_items() as $item) { |
|
| 1505 | - if ($item instanceof EE_Line_Item) { |
|
| 1506 | - $total += $item->total(); |
|
| 1507 | - } |
|
| 1508 | - } |
|
| 1509 | - return $total; |
|
| 1510 | - } |
|
| 1511 | - |
|
| 1512 | - |
|
| 1513 | - /** |
|
| 1514 | - * Gets all the descendants (ie, children or children of children etc) that |
|
| 1515 | - * are of the type 'tax' |
|
| 1516 | - * |
|
| 1517 | - * @return EE_Line_Item[] |
|
| 1518 | - * @throws EE_Error |
|
| 1519 | - */ |
|
| 1520 | - public function tax_descendants() |
|
| 1521 | - { |
|
| 1522 | - return EEH_Line_Item::get_tax_descendants($this); |
|
| 1523 | - } |
|
| 1524 | - |
|
| 1525 | - |
|
| 1526 | - /** |
|
| 1527 | - * Gets all the real items purchased which are children of this item |
|
| 1528 | - * |
|
| 1529 | - * @return EE_Line_Item[] |
|
| 1530 | - * @throws EE_Error |
|
| 1531 | - */ |
|
| 1532 | - public function get_items() |
|
| 1533 | - { |
|
| 1534 | - return EEH_Line_Item::get_line_item_descendants($this); |
|
| 1535 | - } |
|
| 1536 | - |
|
| 1537 | - |
|
| 1538 | - /** |
|
| 1539 | - * Returns the amount taxable among this line item's children (or if it has no children, |
|
| 1540 | - * how much of it is taxable). Does not recalculate totals or subtotals. |
|
| 1541 | - * If the taxable total is negative, (eg, if none of the tickets were taxable, |
|
| 1542 | - * but there is a "Taxable" discount), returns 0. |
|
| 1543 | - * |
|
| 1544 | - * @return float |
|
| 1545 | - * @throws EE_Error |
|
| 1546 | - * @throws InvalidArgumentException |
|
| 1547 | - * @throws InvalidDataTypeException |
|
| 1548 | - * @throws InvalidInterfaceException |
|
| 1549 | - * @throws ReflectionException |
|
| 1550 | - */ |
|
| 1551 | - public function taxable_total() |
|
| 1552 | - { |
|
| 1553 | - $total = 0; |
|
| 1554 | - if ($this->children()) { |
|
| 1555 | - foreach ($this->children() as $child_line_item) { |
|
| 1556 | - if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) { |
|
| 1557 | - // if it's a percent item, only take into account the percent |
|
| 1558 | - // that's taxable too (the taxable total so far) |
|
| 1559 | - if ($child_line_item->is_percent()) { |
|
| 1560 | - $total += ($total * $child_line_item->percent() / 100); |
|
| 1561 | - } else { |
|
| 1562 | - $total += $child_line_item->total(); |
|
| 1563 | - } |
|
| 1564 | - } elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) { |
|
| 1565 | - $total += $child_line_item->taxable_total(); |
|
| 1566 | - } |
|
| 1567 | - } |
|
| 1568 | - } |
|
| 1569 | - return max($total, 0); |
|
| 1570 | - } |
|
| 1571 | - |
|
| 1572 | - |
|
| 1573 | - /** |
|
| 1574 | - * Gets the transaction for this line item |
|
| 1575 | - * |
|
| 1576 | - * @return EE_Base_Class|EE_Transaction |
|
| 1577 | - * @throws EE_Error |
|
| 1578 | - * @throws InvalidArgumentException |
|
| 1579 | - * @throws InvalidDataTypeException |
|
| 1580 | - * @throws InvalidInterfaceException |
|
| 1581 | - * @throws ReflectionException |
|
| 1582 | - */ |
|
| 1583 | - public function transaction() |
|
| 1584 | - { |
|
| 1585 | - return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TRANSACTION); |
|
| 1586 | - } |
|
| 1587 | - |
|
| 1588 | - |
|
| 1589 | - /** |
|
| 1590 | - * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1591 | - * Because there currently is no proper parent-child relation on the model, |
|
| 1592 | - * save_this_and_cached() will NOT save the descendants. |
|
| 1593 | - * Also sets the transaction on this line item and all its descendants before saving |
|
| 1594 | - * |
|
| 1595 | - * @param int $txn_id if none is provided, assumes $this->TXN_ID() |
|
| 1596 | - * @return int count of items saved |
|
| 1597 | - * @throws EE_Error |
|
| 1598 | - * @throws InvalidArgumentException |
|
| 1599 | - * @throws InvalidDataTypeException |
|
| 1600 | - * @throws InvalidInterfaceException |
|
| 1601 | - * @throws ReflectionException |
|
| 1602 | - */ |
|
| 1603 | - public function save_this_and_descendants_to_txn($txn_id = null) |
|
| 1604 | - { |
|
| 1605 | - $count = 0; |
|
| 1606 | - if (! $txn_id) { |
|
| 1607 | - $txn_id = $this->TXN_ID(); |
|
| 1608 | - } |
|
| 1609 | - $this->set_TXN_ID($txn_id); |
|
| 1610 | - $children = $this->children(); |
|
| 1611 | - $count += $this->save() |
|
| 1612 | - ? 1 |
|
| 1613 | - : 0; |
|
| 1614 | - foreach ($children as $child_line_item) { |
|
| 1615 | - if ($child_line_item instanceof EE_Line_Item) { |
|
| 1616 | - $child_line_item->set_parent_ID($this->ID()); |
|
| 1617 | - $count += $child_line_item->save_this_and_descendants_to_txn($txn_id); |
|
| 1618 | - } |
|
| 1619 | - } |
|
| 1620 | - return $count; |
|
| 1621 | - } |
|
| 1622 | - |
|
| 1623 | - |
|
| 1624 | - /** |
|
| 1625 | - * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1626 | - * |
|
| 1627 | - * @return int count of items saved |
|
| 1628 | - * @throws EE_Error |
|
| 1629 | - * @throws InvalidArgumentException |
|
| 1630 | - * @throws InvalidDataTypeException |
|
| 1631 | - * @throws InvalidInterfaceException |
|
| 1632 | - * @throws ReflectionException |
|
| 1633 | - */ |
|
| 1634 | - public function save_this_and_descendants() |
|
| 1635 | - { |
|
| 1636 | - $count = 0; |
|
| 1637 | - $children = $this->children(); |
|
| 1638 | - $count += $this->save() |
|
| 1639 | - ? 1 |
|
| 1640 | - : 0; |
|
| 1641 | - foreach ($children as $child_line_item) { |
|
| 1642 | - if ($child_line_item instanceof EE_Line_Item) { |
|
| 1643 | - $child_line_item->set_parent_ID($this->ID()); |
|
| 1644 | - $count += $child_line_item->save_this_and_descendants(); |
|
| 1645 | - } |
|
| 1646 | - } |
|
| 1647 | - return $count; |
|
| 1648 | - } |
|
| 1649 | - |
|
| 1650 | - |
|
| 1651 | - /** |
|
| 1652 | - * returns the cancellation line item if this item was cancelled |
|
| 1653 | - * |
|
| 1654 | - * @return EE_Line_Item[] |
|
| 1655 | - * @throws InvalidArgumentException |
|
| 1656 | - * @throws InvalidInterfaceException |
|
| 1657 | - * @throws InvalidDataTypeException |
|
| 1658 | - * @throws ReflectionException |
|
| 1659 | - * @throws EE_Error |
|
| 1660 | - */ |
|
| 1661 | - public function get_cancellations() |
|
| 1662 | - { |
|
| 1663 | - EE_Registry::instance()->load_helper('Line_Item'); |
|
| 1664 | - return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation); |
|
| 1665 | - } |
|
| 1666 | - |
|
| 1667 | - |
|
| 1668 | - /** |
|
| 1669 | - * If this item has an ID, then this saves it again to update the db |
|
| 1670 | - * |
|
| 1671 | - * @return int count of items saved |
|
| 1672 | - * @throws EE_Error |
|
| 1673 | - * @throws InvalidArgumentException |
|
| 1674 | - * @throws InvalidDataTypeException |
|
| 1675 | - * @throws InvalidInterfaceException |
|
| 1676 | - * @throws ReflectionException |
|
| 1677 | - */ |
|
| 1678 | - public function maybe_save() |
|
| 1679 | - { |
|
| 1680 | - if ($this->ID()) { |
|
| 1681 | - return $this->save(); |
|
| 1682 | - } |
|
| 1683 | - return false; |
|
| 1684 | - } |
|
| 1685 | - |
|
| 1686 | - |
|
| 1687 | - /** |
|
| 1688 | - * clears the cached children and parent from the line item |
|
| 1689 | - * |
|
| 1690 | - * @return void |
|
| 1691 | - */ |
|
| 1692 | - public function clear_related_line_item_cache() |
|
| 1693 | - { |
|
| 1694 | - $this->_children = array(); |
|
| 1695 | - $this->_parent = null; |
|
| 1696 | - } |
|
| 1697 | - |
|
| 1698 | - |
|
| 1699 | - /** |
|
| 1700 | - * @param bool $raw |
|
| 1701 | - * @return int |
|
| 1702 | - * @throws EE_Error |
|
| 1703 | - * @throws InvalidArgumentException |
|
| 1704 | - * @throws InvalidDataTypeException |
|
| 1705 | - * @throws InvalidInterfaceException |
|
| 1706 | - * @throws ReflectionException |
|
| 1707 | - */ |
|
| 1708 | - public function timestamp($raw = false) |
|
| 1709 | - { |
|
| 1710 | - return $raw |
|
| 1711 | - ? $this->get_raw('LIN_timestamp') |
|
| 1712 | - : $this->get('LIN_timestamp'); |
|
| 1713 | - } |
|
| 1714 | - |
|
| 1715 | - |
|
| 1716 | - |
|
| 1717 | - |
|
| 1718 | - /************************* DEPRECATED *************************/ |
|
| 1719 | - /** |
|
| 1720 | - * @deprecated 4.6.0 |
|
| 1721 | - * @param string $type one of the constants on EEM_Line_Item |
|
| 1722 | - * @return EE_Line_Item[] |
|
| 1723 | - * @throws EE_Error |
|
| 1724 | - */ |
|
| 1725 | - protected function _get_descendants_of_type($type) |
|
| 1726 | - { |
|
| 1727 | - EE_Error::doing_it_wrong( |
|
| 1728 | - 'EE_Line_Item::_get_descendants_of_type()', |
|
| 1729 | - sprintf( |
|
| 1730 | - esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
| 1731 | - 'EEH_Line_Item::get_descendants_of_type()' |
|
| 1732 | - ), |
|
| 1733 | - '4.6.0' |
|
| 1734 | - ); |
|
| 1735 | - return EEH_Line_Item::get_descendants_of_type($this, $type); |
|
| 1736 | - } |
|
| 1737 | - |
|
| 1738 | - |
|
| 1739 | - /** |
|
| 1740 | - * @deprecated 4.6.0 |
|
| 1741 | - * @param string $type like one of the EEM_Line_Item::type_* |
|
| 1742 | - * @return EE_Line_Item |
|
| 1743 | - * @throws EE_Error |
|
| 1744 | - * @throws InvalidArgumentException |
|
| 1745 | - * @throws InvalidDataTypeException |
|
| 1746 | - * @throws InvalidInterfaceException |
|
| 1747 | - * @throws ReflectionException |
|
| 1748 | - */ |
|
| 1749 | - public function get_nearest_descendant_of_type($type) |
|
| 1750 | - { |
|
| 1751 | - EE_Error::doing_it_wrong( |
|
| 1752 | - 'EE_Line_Item::get_nearest_descendant_of_type()', |
|
| 1753 | - sprintf( |
|
| 1754 | - esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
| 1755 | - 'EEH_Line_Item::get_nearest_descendant_of_type()' |
|
| 1756 | - ), |
|
| 1757 | - '4.6.0' |
|
| 1758 | - ); |
|
| 1759 | - return EEH_Line_Item::get_nearest_descendant_of_type($this, $type); |
|
| 1760 | - } |
|
| 17 | + /** |
|
| 18 | + * for children line items (currently not a normal relation) |
|
| 19 | + * |
|
| 20 | + * @type EE_Line_Item[] |
|
| 21 | + */ |
|
| 22 | + protected $_children = array(); |
|
| 23 | + |
|
| 24 | + /** |
|
| 25 | + * for the parent line item |
|
| 26 | + * |
|
| 27 | + * @var EE_Line_Item |
|
| 28 | + */ |
|
| 29 | + protected $_parent; |
|
| 30 | + |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * @param array $props_n_values incoming values |
|
| 34 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 35 | + * used.) |
|
| 36 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 37 | + * date_format and the second value is the time format |
|
| 38 | + * @return EE_Line_Item |
|
| 39 | + * @throws EE_Error |
|
| 40 | + * @throws InvalidArgumentException |
|
| 41 | + * @throws InvalidDataTypeException |
|
| 42 | + * @throws InvalidInterfaceException |
|
| 43 | + * @throws ReflectionException |
|
| 44 | + */ |
|
| 45 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 46 | + { |
|
| 47 | + $has_object = parent::_check_for_object( |
|
| 48 | + $props_n_values, |
|
| 49 | + __CLASS__, |
|
| 50 | + $timezone, |
|
| 51 | + $date_formats |
|
| 52 | + ); |
|
| 53 | + return $has_object |
|
| 54 | + ? $has_object |
|
| 55 | + : new self($props_n_values, false, $timezone); |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + |
|
| 59 | + /** |
|
| 60 | + * @param array $props_n_values incoming values from the database |
|
| 61 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 62 | + * the website will be used. |
|
| 63 | + * @return EE_Line_Item |
|
| 64 | + * @throws EE_Error |
|
| 65 | + * @throws InvalidArgumentException |
|
| 66 | + * @throws InvalidDataTypeException |
|
| 67 | + * @throws InvalidInterfaceException |
|
| 68 | + * @throws ReflectionException |
|
| 69 | + */ |
|
| 70 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 71 | + { |
|
| 72 | + return new self($props_n_values, true, $timezone); |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + |
|
| 76 | + /** |
|
| 77 | + * Adds some defaults if they're not specified |
|
| 78 | + * |
|
| 79 | + * @param array $fieldValues |
|
| 80 | + * @param bool $bydb |
|
| 81 | + * @param string $timezone |
|
| 82 | + * @throws EE_Error |
|
| 83 | + * @throws InvalidArgumentException |
|
| 84 | + * @throws InvalidDataTypeException |
|
| 85 | + * @throws InvalidInterfaceException |
|
| 86 | + * @throws ReflectionException |
|
| 87 | + */ |
|
| 88 | + protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') |
|
| 89 | + { |
|
| 90 | + parent::__construct($fieldValues, $bydb, $timezone); |
|
| 91 | + if (! $this->get('LIN_code')) { |
|
| 92 | + $this->set_code($this->generate_code()); |
|
| 93 | + } |
|
| 94 | + } |
|
| 95 | + |
|
| 96 | + |
|
| 97 | + /** |
|
| 98 | + * Gets ID |
|
| 99 | + * |
|
| 100 | + * @return int |
|
| 101 | + * @throws EE_Error |
|
| 102 | + * @throws InvalidArgumentException |
|
| 103 | + * @throws InvalidDataTypeException |
|
| 104 | + * @throws InvalidInterfaceException |
|
| 105 | + * @throws ReflectionException |
|
| 106 | + */ |
|
| 107 | + public function ID() |
|
| 108 | + { |
|
| 109 | + return $this->get('LIN_ID'); |
|
| 110 | + } |
|
| 111 | + |
|
| 112 | + |
|
| 113 | + /** |
|
| 114 | + * Gets TXN_ID |
|
| 115 | + * |
|
| 116 | + * @return int |
|
| 117 | + * @throws EE_Error |
|
| 118 | + * @throws InvalidArgumentException |
|
| 119 | + * @throws InvalidDataTypeException |
|
| 120 | + * @throws InvalidInterfaceException |
|
| 121 | + * @throws ReflectionException |
|
| 122 | + */ |
|
| 123 | + public function TXN_ID() |
|
| 124 | + { |
|
| 125 | + return $this->get('TXN_ID'); |
|
| 126 | + } |
|
| 127 | + |
|
| 128 | + |
|
| 129 | + /** |
|
| 130 | + * Sets TXN_ID |
|
| 131 | + * |
|
| 132 | + * @param int $TXN_ID |
|
| 133 | + * @throws EE_Error |
|
| 134 | + * @throws InvalidArgumentException |
|
| 135 | + * @throws InvalidDataTypeException |
|
| 136 | + * @throws InvalidInterfaceException |
|
| 137 | + * @throws ReflectionException |
|
| 138 | + */ |
|
| 139 | + public function set_TXN_ID($TXN_ID) |
|
| 140 | + { |
|
| 141 | + $this->set('TXN_ID', $TXN_ID); |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + |
|
| 145 | + /** |
|
| 146 | + * Gets name |
|
| 147 | + * |
|
| 148 | + * @return string |
|
| 149 | + * @throws EE_Error |
|
| 150 | + * @throws InvalidArgumentException |
|
| 151 | + * @throws InvalidDataTypeException |
|
| 152 | + * @throws InvalidInterfaceException |
|
| 153 | + * @throws ReflectionException |
|
| 154 | + */ |
|
| 155 | + public function name() |
|
| 156 | + { |
|
| 157 | + $name = $this->get('LIN_name'); |
|
| 158 | + if (! $name) { |
|
| 159 | + $name = ucwords(str_replace('-', ' ', $this->type())); |
|
| 160 | + } |
|
| 161 | + return $name; |
|
| 162 | + } |
|
| 163 | + |
|
| 164 | + |
|
| 165 | + /** |
|
| 166 | + * Sets name |
|
| 167 | + * |
|
| 168 | + * @param string $name |
|
| 169 | + * @throws EE_Error |
|
| 170 | + * @throws InvalidArgumentException |
|
| 171 | + * @throws InvalidDataTypeException |
|
| 172 | + * @throws InvalidInterfaceException |
|
| 173 | + * @throws ReflectionException |
|
| 174 | + */ |
|
| 175 | + public function set_name($name) |
|
| 176 | + { |
|
| 177 | + $this->set('LIN_name', $name); |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + |
|
| 181 | + /** |
|
| 182 | + * Gets desc |
|
| 183 | + * |
|
| 184 | + * @return string |
|
| 185 | + * @throws EE_Error |
|
| 186 | + * @throws InvalidArgumentException |
|
| 187 | + * @throws InvalidDataTypeException |
|
| 188 | + * @throws InvalidInterfaceException |
|
| 189 | + * @throws ReflectionException |
|
| 190 | + */ |
|
| 191 | + public function desc() |
|
| 192 | + { |
|
| 193 | + return $this->get('LIN_desc'); |
|
| 194 | + } |
|
| 195 | + |
|
| 196 | + |
|
| 197 | + /** |
|
| 198 | + * Sets desc |
|
| 199 | + * |
|
| 200 | + * @param string $desc |
|
| 201 | + * @throws EE_Error |
|
| 202 | + * @throws InvalidArgumentException |
|
| 203 | + * @throws InvalidDataTypeException |
|
| 204 | + * @throws InvalidInterfaceException |
|
| 205 | + * @throws ReflectionException |
|
| 206 | + */ |
|
| 207 | + public function set_desc($desc) |
|
| 208 | + { |
|
| 209 | + $this->set('LIN_desc', $desc); |
|
| 210 | + } |
|
| 211 | + |
|
| 212 | + |
|
| 213 | + /** |
|
| 214 | + * Gets quantity |
|
| 215 | + * |
|
| 216 | + * @return int |
|
| 217 | + * @throws EE_Error |
|
| 218 | + * @throws InvalidArgumentException |
|
| 219 | + * @throws InvalidDataTypeException |
|
| 220 | + * @throws InvalidInterfaceException |
|
| 221 | + * @throws ReflectionException |
|
| 222 | + */ |
|
| 223 | + public function quantity() |
|
| 224 | + { |
|
| 225 | + return $this->get('LIN_quantity'); |
|
| 226 | + } |
|
| 227 | + |
|
| 228 | + |
|
| 229 | + /** |
|
| 230 | + * Sets quantity |
|
| 231 | + * |
|
| 232 | + * @param int $quantity |
|
| 233 | + * @throws EE_Error |
|
| 234 | + * @throws InvalidArgumentException |
|
| 235 | + * @throws InvalidDataTypeException |
|
| 236 | + * @throws InvalidInterfaceException |
|
| 237 | + * @throws ReflectionException |
|
| 238 | + */ |
|
| 239 | + public function set_quantity($quantity) |
|
| 240 | + { |
|
| 241 | + $this->set('LIN_quantity', max($quantity, 0)); |
|
| 242 | + } |
|
| 243 | + |
|
| 244 | + |
|
| 245 | + /** |
|
| 246 | + * Gets item_id |
|
| 247 | + * |
|
| 248 | + * @return string |
|
| 249 | + * @throws EE_Error |
|
| 250 | + * @throws InvalidArgumentException |
|
| 251 | + * @throws InvalidDataTypeException |
|
| 252 | + * @throws InvalidInterfaceException |
|
| 253 | + * @throws ReflectionException |
|
| 254 | + */ |
|
| 255 | + public function OBJ_ID() |
|
| 256 | + { |
|
| 257 | + return $this->get('OBJ_ID'); |
|
| 258 | + } |
|
| 259 | + |
|
| 260 | + |
|
| 261 | + /** |
|
| 262 | + * Sets item_id |
|
| 263 | + * |
|
| 264 | + * @param string $item_id |
|
| 265 | + * @throws EE_Error |
|
| 266 | + * @throws InvalidArgumentException |
|
| 267 | + * @throws InvalidDataTypeException |
|
| 268 | + * @throws InvalidInterfaceException |
|
| 269 | + * @throws ReflectionException |
|
| 270 | + */ |
|
| 271 | + public function set_OBJ_ID($item_id) |
|
| 272 | + { |
|
| 273 | + $this->set('OBJ_ID', $item_id); |
|
| 274 | + } |
|
| 275 | + |
|
| 276 | + |
|
| 277 | + /** |
|
| 278 | + * Gets item_type |
|
| 279 | + * |
|
| 280 | + * @return string |
|
| 281 | + * @throws EE_Error |
|
| 282 | + * @throws InvalidArgumentException |
|
| 283 | + * @throws InvalidDataTypeException |
|
| 284 | + * @throws InvalidInterfaceException |
|
| 285 | + * @throws ReflectionException |
|
| 286 | + */ |
|
| 287 | + public function OBJ_type() |
|
| 288 | + { |
|
| 289 | + return $this->get('OBJ_type'); |
|
| 290 | + } |
|
| 291 | + |
|
| 292 | + |
|
| 293 | + /** |
|
| 294 | + * Gets item_type |
|
| 295 | + * |
|
| 296 | + * @return string |
|
| 297 | + * @throws EE_Error |
|
| 298 | + * @throws InvalidArgumentException |
|
| 299 | + * @throws InvalidDataTypeException |
|
| 300 | + * @throws InvalidInterfaceException |
|
| 301 | + * @throws ReflectionException |
|
| 302 | + */ |
|
| 303 | + public function OBJ_type_i18n() |
|
| 304 | + { |
|
| 305 | + $obj_type = $this->OBJ_type(); |
|
| 306 | + switch ($obj_type) { |
|
| 307 | + case EEM_Line_Item::OBJ_TYPE_EVENT: |
|
| 308 | + $obj_type = esc_html__('Event', 'event_espresso'); |
|
| 309 | + break; |
|
| 310 | + case EEM_Line_Item::OBJ_TYPE_PRICE: |
|
| 311 | + $obj_type = esc_html__('Price', 'event_espresso'); |
|
| 312 | + break; |
|
| 313 | + case EEM_Line_Item::OBJ_TYPE_PROMOTION: |
|
| 314 | + $obj_type = esc_html__('Promotion', 'event_espresso'); |
|
| 315 | + break; |
|
| 316 | + case EEM_Line_Item::OBJ_TYPE_TICKET: |
|
| 317 | + $obj_type = esc_html__('Ticket', 'event_espresso'); |
|
| 318 | + break; |
|
| 319 | + case EEM_Line_Item::OBJ_TYPE_TRANSACTION: |
|
| 320 | + $obj_type = esc_html__('Transaction', 'event_espresso'); |
|
| 321 | + break; |
|
| 322 | + } |
|
| 323 | + return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this); |
|
| 324 | + } |
|
| 325 | + |
|
| 326 | + |
|
| 327 | + /** |
|
| 328 | + * Sets item_type |
|
| 329 | + * |
|
| 330 | + * @param string $OBJ_type |
|
| 331 | + * @throws EE_Error |
|
| 332 | + * @throws InvalidArgumentException |
|
| 333 | + * @throws InvalidDataTypeException |
|
| 334 | + * @throws InvalidInterfaceException |
|
| 335 | + * @throws ReflectionException |
|
| 336 | + */ |
|
| 337 | + public function set_OBJ_type($OBJ_type) |
|
| 338 | + { |
|
| 339 | + $this->set('OBJ_type', $OBJ_type); |
|
| 340 | + } |
|
| 341 | + |
|
| 342 | + |
|
| 343 | + /** |
|
| 344 | + * Gets unit_price |
|
| 345 | + * |
|
| 346 | + * @return float |
|
| 347 | + * @throws EE_Error |
|
| 348 | + * @throws InvalidArgumentException |
|
| 349 | + * @throws InvalidDataTypeException |
|
| 350 | + * @throws InvalidInterfaceException |
|
| 351 | + * @throws ReflectionException |
|
| 352 | + */ |
|
| 353 | + public function unit_price() |
|
| 354 | + { |
|
| 355 | + return $this->get('LIN_unit_price'); |
|
| 356 | + } |
|
| 357 | + |
|
| 358 | + |
|
| 359 | + /** |
|
| 360 | + * Sets unit_price |
|
| 361 | + * |
|
| 362 | + * @param float $unit_price |
|
| 363 | + * @throws EE_Error |
|
| 364 | + * @throws InvalidArgumentException |
|
| 365 | + * @throws InvalidDataTypeException |
|
| 366 | + * @throws InvalidInterfaceException |
|
| 367 | + * @throws ReflectionException |
|
| 368 | + */ |
|
| 369 | + public function set_unit_price($unit_price) |
|
| 370 | + { |
|
| 371 | + $this->set('LIN_unit_price', $unit_price); |
|
| 372 | + } |
|
| 373 | + |
|
| 374 | + |
|
| 375 | + /** |
|
| 376 | + * Checks if this item is a percentage modifier or not |
|
| 377 | + * |
|
| 378 | + * @return boolean |
|
| 379 | + * @throws EE_Error |
|
| 380 | + * @throws InvalidArgumentException |
|
| 381 | + * @throws InvalidDataTypeException |
|
| 382 | + * @throws InvalidInterfaceException |
|
| 383 | + * @throws ReflectionException |
|
| 384 | + */ |
|
| 385 | + public function is_percent() |
|
| 386 | + { |
|
| 387 | + if ($this->is_tax_sub_total()) { |
|
| 388 | + // tax subtotals HAVE a percent on them, that percentage only applies |
|
| 389 | + // to taxable items, so its' an exception. Treat it like a flat line item |
|
| 390 | + return false; |
|
| 391 | + } |
|
| 392 | + $unit_price = abs($this->get('LIN_unit_price')); |
|
| 393 | + $percent = abs($this->get('LIN_percent')); |
|
| 394 | + if ($unit_price < .001 && $percent) { |
|
| 395 | + return true; |
|
| 396 | + } |
|
| 397 | + if ($unit_price >= .001 && ! $percent) { |
|
| 398 | + return false; |
|
| 399 | + } |
|
| 400 | + if ($unit_price >= .001 && $percent) { |
|
| 401 | + throw new EE_Error( |
|
| 402 | + sprintf( |
|
| 403 | + esc_html__( |
|
| 404 | + 'A Line Item can not have a unit price of (%s) AND a percent (%s)!', |
|
| 405 | + 'event_espresso' |
|
| 406 | + ), |
|
| 407 | + $unit_price, |
|
| 408 | + $percent |
|
| 409 | + ) |
|
| 410 | + ); |
|
| 411 | + } |
|
| 412 | + // if they're both 0, assume its not a percent item |
|
| 413 | + return false; |
|
| 414 | + } |
|
| 415 | + |
|
| 416 | + |
|
| 417 | + /** |
|
| 418 | + * Gets percent (between 100-.001) |
|
| 419 | + * |
|
| 420 | + * @return float |
|
| 421 | + * @throws EE_Error |
|
| 422 | + * @throws InvalidArgumentException |
|
| 423 | + * @throws InvalidDataTypeException |
|
| 424 | + * @throws InvalidInterfaceException |
|
| 425 | + * @throws ReflectionException |
|
| 426 | + */ |
|
| 427 | + public function percent() |
|
| 428 | + { |
|
| 429 | + return $this->get('LIN_percent'); |
|
| 430 | + } |
|
| 431 | + |
|
| 432 | + |
|
| 433 | + /** |
|
| 434 | + * Sets percent (between 100-0.01) |
|
| 435 | + * |
|
| 436 | + * @param float $percent |
|
| 437 | + * @throws EE_Error |
|
| 438 | + * @throws InvalidArgumentException |
|
| 439 | + * @throws InvalidDataTypeException |
|
| 440 | + * @throws InvalidInterfaceException |
|
| 441 | + * @throws ReflectionException |
|
| 442 | + */ |
|
| 443 | + public function set_percent($percent) |
|
| 444 | + { |
|
| 445 | + $this->set('LIN_percent', $percent); |
|
| 446 | + } |
|
| 447 | + |
|
| 448 | + |
|
| 449 | + /** |
|
| 450 | + * Gets total |
|
| 451 | + * |
|
| 452 | + * @return float |
|
| 453 | + * @throws EE_Error |
|
| 454 | + * @throws InvalidArgumentException |
|
| 455 | + * @throws InvalidDataTypeException |
|
| 456 | + * @throws InvalidInterfaceException |
|
| 457 | + * @throws ReflectionException |
|
| 458 | + */ |
|
| 459 | + public function total() |
|
| 460 | + { |
|
| 461 | + return $this->get('LIN_total'); |
|
| 462 | + } |
|
| 463 | + |
|
| 464 | + |
|
| 465 | + /** |
|
| 466 | + * Sets total |
|
| 467 | + * |
|
| 468 | + * @param float $total |
|
| 469 | + * @throws EE_Error |
|
| 470 | + * @throws InvalidArgumentException |
|
| 471 | + * @throws InvalidDataTypeException |
|
| 472 | + * @throws InvalidInterfaceException |
|
| 473 | + * @throws ReflectionException |
|
| 474 | + */ |
|
| 475 | + public function set_total($total) |
|
| 476 | + { |
|
| 477 | + $this->set('LIN_total', $total); |
|
| 478 | + } |
|
| 479 | + |
|
| 480 | + |
|
| 481 | + /** |
|
| 482 | + * Gets order |
|
| 483 | + * |
|
| 484 | + * @return int |
|
| 485 | + * @throws EE_Error |
|
| 486 | + * @throws InvalidArgumentException |
|
| 487 | + * @throws InvalidDataTypeException |
|
| 488 | + * @throws InvalidInterfaceException |
|
| 489 | + * @throws ReflectionException |
|
| 490 | + */ |
|
| 491 | + public function order() |
|
| 492 | + { |
|
| 493 | + return $this->get('LIN_order'); |
|
| 494 | + } |
|
| 495 | + |
|
| 496 | + |
|
| 497 | + /** |
|
| 498 | + * Sets order |
|
| 499 | + * |
|
| 500 | + * @param int $order |
|
| 501 | + * @throws EE_Error |
|
| 502 | + * @throws InvalidArgumentException |
|
| 503 | + * @throws InvalidDataTypeException |
|
| 504 | + * @throws InvalidInterfaceException |
|
| 505 | + * @throws ReflectionException |
|
| 506 | + */ |
|
| 507 | + public function set_order($order) |
|
| 508 | + { |
|
| 509 | + $this->set('LIN_order', $order); |
|
| 510 | + } |
|
| 511 | + |
|
| 512 | + |
|
| 513 | + /** |
|
| 514 | + * Gets parent |
|
| 515 | + * |
|
| 516 | + * @return int |
|
| 517 | + * @throws EE_Error |
|
| 518 | + * @throws InvalidArgumentException |
|
| 519 | + * @throws InvalidDataTypeException |
|
| 520 | + * @throws InvalidInterfaceException |
|
| 521 | + * @throws ReflectionException |
|
| 522 | + */ |
|
| 523 | + public function parent_ID() |
|
| 524 | + { |
|
| 525 | + return $this->get('LIN_parent'); |
|
| 526 | + } |
|
| 527 | + |
|
| 528 | + |
|
| 529 | + /** |
|
| 530 | + * Sets parent |
|
| 531 | + * |
|
| 532 | + * @param int $parent |
|
| 533 | + * @throws EE_Error |
|
| 534 | + * @throws InvalidArgumentException |
|
| 535 | + * @throws InvalidDataTypeException |
|
| 536 | + * @throws InvalidInterfaceException |
|
| 537 | + * @throws ReflectionException |
|
| 538 | + */ |
|
| 539 | + public function set_parent_ID($parent) |
|
| 540 | + { |
|
| 541 | + $this->set('LIN_parent', $parent); |
|
| 542 | + } |
|
| 543 | + |
|
| 544 | + |
|
| 545 | + /** |
|
| 546 | + * Gets type |
|
| 547 | + * |
|
| 548 | + * @return string |
|
| 549 | + * @throws EE_Error |
|
| 550 | + * @throws InvalidArgumentException |
|
| 551 | + * @throws InvalidDataTypeException |
|
| 552 | + * @throws InvalidInterfaceException |
|
| 553 | + * @throws ReflectionException |
|
| 554 | + */ |
|
| 555 | + public function type() |
|
| 556 | + { |
|
| 557 | + return $this->get('LIN_type'); |
|
| 558 | + } |
|
| 559 | + |
|
| 560 | + |
|
| 561 | + /** |
|
| 562 | + * Sets type |
|
| 563 | + * |
|
| 564 | + * @param string $type |
|
| 565 | + * @throws EE_Error |
|
| 566 | + * @throws InvalidArgumentException |
|
| 567 | + * @throws InvalidDataTypeException |
|
| 568 | + * @throws InvalidInterfaceException |
|
| 569 | + * @throws ReflectionException |
|
| 570 | + */ |
|
| 571 | + public function set_type($type) |
|
| 572 | + { |
|
| 573 | + $this->set('LIN_type', $type); |
|
| 574 | + } |
|
| 575 | + |
|
| 576 | + |
|
| 577 | + /** |
|
| 578 | + * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\ |
|
| 579 | + * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB |
|
| 580 | + * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()` |
|
| 581 | + * or indirectly by `EE_Line_item::add_child_line_item()`) |
|
| 582 | + * |
|
| 583 | + * @return EE_Base_Class|EE_Line_Item |
|
| 584 | + * @throws EE_Error |
|
| 585 | + * @throws InvalidArgumentException |
|
| 586 | + * @throws InvalidDataTypeException |
|
| 587 | + * @throws InvalidInterfaceException |
|
| 588 | + * @throws ReflectionException |
|
| 589 | + */ |
|
| 590 | + public function parent() |
|
| 591 | + { |
|
| 592 | + return $this->ID() |
|
| 593 | + ? $this->get_model()->get_one_by_ID($this->parent_ID()) |
|
| 594 | + : $this->_parent; |
|
| 595 | + } |
|
| 596 | + |
|
| 597 | + |
|
| 598 | + /** |
|
| 599 | + * Gets ALL the children of this line item (ie, all the parts that contribute towards this total). |
|
| 600 | + * |
|
| 601 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 602 | + * @throws EE_Error |
|
| 603 | + * @throws InvalidArgumentException |
|
| 604 | + * @throws InvalidDataTypeException |
|
| 605 | + * @throws InvalidInterfaceException |
|
| 606 | + * @throws ReflectionException |
|
| 607 | + */ |
|
| 608 | + public function children() |
|
| 609 | + { |
|
| 610 | + if ($this->ID()) { |
|
| 611 | + return $this->get_model()->get_all( |
|
| 612 | + array( |
|
| 613 | + array('LIN_parent' => $this->ID()), |
|
| 614 | + 'order_by' => array('LIN_order' => 'ASC'), |
|
| 615 | + ) |
|
| 616 | + ); |
|
| 617 | + } |
|
| 618 | + if (! is_array($this->_children)) { |
|
| 619 | + $this->_children = array(); |
|
| 620 | + } |
|
| 621 | + return $this->_children; |
|
| 622 | + } |
|
| 623 | + |
|
| 624 | + |
|
| 625 | + /** |
|
| 626 | + * Gets code |
|
| 627 | + * |
|
| 628 | + * @return string |
|
| 629 | + * @throws EE_Error |
|
| 630 | + * @throws InvalidArgumentException |
|
| 631 | + * @throws InvalidDataTypeException |
|
| 632 | + * @throws InvalidInterfaceException |
|
| 633 | + * @throws ReflectionException |
|
| 634 | + */ |
|
| 635 | + public function code() |
|
| 636 | + { |
|
| 637 | + return $this->get('LIN_code'); |
|
| 638 | + } |
|
| 639 | + |
|
| 640 | + |
|
| 641 | + /** |
|
| 642 | + * Sets code |
|
| 643 | + * |
|
| 644 | + * @param string $code |
|
| 645 | + * @throws EE_Error |
|
| 646 | + * @throws InvalidArgumentException |
|
| 647 | + * @throws InvalidDataTypeException |
|
| 648 | + * @throws InvalidInterfaceException |
|
| 649 | + * @throws ReflectionException |
|
| 650 | + */ |
|
| 651 | + public function set_code($code) |
|
| 652 | + { |
|
| 653 | + $this->set('LIN_code', $code); |
|
| 654 | + } |
|
| 655 | + |
|
| 656 | + |
|
| 657 | + /** |
|
| 658 | + * Gets is_taxable |
|
| 659 | + * |
|
| 660 | + * @return boolean |
|
| 661 | + * @throws EE_Error |
|
| 662 | + * @throws InvalidArgumentException |
|
| 663 | + * @throws InvalidDataTypeException |
|
| 664 | + * @throws InvalidInterfaceException |
|
| 665 | + * @throws ReflectionException |
|
| 666 | + */ |
|
| 667 | + public function is_taxable() |
|
| 668 | + { |
|
| 669 | + return $this->get('LIN_is_taxable'); |
|
| 670 | + } |
|
| 671 | + |
|
| 672 | + |
|
| 673 | + /** |
|
| 674 | + * Sets is_taxable |
|
| 675 | + * |
|
| 676 | + * @param boolean $is_taxable |
|
| 677 | + * @throws EE_Error |
|
| 678 | + * @throws InvalidArgumentException |
|
| 679 | + * @throws InvalidDataTypeException |
|
| 680 | + * @throws InvalidInterfaceException |
|
| 681 | + * @throws ReflectionException |
|
| 682 | + */ |
|
| 683 | + public function set_is_taxable($is_taxable) |
|
| 684 | + { |
|
| 685 | + $this->set('LIN_is_taxable', $is_taxable); |
|
| 686 | + } |
|
| 687 | + |
|
| 688 | + |
|
| 689 | + /** |
|
| 690 | + * Gets the object that this model-joins-to. |
|
| 691 | + * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on |
|
| 692 | + * EEM_Promotion_Object |
|
| 693 | + * Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object |
|
| 694 | + * |
|
| 695 | + * @return EE_Base_Class | NULL |
|
| 696 | + * @throws EE_Error |
|
| 697 | + * @throws InvalidArgumentException |
|
| 698 | + * @throws InvalidDataTypeException |
|
| 699 | + * @throws InvalidInterfaceException |
|
| 700 | + * @throws ReflectionException |
|
| 701 | + */ |
|
| 702 | + public function get_object() |
|
| 703 | + { |
|
| 704 | + $model_name_of_related_obj = $this->OBJ_type(); |
|
| 705 | + return $this->get_model()->has_relation($model_name_of_related_obj) |
|
| 706 | + ? $this->get_first_related($model_name_of_related_obj) |
|
| 707 | + : null; |
|
| 708 | + } |
|
| 709 | + |
|
| 710 | + |
|
| 711 | + /** |
|
| 712 | + * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket. |
|
| 713 | + * (IE, if this line item is for a price or something else, will return NULL) |
|
| 714 | + * |
|
| 715 | + * @param array $query_params |
|
| 716 | + * @return EE_Base_Class|EE_Ticket |
|
| 717 | + * @throws EE_Error |
|
| 718 | + * @throws InvalidArgumentException |
|
| 719 | + * @throws InvalidDataTypeException |
|
| 720 | + * @throws InvalidInterfaceException |
|
| 721 | + * @throws ReflectionException |
|
| 722 | + */ |
|
| 723 | + public function ticket($query_params = array()) |
|
| 724 | + { |
|
| 725 | + // we're going to assume that when this method is called |
|
| 726 | + // we always want to receive the attached ticket EVEN if that ticket is archived. |
|
| 727 | + // This can be overridden via the incoming $query_params argument |
|
| 728 | + $remove_defaults = array('default_where_conditions' => 'none'); |
|
| 729 | + $query_params = array_merge($remove_defaults, $query_params); |
|
| 730 | + return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TICKET, $query_params); |
|
| 731 | + } |
|
| 732 | + |
|
| 733 | + |
|
| 734 | + /** |
|
| 735 | + * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket |
|
| 736 | + * |
|
| 737 | + * @return EE_Datetime | NULL |
|
| 738 | + * @throws EE_Error |
|
| 739 | + * @throws InvalidArgumentException |
|
| 740 | + * @throws InvalidDataTypeException |
|
| 741 | + * @throws InvalidInterfaceException |
|
| 742 | + * @throws ReflectionException |
|
| 743 | + */ |
|
| 744 | + public function get_ticket_datetime() |
|
| 745 | + { |
|
| 746 | + if ($this->OBJ_type() === EEM_Line_Item::OBJ_TYPE_TICKET) { |
|
| 747 | + $ticket = $this->ticket(); |
|
| 748 | + if ($ticket instanceof EE_Ticket) { |
|
| 749 | + $datetime = $ticket->first_datetime(); |
|
| 750 | + if ($datetime instanceof EE_Datetime) { |
|
| 751 | + return $datetime; |
|
| 752 | + } |
|
| 753 | + } |
|
| 754 | + } |
|
| 755 | + return null; |
|
| 756 | + } |
|
| 757 | + |
|
| 758 | + |
|
| 759 | + /** |
|
| 760 | + * Gets the event's name that's related to the ticket, if this is for |
|
| 761 | + * a ticket |
|
| 762 | + * |
|
| 763 | + * @return string |
|
| 764 | + * @throws EE_Error |
|
| 765 | + * @throws InvalidArgumentException |
|
| 766 | + * @throws InvalidDataTypeException |
|
| 767 | + * @throws InvalidInterfaceException |
|
| 768 | + * @throws ReflectionException |
|
| 769 | + */ |
|
| 770 | + public function ticket_event_name() |
|
| 771 | + { |
|
| 772 | + $event_name = esc_html__('Unknown', 'event_espresso'); |
|
| 773 | + $event = $this->ticket_event(); |
|
| 774 | + if ($event instanceof EE_Event) { |
|
| 775 | + $event_name = $event->name(); |
|
| 776 | + } |
|
| 777 | + return $event_name; |
|
| 778 | + } |
|
| 779 | + |
|
| 780 | + |
|
| 781 | + /** |
|
| 782 | + * Gets the event that's related to the ticket, if this line item represents a ticket. |
|
| 783 | + * |
|
| 784 | + * @return EE_Event|null |
|
| 785 | + * @throws EE_Error |
|
| 786 | + * @throws InvalidArgumentException |
|
| 787 | + * @throws InvalidDataTypeException |
|
| 788 | + * @throws InvalidInterfaceException |
|
| 789 | + * @throws ReflectionException |
|
| 790 | + */ |
|
| 791 | + public function ticket_event() |
|
| 792 | + { |
|
| 793 | + $event = null; |
|
| 794 | + $ticket = $this->ticket(); |
|
| 795 | + if ($ticket instanceof EE_Ticket) { |
|
| 796 | + $datetime = $ticket->first_datetime(); |
|
| 797 | + if ($datetime instanceof EE_Datetime) { |
|
| 798 | + $event = $datetime->event(); |
|
| 799 | + } |
|
| 800 | + } |
|
| 801 | + return $event; |
|
| 802 | + } |
|
| 803 | + |
|
| 804 | + |
|
| 805 | + /** |
|
| 806 | + * Gets the first datetime for this lien item, assuming it's for a ticket |
|
| 807 | + * |
|
| 808 | + * @param string $date_format |
|
| 809 | + * @param string $time_format |
|
| 810 | + * @return string |
|
| 811 | + * @throws EE_Error |
|
| 812 | + * @throws InvalidArgumentException |
|
| 813 | + * @throws InvalidDataTypeException |
|
| 814 | + * @throws InvalidInterfaceException |
|
| 815 | + * @throws ReflectionException |
|
| 816 | + */ |
|
| 817 | + public function ticket_datetime_start($date_format = '', $time_format = '') |
|
| 818 | + { |
|
| 819 | + $first_datetime_string = esc_html__('Unknown', 'event_espresso'); |
|
| 820 | + $datetime = $this->get_ticket_datetime(); |
|
| 821 | + if ($datetime) { |
|
| 822 | + $first_datetime_string = $datetime->start_date_and_time($date_format, $time_format); |
|
| 823 | + } |
|
| 824 | + return $first_datetime_string; |
|
| 825 | + } |
|
| 826 | + |
|
| 827 | + |
|
| 828 | + /** |
|
| 829 | + * Adds the line item as a child to this line item. If there is another child line |
|
| 830 | + * item with the same LIN_code, it is overwritten by this new one |
|
| 831 | + * |
|
| 832 | + * @param EEI_Line_Item $line_item |
|
| 833 | + * @param bool $set_order |
|
| 834 | + * @return bool success |
|
| 835 | + * @throws EE_Error |
|
| 836 | + * @throws InvalidArgumentException |
|
| 837 | + * @throws InvalidDataTypeException |
|
| 838 | + * @throws InvalidInterfaceException |
|
| 839 | + * @throws ReflectionException |
|
| 840 | + */ |
|
| 841 | + public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true) |
|
| 842 | + { |
|
| 843 | + // should we calculate the LIN_order for this line item ? |
|
| 844 | + if ($set_order || $line_item->order() === null) { |
|
| 845 | + $line_item->set_order(count($this->children())); |
|
| 846 | + } |
|
| 847 | + if ($this->ID()) { |
|
| 848 | + // check for any duplicate line items (with the same code), if so, this replaces it |
|
| 849 | + $line_item_with_same_code = $this->get_child_line_item($line_item->code()); |
|
| 850 | + if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) { |
|
| 851 | + $this->delete_child_line_item($line_item_with_same_code->code()); |
|
| 852 | + } |
|
| 853 | + $line_item->set_parent_ID($this->ID()); |
|
| 854 | + if ($this->TXN_ID()) { |
|
| 855 | + $line_item->set_TXN_ID($this->TXN_ID()); |
|
| 856 | + } |
|
| 857 | + return $line_item->save(); |
|
| 858 | + } |
|
| 859 | + $this->_children[ $line_item->code() ] = $line_item; |
|
| 860 | + if ($line_item->parent() !== $this) { |
|
| 861 | + $line_item->set_parent($this); |
|
| 862 | + } |
|
| 863 | + return true; |
|
| 864 | + } |
|
| 865 | + |
|
| 866 | + |
|
| 867 | + /** |
|
| 868 | + * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation. |
|
| 869 | + * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save() |
|
| 870 | + * However, if this line item is NOT saved to the DB, this just caches the parent on |
|
| 871 | + * the EE_Line_Item::_parent property. |
|
| 872 | + * |
|
| 873 | + * @param EE_Line_Item $line_item |
|
| 874 | + * @throws EE_Error |
|
| 875 | + * @throws InvalidArgumentException |
|
| 876 | + * @throws InvalidDataTypeException |
|
| 877 | + * @throws InvalidInterfaceException |
|
| 878 | + * @throws ReflectionException |
|
| 879 | + */ |
|
| 880 | + public function set_parent($line_item) |
|
| 881 | + { |
|
| 882 | + if ($this->ID()) { |
|
| 883 | + if (! $line_item->ID()) { |
|
| 884 | + $line_item->save(); |
|
| 885 | + } |
|
| 886 | + $this->set_parent_ID($line_item->ID()); |
|
| 887 | + $this->save(); |
|
| 888 | + } else { |
|
| 889 | + $this->_parent = $line_item; |
|
| 890 | + $this->set_parent_ID($line_item->ID()); |
|
| 891 | + } |
|
| 892 | + } |
|
| 893 | + |
|
| 894 | + |
|
| 895 | + /** |
|
| 896 | + * Gets the child line item as specified by its code. Because this returns an object (by reference) |
|
| 897 | + * you can modify this child line item and the parent (this object) can know about them |
|
| 898 | + * because it also has a reference to that line item |
|
| 899 | + * |
|
| 900 | + * @param string $code |
|
| 901 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
| 902 | + * @throws EE_Error |
|
| 903 | + * @throws InvalidArgumentException |
|
| 904 | + * @throws InvalidDataTypeException |
|
| 905 | + * @throws InvalidInterfaceException |
|
| 906 | + * @throws ReflectionException |
|
| 907 | + */ |
|
| 908 | + public function get_child_line_item($code) |
|
| 909 | + { |
|
| 910 | + if ($this->ID()) { |
|
| 911 | + return $this->get_model()->get_one( |
|
| 912 | + array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code)) |
|
| 913 | + ); |
|
| 914 | + } |
|
| 915 | + return isset($this->_children[ $code ]) |
|
| 916 | + ? $this->_children[ $code ] |
|
| 917 | + : null; |
|
| 918 | + } |
|
| 919 | + |
|
| 920 | + |
|
| 921 | + /** |
|
| 922 | + * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD |
|
| 923 | + * cached on it) |
|
| 924 | + * |
|
| 925 | + * @return int |
|
| 926 | + * @throws EE_Error |
|
| 927 | + * @throws InvalidArgumentException |
|
| 928 | + * @throws InvalidDataTypeException |
|
| 929 | + * @throws InvalidInterfaceException |
|
| 930 | + * @throws ReflectionException |
|
| 931 | + */ |
|
| 932 | + public function delete_children_line_items() |
|
| 933 | + { |
|
| 934 | + if ($this->ID()) { |
|
| 935 | + return $this->get_model()->delete(array(array('LIN_parent' => $this->ID()))); |
|
| 936 | + } |
|
| 937 | + $count = count($this->_children); |
|
| 938 | + $this->_children = array(); |
|
| 939 | + return $count; |
|
| 940 | + } |
|
| 941 | + |
|
| 942 | + |
|
| 943 | + /** |
|
| 944 | + * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line |
|
| 945 | + * HAS NOT been saved to the DB, removes the child line item with index $code. |
|
| 946 | + * Also searches through the child's children for a matching line item. However, once a line item has been found |
|
| 947 | + * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be |
|
| 948 | + * deleted) |
|
| 949 | + * |
|
| 950 | + * @param string $code |
|
| 951 | + * @param bool $stop_search_once_found |
|
| 952 | + * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to |
|
| 953 | + * the DB yet) |
|
| 954 | + * @throws EE_Error |
|
| 955 | + * @throws InvalidArgumentException |
|
| 956 | + * @throws InvalidDataTypeException |
|
| 957 | + * @throws InvalidInterfaceException |
|
| 958 | + * @throws ReflectionException |
|
| 959 | + */ |
|
| 960 | + public function delete_child_line_item($code, $stop_search_once_found = true) |
|
| 961 | + { |
|
| 962 | + if ($this->ID()) { |
|
| 963 | + $items_deleted = 0; |
|
| 964 | + if ($this->code() === $code) { |
|
| 965 | + $items_deleted += EEH_Line_Item::delete_all_child_items($this); |
|
| 966 | + $items_deleted += (int) $this->delete(); |
|
| 967 | + if ($stop_search_once_found) { |
|
| 968 | + return $items_deleted; |
|
| 969 | + } |
|
| 970 | + } |
|
| 971 | + foreach ($this->children() as $child_line_item) { |
|
| 972 | + $items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found); |
|
| 973 | + } |
|
| 974 | + return $items_deleted; |
|
| 975 | + } |
|
| 976 | + if (isset($this->_children[ $code ])) { |
|
| 977 | + unset($this->_children[ $code ]); |
|
| 978 | + return 1; |
|
| 979 | + } |
|
| 980 | + return 0; |
|
| 981 | + } |
|
| 982 | + |
|
| 983 | + |
|
| 984 | + /** |
|
| 985 | + * If this line item is in the database, is of the type subtotal, and |
|
| 986 | + * has no children, why do we have it? It should be deleted so this function |
|
| 987 | + * does that |
|
| 988 | + * |
|
| 989 | + * @return boolean |
|
| 990 | + * @throws EE_Error |
|
| 991 | + * @throws InvalidArgumentException |
|
| 992 | + * @throws InvalidDataTypeException |
|
| 993 | + * @throws InvalidInterfaceException |
|
| 994 | + * @throws ReflectionException |
|
| 995 | + */ |
|
| 996 | + public function delete_if_childless_subtotal() |
|
| 997 | + { |
|
| 998 | + if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) { |
|
| 999 | + return $this->delete(); |
|
| 1000 | + } |
|
| 1001 | + return false; |
|
| 1002 | + } |
|
| 1003 | + |
|
| 1004 | + |
|
| 1005 | + /** |
|
| 1006 | + * Creates a code and returns a string. doesn't assign the code to this model object |
|
| 1007 | + * |
|
| 1008 | + * @return string |
|
| 1009 | + * @throws EE_Error |
|
| 1010 | + * @throws InvalidArgumentException |
|
| 1011 | + * @throws InvalidDataTypeException |
|
| 1012 | + * @throws InvalidInterfaceException |
|
| 1013 | + * @throws ReflectionException |
|
| 1014 | + */ |
|
| 1015 | + public function generate_code() |
|
| 1016 | + { |
|
| 1017 | + // each line item in the cart requires a unique identifier |
|
| 1018 | + return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime()); |
|
| 1019 | + } |
|
| 1020 | + |
|
| 1021 | + |
|
| 1022 | + /** |
|
| 1023 | + * @return bool |
|
| 1024 | + * @throws EE_Error |
|
| 1025 | + * @throws InvalidArgumentException |
|
| 1026 | + * @throws InvalidDataTypeException |
|
| 1027 | + * @throws InvalidInterfaceException |
|
| 1028 | + * @throws ReflectionException |
|
| 1029 | + */ |
|
| 1030 | + public function is_tax() |
|
| 1031 | + { |
|
| 1032 | + return $this->type() === EEM_Line_Item::type_tax; |
|
| 1033 | + } |
|
| 1034 | + |
|
| 1035 | + |
|
| 1036 | + /** |
|
| 1037 | + * @return bool |
|
| 1038 | + * @throws EE_Error |
|
| 1039 | + * @throws InvalidArgumentException |
|
| 1040 | + * @throws InvalidDataTypeException |
|
| 1041 | + * @throws InvalidInterfaceException |
|
| 1042 | + * @throws ReflectionException |
|
| 1043 | + */ |
|
| 1044 | + public function is_tax_sub_total() |
|
| 1045 | + { |
|
| 1046 | + return $this->type() === EEM_Line_Item::type_tax_sub_total; |
|
| 1047 | + } |
|
| 1048 | + |
|
| 1049 | + |
|
| 1050 | + /** |
|
| 1051 | + * @return bool |
|
| 1052 | + * @throws EE_Error |
|
| 1053 | + * @throws InvalidArgumentException |
|
| 1054 | + * @throws InvalidDataTypeException |
|
| 1055 | + * @throws InvalidInterfaceException |
|
| 1056 | + * @throws ReflectionException |
|
| 1057 | + */ |
|
| 1058 | + public function is_line_item() |
|
| 1059 | + { |
|
| 1060 | + return $this->type() === EEM_Line_Item::type_line_item; |
|
| 1061 | + } |
|
| 1062 | + |
|
| 1063 | + |
|
| 1064 | + /** |
|
| 1065 | + * @return bool |
|
| 1066 | + * @throws EE_Error |
|
| 1067 | + * @throws InvalidArgumentException |
|
| 1068 | + * @throws InvalidDataTypeException |
|
| 1069 | + * @throws InvalidInterfaceException |
|
| 1070 | + * @throws ReflectionException |
|
| 1071 | + */ |
|
| 1072 | + public function is_sub_line_item() |
|
| 1073 | + { |
|
| 1074 | + return $this->type() === EEM_Line_Item::type_sub_line_item; |
|
| 1075 | + } |
|
| 1076 | + |
|
| 1077 | + |
|
| 1078 | + /** |
|
| 1079 | + * @return bool |
|
| 1080 | + * @throws EE_Error |
|
| 1081 | + * @throws InvalidArgumentException |
|
| 1082 | + * @throws InvalidDataTypeException |
|
| 1083 | + * @throws InvalidInterfaceException |
|
| 1084 | + * @throws ReflectionException |
|
| 1085 | + */ |
|
| 1086 | + public function is_sub_total() |
|
| 1087 | + { |
|
| 1088 | + return $this->type() === EEM_Line_Item::type_sub_total; |
|
| 1089 | + } |
|
| 1090 | + |
|
| 1091 | + |
|
| 1092 | + /** |
|
| 1093 | + * Whether or not this line item is a cancellation line item |
|
| 1094 | + * |
|
| 1095 | + * @return boolean |
|
| 1096 | + * @throws EE_Error |
|
| 1097 | + * @throws InvalidArgumentException |
|
| 1098 | + * @throws InvalidDataTypeException |
|
| 1099 | + * @throws InvalidInterfaceException |
|
| 1100 | + * @throws ReflectionException |
|
| 1101 | + */ |
|
| 1102 | + public function is_cancellation() |
|
| 1103 | + { |
|
| 1104 | + return EEM_Line_Item::type_cancellation === $this->type(); |
|
| 1105 | + } |
|
| 1106 | + |
|
| 1107 | + |
|
| 1108 | + /** |
|
| 1109 | + * @return bool |
|
| 1110 | + * @throws EE_Error |
|
| 1111 | + * @throws InvalidArgumentException |
|
| 1112 | + * @throws InvalidDataTypeException |
|
| 1113 | + * @throws InvalidInterfaceException |
|
| 1114 | + * @throws ReflectionException |
|
| 1115 | + */ |
|
| 1116 | + public function is_total() |
|
| 1117 | + { |
|
| 1118 | + return $this->type() === EEM_Line_Item::type_total; |
|
| 1119 | + } |
|
| 1120 | + |
|
| 1121 | + |
|
| 1122 | + /** |
|
| 1123 | + * @return bool |
|
| 1124 | + * @throws EE_Error |
|
| 1125 | + * @throws InvalidArgumentException |
|
| 1126 | + * @throws InvalidDataTypeException |
|
| 1127 | + * @throws InvalidInterfaceException |
|
| 1128 | + * @throws ReflectionException |
|
| 1129 | + */ |
|
| 1130 | + public function is_cancelled() |
|
| 1131 | + { |
|
| 1132 | + return $this->type() === EEM_Line_Item::type_cancellation; |
|
| 1133 | + } |
|
| 1134 | + |
|
| 1135 | + |
|
| 1136 | + /** |
|
| 1137 | + * @return string like '2, 004.00', formatted according to the localized currency |
|
| 1138 | + * @throws EE_Error |
|
| 1139 | + * @throws InvalidArgumentException |
|
| 1140 | + * @throws InvalidDataTypeException |
|
| 1141 | + * @throws InvalidInterfaceException |
|
| 1142 | + * @throws ReflectionException |
|
| 1143 | + */ |
|
| 1144 | + public function unit_price_no_code() |
|
| 1145 | + { |
|
| 1146 | + return $this->get_pretty('LIN_unit_price', 'no_currency_code'); |
|
| 1147 | + } |
|
| 1148 | + |
|
| 1149 | + |
|
| 1150 | + /** |
|
| 1151 | + * @return string like '2, 004.00', formatted according to the localized currency |
|
| 1152 | + * @throws EE_Error |
|
| 1153 | + * @throws InvalidArgumentException |
|
| 1154 | + * @throws InvalidDataTypeException |
|
| 1155 | + * @throws InvalidInterfaceException |
|
| 1156 | + * @throws ReflectionException |
|
| 1157 | + */ |
|
| 1158 | + public function total_no_code() |
|
| 1159 | + { |
|
| 1160 | + return $this->get_pretty('LIN_total', 'no_currency_code'); |
|
| 1161 | + } |
|
| 1162 | + |
|
| 1163 | + |
|
| 1164 | + /** |
|
| 1165 | + * Gets the final total on this item, taking taxes into account. |
|
| 1166 | + * Has the side-effect of setting the sub-total as it was just calculated. |
|
| 1167 | + * If this is used on a grand-total line item, also updates the transaction's |
|
| 1168 | + * TXN_total (provided this line item is allowed to persist, otherwise we don't |
|
| 1169 | + * want to change a persistable transaction with info from a non-persistent line item) |
|
| 1170 | + * |
|
| 1171 | + * @param bool $update_txn_status |
|
| 1172 | + * @return float |
|
| 1173 | + * @throws EE_Error |
|
| 1174 | + * @throws InvalidArgumentException |
|
| 1175 | + * @throws InvalidDataTypeException |
|
| 1176 | + * @throws InvalidInterfaceException |
|
| 1177 | + * @throws ReflectionException |
|
| 1178 | + * @throws RuntimeException |
|
| 1179 | + */ |
|
| 1180 | + public function recalculate_total_including_taxes($update_txn_status = false) |
|
| 1181 | + { |
|
| 1182 | + $pre_tax_total = $this->recalculate_pre_tax_total(); |
|
| 1183 | + $tax_total = $this->recalculate_taxes_and_tax_total(); |
|
| 1184 | + $total = $pre_tax_total + $tax_total; |
|
| 1185 | + // no negative totals plz |
|
| 1186 | + $total = max($total, 0); |
|
| 1187 | + $this->set_total($total); |
|
| 1188 | + // only update the related transaction's total |
|
| 1189 | + // if we intend to save this line item and its a grand total |
|
| 1190 | + if ( |
|
| 1191 | + $this->allow_persist() && $this->type() === EEM_Line_Item::type_total |
|
| 1192 | + && $this->transaction() |
|
| 1193 | + instanceof |
|
| 1194 | + EE_Transaction |
|
| 1195 | + ) { |
|
| 1196 | + $this->transaction()->set_total($total); |
|
| 1197 | + if ($update_txn_status) { |
|
| 1198 | + // don't save the TXN because that will be done below |
|
| 1199 | + // and the following method only saves if the status changes |
|
| 1200 | + $this->transaction()->update_status_based_on_total_paid(false); |
|
| 1201 | + } |
|
| 1202 | + if ($this->transaction()->ID()) { |
|
| 1203 | + $this->transaction()->save(); |
|
| 1204 | + } |
|
| 1205 | + } |
|
| 1206 | + $this->maybe_save(); |
|
| 1207 | + return $total; |
|
| 1208 | + } |
|
| 1209 | + |
|
| 1210 | + |
|
| 1211 | + /** |
|
| 1212 | + * Recursively goes through all the children and recalculates sub-totals EXCEPT for |
|
| 1213 | + * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its |
|
| 1214 | + * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and |
|
| 1215 | + * when this is called on the grand total |
|
| 1216 | + * |
|
| 1217 | + * @return float |
|
| 1218 | + * @throws EE_Error |
|
| 1219 | + * @throws InvalidArgumentException |
|
| 1220 | + * @throws InvalidDataTypeException |
|
| 1221 | + * @throws InvalidInterfaceException |
|
| 1222 | + * @throws ReflectionException |
|
| 1223 | + */ |
|
| 1224 | + public function recalculate_pre_tax_total() |
|
| 1225 | + { |
|
| 1226 | + $total = 0; |
|
| 1227 | + $my_children = $this->children(); |
|
| 1228 | + $has_children = ! empty($my_children); |
|
| 1229 | + if ($has_children && $this->is_line_item()) { |
|
| 1230 | + $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children); |
|
| 1231 | + } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) { |
|
| 1232 | + $total = $this->unit_price() * $this->quantity(); |
|
| 1233 | + } elseif ($this->is_sub_total() || $this->is_total()) { |
|
| 1234 | + $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children); |
|
| 1235 | + } elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) { |
|
| 1236 | + // completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total |
|
| 1237 | + return 0; |
|
| 1238 | + } |
|
| 1239 | + // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events) |
|
| 1240 | + if (! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()) { |
|
| 1241 | + if ($this->OBJ_type() !== EEM_Line_Item::OBJ_TYPE_EVENT) { |
|
| 1242 | + $this->set_quantity(1); |
|
| 1243 | + } |
|
| 1244 | + if (! $this->is_percent()) { |
|
| 1245 | + $this->set_unit_price($total); |
|
| 1246 | + } |
|
| 1247 | + } |
|
| 1248 | + // we don't want to bother saving grand totals, because that needs to factor in taxes anyways |
|
| 1249 | + // so it ought to be |
|
| 1250 | + if (! $this->is_total()) { |
|
| 1251 | + $this->set_total($total); |
|
| 1252 | + // if not a percent line item, make sure we keep the unit price in sync |
|
| 1253 | + if ( |
|
| 1254 | + $has_children |
|
| 1255 | + && $this->is_line_item() |
|
| 1256 | + && ! $this->is_percent() |
|
| 1257 | + ) { |
|
| 1258 | + if ($this->quantity() === 0) { |
|
| 1259 | + $new_unit_price = 0; |
|
| 1260 | + } else { |
|
| 1261 | + $new_unit_price = $this->total() / $this->quantity(); |
|
| 1262 | + } |
|
| 1263 | + $this->set_unit_price($new_unit_price); |
|
| 1264 | + } |
|
| 1265 | + $this->maybe_save(); |
|
| 1266 | + } |
|
| 1267 | + return $total; |
|
| 1268 | + } |
|
| 1269 | + |
|
| 1270 | + |
|
| 1271 | + /** |
|
| 1272 | + * Calculates the pretax total when this line item is a subtotal or total line item. |
|
| 1273 | + * Basically does a sum-then-round approach (ie, any percent line item that are children |
|
| 1274 | + * will calculate their total based on the un-rounded total we're working with so far, and |
|
| 1275 | + * THEN round the result; instead of rounding as we go like with sub-line-items) |
|
| 1276 | + * |
|
| 1277 | + * @param float $calculated_total_so_far |
|
| 1278 | + * @param EE_Line_Item[] $my_children |
|
| 1279 | + * @return float |
|
| 1280 | + * @throws EE_Error |
|
| 1281 | + * @throws InvalidArgumentException |
|
| 1282 | + * @throws InvalidDataTypeException |
|
| 1283 | + * @throws InvalidInterfaceException |
|
| 1284 | + * @throws ReflectionException |
|
| 1285 | + */ |
|
| 1286 | + protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null) |
|
| 1287 | + { |
|
| 1288 | + if ($my_children === null) { |
|
| 1289 | + $my_children = $this->children(); |
|
| 1290 | + } |
|
| 1291 | + $subtotal_quantity = 0; |
|
| 1292 | + // get the total of all its children |
|
| 1293 | + foreach ($my_children as $child_line_item) { |
|
| 1294 | + if ($child_line_item instanceof EE_Line_Item) { |
|
| 1295 | + // skip line item if it is cancelled or is a tax |
|
| 1296 | + if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
| 1297 | + continue; |
|
| 1298 | + } |
|
| 1299 | + // percentage line items are based on total so far |
|
| 1300 | + if ($child_line_item->is_percent()) { |
|
| 1301 | + // round as we go so that the line items add up ok |
|
| 1302 | + $percent_total = round( |
|
| 1303 | + $calculated_total_so_far * $child_line_item->percent() / 100, |
|
| 1304 | + EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1305 | + ); |
|
| 1306 | + $child_line_item->set_total($percent_total); |
|
| 1307 | + // so far all percent line items should have a quantity of 1 |
|
| 1308 | + // (ie, no double percent discounts. Although that might be requested someday) |
|
| 1309 | + $child_line_item->set_quantity(1); |
|
| 1310 | + $child_line_item->maybe_save(); |
|
| 1311 | + $calculated_total_so_far += $percent_total; |
|
| 1312 | + } else { |
|
| 1313 | + // verify flat sub-line-item quantities match their parent |
|
| 1314 | + if ($child_line_item->is_sub_line_item()) { |
|
| 1315 | + $child_line_item->set_quantity($this->quantity()); |
|
| 1316 | + } |
|
| 1317 | + $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1318 | + $subtotal_quantity += $child_line_item->quantity(); |
|
| 1319 | + } |
|
| 1320 | + } |
|
| 1321 | + } |
|
| 1322 | + if ($this->is_sub_total()) { |
|
| 1323 | + // no negative totals plz |
|
| 1324 | + $calculated_total_so_far = max($calculated_total_so_far, 0); |
|
| 1325 | + $subtotal_quantity = $subtotal_quantity > 0 ? 1 : 0; |
|
| 1326 | + $this->set_quantity($subtotal_quantity); |
|
| 1327 | + $this->maybe_save(); |
|
| 1328 | + } |
|
| 1329 | + return $calculated_total_so_far; |
|
| 1330 | + } |
|
| 1331 | + |
|
| 1332 | + |
|
| 1333 | + /** |
|
| 1334 | + * Calculates the pretax total for a normal line item, in a round-then-sum approach |
|
| 1335 | + * (where each sub-line-item is applied to the base price for the line item |
|
| 1336 | + * and the result is immediately rounded, rather than summing all the sub-line-items |
|
| 1337 | + * then rounding, like we do when recalculating pretax totals on totals and subtotals). |
|
| 1338 | + * |
|
| 1339 | + * @param float $calculated_total_so_far |
|
| 1340 | + * @param EE_Line_Item[] $my_children |
|
| 1341 | + * @return float |
|
| 1342 | + * @throws EE_Error |
|
| 1343 | + * @throws InvalidArgumentException |
|
| 1344 | + * @throws InvalidDataTypeException |
|
| 1345 | + * @throws InvalidInterfaceException |
|
| 1346 | + * @throws ReflectionException |
|
| 1347 | + */ |
|
| 1348 | + protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null) |
|
| 1349 | + { |
|
| 1350 | + if ($my_children === null) { |
|
| 1351 | + $my_children = $this->children(); |
|
| 1352 | + } |
|
| 1353 | + // we need to keep track of the running total for a single item, |
|
| 1354 | + // because we need to round as we go |
|
| 1355 | + $unit_price_for_total = 0; |
|
| 1356 | + $quantity_for_total = 1; |
|
| 1357 | + // get the total of all its children |
|
| 1358 | + foreach ($my_children as $child_line_item) { |
|
| 1359 | + if ($child_line_item instanceof EE_Line_Item) { |
|
| 1360 | + // skip line item if it is cancelled or is a tax |
|
| 1361 | + if ($child_line_item->is_cancellation() || $child_line_item->is_tax()) { |
|
| 1362 | + continue; |
|
| 1363 | + } |
|
| 1364 | + if ($child_line_item->is_percent()) { |
|
| 1365 | + // it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity |
|
| 1366 | + // not total multiplied by percent, because that ignores rounding along-the-way |
|
| 1367 | + $percent_unit_price = round( |
|
| 1368 | + $unit_price_for_total * $child_line_item->percent() / 100, |
|
| 1369 | + EE_Registry::instance()->CFG->currency->dec_plc |
|
| 1370 | + ); |
|
| 1371 | + $percent_total = $percent_unit_price * $quantity_for_total; |
|
| 1372 | + $child_line_item->set_total($percent_total); |
|
| 1373 | + // so far all percent line items should have a quantity of 1 |
|
| 1374 | + // (ie, no double percent discounts. Although that might be requested someday) |
|
| 1375 | + $child_line_item->set_quantity(1); |
|
| 1376 | + $child_line_item->maybe_save(); |
|
| 1377 | + $calculated_total_so_far += $percent_total; |
|
| 1378 | + $unit_price_for_total += $percent_unit_price; |
|
| 1379 | + } else { |
|
| 1380 | + // verify flat sub-line-item quantities match their parent |
|
| 1381 | + if ($child_line_item->is_sub_line_item()) { |
|
| 1382 | + $child_line_item->set_quantity($this->quantity()); |
|
| 1383 | + } |
|
| 1384 | + $quantity_for_total = $child_line_item->quantity(); |
|
| 1385 | + $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total(); |
|
| 1386 | + $unit_price_for_total += $child_line_item->unit_price(); |
|
| 1387 | + } |
|
| 1388 | + } |
|
| 1389 | + } |
|
| 1390 | + return $calculated_total_so_far; |
|
| 1391 | + } |
|
| 1392 | + |
|
| 1393 | + |
|
| 1394 | + /** |
|
| 1395 | + * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets |
|
| 1396 | + * the totals on each tax calculated, and returns the final tax total. Re-saves tax line items |
|
| 1397 | + * and tax sub-total if already in the DB |
|
| 1398 | + * |
|
| 1399 | + * @return float |
|
| 1400 | + * @throws EE_Error |
|
| 1401 | + * @throws InvalidArgumentException |
|
| 1402 | + * @throws InvalidDataTypeException |
|
| 1403 | + * @throws InvalidInterfaceException |
|
| 1404 | + * @throws ReflectionException |
|
| 1405 | + */ |
|
| 1406 | + public function recalculate_taxes_and_tax_total() |
|
| 1407 | + { |
|
| 1408 | + // get all taxes |
|
| 1409 | + $taxes = $this->tax_descendants(); |
|
| 1410 | + // calculate the pretax total |
|
| 1411 | + $taxable_total = $this->taxable_total(); |
|
| 1412 | + $tax_total = 0; |
|
| 1413 | + foreach ($taxes as $tax) { |
|
| 1414 | + $total_on_this_tax = $taxable_total * $tax->percent() / 100; |
|
| 1415 | + // remember the total on this line item |
|
| 1416 | + $tax->set_total($total_on_this_tax); |
|
| 1417 | + $tax->maybe_save(); |
|
| 1418 | + $tax_total += $tax->total(); |
|
| 1419 | + } |
|
| 1420 | + $this->_recalculate_tax_sub_total(); |
|
| 1421 | + return $tax_total; |
|
| 1422 | + } |
|
| 1423 | + |
|
| 1424 | + |
|
| 1425 | + /** |
|
| 1426 | + * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated |
|
| 1427 | + * |
|
| 1428 | + * @return void |
|
| 1429 | + * @throws EE_Error |
|
| 1430 | + * @throws InvalidArgumentException |
|
| 1431 | + * @throws InvalidDataTypeException |
|
| 1432 | + * @throws InvalidInterfaceException |
|
| 1433 | + * @throws ReflectionException |
|
| 1434 | + */ |
|
| 1435 | + private function _recalculate_tax_sub_total() |
|
| 1436 | + { |
|
| 1437 | + if ($this->is_tax_sub_total()) { |
|
| 1438 | + $total = 0; |
|
| 1439 | + $total_percent = 0; |
|
| 1440 | + // simply loop through all its children (which should be taxes) and sum their total |
|
| 1441 | + foreach ($this->children() as $child_tax) { |
|
| 1442 | + if ($child_tax instanceof EE_Line_Item) { |
|
| 1443 | + $total += $child_tax->total(); |
|
| 1444 | + $total_percent += $child_tax->percent(); |
|
| 1445 | + } |
|
| 1446 | + } |
|
| 1447 | + $this->set_total($total); |
|
| 1448 | + $this->set_percent($total_percent); |
|
| 1449 | + $this->maybe_save(); |
|
| 1450 | + } elseif ($this->is_total()) { |
|
| 1451 | + foreach ($this->children() as $maybe_tax_subtotal) { |
|
| 1452 | + if ($maybe_tax_subtotal instanceof EE_Line_Item) { |
|
| 1453 | + $maybe_tax_subtotal->_recalculate_tax_sub_total(); |
|
| 1454 | + } |
|
| 1455 | + } |
|
| 1456 | + } |
|
| 1457 | + } |
|
| 1458 | + |
|
| 1459 | + |
|
| 1460 | + /** |
|
| 1461 | + * Gets the total tax on this line item. Assumes taxes have already been calculated using |
|
| 1462 | + * recalculate_taxes_and_total |
|
| 1463 | + * |
|
| 1464 | + * @return float |
|
| 1465 | + * @throws EE_Error |
|
| 1466 | + * @throws InvalidArgumentException |
|
| 1467 | + * @throws InvalidDataTypeException |
|
| 1468 | + * @throws InvalidInterfaceException |
|
| 1469 | + * @throws ReflectionException |
|
| 1470 | + */ |
|
| 1471 | + public function get_total_tax() |
|
| 1472 | + { |
|
| 1473 | + $this->_recalculate_tax_sub_total(); |
|
| 1474 | + $total = 0; |
|
| 1475 | + foreach ($this->tax_descendants() as $tax_line_item) { |
|
| 1476 | + if ($tax_line_item instanceof EE_Line_Item) { |
|
| 1477 | + $total += $tax_line_item->total(); |
|
| 1478 | + } |
|
| 1479 | + } |
|
| 1480 | + return $total; |
|
| 1481 | + } |
|
| 1482 | + |
|
| 1483 | + |
|
| 1484 | + /** |
|
| 1485 | + * Gets the total for all the items purchased only |
|
| 1486 | + * |
|
| 1487 | + * @return float |
|
| 1488 | + * @throws EE_Error |
|
| 1489 | + * @throws InvalidArgumentException |
|
| 1490 | + * @throws InvalidDataTypeException |
|
| 1491 | + * @throws InvalidInterfaceException |
|
| 1492 | + * @throws ReflectionException |
|
| 1493 | + */ |
|
| 1494 | + public function get_items_total() |
|
| 1495 | + { |
|
| 1496 | + // by default, let's make sure we're consistent with the existing line item |
|
| 1497 | + if ($this->is_total()) { |
|
| 1498 | + $pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this); |
|
| 1499 | + if ($pretax_subtotal_li instanceof EE_Line_Item) { |
|
| 1500 | + return $pretax_subtotal_li->total(); |
|
| 1501 | + } |
|
| 1502 | + } |
|
| 1503 | + $total = 0; |
|
| 1504 | + foreach ($this->get_items() as $item) { |
|
| 1505 | + if ($item instanceof EE_Line_Item) { |
|
| 1506 | + $total += $item->total(); |
|
| 1507 | + } |
|
| 1508 | + } |
|
| 1509 | + return $total; |
|
| 1510 | + } |
|
| 1511 | + |
|
| 1512 | + |
|
| 1513 | + /** |
|
| 1514 | + * Gets all the descendants (ie, children or children of children etc) that |
|
| 1515 | + * are of the type 'tax' |
|
| 1516 | + * |
|
| 1517 | + * @return EE_Line_Item[] |
|
| 1518 | + * @throws EE_Error |
|
| 1519 | + */ |
|
| 1520 | + public function tax_descendants() |
|
| 1521 | + { |
|
| 1522 | + return EEH_Line_Item::get_tax_descendants($this); |
|
| 1523 | + } |
|
| 1524 | + |
|
| 1525 | + |
|
| 1526 | + /** |
|
| 1527 | + * Gets all the real items purchased which are children of this item |
|
| 1528 | + * |
|
| 1529 | + * @return EE_Line_Item[] |
|
| 1530 | + * @throws EE_Error |
|
| 1531 | + */ |
|
| 1532 | + public function get_items() |
|
| 1533 | + { |
|
| 1534 | + return EEH_Line_Item::get_line_item_descendants($this); |
|
| 1535 | + } |
|
| 1536 | + |
|
| 1537 | + |
|
| 1538 | + /** |
|
| 1539 | + * Returns the amount taxable among this line item's children (or if it has no children, |
|
| 1540 | + * how much of it is taxable). Does not recalculate totals or subtotals. |
|
| 1541 | + * If the taxable total is negative, (eg, if none of the tickets were taxable, |
|
| 1542 | + * but there is a "Taxable" discount), returns 0. |
|
| 1543 | + * |
|
| 1544 | + * @return float |
|
| 1545 | + * @throws EE_Error |
|
| 1546 | + * @throws InvalidArgumentException |
|
| 1547 | + * @throws InvalidDataTypeException |
|
| 1548 | + * @throws InvalidInterfaceException |
|
| 1549 | + * @throws ReflectionException |
|
| 1550 | + */ |
|
| 1551 | + public function taxable_total() |
|
| 1552 | + { |
|
| 1553 | + $total = 0; |
|
| 1554 | + if ($this->children()) { |
|
| 1555 | + foreach ($this->children() as $child_line_item) { |
|
| 1556 | + if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) { |
|
| 1557 | + // if it's a percent item, only take into account the percent |
|
| 1558 | + // that's taxable too (the taxable total so far) |
|
| 1559 | + if ($child_line_item->is_percent()) { |
|
| 1560 | + $total += ($total * $child_line_item->percent() / 100); |
|
| 1561 | + } else { |
|
| 1562 | + $total += $child_line_item->total(); |
|
| 1563 | + } |
|
| 1564 | + } elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) { |
|
| 1565 | + $total += $child_line_item->taxable_total(); |
|
| 1566 | + } |
|
| 1567 | + } |
|
| 1568 | + } |
|
| 1569 | + return max($total, 0); |
|
| 1570 | + } |
|
| 1571 | + |
|
| 1572 | + |
|
| 1573 | + /** |
|
| 1574 | + * Gets the transaction for this line item |
|
| 1575 | + * |
|
| 1576 | + * @return EE_Base_Class|EE_Transaction |
|
| 1577 | + * @throws EE_Error |
|
| 1578 | + * @throws InvalidArgumentException |
|
| 1579 | + * @throws InvalidDataTypeException |
|
| 1580 | + * @throws InvalidInterfaceException |
|
| 1581 | + * @throws ReflectionException |
|
| 1582 | + */ |
|
| 1583 | + public function transaction() |
|
| 1584 | + { |
|
| 1585 | + return $this->get_first_related(EEM_Line_Item::OBJ_TYPE_TRANSACTION); |
|
| 1586 | + } |
|
| 1587 | + |
|
| 1588 | + |
|
| 1589 | + /** |
|
| 1590 | + * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1591 | + * Because there currently is no proper parent-child relation on the model, |
|
| 1592 | + * save_this_and_cached() will NOT save the descendants. |
|
| 1593 | + * Also sets the transaction on this line item and all its descendants before saving |
|
| 1594 | + * |
|
| 1595 | + * @param int $txn_id if none is provided, assumes $this->TXN_ID() |
|
| 1596 | + * @return int count of items saved |
|
| 1597 | + * @throws EE_Error |
|
| 1598 | + * @throws InvalidArgumentException |
|
| 1599 | + * @throws InvalidDataTypeException |
|
| 1600 | + * @throws InvalidInterfaceException |
|
| 1601 | + * @throws ReflectionException |
|
| 1602 | + */ |
|
| 1603 | + public function save_this_and_descendants_to_txn($txn_id = null) |
|
| 1604 | + { |
|
| 1605 | + $count = 0; |
|
| 1606 | + if (! $txn_id) { |
|
| 1607 | + $txn_id = $this->TXN_ID(); |
|
| 1608 | + } |
|
| 1609 | + $this->set_TXN_ID($txn_id); |
|
| 1610 | + $children = $this->children(); |
|
| 1611 | + $count += $this->save() |
|
| 1612 | + ? 1 |
|
| 1613 | + : 0; |
|
| 1614 | + foreach ($children as $child_line_item) { |
|
| 1615 | + if ($child_line_item instanceof EE_Line_Item) { |
|
| 1616 | + $child_line_item->set_parent_ID($this->ID()); |
|
| 1617 | + $count += $child_line_item->save_this_and_descendants_to_txn($txn_id); |
|
| 1618 | + } |
|
| 1619 | + } |
|
| 1620 | + return $count; |
|
| 1621 | + } |
|
| 1622 | + |
|
| 1623 | + |
|
| 1624 | + /** |
|
| 1625 | + * Saves this line item to the DB, and recursively saves its descendants. |
|
| 1626 | + * |
|
| 1627 | + * @return int count of items saved |
|
| 1628 | + * @throws EE_Error |
|
| 1629 | + * @throws InvalidArgumentException |
|
| 1630 | + * @throws InvalidDataTypeException |
|
| 1631 | + * @throws InvalidInterfaceException |
|
| 1632 | + * @throws ReflectionException |
|
| 1633 | + */ |
|
| 1634 | + public function save_this_and_descendants() |
|
| 1635 | + { |
|
| 1636 | + $count = 0; |
|
| 1637 | + $children = $this->children(); |
|
| 1638 | + $count += $this->save() |
|
| 1639 | + ? 1 |
|
| 1640 | + : 0; |
|
| 1641 | + foreach ($children as $child_line_item) { |
|
| 1642 | + if ($child_line_item instanceof EE_Line_Item) { |
|
| 1643 | + $child_line_item->set_parent_ID($this->ID()); |
|
| 1644 | + $count += $child_line_item->save_this_and_descendants(); |
|
| 1645 | + } |
|
| 1646 | + } |
|
| 1647 | + return $count; |
|
| 1648 | + } |
|
| 1649 | + |
|
| 1650 | + |
|
| 1651 | + /** |
|
| 1652 | + * returns the cancellation line item if this item was cancelled |
|
| 1653 | + * |
|
| 1654 | + * @return EE_Line_Item[] |
|
| 1655 | + * @throws InvalidArgumentException |
|
| 1656 | + * @throws InvalidInterfaceException |
|
| 1657 | + * @throws InvalidDataTypeException |
|
| 1658 | + * @throws ReflectionException |
|
| 1659 | + * @throws EE_Error |
|
| 1660 | + */ |
|
| 1661 | + public function get_cancellations() |
|
| 1662 | + { |
|
| 1663 | + EE_Registry::instance()->load_helper('Line_Item'); |
|
| 1664 | + return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation); |
|
| 1665 | + } |
|
| 1666 | + |
|
| 1667 | + |
|
| 1668 | + /** |
|
| 1669 | + * If this item has an ID, then this saves it again to update the db |
|
| 1670 | + * |
|
| 1671 | + * @return int count of items saved |
|
| 1672 | + * @throws EE_Error |
|
| 1673 | + * @throws InvalidArgumentException |
|
| 1674 | + * @throws InvalidDataTypeException |
|
| 1675 | + * @throws InvalidInterfaceException |
|
| 1676 | + * @throws ReflectionException |
|
| 1677 | + */ |
|
| 1678 | + public function maybe_save() |
|
| 1679 | + { |
|
| 1680 | + if ($this->ID()) { |
|
| 1681 | + return $this->save(); |
|
| 1682 | + } |
|
| 1683 | + return false; |
|
| 1684 | + } |
|
| 1685 | + |
|
| 1686 | + |
|
| 1687 | + /** |
|
| 1688 | + * clears the cached children and parent from the line item |
|
| 1689 | + * |
|
| 1690 | + * @return void |
|
| 1691 | + */ |
|
| 1692 | + public function clear_related_line_item_cache() |
|
| 1693 | + { |
|
| 1694 | + $this->_children = array(); |
|
| 1695 | + $this->_parent = null; |
|
| 1696 | + } |
|
| 1697 | + |
|
| 1698 | + |
|
| 1699 | + /** |
|
| 1700 | + * @param bool $raw |
|
| 1701 | + * @return int |
|
| 1702 | + * @throws EE_Error |
|
| 1703 | + * @throws InvalidArgumentException |
|
| 1704 | + * @throws InvalidDataTypeException |
|
| 1705 | + * @throws InvalidInterfaceException |
|
| 1706 | + * @throws ReflectionException |
|
| 1707 | + */ |
|
| 1708 | + public function timestamp($raw = false) |
|
| 1709 | + { |
|
| 1710 | + return $raw |
|
| 1711 | + ? $this->get_raw('LIN_timestamp') |
|
| 1712 | + : $this->get('LIN_timestamp'); |
|
| 1713 | + } |
|
| 1714 | + |
|
| 1715 | + |
|
| 1716 | + |
|
| 1717 | + |
|
| 1718 | + /************************* DEPRECATED *************************/ |
|
| 1719 | + /** |
|
| 1720 | + * @deprecated 4.6.0 |
|
| 1721 | + * @param string $type one of the constants on EEM_Line_Item |
|
| 1722 | + * @return EE_Line_Item[] |
|
| 1723 | + * @throws EE_Error |
|
| 1724 | + */ |
|
| 1725 | + protected function _get_descendants_of_type($type) |
|
| 1726 | + { |
|
| 1727 | + EE_Error::doing_it_wrong( |
|
| 1728 | + 'EE_Line_Item::_get_descendants_of_type()', |
|
| 1729 | + sprintf( |
|
| 1730 | + esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
| 1731 | + 'EEH_Line_Item::get_descendants_of_type()' |
|
| 1732 | + ), |
|
| 1733 | + '4.6.0' |
|
| 1734 | + ); |
|
| 1735 | + return EEH_Line_Item::get_descendants_of_type($this, $type); |
|
| 1736 | + } |
|
| 1737 | + |
|
| 1738 | + |
|
| 1739 | + /** |
|
| 1740 | + * @deprecated 4.6.0 |
|
| 1741 | + * @param string $type like one of the EEM_Line_Item::type_* |
|
| 1742 | + * @return EE_Line_Item |
|
| 1743 | + * @throws EE_Error |
|
| 1744 | + * @throws InvalidArgumentException |
|
| 1745 | + * @throws InvalidDataTypeException |
|
| 1746 | + * @throws InvalidInterfaceException |
|
| 1747 | + * @throws ReflectionException |
|
| 1748 | + */ |
|
| 1749 | + public function get_nearest_descendant_of_type($type) |
|
| 1750 | + { |
|
| 1751 | + EE_Error::doing_it_wrong( |
|
| 1752 | + 'EE_Line_Item::get_nearest_descendant_of_type()', |
|
| 1753 | + sprintf( |
|
| 1754 | + esc_html__('Method replaced with %1$s', 'event_espresso'), |
|
| 1755 | + 'EEH_Line_Item::get_nearest_descendant_of_type()' |
|
| 1756 | + ), |
|
| 1757 | + '4.6.0' |
|
| 1758 | + ); |
|
| 1759 | + return EEH_Line_Item::get_nearest_descendant_of_type($this, $type); |
|
| 1760 | + } |
|
| 1761 | 1761 | } |
@@ -14,40 +14,40 @@ |
||
| 14 | 14 | class EE_Currency_Payment_Method extends EE_Base_Class |
| 15 | 15 | { |
| 16 | 16 | |
| 17 | - /** Currency to Payment Method Link ID @var CPM_ID */ |
|
| 18 | - protected $_CPM_ID = null; |
|
| 19 | - /** Currency Code @var CUR_code */ |
|
| 20 | - protected $_CUR_code = null; |
|
| 21 | - /** Payment Method ID @var PMD_ID */ |
|
| 22 | - protected $_PMD_ID = null; |
|
| 23 | - protected $_Payment_Method; |
|
| 24 | - protected $_Currency; |
|
| 17 | + /** Currency to Payment Method Link ID @var CPM_ID */ |
|
| 18 | + protected $_CPM_ID = null; |
|
| 19 | + /** Currency Code @var CUR_code */ |
|
| 20 | + protected $_CUR_code = null; |
|
| 21 | + /** Payment Method ID @var PMD_ID */ |
|
| 22 | + protected $_PMD_ID = null; |
|
| 23 | + protected $_Payment_Method; |
|
| 24 | + protected $_Currency; |
|
| 25 | 25 | |
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * |
|
| 29 | - * @param array $props_n_values incoming values |
|
| 30 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 31 | - * used.) |
|
| 32 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 33 | - * date_format and the second value is the time format |
|
| 34 | - * @return EE_Attendee |
|
| 35 | - */ |
|
| 36 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 37 | - { |
|
| 38 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 39 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 40 | - } |
|
| 27 | + /** |
|
| 28 | + * |
|
| 29 | + * @param array $props_n_values incoming values |
|
| 30 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 31 | + * used.) |
|
| 32 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 33 | + * date_format and the second value is the time format |
|
| 34 | + * @return EE_Attendee |
|
| 35 | + */ |
|
| 36 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 37 | + { |
|
| 38 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 39 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 40 | + } |
|
| 41 | 41 | |
| 42 | 42 | |
| 43 | - /** |
|
| 44 | - * @param array $props_n_values incoming values from the database |
|
| 45 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 46 | - * the website will be used. |
|
| 47 | - * @return EE_Attendee |
|
| 48 | - */ |
|
| 49 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 50 | - { |
|
| 51 | - return new self($props_n_values, true, $timezone); |
|
| 52 | - } |
|
| 43 | + /** |
|
| 44 | + * @param array $props_n_values incoming values from the database |
|
| 45 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 46 | + * the website will be used. |
|
| 47 | + * @return EE_Attendee |
|
| 48 | + */ |
|
| 49 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 50 | + { |
|
| 51 | + return new self($props_n_values, true, $timezone); |
|
| 52 | + } |
|
| 53 | 53 | } |
@@ -12,25 +12,25 @@ |
||
| 12 | 12 | class EE_Event_Message_Template extends EE_Base_Class |
| 13 | 13 | { |
| 14 | 14 | |
| 15 | - /** |
|
| 16 | - * @param array $props_n_values |
|
| 17 | - * @param null $timezone |
|
| 18 | - * @return EE_Event_Message_Template|mixed |
|
| 19 | - */ |
|
| 20 | - public static function new_instance($props_n_values = array(), $timezone = '') |
|
| 21 | - { |
|
| 22 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone); |
|
| 23 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone); |
|
| 24 | - } |
|
| 15 | + /** |
|
| 16 | + * @param array $props_n_values |
|
| 17 | + * @param null $timezone |
|
| 18 | + * @return EE_Event_Message_Template|mixed |
|
| 19 | + */ |
|
| 20 | + public static function new_instance($props_n_values = array(), $timezone = '') |
|
| 21 | + { |
|
| 22 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone); |
|
| 23 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone); |
|
| 24 | + } |
|
| 25 | 25 | |
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * @param array $props_n_values |
|
| 29 | - * @param null $timezone |
|
| 30 | - * @return EE_Event_Message_Template |
|
| 31 | - */ |
|
| 32 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 33 | - { |
|
| 34 | - return new self($props_n_values, true, $timezone); |
|
| 35 | - } |
|
| 27 | + /** |
|
| 28 | + * @param array $props_n_values |
|
| 29 | + * @param null $timezone |
|
| 30 | + * @return EE_Event_Message_Template |
|
| 31 | + */ |
|
| 32 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 33 | + { |
|
| 34 | + return new self($props_n_values, true, $timezone); |
|
| 35 | + } |
|
| 36 | 36 | } |
@@ -10,564 +10,564 @@ |
||
| 10 | 10 | class EE_Venue extends EE_CPT_Base implements EEI_Address |
| 11 | 11 | { |
| 12 | 12 | |
| 13 | - /** |
|
| 14 | - * |
|
| 15 | - * @param array $props_n_values incoming values |
|
| 16 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 17 | - * used.) |
|
| 18 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 19 | - * date_format and the second value is the time format |
|
| 20 | - * @return EE_Attendee |
|
| 21 | - */ |
|
| 22 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 23 | - { |
|
| 24 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 25 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 26 | - } |
|
| 27 | - |
|
| 28 | - |
|
| 29 | - /** |
|
| 30 | - * @param array $props_n_values incoming values from the database |
|
| 31 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 32 | - * the website will be used. |
|
| 33 | - * @return EE_Attendee |
|
| 34 | - */ |
|
| 35 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 36 | - { |
|
| 37 | - return new self($props_n_values, true, $timezone); |
|
| 38 | - } |
|
| 39 | - |
|
| 40 | - |
|
| 41 | - /** |
|
| 42 | - * Gets name |
|
| 43 | - * |
|
| 44 | - * @return string |
|
| 45 | - */ |
|
| 46 | - public function name() |
|
| 47 | - { |
|
| 48 | - return $this->get('VNU_name'); |
|
| 49 | - } |
|
| 50 | - |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * Gets phone |
|
| 54 | - * |
|
| 55 | - * @return string |
|
| 56 | - */ |
|
| 57 | - public function phone() |
|
| 58 | - { |
|
| 59 | - return $this->get('VNU_phone'); |
|
| 60 | - } |
|
| 61 | - |
|
| 62 | - |
|
| 63 | - /** |
|
| 64 | - * venue_url |
|
| 65 | - * |
|
| 66 | - * @return string |
|
| 67 | - */ |
|
| 68 | - public function venue_url() |
|
| 69 | - { |
|
| 70 | - return $this->get('VNU_url'); |
|
| 71 | - } |
|
| 72 | - |
|
| 73 | - |
|
| 74 | - /** |
|
| 75 | - * Gets desc |
|
| 76 | - * |
|
| 77 | - * @return string |
|
| 78 | - */ |
|
| 79 | - public function description() |
|
| 80 | - { |
|
| 81 | - return $this->get('VNU_desc'); |
|
| 82 | - } |
|
| 83 | - |
|
| 84 | - |
|
| 85 | - /** |
|
| 86 | - * Gets short description (AKA: the excerpt) |
|
| 87 | - * |
|
| 88 | - * @return string |
|
| 89 | - */ |
|
| 90 | - public function excerpt() |
|
| 91 | - { |
|
| 92 | - return $this->get('VNU_short_desc'); |
|
| 93 | - } |
|
| 94 | - |
|
| 95 | - |
|
| 96 | - /** |
|
| 97 | - * Gets identifier |
|
| 98 | - * |
|
| 99 | - * @return string |
|
| 100 | - */ |
|
| 101 | - public function identifier() |
|
| 102 | - { |
|
| 103 | - return $this->get('VNU_identifier'); |
|
| 104 | - } |
|
| 105 | - |
|
| 106 | - |
|
| 107 | - /** |
|
| 108 | - * Gets address |
|
| 109 | - * |
|
| 110 | - * @return string |
|
| 111 | - */ |
|
| 112 | - public function address() |
|
| 113 | - { |
|
| 114 | - return $this->get('VNU_address'); |
|
| 115 | - } |
|
| 116 | - |
|
| 117 | - |
|
| 118 | - /** |
|
| 119 | - * Gets address2 |
|
| 120 | - * |
|
| 121 | - * @return string |
|
| 122 | - */ |
|
| 123 | - public function address2() |
|
| 124 | - { |
|
| 125 | - return $this->get('VNU_address2'); |
|
| 126 | - } |
|
| 127 | - |
|
| 128 | - |
|
| 129 | - /** |
|
| 130 | - * Gets city |
|
| 131 | - * |
|
| 132 | - * @return string |
|
| 133 | - */ |
|
| 134 | - public function city() |
|
| 135 | - { |
|
| 136 | - return $this->get('VNU_city'); |
|
| 137 | - } |
|
| 138 | - |
|
| 139 | - /** |
|
| 140 | - * Gets state |
|
| 141 | - * |
|
| 142 | - * @return int |
|
| 143 | - */ |
|
| 144 | - public function state_ID() |
|
| 145 | - { |
|
| 146 | - return $this->get('STA_ID'); |
|
| 147 | - } |
|
| 148 | - |
|
| 149 | - |
|
| 150 | - /** |
|
| 151 | - * @return string |
|
| 152 | - */ |
|
| 153 | - public function state_abbrev() |
|
| 154 | - { |
|
| 155 | - return $this->state_obj() instanceof EE_State ? $this->state_obj()->abbrev() : ''; |
|
| 156 | - } |
|
| 157 | - |
|
| 158 | - |
|
| 159 | - /** |
|
| 160 | - * @return string |
|
| 161 | - */ |
|
| 162 | - public function state_name() |
|
| 163 | - { |
|
| 164 | - return $this->state_obj() instanceof EE_State ? $this->state_obj()->name() : ''; |
|
| 165 | - } |
|
| 166 | - |
|
| 167 | - |
|
| 168 | - /** |
|
| 169 | - * Gets the state for this venue |
|
| 170 | - * |
|
| 171 | - * @return EE_State |
|
| 172 | - */ |
|
| 173 | - public function state_obj() |
|
| 174 | - { |
|
| 175 | - return $this->get_first_related('State'); |
|
| 176 | - } |
|
| 177 | - |
|
| 178 | - |
|
| 179 | - /** |
|
| 180 | - * either displays the state abbreviation or the state name, as determined |
|
| 181 | - * by the "FHEE__EEI_Address__state__use_abbreviation" filter. |
|
| 182 | - * defaults to abbreviation |
|
| 183 | - * |
|
| 184 | - * @return string |
|
| 185 | - */ |
|
| 186 | - public function state() |
|
| 187 | - { |
|
| 188 | - if (apply_filters('FHEE__EEI_Address__state__use_abbreviation', true, $this->state_obj())) { |
|
| 189 | - return $this->state_abbrev(); |
|
| 190 | - } else { |
|
| 191 | - return $this->state_name(); |
|
| 192 | - } |
|
| 193 | - } |
|
| 194 | - |
|
| 195 | - |
|
| 196 | - /** |
|
| 197 | - * country_ID |
|
| 198 | - * |
|
| 199 | - * @return string |
|
| 200 | - */ |
|
| 201 | - public function country_ID() |
|
| 202 | - { |
|
| 203 | - return $this->get('CNT_ISO'); |
|
| 204 | - } |
|
| 205 | - |
|
| 206 | - |
|
| 207 | - /** |
|
| 208 | - * @return string |
|
| 209 | - */ |
|
| 210 | - public function country_name() |
|
| 211 | - { |
|
| 212 | - return $this->country_obj() instanceof EE_Country ? $this->country_obj()->name() : ''; |
|
| 213 | - } |
|
| 214 | - |
|
| 215 | - |
|
| 216 | - /** |
|
| 217 | - * Gets the country of this venue |
|
| 218 | - * |
|
| 219 | - * @return EE_Country |
|
| 220 | - */ |
|
| 221 | - public function country_obj() |
|
| 222 | - { |
|
| 223 | - return $this->get_first_related('Country'); |
|
| 224 | - } |
|
| 225 | - |
|
| 226 | - |
|
| 227 | - /** |
|
| 228 | - * either displays the country ISO2 code or the country name, as determined |
|
| 229 | - * by the "FHEE__EEI_Address__country__use_abbreviation" filter. |
|
| 230 | - * defaults to abbreviation |
|
| 231 | - * |
|
| 232 | - * @return string |
|
| 233 | - */ |
|
| 234 | - public function country() |
|
| 235 | - { |
|
| 236 | - if (apply_filters('FHEE__EEI_Address__country__use_abbreviation', true, $this->country_obj())) { |
|
| 237 | - return $this->country_ID(); |
|
| 238 | - } else { |
|
| 239 | - return $this->country_name(); |
|
| 240 | - } |
|
| 241 | - } |
|
| 242 | - |
|
| 243 | - |
|
| 244 | - /** |
|
| 245 | - * Gets zip |
|
| 246 | - * |
|
| 247 | - * @return string |
|
| 248 | - */ |
|
| 249 | - public function zip() |
|
| 250 | - { |
|
| 251 | - return $this->get('VNU_zip'); |
|
| 252 | - } |
|
| 253 | - |
|
| 254 | - |
|
| 255 | - /** |
|
| 256 | - * Gets capacity |
|
| 257 | - * |
|
| 258 | - * @return int |
|
| 259 | - */ |
|
| 260 | - public function capacity() |
|
| 261 | - { |
|
| 262 | - return $this->get_pretty('VNU_capacity', 'symbol'); |
|
| 263 | - } |
|
| 264 | - |
|
| 265 | - |
|
| 266 | - /** |
|
| 267 | - * Gets created |
|
| 268 | - * |
|
| 269 | - * @return string |
|
| 270 | - */ |
|
| 271 | - public function created() |
|
| 272 | - { |
|
| 273 | - return $this->get('VNU_created'); |
|
| 274 | - } |
|
| 275 | - |
|
| 276 | - |
|
| 277 | - /** |
|
| 278 | - * Gets modified |
|
| 279 | - * |
|
| 280 | - * @return string |
|
| 281 | - */ |
|
| 282 | - public function modified() |
|
| 283 | - { |
|
| 284 | - return $this->get('VNU_modified'); |
|
| 285 | - } |
|
| 286 | - |
|
| 287 | - |
|
| 288 | - /** |
|
| 289 | - * Gets order |
|
| 290 | - * |
|
| 291 | - * @return int |
|
| 292 | - */ |
|
| 293 | - public function order() |
|
| 294 | - { |
|
| 295 | - return $this->get('VNU_order'); |
|
| 296 | - } |
|
| 297 | - |
|
| 298 | - |
|
| 299 | - /** |
|
| 300 | - * Gets wp_user |
|
| 301 | - * |
|
| 302 | - * @return int |
|
| 303 | - */ |
|
| 304 | - public function wp_user() |
|
| 305 | - { |
|
| 306 | - return $this->get('VNU_wp_user'); |
|
| 307 | - } |
|
| 308 | - |
|
| 309 | - |
|
| 310 | - /** |
|
| 311 | - * @return string |
|
| 312 | - */ |
|
| 313 | - public function virtual_phone() |
|
| 314 | - { |
|
| 315 | - return $this->get('VNU_virtual_phone'); |
|
| 316 | - } |
|
| 317 | - |
|
| 318 | - |
|
| 319 | - /** |
|
| 320 | - * @return string |
|
| 321 | - */ |
|
| 322 | - public function virtual_url() |
|
| 323 | - { |
|
| 324 | - return $this->get('VNU_virtual_url'); |
|
| 325 | - } |
|
| 326 | - |
|
| 327 | - |
|
| 328 | - /** |
|
| 329 | - * @return bool |
|
| 330 | - */ |
|
| 331 | - public function enable_for_gmap() |
|
| 332 | - { |
|
| 333 | - return $this->get('VNU_enable_for_gmap'); |
|
| 334 | - } |
|
| 335 | - |
|
| 336 | - |
|
| 337 | - /** |
|
| 338 | - * @return string |
|
| 339 | - */ |
|
| 340 | - public function google_map_link() |
|
| 341 | - { |
|
| 342 | - return $this->get('VNU_google_map_link'); |
|
| 343 | - } |
|
| 344 | - |
|
| 345 | - |
|
| 346 | - /** |
|
| 347 | - * Gets all events happening at this venue. Query parameters can be added to |
|
| 348 | - * fetch a subset of those events. |
|
| 349 | - * |
|
| 350 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 351 | - * @param bool $upcoming |
|
| 352 | - * @return EE_Event[] |
|
| 353 | - */ |
|
| 354 | - public function events($query_params = array(), $upcoming = false) |
|
| 355 | - { |
|
| 356 | - if ($upcoming) { |
|
| 357 | - $query_params = array( |
|
| 358 | - array( |
|
| 359 | - 'status' => 'publish', |
|
| 360 | - 'Datetime.DTT_EVT_start' => array( |
|
| 361 | - '>', |
|
| 362 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
| 363 | - ), |
|
| 364 | - ), |
|
| 365 | - ); |
|
| 366 | - } |
|
| 367 | - return $this->get_many_related('Event', $query_params); |
|
| 368 | - } |
|
| 369 | - |
|
| 370 | - |
|
| 371 | - /** |
|
| 372 | - * Sets address |
|
| 373 | - */ |
|
| 374 | - public function set_address($address = '') |
|
| 375 | - { |
|
| 376 | - $this->set('VNU_address', $address); |
|
| 377 | - } |
|
| 378 | - |
|
| 379 | - |
|
| 380 | - /** |
|
| 381 | - * @param string $address2 |
|
| 382 | - */ |
|
| 383 | - public function set_address2($address2 = '') |
|
| 384 | - { |
|
| 385 | - $this->set('VNU_address2', $address2); |
|
| 386 | - } |
|
| 387 | - |
|
| 388 | - |
|
| 389 | - /** |
|
| 390 | - * @param string $city |
|
| 391 | - */ |
|
| 392 | - public function set_city($city = '') |
|
| 393 | - { |
|
| 394 | - $this->set('VNU_city', $city); |
|
| 395 | - } |
|
| 396 | - |
|
| 397 | - |
|
| 398 | - /** |
|
| 399 | - * @param int $state |
|
| 400 | - */ |
|
| 401 | - public function set_state_ID($state = 0) |
|
| 402 | - { |
|
| 403 | - $this->set('STA_ID', $state); |
|
| 404 | - } |
|
| 405 | - |
|
| 406 | - |
|
| 407 | - /** |
|
| 408 | - * Sets the state, given either a state id or state object |
|
| 409 | - * |
|
| 410 | - * @param EE_State /int $state_id_or_obj |
|
| 411 | - * @return EE_State |
|
| 412 | - */ |
|
| 413 | - public function set_state_obj($state_id_or_obj) |
|
| 414 | - { |
|
| 415 | - return $this->_add_relation_to($state_id_or_obj, 'State'); |
|
| 416 | - } |
|
| 417 | - |
|
| 418 | - |
|
| 419 | - /** |
|
| 420 | - * @param int $country_ID |
|
| 421 | - */ |
|
| 422 | - public function set_country_ID($country_ID = 0) |
|
| 423 | - { |
|
| 424 | - $this->set('CNT_ISO', $country_ID); |
|
| 425 | - } |
|
| 426 | - |
|
| 427 | - |
|
| 428 | - /** |
|
| 429 | - * Sets the country on the venue |
|
| 430 | - * |
|
| 431 | - * @param EE_Country /string $country_id_or_obj |
|
| 432 | - * @return EE_Country |
|
| 433 | - */ |
|
| 434 | - public function set_country_obj($country_id_or_obj) |
|
| 435 | - { |
|
| 436 | - return $this->_add_relation_to($country_id_or_obj, 'Country'); |
|
| 437 | - } |
|
| 438 | - |
|
| 439 | - |
|
| 440 | - /** |
|
| 441 | - * @param string $zip |
|
| 442 | - */ |
|
| 443 | - public function set_zip($zip = '') |
|
| 444 | - { |
|
| 445 | - $this->set('VNU_zip', $zip); |
|
| 446 | - } |
|
| 447 | - |
|
| 448 | - |
|
| 449 | - /** |
|
| 450 | - * @param int $capacity |
|
| 451 | - */ |
|
| 452 | - public function set_capacity($capacity = 0) |
|
| 453 | - { |
|
| 454 | - $this->set('VNU_capacity', $capacity); |
|
| 455 | - } |
|
| 456 | - |
|
| 457 | - |
|
| 458 | - /** |
|
| 459 | - * @param string $created |
|
| 460 | - */ |
|
| 461 | - public function set_created($created = '') |
|
| 462 | - { |
|
| 463 | - $this->set('VNU_created', $created); |
|
| 464 | - } |
|
| 465 | - |
|
| 466 | - |
|
| 467 | - /** |
|
| 468 | - * @param string $desc |
|
| 469 | - */ |
|
| 470 | - public function set_description($desc = '') |
|
| 471 | - { |
|
| 472 | - $this->set('VNU_desc', $desc); |
|
| 473 | - } |
|
| 474 | - |
|
| 475 | - |
|
| 476 | - /** |
|
| 477 | - * @param string $identifier |
|
| 478 | - */ |
|
| 479 | - public function set_identifier($identifier = '') |
|
| 480 | - { |
|
| 481 | - $this->set('VNU_identifier', $identifier); |
|
| 482 | - } |
|
| 483 | - |
|
| 484 | - |
|
| 485 | - /** |
|
| 486 | - * @param string $modified |
|
| 487 | - */ |
|
| 488 | - public function set_modified($modified = '') |
|
| 489 | - { |
|
| 490 | - $this->set('VNU_modified', $modified); |
|
| 491 | - } |
|
| 492 | - |
|
| 493 | - |
|
| 494 | - /** |
|
| 495 | - * @param string $name |
|
| 496 | - */ |
|
| 497 | - public function set_name($name = '') |
|
| 498 | - { |
|
| 499 | - $this->set('VNU_name', $name); |
|
| 500 | - } |
|
| 501 | - |
|
| 502 | - |
|
| 503 | - /** |
|
| 504 | - * @param int $order |
|
| 505 | - */ |
|
| 506 | - public function set_order($order = 0) |
|
| 507 | - { |
|
| 508 | - $this->set('VNU_order', $order); |
|
| 509 | - } |
|
| 510 | - |
|
| 511 | - |
|
| 512 | - /** |
|
| 513 | - * @param string $phone |
|
| 514 | - */ |
|
| 515 | - public function set_phone($phone = '') |
|
| 516 | - { |
|
| 517 | - $this->set('VNU_phone', $phone); |
|
| 518 | - } |
|
| 519 | - |
|
| 520 | - |
|
| 521 | - /** |
|
| 522 | - * @param int $wp_user |
|
| 523 | - */ |
|
| 524 | - public function set_wp_user($wp_user = 1) |
|
| 525 | - { |
|
| 526 | - $this->set('VNU_wp_user', $wp_user); |
|
| 527 | - } |
|
| 528 | - |
|
| 529 | - |
|
| 530 | - /** |
|
| 531 | - * @param string $url |
|
| 532 | - */ |
|
| 533 | - public function set_venue_url($url = '') |
|
| 534 | - { |
|
| 535 | - $this->set('VNU_url', $url); |
|
| 536 | - } |
|
| 537 | - |
|
| 538 | - |
|
| 539 | - /** |
|
| 540 | - * @param string $phone |
|
| 541 | - */ |
|
| 542 | - public function set_virtual_phone($phone = '') |
|
| 543 | - { |
|
| 544 | - $this->set('VNU_virtual_phone', $phone); |
|
| 545 | - } |
|
| 546 | - |
|
| 547 | - |
|
| 548 | - /** |
|
| 549 | - * @param string $url |
|
| 550 | - */ |
|
| 551 | - public function set_virtual_url($url = '') |
|
| 552 | - { |
|
| 553 | - $this->set('VNU_virtual_url', $url); |
|
| 554 | - } |
|
| 555 | - |
|
| 556 | - |
|
| 557 | - /** |
|
| 558 | - * @param string $enable |
|
| 559 | - */ |
|
| 560 | - public function set_enable_for_gmap($enable = '') |
|
| 561 | - { |
|
| 562 | - $this->set('VNU_enable_for_gmap', $enable); |
|
| 563 | - } |
|
| 564 | - |
|
| 565 | - |
|
| 566 | - /** |
|
| 567 | - * @param string $google_map_link |
|
| 568 | - */ |
|
| 569 | - public function set_google_map_link($google_map_link = '') |
|
| 570 | - { |
|
| 571 | - $this->set('VNU_google_map_link', $google_map_link); |
|
| 572 | - } |
|
| 13 | + /** |
|
| 14 | + * |
|
| 15 | + * @param array $props_n_values incoming values |
|
| 16 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 17 | + * used.) |
|
| 18 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 19 | + * date_format and the second value is the time format |
|
| 20 | + * @return EE_Attendee |
|
| 21 | + */ |
|
| 22 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 23 | + { |
|
| 24 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 25 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 26 | + } |
|
| 27 | + |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * @param array $props_n_values incoming values from the database |
|
| 31 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 32 | + * the website will be used. |
|
| 33 | + * @return EE_Attendee |
|
| 34 | + */ |
|
| 35 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 36 | + { |
|
| 37 | + return new self($props_n_values, true, $timezone); |
|
| 38 | + } |
|
| 39 | + |
|
| 40 | + |
|
| 41 | + /** |
|
| 42 | + * Gets name |
|
| 43 | + * |
|
| 44 | + * @return string |
|
| 45 | + */ |
|
| 46 | + public function name() |
|
| 47 | + { |
|
| 48 | + return $this->get('VNU_name'); |
|
| 49 | + } |
|
| 50 | + |
|
| 51 | + |
|
| 52 | + /** |
|
| 53 | + * Gets phone |
|
| 54 | + * |
|
| 55 | + * @return string |
|
| 56 | + */ |
|
| 57 | + public function phone() |
|
| 58 | + { |
|
| 59 | + return $this->get('VNU_phone'); |
|
| 60 | + } |
|
| 61 | + |
|
| 62 | + |
|
| 63 | + /** |
|
| 64 | + * venue_url |
|
| 65 | + * |
|
| 66 | + * @return string |
|
| 67 | + */ |
|
| 68 | + public function venue_url() |
|
| 69 | + { |
|
| 70 | + return $this->get('VNU_url'); |
|
| 71 | + } |
|
| 72 | + |
|
| 73 | + |
|
| 74 | + /** |
|
| 75 | + * Gets desc |
|
| 76 | + * |
|
| 77 | + * @return string |
|
| 78 | + */ |
|
| 79 | + public function description() |
|
| 80 | + { |
|
| 81 | + return $this->get('VNU_desc'); |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + |
|
| 85 | + /** |
|
| 86 | + * Gets short description (AKA: the excerpt) |
|
| 87 | + * |
|
| 88 | + * @return string |
|
| 89 | + */ |
|
| 90 | + public function excerpt() |
|
| 91 | + { |
|
| 92 | + return $this->get('VNU_short_desc'); |
|
| 93 | + } |
|
| 94 | + |
|
| 95 | + |
|
| 96 | + /** |
|
| 97 | + * Gets identifier |
|
| 98 | + * |
|
| 99 | + * @return string |
|
| 100 | + */ |
|
| 101 | + public function identifier() |
|
| 102 | + { |
|
| 103 | + return $this->get('VNU_identifier'); |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + |
|
| 107 | + /** |
|
| 108 | + * Gets address |
|
| 109 | + * |
|
| 110 | + * @return string |
|
| 111 | + */ |
|
| 112 | + public function address() |
|
| 113 | + { |
|
| 114 | + return $this->get('VNU_address'); |
|
| 115 | + } |
|
| 116 | + |
|
| 117 | + |
|
| 118 | + /** |
|
| 119 | + * Gets address2 |
|
| 120 | + * |
|
| 121 | + * @return string |
|
| 122 | + */ |
|
| 123 | + public function address2() |
|
| 124 | + { |
|
| 125 | + return $this->get('VNU_address2'); |
|
| 126 | + } |
|
| 127 | + |
|
| 128 | + |
|
| 129 | + /** |
|
| 130 | + * Gets city |
|
| 131 | + * |
|
| 132 | + * @return string |
|
| 133 | + */ |
|
| 134 | + public function city() |
|
| 135 | + { |
|
| 136 | + return $this->get('VNU_city'); |
|
| 137 | + } |
|
| 138 | + |
|
| 139 | + /** |
|
| 140 | + * Gets state |
|
| 141 | + * |
|
| 142 | + * @return int |
|
| 143 | + */ |
|
| 144 | + public function state_ID() |
|
| 145 | + { |
|
| 146 | + return $this->get('STA_ID'); |
|
| 147 | + } |
|
| 148 | + |
|
| 149 | + |
|
| 150 | + /** |
|
| 151 | + * @return string |
|
| 152 | + */ |
|
| 153 | + public function state_abbrev() |
|
| 154 | + { |
|
| 155 | + return $this->state_obj() instanceof EE_State ? $this->state_obj()->abbrev() : ''; |
|
| 156 | + } |
|
| 157 | + |
|
| 158 | + |
|
| 159 | + /** |
|
| 160 | + * @return string |
|
| 161 | + */ |
|
| 162 | + public function state_name() |
|
| 163 | + { |
|
| 164 | + return $this->state_obj() instanceof EE_State ? $this->state_obj()->name() : ''; |
|
| 165 | + } |
|
| 166 | + |
|
| 167 | + |
|
| 168 | + /** |
|
| 169 | + * Gets the state for this venue |
|
| 170 | + * |
|
| 171 | + * @return EE_State |
|
| 172 | + */ |
|
| 173 | + public function state_obj() |
|
| 174 | + { |
|
| 175 | + return $this->get_first_related('State'); |
|
| 176 | + } |
|
| 177 | + |
|
| 178 | + |
|
| 179 | + /** |
|
| 180 | + * either displays the state abbreviation or the state name, as determined |
|
| 181 | + * by the "FHEE__EEI_Address__state__use_abbreviation" filter. |
|
| 182 | + * defaults to abbreviation |
|
| 183 | + * |
|
| 184 | + * @return string |
|
| 185 | + */ |
|
| 186 | + public function state() |
|
| 187 | + { |
|
| 188 | + if (apply_filters('FHEE__EEI_Address__state__use_abbreviation', true, $this->state_obj())) { |
|
| 189 | + return $this->state_abbrev(); |
|
| 190 | + } else { |
|
| 191 | + return $this->state_name(); |
|
| 192 | + } |
|
| 193 | + } |
|
| 194 | + |
|
| 195 | + |
|
| 196 | + /** |
|
| 197 | + * country_ID |
|
| 198 | + * |
|
| 199 | + * @return string |
|
| 200 | + */ |
|
| 201 | + public function country_ID() |
|
| 202 | + { |
|
| 203 | + return $this->get('CNT_ISO'); |
|
| 204 | + } |
|
| 205 | + |
|
| 206 | + |
|
| 207 | + /** |
|
| 208 | + * @return string |
|
| 209 | + */ |
|
| 210 | + public function country_name() |
|
| 211 | + { |
|
| 212 | + return $this->country_obj() instanceof EE_Country ? $this->country_obj()->name() : ''; |
|
| 213 | + } |
|
| 214 | + |
|
| 215 | + |
|
| 216 | + /** |
|
| 217 | + * Gets the country of this venue |
|
| 218 | + * |
|
| 219 | + * @return EE_Country |
|
| 220 | + */ |
|
| 221 | + public function country_obj() |
|
| 222 | + { |
|
| 223 | + return $this->get_first_related('Country'); |
|
| 224 | + } |
|
| 225 | + |
|
| 226 | + |
|
| 227 | + /** |
|
| 228 | + * either displays the country ISO2 code or the country name, as determined |
|
| 229 | + * by the "FHEE__EEI_Address__country__use_abbreviation" filter. |
|
| 230 | + * defaults to abbreviation |
|
| 231 | + * |
|
| 232 | + * @return string |
|
| 233 | + */ |
|
| 234 | + public function country() |
|
| 235 | + { |
|
| 236 | + if (apply_filters('FHEE__EEI_Address__country__use_abbreviation', true, $this->country_obj())) { |
|
| 237 | + return $this->country_ID(); |
|
| 238 | + } else { |
|
| 239 | + return $this->country_name(); |
|
| 240 | + } |
|
| 241 | + } |
|
| 242 | + |
|
| 243 | + |
|
| 244 | + /** |
|
| 245 | + * Gets zip |
|
| 246 | + * |
|
| 247 | + * @return string |
|
| 248 | + */ |
|
| 249 | + public function zip() |
|
| 250 | + { |
|
| 251 | + return $this->get('VNU_zip'); |
|
| 252 | + } |
|
| 253 | + |
|
| 254 | + |
|
| 255 | + /** |
|
| 256 | + * Gets capacity |
|
| 257 | + * |
|
| 258 | + * @return int |
|
| 259 | + */ |
|
| 260 | + public function capacity() |
|
| 261 | + { |
|
| 262 | + return $this->get_pretty('VNU_capacity', 'symbol'); |
|
| 263 | + } |
|
| 264 | + |
|
| 265 | + |
|
| 266 | + /** |
|
| 267 | + * Gets created |
|
| 268 | + * |
|
| 269 | + * @return string |
|
| 270 | + */ |
|
| 271 | + public function created() |
|
| 272 | + { |
|
| 273 | + return $this->get('VNU_created'); |
|
| 274 | + } |
|
| 275 | + |
|
| 276 | + |
|
| 277 | + /** |
|
| 278 | + * Gets modified |
|
| 279 | + * |
|
| 280 | + * @return string |
|
| 281 | + */ |
|
| 282 | + public function modified() |
|
| 283 | + { |
|
| 284 | + return $this->get('VNU_modified'); |
|
| 285 | + } |
|
| 286 | + |
|
| 287 | + |
|
| 288 | + /** |
|
| 289 | + * Gets order |
|
| 290 | + * |
|
| 291 | + * @return int |
|
| 292 | + */ |
|
| 293 | + public function order() |
|
| 294 | + { |
|
| 295 | + return $this->get('VNU_order'); |
|
| 296 | + } |
|
| 297 | + |
|
| 298 | + |
|
| 299 | + /** |
|
| 300 | + * Gets wp_user |
|
| 301 | + * |
|
| 302 | + * @return int |
|
| 303 | + */ |
|
| 304 | + public function wp_user() |
|
| 305 | + { |
|
| 306 | + return $this->get('VNU_wp_user'); |
|
| 307 | + } |
|
| 308 | + |
|
| 309 | + |
|
| 310 | + /** |
|
| 311 | + * @return string |
|
| 312 | + */ |
|
| 313 | + public function virtual_phone() |
|
| 314 | + { |
|
| 315 | + return $this->get('VNU_virtual_phone'); |
|
| 316 | + } |
|
| 317 | + |
|
| 318 | + |
|
| 319 | + /** |
|
| 320 | + * @return string |
|
| 321 | + */ |
|
| 322 | + public function virtual_url() |
|
| 323 | + { |
|
| 324 | + return $this->get('VNU_virtual_url'); |
|
| 325 | + } |
|
| 326 | + |
|
| 327 | + |
|
| 328 | + /** |
|
| 329 | + * @return bool |
|
| 330 | + */ |
|
| 331 | + public function enable_for_gmap() |
|
| 332 | + { |
|
| 333 | + return $this->get('VNU_enable_for_gmap'); |
|
| 334 | + } |
|
| 335 | + |
|
| 336 | + |
|
| 337 | + /** |
|
| 338 | + * @return string |
|
| 339 | + */ |
|
| 340 | + public function google_map_link() |
|
| 341 | + { |
|
| 342 | + return $this->get('VNU_google_map_link'); |
|
| 343 | + } |
|
| 344 | + |
|
| 345 | + |
|
| 346 | + /** |
|
| 347 | + * Gets all events happening at this venue. Query parameters can be added to |
|
| 348 | + * fetch a subset of those events. |
|
| 349 | + * |
|
| 350 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 351 | + * @param bool $upcoming |
|
| 352 | + * @return EE_Event[] |
|
| 353 | + */ |
|
| 354 | + public function events($query_params = array(), $upcoming = false) |
|
| 355 | + { |
|
| 356 | + if ($upcoming) { |
|
| 357 | + $query_params = array( |
|
| 358 | + array( |
|
| 359 | + 'status' => 'publish', |
|
| 360 | + 'Datetime.DTT_EVT_start' => array( |
|
| 361 | + '>', |
|
| 362 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
| 363 | + ), |
|
| 364 | + ), |
|
| 365 | + ); |
|
| 366 | + } |
|
| 367 | + return $this->get_many_related('Event', $query_params); |
|
| 368 | + } |
|
| 369 | + |
|
| 370 | + |
|
| 371 | + /** |
|
| 372 | + * Sets address |
|
| 373 | + */ |
|
| 374 | + public function set_address($address = '') |
|
| 375 | + { |
|
| 376 | + $this->set('VNU_address', $address); |
|
| 377 | + } |
|
| 378 | + |
|
| 379 | + |
|
| 380 | + /** |
|
| 381 | + * @param string $address2 |
|
| 382 | + */ |
|
| 383 | + public function set_address2($address2 = '') |
|
| 384 | + { |
|
| 385 | + $this->set('VNU_address2', $address2); |
|
| 386 | + } |
|
| 387 | + |
|
| 388 | + |
|
| 389 | + /** |
|
| 390 | + * @param string $city |
|
| 391 | + */ |
|
| 392 | + public function set_city($city = '') |
|
| 393 | + { |
|
| 394 | + $this->set('VNU_city', $city); |
|
| 395 | + } |
|
| 396 | + |
|
| 397 | + |
|
| 398 | + /** |
|
| 399 | + * @param int $state |
|
| 400 | + */ |
|
| 401 | + public function set_state_ID($state = 0) |
|
| 402 | + { |
|
| 403 | + $this->set('STA_ID', $state); |
|
| 404 | + } |
|
| 405 | + |
|
| 406 | + |
|
| 407 | + /** |
|
| 408 | + * Sets the state, given either a state id or state object |
|
| 409 | + * |
|
| 410 | + * @param EE_State /int $state_id_or_obj |
|
| 411 | + * @return EE_State |
|
| 412 | + */ |
|
| 413 | + public function set_state_obj($state_id_or_obj) |
|
| 414 | + { |
|
| 415 | + return $this->_add_relation_to($state_id_or_obj, 'State'); |
|
| 416 | + } |
|
| 417 | + |
|
| 418 | + |
|
| 419 | + /** |
|
| 420 | + * @param int $country_ID |
|
| 421 | + */ |
|
| 422 | + public function set_country_ID($country_ID = 0) |
|
| 423 | + { |
|
| 424 | + $this->set('CNT_ISO', $country_ID); |
|
| 425 | + } |
|
| 426 | + |
|
| 427 | + |
|
| 428 | + /** |
|
| 429 | + * Sets the country on the venue |
|
| 430 | + * |
|
| 431 | + * @param EE_Country /string $country_id_or_obj |
|
| 432 | + * @return EE_Country |
|
| 433 | + */ |
|
| 434 | + public function set_country_obj($country_id_or_obj) |
|
| 435 | + { |
|
| 436 | + return $this->_add_relation_to($country_id_or_obj, 'Country'); |
|
| 437 | + } |
|
| 438 | + |
|
| 439 | + |
|
| 440 | + /** |
|
| 441 | + * @param string $zip |
|
| 442 | + */ |
|
| 443 | + public function set_zip($zip = '') |
|
| 444 | + { |
|
| 445 | + $this->set('VNU_zip', $zip); |
|
| 446 | + } |
|
| 447 | + |
|
| 448 | + |
|
| 449 | + /** |
|
| 450 | + * @param int $capacity |
|
| 451 | + */ |
|
| 452 | + public function set_capacity($capacity = 0) |
|
| 453 | + { |
|
| 454 | + $this->set('VNU_capacity', $capacity); |
|
| 455 | + } |
|
| 456 | + |
|
| 457 | + |
|
| 458 | + /** |
|
| 459 | + * @param string $created |
|
| 460 | + */ |
|
| 461 | + public function set_created($created = '') |
|
| 462 | + { |
|
| 463 | + $this->set('VNU_created', $created); |
|
| 464 | + } |
|
| 465 | + |
|
| 466 | + |
|
| 467 | + /** |
|
| 468 | + * @param string $desc |
|
| 469 | + */ |
|
| 470 | + public function set_description($desc = '') |
|
| 471 | + { |
|
| 472 | + $this->set('VNU_desc', $desc); |
|
| 473 | + } |
|
| 474 | + |
|
| 475 | + |
|
| 476 | + /** |
|
| 477 | + * @param string $identifier |
|
| 478 | + */ |
|
| 479 | + public function set_identifier($identifier = '') |
|
| 480 | + { |
|
| 481 | + $this->set('VNU_identifier', $identifier); |
|
| 482 | + } |
|
| 483 | + |
|
| 484 | + |
|
| 485 | + /** |
|
| 486 | + * @param string $modified |
|
| 487 | + */ |
|
| 488 | + public function set_modified($modified = '') |
|
| 489 | + { |
|
| 490 | + $this->set('VNU_modified', $modified); |
|
| 491 | + } |
|
| 492 | + |
|
| 493 | + |
|
| 494 | + /** |
|
| 495 | + * @param string $name |
|
| 496 | + */ |
|
| 497 | + public function set_name($name = '') |
|
| 498 | + { |
|
| 499 | + $this->set('VNU_name', $name); |
|
| 500 | + } |
|
| 501 | + |
|
| 502 | + |
|
| 503 | + /** |
|
| 504 | + * @param int $order |
|
| 505 | + */ |
|
| 506 | + public function set_order($order = 0) |
|
| 507 | + { |
|
| 508 | + $this->set('VNU_order', $order); |
|
| 509 | + } |
|
| 510 | + |
|
| 511 | + |
|
| 512 | + /** |
|
| 513 | + * @param string $phone |
|
| 514 | + */ |
|
| 515 | + public function set_phone($phone = '') |
|
| 516 | + { |
|
| 517 | + $this->set('VNU_phone', $phone); |
|
| 518 | + } |
|
| 519 | + |
|
| 520 | + |
|
| 521 | + /** |
|
| 522 | + * @param int $wp_user |
|
| 523 | + */ |
|
| 524 | + public function set_wp_user($wp_user = 1) |
|
| 525 | + { |
|
| 526 | + $this->set('VNU_wp_user', $wp_user); |
|
| 527 | + } |
|
| 528 | + |
|
| 529 | + |
|
| 530 | + /** |
|
| 531 | + * @param string $url |
|
| 532 | + */ |
|
| 533 | + public function set_venue_url($url = '') |
|
| 534 | + { |
|
| 535 | + $this->set('VNU_url', $url); |
|
| 536 | + } |
|
| 537 | + |
|
| 538 | + |
|
| 539 | + /** |
|
| 540 | + * @param string $phone |
|
| 541 | + */ |
|
| 542 | + public function set_virtual_phone($phone = '') |
|
| 543 | + { |
|
| 544 | + $this->set('VNU_virtual_phone', $phone); |
|
| 545 | + } |
|
| 546 | + |
|
| 547 | + |
|
| 548 | + /** |
|
| 549 | + * @param string $url |
|
| 550 | + */ |
|
| 551 | + public function set_virtual_url($url = '') |
|
| 552 | + { |
|
| 553 | + $this->set('VNU_virtual_url', $url); |
|
| 554 | + } |
|
| 555 | + |
|
| 556 | + |
|
| 557 | + /** |
|
| 558 | + * @param string $enable |
|
| 559 | + */ |
|
| 560 | + public function set_enable_for_gmap($enable = '') |
|
| 561 | + { |
|
| 562 | + $this->set('VNU_enable_for_gmap', $enable); |
|
| 563 | + } |
|
| 564 | + |
|
| 565 | + |
|
| 566 | + /** |
|
| 567 | + * @param string $google_map_link |
|
| 568 | + */ |
|
| 569 | + public function set_google_map_link($google_map_link = '') |
|
| 570 | + { |
|
| 571 | + $this->set('VNU_google_map_link', $google_map_link); |
|
| 572 | + } |
|
| 573 | 573 | } |
@@ -12,25 +12,25 @@ |
||
| 12 | 12 | class EE_Extra_Join extends EE_Base_Class |
| 13 | 13 | { |
| 14 | 14 | |
| 15 | - /** |
|
| 16 | - * @param array $props_n_values |
|
| 17 | - * @param null $timezone |
|
| 18 | - * @return EE_Extra_Join|mixed |
|
| 19 | - */ |
|
| 20 | - public static function new_instance($props_n_values = array(), $timezone = '') |
|
| 21 | - { |
|
| 22 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone); |
|
| 23 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone); |
|
| 24 | - } |
|
| 15 | + /** |
|
| 16 | + * @param array $props_n_values |
|
| 17 | + * @param null $timezone |
|
| 18 | + * @return EE_Extra_Join|mixed |
|
| 19 | + */ |
|
| 20 | + public static function new_instance($props_n_values = array(), $timezone = '') |
|
| 21 | + { |
|
| 22 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone); |
|
| 23 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone); |
|
| 24 | + } |
|
| 25 | 25 | |
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * @param array $props_n_values |
|
| 29 | - * @param null $timezone |
|
| 30 | - * @return EE_Extra_Join |
|
| 31 | - */ |
|
| 32 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 33 | - { |
|
| 34 | - return new self($props_n_values, true, $timezone); |
|
| 35 | - } |
|
| 27 | + /** |
|
| 28 | + * @param array $props_n_values |
|
| 29 | + * @param null $timezone |
|
| 30 | + * @return EE_Extra_Join |
|
| 31 | + */ |
|
| 32 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 33 | + { |
|
| 34 | + return new self($props_n_values, true, $timezone); |
|
| 35 | + } |
|
| 36 | 36 | } |
@@ -13,1705 +13,1705 @@ |
||
| 13 | 13 | class EE_Transaction extends EE_Base_Class implements EEI_Transaction |
| 14 | 14 | { |
| 15 | 15 | |
| 16 | - /** |
|
| 17 | - * The length of time in seconds that a lock is applied before being considered expired. |
|
| 18 | - * It is not long because a transaction should only be locked for the duration of the request that locked it |
|
| 19 | - */ |
|
| 20 | - const LOCK_EXPIRATION = 2; |
|
| 21 | - |
|
| 22 | - /** |
|
| 23 | - * txn status upon initial construction. |
|
| 24 | - * |
|
| 25 | - * @var string |
|
| 26 | - */ |
|
| 27 | - protected $_old_txn_status; |
|
| 28 | - |
|
| 29 | - |
|
| 30 | - /** |
|
| 31 | - * @param array $props_n_values incoming values |
|
| 32 | - * @param string $timezone incoming timezone |
|
| 33 | - * (if not set the timezone set for the website will be used.) |
|
| 34 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 35 | - * date_format and the second value is the time format |
|
| 36 | - * @return EE_Transaction |
|
| 37 | - * @throws EE_Error |
|
| 38 | - * @throws InvalidArgumentException |
|
| 39 | - * @throws InvalidDataTypeException |
|
| 40 | - * @throws InvalidInterfaceException |
|
| 41 | - * @throws ReflectionException |
|
| 42 | - */ |
|
| 43 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 44 | - { |
|
| 45 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 46 | - $txn = $has_object |
|
| 47 | - ? $has_object |
|
| 48 | - : new self($props_n_values, false, $timezone, $date_formats); |
|
| 49 | - if (! $has_object) { |
|
| 50 | - $txn->set_old_txn_status($txn->status_ID()); |
|
| 51 | - } |
|
| 52 | - return $txn; |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * @param array $props_n_values incoming values from the database |
|
| 58 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 59 | - * the website will be used. |
|
| 60 | - * @return EE_Transaction |
|
| 61 | - * @throws EE_Error |
|
| 62 | - * @throws InvalidArgumentException |
|
| 63 | - * @throws InvalidDataTypeException |
|
| 64 | - * @throws InvalidInterfaceException |
|
| 65 | - * @throws ReflectionException |
|
| 66 | - */ |
|
| 67 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 68 | - { |
|
| 69 | - $txn = new self($props_n_values, true, $timezone); |
|
| 70 | - $txn->set_old_txn_status($txn->status_ID()); |
|
| 71 | - return $txn; |
|
| 72 | - } |
|
| 73 | - |
|
| 74 | - |
|
| 75 | - /** |
|
| 76 | - * Sets a meta field indicating that this TXN is locked and should not be updated in the db. |
|
| 77 | - * If a lock has already been set, then we will attempt to remove it in case it has expired. |
|
| 78 | - * If that also fails, then an exception is thrown. |
|
| 79 | - * |
|
| 80 | - * @throws EE_Error |
|
| 81 | - * @throws InvalidArgumentException |
|
| 82 | - * @throws InvalidDataTypeException |
|
| 83 | - * @throws InvalidInterfaceException |
|
| 84 | - * @throws ReflectionException |
|
| 85 | - */ |
|
| 86 | - public function lock() |
|
| 87 | - { |
|
| 88 | - // attempt to set lock, but if that fails... |
|
| 89 | - if (! $this->add_extra_meta('lock', time(), true)) { |
|
| 90 | - // then attempt to remove the lock in case it is expired |
|
| 91 | - if ($this->_remove_expired_lock()) { |
|
| 92 | - // if removal was successful, then try setting lock again |
|
| 93 | - $this->lock(); |
|
| 94 | - } else { |
|
| 95 | - // but if the lock can not be removed, then throw an exception |
|
| 96 | - throw new EE_Error( |
|
| 97 | - sprintf( |
|
| 98 | - __( |
|
| 99 | - 'Could not lock Transaction %1$d because it is already locked, meaning another part of the system is currently editing it. It should already be unlocked by the time you read this, so please refresh the page and try again.', |
|
| 100 | - 'event_espresso' |
|
| 101 | - ), |
|
| 102 | - $this->ID() |
|
| 103 | - ) |
|
| 104 | - ); |
|
| 105 | - } |
|
| 106 | - } |
|
| 107 | - } |
|
| 108 | - |
|
| 109 | - |
|
| 110 | - /** |
|
| 111 | - * removes transaction lock applied in EE_Transaction::lock() |
|
| 112 | - * |
|
| 113 | - * @return int |
|
| 114 | - * @throws EE_Error |
|
| 115 | - * @throws InvalidArgumentException |
|
| 116 | - * @throws InvalidDataTypeException |
|
| 117 | - * @throws InvalidInterfaceException |
|
| 118 | - * @throws ReflectionException |
|
| 119 | - */ |
|
| 120 | - public function unlock() |
|
| 121 | - { |
|
| 122 | - return $this->delete_extra_meta('lock'); |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - |
|
| 126 | - /** |
|
| 127 | - * Decides whether or not now is the right time to update the transaction. |
|
| 128 | - * This is useful because we don't always know if it is safe to update the transaction |
|
| 129 | - * and its related data. why? |
|
| 130 | - * because it's possible that the transaction is being used in another |
|
| 131 | - * request and could overwrite anything we save. |
|
| 132 | - * So we want to only update the txn once we know that won't happen. |
|
| 133 | - * We also check that the lock isn't expired, and remove it if it is |
|
| 134 | - * |
|
| 135 | - * @return boolean |
|
| 136 | - * @throws EE_Error |
|
| 137 | - * @throws InvalidArgumentException |
|
| 138 | - * @throws InvalidDataTypeException |
|
| 139 | - * @throws InvalidInterfaceException |
|
| 140 | - * @throws ReflectionException |
|
| 141 | - */ |
|
| 142 | - public function is_locked() |
|
| 143 | - { |
|
| 144 | - // if TXN is not locked, then return false immediately |
|
| 145 | - if (! $this->_get_lock()) { |
|
| 146 | - return false; |
|
| 147 | - } |
|
| 148 | - // if not, then let's try and remove the lock in case it's expired... |
|
| 149 | - // _remove_expired_lock() returns 0 when lock is valid (ie: removed = false) |
|
| 150 | - // and a positive number if the lock was removed (ie: number of locks deleted), |
|
| 151 | - // so we need to return the opposite |
|
| 152 | - return ! $this->_remove_expired_lock() ? true : false; |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - |
|
| 156 | - /** |
|
| 157 | - * Gets the meta field indicating that this TXN is locked |
|
| 158 | - * |
|
| 159 | - * @return int |
|
| 160 | - * @throws EE_Error |
|
| 161 | - * @throws InvalidArgumentException |
|
| 162 | - * @throws InvalidDataTypeException |
|
| 163 | - * @throws InvalidInterfaceException |
|
| 164 | - * @throws ReflectionException |
|
| 165 | - */ |
|
| 166 | - protected function _get_lock() |
|
| 167 | - { |
|
| 168 | - return (int) $this->get_extra_meta('lock', true, 0); |
|
| 169 | - } |
|
| 170 | - |
|
| 171 | - |
|
| 172 | - /** |
|
| 173 | - * If the lock on this transaction is expired, then we want to remove it so that the transaction can be updated |
|
| 174 | - * |
|
| 175 | - * @return int |
|
| 176 | - * @throws EE_Error |
|
| 177 | - * @throws InvalidArgumentException |
|
| 178 | - * @throws InvalidDataTypeException |
|
| 179 | - * @throws InvalidInterfaceException |
|
| 180 | - * @throws ReflectionException |
|
| 181 | - */ |
|
| 182 | - protected function _remove_expired_lock() |
|
| 183 | - { |
|
| 184 | - $locked = $this->_get_lock(); |
|
| 185 | - if ($locked && time() - EE_Transaction::LOCK_EXPIRATION > $locked) { |
|
| 186 | - return $this->unlock(); |
|
| 187 | - } |
|
| 188 | - return 0; |
|
| 189 | - } |
|
| 190 | - |
|
| 191 | - |
|
| 192 | - /** |
|
| 193 | - * Set transaction total |
|
| 194 | - * |
|
| 195 | - * @param float $total total value of transaction |
|
| 196 | - * @throws EE_Error |
|
| 197 | - * @throws InvalidArgumentException |
|
| 198 | - * @throws InvalidDataTypeException |
|
| 199 | - * @throws InvalidInterfaceException |
|
| 200 | - * @throws ReflectionException |
|
| 201 | - */ |
|
| 202 | - public function set_total($total = 0.00) |
|
| 203 | - { |
|
| 204 | - $this->set('TXN_total', (float) $total); |
|
| 205 | - } |
|
| 206 | - |
|
| 207 | - |
|
| 208 | - /** |
|
| 209 | - * Set Total Amount Paid to Date |
|
| 210 | - * |
|
| 211 | - * @param float $total_paid total amount paid to date (sum of all payments) |
|
| 212 | - * @throws EE_Error |
|
| 213 | - * @throws InvalidArgumentException |
|
| 214 | - * @throws InvalidDataTypeException |
|
| 215 | - * @throws InvalidInterfaceException |
|
| 216 | - * @throws ReflectionException |
|
| 217 | - */ |
|
| 218 | - public function set_paid($total_paid = 0.00) |
|
| 219 | - { |
|
| 220 | - $this->set('TXN_paid', (float) $total_paid); |
|
| 221 | - } |
|
| 222 | - |
|
| 223 | - |
|
| 224 | - /** |
|
| 225 | - * Set transaction status |
|
| 226 | - * |
|
| 227 | - * @param string $status whether the transaction is open, declined, accepted, |
|
| 228 | - * or any number of custom values that can be set |
|
| 229 | - * @throws EE_Error |
|
| 230 | - * @throws InvalidArgumentException |
|
| 231 | - * @throws InvalidDataTypeException |
|
| 232 | - * @throws InvalidInterfaceException |
|
| 233 | - * @throws ReflectionException |
|
| 234 | - */ |
|
| 235 | - public function set_status($status = '') |
|
| 236 | - { |
|
| 237 | - $this->set('STS_ID', $status); |
|
| 238 | - } |
|
| 239 | - |
|
| 240 | - |
|
| 241 | - /** |
|
| 242 | - * Set hash salt |
|
| 243 | - * |
|
| 244 | - * @param string $hash_salt required for some payment gateways |
|
| 245 | - * @throws EE_Error |
|
| 246 | - * @throws InvalidArgumentException |
|
| 247 | - * @throws InvalidDataTypeException |
|
| 248 | - * @throws InvalidInterfaceException |
|
| 249 | - * @throws ReflectionException |
|
| 250 | - */ |
|
| 251 | - public function set_hash_salt($hash_salt = '') |
|
| 252 | - { |
|
| 253 | - $this->set('TXN_hash_salt', $hash_salt); |
|
| 254 | - } |
|
| 255 | - |
|
| 256 | - |
|
| 257 | - /** |
|
| 258 | - * Sets TXN_reg_steps array |
|
| 259 | - * |
|
| 260 | - * @param array $txn_reg_steps |
|
| 261 | - * @throws EE_Error |
|
| 262 | - * @throws InvalidArgumentException |
|
| 263 | - * @throws InvalidDataTypeException |
|
| 264 | - * @throws InvalidInterfaceException |
|
| 265 | - * @throws ReflectionException |
|
| 266 | - */ |
|
| 267 | - public function set_reg_steps(array $txn_reg_steps) |
|
| 268 | - { |
|
| 269 | - $this->set('TXN_reg_steps', $txn_reg_steps); |
|
| 270 | - } |
|
| 271 | - |
|
| 272 | - |
|
| 273 | - /** |
|
| 274 | - * Gets TXN_reg_steps |
|
| 275 | - * |
|
| 276 | - * @return array |
|
| 277 | - * @throws EE_Error |
|
| 278 | - * @throws InvalidArgumentException |
|
| 279 | - * @throws InvalidDataTypeException |
|
| 280 | - * @throws InvalidInterfaceException |
|
| 281 | - * @throws ReflectionException |
|
| 282 | - */ |
|
| 283 | - public function reg_steps() |
|
| 284 | - { |
|
| 285 | - $TXN_reg_steps = $this->get('TXN_reg_steps'); |
|
| 286 | - return is_array($TXN_reg_steps) ? (array) $TXN_reg_steps : array(); |
|
| 287 | - } |
|
| 288 | - |
|
| 289 | - |
|
| 290 | - /** |
|
| 291 | - * @return string of transaction's total cost, with currency symbol and decimal |
|
| 292 | - * @throws EE_Error |
|
| 293 | - * @throws InvalidArgumentException |
|
| 294 | - * @throws InvalidDataTypeException |
|
| 295 | - * @throws InvalidInterfaceException |
|
| 296 | - * @throws ReflectionException |
|
| 297 | - */ |
|
| 298 | - public function pretty_total() |
|
| 299 | - { |
|
| 300 | - return $this->get_pretty('TXN_total'); |
|
| 301 | - } |
|
| 302 | - |
|
| 303 | - |
|
| 304 | - /** |
|
| 305 | - * Gets the amount paid in a pretty string (formatted and with currency symbol) |
|
| 306 | - * |
|
| 307 | - * @return string |
|
| 308 | - * @throws EE_Error |
|
| 309 | - * @throws InvalidArgumentException |
|
| 310 | - * @throws InvalidDataTypeException |
|
| 311 | - * @throws InvalidInterfaceException |
|
| 312 | - * @throws ReflectionException |
|
| 313 | - */ |
|
| 314 | - public function pretty_paid() |
|
| 315 | - { |
|
| 316 | - return $this->get_pretty('TXN_paid'); |
|
| 317 | - } |
|
| 318 | - |
|
| 319 | - |
|
| 320 | - /** |
|
| 321 | - * calculate the amount remaining for this transaction and return; |
|
| 322 | - * |
|
| 323 | - * @return float amount remaining |
|
| 324 | - * @throws EE_Error |
|
| 325 | - * @throws InvalidArgumentException |
|
| 326 | - * @throws InvalidDataTypeException |
|
| 327 | - * @throws InvalidInterfaceException |
|
| 328 | - * @throws ReflectionException |
|
| 329 | - */ |
|
| 330 | - public function remaining() |
|
| 331 | - { |
|
| 332 | - return $this->total() - $this->paid(); |
|
| 333 | - } |
|
| 334 | - |
|
| 335 | - |
|
| 336 | - /** |
|
| 337 | - * get Transaction Total |
|
| 338 | - * |
|
| 339 | - * @return float |
|
| 340 | - * @throws EE_Error |
|
| 341 | - * @throws InvalidArgumentException |
|
| 342 | - * @throws InvalidDataTypeException |
|
| 343 | - * @throws InvalidInterfaceException |
|
| 344 | - * @throws ReflectionException |
|
| 345 | - */ |
|
| 346 | - public function total() |
|
| 347 | - { |
|
| 348 | - return (float) $this->get('TXN_total'); |
|
| 349 | - } |
|
| 350 | - |
|
| 351 | - |
|
| 352 | - /** |
|
| 353 | - * get Total Amount Paid to Date |
|
| 354 | - * |
|
| 355 | - * @return float |
|
| 356 | - * @throws EE_Error |
|
| 357 | - * @throws InvalidArgumentException |
|
| 358 | - * @throws InvalidDataTypeException |
|
| 359 | - * @throws InvalidInterfaceException |
|
| 360 | - * @throws ReflectionException |
|
| 361 | - */ |
|
| 362 | - public function paid() |
|
| 363 | - { |
|
| 364 | - return (float) $this->get('TXN_paid'); |
|
| 365 | - } |
|
| 366 | - |
|
| 367 | - |
|
| 368 | - /** |
|
| 369 | - * @return mixed|null |
|
| 370 | - * @throws EE_Error |
|
| 371 | - * @throws InvalidArgumentException |
|
| 372 | - * @throws InvalidDataTypeException |
|
| 373 | - * @throws InvalidInterfaceException |
|
| 374 | - * @throws ReflectionException |
|
| 375 | - */ |
|
| 376 | - public function get_cart_session() |
|
| 377 | - { |
|
| 378 | - $session_data = (array) $this->get('TXN_session_data'); |
|
| 379 | - return isset($session_data['cart']) && $session_data['cart'] instanceof EE_Cart |
|
| 380 | - ? $session_data['cart'] |
|
| 381 | - : null; |
|
| 382 | - } |
|
| 383 | - |
|
| 384 | - |
|
| 385 | - /** |
|
| 386 | - * get Transaction session data |
|
| 387 | - * |
|
| 388 | - * @return array|mixed |
|
| 389 | - * @throws EE_Error |
|
| 390 | - * @throws InvalidArgumentException |
|
| 391 | - * @throws InvalidDataTypeException |
|
| 392 | - * @throws InvalidInterfaceException |
|
| 393 | - * @throws ReflectionException |
|
| 394 | - */ |
|
| 395 | - public function session_data() |
|
| 396 | - { |
|
| 397 | - $session_data = $this->get('TXN_session_data'); |
|
| 398 | - if (empty($session_data)) { |
|
| 399 | - $session_data = array( |
|
| 400 | - 'id' => null, |
|
| 401 | - 'user_id' => null, |
|
| 402 | - 'ip_address' => null, |
|
| 403 | - 'user_agent' => null, |
|
| 404 | - 'init_access' => null, |
|
| 405 | - 'last_access' => null, |
|
| 406 | - 'pages_visited' => array(), |
|
| 407 | - ); |
|
| 408 | - } |
|
| 409 | - return $session_data; |
|
| 410 | - } |
|
| 411 | - |
|
| 412 | - |
|
| 413 | - /** |
|
| 414 | - * Set session data within the TXN object |
|
| 415 | - * |
|
| 416 | - * @param EE_Session|array $session_data |
|
| 417 | - * @throws EE_Error |
|
| 418 | - * @throws InvalidArgumentException |
|
| 419 | - * @throws InvalidDataTypeException |
|
| 420 | - * @throws InvalidInterfaceException |
|
| 421 | - * @throws ReflectionException |
|
| 422 | - */ |
|
| 423 | - public function set_txn_session_data($session_data) |
|
| 424 | - { |
|
| 425 | - if ($session_data instanceof EE_Session) { |
|
| 426 | - $this->set('TXN_session_data', $session_data->get_session_data(null, true)); |
|
| 427 | - } else { |
|
| 428 | - $this->set('TXN_session_data', $session_data); |
|
| 429 | - } |
|
| 430 | - } |
|
| 431 | - |
|
| 432 | - |
|
| 433 | - /** |
|
| 434 | - * get Transaction hash salt |
|
| 435 | - * |
|
| 436 | - * @return mixed |
|
| 437 | - * @throws EE_Error |
|
| 438 | - * @throws InvalidArgumentException |
|
| 439 | - * @throws InvalidDataTypeException |
|
| 440 | - * @throws InvalidInterfaceException |
|
| 441 | - * @throws ReflectionException |
|
| 442 | - */ |
|
| 443 | - public function hash_salt_() |
|
| 444 | - { |
|
| 445 | - return $this->get('TXN_hash_salt'); |
|
| 446 | - } |
|
| 447 | - |
|
| 448 | - |
|
| 449 | - /** |
|
| 450 | - * Returns the transaction datetime as either: |
|
| 451 | - * - unix timestamp format ($format = false, $gmt = true) |
|
| 452 | - * - formatted date string including the UTC (timezone) offset ($format = true ($gmt |
|
| 453 | - * has no affect with this option)), this also may include a timezone abbreviation if the |
|
| 454 | - * set timezone in this class differs from what the timezone is on the blog. |
|
| 455 | - * - formatted date string including the UTC (timezone) offset (default). |
|
| 456 | - * |
|
| 457 | - * @param boolean $format - whether to return a unix timestamp (default) or formatted date string |
|
| 458 | - * @param boolean $gmt - whether to return a unix timestamp with UTC offset applied (default) |
|
| 459 | - * or no UTC offset applied |
|
| 460 | - * @return string | int |
|
| 461 | - * @throws EE_Error |
|
| 462 | - * @throws InvalidArgumentException |
|
| 463 | - * @throws InvalidDataTypeException |
|
| 464 | - * @throws InvalidInterfaceException |
|
| 465 | - * @throws ReflectionException |
|
| 466 | - */ |
|
| 467 | - public function datetime($format = false, $gmt = false) |
|
| 468 | - { |
|
| 469 | - if ($format) { |
|
| 470 | - return $this->get_pretty('TXN_timestamp'); |
|
| 471 | - } |
|
| 472 | - if ($gmt) { |
|
| 473 | - return $this->get_raw('TXN_timestamp'); |
|
| 474 | - } |
|
| 475 | - return $this->get('TXN_timestamp'); |
|
| 476 | - } |
|
| 477 | - |
|
| 478 | - |
|
| 479 | - /** |
|
| 480 | - * Gets registrations on this transaction |
|
| 481 | - * |
|
| 482 | - * @param array $query_params array of query parameters |
|
| 483 | - * @param boolean $get_cached TRUE to retrieve cached registrations or FALSE to pull from the db |
|
| 484 | - * @return EE_Base_Class[]|EE_Registration[] |
|
| 485 | - * @throws EE_Error |
|
| 486 | - * @throws InvalidArgumentException |
|
| 487 | - * @throws InvalidDataTypeException |
|
| 488 | - * @throws InvalidInterfaceException |
|
| 489 | - * @throws ReflectionException |
|
| 490 | - */ |
|
| 491 | - public function registrations($query_params = array(), $get_cached = false) |
|
| 492 | - { |
|
| 493 | - $query_params = (empty($query_params) || ! is_array($query_params)) |
|
| 494 | - ? array( |
|
| 495 | - 'order_by' => array( |
|
| 496 | - 'Event.EVT_name' => 'ASC', |
|
| 497 | - 'Attendee.ATT_lname' => 'ASC', |
|
| 498 | - 'Attendee.ATT_fname' => 'ASC', |
|
| 499 | - ), |
|
| 500 | - ) |
|
| 501 | - : $query_params; |
|
| 502 | - $query_params = $get_cached ? array() : $query_params; |
|
| 503 | - return $this->get_many_related('Registration', $query_params); |
|
| 504 | - } |
|
| 505 | - |
|
| 506 | - |
|
| 507 | - /** |
|
| 508 | - * Gets all the attendees for this transaction (handy for use with EE_Attendee's get_registrations_for_event |
|
| 509 | - * function for getting attendees and how many registrations they each have for an event) |
|
| 510 | - * |
|
| 511 | - * @return mixed EE_Attendee[] by default, int if $output is set to 'COUNT' |
|
| 512 | - * @throws EE_Error |
|
| 513 | - * @throws InvalidArgumentException |
|
| 514 | - * @throws InvalidDataTypeException |
|
| 515 | - * @throws InvalidInterfaceException |
|
| 516 | - * @throws ReflectionException |
|
| 517 | - */ |
|
| 518 | - public function attendees() |
|
| 519 | - { |
|
| 520 | - return $this->get_many_related('Attendee', array(array('Registration.Transaction.TXN_ID' => $this->ID()))); |
|
| 521 | - } |
|
| 522 | - |
|
| 523 | - |
|
| 524 | - /** |
|
| 525 | - * Gets payments for this transaction. Unlike other such functions, order by 'DESC' by default |
|
| 526 | - * |
|
| 527 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 528 | - * @return EE_Base_Class[]|EE_Payment[] |
|
| 529 | - * @throws EE_Error |
|
| 530 | - * @throws InvalidArgumentException |
|
| 531 | - * @throws InvalidDataTypeException |
|
| 532 | - * @throws InvalidInterfaceException |
|
| 533 | - * @throws ReflectionException |
|
| 534 | - */ |
|
| 535 | - public function payments($query_params = array()) |
|
| 536 | - { |
|
| 537 | - return $this->get_many_related('Payment', $query_params); |
|
| 538 | - } |
|
| 539 | - |
|
| 540 | - |
|
| 541 | - /** |
|
| 542 | - * gets only approved payments for this transaction |
|
| 543 | - * |
|
| 544 | - * @return EE_Base_Class[]|EE_Payment[] |
|
| 545 | - * @throws EE_Error |
|
| 546 | - * @throws InvalidArgumentException |
|
| 547 | - * @throws ReflectionException |
|
| 548 | - * @throws InvalidDataTypeException |
|
| 549 | - * @throws InvalidInterfaceException |
|
| 550 | - */ |
|
| 551 | - public function approved_payments() |
|
| 552 | - { |
|
| 553 | - EE_Registry::instance()->load_model('Payment'); |
|
| 554 | - return $this->get_many_related( |
|
| 555 | - 'Payment', |
|
| 556 | - array( |
|
| 557 | - array('STS_ID' => EEM_Payment::status_id_approved), |
|
| 558 | - 'order_by' => array('PAY_timestamp' => 'DESC'), |
|
| 559 | - ) |
|
| 560 | - ); |
|
| 561 | - } |
|
| 562 | - |
|
| 563 | - |
|
| 564 | - /** |
|
| 565 | - * Gets all payments which have not been approved |
|
| 566 | - * |
|
| 567 | - * @return EE_Base_Class[]|EEI_Payment[] |
|
| 568 | - * @throws EE_Error if a model is misconfigured somehow |
|
| 569 | - * @throws InvalidArgumentException |
|
| 570 | - * @throws InvalidDataTypeException |
|
| 571 | - * @throws InvalidInterfaceException |
|
| 572 | - * @throws ReflectionException |
|
| 573 | - */ |
|
| 574 | - public function pending_payments() |
|
| 575 | - { |
|
| 576 | - return $this->get_many_related( |
|
| 577 | - 'Payment', |
|
| 578 | - array( |
|
| 579 | - array( |
|
| 580 | - 'STS_ID' => EEM_Payment::status_id_pending, |
|
| 581 | - ), |
|
| 582 | - 'order_by' => array( |
|
| 583 | - 'PAY_timestamp' => 'DESC', |
|
| 584 | - ), |
|
| 585 | - ) |
|
| 586 | - ); |
|
| 587 | - } |
|
| 588 | - |
|
| 589 | - |
|
| 590 | - /** |
|
| 591 | - * echoes $this->pretty_status() |
|
| 592 | - * |
|
| 593 | - * @param bool $show_icons |
|
| 594 | - * @throws EE_Error |
|
| 595 | - * @throws InvalidArgumentException |
|
| 596 | - * @throws InvalidDataTypeException |
|
| 597 | - * @throws InvalidInterfaceException |
|
| 598 | - * @throws ReflectionException |
|
| 599 | - */ |
|
| 600 | - public function e_pretty_status($show_icons = false) |
|
| 601 | - { |
|
| 602 | - echo $this->pretty_status($show_icons); |
|
| 603 | - } |
|
| 604 | - |
|
| 605 | - |
|
| 606 | - /** |
|
| 607 | - * returns a pretty version of the status, good for displaying to users |
|
| 608 | - * |
|
| 609 | - * @param bool $show_icons |
|
| 610 | - * @return string |
|
| 611 | - * @throws EE_Error |
|
| 612 | - * @throws InvalidArgumentException |
|
| 613 | - * @throws InvalidDataTypeException |
|
| 614 | - * @throws InvalidInterfaceException |
|
| 615 | - * @throws ReflectionException |
|
| 616 | - */ |
|
| 617 | - public function pretty_status($show_icons = false) |
|
| 618 | - { |
|
| 619 | - $status = EEM_Status::instance()->localized_status( |
|
| 620 | - array($this->status_ID() => __('unknown', 'event_espresso')), |
|
| 621 | - false, |
|
| 622 | - 'sentence' |
|
| 623 | - ); |
|
| 624 | - $icon = ''; |
|
| 625 | - switch ($this->status_ID()) { |
|
| 626 | - case EEM_Transaction::complete_status_code: |
|
| 627 | - $icon = $show_icons ? '<span class="dashicons dashicons-yes ee-icon-size-24 green-text"></span>' : ''; |
|
| 628 | - break; |
|
| 629 | - case EEM_Transaction::incomplete_status_code: |
|
| 630 | - $icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 lt-blue-text"></span>' |
|
| 631 | - : ''; |
|
| 632 | - break; |
|
| 633 | - case EEM_Transaction::abandoned_status_code: |
|
| 634 | - $icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 red-text"></span>' : ''; |
|
| 635 | - break; |
|
| 636 | - case EEM_Transaction::failed_status_code: |
|
| 637 | - $icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' : ''; |
|
| 638 | - break; |
|
| 639 | - case EEM_Transaction::overpaid_status_code: |
|
| 640 | - $icon = $show_icons ? '<span class="dashicons dashicons-plus ee-icon-size-16 orange-text"></span>' : ''; |
|
| 641 | - break; |
|
| 642 | - } |
|
| 643 | - return $icon . $status[ $this->status_ID() ]; |
|
| 644 | - } |
|
| 645 | - |
|
| 646 | - |
|
| 647 | - /** |
|
| 648 | - * get Transaction Status |
|
| 649 | - * |
|
| 650 | - * @return mixed |
|
| 651 | - * @throws EE_Error |
|
| 652 | - * @throws InvalidArgumentException |
|
| 653 | - * @throws InvalidDataTypeException |
|
| 654 | - * @throws InvalidInterfaceException |
|
| 655 | - * @throws ReflectionException |
|
| 656 | - */ |
|
| 657 | - public function status_ID() |
|
| 658 | - { |
|
| 659 | - return $this->get('STS_ID'); |
|
| 660 | - } |
|
| 661 | - |
|
| 662 | - |
|
| 663 | - /** |
|
| 664 | - * Returns TRUE or FALSE for whether or not this transaction cost any money |
|
| 665 | - * |
|
| 666 | - * @return boolean |
|
| 667 | - * @throws EE_Error |
|
| 668 | - * @throws InvalidArgumentException |
|
| 669 | - * @throws InvalidDataTypeException |
|
| 670 | - * @throws InvalidInterfaceException |
|
| 671 | - * @throws ReflectionException |
|
| 672 | - */ |
|
| 673 | - public function is_free() |
|
| 674 | - { |
|
| 675 | - return EEH_Money::compare_floats($this->get('TXN_total'), 0, '=='); |
|
| 676 | - } |
|
| 677 | - |
|
| 678 | - |
|
| 679 | - /** |
|
| 680 | - * Returns whether this transaction is complete |
|
| 681 | - * Useful in templates and other logic for deciding if we should ask for another payment... |
|
| 682 | - * |
|
| 683 | - * @return boolean |
|
| 684 | - * @throws EE_Error |
|
| 685 | - * @throws InvalidArgumentException |
|
| 686 | - * @throws InvalidDataTypeException |
|
| 687 | - * @throws InvalidInterfaceException |
|
| 688 | - * @throws ReflectionException |
|
| 689 | - */ |
|
| 690 | - public function is_completed() |
|
| 691 | - { |
|
| 692 | - return $this->status_ID() === EEM_Transaction::complete_status_code; |
|
| 693 | - } |
|
| 694 | - |
|
| 695 | - |
|
| 696 | - /** |
|
| 697 | - * Returns whether this transaction is incomplete |
|
| 698 | - * Useful in templates and other logic for deciding if we should ask for another payment... |
|
| 699 | - * |
|
| 700 | - * @return boolean |
|
| 701 | - * @throws EE_Error |
|
| 702 | - * @throws InvalidArgumentException |
|
| 703 | - * @throws InvalidDataTypeException |
|
| 704 | - * @throws InvalidInterfaceException |
|
| 705 | - * @throws ReflectionException |
|
| 706 | - */ |
|
| 707 | - public function is_incomplete() |
|
| 708 | - { |
|
| 709 | - return $this->status_ID() === EEM_Transaction::incomplete_status_code; |
|
| 710 | - } |
|
| 711 | - |
|
| 712 | - |
|
| 713 | - /** |
|
| 714 | - * Returns whether this transaction is overpaid |
|
| 715 | - * Useful in templates and other logic for deciding if monies need to be refunded |
|
| 716 | - * |
|
| 717 | - * @return boolean |
|
| 718 | - * @throws EE_Error |
|
| 719 | - * @throws InvalidArgumentException |
|
| 720 | - * @throws InvalidDataTypeException |
|
| 721 | - * @throws InvalidInterfaceException |
|
| 722 | - * @throws ReflectionException |
|
| 723 | - */ |
|
| 724 | - public function is_overpaid() |
|
| 725 | - { |
|
| 726 | - return $this->status_ID() === EEM_Transaction::overpaid_status_code; |
|
| 727 | - } |
|
| 728 | - |
|
| 729 | - |
|
| 730 | - /** |
|
| 731 | - * Returns whether this transaction was abandoned |
|
| 732 | - * meaning that the transaction/registration process was somehow interrupted and never completed |
|
| 733 | - * but that contact information exists for at least one registrant |
|
| 734 | - * |
|
| 735 | - * @return boolean |
|
| 736 | - * @throws EE_Error |
|
| 737 | - * @throws InvalidArgumentException |
|
| 738 | - * @throws InvalidDataTypeException |
|
| 739 | - * @throws InvalidInterfaceException |
|
| 740 | - * @throws ReflectionException |
|
| 741 | - */ |
|
| 742 | - public function is_abandoned() |
|
| 743 | - { |
|
| 744 | - return $this->status_ID() === EEM_Transaction::abandoned_status_code; |
|
| 745 | - } |
|
| 746 | - |
|
| 747 | - |
|
| 748 | - /** |
|
| 749 | - * Returns whether this transaction failed |
|
| 750 | - * meaning that the transaction/registration process was somehow interrupted and never completed |
|
| 751 | - * and that NO contact information exists for any registrants |
|
| 752 | - * |
|
| 753 | - * @return boolean |
|
| 754 | - * @throws EE_Error |
|
| 755 | - * @throws InvalidArgumentException |
|
| 756 | - * @throws InvalidDataTypeException |
|
| 757 | - * @throws InvalidInterfaceException |
|
| 758 | - * @throws ReflectionException |
|
| 759 | - */ |
|
| 760 | - public function failed() |
|
| 761 | - { |
|
| 762 | - return $this->status_ID() === EEM_Transaction::failed_status_code; |
|
| 763 | - } |
|
| 764 | - |
|
| 765 | - |
|
| 766 | - /** |
|
| 767 | - * This returns the url for the invoice of this transaction |
|
| 768 | - * |
|
| 769 | - * @param string $type 'html' or 'pdf' (default is pdf) |
|
| 770 | - * @return string |
|
| 771 | - * @throws EE_Error |
|
| 772 | - * @throws InvalidArgumentException |
|
| 773 | - * @throws InvalidDataTypeException |
|
| 774 | - * @throws InvalidInterfaceException |
|
| 775 | - * @throws ReflectionException |
|
| 776 | - */ |
|
| 777 | - public function invoice_url($type = 'html') |
|
| 778 | - { |
|
| 779 | - $REG = $this->primary_registration(); |
|
| 780 | - if (! $REG instanceof EE_Registration) { |
|
| 781 | - return ''; |
|
| 782 | - } |
|
| 783 | - return $REG->invoice_url($type); |
|
| 784 | - } |
|
| 785 | - |
|
| 786 | - |
|
| 787 | - /** |
|
| 788 | - * Gets the primary registration only |
|
| 789 | - * |
|
| 790 | - * @return EE_Base_Class|EE_Registration |
|
| 791 | - * @throws EE_Error |
|
| 792 | - * @throws InvalidArgumentException |
|
| 793 | - * @throws InvalidDataTypeException |
|
| 794 | - * @throws InvalidInterfaceException |
|
| 795 | - * @throws ReflectionException |
|
| 796 | - */ |
|
| 797 | - public function primary_registration() |
|
| 798 | - { |
|
| 799 | - $registrations = (array) $this->get_many_related( |
|
| 800 | - 'Registration', |
|
| 801 | - array(array('REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT)) |
|
| 802 | - ); |
|
| 803 | - foreach ($registrations as $registration) { |
|
| 804 | - // valid registration that is NOT cancelled or declined ? |
|
| 805 | - if ( |
|
| 806 | - $registration instanceof EE_Registration |
|
| 807 | - && ! in_array($registration->status_ID(), EEM_Registration::closed_reg_statuses(), true) |
|
| 808 | - ) { |
|
| 809 | - return $registration; |
|
| 810 | - } |
|
| 811 | - } |
|
| 812 | - // nothing valid found, so just return first thing from array of results |
|
| 813 | - return reset($registrations); |
|
| 814 | - } |
|
| 815 | - |
|
| 816 | - |
|
| 817 | - /** |
|
| 818 | - * Gets the URL for viewing the receipt |
|
| 819 | - * |
|
| 820 | - * @param string $type 'pdf' or 'html' (default is 'html') |
|
| 821 | - * @return string |
|
| 822 | - * @throws EE_Error |
|
| 823 | - * @throws InvalidArgumentException |
|
| 824 | - * @throws InvalidDataTypeException |
|
| 825 | - * @throws InvalidInterfaceException |
|
| 826 | - * @throws ReflectionException |
|
| 827 | - */ |
|
| 828 | - public function receipt_url($type = 'html') |
|
| 829 | - { |
|
| 830 | - $REG = $this->primary_registration(); |
|
| 831 | - if (! $REG instanceof EE_Registration) { |
|
| 832 | - return ''; |
|
| 833 | - } |
|
| 834 | - return $REG->receipt_url($type); |
|
| 835 | - } |
|
| 836 | - |
|
| 837 | - |
|
| 838 | - /** |
|
| 839 | - * Gets the URL of the thank you page with this registration REG_url_link added as |
|
| 840 | - * a query parameter |
|
| 841 | - * |
|
| 842 | - * @return string |
|
| 843 | - * @throws EE_Error |
|
| 844 | - * @throws InvalidArgumentException |
|
| 845 | - * @throws InvalidDataTypeException |
|
| 846 | - * @throws InvalidInterfaceException |
|
| 847 | - * @throws ReflectionException |
|
| 848 | - */ |
|
| 849 | - public function payment_overview_url() |
|
| 850 | - { |
|
| 851 | - $primary_registration = $this->primary_registration(); |
|
| 852 | - return $primary_registration instanceof EE_Registration ? $primary_registration->payment_overview_url() : false; |
|
| 853 | - } |
|
| 854 | - |
|
| 855 | - |
|
| 856 | - /** |
|
| 857 | - * @return string |
|
| 858 | - * @throws EE_Error |
|
| 859 | - * @throws InvalidArgumentException |
|
| 860 | - * @throws InvalidDataTypeException |
|
| 861 | - * @throws InvalidInterfaceException |
|
| 862 | - * @throws ReflectionException |
|
| 863 | - */ |
|
| 864 | - public function gateway_response_on_transaction() |
|
| 865 | - { |
|
| 866 | - $payment = $this->get_first_related('Payment'); |
|
| 867 | - return $payment instanceof EE_Payment ? $payment->gateway_response() : ''; |
|
| 868 | - } |
|
| 869 | - |
|
| 870 | - |
|
| 871 | - /** |
|
| 872 | - * Get the status object of this object |
|
| 873 | - * |
|
| 874 | - * @return EE_Base_Class|EE_Status |
|
| 875 | - * @throws EE_Error |
|
| 876 | - * @throws InvalidArgumentException |
|
| 877 | - * @throws InvalidDataTypeException |
|
| 878 | - * @throws InvalidInterfaceException |
|
| 879 | - * @throws ReflectionException |
|
| 880 | - */ |
|
| 881 | - public function status_obj() |
|
| 882 | - { |
|
| 883 | - return $this->get_first_related('Status'); |
|
| 884 | - } |
|
| 885 | - |
|
| 886 | - |
|
| 887 | - /** |
|
| 888 | - * Gets all the extra meta info on this payment |
|
| 889 | - * |
|
| 890 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 891 | - * @return EE_Base_Class[]|EE_Extra_Meta |
|
| 892 | - * @throws EE_Error |
|
| 893 | - * @throws InvalidArgumentException |
|
| 894 | - * @throws InvalidDataTypeException |
|
| 895 | - * @throws InvalidInterfaceException |
|
| 896 | - * @throws ReflectionException |
|
| 897 | - */ |
|
| 898 | - public function extra_meta($query_params = array()) |
|
| 899 | - { |
|
| 900 | - return $this->get_many_related('Extra_Meta', $query_params); |
|
| 901 | - } |
|
| 902 | - |
|
| 903 | - |
|
| 904 | - /** |
|
| 905 | - * Wrapper for _add_relation_to |
|
| 906 | - * |
|
| 907 | - * @param EE_Registration $registration |
|
| 908 | - * @return EE_Base_Class the relation was added to |
|
| 909 | - * @throws EE_Error |
|
| 910 | - * @throws InvalidArgumentException |
|
| 911 | - * @throws InvalidDataTypeException |
|
| 912 | - * @throws InvalidInterfaceException |
|
| 913 | - * @throws ReflectionException |
|
| 914 | - */ |
|
| 915 | - public function add_registration(EE_Registration $registration) |
|
| 916 | - { |
|
| 917 | - return $this->_add_relation_to($registration, 'Registration'); |
|
| 918 | - } |
|
| 919 | - |
|
| 920 | - |
|
| 921 | - /** |
|
| 922 | - * Removes the given registration from being related (even before saving this transaction). |
|
| 923 | - * If an ID/index is provided and this transaction isn't saved yet, removes it from list of cached relations |
|
| 924 | - * |
|
| 925 | - * @param int $registration_or_id |
|
| 926 | - * @return EE_Base_Class that was removed from being related |
|
| 927 | - * @throws EE_Error |
|
| 928 | - * @throws InvalidArgumentException |
|
| 929 | - * @throws InvalidDataTypeException |
|
| 930 | - * @throws InvalidInterfaceException |
|
| 931 | - * @throws ReflectionException |
|
| 932 | - */ |
|
| 933 | - public function remove_registration_with_id($registration_or_id) |
|
| 934 | - { |
|
| 935 | - return $this->_remove_relation_to($registration_or_id, 'Registration'); |
|
| 936 | - } |
|
| 937 | - |
|
| 938 | - |
|
| 939 | - /** |
|
| 940 | - * Gets all the line items which are for ACTUAL items |
|
| 941 | - * |
|
| 942 | - * @return EE_Line_Item[] |
|
| 943 | - * @throws EE_Error |
|
| 944 | - * @throws InvalidArgumentException |
|
| 945 | - * @throws InvalidDataTypeException |
|
| 946 | - * @throws InvalidInterfaceException |
|
| 947 | - * @throws ReflectionException |
|
| 948 | - */ |
|
| 949 | - public function items_purchased() |
|
| 950 | - { |
|
| 951 | - return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_line_item))); |
|
| 952 | - } |
|
| 953 | - |
|
| 954 | - |
|
| 955 | - /** |
|
| 956 | - * Wrapper for _add_relation_to |
|
| 957 | - * |
|
| 958 | - * @param EE_Line_Item $line_item |
|
| 959 | - * @return EE_Base_Class the relation was added to |
|
| 960 | - * @throws EE_Error |
|
| 961 | - * @throws InvalidArgumentException |
|
| 962 | - * @throws InvalidDataTypeException |
|
| 963 | - * @throws InvalidInterfaceException |
|
| 964 | - * @throws ReflectionException |
|
| 965 | - */ |
|
| 966 | - public function add_line_item(EE_Line_Item $line_item) |
|
| 967 | - { |
|
| 968 | - return $this->_add_relation_to($line_item, 'Line_Item'); |
|
| 969 | - } |
|
| 970 | - |
|
| 971 | - |
|
| 972 | - /** |
|
| 973 | - * Gets ALL the line items related to this transaction (unstructured) |
|
| 974 | - * |
|
| 975 | - * @param array $query_params |
|
| 976 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 977 | - * @throws EE_Error |
|
| 978 | - * @throws InvalidArgumentException |
|
| 979 | - * @throws InvalidDataTypeException |
|
| 980 | - * @throws InvalidInterfaceException |
|
| 981 | - * @throws ReflectionException |
|
| 982 | - */ |
|
| 983 | - public function line_items($query_params = array()) |
|
| 984 | - { |
|
| 985 | - return $this->get_many_related('Line_Item', $query_params); |
|
| 986 | - } |
|
| 987 | - |
|
| 988 | - |
|
| 989 | - /** |
|
| 990 | - * Gets all the line items which are taxes on the total |
|
| 991 | - * |
|
| 992 | - * @return EE_Line_Item[] |
|
| 993 | - * @throws EE_Error |
|
| 994 | - * @throws InvalidArgumentException |
|
| 995 | - * @throws InvalidDataTypeException |
|
| 996 | - * @throws InvalidInterfaceException |
|
| 997 | - * @throws ReflectionException |
|
| 998 | - */ |
|
| 999 | - public function tax_items() |
|
| 1000 | - { |
|
| 1001 | - return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_tax))); |
|
| 1002 | - } |
|
| 1003 | - |
|
| 1004 | - |
|
| 1005 | - /** |
|
| 1006 | - * Gets the total line item (which is a parent of all other related line items, |
|
| 1007 | - * meaning it takes them all into account on its total) |
|
| 1008 | - * |
|
| 1009 | - * @param bool $create_if_not_found |
|
| 1010 | - * @return \EE_Line_Item |
|
| 1011 | - * @throws EE_Error |
|
| 1012 | - * @throws InvalidArgumentException |
|
| 1013 | - * @throws InvalidDataTypeException |
|
| 1014 | - * @throws InvalidInterfaceException |
|
| 1015 | - * @throws ReflectionException |
|
| 1016 | - */ |
|
| 1017 | - public function total_line_item($create_if_not_found = true) |
|
| 1018 | - { |
|
| 1019 | - $item = $this->get_first_related('Line_Item', array(array('LIN_type' => EEM_Line_Item::type_total))); |
|
| 1020 | - if (! $item && $create_if_not_found) { |
|
| 1021 | - $item = EEH_Line_Item::create_total_line_item($this); |
|
| 1022 | - } |
|
| 1023 | - return $item; |
|
| 1024 | - } |
|
| 1025 | - |
|
| 1026 | - |
|
| 1027 | - /** |
|
| 1028 | - * Returns the total amount of tax on this transaction |
|
| 1029 | - * (assumes there's only one tax subtotal line item) |
|
| 1030 | - * |
|
| 1031 | - * @return float |
|
| 1032 | - * @throws EE_Error |
|
| 1033 | - * @throws InvalidArgumentException |
|
| 1034 | - * @throws InvalidDataTypeException |
|
| 1035 | - * @throws InvalidInterfaceException |
|
| 1036 | - * @throws ReflectionException |
|
| 1037 | - */ |
|
| 1038 | - public function tax_total() |
|
| 1039 | - { |
|
| 1040 | - $tax_line_item = $this->tax_total_line_item(); |
|
| 1041 | - if ($tax_line_item) { |
|
| 1042 | - return (float) $tax_line_item->total(); |
|
| 1043 | - } |
|
| 1044 | - return (float) 0; |
|
| 1045 | - } |
|
| 1046 | - |
|
| 1047 | - |
|
| 1048 | - /** |
|
| 1049 | - * Gets the tax subtotal line item (assumes there's only one) |
|
| 1050 | - * |
|
| 1051 | - * @return EE_Line_Item |
|
| 1052 | - * @throws EE_Error |
|
| 1053 | - * @throws InvalidArgumentException |
|
| 1054 | - * @throws InvalidDataTypeException |
|
| 1055 | - * @throws InvalidInterfaceException |
|
| 1056 | - * @throws ReflectionException |
|
| 1057 | - */ |
|
| 1058 | - public function tax_total_line_item() |
|
| 1059 | - { |
|
| 1060 | - return EEH_Line_Item::get_taxes_subtotal($this->total_line_item()); |
|
| 1061 | - } |
|
| 1062 | - |
|
| 1063 | - |
|
| 1064 | - /** |
|
| 1065 | - * Gets the array of billing info for the gateway and for this transaction's primary registration's attendee. |
|
| 1066 | - * |
|
| 1067 | - * @return EE_Form_Section_Proper |
|
| 1068 | - * @throws EE_Error |
|
| 1069 | - * @throws InvalidArgumentException |
|
| 1070 | - * @throws InvalidDataTypeException |
|
| 1071 | - * @throws InvalidInterfaceException |
|
| 1072 | - * @throws ReflectionException |
|
| 1073 | - */ |
|
| 1074 | - public function billing_info() |
|
| 1075 | - { |
|
| 1076 | - $payment_method = $this->payment_method(); |
|
| 1077 | - if (! $payment_method) { |
|
| 1078 | - EE_Error::add_error( |
|
| 1079 | - __( |
|
| 1080 | - 'Could not find billing info for transaction because no gateway has been used for it yet', |
|
| 1081 | - 'event_espresso' |
|
| 1082 | - ), |
|
| 1083 | - __FILE__, |
|
| 1084 | - __FUNCTION__, |
|
| 1085 | - __LINE__ |
|
| 1086 | - ); |
|
| 1087 | - return null; |
|
| 1088 | - } |
|
| 1089 | - $primary_reg = $this->primary_registration(); |
|
| 1090 | - if (! $primary_reg) { |
|
| 1091 | - EE_Error::add_error( |
|
| 1092 | - __( |
|
| 1093 | - 'Cannot get billing info for gateway %s on transaction because no primary registration exists', |
|
| 1094 | - 'event_espresso' |
|
| 1095 | - ), |
|
| 1096 | - __FILE__, |
|
| 1097 | - __FUNCTION__, |
|
| 1098 | - __LINE__ |
|
| 1099 | - ); |
|
| 1100 | - return null; |
|
| 1101 | - } |
|
| 1102 | - $attendee = $primary_reg->attendee(); |
|
| 1103 | - if (! $attendee) { |
|
| 1104 | - EE_Error::add_error( |
|
| 1105 | - __( |
|
| 1106 | - 'Cannot get billing info for gateway %s on transaction because the primary registration has no attendee exists', |
|
| 1107 | - 'event_espresso' |
|
| 1108 | - ), |
|
| 1109 | - __FILE__, |
|
| 1110 | - __FUNCTION__, |
|
| 1111 | - __LINE__ |
|
| 1112 | - ); |
|
| 1113 | - return null; |
|
| 1114 | - } |
|
| 1115 | - return $attendee->billing_info_for_payment_method($payment_method); |
|
| 1116 | - } |
|
| 1117 | - |
|
| 1118 | - |
|
| 1119 | - /** |
|
| 1120 | - * Gets PMD_ID |
|
| 1121 | - * |
|
| 1122 | - * @return int |
|
| 1123 | - * @throws EE_Error |
|
| 1124 | - * @throws InvalidArgumentException |
|
| 1125 | - * @throws InvalidDataTypeException |
|
| 1126 | - * @throws InvalidInterfaceException |
|
| 1127 | - * @throws ReflectionException |
|
| 1128 | - */ |
|
| 1129 | - public function payment_method_ID() |
|
| 1130 | - { |
|
| 1131 | - return $this->get('PMD_ID'); |
|
| 1132 | - } |
|
| 1133 | - |
|
| 1134 | - |
|
| 1135 | - /** |
|
| 1136 | - * Sets PMD_ID |
|
| 1137 | - * |
|
| 1138 | - * @param int $PMD_ID |
|
| 1139 | - * @throws EE_Error |
|
| 1140 | - * @throws InvalidArgumentException |
|
| 1141 | - * @throws InvalidDataTypeException |
|
| 1142 | - * @throws InvalidInterfaceException |
|
| 1143 | - * @throws ReflectionException |
|
| 1144 | - */ |
|
| 1145 | - public function set_payment_method_ID($PMD_ID) |
|
| 1146 | - { |
|
| 1147 | - $this->set('PMD_ID', $PMD_ID); |
|
| 1148 | - } |
|
| 1149 | - |
|
| 1150 | - |
|
| 1151 | - /** |
|
| 1152 | - * Gets the last-used payment method on this transaction |
|
| 1153 | - * (we COULD just use the last-made payment, but some payment methods, namely |
|
| 1154 | - * offline ones, dont' create payments) |
|
| 1155 | - * |
|
| 1156 | - * @return EE_Payment_Method |
|
| 1157 | - * @throws EE_Error |
|
| 1158 | - * @throws InvalidArgumentException |
|
| 1159 | - * @throws InvalidDataTypeException |
|
| 1160 | - * @throws InvalidInterfaceException |
|
| 1161 | - * @throws ReflectionException |
|
| 1162 | - */ |
|
| 1163 | - public function payment_method() |
|
| 1164 | - { |
|
| 1165 | - $pm = $this->get_first_related('Payment_Method'); |
|
| 1166 | - if ($pm instanceof EE_Payment_Method) { |
|
| 1167 | - return $pm; |
|
| 1168 | - } |
|
| 1169 | - $last_payment = $this->last_payment(); |
|
| 1170 | - if ($last_payment instanceof EE_Payment && $last_payment->payment_method()) { |
|
| 1171 | - return $last_payment->payment_method(); |
|
| 1172 | - } |
|
| 1173 | - return null; |
|
| 1174 | - } |
|
| 1175 | - |
|
| 1176 | - |
|
| 1177 | - /** |
|
| 1178 | - * Gets the last payment made |
|
| 1179 | - * |
|
| 1180 | - * @return EE_Base_Class|EE_Payment |
|
| 1181 | - * @throws EE_Error |
|
| 1182 | - * @throws InvalidArgumentException |
|
| 1183 | - * @throws InvalidDataTypeException |
|
| 1184 | - * @throws InvalidInterfaceException |
|
| 1185 | - * @throws ReflectionException |
|
| 1186 | - */ |
|
| 1187 | - public function last_payment() |
|
| 1188 | - { |
|
| 1189 | - return $this->get_first_related('Payment', array('order_by' => array('PAY_ID' => 'desc'))); |
|
| 1190 | - } |
|
| 1191 | - |
|
| 1192 | - |
|
| 1193 | - /** |
|
| 1194 | - * Gets all the line items which are unrelated to tickets on this transaction |
|
| 1195 | - * |
|
| 1196 | - * @return EE_Line_Item[] |
|
| 1197 | - * @throws EE_Error |
|
| 1198 | - * @throws InvalidArgumentException |
|
| 1199 | - * @throws InvalidDataTypeException |
|
| 1200 | - * @throws InvalidInterfaceException |
|
| 1201 | - * @throws ReflectionException |
|
| 1202 | - */ |
|
| 1203 | - public function non_ticket_line_items() |
|
| 1204 | - { |
|
| 1205 | - return EEM_Line_Item::instance()->get_all_non_ticket_line_items_for_transaction($this->ID()); |
|
| 1206 | - } |
|
| 1207 | - |
|
| 1208 | - |
|
| 1209 | - /** |
|
| 1210 | - * possibly toggles TXN status |
|
| 1211 | - * |
|
| 1212 | - * @param boolean $update whether to save the TXN |
|
| 1213 | - * @return bool whether the TXN was saved |
|
| 1214 | - * @throws EE_Error |
|
| 1215 | - * @throws InvalidArgumentException |
|
| 1216 | - * @throws InvalidDataTypeException |
|
| 1217 | - * @throws InvalidInterfaceException |
|
| 1218 | - * @throws ReflectionException |
|
| 1219 | - * @throws RuntimeException |
|
| 1220 | - */ |
|
| 1221 | - public function update_status_based_on_total_paid($update = true) |
|
| 1222 | - { |
|
| 1223 | - // set transaction status based on comparison of TXN_paid vs TXN_total |
|
| 1224 | - if (EEH_Money::compare_floats($this->paid(), $this->total(), '>')) { |
|
| 1225 | - $new_txn_status = EEM_Transaction::overpaid_status_code; |
|
| 1226 | - } elseif (EEH_Money::compare_floats($this->paid(), $this->total())) { |
|
| 1227 | - $new_txn_status = EEM_Transaction::complete_status_code; |
|
| 1228 | - } elseif (EEH_Money::compare_floats($this->paid(), $this->total(), '<')) { |
|
| 1229 | - $new_txn_status = EEM_Transaction::incomplete_status_code; |
|
| 1230 | - } else { |
|
| 1231 | - throw new RuntimeException( |
|
| 1232 | - __('The total paid calculation for this transaction is inaccurate.', 'event_espresso') |
|
| 1233 | - ); |
|
| 1234 | - } |
|
| 1235 | - if ($new_txn_status !== $this->status_ID()) { |
|
| 1236 | - $this->set_status($new_txn_status); |
|
| 1237 | - if ($update) { |
|
| 1238 | - return $this->save() ? true : false; |
|
| 1239 | - } |
|
| 1240 | - } |
|
| 1241 | - return false; |
|
| 1242 | - } |
|
| 1243 | - |
|
| 1244 | - |
|
| 1245 | - /** |
|
| 1246 | - * Updates the transaction's status and total_paid based on all the payments |
|
| 1247 | - * that apply to it |
|
| 1248 | - * |
|
| 1249 | - * @deprecated |
|
| 1250 | - * @return array|bool |
|
| 1251 | - * @throws EE_Error |
|
| 1252 | - * @throws InvalidArgumentException |
|
| 1253 | - * @throws ReflectionException |
|
| 1254 | - * @throws InvalidDataTypeException |
|
| 1255 | - * @throws InvalidInterfaceException |
|
| 1256 | - */ |
|
| 1257 | - public function update_based_on_payments() |
|
| 1258 | - { |
|
| 1259 | - EE_Error::doing_it_wrong( |
|
| 1260 | - __CLASS__ . '::' . __FUNCTION__, |
|
| 1261 | - sprintf( |
|
| 1262 | - __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
| 1263 | - 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
|
| 1264 | - ), |
|
| 1265 | - '4.6.0' |
|
| 1266 | - ); |
|
| 1267 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 1268 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 1269 | - return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($this); |
|
| 1270 | - } |
|
| 1271 | - |
|
| 1272 | - |
|
| 1273 | - /** |
|
| 1274 | - * @return string |
|
| 1275 | - */ |
|
| 1276 | - public function old_txn_status() |
|
| 1277 | - { |
|
| 1278 | - return $this->_old_txn_status; |
|
| 1279 | - } |
|
| 1280 | - |
|
| 1281 | - |
|
| 1282 | - /** |
|
| 1283 | - * @param string $old_txn_status |
|
| 1284 | - */ |
|
| 1285 | - public function set_old_txn_status($old_txn_status) |
|
| 1286 | - { |
|
| 1287 | - // only set the first time |
|
| 1288 | - if ($this->_old_txn_status === null) { |
|
| 1289 | - $this->_old_txn_status = $old_txn_status; |
|
| 1290 | - } |
|
| 1291 | - } |
|
| 1292 | - |
|
| 1293 | - |
|
| 1294 | - /** |
|
| 1295 | - * reg_status_updated |
|
| 1296 | - * |
|
| 1297 | - * @return bool |
|
| 1298 | - * @throws EE_Error |
|
| 1299 | - * @throws InvalidArgumentException |
|
| 1300 | - * @throws InvalidDataTypeException |
|
| 1301 | - * @throws InvalidInterfaceException |
|
| 1302 | - * @throws ReflectionException |
|
| 1303 | - */ |
|
| 1304 | - public function txn_status_updated() |
|
| 1305 | - { |
|
| 1306 | - return $this->status_ID() !== $this->_old_txn_status && $this->_old_txn_status !== null; |
|
| 1307 | - } |
|
| 1308 | - |
|
| 1309 | - |
|
| 1310 | - /** |
|
| 1311 | - * _reg_steps_completed |
|
| 1312 | - * if $check_all is TRUE, then returns TRUE if ALL reg steps have been marked as completed, |
|
| 1313 | - * if a $reg_step_slug is provided, then this step will be skipped when testing for completion |
|
| 1314 | - * if $check_all is FALSE and a $reg_step_slug is provided, then ONLY that reg step will be tested for completion |
|
| 1315 | - * |
|
| 1316 | - * @param string $reg_step_slug |
|
| 1317 | - * @param bool $check_all |
|
| 1318 | - * @return bool|int |
|
| 1319 | - * @throws EE_Error |
|
| 1320 | - * @throws InvalidArgumentException |
|
| 1321 | - * @throws InvalidDataTypeException |
|
| 1322 | - * @throws InvalidInterfaceException |
|
| 1323 | - * @throws ReflectionException |
|
| 1324 | - */ |
|
| 1325 | - private function _reg_steps_completed($reg_step_slug = '', $check_all = true) |
|
| 1326 | - { |
|
| 1327 | - $reg_steps = $this->reg_steps(); |
|
| 1328 | - if (! is_array($reg_steps) || empty($reg_steps)) { |
|
| 1329 | - return false; |
|
| 1330 | - } |
|
| 1331 | - // loop thru reg steps array) |
|
| 1332 | - foreach ($reg_steps as $slug => $reg_step_completed) { |
|
| 1333 | - // if NOT checking ALL steps (only checking one step) |
|
| 1334 | - if (! $check_all) { |
|
| 1335 | - // and this is the one |
|
| 1336 | - if ($slug === $reg_step_slug) { |
|
| 1337 | - return $reg_step_completed; |
|
| 1338 | - } |
|
| 1339 | - // skip to next reg step in loop |
|
| 1340 | - continue; |
|
| 1341 | - } |
|
| 1342 | - // $check_all must be true, else we would never have gotten to this point |
|
| 1343 | - if ($slug === $reg_step_slug) { |
|
| 1344 | - // if we reach this point, then we are testing either: |
|
| 1345 | - // all_reg_steps_completed_except() or |
|
| 1346 | - // all_reg_steps_completed_except_final_step(), |
|
| 1347 | - // and since this is the reg step EXCEPTION being tested |
|
| 1348 | - // we want to return true (yes true) if this reg step is NOT completed |
|
| 1349 | - // ie: "is everything completed except the final step?" |
|
| 1350 | - // "that is correct... the final step is not completed, but all others are." |
|
| 1351 | - return $reg_step_completed !== true; |
|
| 1352 | - } |
|
| 1353 | - if ($reg_step_completed !== true) { |
|
| 1354 | - // if any reg step is NOT completed, then ALL steps are not completed |
|
| 1355 | - return false; |
|
| 1356 | - } |
|
| 1357 | - } |
|
| 1358 | - return true; |
|
| 1359 | - } |
|
| 1360 | - |
|
| 1361 | - |
|
| 1362 | - /** |
|
| 1363 | - * all_reg_steps_completed |
|
| 1364 | - * returns: |
|
| 1365 | - * true if ALL reg steps have been marked as completed |
|
| 1366 | - * or false if any step is not completed |
|
| 1367 | - * |
|
| 1368 | - * @return bool |
|
| 1369 | - * @throws EE_Error |
|
| 1370 | - * @throws InvalidArgumentException |
|
| 1371 | - * @throws InvalidDataTypeException |
|
| 1372 | - * @throws InvalidInterfaceException |
|
| 1373 | - * @throws ReflectionException |
|
| 1374 | - */ |
|
| 1375 | - public function all_reg_steps_completed() |
|
| 1376 | - { |
|
| 1377 | - return $this->_reg_steps_completed(); |
|
| 1378 | - } |
|
| 1379 | - |
|
| 1380 | - |
|
| 1381 | - /** |
|
| 1382 | - * all_reg_steps_completed_except |
|
| 1383 | - * returns: |
|
| 1384 | - * true if ALL reg steps, except a particular step that you wish to skip over, have been marked as completed |
|
| 1385 | - * or false if any other step is not completed |
|
| 1386 | - * or false if ALL steps are completed including the exception you are testing !!! |
|
| 1387 | - * |
|
| 1388 | - * @param string $exception |
|
| 1389 | - * @return bool |
|
| 1390 | - * @throws EE_Error |
|
| 1391 | - * @throws InvalidArgumentException |
|
| 1392 | - * @throws InvalidDataTypeException |
|
| 1393 | - * @throws InvalidInterfaceException |
|
| 1394 | - * @throws ReflectionException |
|
| 1395 | - */ |
|
| 1396 | - public function all_reg_steps_completed_except($exception = '') |
|
| 1397 | - { |
|
| 1398 | - return $this->_reg_steps_completed($exception); |
|
| 1399 | - } |
|
| 1400 | - |
|
| 1401 | - |
|
| 1402 | - /** |
|
| 1403 | - * all_reg_steps_completed_except |
|
| 1404 | - * returns: |
|
| 1405 | - * true if ALL reg steps, except the final step, have been marked as completed |
|
| 1406 | - * or false if any step is not completed |
|
| 1407 | - * or false if ALL steps are completed including the final step !!! |
|
| 1408 | - * |
|
| 1409 | - * @return bool |
|
| 1410 | - * @throws EE_Error |
|
| 1411 | - * @throws InvalidArgumentException |
|
| 1412 | - * @throws InvalidDataTypeException |
|
| 1413 | - * @throws InvalidInterfaceException |
|
| 1414 | - * @throws ReflectionException |
|
| 1415 | - */ |
|
| 1416 | - public function all_reg_steps_completed_except_final_step() |
|
| 1417 | - { |
|
| 1418 | - return $this->_reg_steps_completed('finalize_registration'); |
|
| 1419 | - } |
|
| 1420 | - |
|
| 1421 | - |
|
| 1422 | - /** |
|
| 1423 | - * reg_step_completed |
|
| 1424 | - * returns: |
|
| 1425 | - * true if a specific reg step has been marked as completed |
|
| 1426 | - * a Unix timestamp if it has been initialized but not yet completed, |
|
| 1427 | - * or false if it has not yet been initialized |
|
| 1428 | - * |
|
| 1429 | - * @param string $reg_step_slug |
|
| 1430 | - * @return bool|int |
|
| 1431 | - * @throws EE_Error |
|
| 1432 | - * @throws InvalidArgumentException |
|
| 1433 | - * @throws InvalidDataTypeException |
|
| 1434 | - * @throws InvalidInterfaceException |
|
| 1435 | - * @throws ReflectionException |
|
| 1436 | - */ |
|
| 1437 | - public function reg_step_completed($reg_step_slug) |
|
| 1438 | - { |
|
| 1439 | - return $this->_reg_steps_completed($reg_step_slug, false); |
|
| 1440 | - } |
|
| 1441 | - |
|
| 1442 | - |
|
| 1443 | - /** |
|
| 1444 | - * completed_final_reg_step |
|
| 1445 | - * returns: |
|
| 1446 | - * true if the finalize_registration reg step has been marked as completed |
|
| 1447 | - * a Unix timestamp if it has been initialized but not yet completed, |
|
| 1448 | - * or false if it has not yet been initialized |
|
| 1449 | - * |
|
| 1450 | - * @return bool|int |
|
| 1451 | - * @throws EE_Error |
|
| 1452 | - * @throws InvalidArgumentException |
|
| 1453 | - * @throws InvalidDataTypeException |
|
| 1454 | - * @throws InvalidInterfaceException |
|
| 1455 | - * @throws ReflectionException |
|
| 1456 | - */ |
|
| 1457 | - public function final_reg_step_completed() |
|
| 1458 | - { |
|
| 1459 | - return $this->_reg_steps_completed('finalize_registration', false); |
|
| 1460 | - } |
|
| 1461 | - |
|
| 1462 | - |
|
| 1463 | - /** |
|
| 1464 | - * set_reg_step_initiated |
|
| 1465 | - * given a valid TXN_reg_step, this sets it's value to a unix timestamp |
|
| 1466 | - * |
|
| 1467 | - * @param string $reg_step_slug |
|
| 1468 | - * @return boolean |
|
| 1469 | - * @throws EE_Error |
|
| 1470 | - * @throws InvalidArgumentException |
|
| 1471 | - * @throws InvalidDataTypeException |
|
| 1472 | - * @throws InvalidInterfaceException |
|
| 1473 | - * @throws ReflectionException |
|
| 1474 | - */ |
|
| 1475 | - public function set_reg_step_initiated($reg_step_slug) |
|
| 1476 | - { |
|
| 1477 | - return $this->_set_reg_step_completed_status($reg_step_slug, time()); |
|
| 1478 | - } |
|
| 1479 | - |
|
| 1480 | - |
|
| 1481 | - /** |
|
| 1482 | - * set_reg_step_completed |
|
| 1483 | - * given a valid TXN_reg_step, this sets the step as completed |
|
| 1484 | - * |
|
| 1485 | - * @param string $reg_step_slug |
|
| 1486 | - * @return boolean |
|
| 1487 | - * @throws EE_Error |
|
| 1488 | - * @throws InvalidArgumentException |
|
| 1489 | - * @throws InvalidDataTypeException |
|
| 1490 | - * @throws InvalidInterfaceException |
|
| 1491 | - * @throws ReflectionException |
|
| 1492 | - */ |
|
| 1493 | - public function set_reg_step_completed($reg_step_slug) |
|
| 1494 | - { |
|
| 1495 | - return $this->_set_reg_step_completed_status($reg_step_slug, true); |
|
| 1496 | - } |
|
| 1497 | - |
|
| 1498 | - |
|
| 1499 | - /** |
|
| 1500 | - * set_reg_step_completed |
|
| 1501 | - * given a valid TXN_reg_step slug, this sets the step as NOT completed |
|
| 1502 | - * |
|
| 1503 | - * @param string $reg_step_slug |
|
| 1504 | - * @return boolean |
|
| 1505 | - * @throws EE_Error |
|
| 1506 | - * @throws InvalidArgumentException |
|
| 1507 | - * @throws InvalidDataTypeException |
|
| 1508 | - * @throws InvalidInterfaceException |
|
| 1509 | - * @throws ReflectionException |
|
| 1510 | - */ |
|
| 1511 | - public function set_reg_step_not_completed($reg_step_slug) |
|
| 1512 | - { |
|
| 1513 | - return $this->_set_reg_step_completed_status($reg_step_slug, false); |
|
| 1514 | - } |
|
| 1515 | - |
|
| 1516 | - |
|
| 1517 | - /** |
|
| 1518 | - * set_reg_step_completed |
|
| 1519 | - * given a valid reg step slug, this sets the TXN_reg_step completed status which is either: |
|
| 1520 | - * |
|
| 1521 | - * @param string $reg_step_slug |
|
| 1522 | - * @param boolean|int $status |
|
| 1523 | - * @return boolean |
|
| 1524 | - * @throws EE_Error |
|
| 1525 | - * @throws InvalidArgumentException |
|
| 1526 | - * @throws InvalidDataTypeException |
|
| 1527 | - * @throws InvalidInterfaceException |
|
| 1528 | - * @throws ReflectionException |
|
| 1529 | - */ |
|
| 1530 | - private function _set_reg_step_completed_status($reg_step_slug, $status) |
|
| 1531 | - { |
|
| 1532 | - // validate status |
|
| 1533 | - $status = is_bool($status) || is_int($status) ? $status : false; |
|
| 1534 | - // get reg steps array |
|
| 1535 | - $txn_reg_steps = $this->reg_steps(); |
|
| 1536 | - // if reg step does NOT exist |
|
| 1537 | - if (! isset($txn_reg_steps[ $reg_step_slug ])) { |
|
| 1538 | - return false; |
|
| 1539 | - } |
|
| 1540 | - // if we're trying to complete a step that is already completed |
|
| 1541 | - if ($txn_reg_steps[ $reg_step_slug ] === true) { |
|
| 1542 | - return true; |
|
| 1543 | - } |
|
| 1544 | - // if we're trying to complete a step that hasn't even started |
|
| 1545 | - if ($status === true && $txn_reg_steps[ $reg_step_slug ] === false) { |
|
| 1546 | - return false; |
|
| 1547 | - } |
|
| 1548 | - // if current status value matches the incoming value (no change) |
|
| 1549 | - // type casting as int means values should collapse to either 0, 1, or a timestamp like 1234567890 |
|
| 1550 | - if ((int) $txn_reg_steps[ $reg_step_slug ] === (int) $status) { |
|
| 1551 | - // this will happen in cases where multiple AJAX requests occur during the same step |
|
| 1552 | - return true; |
|
| 1553 | - } |
|
| 1554 | - // if we're trying to set a start time, but it has already been set... |
|
| 1555 | - if (is_numeric($status) && is_numeric($txn_reg_steps[ $reg_step_slug ])) { |
|
| 1556 | - // skip the update below, but don't return FALSE so that errors won't be displayed |
|
| 1557 | - return true; |
|
| 1558 | - } |
|
| 1559 | - // update completed status |
|
| 1560 | - $txn_reg_steps[ $reg_step_slug ] = $status; |
|
| 1561 | - $this->set_reg_steps($txn_reg_steps); |
|
| 1562 | - $this->save(); |
|
| 1563 | - return true; |
|
| 1564 | - } |
|
| 1565 | - |
|
| 1566 | - |
|
| 1567 | - /** |
|
| 1568 | - * remove_reg_step |
|
| 1569 | - * given a valid TXN_reg_step slug, this will remove (unset) |
|
| 1570 | - * the reg step from the TXN reg step array |
|
| 1571 | - * |
|
| 1572 | - * @param string $reg_step_slug |
|
| 1573 | - * @return void |
|
| 1574 | - * @throws EE_Error |
|
| 1575 | - * @throws InvalidArgumentException |
|
| 1576 | - * @throws InvalidDataTypeException |
|
| 1577 | - * @throws InvalidInterfaceException |
|
| 1578 | - * @throws ReflectionException |
|
| 1579 | - */ |
|
| 1580 | - public function remove_reg_step($reg_step_slug) |
|
| 1581 | - { |
|
| 1582 | - // get reg steps array |
|
| 1583 | - $txn_reg_steps = $this->reg_steps(); |
|
| 1584 | - unset($txn_reg_steps[ $reg_step_slug ]); |
|
| 1585 | - $this->set_reg_steps($txn_reg_steps); |
|
| 1586 | - } |
|
| 1587 | - |
|
| 1588 | - |
|
| 1589 | - /** |
|
| 1590 | - * toggle_failed_transaction_status |
|
| 1591 | - * upgrades a TXNs status from failed to abandoned, |
|
| 1592 | - * meaning that contact information has been captured for at least one registrant |
|
| 1593 | - * |
|
| 1594 | - * @param bool $save |
|
| 1595 | - * @return bool |
|
| 1596 | - * @throws EE_Error |
|
| 1597 | - * @throws InvalidArgumentException |
|
| 1598 | - * @throws InvalidDataTypeException |
|
| 1599 | - * @throws InvalidInterfaceException |
|
| 1600 | - * @throws ReflectionException |
|
| 1601 | - */ |
|
| 1602 | - public function toggle_failed_transaction_status($save = true) |
|
| 1603 | - { |
|
| 1604 | - // if TXN status is still set as "failed"... |
|
| 1605 | - if ($this->status_ID() === EEM_Transaction::failed_status_code) { |
|
| 1606 | - $this->set_status(EEM_Transaction::abandoned_status_code); |
|
| 1607 | - if ($save) { |
|
| 1608 | - $this->save(); |
|
| 1609 | - } |
|
| 1610 | - return true; |
|
| 1611 | - } |
|
| 1612 | - return false; |
|
| 1613 | - } |
|
| 1614 | - |
|
| 1615 | - |
|
| 1616 | - /** |
|
| 1617 | - * toggle_abandoned_transaction_status |
|
| 1618 | - * upgrades a TXNs status from failed or abandoned to incomplete |
|
| 1619 | - * |
|
| 1620 | - * @return bool |
|
| 1621 | - * @throws EE_Error |
|
| 1622 | - * @throws InvalidArgumentException |
|
| 1623 | - * @throws InvalidDataTypeException |
|
| 1624 | - * @throws InvalidInterfaceException |
|
| 1625 | - * @throws ReflectionException |
|
| 1626 | - */ |
|
| 1627 | - public function toggle_abandoned_transaction_status() |
|
| 1628 | - { |
|
| 1629 | - // if TXN status has not been updated already due to a payment, and is still set as "failed" or "abandoned"... |
|
| 1630 | - $txn_status = $this->status_ID(); |
|
| 1631 | - if ( |
|
| 1632 | - $txn_status === EEM_Transaction::failed_status_code |
|
| 1633 | - || $txn_status === EEM_Transaction::abandoned_status_code |
|
| 1634 | - ) { |
|
| 1635 | - // if a contact record for the primary registrant has been created |
|
| 1636 | - if ( |
|
| 1637 | - $this->primary_registration() instanceof EE_Registration |
|
| 1638 | - && $this->primary_registration()->attendee() instanceof EE_Attendee |
|
| 1639 | - ) { |
|
| 1640 | - $this->set_status(EEM_Transaction::incomplete_status_code); |
|
| 1641 | - } else { |
|
| 1642 | - // no contact record? yer abandoned! |
|
| 1643 | - $this->set_status(EEM_Transaction::abandoned_status_code); |
|
| 1644 | - } |
|
| 1645 | - return true; |
|
| 1646 | - } |
|
| 1647 | - return false; |
|
| 1648 | - } |
|
| 1649 | - |
|
| 1650 | - |
|
| 1651 | - /** |
|
| 1652 | - * checks if an Abandoned TXN has any related payments, and if so, |
|
| 1653 | - * updates the TXN status based on the amount paid |
|
| 1654 | - * |
|
| 1655 | - * @throws EE_Error |
|
| 1656 | - * @throws InvalidDataTypeException |
|
| 1657 | - * @throws InvalidInterfaceException |
|
| 1658 | - * @throws InvalidArgumentException |
|
| 1659 | - * @throws RuntimeException |
|
| 1660 | - * @throws ReflectionException |
|
| 1661 | - */ |
|
| 1662 | - public function verify_abandoned_transaction_status() |
|
| 1663 | - { |
|
| 1664 | - if ($this->status_ID() !== EEM_Transaction::abandoned_status_code) { |
|
| 1665 | - return; |
|
| 1666 | - } |
|
| 1667 | - $payments = $this->get_many_related('Payment'); |
|
| 1668 | - if (! empty($payments)) { |
|
| 1669 | - foreach ($payments as $payment) { |
|
| 1670 | - if ($payment instanceof EE_Payment) { |
|
| 1671 | - // kk this TXN should NOT be abandoned |
|
| 1672 | - $this->update_status_based_on_total_paid(); |
|
| 1673 | - if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) { |
|
| 1674 | - EE_Error::add_attention( |
|
| 1675 | - sprintf( |
|
| 1676 | - esc_html__( |
|
| 1677 | - 'The status for Transaction #%1$d has been updated from "Abandoned" to "%2$s", because at least one payment has been made towards it. If the payment appears in the "Payment Details" table below, you may need to edit its status and/or other details as well.', |
|
| 1678 | - 'event_espresso' |
|
| 1679 | - ), |
|
| 1680 | - $this->ID(), |
|
| 1681 | - $this->pretty_status() |
|
| 1682 | - ) |
|
| 1683 | - ); |
|
| 1684 | - } |
|
| 1685 | - // get final reg step status |
|
| 1686 | - $finalized = $this->final_reg_step_completed(); |
|
| 1687 | - // if the 'finalize_registration' step has been initiated (has a timestamp) |
|
| 1688 | - // but has not yet been fully completed (TRUE) |
|
| 1689 | - if (is_int($finalized) && $finalized !== false && $finalized !== true) { |
|
| 1690 | - $this->set_reg_step_completed('finalize_registration'); |
|
| 1691 | - $this->save(); |
|
| 1692 | - } |
|
| 1693 | - } |
|
| 1694 | - } |
|
| 1695 | - } |
|
| 1696 | - } |
|
| 1697 | - |
|
| 1698 | - |
|
| 1699 | - /** |
|
| 1700 | - * @since 4.10.4.p |
|
| 1701 | - * @throws EE_Error |
|
| 1702 | - * @throws InvalidArgumentException |
|
| 1703 | - * @throws InvalidDataTypeException |
|
| 1704 | - * @throws InvalidInterfaceException |
|
| 1705 | - * @throws ReflectionException |
|
| 1706 | - * @throws RuntimeException |
|
| 1707 | - */ |
|
| 1708 | - public function recalculateLineItems() |
|
| 1709 | - { |
|
| 1710 | - $total_line_item = $this->total_line_item(false); |
|
| 1711 | - if ($total_line_item instanceof EE_Line_Item) { |
|
| 1712 | - EEH_Line_Item::resetIsTaxableForTickets($total_line_item); |
|
| 1713 | - return EEH_Line_Item::apply_taxes($total_line_item, true); |
|
| 1714 | - } |
|
| 1715 | - return false; |
|
| 1716 | - } |
|
| 16 | + /** |
|
| 17 | + * The length of time in seconds that a lock is applied before being considered expired. |
|
| 18 | + * It is not long because a transaction should only be locked for the duration of the request that locked it |
|
| 19 | + */ |
|
| 20 | + const LOCK_EXPIRATION = 2; |
|
| 21 | + |
|
| 22 | + /** |
|
| 23 | + * txn status upon initial construction. |
|
| 24 | + * |
|
| 25 | + * @var string |
|
| 26 | + */ |
|
| 27 | + protected $_old_txn_status; |
|
| 28 | + |
|
| 29 | + |
|
| 30 | + /** |
|
| 31 | + * @param array $props_n_values incoming values |
|
| 32 | + * @param string $timezone incoming timezone |
|
| 33 | + * (if not set the timezone set for the website will be used.) |
|
| 34 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 35 | + * date_format and the second value is the time format |
|
| 36 | + * @return EE_Transaction |
|
| 37 | + * @throws EE_Error |
|
| 38 | + * @throws InvalidArgumentException |
|
| 39 | + * @throws InvalidDataTypeException |
|
| 40 | + * @throws InvalidInterfaceException |
|
| 41 | + * @throws ReflectionException |
|
| 42 | + */ |
|
| 43 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 44 | + { |
|
| 45 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 46 | + $txn = $has_object |
|
| 47 | + ? $has_object |
|
| 48 | + : new self($props_n_values, false, $timezone, $date_formats); |
|
| 49 | + if (! $has_object) { |
|
| 50 | + $txn->set_old_txn_status($txn->status_ID()); |
|
| 51 | + } |
|
| 52 | + return $txn; |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * @param array $props_n_values incoming values from the database |
|
| 58 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 59 | + * the website will be used. |
|
| 60 | + * @return EE_Transaction |
|
| 61 | + * @throws EE_Error |
|
| 62 | + * @throws InvalidArgumentException |
|
| 63 | + * @throws InvalidDataTypeException |
|
| 64 | + * @throws InvalidInterfaceException |
|
| 65 | + * @throws ReflectionException |
|
| 66 | + */ |
|
| 67 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 68 | + { |
|
| 69 | + $txn = new self($props_n_values, true, $timezone); |
|
| 70 | + $txn->set_old_txn_status($txn->status_ID()); |
|
| 71 | + return $txn; |
|
| 72 | + } |
|
| 73 | + |
|
| 74 | + |
|
| 75 | + /** |
|
| 76 | + * Sets a meta field indicating that this TXN is locked and should not be updated in the db. |
|
| 77 | + * If a lock has already been set, then we will attempt to remove it in case it has expired. |
|
| 78 | + * If that also fails, then an exception is thrown. |
|
| 79 | + * |
|
| 80 | + * @throws EE_Error |
|
| 81 | + * @throws InvalidArgumentException |
|
| 82 | + * @throws InvalidDataTypeException |
|
| 83 | + * @throws InvalidInterfaceException |
|
| 84 | + * @throws ReflectionException |
|
| 85 | + */ |
|
| 86 | + public function lock() |
|
| 87 | + { |
|
| 88 | + // attempt to set lock, but if that fails... |
|
| 89 | + if (! $this->add_extra_meta('lock', time(), true)) { |
|
| 90 | + // then attempt to remove the lock in case it is expired |
|
| 91 | + if ($this->_remove_expired_lock()) { |
|
| 92 | + // if removal was successful, then try setting lock again |
|
| 93 | + $this->lock(); |
|
| 94 | + } else { |
|
| 95 | + // but if the lock can not be removed, then throw an exception |
|
| 96 | + throw new EE_Error( |
|
| 97 | + sprintf( |
|
| 98 | + __( |
|
| 99 | + 'Could not lock Transaction %1$d because it is already locked, meaning another part of the system is currently editing it. It should already be unlocked by the time you read this, so please refresh the page and try again.', |
|
| 100 | + 'event_espresso' |
|
| 101 | + ), |
|
| 102 | + $this->ID() |
|
| 103 | + ) |
|
| 104 | + ); |
|
| 105 | + } |
|
| 106 | + } |
|
| 107 | + } |
|
| 108 | + |
|
| 109 | + |
|
| 110 | + /** |
|
| 111 | + * removes transaction lock applied in EE_Transaction::lock() |
|
| 112 | + * |
|
| 113 | + * @return int |
|
| 114 | + * @throws EE_Error |
|
| 115 | + * @throws InvalidArgumentException |
|
| 116 | + * @throws InvalidDataTypeException |
|
| 117 | + * @throws InvalidInterfaceException |
|
| 118 | + * @throws ReflectionException |
|
| 119 | + */ |
|
| 120 | + public function unlock() |
|
| 121 | + { |
|
| 122 | + return $this->delete_extra_meta('lock'); |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + |
|
| 126 | + /** |
|
| 127 | + * Decides whether or not now is the right time to update the transaction. |
|
| 128 | + * This is useful because we don't always know if it is safe to update the transaction |
|
| 129 | + * and its related data. why? |
|
| 130 | + * because it's possible that the transaction is being used in another |
|
| 131 | + * request and could overwrite anything we save. |
|
| 132 | + * So we want to only update the txn once we know that won't happen. |
|
| 133 | + * We also check that the lock isn't expired, and remove it if it is |
|
| 134 | + * |
|
| 135 | + * @return boolean |
|
| 136 | + * @throws EE_Error |
|
| 137 | + * @throws InvalidArgumentException |
|
| 138 | + * @throws InvalidDataTypeException |
|
| 139 | + * @throws InvalidInterfaceException |
|
| 140 | + * @throws ReflectionException |
|
| 141 | + */ |
|
| 142 | + public function is_locked() |
|
| 143 | + { |
|
| 144 | + // if TXN is not locked, then return false immediately |
|
| 145 | + if (! $this->_get_lock()) { |
|
| 146 | + return false; |
|
| 147 | + } |
|
| 148 | + // if not, then let's try and remove the lock in case it's expired... |
|
| 149 | + // _remove_expired_lock() returns 0 when lock is valid (ie: removed = false) |
|
| 150 | + // and a positive number if the lock was removed (ie: number of locks deleted), |
|
| 151 | + // so we need to return the opposite |
|
| 152 | + return ! $this->_remove_expired_lock() ? true : false; |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + |
|
| 156 | + /** |
|
| 157 | + * Gets the meta field indicating that this TXN is locked |
|
| 158 | + * |
|
| 159 | + * @return int |
|
| 160 | + * @throws EE_Error |
|
| 161 | + * @throws InvalidArgumentException |
|
| 162 | + * @throws InvalidDataTypeException |
|
| 163 | + * @throws InvalidInterfaceException |
|
| 164 | + * @throws ReflectionException |
|
| 165 | + */ |
|
| 166 | + protected function _get_lock() |
|
| 167 | + { |
|
| 168 | + return (int) $this->get_extra_meta('lock', true, 0); |
|
| 169 | + } |
|
| 170 | + |
|
| 171 | + |
|
| 172 | + /** |
|
| 173 | + * If the lock on this transaction is expired, then we want to remove it so that the transaction can be updated |
|
| 174 | + * |
|
| 175 | + * @return int |
|
| 176 | + * @throws EE_Error |
|
| 177 | + * @throws InvalidArgumentException |
|
| 178 | + * @throws InvalidDataTypeException |
|
| 179 | + * @throws InvalidInterfaceException |
|
| 180 | + * @throws ReflectionException |
|
| 181 | + */ |
|
| 182 | + protected function _remove_expired_lock() |
|
| 183 | + { |
|
| 184 | + $locked = $this->_get_lock(); |
|
| 185 | + if ($locked && time() - EE_Transaction::LOCK_EXPIRATION > $locked) { |
|
| 186 | + return $this->unlock(); |
|
| 187 | + } |
|
| 188 | + return 0; |
|
| 189 | + } |
|
| 190 | + |
|
| 191 | + |
|
| 192 | + /** |
|
| 193 | + * Set transaction total |
|
| 194 | + * |
|
| 195 | + * @param float $total total value of transaction |
|
| 196 | + * @throws EE_Error |
|
| 197 | + * @throws InvalidArgumentException |
|
| 198 | + * @throws InvalidDataTypeException |
|
| 199 | + * @throws InvalidInterfaceException |
|
| 200 | + * @throws ReflectionException |
|
| 201 | + */ |
|
| 202 | + public function set_total($total = 0.00) |
|
| 203 | + { |
|
| 204 | + $this->set('TXN_total', (float) $total); |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + |
|
| 208 | + /** |
|
| 209 | + * Set Total Amount Paid to Date |
|
| 210 | + * |
|
| 211 | + * @param float $total_paid total amount paid to date (sum of all payments) |
|
| 212 | + * @throws EE_Error |
|
| 213 | + * @throws InvalidArgumentException |
|
| 214 | + * @throws InvalidDataTypeException |
|
| 215 | + * @throws InvalidInterfaceException |
|
| 216 | + * @throws ReflectionException |
|
| 217 | + */ |
|
| 218 | + public function set_paid($total_paid = 0.00) |
|
| 219 | + { |
|
| 220 | + $this->set('TXN_paid', (float) $total_paid); |
|
| 221 | + } |
|
| 222 | + |
|
| 223 | + |
|
| 224 | + /** |
|
| 225 | + * Set transaction status |
|
| 226 | + * |
|
| 227 | + * @param string $status whether the transaction is open, declined, accepted, |
|
| 228 | + * or any number of custom values that can be set |
|
| 229 | + * @throws EE_Error |
|
| 230 | + * @throws InvalidArgumentException |
|
| 231 | + * @throws InvalidDataTypeException |
|
| 232 | + * @throws InvalidInterfaceException |
|
| 233 | + * @throws ReflectionException |
|
| 234 | + */ |
|
| 235 | + public function set_status($status = '') |
|
| 236 | + { |
|
| 237 | + $this->set('STS_ID', $status); |
|
| 238 | + } |
|
| 239 | + |
|
| 240 | + |
|
| 241 | + /** |
|
| 242 | + * Set hash salt |
|
| 243 | + * |
|
| 244 | + * @param string $hash_salt required for some payment gateways |
|
| 245 | + * @throws EE_Error |
|
| 246 | + * @throws InvalidArgumentException |
|
| 247 | + * @throws InvalidDataTypeException |
|
| 248 | + * @throws InvalidInterfaceException |
|
| 249 | + * @throws ReflectionException |
|
| 250 | + */ |
|
| 251 | + public function set_hash_salt($hash_salt = '') |
|
| 252 | + { |
|
| 253 | + $this->set('TXN_hash_salt', $hash_salt); |
|
| 254 | + } |
|
| 255 | + |
|
| 256 | + |
|
| 257 | + /** |
|
| 258 | + * Sets TXN_reg_steps array |
|
| 259 | + * |
|
| 260 | + * @param array $txn_reg_steps |
|
| 261 | + * @throws EE_Error |
|
| 262 | + * @throws InvalidArgumentException |
|
| 263 | + * @throws InvalidDataTypeException |
|
| 264 | + * @throws InvalidInterfaceException |
|
| 265 | + * @throws ReflectionException |
|
| 266 | + */ |
|
| 267 | + public function set_reg_steps(array $txn_reg_steps) |
|
| 268 | + { |
|
| 269 | + $this->set('TXN_reg_steps', $txn_reg_steps); |
|
| 270 | + } |
|
| 271 | + |
|
| 272 | + |
|
| 273 | + /** |
|
| 274 | + * Gets TXN_reg_steps |
|
| 275 | + * |
|
| 276 | + * @return array |
|
| 277 | + * @throws EE_Error |
|
| 278 | + * @throws InvalidArgumentException |
|
| 279 | + * @throws InvalidDataTypeException |
|
| 280 | + * @throws InvalidInterfaceException |
|
| 281 | + * @throws ReflectionException |
|
| 282 | + */ |
|
| 283 | + public function reg_steps() |
|
| 284 | + { |
|
| 285 | + $TXN_reg_steps = $this->get('TXN_reg_steps'); |
|
| 286 | + return is_array($TXN_reg_steps) ? (array) $TXN_reg_steps : array(); |
|
| 287 | + } |
|
| 288 | + |
|
| 289 | + |
|
| 290 | + /** |
|
| 291 | + * @return string of transaction's total cost, with currency symbol and decimal |
|
| 292 | + * @throws EE_Error |
|
| 293 | + * @throws InvalidArgumentException |
|
| 294 | + * @throws InvalidDataTypeException |
|
| 295 | + * @throws InvalidInterfaceException |
|
| 296 | + * @throws ReflectionException |
|
| 297 | + */ |
|
| 298 | + public function pretty_total() |
|
| 299 | + { |
|
| 300 | + return $this->get_pretty('TXN_total'); |
|
| 301 | + } |
|
| 302 | + |
|
| 303 | + |
|
| 304 | + /** |
|
| 305 | + * Gets the amount paid in a pretty string (formatted and with currency symbol) |
|
| 306 | + * |
|
| 307 | + * @return string |
|
| 308 | + * @throws EE_Error |
|
| 309 | + * @throws InvalidArgumentException |
|
| 310 | + * @throws InvalidDataTypeException |
|
| 311 | + * @throws InvalidInterfaceException |
|
| 312 | + * @throws ReflectionException |
|
| 313 | + */ |
|
| 314 | + public function pretty_paid() |
|
| 315 | + { |
|
| 316 | + return $this->get_pretty('TXN_paid'); |
|
| 317 | + } |
|
| 318 | + |
|
| 319 | + |
|
| 320 | + /** |
|
| 321 | + * calculate the amount remaining for this transaction and return; |
|
| 322 | + * |
|
| 323 | + * @return float amount remaining |
|
| 324 | + * @throws EE_Error |
|
| 325 | + * @throws InvalidArgumentException |
|
| 326 | + * @throws InvalidDataTypeException |
|
| 327 | + * @throws InvalidInterfaceException |
|
| 328 | + * @throws ReflectionException |
|
| 329 | + */ |
|
| 330 | + public function remaining() |
|
| 331 | + { |
|
| 332 | + return $this->total() - $this->paid(); |
|
| 333 | + } |
|
| 334 | + |
|
| 335 | + |
|
| 336 | + /** |
|
| 337 | + * get Transaction Total |
|
| 338 | + * |
|
| 339 | + * @return float |
|
| 340 | + * @throws EE_Error |
|
| 341 | + * @throws InvalidArgumentException |
|
| 342 | + * @throws InvalidDataTypeException |
|
| 343 | + * @throws InvalidInterfaceException |
|
| 344 | + * @throws ReflectionException |
|
| 345 | + */ |
|
| 346 | + public function total() |
|
| 347 | + { |
|
| 348 | + return (float) $this->get('TXN_total'); |
|
| 349 | + } |
|
| 350 | + |
|
| 351 | + |
|
| 352 | + /** |
|
| 353 | + * get Total Amount Paid to Date |
|
| 354 | + * |
|
| 355 | + * @return float |
|
| 356 | + * @throws EE_Error |
|
| 357 | + * @throws InvalidArgumentException |
|
| 358 | + * @throws InvalidDataTypeException |
|
| 359 | + * @throws InvalidInterfaceException |
|
| 360 | + * @throws ReflectionException |
|
| 361 | + */ |
|
| 362 | + public function paid() |
|
| 363 | + { |
|
| 364 | + return (float) $this->get('TXN_paid'); |
|
| 365 | + } |
|
| 366 | + |
|
| 367 | + |
|
| 368 | + /** |
|
| 369 | + * @return mixed|null |
|
| 370 | + * @throws EE_Error |
|
| 371 | + * @throws InvalidArgumentException |
|
| 372 | + * @throws InvalidDataTypeException |
|
| 373 | + * @throws InvalidInterfaceException |
|
| 374 | + * @throws ReflectionException |
|
| 375 | + */ |
|
| 376 | + public function get_cart_session() |
|
| 377 | + { |
|
| 378 | + $session_data = (array) $this->get('TXN_session_data'); |
|
| 379 | + return isset($session_data['cart']) && $session_data['cart'] instanceof EE_Cart |
|
| 380 | + ? $session_data['cart'] |
|
| 381 | + : null; |
|
| 382 | + } |
|
| 383 | + |
|
| 384 | + |
|
| 385 | + /** |
|
| 386 | + * get Transaction session data |
|
| 387 | + * |
|
| 388 | + * @return array|mixed |
|
| 389 | + * @throws EE_Error |
|
| 390 | + * @throws InvalidArgumentException |
|
| 391 | + * @throws InvalidDataTypeException |
|
| 392 | + * @throws InvalidInterfaceException |
|
| 393 | + * @throws ReflectionException |
|
| 394 | + */ |
|
| 395 | + public function session_data() |
|
| 396 | + { |
|
| 397 | + $session_data = $this->get('TXN_session_data'); |
|
| 398 | + if (empty($session_data)) { |
|
| 399 | + $session_data = array( |
|
| 400 | + 'id' => null, |
|
| 401 | + 'user_id' => null, |
|
| 402 | + 'ip_address' => null, |
|
| 403 | + 'user_agent' => null, |
|
| 404 | + 'init_access' => null, |
|
| 405 | + 'last_access' => null, |
|
| 406 | + 'pages_visited' => array(), |
|
| 407 | + ); |
|
| 408 | + } |
|
| 409 | + return $session_data; |
|
| 410 | + } |
|
| 411 | + |
|
| 412 | + |
|
| 413 | + /** |
|
| 414 | + * Set session data within the TXN object |
|
| 415 | + * |
|
| 416 | + * @param EE_Session|array $session_data |
|
| 417 | + * @throws EE_Error |
|
| 418 | + * @throws InvalidArgumentException |
|
| 419 | + * @throws InvalidDataTypeException |
|
| 420 | + * @throws InvalidInterfaceException |
|
| 421 | + * @throws ReflectionException |
|
| 422 | + */ |
|
| 423 | + public function set_txn_session_data($session_data) |
|
| 424 | + { |
|
| 425 | + if ($session_data instanceof EE_Session) { |
|
| 426 | + $this->set('TXN_session_data', $session_data->get_session_data(null, true)); |
|
| 427 | + } else { |
|
| 428 | + $this->set('TXN_session_data', $session_data); |
|
| 429 | + } |
|
| 430 | + } |
|
| 431 | + |
|
| 432 | + |
|
| 433 | + /** |
|
| 434 | + * get Transaction hash salt |
|
| 435 | + * |
|
| 436 | + * @return mixed |
|
| 437 | + * @throws EE_Error |
|
| 438 | + * @throws InvalidArgumentException |
|
| 439 | + * @throws InvalidDataTypeException |
|
| 440 | + * @throws InvalidInterfaceException |
|
| 441 | + * @throws ReflectionException |
|
| 442 | + */ |
|
| 443 | + public function hash_salt_() |
|
| 444 | + { |
|
| 445 | + return $this->get('TXN_hash_salt'); |
|
| 446 | + } |
|
| 447 | + |
|
| 448 | + |
|
| 449 | + /** |
|
| 450 | + * Returns the transaction datetime as either: |
|
| 451 | + * - unix timestamp format ($format = false, $gmt = true) |
|
| 452 | + * - formatted date string including the UTC (timezone) offset ($format = true ($gmt |
|
| 453 | + * has no affect with this option)), this also may include a timezone abbreviation if the |
|
| 454 | + * set timezone in this class differs from what the timezone is on the blog. |
|
| 455 | + * - formatted date string including the UTC (timezone) offset (default). |
|
| 456 | + * |
|
| 457 | + * @param boolean $format - whether to return a unix timestamp (default) or formatted date string |
|
| 458 | + * @param boolean $gmt - whether to return a unix timestamp with UTC offset applied (default) |
|
| 459 | + * or no UTC offset applied |
|
| 460 | + * @return string | int |
|
| 461 | + * @throws EE_Error |
|
| 462 | + * @throws InvalidArgumentException |
|
| 463 | + * @throws InvalidDataTypeException |
|
| 464 | + * @throws InvalidInterfaceException |
|
| 465 | + * @throws ReflectionException |
|
| 466 | + */ |
|
| 467 | + public function datetime($format = false, $gmt = false) |
|
| 468 | + { |
|
| 469 | + if ($format) { |
|
| 470 | + return $this->get_pretty('TXN_timestamp'); |
|
| 471 | + } |
|
| 472 | + if ($gmt) { |
|
| 473 | + return $this->get_raw('TXN_timestamp'); |
|
| 474 | + } |
|
| 475 | + return $this->get('TXN_timestamp'); |
|
| 476 | + } |
|
| 477 | + |
|
| 478 | + |
|
| 479 | + /** |
|
| 480 | + * Gets registrations on this transaction |
|
| 481 | + * |
|
| 482 | + * @param array $query_params array of query parameters |
|
| 483 | + * @param boolean $get_cached TRUE to retrieve cached registrations or FALSE to pull from the db |
|
| 484 | + * @return EE_Base_Class[]|EE_Registration[] |
|
| 485 | + * @throws EE_Error |
|
| 486 | + * @throws InvalidArgumentException |
|
| 487 | + * @throws InvalidDataTypeException |
|
| 488 | + * @throws InvalidInterfaceException |
|
| 489 | + * @throws ReflectionException |
|
| 490 | + */ |
|
| 491 | + public function registrations($query_params = array(), $get_cached = false) |
|
| 492 | + { |
|
| 493 | + $query_params = (empty($query_params) || ! is_array($query_params)) |
|
| 494 | + ? array( |
|
| 495 | + 'order_by' => array( |
|
| 496 | + 'Event.EVT_name' => 'ASC', |
|
| 497 | + 'Attendee.ATT_lname' => 'ASC', |
|
| 498 | + 'Attendee.ATT_fname' => 'ASC', |
|
| 499 | + ), |
|
| 500 | + ) |
|
| 501 | + : $query_params; |
|
| 502 | + $query_params = $get_cached ? array() : $query_params; |
|
| 503 | + return $this->get_many_related('Registration', $query_params); |
|
| 504 | + } |
|
| 505 | + |
|
| 506 | + |
|
| 507 | + /** |
|
| 508 | + * Gets all the attendees for this transaction (handy for use with EE_Attendee's get_registrations_for_event |
|
| 509 | + * function for getting attendees and how many registrations they each have for an event) |
|
| 510 | + * |
|
| 511 | + * @return mixed EE_Attendee[] by default, int if $output is set to 'COUNT' |
|
| 512 | + * @throws EE_Error |
|
| 513 | + * @throws InvalidArgumentException |
|
| 514 | + * @throws InvalidDataTypeException |
|
| 515 | + * @throws InvalidInterfaceException |
|
| 516 | + * @throws ReflectionException |
|
| 517 | + */ |
|
| 518 | + public function attendees() |
|
| 519 | + { |
|
| 520 | + return $this->get_many_related('Attendee', array(array('Registration.Transaction.TXN_ID' => $this->ID()))); |
|
| 521 | + } |
|
| 522 | + |
|
| 523 | + |
|
| 524 | + /** |
|
| 525 | + * Gets payments for this transaction. Unlike other such functions, order by 'DESC' by default |
|
| 526 | + * |
|
| 527 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 528 | + * @return EE_Base_Class[]|EE_Payment[] |
|
| 529 | + * @throws EE_Error |
|
| 530 | + * @throws InvalidArgumentException |
|
| 531 | + * @throws InvalidDataTypeException |
|
| 532 | + * @throws InvalidInterfaceException |
|
| 533 | + * @throws ReflectionException |
|
| 534 | + */ |
|
| 535 | + public function payments($query_params = array()) |
|
| 536 | + { |
|
| 537 | + return $this->get_many_related('Payment', $query_params); |
|
| 538 | + } |
|
| 539 | + |
|
| 540 | + |
|
| 541 | + /** |
|
| 542 | + * gets only approved payments for this transaction |
|
| 543 | + * |
|
| 544 | + * @return EE_Base_Class[]|EE_Payment[] |
|
| 545 | + * @throws EE_Error |
|
| 546 | + * @throws InvalidArgumentException |
|
| 547 | + * @throws ReflectionException |
|
| 548 | + * @throws InvalidDataTypeException |
|
| 549 | + * @throws InvalidInterfaceException |
|
| 550 | + */ |
|
| 551 | + public function approved_payments() |
|
| 552 | + { |
|
| 553 | + EE_Registry::instance()->load_model('Payment'); |
|
| 554 | + return $this->get_many_related( |
|
| 555 | + 'Payment', |
|
| 556 | + array( |
|
| 557 | + array('STS_ID' => EEM_Payment::status_id_approved), |
|
| 558 | + 'order_by' => array('PAY_timestamp' => 'DESC'), |
|
| 559 | + ) |
|
| 560 | + ); |
|
| 561 | + } |
|
| 562 | + |
|
| 563 | + |
|
| 564 | + /** |
|
| 565 | + * Gets all payments which have not been approved |
|
| 566 | + * |
|
| 567 | + * @return EE_Base_Class[]|EEI_Payment[] |
|
| 568 | + * @throws EE_Error if a model is misconfigured somehow |
|
| 569 | + * @throws InvalidArgumentException |
|
| 570 | + * @throws InvalidDataTypeException |
|
| 571 | + * @throws InvalidInterfaceException |
|
| 572 | + * @throws ReflectionException |
|
| 573 | + */ |
|
| 574 | + public function pending_payments() |
|
| 575 | + { |
|
| 576 | + return $this->get_many_related( |
|
| 577 | + 'Payment', |
|
| 578 | + array( |
|
| 579 | + array( |
|
| 580 | + 'STS_ID' => EEM_Payment::status_id_pending, |
|
| 581 | + ), |
|
| 582 | + 'order_by' => array( |
|
| 583 | + 'PAY_timestamp' => 'DESC', |
|
| 584 | + ), |
|
| 585 | + ) |
|
| 586 | + ); |
|
| 587 | + } |
|
| 588 | + |
|
| 589 | + |
|
| 590 | + /** |
|
| 591 | + * echoes $this->pretty_status() |
|
| 592 | + * |
|
| 593 | + * @param bool $show_icons |
|
| 594 | + * @throws EE_Error |
|
| 595 | + * @throws InvalidArgumentException |
|
| 596 | + * @throws InvalidDataTypeException |
|
| 597 | + * @throws InvalidInterfaceException |
|
| 598 | + * @throws ReflectionException |
|
| 599 | + */ |
|
| 600 | + public function e_pretty_status($show_icons = false) |
|
| 601 | + { |
|
| 602 | + echo $this->pretty_status($show_icons); |
|
| 603 | + } |
|
| 604 | + |
|
| 605 | + |
|
| 606 | + /** |
|
| 607 | + * returns a pretty version of the status, good for displaying to users |
|
| 608 | + * |
|
| 609 | + * @param bool $show_icons |
|
| 610 | + * @return string |
|
| 611 | + * @throws EE_Error |
|
| 612 | + * @throws InvalidArgumentException |
|
| 613 | + * @throws InvalidDataTypeException |
|
| 614 | + * @throws InvalidInterfaceException |
|
| 615 | + * @throws ReflectionException |
|
| 616 | + */ |
|
| 617 | + public function pretty_status($show_icons = false) |
|
| 618 | + { |
|
| 619 | + $status = EEM_Status::instance()->localized_status( |
|
| 620 | + array($this->status_ID() => __('unknown', 'event_espresso')), |
|
| 621 | + false, |
|
| 622 | + 'sentence' |
|
| 623 | + ); |
|
| 624 | + $icon = ''; |
|
| 625 | + switch ($this->status_ID()) { |
|
| 626 | + case EEM_Transaction::complete_status_code: |
|
| 627 | + $icon = $show_icons ? '<span class="dashicons dashicons-yes ee-icon-size-24 green-text"></span>' : ''; |
|
| 628 | + break; |
|
| 629 | + case EEM_Transaction::incomplete_status_code: |
|
| 630 | + $icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 lt-blue-text"></span>' |
|
| 631 | + : ''; |
|
| 632 | + break; |
|
| 633 | + case EEM_Transaction::abandoned_status_code: |
|
| 634 | + $icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 red-text"></span>' : ''; |
|
| 635 | + break; |
|
| 636 | + case EEM_Transaction::failed_status_code: |
|
| 637 | + $icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' : ''; |
|
| 638 | + break; |
|
| 639 | + case EEM_Transaction::overpaid_status_code: |
|
| 640 | + $icon = $show_icons ? '<span class="dashicons dashicons-plus ee-icon-size-16 orange-text"></span>' : ''; |
|
| 641 | + break; |
|
| 642 | + } |
|
| 643 | + return $icon . $status[ $this->status_ID() ]; |
|
| 644 | + } |
|
| 645 | + |
|
| 646 | + |
|
| 647 | + /** |
|
| 648 | + * get Transaction Status |
|
| 649 | + * |
|
| 650 | + * @return mixed |
|
| 651 | + * @throws EE_Error |
|
| 652 | + * @throws InvalidArgumentException |
|
| 653 | + * @throws InvalidDataTypeException |
|
| 654 | + * @throws InvalidInterfaceException |
|
| 655 | + * @throws ReflectionException |
|
| 656 | + */ |
|
| 657 | + public function status_ID() |
|
| 658 | + { |
|
| 659 | + return $this->get('STS_ID'); |
|
| 660 | + } |
|
| 661 | + |
|
| 662 | + |
|
| 663 | + /** |
|
| 664 | + * Returns TRUE or FALSE for whether or not this transaction cost any money |
|
| 665 | + * |
|
| 666 | + * @return boolean |
|
| 667 | + * @throws EE_Error |
|
| 668 | + * @throws InvalidArgumentException |
|
| 669 | + * @throws InvalidDataTypeException |
|
| 670 | + * @throws InvalidInterfaceException |
|
| 671 | + * @throws ReflectionException |
|
| 672 | + */ |
|
| 673 | + public function is_free() |
|
| 674 | + { |
|
| 675 | + return EEH_Money::compare_floats($this->get('TXN_total'), 0, '=='); |
|
| 676 | + } |
|
| 677 | + |
|
| 678 | + |
|
| 679 | + /** |
|
| 680 | + * Returns whether this transaction is complete |
|
| 681 | + * Useful in templates and other logic for deciding if we should ask for another payment... |
|
| 682 | + * |
|
| 683 | + * @return boolean |
|
| 684 | + * @throws EE_Error |
|
| 685 | + * @throws InvalidArgumentException |
|
| 686 | + * @throws InvalidDataTypeException |
|
| 687 | + * @throws InvalidInterfaceException |
|
| 688 | + * @throws ReflectionException |
|
| 689 | + */ |
|
| 690 | + public function is_completed() |
|
| 691 | + { |
|
| 692 | + return $this->status_ID() === EEM_Transaction::complete_status_code; |
|
| 693 | + } |
|
| 694 | + |
|
| 695 | + |
|
| 696 | + /** |
|
| 697 | + * Returns whether this transaction is incomplete |
|
| 698 | + * Useful in templates and other logic for deciding if we should ask for another payment... |
|
| 699 | + * |
|
| 700 | + * @return boolean |
|
| 701 | + * @throws EE_Error |
|
| 702 | + * @throws InvalidArgumentException |
|
| 703 | + * @throws InvalidDataTypeException |
|
| 704 | + * @throws InvalidInterfaceException |
|
| 705 | + * @throws ReflectionException |
|
| 706 | + */ |
|
| 707 | + public function is_incomplete() |
|
| 708 | + { |
|
| 709 | + return $this->status_ID() === EEM_Transaction::incomplete_status_code; |
|
| 710 | + } |
|
| 711 | + |
|
| 712 | + |
|
| 713 | + /** |
|
| 714 | + * Returns whether this transaction is overpaid |
|
| 715 | + * Useful in templates and other logic for deciding if monies need to be refunded |
|
| 716 | + * |
|
| 717 | + * @return boolean |
|
| 718 | + * @throws EE_Error |
|
| 719 | + * @throws InvalidArgumentException |
|
| 720 | + * @throws InvalidDataTypeException |
|
| 721 | + * @throws InvalidInterfaceException |
|
| 722 | + * @throws ReflectionException |
|
| 723 | + */ |
|
| 724 | + public function is_overpaid() |
|
| 725 | + { |
|
| 726 | + return $this->status_ID() === EEM_Transaction::overpaid_status_code; |
|
| 727 | + } |
|
| 728 | + |
|
| 729 | + |
|
| 730 | + /** |
|
| 731 | + * Returns whether this transaction was abandoned |
|
| 732 | + * meaning that the transaction/registration process was somehow interrupted and never completed |
|
| 733 | + * but that contact information exists for at least one registrant |
|
| 734 | + * |
|
| 735 | + * @return boolean |
|
| 736 | + * @throws EE_Error |
|
| 737 | + * @throws InvalidArgumentException |
|
| 738 | + * @throws InvalidDataTypeException |
|
| 739 | + * @throws InvalidInterfaceException |
|
| 740 | + * @throws ReflectionException |
|
| 741 | + */ |
|
| 742 | + public function is_abandoned() |
|
| 743 | + { |
|
| 744 | + return $this->status_ID() === EEM_Transaction::abandoned_status_code; |
|
| 745 | + } |
|
| 746 | + |
|
| 747 | + |
|
| 748 | + /** |
|
| 749 | + * Returns whether this transaction failed |
|
| 750 | + * meaning that the transaction/registration process was somehow interrupted and never completed |
|
| 751 | + * and that NO contact information exists for any registrants |
|
| 752 | + * |
|
| 753 | + * @return boolean |
|
| 754 | + * @throws EE_Error |
|
| 755 | + * @throws InvalidArgumentException |
|
| 756 | + * @throws InvalidDataTypeException |
|
| 757 | + * @throws InvalidInterfaceException |
|
| 758 | + * @throws ReflectionException |
|
| 759 | + */ |
|
| 760 | + public function failed() |
|
| 761 | + { |
|
| 762 | + return $this->status_ID() === EEM_Transaction::failed_status_code; |
|
| 763 | + } |
|
| 764 | + |
|
| 765 | + |
|
| 766 | + /** |
|
| 767 | + * This returns the url for the invoice of this transaction |
|
| 768 | + * |
|
| 769 | + * @param string $type 'html' or 'pdf' (default is pdf) |
|
| 770 | + * @return string |
|
| 771 | + * @throws EE_Error |
|
| 772 | + * @throws InvalidArgumentException |
|
| 773 | + * @throws InvalidDataTypeException |
|
| 774 | + * @throws InvalidInterfaceException |
|
| 775 | + * @throws ReflectionException |
|
| 776 | + */ |
|
| 777 | + public function invoice_url($type = 'html') |
|
| 778 | + { |
|
| 779 | + $REG = $this->primary_registration(); |
|
| 780 | + if (! $REG instanceof EE_Registration) { |
|
| 781 | + return ''; |
|
| 782 | + } |
|
| 783 | + return $REG->invoice_url($type); |
|
| 784 | + } |
|
| 785 | + |
|
| 786 | + |
|
| 787 | + /** |
|
| 788 | + * Gets the primary registration only |
|
| 789 | + * |
|
| 790 | + * @return EE_Base_Class|EE_Registration |
|
| 791 | + * @throws EE_Error |
|
| 792 | + * @throws InvalidArgumentException |
|
| 793 | + * @throws InvalidDataTypeException |
|
| 794 | + * @throws InvalidInterfaceException |
|
| 795 | + * @throws ReflectionException |
|
| 796 | + */ |
|
| 797 | + public function primary_registration() |
|
| 798 | + { |
|
| 799 | + $registrations = (array) $this->get_many_related( |
|
| 800 | + 'Registration', |
|
| 801 | + array(array('REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT)) |
|
| 802 | + ); |
|
| 803 | + foreach ($registrations as $registration) { |
|
| 804 | + // valid registration that is NOT cancelled or declined ? |
|
| 805 | + if ( |
|
| 806 | + $registration instanceof EE_Registration |
|
| 807 | + && ! in_array($registration->status_ID(), EEM_Registration::closed_reg_statuses(), true) |
|
| 808 | + ) { |
|
| 809 | + return $registration; |
|
| 810 | + } |
|
| 811 | + } |
|
| 812 | + // nothing valid found, so just return first thing from array of results |
|
| 813 | + return reset($registrations); |
|
| 814 | + } |
|
| 815 | + |
|
| 816 | + |
|
| 817 | + /** |
|
| 818 | + * Gets the URL for viewing the receipt |
|
| 819 | + * |
|
| 820 | + * @param string $type 'pdf' or 'html' (default is 'html') |
|
| 821 | + * @return string |
|
| 822 | + * @throws EE_Error |
|
| 823 | + * @throws InvalidArgumentException |
|
| 824 | + * @throws InvalidDataTypeException |
|
| 825 | + * @throws InvalidInterfaceException |
|
| 826 | + * @throws ReflectionException |
|
| 827 | + */ |
|
| 828 | + public function receipt_url($type = 'html') |
|
| 829 | + { |
|
| 830 | + $REG = $this->primary_registration(); |
|
| 831 | + if (! $REG instanceof EE_Registration) { |
|
| 832 | + return ''; |
|
| 833 | + } |
|
| 834 | + return $REG->receipt_url($type); |
|
| 835 | + } |
|
| 836 | + |
|
| 837 | + |
|
| 838 | + /** |
|
| 839 | + * Gets the URL of the thank you page with this registration REG_url_link added as |
|
| 840 | + * a query parameter |
|
| 841 | + * |
|
| 842 | + * @return string |
|
| 843 | + * @throws EE_Error |
|
| 844 | + * @throws InvalidArgumentException |
|
| 845 | + * @throws InvalidDataTypeException |
|
| 846 | + * @throws InvalidInterfaceException |
|
| 847 | + * @throws ReflectionException |
|
| 848 | + */ |
|
| 849 | + public function payment_overview_url() |
|
| 850 | + { |
|
| 851 | + $primary_registration = $this->primary_registration(); |
|
| 852 | + return $primary_registration instanceof EE_Registration ? $primary_registration->payment_overview_url() : false; |
|
| 853 | + } |
|
| 854 | + |
|
| 855 | + |
|
| 856 | + /** |
|
| 857 | + * @return string |
|
| 858 | + * @throws EE_Error |
|
| 859 | + * @throws InvalidArgumentException |
|
| 860 | + * @throws InvalidDataTypeException |
|
| 861 | + * @throws InvalidInterfaceException |
|
| 862 | + * @throws ReflectionException |
|
| 863 | + */ |
|
| 864 | + public function gateway_response_on_transaction() |
|
| 865 | + { |
|
| 866 | + $payment = $this->get_first_related('Payment'); |
|
| 867 | + return $payment instanceof EE_Payment ? $payment->gateway_response() : ''; |
|
| 868 | + } |
|
| 869 | + |
|
| 870 | + |
|
| 871 | + /** |
|
| 872 | + * Get the status object of this object |
|
| 873 | + * |
|
| 874 | + * @return EE_Base_Class|EE_Status |
|
| 875 | + * @throws EE_Error |
|
| 876 | + * @throws InvalidArgumentException |
|
| 877 | + * @throws InvalidDataTypeException |
|
| 878 | + * @throws InvalidInterfaceException |
|
| 879 | + * @throws ReflectionException |
|
| 880 | + */ |
|
| 881 | + public function status_obj() |
|
| 882 | + { |
|
| 883 | + return $this->get_first_related('Status'); |
|
| 884 | + } |
|
| 885 | + |
|
| 886 | + |
|
| 887 | + /** |
|
| 888 | + * Gets all the extra meta info on this payment |
|
| 889 | + * |
|
| 890 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 891 | + * @return EE_Base_Class[]|EE_Extra_Meta |
|
| 892 | + * @throws EE_Error |
|
| 893 | + * @throws InvalidArgumentException |
|
| 894 | + * @throws InvalidDataTypeException |
|
| 895 | + * @throws InvalidInterfaceException |
|
| 896 | + * @throws ReflectionException |
|
| 897 | + */ |
|
| 898 | + public function extra_meta($query_params = array()) |
|
| 899 | + { |
|
| 900 | + return $this->get_many_related('Extra_Meta', $query_params); |
|
| 901 | + } |
|
| 902 | + |
|
| 903 | + |
|
| 904 | + /** |
|
| 905 | + * Wrapper for _add_relation_to |
|
| 906 | + * |
|
| 907 | + * @param EE_Registration $registration |
|
| 908 | + * @return EE_Base_Class the relation was added to |
|
| 909 | + * @throws EE_Error |
|
| 910 | + * @throws InvalidArgumentException |
|
| 911 | + * @throws InvalidDataTypeException |
|
| 912 | + * @throws InvalidInterfaceException |
|
| 913 | + * @throws ReflectionException |
|
| 914 | + */ |
|
| 915 | + public function add_registration(EE_Registration $registration) |
|
| 916 | + { |
|
| 917 | + return $this->_add_relation_to($registration, 'Registration'); |
|
| 918 | + } |
|
| 919 | + |
|
| 920 | + |
|
| 921 | + /** |
|
| 922 | + * Removes the given registration from being related (even before saving this transaction). |
|
| 923 | + * If an ID/index is provided and this transaction isn't saved yet, removes it from list of cached relations |
|
| 924 | + * |
|
| 925 | + * @param int $registration_or_id |
|
| 926 | + * @return EE_Base_Class that was removed from being related |
|
| 927 | + * @throws EE_Error |
|
| 928 | + * @throws InvalidArgumentException |
|
| 929 | + * @throws InvalidDataTypeException |
|
| 930 | + * @throws InvalidInterfaceException |
|
| 931 | + * @throws ReflectionException |
|
| 932 | + */ |
|
| 933 | + public function remove_registration_with_id($registration_or_id) |
|
| 934 | + { |
|
| 935 | + return $this->_remove_relation_to($registration_or_id, 'Registration'); |
|
| 936 | + } |
|
| 937 | + |
|
| 938 | + |
|
| 939 | + /** |
|
| 940 | + * Gets all the line items which are for ACTUAL items |
|
| 941 | + * |
|
| 942 | + * @return EE_Line_Item[] |
|
| 943 | + * @throws EE_Error |
|
| 944 | + * @throws InvalidArgumentException |
|
| 945 | + * @throws InvalidDataTypeException |
|
| 946 | + * @throws InvalidInterfaceException |
|
| 947 | + * @throws ReflectionException |
|
| 948 | + */ |
|
| 949 | + public function items_purchased() |
|
| 950 | + { |
|
| 951 | + return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_line_item))); |
|
| 952 | + } |
|
| 953 | + |
|
| 954 | + |
|
| 955 | + /** |
|
| 956 | + * Wrapper for _add_relation_to |
|
| 957 | + * |
|
| 958 | + * @param EE_Line_Item $line_item |
|
| 959 | + * @return EE_Base_Class the relation was added to |
|
| 960 | + * @throws EE_Error |
|
| 961 | + * @throws InvalidArgumentException |
|
| 962 | + * @throws InvalidDataTypeException |
|
| 963 | + * @throws InvalidInterfaceException |
|
| 964 | + * @throws ReflectionException |
|
| 965 | + */ |
|
| 966 | + public function add_line_item(EE_Line_Item $line_item) |
|
| 967 | + { |
|
| 968 | + return $this->_add_relation_to($line_item, 'Line_Item'); |
|
| 969 | + } |
|
| 970 | + |
|
| 971 | + |
|
| 972 | + /** |
|
| 973 | + * Gets ALL the line items related to this transaction (unstructured) |
|
| 974 | + * |
|
| 975 | + * @param array $query_params |
|
| 976 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
| 977 | + * @throws EE_Error |
|
| 978 | + * @throws InvalidArgumentException |
|
| 979 | + * @throws InvalidDataTypeException |
|
| 980 | + * @throws InvalidInterfaceException |
|
| 981 | + * @throws ReflectionException |
|
| 982 | + */ |
|
| 983 | + public function line_items($query_params = array()) |
|
| 984 | + { |
|
| 985 | + return $this->get_many_related('Line_Item', $query_params); |
|
| 986 | + } |
|
| 987 | + |
|
| 988 | + |
|
| 989 | + /** |
|
| 990 | + * Gets all the line items which are taxes on the total |
|
| 991 | + * |
|
| 992 | + * @return EE_Line_Item[] |
|
| 993 | + * @throws EE_Error |
|
| 994 | + * @throws InvalidArgumentException |
|
| 995 | + * @throws InvalidDataTypeException |
|
| 996 | + * @throws InvalidInterfaceException |
|
| 997 | + * @throws ReflectionException |
|
| 998 | + */ |
|
| 999 | + public function tax_items() |
|
| 1000 | + { |
|
| 1001 | + return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_tax))); |
|
| 1002 | + } |
|
| 1003 | + |
|
| 1004 | + |
|
| 1005 | + /** |
|
| 1006 | + * Gets the total line item (which is a parent of all other related line items, |
|
| 1007 | + * meaning it takes them all into account on its total) |
|
| 1008 | + * |
|
| 1009 | + * @param bool $create_if_not_found |
|
| 1010 | + * @return \EE_Line_Item |
|
| 1011 | + * @throws EE_Error |
|
| 1012 | + * @throws InvalidArgumentException |
|
| 1013 | + * @throws InvalidDataTypeException |
|
| 1014 | + * @throws InvalidInterfaceException |
|
| 1015 | + * @throws ReflectionException |
|
| 1016 | + */ |
|
| 1017 | + public function total_line_item($create_if_not_found = true) |
|
| 1018 | + { |
|
| 1019 | + $item = $this->get_first_related('Line_Item', array(array('LIN_type' => EEM_Line_Item::type_total))); |
|
| 1020 | + if (! $item && $create_if_not_found) { |
|
| 1021 | + $item = EEH_Line_Item::create_total_line_item($this); |
|
| 1022 | + } |
|
| 1023 | + return $item; |
|
| 1024 | + } |
|
| 1025 | + |
|
| 1026 | + |
|
| 1027 | + /** |
|
| 1028 | + * Returns the total amount of tax on this transaction |
|
| 1029 | + * (assumes there's only one tax subtotal line item) |
|
| 1030 | + * |
|
| 1031 | + * @return float |
|
| 1032 | + * @throws EE_Error |
|
| 1033 | + * @throws InvalidArgumentException |
|
| 1034 | + * @throws InvalidDataTypeException |
|
| 1035 | + * @throws InvalidInterfaceException |
|
| 1036 | + * @throws ReflectionException |
|
| 1037 | + */ |
|
| 1038 | + public function tax_total() |
|
| 1039 | + { |
|
| 1040 | + $tax_line_item = $this->tax_total_line_item(); |
|
| 1041 | + if ($tax_line_item) { |
|
| 1042 | + return (float) $tax_line_item->total(); |
|
| 1043 | + } |
|
| 1044 | + return (float) 0; |
|
| 1045 | + } |
|
| 1046 | + |
|
| 1047 | + |
|
| 1048 | + /** |
|
| 1049 | + * Gets the tax subtotal line item (assumes there's only one) |
|
| 1050 | + * |
|
| 1051 | + * @return EE_Line_Item |
|
| 1052 | + * @throws EE_Error |
|
| 1053 | + * @throws InvalidArgumentException |
|
| 1054 | + * @throws InvalidDataTypeException |
|
| 1055 | + * @throws InvalidInterfaceException |
|
| 1056 | + * @throws ReflectionException |
|
| 1057 | + */ |
|
| 1058 | + public function tax_total_line_item() |
|
| 1059 | + { |
|
| 1060 | + return EEH_Line_Item::get_taxes_subtotal($this->total_line_item()); |
|
| 1061 | + } |
|
| 1062 | + |
|
| 1063 | + |
|
| 1064 | + /** |
|
| 1065 | + * Gets the array of billing info for the gateway and for this transaction's primary registration's attendee. |
|
| 1066 | + * |
|
| 1067 | + * @return EE_Form_Section_Proper |
|
| 1068 | + * @throws EE_Error |
|
| 1069 | + * @throws InvalidArgumentException |
|
| 1070 | + * @throws InvalidDataTypeException |
|
| 1071 | + * @throws InvalidInterfaceException |
|
| 1072 | + * @throws ReflectionException |
|
| 1073 | + */ |
|
| 1074 | + public function billing_info() |
|
| 1075 | + { |
|
| 1076 | + $payment_method = $this->payment_method(); |
|
| 1077 | + if (! $payment_method) { |
|
| 1078 | + EE_Error::add_error( |
|
| 1079 | + __( |
|
| 1080 | + 'Could not find billing info for transaction because no gateway has been used for it yet', |
|
| 1081 | + 'event_espresso' |
|
| 1082 | + ), |
|
| 1083 | + __FILE__, |
|
| 1084 | + __FUNCTION__, |
|
| 1085 | + __LINE__ |
|
| 1086 | + ); |
|
| 1087 | + return null; |
|
| 1088 | + } |
|
| 1089 | + $primary_reg = $this->primary_registration(); |
|
| 1090 | + if (! $primary_reg) { |
|
| 1091 | + EE_Error::add_error( |
|
| 1092 | + __( |
|
| 1093 | + 'Cannot get billing info for gateway %s on transaction because no primary registration exists', |
|
| 1094 | + 'event_espresso' |
|
| 1095 | + ), |
|
| 1096 | + __FILE__, |
|
| 1097 | + __FUNCTION__, |
|
| 1098 | + __LINE__ |
|
| 1099 | + ); |
|
| 1100 | + return null; |
|
| 1101 | + } |
|
| 1102 | + $attendee = $primary_reg->attendee(); |
|
| 1103 | + if (! $attendee) { |
|
| 1104 | + EE_Error::add_error( |
|
| 1105 | + __( |
|
| 1106 | + 'Cannot get billing info for gateway %s on transaction because the primary registration has no attendee exists', |
|
| 1107 | + 'event_espresso' |
|
| 1108 | + ), |
|
| 1109 | + __FILE__, |
|
| 1110 | + __FUNCTION__, |
|
| 1111 | + __LINE__ |
|
| 1112 | + ); |
|
| 1113 | + return null; |
|
| 1114 | + } |
|
| 1115 | + return $attendee->billing_info_for_payment_method($payment_method); |
|
| 1116 | + } |
|
| 1117 | + |
|
| 1118 | + |
|
| 1119 | + /** |
|
| 1120 | + * Gets PMD_ID |
|
| 1121 | + * |
|
| 1122 | + * @return int |
|
| 1123 | + * @throws EE_Error |
|
| 1124 | + * @throws InvalidArgumentException |
|
| 1125 | + * @throws InvalidDataTypeException |
|
| 1126 | + * @throws InvalidInterfaceException |
|
| 1127 | + * @throws ReflectionException |
|
| 1128 | + */ |
|
| 1129 | + public function payment_method_ID() |
|
| 1130 | + { |
|
| 1131 | + return $this->get('PMD_ID'); |
|
| 1132 | + } |
|
| 1133 | + |
|
| 1134 | + |
|
| 1135 | + /** |
|
| 1136 | + * Sets PMD_ID |
|
| 1137 | + * |
|
| 1138 | + * @param int $PMD_ID |
|
| 1139 | + * @throws EE_Error |
|
| 1140 | + * @throws InvalidArgumentException |
|
| 1141 | + * @throws InvalidDataTypeException |
|
| 1142 | + * @throws InvalidInterfaceException |
|
| 1143 | + * @throws ReflectionException |
|
| 1144 | + */ |
|
| 1145 | + public function set_payment_method_ID($PMD_ID) |
|
| 1146 | + { |
|
| 1147 | + $this->set('PMD_ID', $PMD_ID); |
|
| 1148 | + } |
|
| 1149 | + |
|
| 1150 | + |
|
| 1151 | + /** |
|
| 1152 | + * Gets the last-used payment method on this transaction |
|
| 1153 | + * (we COULD just use the last-made payment, but some payment methods, namely |
|
| 1154 | + * offline ones, dont' create payments) |
|
| 1155 | + * |
|
| 1156 | + * @return EE_Payment_Method |
|
| 1157 | + * @throws EE_Error |
|
| 1158 | + * @throws InvalidArgumentException |
|
| 1159 | + * @throws InvalidDataTypeException |
|
| 1160 | + * @throws InvalidInterfaceException |
|
| 1161 | + * @throws ReflectionException |
|
| 1162 | + */ |
|
| 1163 | + public function payment_method() |
|
| 1164 | + { |
|
| 1165 | + $pm = $this->get_first_related('Payment_Method'); |
|
| 1166 | + if ($pm instanceof EE_Payment_Method) { |
|
| 1167 | + return $pm; |
|
| 1168 | + } |
|
| 1169 | + $last_payment = $this->last_payment(); |
|
| 1170 | + if ($last_payment instanceof EE_Payment && $last_payment->payment_method()) { |
|
| 1171 | + return $last_payment->payment_method(); |
|
| 1172 | + } |
|
| 1173 | + return null; |
|
| 1174 | + } |
|
| 1175 | + |
|
| 1176 | + |
|
| 1177 | + /** |
|
| 1178 | + * Gets the last payment made |
|
| 1179 | + * |
|
| 1180 | + * @return EE_Base_Class|EE_Payment |
|
| 1181 | + * @throws EE_Error |
|
| 1182 | + * @throws InvalidArgumentException |
|
| 1183 | + * @throws InvalidDataTypeException |
|
| 1184 | + * @throws InvalidInterfaceException |
|
| 1185 | + * @throws ReflectionException |
|
| 1186 | + */ |
|
| 1187 | + public function last_payment() |
|
| 1188 | + { |
|
| 1189 | + return $this->get_first_related('Payment', array('order_by' => array('PAY_ID' => 'desc'))); |
|
| 1190 | + } |
|
| 1191 | + |
|
| 1192 | + |
|
| 1193 | + /** |
|
| 1194 | + * Gets all the line items which are unrelated to tickets on this transaction |
|
| 1195 | + * |
|
| 1196 | + * @return EE_Line_Item[] |
|
| 1197 | + * @throws EE_Error |
|
| 1198 | + * @throws InvalidArgumentException |
|
| 1199 | + * @throws InvalidDataTypeException |
|
| 1200 | + * @throws InvalidInterfaceException |
|
| 1201 | + * @throws ReflectionException |
|
| 1202 | + */ |
|
| 1203 | + public function non_ticket_line_items() |
|
| 1204 | + { |
|
| 1205 | + return EEM_Line_Item::instance()->get_all_non_ticket_line_items_for_transaction($this->ID()); |
|
| 1206 | + } |
|
| 1207 | + |
|
| 1208 | + |
|
| 1209 | + /** |
|
| 1210 | + * possibly toggles TXN status |
|
| 1211 | + * |
|
| 1212 | + * @param boolean $update whether to save the TXN |
|
| 1213 | + * @return bool whether the TXN was saved |
|
| 1214 | + * @throws EE_Error |
|
| 1215 | + * @throws InvalidArgumentException |
|
| 1216 | + * @throws InvalidDataTypeException |
|
| 1217 | + * @throws InvalidInterfaceException |
|
| 1218 | + * @throws ReflectionException |
|
| 1219 | + * @throws RuntimeException |
|
| 1220 | + */ |
|
| 1221 | + public function update_status_based_on_total_paid($update = true) |
|
| 1222 | + { |
|
| 1223 | + // set transaction status based on comparison of TXN_paid vs TXN_total |
|
| 1224 | + if (EEH_Money::compare_floats($this->paid(), $this->total(), '>')) { |
|
| 1225 | + $new_txn_status = EEM_Transaction::overpaid_status_code; |
|
| 1226 | + } elseif (EEH_Money::compare_floats($this->paid(), $this->total())) { |
|
| 1227 | + $new_txn_status = EEM_Transaction::complete_status_code; |
|
| 1228 | + } elseif (EEH_Money::compare_floats($this->paid(), $this->total(), '<')) { |
|
| 1229 | + $new_txn_status = EEM_Transaction::incomplete_status_code; |
|
| 1230 | + } else { |
|
| 1231 | + throw new RuntimeException( |
|
| 1232 | + __('The total paid calculation for this transaction is inaccurate.', 'event_espresso') |
|
| 1233 | + ); |
|
| 1234 | + } |
|
| 1235 | + if ($new_txn_status !== $this->status_ID()) { |
|
| 1236 | + $this->set_status($new_txn_status); |
|
| 1237 | + if ($update) { |
|
| 1238 | + return $this->save() ? true : false; |
|
| 1239 | + } |
|
| 1240 | + } |
|
| 1241 | + return false; |
|
| 1242 | + } |
|
| 1243 | + |
|
| 1244 | + |
|
| 1245 | + /** |
|
| 1246 | + * Updates the transaction's status and total_paid based on all the payments |
|
| 1247 | + * that apply to it |
|
| 1248 | + * |
|
| 1249 | + * @deprecated |
|
| 1250 | + * @return array|bool |
|
| 1251 | + * @throws EE_Error |
|
| 1252 | + * @throws InvalidArgumentException |
|
| 1253 | + * @throws ReflectionException |
|
| 1254 | + * @throws InvalidDataTypeException |
|
| 1255 | + * @throws InvalidInterfaceException |
|
| 1256 | + */ |
|
| 1257 | + public function update_based_on_payments() |
|
| 1258 | + { |
|
| 1259 | + EE_Error::doing_it_wrong( |
|
| 1260 | + __CLASS__ . '::' . __FUNCTION__, |
|
| 1261 | + sprintf( |
|
| 1262 | + __('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
| 1263 | + 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()' |
|
| 1264 | + ), |
|
| 1265 | + '4.6.0' |
|
| 1266 | + ); |
|
| 1267 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
| 1268 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
| 1269 | + return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($this); |
|
| 1270 | + } |
|
| 1271 | + |
|
| 1272 | + |
|
| 1273 | + /** |
|
| 1274 | + * @return string |
|
| 1275 | + */ |
|
| 1276 | + public function old_txn_status() |
|
| 1277 | + { |
|
| 1278 | + return $this->_old_txn_status; |
|
| 1279 | + } |
|
| 1280 | + |
|
| 1281 | + |
|
| 1282 | + /** |
|
| 1283 | + * @param string $old_txn_status |
|
| 1284 | + */ |
|
| 1285 | + public function set_old_txn_status($old_txn_status) |
|
| 1286 | + { |
|
| 1287 | + // only set the first time |
|
| 1288 | + if ($this->_old_txn_status === null) { |
|
| 1289 | + $this->_old_txn_status = $old_txn_status; |
|
| 1290 | + } |
|
| 1291 | + } |
|
| 1292 | + |
|
| 1293 | + |
|
| 1294 | + /** |
|
| 1295 | + * reg_status_updated |
|
| 1296 | + * |
|
| 1297 | + * @return bool |
|
| 1298 | + * @throws EE_Error |
|
| 1299 | + * @throws InvalidArgumentException |
|
| 1300 | + * @throws InvalidDataTypeException |
|
| 1301 | + * @throws InvalidInterfaceException |
|
| 1302 | + * @throws ReflectionException |
|
| 1303 | + */ |
|
| 1304 | + public function txn_status_updated() |
|
| 1305 | + { |
|
| 1306 | + return $this->status_ID() !== $this->_old_txn_status && $this->_old_txn_status !== null; |
|
| 1307 | + } |
|
| 1308 | + |
|
| 1309 | + |
|
| 1310 | + /** |
|
| 1311 | + * _reg_steps_completed |
|
| 1312 | + * if $check_all is TRUE, then returns TRUE if ALL reg steps have been marked as completed, |
|
| 1313 | + * if a $reg_step_slug is provided, then this step will be skipped when testing for completion |
|
| 1314 | + * if $check_all is FALSE and a $reg_step_slug is provided, then ONLY that reg step will be tested for completion |
|
| 1315 | + * |
|
| 1316 | + * @param string $reg_step_slug |
|
| 1317 | + * @param bool $check_all |
|
| 1318 | + * @return bool|int |
|
| 1319 | + * @throws EE_Error |
|
| 1320 | + * @throws InvalidArgumentException |
|
| 1321 | + * @throws InvalidDataTypeException |
|
| 1322 | + * @throws InvalidInterfaceException |
|
| 1323 | + * @throws ReflectionException |
|
| 1324 | + */ |
|
| 1325 | + private function _reg_steps_completed($reg_step_slug = '', $check_all = true) |
|
| 1326 | + { |
|
| 1327 | + $reg_steps = $this->reg_steps(); |
|
| 1328 | + if (! is_array($reg_steps) || empty($reg_steps)) { |
|
| 1329 | + return false; |
|
| 1330 | + } |
|
| 1331 | + // loop thru reg steps array) |
|
| 1332 | + foreach ($reg_steps as $slug => $reg_step_completed) { |
|
| 1333 | + // if NOT checking ALL steps (only checking one step) |
|
| 1334 | + if (! $check_all) { |
|
| 1335 | + // and this is the one |
|
| 1336 | + if ($slug === $reg_step_slug) { |
|
| 1337 | + return $reg_step_completed; |
|
| 1338 | + } |
|
| 1339 | + // skip to next reg step in loop |
|
| 1340 | + continue; |
|
| 1341 | + } |
|
| 1342 | + // $check_all must be true, else we would never have gotten to this point |
|
| 1343 | + if ($slug === $reg_step_slug) { |
|
| 1344 | + // if we reach this point, then we are testing either: |
|
| 1345 | + // all_reg_steps_completed_except() or |
|
| 1346 | + // all_reg_steps_completed_except_final_step(), |
|
| 1347 | + // and since this is the reg step EXCEPTION being tested |
|
| 1348 | + // we want to return true (yes true) if this reg step is NOT completed |
|
| 1349 | + // ie: "is everything completed except the final step?" |
|
| 1350 | + // "that is correct... the final step is not completed, but all others are." |
|
| 1351 | + return $reg_step_completed !== true; |
|
| 1352 | + } |
|
| 1353 | + if ($reg_step_completed !== true) { |
|
| 1354 | + // if any reg step is NOT completed, then ALL steps are not completed |
|
| 1355 | + return false; |
|
| 1356 | + } |
|
| 1357 | + } |
|
| 1358 | + return true; |
|
| 1359 | + } |
|
| 1360 | + |
|
| 1361 | + |
|
| 1362 | + /** |
|
| 1363 | + * all_reg_steps_completed |
|
| 1364 | + * returns: |
|
| 1365 | + * true if ALL reg steps have been marked as completed |
|
| 1366 | + * or false if any step is not completed |
|
| 1367 | + * |
|
| 1368 | + * @return bool |
|
| 1369 | + * @throws EE_Error |
|
| 1370 | + * @throws InvalidArgumentException |
|
| 1371 | + * @throws InvalidDataTypeException |
|
| 1372 | + * @throws InvalidInterfaceException |
|
| 1373 | + * @throws ReflectionException |
|
| 1374 | + */ |
|
| 1375 | + public function all_reg_steps_completed() |
|
| 1376 | + { |
|
| 1377 | + return $this->_reg_steps_completed(); |
|
| 1378 | + } |
|
| 1379 | + |
|
| 1380 | + |
|
| 1381 | + /** |
|
| 1382 | + * all_reg_steps_completed_except |
|
| 1383 | + * returns: |
|
| 1384 | + * true if ALL reg steps, except a particular step that you wish to skip over, have been marked as completed |
|
| 1385 | + * or false if any other step is not completed |
|
| 1386 | + * or false if ALL steps are completed including the exception you are testing !!! |
|
| 1387 | + * |
|
| 1388 | + * @param string $exception |
|
| 1389 | + * @return bool |
|
| 1390 | + * @throws EE_Error |
|
| 1391 | + * @throws InvalidArgumentException |
|
| 1392 | + * @throws InvalidDataTypeException |
|
| 1393 | + * @throws InvalidInterfaceException |
|
| 1394 | + * @throws ReflectionException |
|
| 1395 | + */ |
|
| 1396 | + public function all_reg_steps_completed_except($exception = '') |
|
| 1397 | + { |
|
| 1398 | + return $this->_reg_steps_completed($exception); |
|
| 1399 | + } |
|
| 1400 | + |
|
| 1401 | + |
|
| 1402 | + /** |
|
| 1403 | + * all_reg_steps_completed_except |
|
| 1404 | + * returns: |
|
| 1405 | + * true if ALL reg steps, except the final step, have been marked as completed |
|
| 1406 | + * or false if any step is not completed |
|
| 1407 | + * or false if ALL steps are completed including the final step !!! |
|
| 1408 | + * |
|
| 1409 | + * @return bool |
|
| 1410 | + * @throws EE_Error |
|
| 1411 | + * @throws InvalidArgumentException |
|
| 1412 | + * @throws InvalidDataTypeException |
|
| 1413 | + * @throws InvalidInterfaceException |
|
| 1414 | + * @throws ReflectionException |
|
| 1415 | + */ |
|
| 1416 | + public function all_reg_steps_completed_except_final_step() |
|
| 1417 | + { |
|
| 1418 | + return $this->_reg_steps_completed('finalize_registration'); |
|
| 1419 | + } |
|
| 1420 | + |
|
| 1421 | + |
|
| 1422 | + /** |
|
| 1423 | + * reg_step_completed |
|
| 1424 | + * returns: |
|
| 1425 | + * true if a specific reg step has been marked as completed |
|
| 1426 | + * a Unix timestamp if it has been initialized but not yet completed, |
|
| 1427 | + * or false if it has not yet been initialized |
|
| 1428 | + * |
|
| 1429 | + * @param string $reg_step_slug |
|
| 1430 | + * @return bool|int |
|
| 1431 | + * @throws EE_Error |
|
| 1432 | + * @throws InvalidArgumentException |
|
| 1433 | + * @throws InvalidDataTypeException |
|
| 1434 | + * @throws InvalidInterfaceException |
|
| 1435 | + * @throws ReflectionException |
|
| 1436 | + */ |
|
| 1437 | + public function reg_step_completed($reg_step_slug) |
|
| 1438 | + { |
|
| 1439 | + return $this->_reg_steps_completed($reg_step_slug, false); |
|
| 1440 | + } |
|
| 1441 | + |
|
| 1442 | + |
|
| 1443 | + /** |
|
| 1444 | + * completed_final_reg_step |
|
| 1445 | + * returns: |
|
| 1446 | + * true if the finalize_registration reg step has been marked as completed |
|
| 1447 | + * a Unix timestamp if it has been initialized but not yet completed, |
|
| 1448 | + * or false if it has not yet been initialized |
|
| 1449 | + * |
|
| 1450 | + * @return bool|int |
|
| 1451 | + * @throws EE_Error |
|
| 1452 | + * @throws InvalidArgumentException |
|
| 1453 | + * @throws InvalidDataTypeException |
|
| 1454 | + * @throws InvalidInterfaceException |
|
| 1455 | + * @throws ReflectionException |
|
| 1456 | + */ |
|
| 1457 | + public function final_reg_step_completed() |
|
| 1458 | + { |
|
| 1459 | + return $this->_reg_steps_completed('finalize_registration', false); |
|
| 1460 | + } |
|
| 1461 | + |
|
| 1462 | + |
|
| 1463 | + /** |
|
| 1464 | + * set_reg_step_initiated |
|
| 1465 | + * given a valid TXN_reg_step, this sets it's value to a unix timestamp |
|
| 1466 | + * |
|
| 1467 | + * @param string $reg_step_slug |
|
| 1468 | + * @return boolean |
|
| 1469 | + * @throws EE_Error |
|
| 1470 | + * @throws InvalidArgumentException |
|
| 1471 | + * @throws InvalidDataTypeException |
|
| 1472 | + * @throws InvalidInterfaceException |
|
| 1473 | + * @throws ReflectionException |
|
| 1474 | + */ |
|
| 1475 | + public function set_reg_step_initiated($reg_step_slug) |
|
| 1476 | + { |
|
| 1477 | + return $this->_set_reg_step_completed_status($reg_step_slug, time()); |
|
| 1478 | + } |
|
| 1479 | + |
|
| 1480 | + |
|
| 1481 | + /** |
|
| 1482 | + * set_reg_step_completed |
|
| 1483 | + * given a valid TXN_reg_step, this sets the step as completed |
|
| 1484 | + * |
|
| 1485 | + * @param string $reg_step_slug |
|
| 1486 | + * @return boolean |
|
| 1487 | + * @throws EE_Error |
|
| 1488 | + * @throws InvalidArgumentException |
|
| 1489 | + * @throws InvalidDataTypeException |
|
| 1490 | + * @throws InvalidInterfaceException |
|
| 1491 | + * @throws ReflectionException |
|
| 1492 | + */ |
|
| 1493 | + public function set_reg_step_completed($reg_step_slug) |
|
| 1494 | + { |
|
| 1495 | + return $this->_set_reg_step_completed_status($reg_step_slug, true); |
|
| 1496 | + } |
|
| 1497 | + |
|
| 1498 | + |
|
| 1499 | + /** |
|
| 1500 | + * set_reg_step_completed |
|
| 1501 | + * given a valid TXN_reg_step slug, this sets the step as NOT completed |
|
| 1502 | + * |
|
| 1503 | + * @param string $reg_step_slug |
|
| 1504 | + * @return boolean |
|
| 1505 | + * @throws EE_Error |
|
| 1506 | + * @throws InvalidArgumentException |
|
| 1507 | + * @throws InvalidDataTypeException |
|
| 1508 | + * @throws InvalidInterfaceException |
|
| 1509 | + * @throws ReflectionException |
|
| 1510 | + */ |
|
| 1511 | + public function set_reg_step_not_completed($reg_step_slug) |
|
| 1512 | + { |
|
| 1513 | + return $this->_set_reg_step_completed_status($reg_step_slug, false); |
|
| 1514 | + } |
|
| 1515 | + |
|
| 1516 | + |
|
| 1517 | + /** |
|
| 1518 | + * set_reg_step_completed |
|
| 1519 | + * given a valid reg step slug, this sets the TXN_reg_step completed status which is either: |
|
| 1520 | + * |
|
| 1521 | + * @param string $reg_step_slug |
|
| 1522 | + * @param boolean|int $status |
|
| 1523 | + * @return boolean |
|
| 1524 | + * @throws EE_Error |
|
| 1525 | + * @throws InvalidArgumentException |
|
| 1526 | + * @throws InvalidDataTypeException |
|
| 1527 | + * @throws InvalidInterfaceException |
|
| 1528 | + * @throws ReflectionException |
|
| 1529 | + */ |
|
| 1530 | + private function _set_reg_step_completed_status($reg_step_slug, $status) |
|
| 1531 | + { |
|
| 1532 | + // validate status |
|
| 1533 | + $status = is_bool($status) || is_int($status) ? $status : false; |
|
| 1534 | + // get reg steps array |
|
| 1535 | + $txn_reg_steps = $this->reg_steps(); |
|
| 1536 | + // if reg step does NOT exist |
|
| 1537 | + if (! isset($txn_reg_steps[ $reg_step_slug ])) { |
|
| 1538 | + return false; |
|
| 1539 | + } |
|
| 1540 | + // if we're trying to complete a step that is already completed |
|
| 1541 | + if ($txn_reg_steps[ $reg_step_slug ] === true) { |
|
| 1542 | + return true; |
|
| 1543 | + } |
|
| 1544 | + // if we're trying to complete a step that hasn't even started |
|
| 1545 | + if ($status === true && $txn_reg_steps[ $reg_step_slug ] === false) { |
|
| 1546 | + return false; |
|
| 1547 | + } |
|
| 1548 | + // if current status value matches the incoming value (no change) |
|
| 1549 | + // type casting as int means values should collapse to either 0, 1, or a timestamp like 1234567890 |
|
| 1550 | + if ((int) $txn_reg_steps[ $reg_step_slug ] === (int) $status) { |
|
| 1551 | + // this will happen in cases where multiple AJAX requests occur during the same step |
|
| 1552 | + return true; |
|
| 1553 | + } |
|
| 1554 | + // if we're trying to set a start time, but it has already been set... |
|
| 1555 | + if (is_numeric($status) && is_numeric($txn_reg_steps[ $reg_step_slug ])) { |
|
| 1556 | + // skip the update below, but don't return FALSE so that errors won't be displayed |
|
| 1557 | + return true; |
|
| 1558 | + } |
|
| 1559 | + // update completed status |
|
| 1560 | + $txn_reg_steps[ $reg_step_slug ] = $status; |
|
| 1561 | + $this->set_reg_steps($txn_reg_steps); |
|
| 1562 | + $this->save(); |
|
| 1563 | + return true; |
|
| 1564 | + } |
|
| 1565 | + |
|
| 1566 | + |
|
| 1567 | + /** |
|
| 1568 | + * remove_reg_step |
|
| 1569 | + * given a valid TXN_reg_step slug, this will remove (unset) |
|
| 1570 | + * the reg step from the TXN reg step array |
|
| 1571 | + * |
|
| 1572 | + * @param string $reg_step_slug |
|
| 1573 | + * @return void |
|
| 1574 | + * @throws EE_Error |
|
| 1575 | + * @throws InvalidArgumentException |
|
| 1576 | + * @throws InvalidDataTypeException |
|
| 1577 | + * @throws InvalidInterfaceException |
|
| 1578 | + * @throws ReflectionException |
|
| 1579 | + */ |
|
| 1580 | + public function remove_reg_step($reg_step_slug) |
|
| 1581 | + { |
|
| 1582 | + // get reg steps array |
|
| 1583 | + $txn_reg_steps = $this->reg_steps(); |
|
| 1584 | + unset($txn_reg_steps[ $reg_step_slug ]); |
|
| 1585 | + $this->set_reg_steps($txn_reg_steps); |
|
| 1586 | + } |
|
| 1587 | + |
|
| 1588 | + |
|
| 1589 | + /** |
|
| 1590 | + * toggle_failed_transaction_status |
|
| 1591 | + * upgrades a TXNs status from failed to abandoned, |
|
| 1592 | + * meaning that contact information has been captured for at least one registrant |
|
| 1593 | + * |
|
| 1594 | + * @param bool $save |
|
| 1595 | + * @return bool |
|
| 1596 | + * @throws EE_Error |
|
| 1597 | + * @throws InvalidArgumentException |
|
| 1598 | + * @throws InvalidDataTypeException |
|
| 1599 | + * @throws InvalidInterfaceException |
|
| 1600 | + * @throws ReflectionException |
|
| 1601 | + */ |
|
| 1602 | + public function toggle_failed_transaction_status($save = true) |
|
| 1603 | + { |
|
| 1604 | + // if TXN status is still set as "failed"... |
|
| 1605 | + if ($this->status_ID() === EEM_Transaction::failed_status_code) { |
|
| 1606 | + $this->set_status(EEM_Transaction::abandoned_status_code); |
|
| 1607 | + if ($save) { |
|
| 1608 | + $this->save(); |
|
| 1609 | + } |
|
| 1610 | + return true; |
|
| 1611 | + } |
|
| 1612 | + return false; |
|
| 1613 | + } |
|
| 1614 | + |
|
| 1615 | + |
|
| 1616 | + /** |
|
| 1617 | + * toggle_abandoned_transaction_status |
|
| 1618 | + * upgrades a TXNs status from failed or abandoned to incomplete |
|
| 1619 | + * |
|
| 1620 | + * @return bool |
|
| 1621 | + * @throws EE_Error |
|
| 1622 | + * @throws InvalidArgumentException |
|
| 1623 | + * @throws InvalidDataTypeException |
|
| 1624 | + * @throws InvalidInterfaceException |
|
| 1625 | + * @throws ReflectionException |
|
| 1626 | + */ |
|
| 1627 | + public function toggle_abandoned_transaction_status() |
|
| 1628 | + { |
|
| 1629 | + // if TXN status has not been updated already due to a payment, and is still set as "failed" or "abandoned"... |
|
| 1630 | + $txn_status = $this->status_ID(); |
|
| 1631 | + if ( |
|
| 1632 | + $txn_status === EEM_Transaction::failed_status_code |
|
| 1633 | + || $txn_status === EEM_Transaction::abandoned_status_code |
|
| 1634 | + ) { |
|
| 1635 | + // if a contact record for the primary registrant has been created |
|
| 1636 | + if ( |
|
| 1637 | + $this->primary_registration() instanceof EE_Registration |
|
| 1638 | + && $this->primary_registration()->attendee() instanceof EE_Attendee |
|
| 1639 | + ) { |
|
| 1640 | + $this->set_status(EEM_Transaction::incomplete_status_code); |
|
| 1641 | + } else { |
|
| 1642 | + // no contact record? yer abandoned! |
|
| 1643 | + $this->set_status(EEM_Transaction::abandoned_status_code); |
|
| 1644 | + } |
|
| 1645 | + return true; |
|
| 1646 | + } |
|
| 1647 | + return false; |
|
| 1648 | + } |
|
| 1649 | + |
|
| 1650 | + |
|
| 1651 | + /** |
|
| 1652 | + * checks if an Abandoned TXN has any related payments, and if so, |
|
| 1653 | + * updates the TXN status based on the amount paid |
|
| 1654 | + * |
|
| 1655 | + * @throws EE_Error |
|
| 1656 | + * @throws InvalidDataTypeException |
|
| 1657 | + * @throws InvalidInterfaceException |
|
| 1658 | + * @throws InvalidArgumentException |
|
| 1659 | + * @throws RuntimeException |
|
| 1660 | + * @throws ReflectionException |
|
| 1661 | + */ |
|
| 1662 | + public function verify_abandoned_transaction_status() |
|
| 1663 | + { |
|
| 1664 | + if ($this->status_ID() !== EEM_Transaction::abandoned_status_code) { |
|
| 1665 | + return; |
|
| 1666 | + } |
|
| 1667 | + $payments = $this->get_many_related('Payment'); |
|
| 1668 | + if (! empty($payments)) { |
|
| 1669 | + foreach ($payments as $payment) { |
|
| 1670 | + if ($payment instanceof EE_Payment) { |
|
| 1671 | + // kk this TXN should NOT be abandoned |
|
| 1672 | + $this->update_status_based_on_total_paid(); |
|
| 1673 | + if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) { |
|
| 1674 | + EE_Error::add_attention( |
|
| 1675 | + sprintf( |
|
| 1676 | + esc_html__( |
|
| 1677 | + 'The status for Transaction #%1$d has been updated from "Abandoned" to "%2$s", because at least one payment has been made towards it. If the payment appears in the "Payment Details" table below, you may need to edit its status and/or other details as well.', |
|
| 1678 | + 'event_espresso' |
|
| 1679 | + ), |
|
| 1680 | + $this->ID(), |
|
| 1681 | + $this->pretty_status() |
|
| 1682 | + ) |
|
| 1683 | + ); |
|
| 1684 | + } |
|
| 1685 | + // get final reg step status |
|
| 1686 | + $finalized = $this->final_reg_step_completed(); |
|
| 1687 | + // if the 'finalize_registration' step has been initiated (has a timestamp) |
|
| 1688 | + // but has not yet been fully completed (TRUE) |
|
| 1689 | + if (is_int($finalized) && $finalized !== false && $finalized !== true) { |
|
| 1690 | + $this->set_reg_step_completed('finalize_registration'); |
|
| 1691 | + $this->save(); |
|
| 1692 | + } |
|
| 1693 | + } |
|
| 1694 | + } |
|
| 1695 | + } |
|
| 1696 | + } |
|
| 1697 | + |
|
| 1698 | + |
|
| 1699 | + /** |
|
| 1700 | + * @since 4.10.4.p |
|
| 1701 | + * @throws EE_Error |
|
| 1702 | + * @throws InvalidArgumentException |
|
| 1703 | + * @throws InvalidDataTypeException |
|
| 1704 | + * @throws InvalidInterfaceException |
|
| 1705 | + * @throws ReflectionException |
|
| 1706 | + * @throws RuntimeException |
|
| 1707 | + */ |
|
| 1708 | + public function recalculateLineItems() |
|
| 1709 | + { |
|
| 1710 | + $total_line_item = $this->total_line_item(false); |
|
| 1711 | + if ($total_line_item instanceof EE_Line_Item) { |
|
| 1712 | + EEH_Line_Item::resetIsTaxableForTickets($total_line_item); |
|
| 1713 | + return EEH_Line_Item::apply_taxes($total_line_item, true); |
|
| 1714 | + } |
|
| 1715 | + return false; |
|
| 1716 | + } |
|
| 1717 | 1717 | } |
@@ -14,668 +14,668 @@ |
||
| 14 | 14 | class EE_Question extends EE_Soft_Delete_Base_Class implements EEI_Duplicatable |
| 15 | 15 | { |
| 16 | 16 | |
| 17 | - /** |
|
| 18 | - * |
|
| 19 | - * @param array $props_n_values incoming values |
|
| 20 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 21 | - * used.) |
|
| 22 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 23 | - * date_format and the second value is the time format |
|
| 24 | - * @return EE_Question |
|
| 25 | - */ |
|
| 26 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 27 | - { |
|
| 28 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 29 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 30 | - } |
|
| 31 | - |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * @param array $props_n_values incoming values from the database |
|
| 35 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 36 | - * the website will be used. |
|
| 37 | - * @return EE_Question |
|
| 38 | - */ |
|
| 39 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 40 | - { |
|
| 41 | - return new self($props_n_values, true, $timezone); |
|
| 42 | - } |
|
| 43 | - |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * Set Question display text |
|
| 47 | - * |
|
| 48 | - * @access public |
|
| 49 | - * @param string $QST_display_text |
|
| 50 | - */ |
|
| 51 | - public function set_display_text($QST_display_text = '') |
|
| 52 | - { |
|
| 53 | - $this->set('QST_display_text', $QST_display_text); |
|
| 54 | - } |
|
| 55 | - |
|
| 56 | - |
|
| 57 | - /** |
|
| 58 | - * Set Question admin text |
|
| 59 | - * |
|
| 60 | - * @access public |
|
| 61 | - * @param string $QST_admin_label |
|
| 62 | - */ |
|
| 63 | - public function set_admin_label($QST_admin_label = '') |
|
| 64 | - { |
|
| 65 | - $this->set('QST_admin_label', $QST_admin_label); |
|
| 66 | - } |
|
| 67 | - |
|
| 68 | - |
|
| 69 | - /** |
|
| 70 | - * Set system name |
|
| 71 | - * |
|
| 72 | - * @access public |
|
| 73 | - * @param mixed $QST_system |
|
| 74 | - */ |
|
| 75 | - public function set_system_ID($QST_system = '') |
|
| 76 | - { |
|
| 77 | - $this->set('QST_system', $QST_system); |
|
| 78 | - } |
|
| 79 | - |
|
| 80 | - |
|
| 81 | - /** |
|
| 82 | - * Set question's type |
|
| 83 | - * |
|
| 84 | - * @access public |
|
| 85 | - * @param string $QST_type |
|
| 86 | - */ |
|
| 87 | - public function set_question_type($QST_type = '') |
|
| 88 | - { |
|
| 89 | - $this->set('QST_type', $QST_type); |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - |
|
| 93 | - /** |
|
| 94 | - * Sets whether this question must be answered when presented in a form |
|
| 95 | - * |
|
| 96 | - * @access public |
|
| 97 | - * @param bool $QST_required |
|
| 98 | - */ |
|
| 99 | - public function set_required($QST_required = false) |
|
| 100 | - { |
|
| 101 | - $this->set('QST_required', $QST_required); |
|
| 102 | - } |
|
| 103 | - |
|
| 104 | - |
|
| 105 | - /** |
|
| 106 | - * Set Question display text |
|
| 107 | - * |
|
| 108 | - * @access public |
|
| 109 | - * @param string $QST_required_text |
|
| 110 | - */ |
|
| 111 | - public function set_required_text($QST_required_text = '') |
|
| 112 | - { |
|
| 113 | - $this->set('QST_required_text', $QST_required_text); |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - |
|
| 117 | - /** |
|
| 118 | - * Sets the order of this question when placed in a sequence of questions |
|
| 119 | - * |
|
| 120 | - * @access public |
|
| 121 | - * @param int $QST_order |
|
| 122 | - */ |
|
| 123 | - public function set_order($QST_order = 0) |
|
| 124 | - { |
|
| 125 | - $this->set('QST_order', $QST_order); |
|
| 126 | - } |
|
| 127 | - |
|
| 128 | - |
|
| 129 | - /** |
|
| 130 | - * Sets whether the question is admin-only |
|
| 131 | - * |
|
| 132 | - * @access public |
|
| 133 | - * @param bool $QST_admin_only |
|
| 134 | - */ |
|
| 135 | - public function set_admin_only($QST_admin_only = false) |
|
| 136 | - { |
|
| 137 | - $this->set('QST_admin_only', $QST_admin_only); |
|
| 138 | - } |
|
| 139 | - |
|
| 140 | - |
|
| 141 | - /** |
|
| 142 | - * Sets the wordpress user ID on the question |
|
| 143 | - * |
|
| 144 | - * @access public |
|
| 145 | - * @param int $QST_wp_user |
|
| 146 | - */ |
|
| 147 | - public function set_wp_user($QST_wp_user = 1) |
|
| 148 | - { |
|
| 149 | - $this->set('QST_wp_user', $QST_wp_user); |
|
| 150 | - } |
|
| 151 | - |
|
| 152 | - |
|
| 153 | - /** |
|
| 154 | - * Sets whether the question has been deleted |
|
| 155 | - * (we use this boolean instead of actually |
|
| 156 | - * deleting it because when users delete this question |
|
| 157 | - * they really want to remove the question from future |
|
| 158 | - * forms, BUT keep their old answers which depend |
|
| 159 | - * on this record actually existing. |
|
| 160 | - * |
|
| 161 | - * @access public |
|
| 162 | - * @param bool $QST_deleted |
|
| 163 | - */ |
|
| 164 | - public function set_deleted($QST_deleted = false) |
|
| 165 | - { |
|
| 166 | - $this->set('QST_deleted', $QST_deleted); |
|
| 167 | - } |
|
| 168 | - |
|
| 169 | - |
|
| 170 | - /** |
|
| 171 | - * returns the text for displaying the question to users |
|
| 172 | - * |
|
| 173 | - * @access public |
|
| 174 | - * @return string |
|
| 175 | - */ |
|
| 176 | - public function display_text() |
|
| 177 | - { |
|
| 178 | - return $this->get('QST_display_text'); |
|
| 179 | - } |
|
| 180 | - |
|
| 181 | - |
|
| 182 | - /** |
|
| 183 | - * returns the text for the administrative label |
|
| 184 | - * |
|
| 185 | - * @access public |
|
| 186 | - * @return string |
|
| 187 | - */ |
|
| 188 | - public function admin_label() |
|
| 189 | - { |
|
| 190 | - return $this->get('QST_admin_label'); |
|
| 191 | - } |
|
| 192 | - |
|
| 193 | - |
|
| 194 | - /** |
|
| 195 | - * returns the attendee column name for this question |
|
| 196 | - * |
|
| 197 | - * @access public |
|
| 198 | - * @return string |
|
| 199 | - */ |
|
| 200 | - public function system_ID() |
|
| 201 | - { |
|
| 202 | - return $this->get('QST_system'); |
|
| 203 | - } |
|
| 204 | - |
|
| 205 | - |
|
| 206 | - /** |
|
| 207 | - * returns either a string of 'text', 'textfield', etc. |
|
| 208 | - * |
|
| 209 | - * @access public |
|
| 210 | - * @return boolean |
|
| 211 | - */ |
|
| 212 | - public function required() |
|
| 213 | - { |
|
| 214 | - return $this->get('QST_required'); |
|
| 215 | - } |
|
| 216 | - |
|
| 217 | - |
|
| 218 | - /** |
|
| 219 | - * returns the text which should be displayed when a user |
|
| 220 | - * doesn't answer this question in a form |
|
| 221 | - * |
|
| 222 | - * @access public |
|
| 223 | - * @return string |
|
| 224 | - */ |
|
| 225 | - public function required_text() |
|
| 226 | - { |
|
| 227 | - return $this->get('QST_required_text'); |
|
| 228 | - } |
|
| 229 | - |
|
| 230 | - |
|
| 231 | - /** |
|
| 232 | - * returns the type of this question |
|
| 233 | - * |
|
| 234 | - * @access public |
|
| 235 | - * @return string |
|
| 236 | - */ |
|
| 237 | - public function type() |
|
| 238 | - { |
|
| 239 | - return $this->get('QST_type'); |
|
| 240 | - } |
|
| 241 | - |
|
| 242 | - |
|
| 243 | - /** |
|
| 244 | - * returns an integer showing where this question should |
|
| 245 | - * be placed in a sequence of questions |
|
| 246 | - * |
|
| 247 | - * @access public |
|
| 248 | - * @return int |
|
| 249 | - */ |
|
| 250 | - public function order() |
|
| 251 | - { |
|
| 252 | - return $this->get('QST_order'); |
|
| 253 | - } |
|
| 254 | - |
|
| 255 | - |
|
| 256 | - /** |
|
| 257 | - * returns whether this question should only appears to admins, |
|
| 258 | - * or to everyone |
|
| 259 | - * |
|
| 260 | - * @access public |
|
| 261 | - * @return boolean |
|
| 262 | - */ |
|
| 263 | - public function admin_only() |
|
| 264 | - { |
|
| 265 | - return $this->get('QST_admin_only'); |
|
| 266 | - } |
|
| 267 | - |
|
| 268 | - |
|
| 269 | - /** |
|
| 270 | - * returns the id the wordpress user who created this question |
|
| 271 | - * |
|
| 272 | - * @access public |
|
| 273 | - * @return int |
|
| 274 | - */ |
|
| 275 | - public function wp_user() |
|
| 276 | - { |
|
| 277 | - return $this->get('QST_wp_user'); |
|
| 278 | - } |
|
| 279 | - |
|
| 280 | - |
|
| 281 | - /** |
|
| 282 | - * returns whether this question has been marked as 'deleted' |
|
| 283 | - * |
|
| 284 | - * @access public |
|
| 285 | - * @return boolean |
|
| 286 | - */ |
|
| 287 | - public function deleted() |
|
| 288 | - { |
|
| 289 | - return $this->get('QST_deleted'); |
|
| 290 | - } |
|
| 291 | - |
|
| 292 | - |
|
| 293 | - /** |
|
| 294 | - * Gets an array of related EE_Answer to this EE_Question |
|
| 295 | - * |
|
| 296 | - * @return EE_Answer[] |
|
| 297 | - */ |
|
| 298 | - public function answers() |
|
| 299 | - { |
|
| 300 | - return $this->get_many_related('Answer'); |
|
| 301 | - } |
|
| 302 | - |
|
| 303 | - |
|
| 304 | - /** |
|
| 305 | - * Boolean check for if there are answers on this question in th db |
|
| 306 | - * |
|
| 307 | - * @return boolean true = has answers, false = no answers. |
|
| 308 | - */ |
|
| 309 | - public function has_answers() |
|
| 310 | - { |
|
| 311 | - return $this->count_related('Answer') > 0 ? true : false; |
|
| 312 | - } |
|
| 313 | - |
|
| 314 | - |
|
| 315 | - /** |
|
| 316 | - * gets an array of EE_Question_Group which relate to this question |
|
| 317 | - * |
|
| 318 | - * @return EE_Question_Group[] |
|
| 319 | - */ |
|
| 320 | - public function question_groups() |
|
| 321 | - { |
|
| 322 | - return $this->get_many_related('Question_Group'); |
|
| 323 | - } |
|
| 324 | - |
|
| 325 | - |
|
| 326 | - /** |
|
| 327 | - * Returns all the options for this question. By default, it returns only the not-yet-deleted ones. |
|
| 328 | - * |
|
| 329 | - * @param boolean $notDeletedOptionsOnly 1 |
|
| 330 | - * whether to return ALL options, or only the ones which have |
|
| 331 | - * not yet been deleleted |
|
| 332 | - * @param string|array $selected_value_to_always_include , when retrieving options to an ANSWERED question, |
|
| 333 | - * we want to usually only show non-deleted options AND the |
|
| 334 | - * value that was selected for the answer, whether it was |
|
| 335 | - * trashed or not. |
|
| 336 | - * @return EE_Question_Option[] |
|
| 337 | - */ |
|
| 338 | - public function options($notDeletedOptionsOnly = true, $selected_value_to_always_include = null) |
|
| 339 | - { |
|
| 340 | - if (! $this->ID()) { |
|
| 341 | - return array(); |
|
| 342 | - } |
|
| 343 | - $query_params = array(); |
|
| 344 | - if ($selected_value_to_always_include) { |
|
| 345 | - if (is_array($selected_value_to_always_include)) { |
|
| 346 | - $query_params[0]['OR*options-query']['QSO_value'] = array('IN', $selected_value_to_always_include); |
|
| 347 | - } else { |
|
| 348 | - $query_params[0]['OR*options-query']['QSO_value'] = $selected_value_to_always_include; |
|
| 349 | - } |
|
| 350 | - } |
|
| 351 | - if ($notDeletedOptionsOnly) { |
|
| 352 | - $query_params[0]['OR*options-query']['QSO_deleted'] = false; |
|
| 353 | - } |
|
| 354 | - // order by QSO_order |
|
| 355 | - $query_params['order_by'] = array('QSO_order' => 'ASC'); |
|
| 356 | - return $this->get_many_related('Question_Option', $query_params); |
|
| 357 | - } |
|
| 358 | - |
|
| 359 | - |
|
| 360 | - /** |
|
| 361 | - * returns an array of EE_Question_Options which relate to this question |
|
| 362 | - * |
|
| 363 | - * @return \EE_Question_Option[] |
|
| 364 | - */ |
|
| 365 | - public function temp_options() |
|
| 366 | - { |
|
| 367 | - return $this->_model_relations['Question_Option']; |
|
| 368 | - } |
|
| 369 | - |
|
| 370 | - |
|
| 371 | - /** |
|
| 372 | - * Adds an option for this question. Note: if the option were previously associated with a different |
|
| 373 | - * Question, that relationship will be overwritten. |
|
| 374 | - * |
|
| 375 | - * @param EE_Question_Option $option |
|
| 376 | - * @return boolean success |
|
| 377 | - */ |
|
| 378 | - public function add_option(EE_Question_Option $option) |
|
| 379 | - { |
|
| 380 | - return $this->_add_relation_to($option, 'Question_Option'); |
|
| 381 | - } |
|
| 382 | - |
|
| 383 | - |
|
| 384 | - /** |
|
| 385 | - * Adds an option directly to this question without saving to the db |
|
| 386 | - * |
|
| 387 | - * @param EE_Question_Option $option |
|
| 388 | - * @return boolean success |
|
| 389 | - */ |
|
| 390 | - public function add_temp_option(EE_Question_Option $option) |
|
| 391 | - { |
|
| 392 | - $this->_model_relations['Question_Option'][] = $option; |
|
| 393 | - return true; |
|
| 394 | - } |
|
| 395 | - |
|
| 396 | - |
|
| 397 | - /** |
|
| 398 | - * Marks the option as deleted. |
|
| 399 | - * |
|
| 400 | - * @param EE_Question_Option $option |
|
| 401 | - * @return boolean success |
|
| 402 | - */ |
|
| 403 | - public function remove_option(EE_Question_Option $option) |
|
| 404 | - { |
|
| 405 | - return $this->_remove_relation_to($option, 'Question_Option'); |
|
| 406 | - } |
|
| 407 | - |
|
| 408 | - |
|
| 409 | - /** |
|
| 410 | - * @return bool |
|
| 411 | - */ |
|
| 412 | - public function is_system_question() |
|
| 413 | - { |
|
| 414 | - $system_ID = $this->get('QST_system'); |
|
| 415 | - return ! empty($system_ID) ? true : false; |
|
| 416 | - } |
|
| 417 | - |
|
| 418 | - |
|
| 419 | - /** |
|
| 420 | - * The purpose of this method is set the question order this question order to be the max out of all questions |
|
| 421 | - * |
|
| 422 | - * @access public |
|
| 423 | - * @return void |
|
| 424 | - */ |
|
| 425 | - public function set_order_to_latest() |
|
| 426 | - { |
|
| 427 | - $latest_order = $this->get_model()->get_latest_question_order(); |
|
| 428 | - $latest_order++; |
|
| 429 | - $this->set('QST_order', $latest_order); |
|
| 430 | - } |
|
| 431 | - |
|
| 432 | - |
|
| 433 | - /** |
|
| 434 | - * Retrieves the list of allowed question types from the model. |
|
| 435 | - * |
|
| 436 | - * @return string[] |
|
| 437 | - */ |
|
| 438 | - private function _allowed_question_types() |
|
| 439 | - { |
|
| 440 | - $questionModel = $this->get_model(); |
|
| 441 | - /* @var $questionModel EEM_Question */ |
|
| 442 | - return $questionModel->allowed_question_types(); |
|
| 443 | - } |
|
| 444 | - |
|
| 445 | - /** |
|
| 446 | - * Duplicates this question and its question options |
|
| 447 | - * |
|
| 448 | - * @return \EE_Question |
|
| 449 | - */ |
|
| 450 | - public function duplicate($options = array()) |
|
| 451 | - { |
|
| 452 | - $new_question = clone $this; |
|
| 453 | - $new_question->set('QST_ID', null); |
|
| 454 | - $new_question->set_display_text(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->display_text())); |
|
| 455 | - $new_question->set_admin_label(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->admin_label())); |
|
| 456 | - $new_question->set_system_ID(null); |
|
| 457 | - $new_question->set_wp_user(get_current_user_id()); |
|
| 458 | - // if we're duplicating a trashed question, assume we don't want the new one to be trashed |
|
| 459 | - $new_question->set_deleted(false); |
|
| 460 | - $success = $new_question->save(); |
|
| 461 | - if ($success) { |
|
| 462 | - // we don't totally want to duplicate the question options, because we want them to be for the NEW question |
|
| 463 | - foreach ($this->options() as $question_option) { |
|
| 464 | - $question_option->duplicate(array('QST_ID' => $new_question->ID())); |
|
| 465 | - } |
|
| 466 | - return $new_question; |
|
| 467 | - } else { |
|
| 468 | - return null; |
|
| 469 | - } |
|
| 470 | - } |
|
| 471 | - |
|
| 472 | - /** |
|
| 473 | - * Returns the question's maximum allowed response size |
|
| 474 | - * |
|
| 475 | - * @return int|float |
|
| 476 | - */ |
|
| 477 | - public function max() |
|
| 478 | - { |
|
| 479 | - return $this->get('QST_max'); |
|
| 480 | - } |
|
| 481 | - |
|
| 482 | - /** |
|
| 483 | - * Sets the question's maximum allowed response size |
|
| 484 | - * |
|
| 485 | - * @param int|float $new_max |
|
| 486 | - * @return void |
|
| 487 | - */ |
|
| 488 | - public function set_max($new_max) |
|
| 489 | - { |
|
| 490 | - $this->set('QST_max', $new_max); |
|
| 491 | - } |
|
| 492 | - |
|
| 493 | - |
|
| 494 | - /** |
|
| 495 | - * Creates a form input from this question which can be used in HTML forms |
|
| 496 | - * |
|
| 497 | - * @param EE_Registration $registration |
|
| 498 | - * @param EE_Answer $answer |
|
| 499 | - * @param array $input_constructor_args |
|
| 500 | - * @return EE_Form_Input_Base |
|
| 501 | - */ |
|
| 502 | - public function generate_form_input($registration = null, $answer = null, $input_constructor_args = array()) |
|
| 503 | - { |
|
| 504 | - $identifier = $this->is_system_question() ? $this->system_ID() : $this->ID(); |
|
| 505 | - |
|
| 506 | - $input_constructor_args = array_merge( |
|
| 507 | - array( |
|
| 508 | - 'required' => $this->required() ? true : false, |
|
| 509 | - 'html_label_text' => $this->display_text(), |
|
| 510 | - 'required_validation_error_message' => $this->required_text(), |
|
| 511 | - ), |
|
| 512 | - $input_constructor_args |
|
| 513 | - ); |
|
| 514 | - if (! $answer instanceof EE_Answer && $registration instanceof EE_Registration) { |
|
| 515 | - $answer = EEM_Answer::instance()->get_registration_question_answer_object($registration, $this->ID()); |
|
| 516 | - } |
|
| 517 | - // has this question been answered ? |
|
| 518 | - if ( |
|
| 519 | - $answer instanceof EE_Answer |
|
| 520 | - && $answer->value() !== '' |
|
| 521 | - ) { |
|
| 522 | - // answer gets htmlspecialchars called on it, undo that please |
|
| 523 | - // because the form input's display strategy may call esc_attr too |
|
| 524 | - // which also does html special characters |
|
| 525 | - $values_with_html_special_chars = $answer->value(); |
|
| 526 | - if (is_array($values_with_html_special_chars)) { |
|
| 527 | - $default_value = array_map('htmlspecialchars_decode', $values_with_html_special_chars); |
|
| 528 | - } else { |
|
| 529 | - $default_value = htmlspecialchars_decode($values_with_html_special_chars); |
|
| 530 | - } |
|
| 531 | - $input_constructor_args['default'] = $default_value; |
|
| 532 | - } |
|
| 533 | - $max_max_for_question = EEM_Question::instance()->absolute_max_for_system_question($this->system_ID()); |
|
| 534 | - if ( |
|
| 535 | - in_array( |
|
| 536 | - $this->type(), |
|
| 537 | - EEM_Question::instance()->questionTypesWithMaxLength(), |
|
| 538 | - true |
|
| 539 | - ) |
|
| 540 | - ) { |
|
| 541 | - $input_constructor_args['validation_strategies'][] = new EE_Max_Length_Validation_Strategy( |
|
| 542 | - null, |
|
| 543 | - min($max_max_for_question, $this->max()) |
|
| 544 | - ); |
|
| 545 | - } |
|
| 546 | - $input_constructor_args = apply_filters( |
|
| 547 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__input_constructor_args', |
|
| 548 | - $input_constructor_args, |
|
| 549 | - $registration, |
|
| 550 | - $this, |
|
| 551 | - $answer |
|
| 552 | - ); |
|
| 553 | - |
|
| 554 | - $result = null; |
|
| 555 | - switch ($this->type()) { |
|
| 556 | - // Text |
|
| 557 | - case EEM_Question::QST_type_text: |
|
| 558 | - $result = new EE_Text_Input($input_constructor_args); |
|
| 559 | - break; |
|
| 560 | - // Textarea |
|
| 561 | - case EEM_Question::QST_type_textarea: |
|
| 562 | - $result = new EE_Text_Area_Input($input_constructor_args); |
|
| 563 | - break; |
|
| 564 | - // Radio Buttons |
|
| 565 | - case EEM_Question::QST_type_radio: |
|
| 566 | - $result = new EE_Radio_Button_Input($this->options(), $input_constructor_args); |
|
| 567 | - break; |
|
| 568 | - // Dropdown |
|
| 569 | - case EEM_Question::QST_type_dropdown: |
|
| 570 | - $result = new EE_Select_Input($this->options(), $input_constructor_args); |
|
| 571 | - break; |
|
| 572 | - // State Dropdown |
|
| 573 | - case EEM_Question::QST_type_state: |
|
| 574 | - $state_options = apply_filters( |
|
| 575 | - 'FHEE__EE_Question__generate_form_input__state_options', |
|
| 576 | - null, |
|
| 577 | - $this, |
|
| 578 | - $registration, |
|
| 579 | - $answer |
|
| 580 | - ); |
|
| 581 | - $result = new EE_State_Select_Input($state_options, $input_constructor_args); |
|
| 582 | - break; |
|
| 583 | - // Country Dropdown |
|
| 584 | - case EEM_Question::QST_type_country: |
|
| 585 | - $country_options = apply_filters( |
|
| 586 | - 'FHEE__EE_Question__generate_form_input__country_options', |
|
| 587 | - null, |
|
| 588 | - $this, |
|
| 589 | - $registration, |
|
| 590 | - $answer |
|
| 591 | - ); |
|
| 592 | - $result = new EE_Country_Select_Input($country_options, $input_constructor_args); |
|
| 593 | - break; |
|
| 594 | - // Checkboxes |
|
| 595 | - case EEM_Question::QST_type_checkbox: |
|
| 596 | - $result = new EE_Checkbox_Multi_Input($this->options(), $input_constructor_args); |
|
| 597 | - break; |
|
| 598 | - // Date |
|
| 599 | - case EEM_Question::QST_type_date: |
|
| 600 | - $result = new EE_Datepicker_Input($input_constructor_args); |
|
| 601 | - break; |
|
| 602 | - case EEM_Question::QST_type_html_textarea: |
|
| 603 | - $input_constructor_args['validation_strategies'][] = new EE_Simple_HTML_Validation_Strategy(); |
|
| 604 | - $result = new EE_Text_Area_Input($input_constructor_args); |
|
| 605 | - $result->remove_validation_strategy('EE_Plaintext_Validation_Strategy'); |
|
| 606 | - break; |
|
| 607 | - case EEM_Question::QST_type_email: |
|
| 608 | - $result = new EE_Email_Input($input_constructor_args); |
|
| 609 | - break; |
|
| 610 | - // Email confirm |
|
| 611 | - case EEM_Question::QST_type_email_confirm: |
|
| 612 | - $result = new EE_Email_Confirm_Input($input_constructor_args); |
|
| 613 | - break; |
|
| 614 | - case EEM_Question::QST_type_us_phone: |
|
| 615 | - $result = new EE_Phone_Input($input_constructor_args); |
|
| 616 | - break; |
|
| 617 | - case EEM_Question::QST_type_int: |
|
| 618 | - $result = new EE_Integer_Input($input_constructor_args); |
|
| 619 | - break; |
|
| 620 | - case EEM_Question::QST_type_decimal: |
|
| 621 | - $result = new EE_Float_Input($input_constructor_args); |
|
| 622 | - break; |
|
| 623 | - case EEM_Question::QST_type_url: |
|
| 624 | - $input_constructor_args['validation_strategies'][] = LoaderFactory::getLoader()->getNew('EE_URL_Validation_Strategy'); |
|
| 625 | - $result = new EE_Text_Input($input_constructor_args); |
|
| 626 | - break; |
|
| 627 | - case EEM_Question::QST_type_year: |
|
| 628 | - $result = new EE_Year_Input( |
|
| 629 | - $input_constructor_args, |
|
| 630 | - apply_filters( |
|
| 631 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__four_digit', |
|
| 632 | - true, |
|
| 633 | - $this |
|
| 634 | - ), |
|
| 635 | - apply_filters( |
|
| 636 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__early_range', |
|
| 637 | - 100, |
|
| 638 | - $this |
|
| 639 | - ), |
|
| 640 | - apply_filters( |
|
| 641 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__end_range', |
|
| 642 | - 100, |
|
| 643 | - $this |
|
| 644 | - ) |
|
| 645 | - ); |
|
| 646 | - break; |
|
| 647 | - case EEM_Question::QST_type_multi_select: |
|
| 648 | - $result = new EE_Select_Multiple_Input($this->options(), $input_constructor_args); |
|
| 649 | - break; |
|
| 650 | - // fallback |
|
| 651 | - default: |
|
| 652 | - $default_input = apply_filters( |
|
| 653 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__default', |
|
| 654 | - null, |
|
| 655 | - $this->type(), |
|
| 656 | - $this, |
|
| 657 | - $input_constructor_args |
|
| 658 | - ); |
|
| 659 | - if (! $default_input) { |
|
| 660 | - $default_input = new EE_Text_Input($input_constructor_args); |
|
| 661 | - } |
|
| 662 | - $result = $default_input; |
|
| 663 | - } |
|
| 664 | - return apply_filters('FHEE__EE_Question__generate_form_input__return', $result, $registration, $this, $answer); |
|
| 665 | - } |
|
| 666 | - |
|
| 667 | - |
|
| 668 | - /** |
|
| 669 | - * Returns whether or not this question type should have question option entries |
|
| 670 | - * |
|
| 671 | - * @return bool |
|
| 672 | - */ |
|
| 673 | - public function should_have_question_options() |
|
| 674 | - { |
|
| 675 | - return in_array( |
|
| 676 | - $this->type(), |
|
| 677 | - $this->_model->question_types_with_options(), |
|
| 678 | - true |
|
| 679 | - ); |
|
| 680 | - } |
|
| 17 | + /** |
|
| 18 | + * |
|
| 19 | + * @param array $props_n_values incoming values |
|
| 20 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 21 | + * used.) |
|
| 22 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 23 | + * date_format and the second value is the time format |
|
| 24 | + * @return EE_Question |
|
| 25 | + */ |
|
| 26 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 27 | + { |
|
| 28 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 29 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 30 | + } |
|
| 31 | + |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * @param array $props_n_values incoming values from the database |
|
| 35 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 36 | + * the website will be used. |
|
| 37 | + * @return EE_Question |
|
| 38 | + */ |
|
| 39 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 40 | + { |
|
| 41 | + return new self($props_n_values, true, $timezone); |
|
| 42 | + } |
|
| 43 | + |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * Set Question display text |
|
| 47 | + * |
|
| 48 | + * @access public |
|
| 49 | + * @param string $QST_display_text |
|
| 50 | + */ |
|
| 51 | + public function set_display_text($QST_display_text = '') |
|
| 52 | + { |
|
| 53 | + $this->set('QST_display_text', $QST_display_text); |
|
| 54 | + } |
|
| 55 | + |
|
| 56 | + |
|
| 57 | + /** |
|
| 58 | + * Set Question admin text |
|
| 59 | + * |
|
| 60 | + * @access public |
|
| 61 | + * @param string $QST_admin_label |
|
| 62 | + */ |
|
| 63 | + public function set_admin_label($QST_admin_label = '') |
|
| 64 | + { |
|
| 65 | + $this->set('QST_admin_label', $QST_admin_label); |
|
| 66 | + } |
|
| 67 | + |
|
| 68 | + |
|
| 69 | + /** |
|
| 70 | + * Set system name |
|
| 71 | + * |
|
| 72 | + * @access public |
|
| 73 | + * @param mixed $QST_system |
|
| 74 | + */ |
|
| 75 | + public function set_system_ID($QST_system = '') |
|
| 76 | + { |
|
| 77 | + $this->set('QST_system', $QST_system); |
|
| 78 | + } |
|
| 79 | + |
|
| 80 | + |
|
| 81 | + /** |
|
| 82 | + * Set question's type |
|
| 83 | + * |
|
| 84 | + * @access public |
|
| 85 | + * @param string $QST_type |
|
| 86 | + */ |
|
| 87 | + public function set_question_type($QST_type = '') |
|
| 88 | + { |
|
| 89 | + $this->set('QST_type', $QST_type); |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + |
|
| 93 | + /** |
|
| 94 | + * Sets whether this question must be answered when presented in a form |
|
| 95 | + * |
|
| 96 | + * @access public |
|
| 97 | + * @param bool $QST_required |
|
| 98 | + */ |
|
| 99 | + public function set_required($QST_required = false) |
|
| 100 | + { |
|
| 101 | + $this->set('QST_required', $QST_required); |
|
| 102 | + } |
|
| 103 | + |
|
| 104 | + |
|
| 105 | + /** |
|
| 106 | + * Set Question display text |
|
| 107 | + * |
|
| 108 | + * @access public |
|
| 109 | + * @param string $QST_required_text |
|
| 110 | + */ |
|
| 111 | + public function set_required_text($QST_required_text = '') |
|
| 112 | + { |
|
| 113 | + $this->set('QST_required_text', $QST_required_text); |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + |
|
| 117 | + /** |
|
| 118 | + * Sets the order of this question when placed in a sequence of questions |
|
| 119 | + * |
|
| 120 | + * @access public |
|
| 121 | + * @param int $QST_order |
|
| 122 | + */ |
|
| 123 | + public function set_order($QST_order = 0) |
|
| 124 | + { |
|
| 125 | + $this->set('QST_order', $QST_order); |
|
| 126 | + } |
|
| 127 | + |
|
| 128 | + |
|
| 129 | + /** |
|
| 130 | + * Sets whether the question is admin-only |
|
| 131 | + * |
|
| 132 | + * @access public |
|
| 133 | + * @param bool $QST_admin_only |
|
| 134 | + */ |
|
| 135 | + public function set_admin_only($QST_admin_only = false) |
|
| 136 | + { |
|
| 137 | + $this->set('QST_admin_only', $QST_admin_only); |
|
| 138 | + } |
|
| 139 | + |
|
| 140 | + |
|
| 141 | + /** |
|
| 142 | + * Sets the wordpress user ID on the question |
|
| 143 | + * |
|
| 144 | + * @access public |
|
| 145 | + * @param int $QST_wp_user |
|
| 146 | + */ |
|
| 147 | + public function set_wp_user($QST_wp_user = 1) |
|
| 148 | + { |
|
| 149 | + $this->set('QST_wp_user', $QST_wp_user); |
|
| 150 | + } |
|
| 151 | + |
|
| 152 | + |
|
| 153 | + /** |
|
| 154 | + * Sets whether the question has been deleted |
|
| 155 | + * (we use this boolean instead of actually |
|
| 156 | + * deleting it because when users delete this question |
|
| 157 | + * they really want to remove the question from future |
|
| 158 | + * forms, BUT keep their old answers which depend |
|
| 159 | + * on this record actually existing. |
|
| 160 | + * |
|
| 161 | + * @access public |
|
| 162 | + * @param bool $QST_deleted |
|
| 163 | + */ |
|
| 164 | + public function set_deleted($QST_deleted = false) |
|
| 165 | + { |
|
| 166 | + $this->set('QST_deleted', $QST_deleted); |
|
| 167 | + } |
|
| 168 | + |
|
| 169 | + |
|
| 170 | + /** |
|
| 171 | + * returns the text for displaying the question to users |
|
| 172 | + * |
|
| 173 | + * @access public |
|
| 174 | + * @return string |
|
| 175 | + */ |
|
| 176 | + public function display_text() |
|
| 177 | + { |
|
| 178 | + return $this->get('QST_display_text'); |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + |
|
| 182 | + /** |
|
| 183 | + * returns the text for the administrative label |
|
| 184 | + * |
|
| 185 | + * @access public |
|
| 186 | + * @return string |
|
| 187 | + */ |
|
| 188 | + public function admin_label() |
|
| 189 | + { |
|
| 190 | + return $this->get('QST_admin_label'); |
|
| 191 | + } |
|
| 192 | + |
|
| 193 | + |
|
| 194 | + /** |
|
| 195 | + * returns the attendee column name for this question |
|
| 196 | + * |
|
| 197 | + * @access public |
|
| 198 | + * @return string |
|
| 199 | + */ |
|
| 200 | + public function system_ID() |
|
| 201 | + { |
|
| 202 | + return $this->get('QST_system'); |
|
| 203 | + } |
|
| 204 | + |
|
| 205 | + |
|
| 206 | + /** |
|
| 207 | + * returns either a string of 'text', 'textfield', etc. |
|
| 208 | + * |
|
| 209 | + * @access public |
|
| 210 | + * @return boolean |
|
| 211 | + */ |
|
| 212 | + public function required() |
|
| 213 | + { |
|
| 214 | + return $this->get('QST_required'); |
|
| 215 | + } |
|
| 216 | + |
|
| 217 | + |
|
| 218 | + /** |
|
| 219 | + * returns the text which should be displayed when a user |
|
| 220 | + * doesn't answer this question in a form |
|
| 221 | + * |
|
| 222 | + * @access public |
|
| 223 | + * @return string |
|
| 224 | + */ |
|
| 225 | + public function required_text() |
|
| 226 | + { |
|
| 227 | + return $this->get('QST_required_text'); |
|
| 228 | + } |
|
| 229 | + |
|
| 230 | + |
|
| 231 | + /** |
|
| 232 | + * returns the type of this question |
|
| 233 | + * |
|
| 234 | + * @access public |
|
| 235 | + * @return string |
|
| 236 | + */ |
|
| 237 | + public function type() |
|
| 238 | + { |
|
| 239 | + return $this->get('QST_type'); |
|
| 240 | + } |
|
| 241 | + |
|
| 242 | + |
|
| 243 | + /** |
|
| 244 | + * returns an integer showing where this question should |
|
| 245 | + * be placed in a sequence of questions |
|
| 246 | + * |
|
| 247 | + * @access public |
|
| 248 | + * @return int |
|
| 249 | + */ |
|
| 250 | + public function order() |
|
| 251 | + { |
|
| 252 | + return $this->get('QST_order'); |
|
| 253 | + } |
|
| 254 | + |
|
| 255 | + |
|
| 256 | + /** |
|
| 257 | + * returns whether this question should only appears to admins, |
|
| 258 | + * or to everyone |
|
| 259 | + * |
|
| 260 | + * @access public |
|
| 261 | + * @return boolean |
|
| 262 | + */ |
|
| 263 | + public function admin_only() |
|
| 264 | + { |
|
| 265 | + return $this->get('QST_admin_only'); |
|
| 266 | + } |
|
| 267 | + |
|
| 268 | + |
|
| 269 | + /** |
|
| 270 | + * returns the id the wordpress user who created this question |
|
| 271 | + * |
|
| 272 | + * @access public |
|
| 273 | + * @return int |
|
| 274 | + */ |
|
| 275 | + public function wp_user() |
|
| 276 | + { |
|
| 277 | + return $this->get('QST_wp_user'); |
|
| 278 | + } |
|
| 279 | + |
|
| 280 | + |
|
| 281 | + /** |
|
| 282 | + * returns whether this question has been marked as 'deleted' |
|
| 283 | + * |
|
| 284 | + * @access public |
|
| 285 | + * @return boolean |
|
| 286 | + */ |
|
| 287 | + public function deleted() |
|
| 288 | + { |
|
| 289 | + return $this->get('QST_deleted'); |
|
| 290 | + } |
|
| 291 | + |
|
| 292 | + |
|
| 293 | + /** |
|
| 294 | + * Gets an array of related EE_Answer to this EE_Question |
|
| 295 | + * |
|
| 296 | + * @return EE_Answer[] |
|
| 297 | + */ |
|
| 298 | + public function answers() |
|
| 299 | + { |
|
| 300 | + return $this->get_many_related('Answer'); |
|
| 301 | + } |
|
| 302 | + |
|
| 303 | + |
|
| 304 | + /** |
|
| 305 | + * Boolean check for if there are answers on this question in th db |
|
| 306 | + * |
|
| 307 | + * @return boolean true = has answers, false = no answers. |
|
| 308 | + */ |
|
| 309 | + public function has_answers() |
|
| 310 | + { |
|
| 311 | + return $this->count_related('Answer') > 0 ? true : false; |
|
| 312 | + } |
|
| 313 | + |
|
| 314 | + |
|
| 315 | + /** |
|
| 316 | + * gets an array of EE_Question_Group which relate to this question |
|
| 317 | + * |
|
| 318 | + * @return EE_Question_Group[] |
|
| 319 | + */ |
|
| 320 | + public function question_groups() |
|
| 321 | + { |
|
| 322 | + return $this->get_many_related('Question_Group'); |
|
| 323 | + } |
|
| 324 | + |
|
| 325 | + |
|
| 326 | + /** |
|
| 327 | + * Returns all the options for this question. By default, it returns only the not-yet-deleted ones. |
|
| 328 | + * |
|
| 329 | + * @param boolean $notDeletedOptionsOnly 1 |
|
| 330 | + * whether to return ALL options, or only the ones which have |
|
| 331 | + * not yet been deleleted |
|
| 332 | + * @param string|array $selected_value_to_always_include , when retrieving options to an ANSWERED question, |
|
| 333 | + * we want to usually only show non-deleted options AND the |
|
| 334 | + * value that was selected for the answer, whether it was |
|
| 335 | + * trashed or not. |
|
| 336 | + * @return EE_Question_Option[] |
|
| 337 | + */ |
|
| 338 | + public function options($notDeletedOptionsOnly = true, $selected_value_to_always_include = null) |
|
| 339 | + { |
|
| 340 | + if (! $this->ID()) { |
|
| 341 | + return array(); |
|
| 342 | + } |
|
| 343 | + $query_params = array(); |
|
| 344 | + if ($selected_value_to_always_include) { |
|
| 345 | + if (is_array($selected_value_to_always_include)) { |
|
| 346 | + $query_params[0]['OR*options-query']['QSO_value'] = array('IN', $selected_value_to_always_include); |
|
| 347 | + } else { |
|
| 348 | + $query_params[0]['OR*options-query']['QSO_value'] = $selected_value_to_always_include; |
|
| 349 | + } |
|
| 350 | + } |
|
| 351 | + if ($notDeletedOptionsOnly) { |
|
| 352 | + $query_params[0]['OR*options-query']['QSO_deleted'] = false; |
|
| 353 | + } |
|
| 354 | + // order by QSO_order |
|
| 355 | + $query_params['order_by'] = array('QSO_order' => 'ASC'); |
|
| 356 | + return $this->get_many_related('Question_Option', $query_params); |
|
| 357 | + } |
|
| 358 | + |
|
| 359 | + |
|
| 360 | + /** |
|
| 361 | + * returns an array of EE_Question_Options which relate to this question |
|
| 362 | + * |
|
| 363 | + * @return \EE_Question_Option[] |
|
| 364 | + */ |
|
| 365 | + public function temp_options() |
|
| 366 | + { |
|
| 367 | + return $this->_model_relations['Question_Option']; |
|
| 368 | + } |
|
| 369 | + |
|
| 370 | + |
|
| 371 | + /** |
|
| 372 | + * Adds an option for this question. Note: if the option were previously associated with a different |
|
| 373 | + * Question, that relationship will be overwritten. |
|
| 374 | + * |
|
| 375 | + * @param EE_Question_Option $option |
|
| 376 | + * @return boolean success |
|
| 377 | + */ |
|
| 378 | + public function add_option(EE_Question_Option $option) |
|
| 379 | + { |
|
| 380 | + return $this->_add_relation_to($option, 'Question_Option'); |
|
| 381 | + } |
|
| 382 | + |
|
| 383 | + |
|
| 384 | + /** |
|
| 385 | + * Adds an option directly to this question without saving to the db |
|
| 386 | + * |
|
| 387 | + * @param EE_Question_Option $option |
|
| 388 | + * @return boolean success |
|
| 389 | + */ |
|
| 390 | + public function add_temp_option(EE_Question_Option $option) |
|
| 391 | + { |
|
| 392 | + $this->_model_relations['Question_Option'][] = $option; |
|
| 393 | + return true; |
|
| 394 | + } |
|
| 395 | + |
|
| 396 | + |
|
| 397 | + /** |
|
| 398 | + * Marks the option as deleted. |
|
| 399 | + * |
|
| 400 | + * @param EE_Question_Option $option |
|
| 401 | + * @return boolean success |
|
| 402 | + */ |
|
| 403 | + public function remove_option(EE_Question_Option $option) |
|
| 404 | + { |
|
| 405 | + return $this->_remove_relation_to($option, 'Question_Option'); |
|
| 406 | + } |
|
| 407 | + |
|
| 408 | + |
|
| 409 | + /** |
|
| 410 | + * @return bool |
|
| 411 | + */ |
|
| 412 | + public function is_system_question() |
|
| 413 | + { |
|
| 414 | + $system_ID = $this->get('QST_system'); |
|
| 415 | + return ! empty($system_ID) ? true : false; |
|
| 416 | + } |
|
| 417 | + |
|
| 418 | + |
|
| 419 | + /** |
|
| 420 | + * The purpose of this method is set the question order this question order to be the max out of all questions |
|
| 421 | + * |
|
| 422 | + * @access public |
|
| 423 | + * @return void |
|
| 424 | + */ |
|
| 425 | + public function set_order_to_latest() |
|
| 426 | + { |
|
| 427 | + $latest_order = $this->get_model()->get_latest_question_order(); |
|
| 428 | + $latest_order++; |
|
| 429 | + $this->set('QST_order', $latest_order); |
|
| 430 | + } |
|
| 431 | + |
|
| 432 | + |
|
| 433 | + /** |
|
| 434 | + * Retrieves the list of allowed question types from the model. |
|
| 435 | + * |
|
| 436 | + * @return string[] |
|
| 437 | + */ |
|
| 438 | + private function _allowed_question_types() |
|
| 439 | + { |
|
| 440 | + $questionModel = $this->get_model(); |
|
| 441 | + /* @var $questionModel EEM_Question */ |
|
| 442 | + return $questionModel->allowed_question_types(); |
|
| 443 | + } |
|
| 444 | + |
|
| 445 | + /** |
|
| 446 | + * Duplicates this question and its question options |
|
| 447 | + * |
|
| 448 | + * @return \EE_Question |
|
| 449 | + */ |
|
| 450 | + public function duplicate($options = array()) |
|
| 451 | + { |
|
| 452 | + $new_question = clone $this; |
|
| 453 | + $new_question->set('QST_ID', null); |
|
| 454 | + $new_question->set_display_text(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->display_text())); |
|
| 455 | + $new_question->set_admin_label(sprintf(__('%s **Duplicate**', 'event_espresso'), $this->admin_label())); |
|
| 456 | + $new_question->set_system_ID(null); |
|
| 457 | + $new_question->set_wp_user(get_current_user_id()); |
|
| 458 | + // if we're duplicating a trashed question, assume we don't want the new one to be trashed |
|
| 459 | + $new_question->set_deleted(false); |
|
| 460 | + $success = $new_question->save(); |
|
| 461 | + if ($success) { |
|
| 462 | + // we don't totally want to duplicate the question options, because we want them to be for the NEW question |
|
| 463 | + foreach ($this->options() as $question_option) { |
|
| 464 | + $question_option->duplicate(array('QST_ID' => $new_question->ID())); |
|
| 465 | + } |
|
| 466 | + return $new_question; |
|
| 467 | + } else { |
|
| 468 | + return null; |
|
| 469 | + } |
|
| 470 | + } |
|
| 471 | + |
|
| 472 | + /** |
|
| 473 | + * Returns the question's maximum allowed response size |
|
| 474 | + * |
|
| 475 | + * @return int|float |
|
| 476 | + */ |
|
| 477 | + public function max() |
|
| 478 | + { |
|
| 479 | + return $this->get('QST_max'); |
|
| 480 | + } |
|
| 481 | + |
|
| 482 | + /** |
|
| 483 | + * Sets the question's maximum allowed response size |
|
| 484 | + * |
|
| 485 | + * @param int|float $new_max |
|
| 486 | + * @return void |
|
| 487 | + */ |
|
| 488 | + public function set_max($new_max) |
|
| 489 | + { |
|
| 490 | + $this->set('QST_max', $new_max); |
|
| 491 | + } |
|
| 492 | + |
|
| 493 | + |
|
| 494 | + /** |
|
| 495 | + * Creates a form input from this question which can be used in HTML forms |
|
| 496 | + * |
|
| 497 | + * @param EE_Registration $registration |
|
| 498 | + * @param EE_Answer $answer |
|
| 499 | + * @param array $input_constructor_args |
|
| 500 | + * @return EE_Form_Input_Base |
|
| 501 | + */ |
|
| 502 | + public function generate_form_input($registration = null, $answer = null, $input_constructor_args = array()) |
|
| 503 | + { |
|
| 504 | + $identifier = $this->is_system_question() ? $this->system_ID() : $this->ID(); |
|
| 505 | + |
|
| 506 | + $input_constructor_args = array_merge( |
|
| 507 | + array( |
|
| 508 | + 'required' => $this->required() ? true : false, |
|
| 509 | + 'html_label_text' => $this->display_text(), |
|
| 510 | + 'required_validation_error_message' => $this->required_text(), |
|
| 511 | + ), |
|
| 512 | + $input_constructor_args |
|
| 513 | + ); |
|
| 514 | + if (! $answer instanceof EE_Answer && $registration instanceof EE_Registration) { |
|
| 515 | + $answer = EEM_Answer::instance()->get_registration_question_answer_object($registration, $this->ID()); |
|
| 516 | + } |
|
| 517 | + // has this question been answered ? |
|
| 518 | + if ( |
|
| 519 | + $answer instanceof EE_Answer |
|
| 520 | + && $answer->value() !== '' |
|
| 521 | + ) { |
|
| 522 | + // answer gets htmlspecialchars called on it, undo that please |
|
| 523 | + // because the form input's display strategy may call esc_attr too |
|
| 524 | + // which also does html special characters |
|
| 525 | + $values_with_html_special_chars = $answer->value(); |
|
| 526 | + if (is_array($values_with_html_special_chars)) { |
|
| 527 | + $default_value = array_map('htmlspecialchars_decode', $values_with_html_special_chars); |
|
| 528 | + } else { |
|
| 529 | + $default_value = htmlspecialchars_decode($values_with_html_special_chars); |
|
| 530 | + } |
|
| 531 | + $input_constructor_args['default'] = $default_value; |
|
| 532 | + } |
|
| 533 | + $max_max_for_question = EEM_Question::instance()->absolute_max_for_system_question($this->system_ID()); |
|
| 534 | + if ( |
|
| 535 | + in_array( |
|
| 536 | + $this->type(), |
|
| 537 | + EEM_Question::instance()->questionTypesWithMaxLength(), |
|
| 538 | + true |
|
| 539 | + ) |
|
| 540 | + ) { |
|
| 541 | + $input_constructor_args['validation_strategies'][] = new EE_Max_Length_Validation_Strategy( |
|
| 542 | + null, |
|
| 543 | + min($max_max_for_question, $this->max()) |
|
| 544 | + ); |
|
| 545 | + } |
|
| 546 | + $input_constructor_args = apply_filters( |
|
| 547 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__input_constructor_args', |
|
| 548 | + $input_constructor_args, |
|
| 549 | + $registration, |
|
| 550 | + $this, |
|
| 551 | + $answer |
|
| 552 | + ); |
|
| 553 | + |
|
| 554 | + $result = null; |
|
| 555 | + switch ($this->type()) { |
|
| 556 | + // Text |
|
| 557 | + case EEM_Question::QST_type_text: |
|
| 558 | + $result = new EE_Text_Input($input_constructor_args); |
|
| 559 | + break; |
|
| 560 | + // Textarea |
|
| 561 | + case EEM_Question::QST_type_textarea: |
|
| 562 | + $result = new EE_Text_Area_Input($input_constructor_args); |
|
| 563 | + break; |
|
| 564 | + // Radio Buttons |
|
| 565 | + case EEM_Question::QST_type_radio: |
|
| 566 | + $result = new EE_Radio_Button_Input($this->options(), $input_constructor_args); |
|
| 567 | + break; |
|
| 568 | + // Dropdown |
|
| 569 | + case EEM_Question::QST_type_dropdown: |
|
| 570 | + $result = new EE_Select_Input($this->options(), $input_constructor_args); |
|
| 571 | + break; |
|
| 572 | + // State Dropdown |
|
| 573 | + case EEM_Question::QST_type_state: |
|
| 574 | + $state_options = apply_filters( |
|
| 575 | + 'FHEE__EE_Question__generate_form_input__state_options', |
|
| 576 | + null, |
|
| 577 | + $this, |
|
| 578 | + $registration, |
|
| 579 | + $answer |
|
| 580 | + ); |
|
| 581 | + $result = new EE_State_Select_Input($state_options, $input_constructor_args); |
|
| 582 | + break; |
|
| 583 | + // Country Dropdown |
|
| 584 | + case EEM_Question::QST_type_country: |
|
| 585 | + $country_options = apply_filters( |
|
| 586 | + 'FHEE__EE_Question__generate_form_input__country_options', |
|
| 587 | + null, |
|
| 588 | + $this, |
|
| 589 | + $registration, |
|
| 590 | + $answer |
|
| 591 | + ); |
|
| 592 | + $result = new EE_Country_Select_Input($country_options, $input_constructor_args); |
|
| 593 | + break; |
|
| 594 | + // Checkboxes |
|
| 595 | + case EEM_Question::QST_type_checkbox: |
|
| 596 | + $result = new EE_Checkbox_Multi_Input($this->options(), $input_constructor_args); |
|
| 597 | + break; |
|
| 598 | + // Date |
|
| 599 | + case EEM_Question::QST_type_date: |
|
| 600 | + $result = new EE_Datepicker_Input($input_constructor_args); |
|
| 601 | + break; |
|
| 602 | + case EEM_Question::QST_type_html_textarea: |
|
| 603 | + $input_constructor_args['validation_strategies'][] = new EE_Simple_HTML_Validation_Strategy(); |
|
| 604 | + $result = new EE_Text_Area_Input($input_constructor_args); |
|
| 605 | + $result->remove_validation_strategy('EE_Plaintext_Validation_Strategy'); |
|
| 606 | + break; |
|
| 607 | + case EEM_Question::QST_type_email: |
|
| 608 | + $result = new EE_Email_Input($input_constructor_args); |
|
| 609 | + break; |
|
| 610 | + // Email confirm |
|
| 611 | + case EEM_Question::QST_type_email_confirm: |
|
| 612 | + $result = new EE_Email_Confirm_Input($input_constructor_args); |
|
| 613 | + break; |
|
| 614 | + case EEM_Question::QST_type_us_phone: |
|
| 615 | + $result = new EE_Phone_Input($input_constructor_args); |
|
| 616 | + break; |
|
| 617 | + case EEM_Question::QST_type_int: |
|
| 618 | + $result = new EE_Integer_Input($input_constructor_args); |
|
| 619 | + break; |
|
| 620 | + case EEM_Question::QST_type_decimal: |
|
| 621 | + $result = new EE_Float_Input($input_constructor_args); |
|
| 622 | + break; |
|
| 623 | + case EEM_Question::QST_type_url: |
|
| 624 | + $input_constructor_args['validation_strategies'][] = LoaderFactory::getLoader()->getNew('EE_URL_Validation_Strategy'); |
|
| 625 | + $result = new EE_Text_Input($input_constructor_args); |
|
| 626 | + break; |
|
| 627 | + case EEM_Question::QST_type_year: |
|
| 628 | + $result = new EE_Year_Input( |
|
| 629 | + $input_constructor_args, |
|
| 630 | + apply_filters( |
|
| 631 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__four_digit', |
|
| 632 | + true, |
|
| 633 | + $this |
|
| 634 | + ), |
|
| 635 | + apply_filters( |
|
| 636 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__early_range', |
|
| 637 | + 100, |
|
| 638 | + $this |
|
| 639 | + ), |
|
| 640 | + apply_filters( |
|
| 641 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__year_question__end_range', |
|
| 642 | + 100, |
|
| 643 | + $this |
|
| 644 | + ) |
|
| 645 | + ); |
|
| 646 | + break; |
|
| 647 | + case EEM_Question::QST_type_multi_select: |
|
| 648 | + $result = new EE_Select_Multiple_Input($this->options(), $input_constructor_args); |
|
| 649 | + break; |
|
| 650 | + // fallback |
|
| 651 | + default: |
|
| 652 | + $default_input = apply_filters( |
|
| 653 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__default', |
|
| 654 | + null, |
|
| 655 | + $this->type(), |
|
| 656 | + $this, |
|
| 657 | + $input_constructor_args |
|
| 658 | + ); |
|
| 659 | + if (! $default_input) { |
|
| 660 | + $default_input = new EE_Text_Input($input_constructor_args); |
|
| 661 | + } |
|
| 662 | + $result = $default_input; |
|
| 663 | + } |
|
| 664 | + return apply_filters('FHEE__EE_Question__generate_form_input__return', $result, $registration, $this, $answer); |
|
| 665 | + } |
|
| 666 | + |
|
| 667 | + |
|
| 668 | + /** |
|
| 669 | + * Returns whether or not this question type should have question option entries |
|
| 670 | + * |
|
| 671 | + * @return bool |
|
| 672 | + */ |
|
| 673 | + public function should_have_question_options() |
|
| 674 | + { |
|
| 675 | + return in_array( |
|
| 676 | + $this->type(), |
|
| 677 | + $this->_model->question_types_with_options(), |
|
| 678 | + true |
|
| 679 | + ); |
|
| 680 | + } |
|
| 681 | 681 | } |
@@ -13,446 +13,446 @@ |
||
| 13 | 13 | class EE_Price extends EE_Soft_Delete_Base_Class |
| 14 | 14 | { |
| 15 | 15 | |
| 16 | - /** |
|
| 17 | - * @param array $props_n_values incoming values |
|
| 18 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 19 | - * used.) |
|
| 20 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 21 | - * date_format and the second value is the time format |
|
| 22 | - * @return EE_Price |
|
| 23 | - * @throws EE_Error |
|
| 24 | - * @throws InvalidArgumentException |
|
| 25 | - * @throws ReflectionException |
|
| 26 | - * @throws InvalidDataTypeException |
|
| 27 | - * @throws InvalidInterfaceException |
|
| 28 | - */ |
|
| 29 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 30 | - { |
|
| 31 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 32 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 33 | - } |
|
| 34 | - |
|
| 35 | - |
|
| 36 | - /** |
|
| 37 | - * @param array $props_n_values incoming values from the database |
|
| 38 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 39 | - * the website will be used. |
|
| 40 | - * @return EE_Price |
|
| 41 | - * @throws EE_Error |
|
| 42 | - * @throws InvalidArgumentException |
|
| 43 | - * @throws ReflectionException |
|
| 44 | - * @throws InvalidDataTypeException |
|
| 45 | - * @throws InvalidInterfaceException |
|
| 46 | - */ |
|
| 47 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 48 | - { |
|
| 49 | - return new self($props_n_values, true, $timezone); |
|
| 50 | - } |
|
| 51 | - |
|
| 52 | - |
|
| 53 | - /** |
|
| 54 | - * Set Price type ID |
|
| 55 | - * |
|
| 56 | - * @param int $PRT_ID |
|
| 57 | - * @throws EE_Error |
|
| 58 | - * @throws InvalidArgumentException |
|
| 59 | - * @throws ReflectionException |
|
| 60 | - * @throws InvalidDataTypeException |
|
| 61 | - * @throws InvalidInterfaceException |
|
| 62 | - */ |
|
| 63 | - public function set_type($PRT_ID = 0) |
|
| 64 | - { |
|
| 65 | - $this->set('PRT_ID', $PRT_ID); |
|
| 66 | - } |
|
| 67 | - |
|
| 68 | - |
|
| 69 | - /** |
|
| 70 | - * Set Price Amount |
|
| 71 | - * |
|
| 72 | - * @param float $PRC_amount |
|
| 73 | - * @throws EE_Error |
|
| 74 | - * @throws InvalidArgumentException |
|
| 75 | - * @throws ReflectionException |
|
| 76 | - * @throws InvalidDataTypeException |
|
| 77 | - * @throws InvalidInterfaceException |
|
| 78 | - */ |
|
| 79 | - public function set_amount($PRC_amount = 0.00) |
|
| 80 | - { |
|
| 81 | - $this->set('PRC_amount', $PRC_amount); |
|
| 82 | - } |
|
| 83 | - |
|
| 84 | - |
|
| 85 | - /** |
|
| 86 | - * Set Price Name |
|
| 87 | - * |
|
| 88 | - * @param string $PRC_name |
|
| 89 | - * @throws EE_Error |
|
| 90 | - * @throws InvalidArgumentException |
|
| 91 | - * @throws ReflectionException |
|
| 92 | - * @throws InvalidDataTypeException |
|
| 93 | - * @throws InvalidInterfaceException |
|
| 94 | - */ |
|
| 95 | - public function set_name($PRC_name = '') |
|
| 96 | - { |
|
| 97 | - $this->set('PRC_name', $PRC_name); |
|
| 98 | - } |
|
| 99 | - |
|
| 100 | - |
|
| 101 | - /** |
|
| 102 | - * Set Price Description |
|
| 103 | - * |
|
| 104 | - * @param string $PRC_desc |
|
| 105 | - * @throws EE_Error |
|
| 106 | - * @throws InvalidArgumentException |
|
| 107 | - * @throws ReflectionException |
|
| 108 | - * @throws InvalidDataTypeException |
|
| 109 | - * @throws InvalidInterfaceException |
|
| 110 | - */ |
|
| 111 | - public function set_description($PRC_desc = '') |
|
| 112 | - { |
|
| 113 | - $this->Set('PRC_desc', $PRC_desc); |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - |
|
| 117 | - /** |
|
| 118 | - * set is_default |
|
| 119 | - * |
|
| 120 | - * @param bool $PRC_is_default |
|
| 121 | - * @throws EE_Error |
|
| 122 | - * @throws InvalidArgumentException |
|
| 123 | - * @throws ReflectionException |
|
| 124 | - * @throws InvalidDataTypeException |
|
| 125 | - * @throws InvalidInterfaceException |
|
| 126 | - */ |
|
| 127 | - public function set_is_default($PRC_is_default = false) |
|
| 128 | - { |
|
| 129 | - $this->set('PRC_is_default', $PRC_is_default); |
|
| 130 | - } |
|
| 131 | - |
|
| 132 | - |
|
| 133 | - /** |
|
| 134 | - * set deleted |
|
| 135 | - * |
|
| 136 | - * @param bool $PRC_deleted |
|
| 137 | - * @throws EE_Error |
|
| 138 | - * @throws InvalidArgumentException |
|
| 139 | - * @throws ReflectionException |
|
| 140 | - * @throws InvalidDataTypeException |
|
| 141 | - * @throws InvalidInterfaceException |
|
| 142 | - */ |
|
| 143 | - public function set_deleted($PRC_deleted = null) |
|
| 144 | - { |
|
| 145 | - $this->set('PRC_deleted', $PRC_deleted); |
|
| 146 | - } |
|
| 147 | - |
|
| 148 | - |
|
| 149 | - /** |
|
| 150 | - * get Price type |
|
| 151 | - * |
|
| 152 | - * @return int |
|
| 153 | - * @throws EE_Error |
|
| 154 | - * @throws InvalidArgumentException |
|
| 155 | - * @throws ReflectionException |
|
| 156 | - * @throws InvalidDataTypeException |
|
| 157 | - * @throws InvalidInterfaceException |
|
| 158 | - */ |
|
| 159 | - public function type() |
|
| 160 | - { |
|
| 161 | - return $this->get('PRT_ID'); |
|
| 162 | - } |
|
| 163 | - |
|
| 164 | - |
|
| 165 | - /** |
|
| 166 | - * get Price Amount |
|
| 167 | - * |
|
| 168 | - * @return float |
|
| 169 | - * @throws EE_Error |
|
| 170 | - * @throws InvalidArgumentException |
|
| 171 | - * @throws ReflectionException |
|
| 172 | - * @throws InvalidDataTypeException |
|
| 173 | - * @throws InvalidInterfaceException |
|
| 174 | - */ |
|
| 175 | - public function amount() |
|
| 176 | - { |
|
| 177 | - return $this->get('PRC_amount'); |
|
| 178 | - } |
|
| 179 | - |
|
| 180 | - |
|
| 181 | - /** |
|
| 182 | - * get Price Name |
|
| 183 | - * |
|
| 184 | - * @return string |
|
| 185 | - * @throws EE_Error |
|
| 186 | - * @throws InvalidArgumentException |
|
| 187 | - * @throws ReflectionException |
|
| 188 | - * @throws InvalidDataTypeException |
|
| 189 | - * @throws InvalidInterfaceException |
|
| 190 | - */ |
|
| 191 | - public function name() |
|
| 192 | - { |
|
| 193 | - return $this->get('PRC_name'); |
|
| 194 | - } |
|
| 195 | - |
|
| 196 | - |
|
| 197 | - /** |
|
| 198 | - * get Price description |
|
| 199 | - * |
|
| 200 | - * @return string |
|
| 201 | - * @throws EE_Error |
|
| 202 | - * @throws InvalidArgumentException |
|
| 203 | - * @throws ReflectionException |
|
| 204 | - * @throws InvalidDataTypeException |
|
| 205 | - * @throws InvalidInterfaceException |
|
| 206 | - */ |
|
| 207 | - public function desc() |
|
| 208 | - { |
|
| 209 | - return $this->get('PRC_desc'); |
|
| 210 | - } |
|
| 211 | - |
|
| 212 | - |
|
| 213 | - /** |
|
| 214 | - * get overrides |
|
| 215 | - * |
|
| 216 | - * @return int |
|
| 217 | - * @throws EE_Error |
|
| 218 | - * @throws InvalidArgumentException |
|
| 219 | - * @throws ReflectionException |
|
| 220 | - * @throws InvalidDataTypeException |
|
| 221 | - * @throws InvalidInterfaceException |
|
| 222 | - */ |
|
| 223 | - public function overrides() |
|
| 224 | - { |
|
| 225 | - return $this->get('PRC_overrides'); |
|
| 226 | - } |
|
| 227 | - |
|
| 228 | - |
|
| 229 | - /** |
|
| 230 | - * get order |
|
| 231 | - * |
|
| 232 | - * @return int |
|
| 233 | - * @throws EE_Error |
|
| 234 | - * @throws InvalidArgumentException |
|
| 235 | - * @throws ReflectionException |
|
| 236 | - * @throws InvalidDataTypeException |
|
| 237 | - * @throws InvalidInterfaceException |
|
| 238 | - */ |
|
| 239 | - public function order() |
|
| 240 | - { |
|
| 241 | - return $this->get('PRC_order'); |
|
| 242 | - } |
|
| 243 | - |
|
| 244 | - |
|
| 245 | - /** |
|
| 246 | - * get the author of the price |
|
| 247 | - * |
|
| 248 | - * @return int |
|
| 249 | - * @throws EE_Error |
|
| 250 | - * @throws InvalidArgumentException |
|
| 251 | - * @throws ReflectionException |
|
| 252 | - * @throws InvalidDataTypeException |
|
| 253 | - * @throws InvalidInterfaceException |
|
| 254 | - * @since 4.5.0 |
|
| 255 | - */ |
|
| 256 | - public function wp_user() |
|
| 257 | - { |
|
| 258 | - return $this->get('PRC_wp_user'); |
|
| 259 | - } |
|
| 260 | - |
|
| 261 | - |
|
| 262 | - /** |
|
| 263 | - * get is_default |
|
| 264 | - * |
|
| 265 | - * @return bool |
|
| 266 | - * @throws EE_Error |
|
| 267 | - * @throws InvalidArgumentException |
|
| 268 | - * @throws ReflectionException |
|
| 269 | - * @throws InvalidDataTypeException |
|
| 270 | - * @throws InvalidInterfaceException |
|
| 271 | - */ |
|
| 272 | - public function is_default() |
|
| 273 | - { |
|
| 274 | - return $this->get('PRC_is_default'); |
|
| 275 | - } |
|
| 276 | - |
|
| 277 | - |
|
| 278 | - /** |
|
| 279 | - * get deleted |
|
| 280 | - * |
|
| 281 | - * @return bool |
|
| 282 | - * @throws EE_Error |
|
| 283 | - * @throws InvalidArgumentException |
|
| 284 | - * @throws ReflectionException |
|
| 285 | - * @throws InvalidDataTypeException |
|
| 286 | - * @throws InvalidInterfaceException |
|
| 287 | - */ |
|
| 288 | - public function deleted() |
|
| 289 | - { |
|
| 290 | - return $this->get('PRC_deleted'); |
|
| 291 | - } |
|
| 292 | - |
|
| 293 | - |
|
| 294 | - /** |
|
| 295 | - * @return bool |
|
| 296 | - * @throws EE_Error |
|
| 297 | - * @throws InvalidArgumentException |
|
| 298 | - * @throws ReflectionException |
|
| 299 | - * @throws InvalidDataTypeException |
|
| 300 | - * @throws InvalidInterfaceException |
|
| 301 | - */ |
|
| 302 | - public function parent() |
|
| 303 | - { |
|
| 304 | - return $this->get('PRC_parent'); |
|
| 305 | - } |
|
| 306 | - |
|
| 307 | - |
|
| 308 | - // some helper methods for getting info on the price_type for this price |
|
| 309 | - |
|
| 310 | - |
|
| 311 | - /** |
|
| 312 | - * return whether the price is a base price or not |
|
| 313 | - * |
|
| 314 | - * @return boolean |
|
| 315 | - * @throws EE_Error |
|
| 316 | - * @throws InvalidArgumentException |
|
| 317 | - * @throws InvalidDataTypeException |
|
| 318 | - * @throws InvalidInterfaceException |
|
| 319 | - * @throws ReflectionException |
|
| 320 | - */ |
|
| 321 | - public function is_base_price() |
|
| 322 | - { |
|
| 323 | - $price_type = $this->type_obj(); |
|
| 324 | - return $price_type->is_base_price(); |
|
| 325 | - } |
|
| 326 | - |
|
| 327 | - |
|
| 328 | - /** |
|
| 329 | - * @return EE_Base_Class|EE_Price_Type |
|
| 330 | - * @throws EE_Error |
|
| 331 | - * @throws InvalidArgumentException |
|
| 332 | - * @throws ReflectionException |
|
| 333 | - * @throws InvalidDataTypeException |
|
| 334 | - * @throws InvalidInterfaceException |
|
| 335 | - */ |
|
| 336 | - public function type_obj() |
|
| 337 | - { |
|
| 338 | - return $this->get_first_related('Price_Type'); |
|
| 339 | - } |
|
| 340 | - |
|
| 341 | - |
|
| 342 | - /** |
|
| 343 | - * @return int |
|
| 344 | - * @throws EE_Error |
|
| 345 | - * @throws InvalidArgumentException |
|
| 346 | - * @throws ReflectionException |
|
| 347 | - * @throws InvalidDataTypeException |
|
| 348 | - * @throws InvalidInterfaceException |
|
| 349 | - */ |
|
| 350 | - public function type_order() |
|
| 351 | - { |
|
| 352 | - return $this->get_first_related('Price_Type')->order(); |
|
| 353 | - } |
|
| 354 | - |
|
| 355 | - |
|
| 356 | - /** |
|
| 357 | - * Simply indicates whether this price increases or decreases the total |
|
| 358 | - * |
|
| 359 | - * @return boolean true = discount, otherwise adds to the total |
|
| 360 | - * @throws EE_Error |
|
| 361 | - * @throws InvalidArgumentException |
|
| 362 | - * @throws ReflectionException |
|
| 363 | - * @throws InvalidDataTypeException |
|
| 364 | - * @throws InvalidInterfaceException |
|
| 365 | - */ |
|
| 366 | - public function is_discount() |
|
| 367 | - { |
|
| 368 | - $price_type = $this->type_obj(); |
|
| 369 | - return $price_type->is_discount(); |
|
| 370 | - } |
|
| 371 | - |
|
| 372 | - |
|
| 373 | - /** |
|
| 374 | - * whether the price is a percentage or not |
|
| 375 | - * |
|
| 376 | - * @return boolean |
|
| 377 | - * @throws EE_Error |
|
| 378 | - * @throws InvalidArgumentException |
|
| 379 | - * @throws InvalidDataTypeException |
|
| 380 | - * @throws InvalidInterfaceException |
|
| 381 | - * @throws ReflectionException |
|
| 382 | - */ |
|
| 383 | - public function is_percent() |
|
| 384 | - { |
|
| 385 | - $price_type = $this->type_obj(); |
|
| 386 | - return $price_type->is_percent(); |
|
| 387 | - } |
|
| 388 | - |
|
| 389 | - |
|
| 390 | - /** |
|
| 391 | - * whether the price is a percentage or not |
|
| 392 | - * |
|
| 393 | - * @return boolean |
|
| 394 | - * @throws EE_Error |
|
| 395 | - * @throws InvalidArgumentException |
|
| 396 | - * @throws ReflectionException |
|
| 397 | - * @throws InvalidDataTypeException |
|
| 398 | - * @throws InvalidInterfaceException |
|
| 399 | - */ |
|
| 400 | - public function is_surcharge() |
|
| 401 | - { |
|
| 402 | - $price_type = $this->type_obj(); |
|
| 403 | - return $price_type->is_surcharge(); |
|
| 404 | - } |
|
| 405 | - |
|
| 406 | - /** |
|
| 407 | - * whether the price is a percentage or not |
|
| 408 | - * |
|
| 409 | - * @return boolean |
|
| 410 | - * @throws EE_Error |
|
| 411 | - * @throws InvalidArgumentException |
|
| 412 | - * @throws ReflectionException |
|
| 413 | - * @throws InvalidDataTypeException |
|
| 414 | - * @throws InvalidInterfaceException |
|
| 415 | - */ |
|
| 416 | - public function is_tax() |
|
| 417 | - { |
|
| 418 | - $price_type = $this->type_obj(); |
|
| 419 | - return $price_type->is_tax(); |
|
| 420 | - } |
|
| 421 | - |
|
| 422 | - |
|
| 423 | - /** |
|
| 424 | - * return pretty price dependant on whether its a dollar or percent. |
|
| 425 | - * |
|
| 426 | - * @return string |
|
| 427 | - * @throws EE_Error |
|
| 428 | - * @throws InvalidArgumentException |
|
| 429 | - * @throws ReflectionException |
|
| 430 | - * @throws InvalidDataTypeException |
|
| 431 | - * @throws InvalidInterfaceException |
|
| 432 | - * @since 4.4.0 |
|
| 433 | - */ |
|
| 434 | - public function pretty_price() |
|
| 435 | - { |
|
| 436 | - return ! $this->is_percent() |
|
| 437 | - ? $this->get_pretty('PRC_amount') |
|
| 438 | - : $this->get('PRC_amount') . '%'; |
|
| 439 | - } |
|
| 440 | - |
|
| 441 | - |
|
| 442 | - /** |
|
| 443 | - * @return mixed |
|
| 444 | - * @throws EE_Error |
|
| 445 | - * @throws InvalidArgumentException |
|
| 446 | - * @throws ReflectionException |
|
| 447 | - * @throws InvalidDataTypeException |
|
| 448 | - * @throws InvalidInterfaceException |
|
| 449 | - */ |
|
| 450 | - public function get_price_without_currency_symbol() |
|
| 451 | - { |
|
| 452 | - return str_replace( |
|
| 453 | - EE_Registry::instance()->CFG->currency->sign, |
|
| 454 | - '', |
|
| 455 | - $this->get_pretty('PRC_amount') |
|
| 456 | - ); |
|
| 457 | - } |
|
| 16 | + /** |
|
| 17 | + * @param array $props_n_values incoming values |
|
| 18 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
| 19 | + * used.) |
|
| 20 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
| 21 | + * date_format and the second value is the time format |
|
| 22 | + * @return EE_Price |
|
| 23 | + * @throws EE_Error |
|
| 24 | + * @throws InvalidArgumentException |
|
| 25 | + * @throws ReflectionException |
|
| 26 | + * @throws InvalidDataTypeException |
|
| 27 | + * @throws InvalidInterfaceException |
|
| 28 | + */ |
|
| 29 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 30 | + { |
|
| 31 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
| 32 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
| 33 | + } |
|
| 34 | + |
|
| 35 | + |
|
| 36 | + /** |
|
| 37 | + * @param array $props_n_values incoming values from the database |
|
| 38 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 39 | + * the website will be used. |
|
| 40 | + * @return EE_Price |
|
| 41 | + * @throws EE_Error |
|
| 42 | + * @throws InvalidArgumentException |
|
| 43 | + * @throws ReflectionException |
|
| 44 | + * @throws InvalidDataTypeException |
|
| 45 | + * @throws InvalidInterfaceException |
|
| 46 | + */ |
|
| 47 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 48 | + { |
|
| 49 | + return new self($props_n_values, true, $timezone); |
|
| 50 | + } |
|
| 51 | + |
|
| 52 | + |
|
| 53 | + /** |
|
| 54 | + * Set Price type ID |
|
| 55 | + * |
|
| 56 | + * @param int $PRT_ID |
|
| 57 | + * @throws EE_Error |
|
| 58 | + * @throws InvalidArgumentException |
|
| 59 | + * @throws ReflectionException |
|
| 60 | + * @throws InvalidDataTypeException |
|
| 61 | + * @throws InvalidInterfaceException |
|
| 62 | + */ |
|
| 63 | + public function set_type($PRT_ID = 0) |
|
| 64 | + { |
|
| 65 | + $this->set('PRT_ID', $PRT_ID); |
|
| 66 | + } |
|
| 67 | + |
|
| 68 | + |
|
| 69 | + /** |
|
| 70 | + * Set Price Amount |
|
| 71 | + * |
|
| 72 | + * @param float $PRC_amount |
|
| 73 | + * @throws EE_Error |
|
| 74 | + * @throws InvalidArgumentException |
|
| 75 | + * @throws ReflectionException |
|
| 76 | + * @throws InvalidDataTypeException |
|
| 77 | + * @throws InvalidInterfaceException |
|
| 78 | + */ |
|
| 79 | + public function set_amount($PRC_amount = 0.00) |
|
| 80 | + { |
|
| 81 | + $this->set('PRC_amount', $PRC_amount); |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + |
|
| 85 | + /** |
|
| 86 | + * Set Price Name |
|
| 87 | + * |
|
| 88 | + * @param string $PRC_name |
|
| 89 | + * @throws EE_Error |
|
| 90 | + * @throws InvalidArgumentException |
|
| 91 | + * @throws ReflectionException |
|
| 92 | + * @throws InvalidDataTypeException |
|
| 93 | + * @throws InvalidInterfaceException |
|
| 94 | + */ |
|
| 95 | + public function set_name($PRC_name = '') |
|
| 96 | + { |
|
| 97 | + $this->set('PRC_name', $PRC_name); |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + |
|
| 101 | + /** |
|
| 102 | + * Set Price Description |
|
| 103 | + * |
|
| 104 | + * @param string $PRC_desc |
|
| 105 | + * @throws EE_Error |
|
| 106 | + * @throws InvalidArgumentException |
|
| 107 | + * @throws ReflectionException |
|
| 108 | + * @throws InvalidDataTypeException |
|
| 109 | + * @throws InvalidInterfaceException |
|
| 110 | + */ |
|
| 111 | + public function set_description($PRC_desc = '') |
|
| 112 | + { |
|
| 113 | + $this->Set('PRC_desc', $PRC_desc); |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + |
|
| 117 | + /** |
|
| 118 | + * set is_default |
|
| 119 | + * |
|
| 120 | + * @param bool $PRC_is_default |
|
| 121 | + * @throws EE_Error |
|
| 122 | + * @throws InvalidArgumentException |
|
| 123 | + * @throws ReflectionException |
|
| 124 | + * @throws InvalidDataTypeException |
|
| 125 | + * @throws InvalidInterfaceException |
|
| 126 | + */ |
|
| 127 | + public function set_is_default($PRC_is_default = false) |
|
| 128 | + { |
|
| 129 | + $this->set('PRC_is_default', $PRC_is_default); |
|
| 130 | + } |
|
| 131 | + |
|
| 132 | + |
|
| 133 | + /** |
|
| 134 | + * set deleted |
|
| 135 | + * |
|
| 136 | + * @param bool $PRC_deleted |
|
| 137 | + * @throws EE_Error |
|
| 138 | + * @throws InvalidArgumentException |
|
| 139 | + * @throws ReflectionException |
|
| 140 | + * @throws InvalidDataTypeException |
|
| 141 | + * @throws InvalidInterfaceException |
|
| 142 | + */ |
|
| 143 | + public function set_deleted($PRC_deleted = null) |
|
| 144 | + { |
|
| 145 | + $this->set('PRC_deleted', $PRC_deleted); |
|
| 146 | + } |
|
| 147 | + |
|
| 148 | + |
|
| 149 | + /** |
|
| 150 | + * get Price type |
|
| 151 | + * |
|
| 152 | + * @return int |
|
| 153 | + * @throws EE_Error |
|
| 154 | + * @throws InvalidArgumentException |
|
| 155 | + * @throws ReflectionException |
|
| 156 | + * @throws InvalidDataTypeException |
|
| 157 | + * @throws InvalidInterfaceException |
|
| 158 | + */ |
|
| 159 | + public function type() |
|
| 160 | + { |
|
| 161 | + return $this->get('PRT_ID'); |
|
| 162 | + } |
|
| 163 | + |
|
| 164 | + |
|
| 165 | + /** |
|
| 166 | + * get Price Amount |
|
| 167 | + * |
|
| 168 | + * @return float |
|
| 169 | + * @throws EE_Error |
|
| 170 | + * @throws InvalidArgumentException |
|
| 171 | + * @throws ReflectionException |
|
| 172 | + * @throws InvalidDataTypeException |
|
| 173 | + * @throws InvalidInterfaceException |
|
| 174 | + */ |
|
| 175 | + public function amount() |
|
| 176 | + { |
|
| 177 | + return $this->get('PRC_amount'); |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + |
|
| 181 | + /** |
|
| 182 | + * get Price Name |
|
| 183 | + * |
|
| 184 | + * @return string |
|
| 185 | + * @throws EE_Error |
|
| 186 | + * @throws InvalidArgumentException |
|
| 187 | + * @throws ReflectionException |
|
| 188 | + * @throws InvalidDataTypeException |
|
| 189 | + * @throws InvalidInterfaceException |
|
| 190 | + */ |
|
| 191 | + public function name() |
|
| 192 | + { |
|
| 193 | + return $this->get('PRC_name'); |
|
| 194 | + } |
|
| 195 | + |
|
| 196 | + |
|
| 197 | + /** |
|
| 198 | + * get Price description |
|
| 199 | + * |
|
| 200 | + * @return string |
|
| 201 | + * @throws EE_Error |
|
| 202 | + * @throws InvalidArgumentException |
|
| 203 | + * @throws ReflectionException |
|
| 204 | + * @throws InvalidDataTypeException |
|
| 205 | + * @throws InvalidInterfaceException |
|
| 206 | + */ |
|
| 207 | + public function desc() |
|
| 208 | + { |
|
| 209 | + return $this->get('PRC_desc'); |
|
| 210 | + } |
|
| 211 | + |
|
| 212 | + |
|
| 213 | + /** |
|
| 214 | + * get overrides |
|
| 215 | + * |
|
| 216 | + * @return int |
|
| 217 | + * @throws EE_Error |
|
| 218 | + * @throws InvalidArgumentException |
|
| 219 | + * @throws ReflectionException |
|
| 220 | + * @throws InvalidDataTypeException |
|
| 221 | + * @throws InvalidInterfaceException |
|
| 222 | + */ |
|
| 223 | + public function overrides() |
|
| 224 | + { |
|
| 225 | + return $this->get('PRC_overrides'); |
|
| 226 | + } |
|
| 227 | + |
|
| 228 | + |
|
| 229 | + /** |
|
| 230 | + * get order |
|
| 231 | + * |
|
| 232 | + * @return int |
|
| 233 | + * @throws EE_Error |
|
| 234 | + * @throws InvalidArgumentException |
|
| 235 | + * @throws ReflectionException |
|
| 236 | + * @throws InvalidDataTypeException |
|
| 237 | + * @throws InvalidInterfaceException |
|
| 238 | + */ |
|
| 239 | + public function order() |
|
| 240 | + { |
|
| 241 | + return $this->get('PRC_order'); |
|
| 242 | + } |
|
| 243 | + |
|
| 244 | + |
|
| 245 | + /** |
|
| 246 | + * get the author of the price |
|
| 247 | + * |
|
| 248 | + * @return int |
|
| 249 | + * @throws EE_Error |
|
| 250 | + * @throws InvalidArgumentException |
|
| 251 | + * @throws ReflectionException |
|
| 252 | + * @throws InvalidDataTypeException |
|
| 253 | + * @throws InvalidInterfaceException |
|
| 254 | + * @since 4.5.0 |
|
| 255 | + */ |
|
| 256 | + public function wp_user() |
|
| 257 | + { |
|
| 258 | + return $this->get('PRC_wp_user'); |
|
| 259 | + } |
|
| 260 | + |
|
| 261 | + |
|
| 262 | + /** |
|
| 263 | + * get is_default |
|
| 264 | + * |
|
| 265 | + * @return bool |
|
| 266 | + * @throws EE_Error |
|
| 267 | + * @throws InvalidArgumentException |
|
| 268 | + * @throws ReflectionException |
|
| 269 | + * @throws InvalidDataTypeException |
|
| 270 | + * @throws InvalidInterfaceException |
|
| 271 | + */ |
|
| 272 | + public function is_default() |
|
| 273 | + { |
|
| 274 | + return $this->get('PRC_is_default'); |
|
| 275 | + } |
|
| 276 | + |
|
| 277 | + |
|
| 278 | + /** |
|
| 279 | + * get deleted |
|
| 280 | + * |
|
| 281 | + * @return bool |
|
| 282 | + * @throws EE_Error |
|
| 283 | + * @throws InvalidArgumentException |
|
| 284 | + * @throws ReflectionException |
|
| 285 | + * @throws InvalidDataTypeException |
|
| 286 | + * @throws InvalidInterfaceException |
|
| 287 | + */ |
|
| 288 | + public function deleted() |
|
| 289 | + { |
|
| 290 | + return $this->get('PRC_deleted'); |
|
| 291 | + } |
|
| 292 | + |
|
| 293 | + |
|
| 294 | + /** |
|
| 295 | + * @return bool |
|
| 296 | + * @throws EE_Error |
|
| 297 | + * @throws InvalidArgumentException |
|
| 298 | + * @throws ReflectionException |
|
| 299 | + * @throws InvalidDataTypeException |
|
| 300 | + * @throws InvalidInterfaceException |
|
| 301 | + */ |
|
| 302 | + public function parent() |
|
| 303 | + { |
|
| 304 | + return $this->get('PRC_parent'); |
|
| 305 | + } |
|
| 306 | + |
|
| 307 | + |
|
| 308 | + // some helper methods for getting info on the price_type for this price |
|
| 309 | + |
|
| 310 | + |
|
| 311 | + /** |
|
| 312 | + * return whether the price is a base price or not |
|
| 313 | + * |
|
| 314 | + * @return boolean |
|
| 315 | + * @throws EE_Error |
|
| 316 | + * @throws InvalidArgumentException |
|
| 317 | + * @throws InvalidDataTypeException |
|
| 318 | + * @throws InvalidInterfaceException |
|
| 319 | + * @throws ReflectionException |
|
| 320 | + */ |
|
| 321 | + public function is_base_price() |
|
| 322 | + { |
|
| 323 | + $price_type = $this->type_obj(); |
|
| 324 | + return $price_type->is_base_price(); |
|
| 325 | + } |
|
| 326 | + |
|
| 327 | + |
|
| 328 | + /** |
|
| 329 | + * @return EE_Base_Class|EE_Price_Type |
|
| 330 | + * @throws EE_Error |
|
| 331 | + * @throws InvalidArgumentException |
|
| 332 | + * @throws ReflectionException |
|
| 333 | + * @throws InvalidDataTypeException |
|
| 334 | + * @throws InvalidInterfaceException |
|
| 335 | + */ |
|
| 336 | + public function type_obj() |
|
| 337 | + { |
|
| 338 | + return $this->get_first_related('Price_Type'); |
|
| 339 | + } |
|
| 340 | + |
|
| 341 | + |
|
| 342 | + /** |
|
| 343 | + * @return int |
|
| 344 | + * @throws EE_Error |
|
| 345 | + * @throws InvalidArgumentException |
|
| 346 | + * @throws ReflectionException |
|
| 347 | + * @throws InvalidDataTypeException |
|
| 348 | + * @throws InvalidInterfaceException |
|
| 349 | + */ |
|
| 350 | + public function type_order() |
|
| 351 | + { |
|
| 352 | + return $this->get_first_related('Price_Type')->order(); |
|
| 353 | + } |
|
| 354 | + |
|
| 355 | + |
|
| 356 | + /** |
|
| 357 | + * Simply indicates whether this price increases or decreases the total |
|
| 358 | + * |
|
| 359 | + * @return boolean true = discount, otherwise adds to the total |
|
| 360 | + * @throws EE_Error |
|
| 361 | + * @throws InvalidArgumentException |
|
| 362 | + * @throws ReflectionException |
|
| 363 | + * @throws InvalidDataTypeException |
|
| 364 | + * @throws InvalidInterfaceException |
|
| 365 | + */ |
|
| 366 | + public function is_discount() |
|
| 367 | + { |
|
| 368 | + $price_type = $this->type_obj(); |
|
| 369 | + return $price_type->is_discount(); |
|
| 370 | + } |
|
| 371 | + |
|
| 372 | + |
|
| 373 | + /** |
|
| 374 | + * whether the price is a percentage or not |
|
| 375 | + * |
|
| 376 | + * @return boolean |
|
| 377 | + * @throws EE_Error |
|
| 378 | + * @throws InvalidArgumentException |
|
| 379 | + * @throws InvalidDataTypeException |
|
| 380 | + * @throws InvalidInterfaceException |
|
| 381 | + * @throws ReflectionException |
|
| 382 | + */ |
|
| 383 | + public function is_percent() |
|
| 384 | + { |
|
| 385 | + $price_type = $this->type_obj(); |
|
| 386 | + return $price_type->is_percent(); |
|
| 387 | + } |
|
| 388 | + |
|
| 389 | + |
|
| 390 | + /** |
|
| 391 | + * whether the price is a percentage or not |
|
| 392 | + * |
|
| 393 | + * @return boolean |
|
| 394 | + * @throws EE_Error |
|
| 395 | + * @throws InvalidArgumentException |
|
| 396 | + * @throws ReflectionException |
|
| 397 | + * @throws InvalidDataTypeException |
|
| 398 | + * @throws InvalidInterfaceException |
|
| 399 | + */ |
|
| 400 | + public function is_surcharge() |
|
| 401 | + { |
|
| 402 | + $price_type = $this->type_obj(); |
|
| 403 | + return $price_type->is_surcharge(); |
|
| 404 | + } |
|
| 405 | + |
|
| 406 | + /** |
|
| 407 | + * whether the price is a percentage or not |
|
| 408 | + * |
|
| 409 | + * @return boolean |
|
| 410 | + * @throws EE_Error |
|
| 411 | + * @throws InvalidArgumentException |
|
| 412 | + * @throws ReflectionException |
|
| 413 | + * @throws InvalidDataTypeException |
|
| 414 | + * @throws InvalidInterfaceException |
|
| 415 | + */ |
|
| 416 | + public function is_tax() |
|
| 417 | + { |
|
| 418 | + $price_type = $this->type_obj(); |
|
| 419 | + return $price_type->is_tax(); |
|
| 420 | + } |
|
| 421 | + |
|
| 422 | + |
|
| 423 | + /** |
|
| 424 | + * return pretty price dependant on whether its a dollar or percent. |
|
| 425 | + * |
|
| 426 | + * @return string |
|
| 427 | + * @throws EE_Error |
|
| 428 | + * @throws InvalidArgumentException |
|
| 429 | + * @throws ReflectionException |
|
| 430 | + * @throws InvalidDataTypeException |
|
| 431 | + * @throws InvalidInterfaceException |
|
| 432 | + * @since 4.4.0 |
|
| 433 | + */ |
|
| 434 | + public function pretty_price() |
|
| 435 | + { |
|
| 436 | + return ! $this->is_percent() |
|
| 437 | + ? $this->get_pretty('PRC_amount') |
|
| 438 | + : $this->get('PRC_amount') . '%'; |
|
| 439 | + } |
|
| 440 | + |
|
| 441 | + |
|
| 442 | + /** |
|
| 443 | + * @return mixed |
|
| 444 | + * @throws EE_Error |
|
| 445 | + * @throws InvalidArgumentException |
|
| 446 | + * @throws ReflectionException |
|
| 447 | + * @throws InvalidDataTypeException |
|
| 448 | + * @throws InvalidInterfaceException |
|
| 449 | + */ |
|
| 450 | + public function get_price_without_currency_symbol() |
|
| 451 | + { |
|
| 452 | + return str_replace( |
|
| 453 | + EE_Registry::instance()->CFG->currency->sign, |
|
| 454 | + '', |
|
| 455 | + $this->get_pretty('PRC_amount') |
|
| 456 | + ); |
|
| 457 | + } |
|
| 458 | 458 | } |
@@ -13,1412 +13,1412 @@ |
||
| 13 | 13 | class EE_Datetime extends EE_Soft_Delete_Base_Class |
| 14 | 14 | { |
| 15 | 15 | |
| 16 | - /** |
|
| 17 | - * constant used by get_active_status, indicates datetime has no more available spaces |
|
| 18 | - */ |
|
| 19 | - const sold_out = 'DTS'; |
|
| 20 | - |
|
| 21 | - /** |
|
| 22 | - * constant used by get_active_status, indicating datetime is still active (even is not over, can be registered-for) |
|
| 23 | - */ |
|
| 24 | - const active = 'DTA'; |
|
| 25 | - |
|
| 26 | - /** |
|
| 27 | - * constant used by get_active_status, indicating the datetime cannot be used for registrations yet, but has not |
|
| 28 | - * expired |
|
| 29 | - */ |
|
| 30 | - const upcoming = 'DTU'; |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * Datetime is postponed |
|
| 34 | - */ |
|
| 35 | - const postponed = 'DTP'; |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * Datetime is cancelled |
|
| 39 | - */ |
|
| 40 | - const cancelled = 'DTC'; |
|
| 41 | - |
|
| 42 | - /** |
|
| 43 | - * constant used by get_active_status, indicates datetime has expired (event is over) |
|
| 44 | - */ |
|
| 45 | - const expired = 'DTE'; |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * constant used in various places indicating that an event is INACTIVE (not yet ready to be published) |
|
| 49 | - */ |
|
| 50 | - const inactive = 'DTI'; |
|
| 51 | - |
|
| 52 | - |
|
| 53 | - /** |
|
| 54 | - * @param array $props_n_values incoming values |
|
| 55 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be used.) |
|
| 56 | - * @param array $date_formats incoming date_formats in an array where the first value is the date_format |
|
| 57 | - * and the second value is the time format |
|
| 58 | - * @return EE_Datetime |
|
| 59 | - * @throws ReflectionException |
|
| 60 | - * @throws InvalidArgumentException |
|
| 61 | - * @throws InvalidInterfaceException |
|
| 62 | - * @throws InvalidDataTypeException |
|
| 63 | - * @throws EE_Error |
|
| 64 | - */ |
|
| 65 | - public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 66 | - { |
|
| 67 | - $has_object = parent::_check_for_object( |
|
| 68 | - $props_n_values, |
|
| 69 | - __CLASS__, |
|
| 70 | - $timezone, |
|
| 71 | - $date_formats |
|
| 72 | - ); |
|
| 73 | - return $has_object |
|
| 74 | - ? $has_object |
|
| 75 | - : new self($props_n_values, false, $timezone, $date_formats); |
|
| 76 | - } |
|
| 77 | - |
|
| 78 | - |
|
| 79 | - /** |
|
| 80 | - * @param array $props_n_values incoming values from the database |
|
| 81 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 82 | - * the website will be used. |
|
| 83 | - * @return EE_Datetime |
|
| 84 | - * @throws ReflectionException |
|
| 85 | - * @throws InvalidArgumentException |
|
| 86 | - * @throws InvalidInterfaceException |
|
| 87 | - * @throws InvalidDataTypeException |
|
| 88 | - * @throws EE_Error |
|
| 89 | - */ |
|
| 90 | - public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 91 | - { |
|
| 92 | - return new self($props_n_values, true, $timezone); |
|
| 93 | - } |
|
| 94 | - |
|
| 95 | - |
|
| 96 | - /** |
|
| 97 | - * @param $name |
|
| 98 | - * @throws ReflectionException |
|
| 99 | - * @throws InvalidArgumentException |
|
| 100 | - * @throws InvalidInterfaceException |
|
| 101 | - * @throws InvalidDataTypeException |
|
| 102 | - * @throws EE_Error |
|
| 103 | - */ |
|
| 104 | - public function set_name($name) |
|
| 105 | - { |
|
| 106 | - $this->set('DTT_name', $name); |
|
| 107 | - } |
|
| 108 | - |
|
| 109 | - |
|
| 110 | - /** |
|
| 111 | - * @param $description |
|
| 112 | - * @throws ReflectionException |
|
| 113 | - * @throws InvalidArgumentException |
|
| 114 | - * @throws InvalidInterfaceException |
|
| 115 | - * @throws InvalidDataTypeException |
|
| 116 | - * @throws EE_Error |
|
| 117 | - */ |
|
| 118 | - public function set_description($description) |
|
| 119 | - { |
|
| 120 | - $this->set('DTT_description', $description); |
|
| 121 | - } |
|
| 122 | - |
|
| 123 | - |
|
| 124 | - /** |
|
| 125 | - * Set event start date |
|
| 126 | - * set the start date for an event |
|
| 127 | - * |
|
| 128 | - * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
| 129 | - * @throws ReflectionException |
|
| 130 | - * @throws InvalidArgumentException |
|
| 131 | - * @throws InvalidInterfaceException |
|
| 132 | - * @throws InvalidDataTypeException |
|
| 133 | - * @throws EE_Error |
|
| 134 | - */ |
|
| 135 | - public function set_start_date($date) |
|
| 136 | - { |
|
| 137 | - $this->_set_date_for($date, 'DTT_EVT_start'); |
|
| 138 | - } |
|
| 139 | - |
|
| 140 | - |
|
| 141 | - /** |
|
| 142 | - * Set event start time |
|
| 143 | - * set the start time for an event |
|
| 144 | - * |
|
| 145 | - * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
| 146 | - * @throws ReflectionException |
|
| 147 | - * @throws InvalidArgumentException |
|
| 148 | - * @throws InvalidInterfaceException |
|
| 149 | - * @throws InvalidDataTypeException |
|
| 150 | - * @throws EE_Error |
|
| 151 | - */ |
|
| 152 | - public function set_start_time($time) |
|
| 153 | - { |
|
| 154 | - $this->_set_time_for($time, 'DTT_EVT_start'); |
|
| 155 | - } |
|
| 156 | - |
|
| 157 | - |
|
| 158 | - /** |
|
| 159 | - * Set event end date |
|
| 160 | - * set the end date for an event |
|
| 161 | - * |
|
| 162 | - * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
| 163 | - * @throws ReflectionException |
|
| 164 | - * @throws InvalidArgumentException |
|
| 165 | - * @throws InvalidInterfaceException |
|
| 166 | - * @throws InvalidDataTypeException |
|
| 167 | - * @throws EE_Error |
|
| 168 | - */ |
|
| 169 | - public function set_end_date($date) |
|
| 170 | - { |
|
| 171 | - $this->_set_date_for($date, 'DTT_EVT_end'); |
|
| 172 | - } |
|
| 173 | - |
|
| 174 | - |
|
| 175 | - /** |
|
| 176 | - * Set event end time |
|
| 177 | - * set the end time for an event |
|
| 178 | - * |
|
| 179 | - * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
| 180 | - * @throws ReflectionException |
|
| 181 | - * @throws InvalidArgumentException |
|
| 182 | - * @throws InvalidInterfaceException |
|
| 183 | - * @throws InvalidDataTypeException |
|
| 184 | - * @throws EE_Error |
|
| 185 | - */ |
|
| 186 | - public function set_end_time($time) |
|
| 187 | - { |
|
| 188 | - $this->_set_time_for($time, 'DTT_EVT_end'); |
|
| 189 | - } |
|
| 190 | - |
|
| 191 | - |
|
| 192 | - /** |
|
| 193 | - * Set registration limit |
|
| 194 | - * set the maximum number of attendees that can be registered for this datetime slot |
|
| 195 | - * |
|
| 196 | - * @param int $reg_limit |
|
| 197 | - * @throws ReflectionException |
|
| 198 | - * @throws InvalidArgumentException |
|
| 199 | - * @throws InvalidInterfaceException |
|
| 200 | - * @throws InvalidDataTypeException |
|
| 201 | - * @throws EE_Error |
|
| 202 | - */ |
|
| 203 | - public function set_reg_limit($reg_limit) |
|
| 204 | - { |
|
| 205 | - $this->set('DTT_reg_limit', $reg_limit); |
|
| 206 | - } |
|
| 207 | - |
|
| 208 | - |
|
| 209 | - /** |
|
| 210 | - * get the number of tickets sold for this datetime slot |
|
| 211 | - * |
|
| 212 | - * @return mixed int on success, FALSE on fail |
|
| 213 | - * @throws ReflectionException |
|
| 214 | - * @throws InvalidArgumentException |
|
| 215 | - * @throws InvalidInterfaceException |
|
| 216 | - * @throws InvalidDataTypeException |
|
| 217 | - * @throws EE_Error |
|
| 218 | - */ |
|
| 219 | - public function sold() |
|
| 220 | - { |
|
| 221 | - return $this->get_raw('DTT_sold'); |
|
| 222 | - } |
|
| 223 | - |
|
| 224 | - |
|
| 225 | - /** |
|
| 226 | - * @param int $sold |
|
| 227 | - * @throws ReflectionException |
|
| 228 | - * @throws InvalidArgumentException |
|
| 229 | - * @throws InvalidInterfaceException |
|
| 230 | - * @throws InvalidDataTypeException |
|
| 231 | - * @throws EE_Error |
|
| 232 | - */ |
|
| 233 | - public function set_sold($sold) |
|
| 234 | - { |
|
| 235 | - // sold can not go below zero |
|
| 236 | - $sold = max(0, $sold); |
|
| 237 | - $this->set('DTT_sold', $sold); |
|
| 238 | - } |
|
| 239 | - |
|
| 240 | - |
|
| 241 | - /** |
|
| 242 | - * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
| 243 | - * Simultaneously decreases the reserved count, unless $also_decrease_reserved is false. |
|
| 244 | - * |
|
| 245 | - * @param int $qty |
|
| 246 | - * @param boolean $also_decrease_reserved |
|
| 247 | - * @return boolean indicating success |
|
| 248 | - * @throws ReflectionException |
|
| 249 | - * @throws InvalidArgumentException |
|
| 250 | - * @throws InvalidInterfaceException |
|
| 251 | - * @throws InvalidDataTypeException |
|
| 252 | - * @throws EE_Error |
|
| 253 | - */ |
|
| 254 | - public function increaseSold($qty = 1, $also_decrease_reserved = true) |
|
| 255 | - { |
|
| 256 | - $qty = absint($qty); |
|
| 257 | - if ($also_decrease_reserved) { |
|
| 258 | - $success = $this->adjustNumericFieldsInDb( |
|
| 259 | - [ |
|
| 260 | - 'DTT_reserved' => $qty * -1, |
|
| 261 | - 'DTT_sold' => $qty |
|
| 262 | - ] |
|
| 263 | - ); |
|
| 264 | - } else { |
|
| 265 | - $success = $this->adjustNumericFieldsInDb( |
|
| 266 | - [ |
|
| 267 | - 'DTT_sold' => $qty |
|
| 268 | - ] |
|
| 269 | - ); |
|
| 270 | - } |
|
| 271 | - |
|
| 272 | - do_action( |
|
| 273 | - 'AHEE__EE_Datetime__increase_sold', |
|
| 274 | - $this, |
|
| 275 | - $qty, |
|
| 276 | - $this->sold(), |
|
| 277 | - $success |
|
| 278 | - ); |
|
| 279 | - return $success; |
|
| 280 | - } |
|
| 281 | - |
|
| 282 | - |
|
| 283 | - /** |
|
| 284 | - * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
| 285 | - * to save afterwards.) |
|
| 286 | - * |
|
| 287 | - * @param int $qty |
|
| 288 | - * @return boolean indicating success |
|
| 289 | - * @throws ReflectionException |
|
| 290 | - * @throws InvalidArgumentException |
|
| 291 | - * @throws InvalidInterfaceException |
|
| 292 | - * @throws InvalidDataTypeException |
|
| 293 | - * @throws EE_Error |
|
| 294 | - */ |
|
| 295 | - public function decreaseSold($qty = 1) |
|
| 296 | - { |
|
| 297 | - $qty = absint($qty); |
|
| 298 | - $success = $this->adjustNumericFieldsInDb( |
|
| 299 | - [ |
|
| 300 | - 'DTT_sold' => $qty * -1 |
|
| 301 | - ] |
|
| 302 | - ); |
|
| 303 | - do_action( |
|
| 304 | - 'AHEE__EE_Datetime__decrease_sold', |
|
| 305 | - $this, |
|
| 306 | - $qty, |
|
| 307 | - $this->sold(), |
|
| 308 | - $success |
|
| 309 | - ); |
|
| 310 | - return $success; |
|
| 311 | - } |
|
| 312 | - |
|
| 313 | - |
|
| 314 | - /** |
|
| 315 | - * Gets qty of reserved tickets for this datetime |
|
| 316 | - * |
|
| 317 | - * @return int |
|
| 318 | - * @throws ReflectionException |
|
| 319 | - * @throws InvalidArgumentException |
|
| 320 | - * @throws InvalidInterfaceException |
|
| 321 | - * @throws InvalidDataTypeException |
|
| 322 | - * @throws EE_Error |
|
| 323 | - */ |
|
| 324 | - public function reserved() |
|
| 325 | - { |
|
| 326 | - return $this->get_raw('DTT_reserved'); |
|
| 327 | - } |
|
| 328 | - |
|
| 329 | - |
|
| 330 | - /** |
|
| 331 | - * Sets qty of reserved tickets for this datetime |
|
| 332 | - * |
|
| 333 | - * @param int $reserved |
|
| 334 | - * @throws ReflectionException |
|
| 335 | - * @throws InvalidArgumentException |
|
| 336 | - * @throws InvalidInterfaceException |
|
| 337 | - * @throws InvalidDataTypeException |
|
| 338 | - * @throws EE_Error |
|
| 339 | - */ |
|
| 340 | - public function set_reserved($reserved) |
|
| 341 | - { |
|
| 342 | - // reserved can not go below zero |
|
| 343 | - $reserved = max(0, (int) $reserved); |
|
| 344 | - $this->set('DTT_reserved', $reserved); |
|
| 345 | - } |
|
| 346 | - |
|
| 347 | - |
|
| 348 | - /** |
|
| 349 | - * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 350 | - * |
|
| 351 | - * @param int $qty |
|
| 352 | - * @return boolean indicating success |
|
| 353 | - * @throws ReflectionException |
|
| 354 | - * @throws InvalidArgumentException |
|
| 355 | - * @throws InvalidInterfaceException |
|
| 356 | - * @throws InvalidDataTypeException |
|
| 357 | - * @throws EE_Error |
|
| 358 | - */ |
|
| 359 | - public function increaseReserved($qty = 1) |
|
| 360 | - { |
|
| 361 | - $qty = absint($qty); |
|
| 362 | - $success = $this->incrementFieldConditionallyInDb( |
|
| 363 | - 'DTT_reserved', |
|
| 364 | - 'DTT_sold', |
|
| 365 | - 'DTT_reg_limit', |
|
| 366 | - $qty |
|
| 367 | - ); |
|
| 368 | - do_action( |
|
| 369 | - 'AHEE__EE_Datetime__increase_reserved', |
|
| 370 | - $this, |
|
| 371 | - $qty, |
|
| 372 | - $this->reserved(), |
|
| 373 | - $success |
|
| 374 | - ); |
|
| 375 | - return $success; |
|
| 376 | - } |
|
| 377 | - |
|
| 378 | - |
|
| 379 | - /** |
|
| 380 | - * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 381 | - * |
|
| 382 | - * @param int $qty |
|
| 383 | - * @return boolean indicating success |
|
| 384 | - * @throws ReflectionException |
|
| 385 | - * @throws InvalidArgumentException |
|
| 386 | - * @throws InvalidInterfaceException |
|
| 387 | - * @throws InvalidDataTypeException |
|
| 388 | - * @throws EE_Error |
|
| 389 | - */ |
|
| 390 | - public function decreaseReserved($qty = 1) |
|
| 391 | - { |
|
| 392 | - $qty = absint($qty); |
|
| 393 | - $success = $this->adjustNumericFieldsInDb( |
|
| 394 | - [ |
|
| 395 | - 'DTT_reserved' => $qty * -1 |
|
| 396 | - ] |
|
| 397 | - ); |
|
| 398 | - do_action( |
|
| 399 | - 'AHEE__EE_Datetime__decrease_reserved', |
|
| 400 | - $this, |
|
| 401 | - $qty, |
|
| 402 | - $this->reserved(), |
|
| 403 | - $success |
|
| 404 | - ); |
|
| 405 | - return $success; |
|
| 406 | - } |
|
| 407 | - |
|
| 408 | - |
|
| 409 | - /** |
|
| 410 | - * total sold and reserved tickets |
|
| 411 | - * |
|
| 412 | - * @return int |
|
| 413 | - * @throws ReflectionException |
|
| 414 | - * @throws InvalidArgumentException |
|
| 415 | - * @throws InvalidInterfaceException |
|
| 416 | - * @throws InvalidDataTypeException |
|
| 417 | - * @throws EE_Error |
|
| 418 | - */ |
|
| 419 | - public function sold_and_reserved() |
|
| 420 | - { |
|
| 421 | - return $this->sold() + $this->reserved(); |
|
| 422 | - } |
|
| 423 | - |
|
| 424 | - |
|
| 425 | - /** |
|
| 426 | - * returns the datetime name |
|
| 427 | - * |
|
| 428 | - * @return string |
|
| 429 | - * @throws ReflectionException |
|
| 430 | - * @throws InvalidArgumentException |
|
| 431 | - * @throws InvalidInterfaceException |
|
| 432 | - * @throws InvalidDataTypeException |
|
| 433 | - * @throws EE_Error |
|
| 434 | - */ |
|
| 435 | - public function name() |
|
| 436 | - { |
|
| 437 | - return $this->get('DTT_name'); |
|
| 438 | - } |
|
| 439 | - |
|
| 440 | - |
|
| 441 | - /** |
|
| 442 | - * returns the datetime description |
|
| 443 | - * |
|
| 444 | - * @return string |
|
| 445 | - * @throws ReflectionException |
|
| 446 | - * @throws InvalidArgumentException |
|
| 447 | - * @throws InvalidInterfaceException |
|
| 448 | - * @throws InvalidDataTypeException |
|
| 449 | - * @throws EE_Error |
|
| 450 | - */ |
|
| 451 | - public function description() |
|
| 452 | - { |
|
| 453 | - return $this->get('DTT_description'); |
|
| 454 | - } |
|
| 455 | - |
|
| 456 | - |
|
| 457 | - /** |
|
| 458 | - * This helper simply returns whether the event_datetime for the current datetime is a primary datetime |
|
| 459 | - * |
|
| 460 | - * @return boolean TRUE if is primary, FALSE if not. |
|
| 461 | - * @throws ReflectionException |
|
| 462 | - * @throws InvalidArgumentException |
|
| 463 | - * @throws InvalidInterfaceException |
|
| 464 | - * @throws InvalidDataTypeException |
|
| 465 | - * @throws EE_Error |
|
| 466 | - */ |
|
| 467 | - public function is_primary() |
|
| 468 | - { |
|
| 469 | - return $this->get('DTT_is_primary'); |
|
| 470 | - } |
|
| 471 | - |
|
| 472 | - |
|
| 473 | - /** |
|
| 474 | - * This helper simply returns the order for the datetime |
|
| 475 | - * |
|
| 476 | - * @return int The order of the datetime for this event. |
|
| 477 | - * @throws ReflectionException |
|
| 478 | - * @throws InvalidArgumentException |
|
| 479 | - * @throws InvalidInterfaceException |
|
| 480 | - * @throws InvalidDataTypeException |
|
| 481 | - * @throws EE_Error |
|
| 482 | - */ |
|
| 483 | - public function order() |
|
| 484 | - { |
|
| 485 | - return $this->get('DTT_order'); |
|
| 486 | - } |
|
| 487 | - |
|
| 488 | - |
|
| 489 | - /** |
|
| 490 | - * This helper simply returns the parent id for the datetime |
|
| 491 | - * |
|
| 492 | - * @return int |
|
| 493 | - * @throws ReflectionException |
|
| 494 | - * @throws InvalidArgumentException |
|
| 495 | - * @throws InvalidInterfaceException |
|
| 496 | - * @throws InvalidDataTypeException |
|
| 497 | - * @throws EE_Error |
|
| 498 | - */ |
|
| 499 | - public function parent() |
|
| 500 | - { |
|
| 501 | - return $this->get('DTT_parent'); |
|
| 502 | - } |
|
| 503 | - |
|
| 504 | - |
|
| 505 | - /** |
|
| 506 | - * show date and/or time |
|
| 507 | - * |
|
| 508 | - * @param string $date_or_time whether to display a date or time or both |
|
| 509 | - * @param string $start_or_end whether to display start or end datetimes |
|
| 510 | - * @param string $dt_frmt |
|
| 511 | - * @param string $tm_frmt |
|
| 512 | - * @param bool $echo whether we echo or return (note echoing uses "pretty" formats, |
|
| 513 | - * otherwise we use the standard formats) |
|
| 514 | - * @return string|bool string on success, FALSE on fail |
|
| 515 | - * @throws ReflectionException |
|
| 516 | - * @throws InvalidArgumentException |
|
| 517 | - * @throws InvalidInterfaceException |
|
| 518 | - * @throws InvalidDataTypeException |
|
| 519 | - * @throws EE_Error |
|
| 520 | - */ |
|
| 521 | - private function _show_datetime( |
|
| 522 | - $date_or_time = null, |
|
| 523 | - $start_or_end = 'start', |
|
| 524 | - $dt_frmt = '', |
|
| 525 | - $tm_frmt = '', |
|
| 526 | - $echo = false |
|
| 527 | - ) { |
|
| 528 | - $field_name = "DTT_EVT_{$start_or_end}"; |
|
| 529 | - $dtt = $this->_get_datetime( |
|
| 530 | - $field_name, |
|
| 531 | - $dt_frmt, |
|
| 532 | - $tm_frmt, |
|
| 533 | - $date_or_time, |
|
| 534 | - $echo |
|
| 535 | - ); |
|
| 536 | - if (! $echo) { |
|
| 537 | - return $dtt; |
|
| 538 | - } |
|
| 539 | - return ''; |
|
| 540 | - } |
|
| 541 | - |
|
| 542 | - |
|
| 543 | - /** |
|
| 544 | - * get event start date. Provide either the date format, or NULL to re-use the |
|
| 545 | - * last-used format, or '' to use the default date format |
|
| 546 | - * |
|
| 547 | - * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
| 548 | - * @return mixed string on success, FALSE on fail |
|
| 549 | - * @throws ReflectionException |
|
| 550 | - * @throws InvalidArgumentException |
|
| 551 | - * @throws InvalidInterfaceException |
|
| 552 | - * @throws InvalidDataTypeException |
|
| 553 | - * @throws EE_Error |
|
| 554 | - */ |
|
| 555 | - public function start_date($dt_frmt = '') |
|
| 556 | - { |
|
| 557 | - return $this->_show_datetime('D', 'start', $dt_frmt); |
|
| 558 | - } |
|
| 559 | - |
|
| 560 | - |
|
| 561 | - /** |
|
| 562 | - * Echoes start_date() |
|
| 563 | - * |
|
| 564 | - * @param string $dt_frmt |
|
| 565 | - * @throws ReflectionException |
|
| 566 | - * @throws InvalidArgumentException |
|
| 567 | - * @throws InvalidInterfaceException |
|
| 568 | - * @throws InvalidDataTypeException |
|
| 569 | - * @throws EE_Error |
|
| 570 | - */ |
|
| 571 | - public function e_start_date($dt_frmt = '') |
|
| 572 | - { |
|
| 573 | - $this->_show_datetime('D', 'start', $dt_frmt, null, true); |
|
| 574 | - } |
|
| 575 | - |
|
| 576 | - |
|
| 577 | - /** |
|
| 578 | - * get end date. Provide either the date format, or NULL to re-use the |
|
| 579 | - * last-used format, or '' to use the default date format |
|
| 580 | - * |
|
| 581 | - * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
| 582 | - * @return mixed string on success, FALSE on fail |
|
| 583 | - * @throws ReflectionException |
|
| 584 | - * @throws InvalidArgumentException |
|
| 585 | - * @throws InvalidInterfaceException |
|
| 586 | - * @throws InvalidDataTypeException |
|
| 587 | - * @throws EE_Error |
|
| 588 | - */ |
|
| 589 | - public function end_date($dt_frmt = '') |
|
| 590 | - { |
|
| 591 | - return $this->_show_datetime('D', 'end', $dt_frmt); |
|
| 592 | - } |
|
| 593 | - |
|
| 594 | - |
|
| 595 | - /** |
|
| 596 | - * Echoes the end date. See end_date() |
|
| 597 | - * |
|
| 598 | - * @param string $dt_frmt |
|
| 599 | - * @throws ReflectionException |
|
| 600 | - * @throws InvalidArgumentException |
|
| 601 | - * @throws InvalidInterfaceException |
|
| 602 | - * @throws InvalidDataTypeException |
|
| 603 | - * @throws EE_Error |
|
| 604 | - */ |
|
| 605 | - public function e_end_date($dt_frmt = '') |
|
| 606 | - { |
|
| 607 | - $this->_show_datetime('D', 'end', $dt_frmt, null, true); |
|
| 608 | - } |
|
| 609 | - |
|
| 610 | - |
|
| 611 | - /** |
|
| 612 | - * get date_range - meaning the start AND end date |
|
| 613 | - * |
|
| 614 | - * @access public |
|
| 615 | - * @param string $dt_frmt string representation of date format defaults to WP settings |
|
| 616 | - * @param string $conjunction conjunction junction what's your function ? |
|
| 617 | - * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
| 618 | - * @return mixed string on success, FALSE on fail |
|
| 619 | - * @throws ReflectionException |
|
| 620 | - * @throws InvalidArgumentException |
|
| 621 | - * @throws InvalidInterfaceException |
|
| 622 | - * @throws InvalidDataTypeException |
|
| 623 | - * @throws EE_Error |
|
| 624 | - */ |
|
| 625 | - public function date_range($dt_frmt = '', $conjunction = ' - ') |
|
| 626 | - { |
|
| 627 | - $dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt; |
|
| 628 | - $start = str_replace( |
|
| 629 | - ' ', |
|
| 630 | - ' ', |
|
| 631 | - $this->get_i18n_datetime('DTT_EVT_start', $dt_frmt) |
|
| 632 | - ); |
|
| 633 | - $end = str_replace( |
|
| 634 | - ' ', |
|
| 635 | - ' ', |
|
| 636 | - $this->get_i18n_datetime('DTT_EVT_end', $dt_frmt) |
|
| 637 | - ); |
|
| 638 | - return $start !== $end ? $start . $conjunction . $end : $start; |
|
| 639 | - } |
|
| 640 | - |
|
| 641 | - |
|
| 642 | - /** |
|
| 643 | - * @param string $dt_frmt |
|
| 644 | - * @param string $conjunction |
|
| 645 | - * @throws ReflectionException |
|
| 646 | - * @throws InvalidArgumentException |
|
| 647 | - * @throws InvalidInterfaceException |
|
| 648 | - * @throws InvalidDataTypeException |
|
| 649 | - * @throws EE_Error |
|
| 650 | - */ |
|
| 651 | - public function e_date_range($dt_frmt = '', $conjunction = ' - ') |
|
| 652 | - { |
|
| 653 | - echo $this->date_range($dt_frmt, $conjunction); |
|
| 654 | - } |
|
| 655 | - |
|
| 656 | - |
|
| 657 | - /** |
|
| 658 | - * get start time |
|
| 659 | - * |
|
| 660 | - * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
| 661 | - * @return mixed string on success, FALSE on fail |
|
| 662 | - * @throws ReflectionException |
|
| 663 | - * @throws InvalidArgumentException |
|
| 664 | - * @throws InvalidInterfaceException |
|
| 665 | - * @throws InvalidDataTypeException |
|
| 666 | - * @throws EE_Error |
|
| 667 | - */ |
|
| 668 | - public function start_time($tm_format = '') |
|
| 669 | - { |
|
| 670 | - return $this->_show_datetime('T', 'start', null, $tm_format); |
|
| 671 | - } |
|
| 672 | - |
|
| 673 | - |
|
| 674 | - /** |
|
| 675 | - * @param string $tm_format |
|
| 676 | - * @throws ReflectionException |
|
| 677 | - * @throws InvalidArgumentException |
|
| 678 | - * @throws InvalidInterfaceException |
|
| 679 | - * @throws InvalidDataTypeException |
|
| 680 | - * @throws EE_Error |
|
| 681 | - */ |
|
| 682 | - public function e_start_time($tm_format = '') |
|
| 683 | - { |
|
| 684 | - $this->_show_datetime('T', 'start', null, $tm_format, true); |
|
| 685 | - } |
|
| 686 | - |
|
| 687 | - |
|
| 688 | - /** |
|
| 689 | - * get end time |
|
| 690 | - * |
|
| 691 | - * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
| 692 | - * @return mixed string on success, FALSE on fail |
|
| 693 | - * @throws ReflectionException |
|
| 694 | - * @throws InvalidArgumentException |
|
| 695 | - * @throws InvalidInterfaceException |
|
| 696 | - * @throws InvalidDataTypeException |
|
| 697 | - * @throws EE_Error |
|
| 698 | - */ |
|
| 699 | - public function end_time($tm_format = '') |
|
| 700 | - { |
|
| 701 | - return $this->_show_datetime('T', 'end', null, $tm_format); |
|
| 702 | - } |
|
| 703 | - |
|
| 704 | - |
|
| 705 | - /** |
|
| 706 | - * @param string $tm_format |
|
| 707 | - * @throws ReflectionException |
|
| 708 | - * @throws InvalidArgumentException |
|
| 709 | - * @throws InvalidInterfaceException |
|
| 710 | - * @throws InvalidDataTypeException |
|
| 711 | - * @throws EE_Error |
|
| 712 | - */ |
|
| 713 | - public function e_end_time($tm_format = '') |
|
| 714 | - { |
|
| 715 | - $this->_show_datetime('T', 'end', null, $tm_format, true); |
|
| 716 | - } |
|
| 717 | - |
|
| 718 | - |
|
| 719 | - /** |
|
| 720 | - * get time_range |
|
| 721 | - * |
|
| 722 | - * @access public |
|
| 723 | - * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
| 724 | - * @param string $conjunction conjunction junction what's your function ? |
|
| 725 | - * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
| 726 | - * @return mixed string on success, FALSE on fail |
|
| 727 | - * @throws ReflectionException |
|
| 728 | - * @throws InvalidArgumentException |
|
| 729 | - * @throws InvalidInterfaceException |
|
| 730 | - * @throws InvalidDataTypeException |
|
| 731 | - * @throws EE_Error |
|
| 732 | - */ |
|
| 733 | - public function time_range($tm_format = '', $conjunction = ' - ') |
|
| 734 | - { |
|
| 735 | - $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
| 736 | - $start = str_replace( |
|
| 737 | - ' ', |
|
| 738 | - ' ', |
|
| 739 | - $this->get_i18n_datetime('DTT_EVT_start', $tm_format) |
|
| 740 | - ); |
|
| 741 | - $end = str_replace( |
|
| 742 | - ' ', |
|
| 743 | - ' ', |
|
| 744 | - $this->get_i18n_datetime('DTT_EVT_end', $tm_format) |
|
| 745 | - ); |
|
| 746 | - return $start !== $end ? $start . $conjunction . $end : $start; |
|
| 747 | - } |
|
| 748 | - |
|
| 749 | - |
|
| 750 | - /** |
|
| 751 | - * @param string $tm_format |
|
| 752 | - * @param string $conjunction |
|
| 753 | - * @throws ReflectionException |
|
| 754 | - * @throws InvalidArgumentException |
|
| 755 | - * @throws InvalidInterfaceException |
|
| 756 | - * @throws InvalidDataTypeException |
|
| 757 | - * @throws EE_Error |
|
| 758 | - */ |
|
| 759 | - public function e_time_range($tm_format = '', $conjunction = ' - ') |
|
| 760 | - { |
|
| 761 | - echo $this->time_range($tm_format, $conjunction); |
|
| 762 | - } |
|
| 763 | - |
|
| 764 | - |
|
| 765 | - /** |
|
| 766 | - * This returns a range representation of the date and times. |
|
| 767 | - * Output is dependent on the difference (or similarity) between DTT_EVT_start and DTT_EVT_end. |
|
| 768 | - * Also, the return value is localized. |
|
| 769 | - * |
|
| 770 | - * @param string $dt_format |
|
| 771 | - * @param string $tm_format |
|
| 772 | - * @param string $conjunction used between two different dates or times. |
|
| 773 | - * ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm |
|
| 774 | - * @param string $separator used between the date and time formats. |
|
| 775 | - * ex: Dec 1, 2016{$separator}2pm |
|
| 776 | - * @return string |
|
| 777 | - * @throws ReflectionException |
|
| 778 | - * @throws InvalidArgumentException |
|
| 779 | - * @throws InvalidInterfaceException |
|
| 780 | - * @throws InvalidDataTypeException |
|
| 781 | - * @throws EE_Error |
|
| 782 | - */ |
|
| 783 | - public function date_and_time_range( |
|
| 784 | - $dt_format = '', |
|
| 785 | - $tm_format = '', |
|
| 786 | - $conjunction = ' - ', |
|
| 787 | - $separator = ' ' |
|
| 788 | - ) { |
|
| 789 | - $dt_format = ! empty($dt_format) ? $dt_format : $this->_dt_frmt; |
|
| 790 | - $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
| 791 | - $full_format = $dt_format . $separator . $tm_format; |
|
| 792 | - // the range output depends on various conditions |
|
| 793 | - switch (true) { |
|
| 794 | - // start date timestamp and end date timestamp are the same. |
|
| 795 | - case ($this->get_raw('DTT_EVT_start') === $this->get_raw('DTT_EVT_end')): |
|
| 796 | - $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format); |
|
| 797 | - break; |
|
| 798 | - // start and end date are the same but times are different |
|
| 799 | - case ($this->start_date() === $this->end_date()): |
|
| 800 | - $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
| 801 | - . $conjunction |
|
| 802 | - . $this->get_i18n_datetime('DTT_EVT_end', $tm_format); |
|
| 803 | - break; |
|
| 804 | - // all other conditions |
|
| 805 | - default: |
|
| 806 | - $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
| 807 | - . $conjunction |
|
| 808 | - . $this->get_i18n_datetime('DTT_EVT_end', $full_format); |
|
| 809 | - break; |
|
| 810 | - } |
|
| 811 | - return $output; |
|
| 812 | - } |
|
| 813 | - |
|
| 814 | - |
|
| 815 | - /** |
|
| 816 | - * This echos the results of date and time range. |
|
| 817 | - * |
|
| 818 | - * @see date_and_time_range() for more details on purpose. |
|
| 819 | - * @param string $dt_format |
|
| 820 | - * @param string $tm_format |
|
| 821 | - * @param string $conjunction |
|
| 822 | - * @return void |
|
| 823 | - * @throws ReflectionException |
|
| 824 | - * @throws InvalidArgumentException |
|
| 825 | - * @throws InvalidInterfaceException |
|
| 826 | - * @throws InvalidDataTypeException |
|
| 827 | - * @throws EE_Error |
|
| 828 | - */ |
|
| 829 | - public function e_date_and_time_range($dt_format = '', $tm_format = '', $conjunction = ' - ') |
|
| 830 | - { |
|
| 831 | - echo $this->date_and_time_range($dt_format, $tm_format, $conjunction); |
|
| 832 | - } |
|
| 833 | - |
|
| 834 | - |
|
| 835 | - /** |
|
| 836 | - * get start date and start time |
|
| 837 | - * |
|
| 838 | - * @param string $dt_format - string representation of date format defaults to 'F j, Y' |
|
| 839 | - * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
| 840 | - * @return mixed string on success, FALSE on fail |
|
| 841 | - * @throws ReflectionException |
|
| 842 | - * @throws InvalidArgumentException |
|
| 843 | - * @throws InvalidInterfaceException |
|
| 844 | - * @throws InvalidDataTypeException |
|
| 845 | - * @throws EE_Error |
|
| 846 | - */ |
|
| 847 | - public function start_date_and_time($dt_format = '', $tm_format = '') |
|
| 848 | - { |
|
| 849 | - return $this->_show_datetime('', 'start', $dt_format, $tm_format); |
|
| 850 | - } |
|
| 851 | - |
|
| 852 | - |
|
| 853 | - /** |
|
| 854 | - * @param string $dt_frmt |
|
| 855 | - * @param string $tm_format |
|
| 856 | - * @throws ReflectionException |
|
| 857 | - * @throws InvalidArgumentException |
|
| 858 | - * @throws InvalidInterfaceException |
|
| 859 | - * @throws InvalidDataTypeException |
|
| 860 | - * @throws EE_Error |
|
| 861 | - */ |
|
| 862 | - public function e_start_date_and_time($dt_frmt = '', $tm_format = '') |
|
| 863 | - { |
|
| 864 | - $this->_show_datetime('', 'start', $dt_frmt, $tm_format, true); |
|
| 865 | - } |
|
| 866 | - |
|
| 867 | - |
|
| 868 | - /** |
|
| 869 | - * Shows the length of the event (start to end time). |
|
| 870 | - * Can be shown in 'seconds','minutes','hours', or 'days'. |
|
| 871 | - * By default, rounds up. (So if you use 'days', and then event |
|
| 872 | - * only occurs for 1 hour, it will return 1 day). |
|
| 873 | - * |
|
| 874 | - * @param string $units 'seconds','minutes','hours','days' |
|
| 875 | - * @param bool $round_up |
|
| 876 | - * @return float|int|mixed |
|
| 877 | - * @throws ReflectionException |
|
| 878 | - * @throws InvalidArgumentException |
|
| 879 | - * @throws InvalidInterfaceException |
|
| 880 | - * @throws InvalidDataTypeException |
|
| 881 | - * @throws EE_Error |
|
| 882 | - */ |
|
| 883 | - public function length($units = 'seconds', $round_up = false) |
|
| 884 | - { |
|
| 885 | - $start = $this->get_raw('DTT_EVT_start'); |
|
| 886 | - $end = $this->get_raw('DTT_EVT_end'); |
|
| 887 | - $length_in_units = $end - $start; |
|
| 888 | - switch ($units) { |
|
| 889 | - // NOTE: We purposefully don't use "break;" in order to chain the divisions |
|
| 890 | - /** @noinspection PhpMissingBreakStatementInspection */ |
|
| 891 | - // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment |
|
| 892 | - case 'days': |
|
| 893 | - $length_in_units /= 24; |
|
| 894 | - /** @noinspection PhpMissingBreakStatementInspection */ |
|
| 895 | - case 'hours': |
|
| 896 | - // fall through is intentional |
|
| 897 | - $length_in_units /= 60; |
|
| 898 | - /** @noinspection PhpMissingBreakStatementInspection */ |
|
| 899 | - case 'minutes': |
|
| 900 | - // fall through is intentional |
|
| 901 | - $length_in_units /= 60; |
|
| 902 | - case 'seconds': |
|
| 903 | - default: |
|
| 904 | - $length_in_units = ceil($length_in_units); |
|
| 905 | - } |
|
| 906 | - // phpcs:enable |
|
| 907 | - if ($round_up) { |
|
| 908 | - $length_in_units = max($length_in_units, 1); |
|
| 909 | - } |
|
| 910 | - return $length_in_units; |
|
| 911 | - } |
|
| 912 | - |
|
| 913 | - |
|
| 914 | - /** |
|
| 915 | - * get end date and time |
|
| 916 | - * |
|
| 917 | - * @param string $dt_frmt - string representation of date format defaults to 'F j, Y' |
|
| 918 | - * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
| 919 | - * @return mixed string on success, FALSE on fail |
|
| 920 | - * @throws ReflectionException |
|
| 921 | - * @throws InvalidArgumentException |
|
| 922 | - * @throws InvalidInterfaceException |
|
| 923 | - * @throws InvalidDataTypeException |
|
| 924 | - * @throws EE_Error |
|
| 925 | - */ |
|
| 926 | - public function end_date_and_time($dt_frmt = '', $tm_format = '') |
|
| 927 | - { |
|
| 928 | - return $this->_show_datetime('', 'end', $dt_frmt, $tm_format); |
|
| 929 | - } |
|
| 930 | - |
|
| 931 | - |
|
| 932 | - /** |
|
| 933 | - * @param string $dt_frmt |
|
| 934 | - * @param string $tm_format |
|
| 935 | - * @throws ReflectionException |
|
| 936 | - * @throws InvalidArgumentException |
|
| 937 | - * @throws InvalidInterfaceException |
|
| 938 | - * @throws InvalidDataTypeException |
|
| 939 | - * @throws EE_Error |
|
| 940 | - */ |
|
| 941 | - public function e_end_date_and_time($dt_frmt = '', $tm_format = '') |
|
| 942 | - { |
|
| 943 | - $this->_show_datetime('', 'end', $dt_frmt, $tm_format, true); |
|
| 944 | - } |
|
| 945 | - |
|
| 946 | - |
|
| 947 | - /** |
|
| 948 | - * get start timestamp |
|
| 949 | - * |
|
| 950 | - * @return int |
|
| 951 | - * @throws ReflectionException |
|
| 952 | - * @throws InvalidArgumentException |
|
| 953 | - * @throws InvalidInterfaceException |
|
| 954 | - * @throws InvalidDataTypeException |
|
| 955 | - * @throws EE_Error |
|
| 956 | - */ |
|
| 957 | - public function start() |
|
| 958 | - { |
|
| 959 | - return $this->get_raw('DTT_EVT_start'); |
|
| 960 | - } |
|
| 961 | - |
|
| 962 | - |
|
| 963 | - /** |
|
| 964 | - * get end timestamp |
|
| 965 | - * |
|
| 966 | - * @return int |
|
| 967 | - * @throws ReflectionException |
|
| 968 | - * @throws InvalidArgumentException |
|
| 969 | - * @throws InvalidInterfaceException |
|
| 970 | - * @throws InvalidDataTypeException |
|
| 971 | - * @throws EE_Error |
|
| 972 | - */ |
|
| 973 | - public function end() |
|
| 974 | - { |
|
| 975 | - return $this->get_raw('DTT_EVT_end'); |
|
| 976 | - } |
|
| 977 | - |
|
| 978 | - |
|
| 979 | - /** |
|
| 980 | - * get the registration limit for this datetime slot |
|
| 981 | - * |
|
| 982 | - * @return mixed int on success, FALSE on fail |
|
| 983 | - * @throws ReflectionException |
|
| 984 | - * @throws InvalidArgumentException |
|
| 985 | - * @throws InvalidInterfaceException |
|
| 986 | - * @throws InvalidDataTypeException |
|
| 987 | - * @throws EE_Error |
|
| 988 | - */ |
|
| 989 | - public function reg_limit() |
|
| 990 | - { |
|
| 991 | - return $this->get_raw('DTT_reg_limit'); |
|
| 992 | - } |
|
| 993 | - |
|
| 994 | - |
|
| 995 | - /** |
|
| 996 | - * have the tickets sold for this datetime, met or exceed the registration limit ? |
|
| 997 | - * |
|
| 998 | - * @return boolean |
|
| 999 | - * @throws ReflectionException |
|
| 1000 | - * @throws InvalidArgumentException |
|
| 1001 | - * @throws InvalidInterfaceException |
|
| 1002 | - * @throws InvalidDataTypeException |
|
| 1003 | - * @throws EE_Error |
|
| 1004 | - */ |
|
| 1005 | - public function sold_out() |
|
| 1006 | - { |
|
| 1007 | - return $this->reg_limit() > 0 && $this->sold() >= $this->reg_limit(); |
|
| 1008 | - } |
|
| 1009 | - |
|
| 1010 | - |
|
| 1011 | - /** |
|
| 1012 | - * return the total number of spaces remaining at this venue. |
|
| 1013 | - * This only takes the venue's capacity into account, NOT the tickets available for sale |
|
| 1014 | - * |
|
| 1015 | - * @param bool $consider_tickets Whether to consider tickets remaining when determining if there are any spaces left |
|
| 1016 | - * Because if all tickets attached to this datetime have no spaces left, |
|
| 1017 | - * then this datetime IS effectively sold out. |
|
| 1018 | - * However, there are cases where we just want to know the spaces |
|
| 1019 | - * remaining for this particular datetime, hence the flag. |
|
| 1020 | - * @return int |
|
| 1021 | - * @throws ReflectionException |
|
| 1022 | - * @throws InvalidArgumentException |
|
| 1023 | - * @throws InvalidInterfaceException |
|
| 1024 | - * @throws InvalidDataTypeException |
|
| 1025 | - * @throws EE_Error |
|
| 1026 | - */ |
|
| 1027 | - public function spaces_remaining($consider_tickets = false) |
|
| 1028 | - { |
|
| 1029 | - // tickets remaining available for purchase |
|
| 1030 | - // no need for special checks for infinite, because if DTT_reg_limit == EE_INF, then EE_INF - x = EE_INF |
|
| 1031 | - $dtt_remaining = $this->reg_limit() - $this->sold_and_reserved(); |
|
| 1032 | - if (! $consider_tickets) { |
|
| 1033 | - return $dtt_remaining; |
|
| 1034 | - } |
|
| 1035 | - $tickets_remaining = $this->tickets_remaining(); |
|
| 1036 | - return min($dtt_remaining, $tickets_remaining); |
|
| 1037 | - } |
|
| 1038 | - |
|
| 1039 | - |
|
| 1040 | - /** |
|
| 1041 | - * Counts the total tickets available |
|
| 1042 | - * (from all the different types of tickets which are available for this datetime). |
|
| 1043 | - * |
|
| 1044 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1045 | - * @return int |
|
| 1046 | - * @throws ReflectionException |
|
| 1047 | - * @throws InvalidArgumentException |
|
| 1048 | - * @throws InvalidInterfaceException |
|
| 1049 | - * @throws InvalidDataTypeException |
|
| 1050 | - * @throws EE_Error |
|
| 1051 | - */ |
|
| 1052 | - public function tickets_remaining($query_params = array()) |
|
| 1053 | - { |
|
| 1054 | - $sum = 0; |
|
| 1055 | - $tickets = $this->tickets($query_params); |
|
| 1056 | - if (! empty($tickets)) { |
|
| 1057 | - foreach ($tickets as $ticket) { |
|
| 1058 | - if ($ticket instanceof EE_Ticket) { |
|
| 1059 | - // get the actual amount of tickets that can be sold |
|
| 1060 | - $qty = $ticket->qty('saleable'); |
|
| 1061 | - if ($qty === EE_INF) { |
|
| 1062 | - return EE_INF; |
|
| 1063 | - } |
|
| 1064 | - // no negative ticket quantities plz |
|
| 1065 | - if ($qty > 0) { |
|
| 1066 | - $sum += $qty; |
|
| 1067 | - } |
|
| 1068 | - } |
|
| 1069 | - } |
|
| 1070 | - } |
|
| 1071 | - return $sum; |
|
| 1072 | - } |
|
| 1073 | - |
|
| 1074 | - |
|
| 1075 | - /** |
|
| 1076 | - * Gets the count of all the tickets available at this datetime (not ticket types) |
|
| 1077 | - * before any were sold |
|
| 1078 | - * |
|
| 1079 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1080 | - * @return int |
|
| 1081 | - * @throws ReflectionException |
|
| 1082 | - * @throws InvalidArgumentException |
|
| 1083 | - * @throws InvalidInterfaceException |
|
| 1084 | - * @throws InvalidDataTypeException |
|
| 1085 | - * @throws EE_Error |
|
| 1086 | - */ |
|
| 1087 | - public function sum_tickets_initially_available($query_params = array()) |
|
| 1088 | - { |
|
| 1089 | - return $this->sum_related('Ticket', $query_params, 'TKT_qty'); |
|
| 1090 | - } |
|
| 1091 | - |
|
| 1092 | - |
|
| 1093 | - /** |
|
| 1094 | - * Returns the lesser-of-the two: spaces remaining at this datetime, or |
|
| 1095 | - * the total tickets remaining (a sum of the tickets remaining for each ticket type |
|
| 1096 | - * that is available for this datetime). |
|
| 1097 | - * |
|
| 1098 | - * @return int |
|
| 1099 | - * @throws ReflectionException |
|
| 1100 | - * @throws InvalidArgumentException |
|
| 1101 | - * @throws InvalidInterfaceException |
|
| 1102 | - * @throws InvalidDataTypeException |
|
| 1103 | - * @throws EE_Error |
|
| 1104 | - */ |
|
| 1105 | - public function total_tickets_available_at_this_datetime() |
|
| 1106 | - { |
|
| 1107 | - return $this->spaces_remaining(true); |
|
| 1108 | - } |
|
| 1109 | - |
|
| 1110 | - |
|
| 1111 | - /** |
|
| 1112 | - * This simply compares the internal dtt for the given string with NOW |
|
| 1113 | - * and determines if the date is upcoming or not. |
|
| 1114 | - * |
|
| 1115 | - * @access public |
|
| 1116 | - * @return boolean |
|
| 1117 | - * @throws ReflectionException |
|
| 1118 | - * @throws InvalidArgumentException |
|
| 1119 | - * @throws InvalidInterfaceException |
|
| 1120 | - * @throws InvalidDataTypeException |
|
| 1121 | - * @throws EE_Error |
|
| 1122 | - */ |
|
| 1123 | - public function is_upcoming() |
|
| 1124 | - { |
|
| 1125 | - return ($this->get_raw('DTT_EVT_start') > time()); |
|
| 1126 | - } |
|
| 1127 | - |
|
| 1128 | - |
|
| 1129 | - /** |
|
| 1130 | - * This simply compares the internal datetime for the given string with NOW |
|
| 1131 | - * and returns if the date is active (i.e. start and end time) |
|
| 1132 | - * |
|
| 1133 | - * @return boolean |
|
| 1134 | - * @throws ReflectionException |
|
| 1135 | - * @throws InvalidArgumentException |
|
| 1136 | - * @throws InvalidInterfaceException |
|
| 1137 | - * @throws InvalidDataTypeException |
|
| 1138 | - * @throws EE_Error |
|
| 1139 | - */ |
|
| 1140 | - public function is_active() |
|
| 1141 | - { |
|
| 1142 | - return ($this->get_raw('DTT_EVT_start') < time() && $this->get_raw('DTT_EVT_end') > time()); |
|
| 1143 | - } |
|
| 1144 | - |
|
| 1145 | - |
|
| 1146 | - /** |
|
| 1147 | - * This simply compares the internal dtt for the given string with NOW |
|
| 1148 | - * and determines if the date is expired or not. |
|
| 1149 | - * |
|
| 1150 | - * @return boolean |
|
| 1151 | - * @throws ReflectionException |
|
| 1152 | - * @throws InvalidArgumentException |
|
| 1153 | - * @throws InvalidInterfaceException |
|
| 1154 | - * @throws InvalidDataTypeException |
|
| 1155 | - * @throws EE_Error |
|
| 1156 | - */ |
|
| 1157 | - public function is_expired() |
|
| 1158 | - { |
|
| 1159 | - return ($this->get_raw('DTT_EVT_end') < time()); |
|
| 1160 | - } |
|
| 1161 | - |
|
| 1162 | - |
|
| 1163 | - /** |
|
| 1164 | - * This returns the active status for whether an event is active, upcoming, or expired |
|
| 1165 | - * |
|
| 1166 | - * @return int return value will be one of the EE_Datetime status constants. |
|
| 1167 | - * @throws ReflectionException |
|
| 1168 | - * @throws InvalidArgumentException |
|
| 1169 | - * @throws InvalidInterfaceException |
|
| 1170 | - * @throws InvalidDataTypeException |
|
| 1171 | - * @throws EE_Error |
|
| 1172 | - */ |
|
| 1173 | - public function get_active_status() |
|
| 1174 | - { |
|
| 1175 | - $total_tickets_for_this_dtt = $this->total_tickets_available_at_this_datetime(); |
|
| 1176 | - if ($total_tickets_for_this_dtt !== false && $total_tickets_for_this_dtt < 1) { |
|
| 1177 | - return EE_Datetime::sold_out; |
|
| 1178 | - } |
|
| 1179 | - if ($this->is_expired()) { |
|
| 1180 | - return EE_Datetime::expired; |
|
| 1181 | - } |
|
| 1182 | - if ($this->is_upcoming()) { |
|
| 1183 | - return EE_Datetime::upcoming; |
|
| 1184 | - } |
|
| 1185 | - if ($this->is_active()) { |
|
| 1186 | - return EE_Datetime::active; |
|
| 1187 | - } |
|
| 1188 | - return null; |
|
| 1189 | - } |
|
| 1190 | - |
|
| 1191 | - |
|
| 1192 | - /** |
|
| 1193 | - * This returns a nice display name for the datetime that is contingent on the span between the dates and times. |
|
| 1194 | - * |
|
| 1195 | - * @param boolean $use_dtt_name if TRUE then we'll use DTT->name() if its not empty. |
|
| 1196 | - * @return string |
|
| 1197 | - * @throws ReflectionException |
|
| 1198 | - * @throws InvalidArgumentException |
|
| 1199 | - * @throws InvalidInterfaceException |
|
| 1200 | - * @throws InvalidDataTypeException |
|
| 1201 | - * @throws EE_Error |
|
| 1202 | - */ |
|
| 1203 | - public function get_dtt_display_name($use_dtt_name = false) |
|
| 1204 | - { |
|
| 1205 | - if ($use_dtt_name) { |
|
| 1206 | - $dtt_name = $this->name(); |
|
| 1207 | - if (! empty($dtt_name)) { |
|
| 1208 | - return $dtt_name; |
|
| 1209 | - } |
|
| 1210 | - } |
|
| 1211 | - // first condition is to see if the months are different |
|
| 1212 | - if ( |
|
| 1213 | - date('m', $this->get_raw('DTT_EVT_start')) !== date('m', $this->get_raw('DTT_EVT_end')) |
|
| 1214 | - ) { |
|
| 1215 | - $display_date = $this->start_date('M j\, Y g:i a') . ' - ' . $this->end_date('M j\, Y g:i a'); |
|
| 1216 | - // next condition is if its the same month but different day |
|
| 1217 | - } else { |
|
| 1218 | - if ( |
|
| 1219 | - date('m', $this->get_raw('DTT_EVT_start')) === date('m', $this->get_raw('DTT_EVT_end')) |
|
| 1220 | - && date('d', $this->get_raw('DTT_EVT_start')) !== date('d', $this->get_raw('DTT_EVT_end')) |
|
| 1221 | - ) { |
|
| 1222 | - $display_date = $this->start_date('M j\, g:i a') . ' - ' . $this->end_date('M j\, g:i a Y'); |
|
| 1223 | - } else { |
|
| 1224 | - $display_date = $this->start_date('F j\, Y') |
|
| 1225 | - . ' @ ' |
|
| 1226 | - . $this->start_date('g:i a') |
|
| 1227 | - . ' - ' |
|
| 1228 | - . $this->end_date('g:i a'); |
|
| 1229 | - } |
|
| 1230 | - } |
|
| 1231 | - return $display_date; |
|
| 1232 | - } |
|
| 1233 | - |
|
| 1234 | - |
|
| 1235 | - /** |
|
| 1236 | - * Gets all the tickets for this datetime |
|
| 1237 | - * |
|
| 1238 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1239 | - * @return EE_Base_Class[]|EE_Ticket[] |
|
| 1240 | - * @throws ReflectionException |
|
| 1241 | - * @throws InvalidArgumentException |
|
| 1242 | - * @throws InvalidInterfaceException |
|
| 1243 | - * @throws InvalidDataTypeException |
|
| 1244 | - * @throws EE_Error |
|
| 1245 | - */ |
|
| 1246 | - public function tickets($query_params = array()) |
|
| 1247 | - { |
|
| 1248 | - return $this->get_many_related('Ticket', $query_params); |
|
| 1249 | - } |
|
| 1250 | - |
|
| 1251 | - |
|
| 1252 | - /** |
|
| 1253 | - * Gets all the ticket types currently available for purchase |
|
| 1254 | - * |
|
| 1255 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1256 | - * @return EE_Ticket[] |
|
| 1257 | - * @throws ReflectionException |
|
| 1258 | - * @throws InvalidArgumentException |
|
| 1259 | - * @throws InvalidInterfaceException |
|
| 1260 | - * @throws InvalidDataTypeException |
|
| 1261 | - * @throws EE_Error |
|
| 1262 | - */ |
|
| 1263 | - public function ticket_types_available_for_purchase($query_params = array()) |
|
| 1264 | - { |
|
| 1265 | - // first check if datetime is valid |
|
| 1266 | - if ($this->sold_out() || ! ($this->is_upcoming() || $this->is_active())) { |
|
| 1267 | - return array(); |
|
| 1268 | - } |
|
| 1269 | - if (empty($query_params)) { |
|
| 1270 | - $query_params = array( |
|
| 1271 | - array( |
|
| 1272 | - 'TKT_start_date' => array('<=', EEM_Ticket::instance()->current_time_for_query('TKT_start_date')), |
|
| 1273 | - 'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')), |
|
| 1274 | - 'TKT_deleted' => false, |
|
| 1275 | - ), |
|
| 1276 | - ); |
|
| 1277 | - } |
|
| 1278 | - return $this->tickets($query_params); |
|
| 1279 | - } |
|
| 1280 | - |
|
| 1281 | - |
|
| 1282 | - /** |
|
| 1283 | - * @return EE_Base_Class|EE_Event |
|
| 1284 | - * @throws ReflectionException |
|
| 1285 | - * @throws InvalidArgumentException |
|
| 1286 | - * @throws InvalidInterfaceException |
|
| 1287 | - * @throws InvalidDataTypeException |
|
| 1288 | - * @throws EE_Error |
|
| 1289 | - */ |
|
| 1290 | - public function event() |
|
| 1291 | - { |
|
| 1292 | - return $this->get_first_related('Event'); |
|
| 1293 | - } |
|
| 1294 | - |
|
| 1295 | - |
|
| 1296 | - /** |
|
| 1297 | - * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime |
|
| 1298 | - * (via the tickets). |
|
| 1299 | - * |
|
| 1300 | - * @return int |
|
| 1301 | - * @throws ReflectionException |
|
| 1302 | - * @throws InvalidArgumentException |
|
| 1303 | - * @throws InvalidInterfaceException |
|
| 1304 | - * @throws InvalidDataTypeException |
|
| 1305 | - * @throws EE_Error |
|
| 1306 | - */ |
|
| 1307 | - public function update_sold() |
|
| 1308 | - { |
|
| 1309 | - $count_regs_for_this_datetime = EEM_Registration::instance()->count( |
|
| 1310 | - array( |
|
| 1311 | - array( |
|
| 1312 | - 'STS_ID' => EEM_Registration::status_id_approved, |
|
| 1313 | - 'REG_deleted' => 0, |
|
| 1314 | - 'Ticket.Datetime.DTT_ID' => $this->ID(), |
|
| 1315 | - ), |
|
| 1316 | - ) |
|
| 1317 | - ); |
|
| 1318 | - $this->set_sold($count_regs_for_this_datetime); |
|
| 1319 | - $this->save(); |
|
| 1320 | - return $count_regs_for_this_datetime; |
|
| 1321 | - } |
|
| 1322 | - |
|
| 1323 | - |
|
| 1324 | - /******************************************************************* |
|
| 16 | + /** |
|
| 17 | + * constant used by get_active_status, indicates datetime has no more available spaces |
|
| 18 | + */ |
|
| 19 | + const sold_out = 'DTS'; |
|
| 20 | + |
|
| 21 | + /** |
|
| 22 | + * constant used by get_active_status, indicating datetime is still active (even is not over, can be registered-for) |
|
| 23 | + */ |
|
| 24 | + const active = 'DTA'; |
|
| 25 | + |
|
| 26 | + /** |
|
| 27 | + * constant used by get_active_status, indicating the datetime cannot be used for registrations yet, but has not |
|
| 28 | + * expired |
|
| 29 | + */ |
|
| 30 | + const upcoming = 'DTU'; |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * Datetime is postponed |
|
| 34 | + */ |
|
| 35 | + const postponed = 'DTP'; |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * Datetime is cancelled |
|
| 39 | + */ |
|
| 40 | + const cancelled = 'DTC'; |
|
| 41 | + |
|
| 42 | + /** |
|
| 43 | + * constant used by get_active_status, indicates datetime has expired (event is over) |
|
| 44 | + */ |
|
| 45 | + const expired = 'DTE'; |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * constant used in various places indicating that an event is INACTIVE (not yet ready to be published) |
|
| 49 | + */ |
|
| 50 | + const inactive = 'DTI'; |
|
| 51 | + |
|
| 52 | + |
|
| 53 | + /** |
|
| 54 | + * @param array $props_n_values incoming values |
|
| 55 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be used.) |
|
| 56 | + * @param array $date_formats incoming date_formats in an array where the first value is the date_format |
|
| 57 | + * and the second value is the time format |
|
| 58 | + * @return EE_Datetime |
|
| 59 | + * @throws ReflectionException |
|
| 60 | + * @throws InvalidArgumentException |
|
| 61 | + * @throws InvalidInterfaceException |
|
| 62 | + * @throws InvalidDataTypeException |
|
| 63 | + * @throws EE_Error |
|
| 64 | + */ |
|
| 65 | + public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array()) |
|
| 66 | + { |
|
| 67 | + $has_object = parent::_check_for_object( |
|
| 68 | + $props_n_values, |
|
| 69 | + __CLASS__, |
|
| 70 | + $timezone, |
|
| 71 | + $date_formats |
|
| 72 | + ); |
|
| 73 | + return $has_object |
|
| 74 | + ? $has_object |
|
| 75 | + : new self($props_n_values, false, $timezone, $date_formats); |
|
| 76 | + } |
|
| 77 | + |
|
| 78 | + |
|
| 79 | + /** |
|
| 80 | + * @param array $props_n_values incoming values from the database |
|
| 81 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
| 82 | + * the website will be used. |
|
| 83 | + * @return EE_Datetime |
|
| 84 | + * @throws ReflectionException |
|
| 85 | + * @throws InvalidArgumentException |
|
| 86 | + * @throws InvalidInterfaceException |
|
| 87 | + * @throws InvalidDataTypeException |
|
| 88 | + * @throws EE_Error |
|
| 89 | + */ |
|
| 90 | + public static function new_instance_from_db($props_n_values = array(), $timezone = '') |
|
| 91 | + { |
|
| 92 | + return new self($props_n_values, true, $timezone); |
|
| 93 | + } |
|
| 94 | + |
|
| 95 | + |
|
| 96 | + /** |
|
| 97 | + * @param $name |
|
| 98 | + * @throws ReflectionException |
|
| 99 | + * @throws InvalidArgumentException |
|
| 100 | + * @throws InvalidInterfaceException |
|
| 101 | + * @throws InvalidDataTypeException |
|
| 102 | + * @throws EE_Error |
|
| 103 | + */ |
|
| 104 | + public function set_name($name) |
|
| 105 | + { |
|
| 106 | + $this->set('DTT_name', $name); |
|
| 107 | + } |
|
| 108 | + |
|
| 109 | + |
|
| 110 | + /** |
|
| 111 | + * @param $description |
|
| 112 | + * @throws ReflectionException |
|
| 113 | + * @throws InvalidArgumentException |
|
| 114 | + * @throws InvalidInterfaceException |
|
| 115 | + * @throws InvalidDataTypeException |
|
| 116 | + * @throws EE_Error |
|
| 117 | + */ |
|
| 118 | + public function set_description($description) |
|
| 119 | + { |
|
| 120 | + $this->set('DTT_description', $description); |
|
| 121 | + } |
|
| 122 | + |
|
| 123 | + |
|
| 124 | + /** |
|
| 125 | + * Set event start date |
|
| 126 | + * set the start date for an event |
|
| 127 | + * |
|
| 128 | + * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
| 129 | + * @throws ReflectionException |
|
| 130 | + * @throws InvalidArgumentException |
|
| 131 | + * @throws InvalidInterfaceException |
|
| 132 | + * @throws InvalidDataTypeException |
|
| 133 | + * @throws EE_Error |
|
| 134 | + */ |
|
| 135 | + public function set_start_date($date) |
|
| 136 | + { |
|
| 137 | + $this->_set_date_for($date, 'DTT_EVT_start'); |
|
| 138 | + } |
|
| 139 | + |
|
| 140 | + |
|
| 141 | + /** |
|
| 142 | + * Set event start time |
|
| 143 | + * set the start time for an event |
|
| 144 | + * |
|
| 145 | + * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
| 146 | + * @throws ReflectionException |
|
| 147 | + * @throws InvalidArgumentException |
|
| 148 | + * @throws InvalidInterfaceException |
|
| 149 | + * @throws InvalidDataTypeException |
|
| 150 | + * @throws EE_Error |
|
| 151 | + */ |
|
| 152 | + public function set_start_time($time) |
|
| 153 | + { |
|
| 154 | + $this->_set_time_for($time, 'DTT_EVT_start'); |
|
| 155 | + } |
|
| 156 | + |
|
| 157 | + |
|
| 158 | + /** |
|
| 159 | + * Set event end date |
|
| 160 | + * set the end date for an event |
|
| 161 | + * |
|
| 162 | + * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
| 163 | + * @throws ReflectionException |
|
| 164 | + * @throws InvalidArgumentException |
|
| 165 | + * @throws InvalidInterfaceException |
|
| 166 | + * @throws InvalidDataTypeException |
|
| 167 | + * @throws EE_Error |
|
| 168 | + */ |
|
| 169 | + public function set_end_date($date) |
|
| 170 | + { |
|
| 171 | + $this->_set_date_for($date, 'DTT_EVT_end'); |
|
| 172 | + } |
|
| 173 | + |
|
| 174 | + |
|
| 175 | + /** |
|
| 176 | + * Set event end time |
|
| 177 | + * set the end time for an event |
|
| 178 | + * |
|
| 179 | + * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
| 180 | + * @throws ReflectionException |
|
| 181 | + * @throws InvalidArgumentException |
|
| 182 | + * @throws InvalidInterfaceException |
|
| 183 | + * @throws InvalidDataTypeException |
|
| 184 | + * @throws EE_Error |
|
| 185 | + */ |
|
| 186 | + public function set_end_time($time) |
|
| 187 | + { |
|
| 188 | + $this->_set_time_for($time, 'DTT_EVT_end'); |
|
| 189 | + } |
|
| 190 | + |
|
| 191 | + |
|
| 192 | + /** |
|
| 193 | + * Set registration limit |
|
| 194 | + * set the maximum number of attendees that can be registered for this datetime slot |
|
| 195 | + * |
|
| 196 | + * @param int $reg_limit |
|
| 197 | + * @throws ReflectionException |
|
| 198 | + * @throws InvalidArgumentException |
|
| 199 | + * @throws InvalidInterfaceException |
|
| 200 | + * @throws InvalidDataTypeException |
|
| 201 | + * @throws EE_Error |
|
| 202 | + */ |
|
| 203 | + public function set_reg_limit($reg_limit) |
|
| 204 | + { |
|
| 205 | + $this->set('DTT_reg_limit', $reg_limit); |
|
| 206 | + } |
|
| 207 | + |
|
| 208 | + |
|
| 209 | + /** |
|
| 210 | + * get the number of tickets sold for this datetime slot |
|
| 211 | + * |
|
| 212 | + * @return mixed int on success, FALSE on fail |
|
| 213 | + * @throws ReflectionException |
|
| 214 | + * @throws InvalidArgumentException |
|
| 215 | + * @throws InvalidInterfaceException |
|
| 216 | + * @throws InvalidDataTypeException |
|
| 217 | + * @throws EE_Error |
|
| 218 | + */ |
|
| 219 | + public function sold() |
|
| 220 | + { |
|
| 221 | + return $this->get_raw('DTT_sold'); |
|
| 222 | + } |
|
| 223 | + |
|
| 224 | + |
|
| 225 | + /** |
|
| 226 | + * @param int $sold |
|
| 227 | + * @throws ReflectionException |
|
| 228 | + * @throws InvalidArgumentException |
|
| 229 | + * @throws InvalidInterfaceException |
|
| 230 | + * @throws InvalidDataTypeException |
|
| 231 | + * @throws EE_Error |
|
| 232 | + */ |
|
| 233 | + public function set_sold($sold) |
|
| 234 | + { |
|
| 235 | + // sold can not go below zero |
|
| 236 | + $sold = max(0, $sold); |
|
| 237 | + $this->set('DTT_sold', $sold); |
|
| 238 | + } |
|
| 239 | + |
|
| 240 | + |
|
| 241 | + /** |
|
| 242 | + * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
| 243 | + * Simultaneously decreases the reserved count, unless $also_decrease_reserved is false. |
|
| 244 | + * |
|
| 245 | + * @param int $qty |
|
| 246 | + * @param boolean $also_decrease_reserved |
|
| 247 | + * @return boolean indicating success |
|
| 248 | + * @throws ReflectionException |
|
| 249 | + * @throws InvalidArgumentException |
|
| 250 | + * @throws InvalidInterfaceException |
|
| 251 | + * @throws InvalidDataTypeException |
|
| 252 | + * @throws EE_Error |
|
| 253 | + */ |
|
| 254 | + public function increaseSold($qty = 1, $also_decrease_reserved = true) |
|
| 255 | + { |
|
| 256 | + $qty = absint($qty); |
|
| 257 | + if ($also_decrease_reserved) { |
|
| 258 | + $success = $this->adjustNumericFieldsInDb( |
|
| 259 | + [ |
|
| 260 | + 'DTT_reserved' => $qty * -1, |
|
| 261 | + 'DTT_sold' => $qty |
|
| 262 | + ] |
|
| 263 | + ); |
|
| 264 | + } else { |
|
| 265 | + $success = $this->adjustNumericFieldsInDb( |
|
| 266 | + [ |
|
| 267 | + 'DTT_sold' => $qty |
|
| 268 | + ] |
|
| 269 | + ); |
|
| 270 | + } |
|
| 271 | + |
|
| 272 | + do_action( |
|
| 273 | + 'AHEE__EE_Datetime__increase_sold', |
|
| 274 | + $this, |
|
| 275 | + $qty, |
|
| 276 | + $this->sold(), |
|
| 277 | + $success |
|
| 278 | + ); |
|
| 279 | + return $success; |
|
| 280 | + } |
|
| 281 | + |
|
| 282 | + |
|
| 283 | + /** |
|
| 284 | + * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
| 285 | + * to save afterwards.) |
|
| 286 | + * |
|
| 287 | + * @param int $qty |
|
| 288 | + * @return boolean indicating success |
|
| 289 | + * @throws ReflectionException |
|
| 290 | + * @throws InvalidArgumentException |
|
| 291 | + * @throws InvalidInterfaceException |
|
| 292 | + * @throws InvalidDataTypeException |
|
| 293 | + * @throws EE_Error |
|
| 294 | + */ |
|
| 295 | + public function decreaseSold($qty = 1) |
|
| 296 | + { |
|
| 297 | + $qty = absint($qty); |
|
| 298 | + $success = $this->adjustNumericFieldsInDb( |
|
| 299 | + [ |
|
| 300 | + 'DTT_sold' => $qty * -1 |
|
| 301 | + ] |
|
| 302 | + ); |
|
| 303 | + do_action( |
|
| 304 | + 'AHEE__EE_Datetime__decrease_sold', |
|
| 305 | + $this, |
|
| 306 | + $qty, |
|
| 307 | + $this->sold(), |
|
| 308 | + $success |
|
| 309 | + ); |
|
| 310 | + return $success; |
|
| 311 | + } |
|
| 312 | + |
|
| 313 | + |
|
| 314 | + /** |
|
| 315 | + * Gets qty of reserved tickets for this datetime |
|
| 316 | + * |
|
| 317 | + * @return int |
|
| 318 | + * @throws ReflectionException |
|
| 319 | + * @throws InvalidArgumentException |
|
| 320 | + * @throws InvalidInterfaceException |
|
| 321 | + * @throws InvalidDataTypeException |
|
| 322 | + * @throws EE_Error |
|
| 323 | + */ |
|
| 324 | + public function reserved() |
|
| 325 | + { |
|
| 326 | + return $this->get_raw('DTT_reserved'); |
|
| 327 | + } |
|
| 328 | + |
|
| 329 | + |
|
| 330 | + /** |
|
| 331 | + * Sets qty of reserved tickets for this datetime |
|
| 332 | + * |
|
| 333 | + * @param int $reserved |
|
| 334 | + * @throws ReflectionException |
|
| 335 | + * @throws InvalidArgumentException |
|
| 336 | + * @throws InvalidInterfaceException |
|
| 337 | + * @throws InvalidDataTypeException |
|
| 338 | + * @throws EE_Error |
|
| 339 | + */ |
|
| 340 | + public function set_reserved($reserved) |
|
| 341 | + { |
|
| 342 | + // reserved can not go below zero |
|
| 343 | + $reserved = max(0, (int) $reserved); |
|
| 344 | + $this->set('DTT_reserved', $reserved); |
|
| 345 | + } |
|
| 346 | + |
|
| 347 | + |
|
| 348 | + /** |
|
| 349 | + * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 350 | + * |
|
| 351 | + * @param int $qty |
|
| 352 | + * @return boolean indicating success |
|
| 353 | + * @throws ReflectionException |
|
| 354 | + * @throws InvalidArgumentException |
|
| 355 | + * @throws InvalidInterfaceException |
|
| 356 | + * @throws InvalidDataTypeException |
|
| 357 | + * @throws EE_Error |
|
| 358 | + */ |
|
| 359 | + public function increaseReserved($qty = 1) |
|
| 360 | + { |
|
| 361 | + $qty = absint($qty); |
|
| 362 | + $success = $this->incrementFieldConditionallyInDb( |
|
| 363 | + 'DTT_reserved', |
|
| 364 | + 'DTT_sold', |
|
| 365 | + 'DTT_reg_limit', |
|
| 366 | + $qty |
|
| 367 | + ); |
|
| 368 | + do_action( |
|
| 369 | + 'AHEE__EE_Datetime__increase_reserved', |
|
| 370 | + $this, |
|
| 371 | + $qty, |
|
| 372 | + $this->reserved(), |
|
| 373 | + $success |
|
| 374 | + ); |
|
| 375 | + return $success; |
|
| 376 | + } |
|
| 377 | + |
|
| 378 | + |
|
| 379 | + /** |
|
| 380 | + * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 381 | + * |
|
| 382 | + * @param int $qty |
|
| 383 | + * @return boolean indicating success |
|
| 384 | + * @throws ReflectionException |
|
| 385 | + * @throws InvalidArgumentException |
|
| 386 | + * @throws InvalidInterfaceException |
|
| 387 | + * @throws InvalidDataTypeException |
|
| 388 | + * @throws EE_Error |
|
| 389 | + */ |
|
| 390 | + public function decreaseReserved($qty = 1) |
|
| 391 | + { |
|
| 392 | + $qty = absint($qty); |
|
| 393 | + $success = $this->adjustNumericFieldsInDb( |
|
| 394 | + [ |
|
| 395 | + 'DTT_reserved' => $qty * -1 |
|
| 396 | + ] |
|
| 397 | + ); |
|
| 398 | + do_action( |
|
| 399 | + 'AHEE__EE_Datetime__decrease_reserved', |
|
| 400 | + $this, |
|
| 401 | + $qty, |
|
| 402 | + $this->reserved(), |
|
| 403 | + $success |
|
| 404 | + ); |
|
| 405 | + return $success; |
|
| 406 | + } |
|
| 407 | + |
|
| 408 | + |
|
| 409 | + /** |
|
| 410 | + * total sold and reserved tickets |
|
| 411 | + * |
|
| 412 | + * @return int |
|
| 413 | + * @throws ReflectionException |
|
| 414 | + * @throws InvalidArgumentException |
|
| 415 | + * @throws InvalidInterfaceException |
|
| 416 | + * @throws InvalidDataTypeException |
|
| 417 | + * @throws EE_Error |
|
| 418 | + */ |
|
| 419 | + public function sold_and_reserved() |
|
| 420 | + { |
|
| 421 | + return $this->sold() + $this->reserved(); |
|
| 422 | + } |
|
| 423 | + |
|
| 424 | + |
|
| 425 | + /** |
|
| 426 | + * returns the datetime name |
|
| 427 | + * |
|
| 428 | + * @return string |
|
| 429 | + * @throws ReflectionException |
|
| 430 | + * @throws InvalidArgumentException |
|
| 431 | + * @throws InvalidInterfaceException |
|
| 432 | + * @throws InvalidDataTypeException |
|
| 433 | + * @throws EE_Error |
|
| 434 | + */ |
|
| 435 | + public function name() |
|
| 436 | + { |
|
| 437 | + return $this->get('DTT_name'); |
|
| 438 | + } |
|
| 439 | + |
|
| 440 | + |
|
| 441 | + /** |
|
| 442 | + * returns the datetime description |
|
| 443 | + * |
|
| 444 | + * @return string |
|
| 445 | + * @throws ReflectionException |
|
| 446 | + * @throws InvalidArgumentException |
|
| 447 | + * @throws InvalidInterfaceException |
|
| 448 | + * @throws InvalidDataTypeException |
|
| 449 | + * @throws EE_Error |
|
| 450 | + */ |
|
| 451 | + public function description() |
|
| 452 | + { |
|
| 453 | + return $this->get('DTT_description'); |
|
| 454 | + } |
|
| 455 | + |
|
| 456 | + |
|
| 457 | + /** |
|
| 458 | + * This helper simply returns whether the event_datetime for the current datetime is a primary datetime |
|
| 459 | + * |
|
| 460 | + * @return boolean TRUE if is primary, FALSE if not. |
|
| 461 | + * @throws ReflectionException |
|
| 462 | + * @throws InvalidArgumentException |
|
| 463 | + * @throws InvalidInterfaceException |
|
| 464 | + * @throws InvalidDataTypeException |
|
| 465 | + * @throws EE_Error |
|
| 466 | + */ |
|
| 467 | + public function is_primary() |
|
| 468 | + { |
|
| 469 | + return $this->get('DTT_is_primary'); |
|
| 470 | + } |
|
| 471 | + |
|
| 472 | + |
|
| 473 | + /** |
|
| 474 | + * This helper simply returns the order for the datetime |
|
| 475 | + * |
|
| 476 | + * @return int The order of the datetime for this event. |
|
| 477 | + * @throws ReflectionException |
|
| 478 | + * @throws InvalidArgumentException |
|
| 479 | + * @throws InvalidInterfaceException |
|
| 480 | + * @throws InvalidDataTypeException |
|
| 481 | + * @throws EE_Error |
|
| 482 | + */ |
|
| 483 | + public function order() |
|
| 484 | + { |
|
| 485 | + return $this->get('DTT_order'); |
|
| 486 | + } |
|
| 487 | + |
|
| 488 | + |
|
| 489 | + /** |
|
| 490 | + * This helper simply returns the parent id for the datetime |
|
| 491 | + * |
|
| 492 | + * @return int |
|
| 493 | + * @throws ReflectionException |
|
| 494 | + * @throws InvalidArgumentException |
|
| 495 | + * @throws InvalidInterfaceException |
|
| 496 | + * @throws InvalidDataTypeException |
|
| 497 | + * @throws EE_Error |
|
| 498 | + */ |
|
| 499 | + public function parent() |
|
| 500 | + { |
|
| 501 | + return $this->get('DTT_parent'); |
|
| 502 | + } |
|
| 503 | + |
|
| 504 | + |
|
| 505 | + /** |
|
| 506 | + * show date and/or time |
|
| 507 | + * |
|
| 508 | + * @param string $date_or_time whether to display a date or time or both |
|
| 509 | + * @param string $start_or_end whether to display start or end datetimes |
|
| 510 | + * @param string $dt_frmt |
|
| 511 | + * @param string $tm_frmt |
|
| 512 | + * @param bool $echo whether we echo or return (note echoing uses "pretty" formats, |
|
| 513 | + * otherwise we use the standard formats) |
|
| 514 | + * @return string|bool string on success, FALSE on fail |
|
| 515 | + * @throws ReflectionException |
|
| 516 | + * @throws InvalidArgumentException |
|
| 517 | + * @throws InvalidInterfaceException |
|
| 518 | + * @throws InvalidDataTypeException |
|
| 519 | + * @throws EE_Error |
|
| 520 | + */ |
|
| 521 | + private function _show_datetime( |
|
| 522 | + $date_or_time = null, |
|
| 523 | + $start_or_end = 'start', |
|
| 524 | + $dt_frmt = '', |
|
| 525 | + $tm_frmt = '', |
|
| 526 | + $echo = false |
|
| 527 | + ) { |
|
| 528 | + $field_name = "DTT_EVT_{$start_or_end}"; |
|
| 529 | + $dtt = $this->_get_datetime( |
|
| 530 | + $field_name, |
|
| 531 | + $dt_frmt, |
|
| 532 | + $tm_frmt, |
|
| 533 | + $date_or_time, |
|
| 534 | + $echo |
|
| 535 | + ); |
|
| 536 | + if (! $echo) { |
|
| 537 | + return $dtt; |
|
| 538 | + } |
|
| 539 | + return ''; |
|
| 540 | + } |
|
| 541 | + |
|
| 542 | + |
|
| 543 | + /** |
|
| 544 | + * get event start date. Provide either the date format, or NULL to re-use the |
|
| 545 | + * last-used format, or '' to use the default date format |
|
| 546 | + * |
|
| 547 | + * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
| 548 | + * @return mixed string on success, FALSE on fail |
|
| 549 | + * @throws ReflectionException |
|
| 550 | + * @throws InvalidArgumentException |
|
| 551 | + * @throws InvalidInterfaceException |
|
| 552 | + * @throws InvalidDataTypeException |
|
| 553 | + * @throws EE_Error |
|
| 554 | + */ |
|
| 555 | + public function start_date($dt_frmt = '') |
|
| 556 | + { |
|
| 557 | + return $this->_show_datetime('D', 'start', $dt_frmt); |
|
| 558 | + } |
|
| 559 | + |
|
| 560 | + |
|
| 561 | + /** |
|
| 562 | + * Echoes start_date() |
|
| 563 | + * |
|
| 564 | + * @param string $dt_frmt |
|
| 565 | + * @throws ReflectionException |
|
| 566 | + * @throws InvalidArgumentException |
|
| 567 | + * @throws InvalidInterfaceException |
|
| 568 | + * @throws InvalidDataTypeException |
|
| 569 | + * @throws EE_Error |
|
| 570 | + */ |
|
| 571 | + public function e_start_date($dt_frmt = '') |
|
| 572 | + { |
|
| 573 | + $this->_show_datetime('D', 'start', $dt_frmt, null, true); |
|
| 574 | + } |
|
| 575 | + |
|
| 576 | + |
|
| 577 | + /** |
|
| 578 | + * get end date. Provide either the date format, or NULL to re-use the |
|
| 579 | + * last-used format, or '' to use the default date format |
|
| 580 | + * |
|
| 581 | + * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
| 582 | + * @return mixed string on success, FALSE on fail |
|
| 583 | + * @throws ReflectionException |
|
| 584 | + * @throws InvalidArgumentException |
|
| 585 | + * @throws InvalidInterfaceException |
|
| 586 | + * @throws InvalidDataTypeException |
|
| 587 | + * @throws EE_Error |
|
| 588 | + */ |
|
| 589 | + public function end_date($dt_frmt = '') |
|
| 590 | + { |
|
| 591 | + return $this->_show_datetime('D', 'end', $dt_frmt); |
|
| 592 | + } |
|
| 593 | + |
|
| 594 | + |
|
| 595 | + /** |
|
| 596 | + * Echoes the end date. See end_date() |
|
| 597 | + * |
|
| 598 | + * @param string $dt_frmt |
|
| 599 | + * @throws ReflectionException |
|
| 600 | + * @throws InvalidArgumentException |
|
| 601 | + * @throws InvalidInterfaceException |
|
| 602 | + * @throws InvalidDataTypeException |
|
| 603 | + * @throws EE_Error |
|
| 604 | + */ |
|
| 605 | + public function e_end_date($dt_frmt = '') |
|
| 606 | + { |
|
| 607 | + $this->_show_datetime('D', 'end', $dt_frmt, null, true); |
|
| 608 | + } |
|
| 609 | + |
|
| 610 | + |
|
| 611 | + /** |
|
| 612 | + * get date_range - meaning the start AND end date |
|
| 613 | + * |
|
| 614 | + * @access public |
|
| 615 | + * @param string $dt_frmt string representation of date format defaults to WP settings |
|
| 616 | + * @param string $conjunction conjunction junction what's your function ? |
|
| 617 | + * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
| 618 | + * @return mixed string on success, FALSE on fail |
|
| 619 | + * @throws ReflectionException |
|
| 620 | + * @throws InvalidArgumentException |
|
| 621 | + * @throws InvalidInterfaceException |
|
| 622 | + * @throws InvalidDataTypeException |
|
| 623 | + * @throws EE_Error |
|
| 624 | + */ |
|
| 625 | + public function date_range($dt_frmt = '', $conjunction = ' - ') |
|
| 626 | + { |
|
| 627 | + $dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt; |
|
| 628 | + $start = str_replace( |
|
| 629 | + ' ', |
|
| 630 | + ' ', |
|
| 631 | + $this->get_i18n_datetime('DTT_EVT_start', $dt_frmt) |
|
| 632 | + ); |
|
| 633 | + $end = str_replace( |
|
| 634 | + ' ', |
|
| 635 | + ' ', |
|
| 636 | + $this->get_i18n_datetime('DTT_EVT_end', $dt_frmt) |
|
| 637 | + ); |
|
| 638 | + return $start !== $end ? $start . $conjunction . $end : $start; |
|
| 639 | + } |
|
| 640 | + |
|
| 641 | + |
|
| 642 | + /** |
|
| 643 | + * @param string $dt_frmt |
|
| 644 | + * @param string $conjunction |
|
| 645 | + * @throws ReflectionException |
|
| 646 | + * @throws InvalidArgumentException |
|
| 647 | + * @throws InvalidInterfaceException |
|
| 648 | + * @throws InvalidDataTypeException |
|
| 649 | + * @throws EE_Error |
|
| 650 | + */ |
|
| 651 | + public function e_date_range($dt_frmt = '', $conjunction = ' - ') |
|
| 652 | + { |
|
| 653 | + echo $this->date_range($dt_frmt, $conjunction); |
|
| 654 | + } |
|
| 655 | + |
|
| 656 | + |
|
| 657 | + /** |
|
| 658 | + * get start time |
|
| 659 | + * |
|
| 660 | + * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
| 661 | + * @return mixed string on success, FALSE on fail |
|
| 662 | + * @throws ReflectionException |
|
| 663 | + * @throws InvalidArgumentException |
|
| 664 | + * @throws InvalidInterfaceException |
|
| 665 | + * @throws InvalidDataTypeException |
|
| 666 | + * @throws EE_Error |
|
| 667 | + */ |
|
| 668 | + public function start_time($tm_format = '') |
|
| 669 | + { |
|
| 670 | + return $this->_show_datetime('T', 'start', null, $tm_format); |
|
| 671 | + } |
|
| 672 | + |
|
| 673 | + |
|
| 674 | + /** |
|
| 675 | + * @param string $tm_format |
|
| 676 | + * @throws ReflectionException |
|
| 677 | + * @throws InvalidArgumentException |
|
| 678 | + * @throws InvalidInterfaceException |
|
| 679 | + * @throws InvalidDataTypeException |
|
| 680 | + * @throws EE_Error |
|
| 681 | + */ |
|
| 682 | + public function e_start_time($tm_format = '') |
|
| 683 | + { |
|
| 684 | + $this->_show_datetime('T', 'start', null, $tm_format, true); |
|
| 685 | + } |
|
| 686 | + |
|
| 687 | + |
|
| 688 | + /** |
|
| 689 | + * get end time |
|
| 690 | + * |
|
| 691 | + * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
| 692 | + * @return mixed string on success, FALSE on fail |
|
| 693 | + * @throws ReflectionException |
|
| 694 | + * @throws InvalidArgumentException |
|
| 695 | + * @throws InvalidInterfaceException |
|
| 696 | + * @throws InvalidDataTypeException |
|
| 697 | + * @throws EE_Error |
|
| 698 | + */ |
|
| 699 | + public function end_time($tm_format = '') |
|
| 700 | + { |
|
| 701 | + return $this->_show_datetime('T', 'end', null, $tm_format); |
|
| 702 | + } |
|
| 703 | + |
|
| 704 | + |
|
| 705 | + /** |
|
| 706 | + * @param string $tm_format |
|
| 707 | + * @throws ReflectionException |
|
| 708 | + * @throws InvalidArgumentException |
|
| 709 | + * @throws InvalidInterfaceException |
|
| 710 | + * @throws InvalidDataTypeException |
|
| 711 | + * @throws EE_Error |
|
| 712 | + */ |
|
| 713 | + public function e_end_time($tm_format = '') |
|
| 714 | + { |
|
| 715 | + $this->_show_datetime('T', 'end', null, $tm_format, true); |
|
| 716 | + } |
|
| 717 | + |
|
| 718 | + |
|
| 719 | + /** |
|
| 720 | + * get time_range |
|
| 721 | + * |
|
| 722 | + * @access public |
|
| 723 | + * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
| 724 | + * @param string $conjunction conjunction junction what's your function ? |
|
| 725 | + * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
| 726 | + * @return mixed string on success, FALSE on fail |
|
| 727 | + * @throws ReflectionException |
|
| 728 | + * @throws InvalidArgumentException |
|
| 729 | + * @throws InvalidInterfaceException |
|
| 730 | + * @throws InvalidDataTypeException |
|
| 731 | + * @throws EE_Error |
|
| 732 | + */ |
|
| 733 | + public function time_range($tm_format = '', $conjunction = ' - ') |
|
| 734 | + { |
|
| 735 | + $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
| 736 | + $start = str_replace( |
|
| 737 | + ' ', |
|
| 738 | + ' ', |
|
| 739 | + $this->get_i18n_datetime('DTT_EVT_start', $tm_format) |
|
| 740 | + ); |
|
| 741 | + $end = str_replace( |
|
| 742 | + ' ', |
|
| 743 | + ' ', |
|
| 744 | + $this->get_i18n_datetime('DTT_EVT_end', $tm_format) |
|
| 745 | + ); |
|
| 746 | + return $start !== $end ? $start . $conjunction . $end : $start; |
|
| 747 | + } |
|
| 748 | + |
|
| 749 | + |
|
| 750 | + /** |
|
| 751 | + * @param string $tm_format |
|
| 752 | + * @param string $conjunction |
|
| 753 | + * @throws ReflectionException |
|
| 754 | + * @throws InvalidArgumentException |
|
| 755 | + * @throws InvalidInterfaceException |
|
| 756 | + * @throws InvalidDataTypeException |
|
| 757 | + * @throws EE_Error |
|
| 758 | + */ |
|
| 759 | + public function e_time_range($tm_format = '', $conjunction = ' - ') |
|
| 760 | + { |
|
| 761 | + echo $this->time_range($tm_format, $conjunction); |
|
| 762 | + } |
|
| 763 | + |
|
| 764 | + |
|
| 765 | + /** |
|
| 766 | + * This returns a range representation of the date and times. |
|
| 767 | + * Output is dependent on the difference (or similarity) between DTT_EVT_start and DTT_EVT_end. |
|
| 768 | + * Also, the return value is localized. |
|
| 769 | + * |
|
| 770 | + * @param string $dt_format |
|
| 771 | + * @param string $tm_format |
|
| 772 | + * @param string $conjunction used between two different dates or times. |
|
| 773 | + * ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm |
|
| 774 | + * @param string $separator used between the date and time formats. |
|
| 775 | + * ex: Dec 1, 2016{$separator}2pm |
|
| 776 | + * @return string |
|
| 777 | + * @throws ReflectionException |
|
| 778 | + * @throws InvalidArgumentException |
|
| 779 | + * @throws InvalidInterfaceException |
|
| 780 | + * @throws InvalidDataTypeException |
|
| 781 | + * @throws EE_Error |
|
| 782 | + */ |
|
| 783 | + public function date_and_time_range( |
|
| 784 | + $dt_format = '', |
|
| 785 | + $tm_format = '', |
|
| 786 | + $conjunction = ' - ', |
|
| 787 | + $separator = ' ' |
|
| 788 | + ) { |
|
| 789 | + $dt_format = ! empty($dt_format) ? $dt_format : $this->_dt_frmt; |
|
| 790 | + $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
| 791 | + $full_format = $dt_format . $separator . $tm_format; |
|
| 792 | + // the range output depends on various conditions |
|
| 793 | + switch (true) { |
|
| 794 | + // start date timestamp and end date timestamp are the same. |
|
| 795 | + case ($this->get_raw('DTT_EVT_start') === $this->get_raw('DTT_EVT_end')): |
|
| 796 | + $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format); |
|
| 797 | + break; |
|
| 798 | + // start and end date are the same but times are different |
|
| 799 | + case ($this->start_date() === $this->end_date()): |
|
| 800 | + $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
| 801 | + . $conjunction |
|
| 802 | + . $this->get_i18n_datetime('DTT_EVT_end', $tm_format); |
|
| 803 | + break; |
|
| 804 | + // all other conditions |
|
| 805 | + default: |
|
| 806 | + $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
| 807 | + . $conjunction |
|
| 808 | + . $this->get_i18n_datetime('DTT_EVT_end', $full_format); |
|
| 809 | + break; |
|
| 810 | + } |
|
| 811 | + return $output; |
|
| 812 | + } |
|
| 813 | + |
|
| 814 | + |
|
| 815 | + /** |
|
| 816 | + * This echos the results of date and time range. |
|
| 817 | + * |
|
| 818 | + * @see date_and_time_range() for more details on purpose. |
|
| 819 | + * @param string $dt_format |
|
| 820 | + * @param string $tm_format |
|
| 821 | + * @param string $conjunction |
|
| 822 | + * @return void |
|
| 823 | + * @throws ReflectionException |
|
| 824 | + * @throws InvalidArgumentException |
|
| 825 | + * @throws InvalidInterfaceException |
|
| 826 | + * @throws InvalidDataTypeException |
|
| 827 | + * @throws EE_Error |
|
| 828 | + */ |
|
| 829 | + public function e_date_and_time_range($dt_format = '', $tm_format = '', $conjunction = ' - ') |
|
| 830 | + { |
|
| 831 | + echo $this->date_and_time_range($dt_format, $tm_format, $conjunction); |
|
| 832 | + } |
|
| 833 | + |
|
| 834 | + |
|
| 835 | + /** |
|
| 836 | + * get start date and start time |
|
| 837 | + * |
|
| 838 | + * @param string $dt_format - string representation of date format defaults to 'F j, Y' |
|
| 839 | + * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
| 840 | + * @return mixed string on success, FALSE on fail |
|
| 841 | + * @throws ReflectionException |
|
| 842 | + * @throws InvalidArgumentException |
|
| 843 | + * @throws InvalidInterfaceException |
|
| 844 | + * @throws InvalidDataTypeException |
|
| 845 | + * @throws EE_Error |
|
| 846 | + */ |
|
| 847 | + public function start_date_and_time($dt_format = '', $tm_format = '') |
|
| 848 | + { |
|
| 849 | + return $this->_show_datetime('', 'start', $dt_format, $tm_format); |
|
| 850 | + } |
|
| 851 | + |
|
| 852 | + |
|
| 853 | + /** |
|
| 854 | + * @param string $dt_frmt |
|
| 855 | + * @param string $tm_format |
|
| 856 | + * @throws ReflectionException |
|
| 857 | + * @throws InvalidArgumentException |
|
| 858 | + * @throws InvalidInterfaceException |
|
| 859 | + * @throws InvalidDataTypeException |
|
| 860 | + * @throws EE_Error |
|
| 861 | + */ |
|
| 862 | + public function e_start_date_and_time($dt_frmt = '', $tm_format = '') |
|
| 863 | + { |
|
| 864 | + $this->_show_datetime('', 'start', $dt_frmt, $tm_format, true); |
|
| 865 | + } |
|
| 866 | + |
|
| 867 | + |
|
| 868 | + /** |
|
| 869 | + * Shows the length of the event (start to end time). |
|
| 870 | + * Can be shown in 'seconds','minutes','hours', or 'days'. |
|
| 871 | + * By default, rounds up. (So if you use 'days', and then event |
|
| 872 | + * only occurs for 1 hour, it will return 1 day). |
|
| 873 | + * |
|
| 874 | + * @param string $units 'seconds','minutes','hours','days' |
|
| 875 | + * @param bool $round_up |
|
| 876 | + * @return float|int|mixed |
|
| 877 | + * @throws ReflectionException |
|
| 878 | + * @throws InvalidArgumentException |
|
| 879 | + * @throws InvalidInterfaceException |
|
| 880 | + * @throws InvalidDataTypeException |
|
| 881 | + * @throws EE_Error |
|
| 882 | + */ |
|
| 883 | + public function length($units = 'seconds', $round_up = false) |
|
| 884 | + { |
|
| 885 | + $start = $this->get_raw('DTT_EVT_start'); |
|
| 886 | + $end = $this->get_raw('DTT_EVT_end'); |
|
| 887 | + $length_in_units = $end - $start; |
|
| 888 | + switch ($units) { |
|
| 889 | + // NOTE: We purposefully don't use "break;" in order to chain the divisions |
|
| 890 | + /** @noinspection PhpMissingBreakStatementInspection */ |
|
| 891 | + // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment |
|
| 892 | + case 'days': |
|
| 893 | + $length_in_units /= 24; |
|
| 894 | + /** @noinspection PhpMissingBreakStatementInspection */ |
|
| 895 | + case 'hours': |
|
| 896 | + // fall through is intentional |
|
| 897 | + $length_in_units /= 60; |
|
| 898 | + /** @noinspection PhpMissingBreakStatementInspection */ |
|
| 899 | + case 'minutes': |
|
| 900 | + // fall through is intentional |
|
| 901 | + $length_in_units /= 60; |
|
| 902 | + case 'seconds': |
|
| 903 | + default: |
|
| 904 | + $length_in_units = ceil($length_in_units); |
|
| 905 | + } |
|
| 906 | + // phpcs:enable |
|
| 907 | + if ($round_up) { |
|
| 908 | + $length_in_units = max($length_in_units, 1); |
|
| 909 | + } |
|
| 910 | + return $length_in_units; |
|
| 911 | + } |
|
| 912 | + |
|
| 913 | + |
|
| 914 | + /** |
|
| 915 | + * get end date and time |
|
| 916 | + * |
|
| 917 | + * @param string $dt_frmt - string representation of date format defaults to 'F j, Y' |
|
| 918 | + * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
| 919 | + * @return mixed string on success, FALSE on fail |
|
| 920 | + * @throws ReflectionException |
|
| 921 | + * @throws InvalidArgumentException |
|
| 922 | + * @throws InvalidInterfaceException |
|
| 923 | + * @throws InvalidDataTypeException |
|
| 924 | + * @throws EE_Error |
|
| 925 | + */ |
|
| 926 | + public function end_date_and_time($dt_frmt = '', $tm_format = '') |
|
| 927 | + { |
|
| 928 | + return $this->_show_datetime('', 'end', $dt_frmt, $tm_format); |
|
| 929 | + } |
|
| 930 | + |
|
| 931 | + |
|
| 932 | + /** |
|
| 933 | + * @param string $dt_frmt |
|
| 934 | + * @param string $tm_format |
|
| 935 | + * @throws ReflectionException |
|
| 936 | + * @throws InvalidArgumentException |
|
| 937 | + * @throws InvalidInterfaceException |
|
| 938 | + * @throws InvalidDataTypeException |
|
| 939 | + * @throws EE_Error |
|
| 940 | + */ |
|
| 941 | + public function e_end_date_and_time($dt_frmt = '', $tm_format = '') |
|
| 942 | + { |
|
| 943 | + $this->_show_datetime('', 'end', $dt_frmt, $tm_format, true); |
|
| 944 | + } |
|
| 945 | + |
|
| 946 | + |
|
| 947 | + /** |
|
| 948 | + * get start timestamp |
|
| 949 | + * |
|
| 950 | + * @return int |
|
| 951 | + * @throws ReflectionException |
|
| 952 | + * @throws InvalidArgumentException |
|
| 953 | + * @throws InvalidInterfaceException |
|
| 954 | + * @throws InvalidDataTypeException |
|
| 955 | + * @throws EE_Error |
|
| 956 | + */ |
|
| 957 | + public function start() |
|
| 958 | + { |
|
| 959 | + return $this->get_raw('DTT_EVT_start'); |
|
| 960 | + } |
|
| 961 | + |
|
| 962 | + |
|
| 963 | + /** |
|
| 964 | + * get end timestamp |
|
| 965 | + * |
|
| 966 | + * @return int |
|
| 967 | + * @throws ReflectionException |
|
| 968 | + * @throws InvalidArgumentException |
|
| 969 | + * @throws InvalidInterfaceException |
|
| 970 | + * @throws InvalidDataTypeException |
|
| 971 | + * @throws EE_Error |
|
| 972 | + */ |
|
| 973 | + public function end() |
|
| 974 | + { |
|
| 975 | + return $this->get_raw('DTT_EVT_end'); |
|
| 976 | + } |
|
| 977 | + |
|
| 978 | + |
|
| 979 | + /** |
|
| 980 | + * get the registration limit for this datetime slot |
|
| 981 | + * |
|
| 982 | + * @return mixed int on success, FALSE on fail |
|
| 983 | + * @throws ReflectionException |
|
| 984 | + * @throws InvalidArgumentException |
|
| 985 | + * @throws InvalidInterfaceException |
|
| 986 | + * @throws InvalidDataTypeException |
|
| 987 | + * @throws EE_Error |
|
| 988 | + */ |
|
| 989 | + public function reg_limit() |
|
| 990 | + { |
|
| 991 | + return $this->get_raw('DTT_reg_limit'); |
|
| 992 | + } |
|
| 993 | + |
|
| 994 | + |
|
| 995 | + /** |
|
| 996 | + * have the tickets sold for this datetime, met or exceed the registration limit ? |
|
| 997 | + * |
|
| 998 | + * @return boolean |
|
| 999 | + * @throws ReflectionException |
|
| 1000 | + * @throws InvalidArgumentException |
|
| 1001 | + * @throws InvalidInterfaceException |
|
| 1002 | + * @throws InvalidDataTypeException |
|
| 1003 | + * @throws EE_Error |
|
| 1004 | + */ |
|
| 1005 | + public function sold_out() |
|
| 1006 | + { |
|
| 1007 | + return $this->reg_limit() > 0 && $this->sold() >= $this->reg_limit(); |
|
| 1008 | + } |
|
| 1009 | + |
|
| 1010 | + |
|
| 1011 | + /** |
|
| 1012 | + * return the total number of spaces remaining at this venue. |
|
| 1013 | + * This only takes the venue's capacity into account, NOT the tickets available for sale |
|
| 1014 | + * |
|
| 1015 | + * @param bool $consider_tickets Whether to consider tickets remaining when determining if there are any spaces left |
|
| 1016 | + * Because if all tickets attached to this datetime have no spaces left, |
|
| 1017 | + * then this datetime IS effectively sold out. |
|
| 1018 | + * However, there are cases where we just want to know the spaces |
|
| 1019 | + * remaining for this particular datetime, hence the flag. |
|
| 1020 | + * @return int |
|
| 1021 | + * @throws ReflectionException |
|
| 1022 | + * @throws InvalidArgumentException |
|
| 1023 | + * @throws InvalidInterfaceException |
|
| 1024 | + * @throws InvalidDataTypeException |
|
| 1025 | + * @throws EE_Error |
|
| 1026 | + */ |
|
| 1027 | + public function spaces_remaining($consider_tickets = false) |
|
| 1028 | + { |
|
| 1029 | + // tickets remaining available for purchase |
|
| 1030 | + // no need for special checks for infinite, because if DTT_reg_limit == EE_INF, then EE_INF - x = EE_INF |
|
| 1031 | + $dtt_remaining = $this->reg_limit() - $this->sold_and_reserved(); |
|
| 1032 | + if (! $consider_tickets) { |
|
| 1033 | + return $dtt_remaining; |
|
| 1034 | + } |
|
| 1035 | + $tickets_remaining = $this->tickets_remaining(); |
|
| 1036 | + return min($dtt_remaining, $tickets_remaining); |
|
| 1037 | + } |
|
| 1038 | + |
|
| 1039 | + |
|
| 1040 | + /** |
|
| 1041 | + * Counts the total tickets available |
|
| 1042 | + * (from all the different types of tickets which are available for this datetime). |
|
| 1043 | + * |
|
| 1044 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1045 | + * @return int |
|
| 1046 | + * @throws ReflectionException |
|
| 1047 | + * @throws InvalidArgumentException |
|
| 1048 | + * @throws InvalidInterfaceException |
|
| 1049 | + * @throws InvalidDataTypeException |
|
| 1050 | + * @throws EE_Error |
|
| 1051 | + */ |
|
| 1052 | + public function tickets_remaining($query_params = array()) |
|
| 1053 | + { |
|
| 1054 | + $sum = 0; |
|
| 1055 | + $tickets = $this->tickets($query_params); |
|
| 1056 | + if (! empty($tickets)) { |
|
| 1057 | + foreach ($tickets as $ticket) { |
|
| 1058 | + if ($ticket instanceof EE_Ticket) { |
|
| 1059 | + // get the actual amount of tickets that can be sold |
|
| 1060 | + $qty = $ticket->qty('saleable'); |
|
| 1061 | + if ($qty === EE_INF) { |
|
| 1062 | + return EE_INF; |
|
| 1063 | + } |
|
| 1064 | + // no negative ticket quantities plz |
|
| 1065 | + if ($qty > 0) { |
|
| 1066 | + $sum += $qty; |
|
| 1067 | + } |
|
| 1068 | + } |
|
| 1069 | + } |
|
| 1070 | + } |
|
| 1071 | + return $sum; |
|
| 1072 | + } |
|
| 1073 | + |
|
| 1074 | + |
|
| 1075 | + /** |
|
| 1076 | + * Gets the count of all the tickets available at this datetime (not ticket types) |
|
| 1077 | + * before any were sold |
|
| 1078 | + * |
|
| 1079 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1080 | + * @return int |
|
| 1081 | + * @throws ReflectionException |
|
| 1082 | + * @throws InvalidArgumentException |
|
| 1083 | + * @throws InvalidInterfaceException |
|
| 1084 | + * @throws InvalidDataTypeException |
|
| 1085 | + * @throws EE_Error |
|
| 1086 | + */ |
|
| 1087 | + public function sum_tickets_initially_available($query_params = array()) |
|
| 1088 | + { |
|
| 1089 | + return $this->sum_related('Ticket', $query_params, 'TKT_qty'); |
|
| 1090 | + } |
|
| 1091 | + |
|
| 1092 | + |
|
| 1093 | + /** |
|
| 1094 | + * Returns the lesser-of-the two: spaces remaining at this datetime, or |
|
| 1095 | + * the total tickets remaining (a sum of the tickets remaining for each ticket type |
|
| 1096 | + * that is available for this datetime). |
|
| 1097 | + * |
|
| 1098 | + * @return int |
|
| 1099 | + * @throws ReflectionException |
|
| 1100 | + * @throws InvalidArgumentException |
|
| 1101 | + * @throws InvalidInterfaceException |
|
| 1102 | + * @throws InvalidDataTypeException |
|
| 1103 | + * @throws EE_Error |
|
| 1104 | + */ |
|
| 1105 | + public function total_tickets_available_at_this_datetime() |
|
| 1106 | + { |
|
| 1107 | + return $this->spaces_remaining(true); |
|
| 1108 | + } |
|
| 1109 | + |
|
| 1110 | + |
|
| 1111 | + /** |
|
| 1112 | + * This simply compares the internal dtt for the given string with NOW |
|
| 1113 | + * and determines if the date is upcoming or not. |
|
| 1114 | + * |
|
| 1115 | + * @access public |
|
| 1116 | + * @return boolean |
|
| 1117 | + * @throws ReflectionException |
|
| 1118 | + * @throws InvalidArgumentException |
|
| 1119 | + * @throws InvalidInterfaceException |
|
| 1120 | + * @throws InvalidDataTypeException |
|
| 1121 | + * @throws EE_Error |
|
| 1122 | + */ |
|
| 1123 | + public function is_upcoming() |
|
| 1124 | + { |
|
| 1125 | + return ($this->get_raw('DTT_EVT_start') > time()); |
|
| 1126 | + } |
|
| 1127 | + |
|
| 1128 | + |
|
| 1129 | + /** |
|
| 1130 | + * This simply compares the internal datetime for the given string with NOW |
|
| 1131 | + * and returns if the date is active (i.e. start and end time) |
|
| 1132 | + * |
|
| 1133 | + * @return boolean |
|
| 1134 | + * @throws ReflectionException |
|
| 1135 | + * @throws InvalidArgumentException |
|
| 1136 | + * @throws InvalidInterfaceException |
|
| 1137 | + * @throws InvalidDataTypeException |
|
| 1138 | + * @throws EE_Error |
|
| 1139 | + */ |
|
| 1140 | + public function is_active() |
|
| 1141 | + { |
|
| 1142 | + return ($this->get_raw('DTT_EVT_start') < time() && $this->get_raw('DTT_EVT_end') > time()); |
|
| 1143 | + } |
|
| 1144 | + |
|
| 1145 | + |
|
| 1146 | + /** |
|
| 1147 | + * This simply compares the internal dtt for the given string with NOW |
|
| 1148 | + * and determines if the date is expired or not. |
|
| 1149 | + * |
|
| 1150 | + * @return boolean |
|
| 1151 | + * @throws ReflectionException |
|
| 1152 | + * @throws InvalidArgumentException |
|
| 1153 | + * @throws InvalidInterfaceException |
|
| 1154 | + * @throws InvalidDataTypeException |
|
| 1155 | + * @throws EE_Error |
|
| 1156 | + */ |
|
| 1157 | + public function is_expired() |
|
| 1158 | + { |
|
| 1159 | + return ($this->get_raw('DTT_EVT_end') < time()); |
|
| 1160 | + } |
|
| 1161 | + |
|
| 1162 | + |
|
| 1163 | + /** |
|
| 1164 | + * This returns the active status for whether an event is active, upcoming, or expired |
|
| 1165 | + * |
|
| 1166 | + * @return int return value will be one of the EE_Datetime status constants. |
|
| 1167 | + * @throws ReflectionException |
|
| 1168 | + * @throws InvalidArgumentException |
|
| 1169 | + * @throws InvalidInterfaceException |
|
| 1170 | + * @throws InvalidDataTypeException |
|
| 1171 | + * @throws EE_Error |
|
| 1172 | + */ |
|
| 1173 | + public function get_active_status() |
|
| 1174 | + { |
|
| 1175 | + $total_tickets_for_this_dtt = $this->total_tickets_available_at_this_datetime(); |
|
| 1176 | + if ($total_tickets_for_this_dtt !== false && $total_tickets_for_this_dtt < 1) { |
|
| 1177 | + return EE_Datetime::sold_out; |
|
| 1178 | + } |
|
| 1179 | + if ($this->is_expired()) { |
|
| 1180 | + return EE_Datetime::expired; |
|
| 1181 | + } |
|
| 1182 | + if ($this->is_upcoming()) { |
|
| 1183 | + return EE_Datetime::upcoming; |
|
| 1184 | + } |
|
| 1185 | + if ($this->is_active()) { |
|
| 1186 | + return EE_Datetime::active; |
|
| 1187 | + } |
|
| 1188 | + return null; |
|
| 1189 | + } |
|
| 1190 | + |
|
| 1191 | + |
|
| 1192 | + /** |
|
| 1193 | + * This returns a nice display name for the datetime that is contingent on the span between the dates and times. |
|
| 1194 | + * |
|
| 1195 | + * @param boolean $use_dtt_name if TRUE then we'll use DTT->name() if its not empty. |
|
| 1196 | + * @return string |
|
| 1197 | + * @throws ReflectionException |
|
| 1198 | + * @throws InvalidArgumentException |
|
| 1199 | + * @throws InvalidInterfaceException |
|
| 1200 | + * @throws InvalidDataTypeException |
|
| 1201 | + * @throws EE_Error |
|
| 1202 | + */ |
|
| 1203 | + public function get_dtt_display_name($use_dtt_name = false) |
|
| 1204 | + { |
|
| 1205 | + if ($use_dtt_name) { |
|
| 1206 | + $dtt_name = $this->name(); |
|
| 1207 | + if (! empty($dtt_name)) { |
|
| 1208 | + return $dtt_name; |
|
| 1209 | + } |
|
| 1210 | + } |
|
| 1211 | + // first condition is to see if the months are different |
|
| 1212 | + if ( |
|
| 1213 | + date('m', $this->get_raw('DTT_EVT_start')) !== date('m', $this->get_raw('DTT_EVT_end')) |
|
| 1214 | + ) { |
|
| 1215 | + $display_date = $this->start_date('M j\, Y g:i a') . ' - ' . $this->end_date('M j\, Y g:i a'); |
|
| 1216 | + // next condition is if its the same month but different day |
|
| 1217 | + } else { |
|
| 1218 | + if ( |
|
| 1219 | + date('m', $this->get_raw('DTT_EVT_start')) === date('m', $this->get_raw('DTT_EVT_end')) |
|
| 1220 | + && date('d', $this->get_raw('DTT_EVT_start')) !== date('d', $this->get_raw('DTT_EVT_end')) |
|
| 1221 | + ) { |
|
| 1222 | + $display_date = $this->start_date('M j\, g:i a') . ' - ' . $this->end_date('M j\, g:i a Y'); |
|
| 1223 | + } else { |
|
| 1224 | + $display_date = $this->start_date('F j\, Y') |
|
| 1225 | + . ' @ ' |
|
| 1226 | + . $this->start_date('g:i a') |
|
| 1227 | + . ' - ' |
|
| 1228 | + . $this->end_date('g:i a'); |
|
| 1229 | + } |
|
| 1230 | + } |
|
| 1231 | + return $display_date; |
|
| 1232 | + } |
|
| 1233 | + |
|
| 1234 | + |
|
| 1235 | + /** |
|
| 1236 | + * Gets all the tickets for this datetime |
|
| 1237 | + * |
|
| 1238 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1239 | + * @return EE_Base_Class[]|EE_Ticket[] |
|
| 1240 | + * @throws ReflectionException |
|
| 1241 | + * @throws InvalidArgumentException |
|
| 1242 | + * @throws InvalidInterfaceException |
|
| 1243 | + * @throws InvalidDataTypeException |
|
| 1244 | + * @throws EE_Error |
|
| 1245 | + */ |
|
| 1246 | + public function tickets($query_params = array()) |
|
| 1247 | + { |
|
| 1248 | + return $this->get_many_related('Ticket', $query_params); |
|
| 1249 | + } |
|
| 1250 | + |
|
| 1251 | + |
|
| 1252 | + /** |
|
| 1253 | + * Gets all the ticket types currently available for purchase |
|
| 1254 | + * |
|
| 1255 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
| 1256 | + * @return EE_Ticket[] |
|
| 1257 | + * @throws ReflectionException |
|
| 1258 | + * @throws InvalidArgumentException |
|
| 1259 | + * @throws InvalidInterfaceException |
|
| 1260 | + * @throws InvalidDataTypeException |
|
| 1261 | + * @throws EE_Error |
|
| 1262 | + */ |
|
| 1263 | + public function ticket_types_available_for_purchase($query_params = array()) |
|
| 1264 | + { |
|
| 1265 | + // first check if datetime is valid |
|
| 1266 | + if ($this->sold_out() || ! ($this->is_upcoming() || $this->is_active())) { |
|
| 1267 | + return array(); |
|
| 1268 | + } |
|
| 1269 | + if (empty($query_params)) { |
|
| 1270 | + $query_params = array( |
|
| 1271 | + array( |
|
| 1272 | + 'TKT_start_date' => array('<=', EEM_Ticket::instance()->current_time_for_query('TKT_start_date')), |
|
| 1273 | + 'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')), |
|
| 1274 | + 'TKT_deleted' => false, |
|
| 1275 | + ), |
|
| 1276 | + ); |
|
| 1277 | + } |
|
| 1278 | + return $this->tickets($query_params); |
|
| 1279 | + } |
|
| 1280 | + |
|
| 1281 | + |
|
| 1282 | + /** |
|
| 1283 | + * @return EE_Base_Class|EE_Event |
|
| 1284 | + * @throws ReflectionException |
|
| 1285 | + * @throws InvalidArgumentException |
|
| 1286 | + * @throws InvalidInterfaceException |
|
| 1287 | + * @throws InvalidDataTypeException |
|
| 1288 | + * @throws EE_Error |
|
| 1289 | + */ |
|
| 1290 | + public function event() |
|
| 1291 | + { |
|
| 1292 | + return $this->get_first_related('Event'); |
|
| 1293 | + } |
|
| 1294 | + |
|
| 1295 | + |
|
| 1296 | + /** |
|
| 1297 | + * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime |
|
| 1298 | + * (via the tickets). |
|
| 1299 | + * |
|
| 1300 | + * @return int |
|
| 1301 | + * @throws ReflectionException |
|
| 1302 | + * @throws InvalidArgumentException |
|
| 1303 | + * @throws InvalidInterfaceException |
|
| 1304 | + * @throws InvalidDataTypeException |
|
| 1305 | + * @throws EE_Error |
|
| 1306 | + */ |
|
| 1307 | + public function update_sold() |
|
| 1308 | + { |
|
| 1309 | + $count_regs_for_this_datetime = EEM_Registration::instance()->count( |
|
| 1310 | + array( |
|
| 1311 | + array( |
|
| 1312 | + 'STS_ID' => EEM_Registration::status_id_approved, |
|
| 1313 | + 'REG_deleted' => 0, |
|
| 1314 | + 'Ticket.Datetime.DTT_ID' => $this->ID(), |
|
| 1315 | + ), |
|
| 1316 | + ) |
|
| 1317 | + ); |
|
| 1318 | + $this->set_sold($count_regs_for_this_datetime); |
|
| 1319 | + $this->save(); |
|
| 1320 | + return $count_regs_for_this_datetime; |
|
| 1321 | + } |
|
| 1322 | + |
|
| 1323 | + |
|
| 1324 | + /******************************************************************* |
|
| 1325 | 1325 | *********************** DEPRECATED METHODS ********************** |
| 1326 | 1326 | *******************************************************************/ |
| 1327 | 1327 | |
| 1328 | 1328 | |
| 1329 | - /** |
|
| 1330 | - * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
| 1331 | - * |
|
| 1332 | - * @deprecated 4.9.80.p |
|
| 1333 | - * @param int $qty |
|
| 1334 | - * @return boolean |
|
| 1335 | - * @throws ReflectionException |
|
| 1336 | - * @throws InvalidArgumentException |
|
| 1337 | - * @throws InvalidInterfaceException |
|
| 1338 | - * @throws InvalidDataTypeException |
|
| 1339 | - * @throws EE_Error |
|
| 1340 | - */ |
|
| 1341 | - public function increase_sold($qty = 1) |
|
| 1342 | - { |
|
| 1343 | - EE_Error::doing_it_wrong( |
|
| 1344 | - __FUNCTION__, |
|
| 1345 | - esc_html__('Please use EE_Datetime::increaseSold() instead', 'event_espresso'), |
|
| 1346 | - '4.9.80.p', |
|
| 1347 | - '5.0.0.p' |
|
| 1348 | - ); |
|
| 1349 | - return $this->increaseSold($qty); |
|
| 1350 | - } |
|
| 1351 | - |
|
| 1352 | - |
|
| 1353 | - /** |
|
| 1354 | - * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
| 1355 | - * to save afterwards.) |
|
| 1356 | - * |
|
| 1357 | - * @deprecated 4.9.80.p |
|
| 1358 | - * @param int $qty |
|
| 1359 | - * @return boolean |
|
| 1360 | - * @throws ReflectionException |
|
| 1361 | - * @throws InvalidArgumentException |
|
| 1362 | - * @throws InvalidInterfaceException |
|
| 1363 | - * @throws InvalidDataTypeException |
|
| 1364 | - * @throws EE_Error |
|
| 1365 | - */ |
|
| 1366 | - public function decrease_sold($qty = 1) |
|
| 1367 | - { |
|
| 1368 | - EE_Error::doing_it_wrong( |
|
| 1369 | - __FUNCTION__, |
|
| 1370 | - esc_html__('Please use EE_Datetime::decreaseSold() instead', 'event_espresso'), |
|
| 1371 | - '4.9.80.p', |
|
| 1372 | - '5.0.0.p' |
|
| 1373 | - ); |
|
| 1374 | - return $this->decreaseSold($qty); |
|
| 1375 | - } |
|
| 1376 | - |
|
| 1377 | - |
|
| 1378 | - /** |
|
| 1379 | - * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 1380 | - * |
|
| 1381 | - * @deprecated 4.9.80.p |
|
| 1382 | - * @param int $qty |
|
| 1383 | - * @return boolean indicating success |
|
| 1384 | - * @throws ReflectionException |
|
| 1385 | - * @throws InvalidArgumentException |
|
| 1386 | - * @throws InvalidInterfaceException |
|
| 1387 | - * @throws InvalidDataTypeException |
|
| 1388 | - * @throws EE_Error |
|
| 1389 | - */ |
|
| 1390 | - public function increase_reserved($qty = 1) |
|
| 1391 | - { |
|
| 1392 | - EE_Error::doing_it_wrong( |
|
| 1393 | - __FUNCTION__, |
|
| 1394 | - esc_html__('Please use EE_Datetime::increaseReserved() instead', 'event_espresso'), |
|
| 1395 | - '4.9.80.p', |
|
| 1396 | - '5.0.0.p' |
|
| 1397 | - ); |
|
| 1398 | - return $this->increaseReserved($qty); |
|
| 1399 | - } |
|
| 1400 | - |
|
| 1401 | - |
|
| 1402 | - /** |
|
| 1403 | - * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 1404 | - * |
|
| 1405 | - * @deprecated 4.9.80.p |
|
| 1406 | - * @param int $qty |
|
| 1407 | - * @return boolean |
|
| 1408 | - * @throws ReflectionException |
|
| 1409 | - * @throws InvalidArgumentException |
|
| 1410 | - * @throws InvalidInterfaceException |
|
| 1411 | - * @throws InvalidDataTypeException |
|
| 1412 | - * @throws EE_Error |
|
| 1413 | - */ |
|
| 1414 | - public function decrease_reserved($qty = 1) |
|
| 1415 | - { |
|
| 1416 | - EE_Error::doing_it_wrong( |
|
| 1417 | - __FUNCTION__, |
|
| 1418 | - esc_html__('Please use EE_Datetime::decreaseReserved() instead', 'event_espresso'), |
|
| 1419 | - '4.9.80.p', |
|
| 1420 | - '5.0.0.p' |
|
| 1421 | - ); |
|
| 1422 | - return $this->decreaseReserved($qty); |
|
| 1423 | - } |
|
| 1329 | + /** |
|
| 1330 | + * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
| 1331 | + * |
|
| 1332 | + * @deprecated 4.9.80.p |
|
| 1333 | + * @param int $qty |
|
| 1334 | + * @return boolean |
|
| 1335 | + * @throws ReflectionException |
|
| 1336 | + * @throws InvalidArgumentException |
|
| 1337 | + * @throws InvalidInterfaceException |
|
| 1338 | + * @throws InvalidDataTypeException |
|
| 1339 | + * @throws EE_Error |
|
| 1340 | + */ |
|
| 1341 | + public function increase_sold($qty = 1) |
|
| 1342 | + { |
|
| 1343 | + EE_Error::doing_it_wrong( |
|
| 1344 | + __FUNCTION__, |
|
| 1345 | + esc_html__('Please use EE_Datetime::increaseSold() instead', 'event_espresso'), |
|
| 1346 | + '4.9.80.p', |
|
| 1347 | + '5.0.0.p' |
|
| 1348 | + ); |
|
| 1349 | + return $this->increaseSold($qty); |
|
| 1350 | + } |
|
| 1351 | + |
|
| 1352 | + |
|
| 1353 | + /** |
|
| 1354 | + * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
| 1355 | + * to save afterwards.) |
|
| 1356 | + * |
|
| 1357 | + * @deprecated 4.9.80.p |
|
| 1358 | + * @param int $qty |
|
| 1359 | + * @return boolean |
|
| 1360 | + * @throws ReflectionException |
|
| 1361 | + * @throws InvalidArgumentException |
|
| 1362 | + * @throws InvalidInterfaceException |
|
| 1363 | + * @throws InvalidDataTypeException |
|
| 1364 | + * @throws EE_Error |
|
| 1365 | + */ |
|
| 1366 | + public function decrease_sold($qty = 1) |
|
| 1367 | + { |
|
| 1368 | + EE_Error::doing_it_wrong( |
|
| 1369 | + __FUNCTION__, |
|
| 1370 | + esc_html__('Please use EE_Datetime::decreaseSold() instead', 'event_espresso'), |
|
| 1371 | + '4.9.80.p', |
|
| 1372 | + '5.0.0.p' |
|
| 1373 | + ); |
|
| 1374 | + return $this->decreaseSold($qty); |
|
| 1375 | + } |
|
| 1376 | + |
|
| 1377 | + |
|
| 1378 | + /** |
|
| 1379 | + * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 1380 | + * |
|
| 1381 | + * @deprecated 4.9.80.p |
|
| 1382 | + * @param int $qty |
|
| 1383 | + * @return boolean indicating success |
|
| 1384 | + * @throws ReflectionException |
|
| 1385 | + * @throws InvalidArgumentException |
|
| 1386 | + * @throws InvalidInterfaceException |
|
| 1387 | + * @throws InvalidDataTypeException |
|
| 1388 | + * @throws EE_Error |
|
| 1389 | + */ |
|
| 1390 | + public function increase_reserved($qty = 1) |
|
| 1391 | + { |
|
| 1392 | + EE_Error::doing_it_wrong( |
|
| 1393 | + __FUNCTION__, |
|
| 1394 | + esc_html__('Please use EE_Datetime::increaseReserved() instead', 'event_espresso'), |
|
| 1395 | + '4.9.80.p', |
|
| 1396 | + '5.0.0.p' |
|
| 1397 | + ); |
|
| 1398 | + return $this->increaseReserved($qty); |
|
| 1399 | + } |
|
| 1400 | + |
|
| 1401 | + |
|
| 1402 | + /** |
|
| 1403 | + * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
| 1404 | + * |
|
| 1405 | + * @deprecated 4.9.80.p |
|
| 1406 | + * @param int $qty |
|
| 1407 | + * @return boolean |
|
| 1408 | + * @throws ReflectionException |
|
| 1409 | + * @throws InvalidArgumentException |
|
| 1410 | + * @throws InvalidInterfaceException |
|
| 1411 | + * @throws InvalidDataTypeException |
|
| 1412 | + * @throws EE_Error |
|
| 1413 | + */ |
|
| 1414 | + public function decrease_reserved($qty = 1) |
|
| 1415 | + { |
|
| 1416 | + EE_Error::doing_it_wrong( |
|
| 1417 | + __FUNCTION__, |
|
| 1418 | + esc_html__('Please use EE_Datetime::decreaseReserved() instead', 'event_espresso'), |
|
| 1419 | + '4.9.80.p', |
|
| 1420 | + '5.0.0.p' |
|
| 1421 | + ); |
|
| 1422 | + return $this->decreaseReserved($qty); |
|
| 1423 | + } |
|
| 1424 | 1424 | } |